151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)/*
251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *
651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * modification, are permitted provided that the following conditions
851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * are met:
951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
1051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
1151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
1251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
1351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *     documentation and/or other materials provided with the distribution.
1451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) *
1551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
1651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
1951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
2451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) */
2651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
2751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#ifndef ScopedStyleTree_h
2851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#define ScopedStyleTree_h
2951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/css/resolver/ScopedStyleResolver.h"
3151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/HashMap.h"
3251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/OwnPtr.h"
3351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/Vector.h"
3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)namespace WebCore {
3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)class ScopedStyleTree {
3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    WTF_MAKE_NONCOPYABLE(ScopedStyleTree); WTF_MAKE_FAST_ALLOCATED;
3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)public:
4051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleTree() : m_scopedResolverForDocument(0), m_buildInDocumentOrder(true) { }
4151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
4251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* ensureScopedStyleResolver(ContainerNode& scopingNode);
4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* lookupScopedStyleResolverFor(const ContainerNode* scopingNode)
4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    {
4551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator it = m_authorStyles.find(scopingNode);
4651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return it != m_authorStyles.end() ? it->value.get() : 0;
4751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
4951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* scopedStyleResolverFor(const ContainerNode& scopingNode);
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* addScopedStyleResolver(ContainerNode& scopingNode, bool& isNewEntry);
5151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void clear();
5251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    // for fast-path.
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool hasOnlyScopedResolverForDocument() const { return m_scopedResolverForDocument && m_authorStyles.size() == 1; }
5551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* scopedStyleResolverForDocument() const { return m_scopedResolverForDocument; }
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void resolveScopedStyles(const Element*, Vector<ScopedStyleResolver*, 8>&);
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void collectScopedResolversForHostedShadowTrees(const Element*, Vector<ScopedStyleResolver*, 8>&);
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void resolveScopedKeyframesRules(const Element*, Vector<ScopedStyleResolver*, 8>&);
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* scopedResolverFor(const Element*);
6151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void remove(const ContainerNode* scopingNode);
6351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void pushStyleCache(const ContainerNode& scopingNode, const ContainerNode* parent);
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void popStyleCache(const ContainerNode& scopingNode);
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void collectFeaturesTo(RuleFeatureSet& features);
6851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void setBuildInDocumentOrder(bool enabled) { m_buildInDocumentOrder = enabled; }
6951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool buildInDocumentOrder() const { return m_buildInDocumentOrder; }
7051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
7151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)private:
7251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void setupScopedStylesTree(ScopedStyleResolver* target);
7351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
7451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool cacheIsValid(const ContainerNode* parent) const { return parent && parent == m_cache.nodeForScopedStyles; }
7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void resolveStyleCache(const ContainerNode* scopingNode);
7651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* enclosingScopedStyleResolverFor(const ContainerNode* scopingNode);
7751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
7851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void reparentNodes(const ScopedStyleResolver* oldParent, ScopedStyleResolver* newParent);
7951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
8051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)private:
8151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> > m_authorStyles;
8251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleResolver* m_scopedResolverForDocument;
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool m_buildInDocumentOrder;
8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
8551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    struct ScopedStyleCache {
8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        ScopedStyleResolver* scopedResolver;
8751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        const ContainerNode* nodeForScopedStyles;
8851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
8951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        void clear()
9051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        {
9151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            scopedResolver = 0;
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            nodeForScopedStyles = 0;
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
9451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    };
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ScopedStyleCache m_cache;
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)};
9751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline ScopedStyleResolver* ScopedStyleTree::scopedResolverFor(const Element* element)
9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
10051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (!cacheIsValid(element))
10151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        resolveStyleCache(element);
10251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return m_cache.scopedResolver;
10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
10551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)} // namespace WebCore
10751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
10851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#endif // ScopedStyleTree_h
109