Home | History | Annotate | Download | only in shadow
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Neither the name of Google Inc. nor the names of its
     11  * contributors may be used to endorse or promote products derived from
     12  * this software without specific prior written permission.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     15  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     16  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     17  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     18  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     19  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     20  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #ifndef ElementShadow_h
     28 #define ElementShadow_h
     29 
     30 #include "core/dom/shadow/ContentDistributor.h"
     31 #include "core/dom/shadow/ShadowRoot.h"
     32 #include "wtf/DoublyLinkedList.h"
     33 #include "wtf/Noncopyable.h"
     34 #include "wtf/PassOwnPtr.h"
     35 #include "wtf/Vector.h"
     36 
     37 namespace WebCore {
     38 
     39 class ElementShadow {
     40     WTF_MAKE_NONCOPYABLE(ElementShadow); WTF_MAKE_FAST_ALLOCATED;
     41 public:
     42     static PassOwnPtr<ElementShadow> create()
     43     {
     44         return adoptPtr(new ElementShadow());
     45     }
     46 
     47     ~ElementShadow()
     48     {
     49         removeAllShadowRoots();
     50     }
     51 
     52     Element* host() const;
     53     ShadowRoot* youngestShadowRoot() const { return m_shadowRoots.head(); }
     54     ShadowRoot* oldestShadowRoot() const { return m_shadowRoots.tail(); }
     55     ElementShadow* containingShadow() const;
     56 
     57     ShadowRoot* addShadowRoot(Element* shadowHost, ShadowRoot::ShadowRootType);
     58     bool applyAuthorStyles() const { return m_applyAuthorStyles; }
     59 
     60     void attach(const Node::AttachContext&);
     61     void detach(const Node::AttachContext&);
     62 
     63     void removeAllEventListeners();
     64 
     65     void didAffectSelector(AffectedSelectorMask mask) { m_distributor.didAffectSelector(host(), mask); }
     66     void willAffectSelector() { m_distributor.willAffectSelector(host()); }
     67     const SelectRuleFeatureSet& ensureSelectFeatureSet() { return m_distributor.ensureSelectFeatureSet(this); }
     68 
     69     // FIXME: Move all callers of this to APIs on ElementShadow and remove it.
     70     ContentDistributor& distributor() { return m_distributor; }
     71     const ContentDistributor& distributor() const { return m_distributor; }
     72 
     73     void distributeIfNeeded()
     74     {
     75         if (m_needsDistributionRecalc)
     76             m_distributor.distribute(host());
     77         m_needsDistributionRecalc = false;
     78     }
     79     void clearDistribution() { m_distributor.clearDistribution(host()); }
     80 
     81     void setNeedsDistributionRecalc();
     82 
     83     bool didAffectApplyAuthorStyles();
     84     bool containsActiveStyles() const;
     85 
     86 private:
     87     ElementShadow()
     88         : m_needsDistributionRecalc(false)
     89         , m_applyAuthorStyles(false)
     90     { }
     91 
     92     void removeAllShadowRoots();
     93     bool resolveApplyAuthorStyles() const;
     94 
     95     DoublyLinkedList<ShadowRoot> m_shadowRoots;
     96     ContentDistributor m_distributor;
     97     bool m_needsDistributionRecalc;
     98     bool m_applyAuthorStyles;
     99 };
    100 
    101 inline Element* ElementShadow::host() const
    102 {
    103     ASSERT(!m_shadowRoots.isEmpty());
    104     return youngestShadowRoot()->host();
    105 }
    106 
    107 inline ShadowRoot* Node::youngestShadowRoot() const
    108 {
    109     if (!this->isElementNode())
    110         return 0;
    111     if (ElementShadow* shadow = toElement(this)->shadow())
    112         return shadow->youngestShadowRoot();
    113     return 0;
    114 }
    115 
    116 inline ElementShadow* ElementShadow::containingShadow() const
    117 {
    118     if (ShadowRoot* parentRoot = host()->containingShadowRoot())
    119         return parentRoot->owner();
    120     return 0;
    121 }
    122 
    123 class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
    124 public:
    125     explicit ShadowRootVector(ElementShadow* tree)
    126     {
    127         for (ShadowRoot* root = tree->youngestShadowRoot(); root; root = root->olderShadowRoot())
    128             append(root);
    129     }
    130 };
    131 
    132 inline ElementShadow* shadowOfParent(const Node* node)
    133 {
    134     if (!node)
    135         return 0;
    136     if (Node* parent = node->parentNode())
    137         if (parent->isElementNode())
    138             return toElement(parent)->shadow();
    139     return 0;
    140 }
    141 
    142 
    143 } // namespace
    144 
    145 #endif
    146