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 "platform/heap/Handle.h" 34 #include "wtf/DoublyLinkedList.h" 35 #include "wtf/HashMap.h" 36 #include "wtf/Noncopyable.h" 37 #include "wtf/PassOwnPtr.h" 38 39 namespace blink { 40 41 class ElementShadow FINAL : public NoBaseWillBeGarbageCollectedFinalized<ElementShadow> { 42 WTF_MAKE_NONCOPYABLE(ElementShadow); 43 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 44 public: 45 static PassOwnPtrWillBeRawPtr<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 hasSameStyles(const ElementShadow*) const; 56 57 void attach(const Node::AttachContext&); 58 void detach(const Node::AttachContext&); 59 60 void distributedNodePseudoStateChanged(CSSSelector::PseudoType); 61 void willAffectSelector(); 62 const SelectRuleFeatureSet& ensureSelectFeatureSet(); 63 64 void distributeIfNeeded(); 65 void setNeedsDistributionRecalc(); 66 67 const InsertionPoint* finalDestinationInsertionPointFor(const Node*) const; 68 const DestinationInsertionPoints* destinationInsertionPointsFor(const Node*) const; 69 70 void didDistributeNode(const Node*, InsertionPoint*); 71 72 void trace(Visitor*); 73 74 private: 75 ElementShadow(); 76 77 #if !ENABLE(OILPAN) 78 void removeDetachedShadowRoots(); 79 #endif 80 81 void distribute(); 82 void clearDistribution(); 83 84 void collectSelectFeatureSetFrom(ShadowRoot&); 85 void distributeNodeChildrenTo(InsertionPoint*, ContainerNode*); 86 87 bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; } 88 void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; } 89 90 typedef WillBeHeapHashMap<RawPtrWillBeMember<const Node>, DestinationInsertionPoints> NodeToDestinationInsertionPoints; 91 NodeToDestinationInsertionPoints m_nodeToInsertionPoints; 92 93 SelectRuleFeatureSet m_selectFeatures; 94 // FIXME: Oilpan: add a heap-based version of DoublyLinkedList<>. 95 DoublyLinkedList<ShadowRoot> m_shadowRoots; 96 bool m_needsDistributionRecalc; 97 bool m_needsSelectFeatureSet; 98 }; 99 100 inline Element* ElementShadow::host() const 101 { 102 ASSERT(!m_shadowRoots.isEmpty()); 103 return youngestShadowRoot()->host(); 104 } 105 106 inline ShadowRoot* Node::youngestShadowRoot() const 107 { 108 if (!isElementNode()) 109 return 0; 110 return toElement(this)->youngestShadowRoot(); 111 } 112 113 inline ShadowRoot* Element::youngestShadowRoot() const 114 { 115 if (ElementShadow* shadow = this->shadow()) 116 return shadow->youngestShadowRoot(); 117 return 0; 118 } 119 120 inline ElementShadow* ElementShadow::containingShadow() const 121 { 122 if (ShadowRoot* parentRoot = host()->containingShadowRoot()) 123 return parentRoot->owner(); 124 return 0; 125 } 126 127 inline void ElementShadow::distributeIfNeeded() 128 { 129 if (m_needsDistributionRecalc) 130 distribute(); 131 m_needsDistributionRecalc = false; 132 } 133 134 } // namespace 135 136 #endif 137