1 /* 2 * Copyright (C) 2011 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 ShadowRoot_h 28 #define ShadowRoot_h 29 30 #include "core/dom/ContainerNode.h" 31 #include "core/dom/Document.h" 32 #include "core/dom/DocumentFragment.h" 33 #include "core/dom/Element.h" 34 #include "core/dom/TreeScope.h" 35 #include "wtf/DoublyLinkedList.h" 36 37 namespace WebCore { 38 39 class ElementShadow; 40 class ExceptionState; 41 class InsertionPoint; 42 class ScopeContentDistribution; 43 44 class ShadowRoot FINAL : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> { 45 friend class WTF::DoublyLinkedListNode<ShadowRoot>; 46 public: 47 // FIXME: We will support multiple shadow subtrees, however current implementation does not work well 48 // if a shadow root is dynamically created. So we prohibit multiple shadow subtrees 49 // in several elements for a while. 50 // See https://bugs.webkit.org/show_bug.cgi?id=77503 and related bugs. 51 enum ShadowRootType { 52 UserAgentShadowRoot = 0, 53 AuthorShadowRoot 54 }; 55 56 static PassRefPtr<ShadowRoot> create(Document* document, ShadowRootType type) 57 { 58 return adoptRef(new ShadowRoot(document, type)); 59 } 60 61 void recalcStyle(StyleChange); 62 63 bool applyAuthorStyles() const { return m_applyAuthorStyles; } 64 void setApplyAuthorStyles(bool); 65 bool resetStyleInheritance() const { return m_resetStyleInheritance; } 66 void setResetStyleInheritance(bool); 67 68 Element* host() const { return toElement(parentOrShadowHostNode()); } 69 ElementShadow* owner() const { return host() ? host()->shadow() : 0; } 70 71 String innerHTML() const; 72 void setInnerHTML(const String&, ExceptionState&); 73 74 Element* activeElement() const; 75 76 ShadowRoot* youngerShadowRoot() const { return prev(); } 77 ShadowRoot* olderShadowRoot() const { return next(); } 78 79 ShadowRoot* bindingsOlderShadowRoot() const; 80 bool shouldExposeToBindings() const { return type() == AuthorShadowRoot; } 81 82 bool isYoungest() const { return !youngerShadowRoot(); } 83 bool isOldest() const { return !olderShadowRoot(); } 84 bool isOldestAuthorShadowRoot() const; 85 86 virtual void attach(const AttachContext& = AttachContext()) OVERRIDE; 87 88 virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE; 89 virtual void removedFrom(ContainerNode*) OVERRIDE; 90 91 virtual void registerScopedHTMLStyleChild() OVERRIDE; 92 virtual void unregisterScopedHTMLStyleChild() OVERRIDE; 93 94 ScopeContentDistribution* scopeDistribution() { return m_scopeDistribution.get(); } 95 const ScopeContentDistribution* scopeDistribution() const { return m_scopeDistribution.get(); } 96 ScopeContentDistribution* ensureScopeDistribution(); 97 98 bool containsShadowElements() const; 99 bool containsContentElements() const; 100 bool containsInsertionPoints() const { return containsShadowElements() || containsContentElements(); } 101 bool containsShadowRoots() const; 102 InsertionPoint* insertionPoint() const; 103 104 ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); } 105 106 PassRefPtr<Node> cloneNode(bool, ExceptionState&); 107 PassRefPtr<Node> cloneNode(ExceptionState& es) { return cloneNode(true, es); } 108 109 private: 110 ShadowRoot(Document*, ShadowRootType); 111 virtual ~ShadowRoot(); 112 113 virtual void dispose() OVERRIDE; 114 virtual bool childTypeAllowed(NodeType) const OVERRIDE; 115 virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE; 116 117 // ShadowRoots should never be cloned. 118 virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; } 119 120 // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834 121 bool isOrphan() const { return !host(); } 122 bool isActive() const; 123 124 ShadowRoot* m_prev; 125 ShadowRoot* m_next; 126 OwnPtr<ScopeContentDistribution> m_scopeDistribution; 127 unsigned m_numberOfStyles : 28; 128 unsigned m_applyAuthorStyles : 1; 129 unsigned m_resetStyleInheritance : 1; 130 unsigned m_type : 1; 131 unsigned m_registeredWithParentShadowRoot : 1; 132 }; 133 134 inline Element* ShadowRoot::activeElement() const 135 { 136 if (Element* element = treeScope()->adjustedFocusedElement()) 137 return element; 138 return 0; 139 } 140 141 inline const ShadowRoot* toShadowRoot(const Node* node) 142 { 143 ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isShadowRoot()); 144 return static_cast<const ShadowRoot*>(node); 145 } 146 147 inline ShadowRoot* toShadowRoot(Node* node) 148 { 149 return const_cast<ShadowRoot*>(toShadowRoot(static_cast<const Node*>(node))); 150 } 151 152 } // namespace 153 154 #endif 155