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/InsertionPoint.h" 31 #include "core/dom/shadow/SelectRuleFeatureSet.h" 32 #include "core/dom/shadow/ShadowRoot.h" 33 #include "wtf/DoublyLinkedList.h" 34 #include "wtf/Forward.h" 35 #include "wtf/HashMap.h" 36 #include "wtf/Noncopyable.h" 37 #include "wtf/PassOwnPtr.h" 38 #include "wtf/Vector.h" 39 40 namespace WebCore { 41 42 class ElementShadow { 43 WTF_MAKE_NONCOPYABLE(ElementShadow); WTF_MAKE_FAST_ALLOCATED; 44 public: 45 static PassOwnPtr<ElementShadow> create(); 46 ~ElementShadow(); 47 48 Element* host() const; 49 ShadowRoot* youngestShadowRoot() const { return m_shadowRoots.head(); } 50 ShadowRoot* oldestShadowRoot() const { return m_shadowRoots.tail(); } 51 ElementShadow* containingShadow() const; 52 53 ShadowRoot& addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType); 54 55 bool applyAuthorStyles() const { return m_applyAuthorStyles; } 56 bool didAffectApplyAuthorStyles(); 57 bool containsActiveStyles() const; 58 59 void attach(const Node::AttachContext&); 60 void detach(const Node::AttachContext&); 61 62 void removeAllEventListeners(); 63 64 void didAffectSelector(AffectedSelectorMask); 65 void willAffectSelector(); 66 const SelectRuleFeatureSet& ensureSelectFeatureSet(); 67 68 void distributeIfNeeded(); 69 void setNeedsDistributionRecalc(); 70 71 const InsertionPoint* finalDestinationInsertionPointFor(const Node*) const; 72 const DestinationInsertionPoints* destinationInsertionPointsFor(const Node*) const; 73 74 void didDistributeNode(const Node*, InsertionPoint*); 75 76 private: 77 ElementShadow(); 78 79 void removeAllShadowRoots(); 80 bool resolveApplyAuthorStyles() const; 81 82 void distribute(); 83 void clearDistribution(); 84 85 void collectSelectFeatureSetFrom(ShadowRoot&); 86 void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*); 87 88 bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; } 89 void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; } 90 91 typedef HashMap<const Node*, DestinationInsertionPoints> NodeToDestinationInsertionPoints; 92 NodeToDestinationInsertionPoints m_nodeToInsertionPoints; 93 94 SelectRuleFeatureSet m_selectFeatures; 95 DoublyLinkedList<ShadowRoot> m_shadowRoots; 96 bool m_needsDistributionRecalc; 97 bool m_applyAuthorStyles; 98 bool m_needsSelectFeatureSet; 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 (!isElementNode()) 110 return 0; 111 return toElement(this)->youngestShadowRoot(); 112 } 113 114 inline ShadowRoot* Element::youngestShadowRoot() const 115 { 116 if (ElementShadow* shadow = this->shadow()) 117 return shadow->youngestShadowRoot(); 118 return 0; 119 } 120 121 inline ElementShadow* ElementShadow::containingShadow() const 122 { 123 if (ShadowRoot* parentRoot = host()->containingShadowRoot()) 124 return parentRoot->owner(); 125 return 0; 126 } 127 128 inline void ElementShadow::distributeIfNeeded() 129 { 130 if (m_needsDistributionRecalc) 131 distribute(); 132 m_needsDistributionRecalc = false; 133 } 134 135 } // namespace 136 137 #endif 138