OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Neither the name of Google Inc. nor the names of its | 10 * * Neither the name of Google Inc. nor the names of its |
(...skipping 14 matching lines...) Expand all Loading... |
25 */ | 25 */ |
26 | 26 |
27 #ifndef ShadowRoot_h | 27 #ifndef ShadowRoot_h |
28 #define ShadowRoot_h | 28 #define ShadowRoot_h |
29 | 29 |
30 #include "core/CoreExport.h" | 30 #include "core/CoreExport.h" |
31 #include "core/dom/ContainerNode.h" | 31 #include "core/dom/ContainerNode.h" |
32 #include "core/dom/DocumentFragment.h" | 32 #include "core/dom/DocumentFragment.h" |
33 #include "core/dom/Element.h" | 33 #include "core/dom/Element.h" |
34 #include "core/dom/TreeScope.h" | 34 #include "core/dom/TreeScope.h" |
35 #include "core/dom/shadow/SlotAssignment.h" | |
36 | 35 |
37 namespace blink { | 36 namespace blink { |
38 | 37 |
39 class Document; | 38 class Document; |
40 class ElementShadow; | 39 class ElementShadow; |
41 class ExceptionState; | 40 class ExceptionState; |
42 class HTMLShadowElement; | 41 class HTMLShadowElement; |
| 42 class HTMLSlotElement; |
43 class InsertionPoint; | 43 class InsertionPoint; |
44 class ShadowRootRareData; | |
45 class ShadowRootRareDataV0; | 44 class ShadowRootRareDataV0; |
| 45 class SlotAssignment; |
46 class StyleSheetList; | 46 class StyleSheetList; |
47 | 47 |
48 enum class ShadowRootType { | 48 enum class ShadowRootType { |
49 UserAgent, | 49 UserAgent, |
50 V0, | 50 V0, |
51 Open, | 51 Open, |
52 Closed | 52 Closed |
53 }; | 53 }; |
54 | 54 |
55 class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { | 55 class CORE_EXPORT ShadowRoot final : public DocumentFragment, public TreeScope { |
56 DEFINE_WRAPPERTYPEINFO(); | 56 DEFINE_WRAPPERTYPEINFO(); |
57 USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot); | 57 USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot); |
58 public: | 58 public: |
59 // FIXME: Current implementation does not work well if a shadow root is dyna
mically created. | 59 // FIXME: Current implementation does not work well if a shadow root is dyna
mically created. |
60 // So multiple shadow subtrees in several elements are prohibited. | 60 // So multiple shadow subtrees in several elements are prohibited. |
61 // See https://github.com/w3c/webcomponents/issues/102 and http://crbug.com/
234020 | 61 // See https://github.com/w3c/webcomponents/issues/102 and http://crbug.com/
234020 |
62 static ShadowRoot* create(Document& document, ShadowRootType type) | 62 static ShadowRoot* create(Document& document, ShadowRootType type) |
63 { | 63 { |
64 return new ShadowRoot(document, type); | 64 return new ShadowRoot(document, type); |
65 } | 65 } |
66 | 66 |
67 void recalcStyle(StyleRecalcChange); | |
68 | |
69 // Disambiguate between Node and TreeScope hierarchies; TreeScope's implemen
tation is simpler. | 67 // Disambiguate between Node and TreeScope hierarchies; TreeScope's implemen
tation is simpler. |
70 using TreeScope::document; | 68 using TreeScope::document; |
71 using TreeScope::getElementById; | 69 using TreeScope::getElementById; |
72 | 70 |
| 71 // Make protected methods from base class public here. |
| 72 using TreeScope::setDocument; |
| 73 using TreeScope::setParentTreeScope; |
| 74 |
73 // TODO(kochi): crbug.com/507413 In non-Oilpan, host() may return null durin
g queued | 75 // TODO(kochi): crbug.com/507413 In non-Oilpan, host() may return null durin
g queued |
74 // event handling (e.g. during execCommand()). | 76 // event handling (e.g. during execCommand()). |
75 Element* host() const { return toElement(parentOrShadowHostNode()); } | 77 Element* host() const { return toElement(parentOrShadowHostNode()); } |
76 ElementShadow* owner() const { return host() ? host()->shadow() : 0; } | 78 ElementShadow* owner() const { return host() ? host()->shadow() : 0; } |
77 | 79 ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); } |
78 ShadowRoot* youngerShadowRoot() const; | |
79 ShadowRoot* olderShadowRoot() const; | |
80 ShadowRoot* olderShadowRootForBindings() const; | |
81 | |
82 void setYoungerShadowRoot(ShadowRoot&); | |
83 void setOlderShadowRoot(ShadowRoot&); | |
84 | |
85 String mode() const { return (type() == ShadowRootType::V0 || type() == Shad
owRootType::Open) ? "open" : "closed"; }; | 80 String mode() const { return (type() == ShadowRootType::V0 || type() == Shad
owRootType::Open) ? "open" : "closed"; }; |
86 | 81 |
87 bool isOpenOrV0() const { return type() == ShadowRootType::V0 || type() == S
hadowRootType::Open; } | 82 bool isOpenOrV0() const { return type() == ShadowRootType::V0 || type() == S
hadowRootType::Open; } |
88 | |
89 bool isV1() const { return type() == ShadowRootType::Open || type() == Shado
wRootType::Closed; } | 83 bool isV1() const { return type() == ShadowRootType::Open || type() == Shado
wRootType::Closed; } |
90 | 84 |
91 bool isYoungest() const { return !youngerShadowRoot(); } | |
92 bool isOldest() const { return !olderShadowRoot(); } | |
93 | |
94 void attach(const AttachContext& = AttachContext()) override; | 85 void attach(const AttachContext& = AttachContext()) override; |
95 | 86 |
96 InsertionNotificationRequest insertedInto(ContainerNode*) override; | 87 InsertionNotificationRequest insertedInto(ContainerNode*) override; |
97 void removedFrom(ContainerNode*) override; | 88 void removedFrom(ContainerNode*) override; |
98 | 89 |
99 void registerScopedHTMLStyleChild(); | 90 // For V0 |
100 void unregisterScopedHTMLStyleChild(); | 91 ShadowRoot* youngerShadowRoot() const; |
101 | 92 ShadowRoot* olderShadowRoot() const; |
| 93 ShadowRoot* olderShadowRootForBindings() const; |
| 94 void setYoungerShadowRoot(ShadowRoot&); |
| 95 void setOlderShadowRoot(ShadowRoot&); |
| 96 bool isYoungest() const { return !youngerShadowRoot(); } |
| 97 bool isOldest() const { return !olderShadowRoot(); } |
102 bool containsShadowElements() const; | 98 bool containsShadowElements() const; |
103 bool containsContentElements() const; | 99 bool containsContentElements() const; |
104 bool containsInsertionPoints() const { return containsShadowElements() || co
ntainsContentElements(); } | 100 bool containsInsertionPoints() const { return containsShadowElements() || co
ntainsContentElements(); } |
105 bool containsShadowRoots() const; | |
106 | |
107 unsigned descendantShadowElementCount() const; | 101 unsigned descendantShadowElementCount() const; |
108 | |
109 // For Internals, don't use this. | |
110 unsigned childShadowRootCount() const; | |
111 unsigned numberOfStyles() const { return m_numberOfStyles; } | |
112 | |
113 HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const; | 102 HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const; |
114 void setShadowInsertionPointOfYoungerShadowRoot(HTMLShadowElement*); | 103 void setShadowInsertionPointOfYoungerShadowRoot(HTMLShadowElement*); |
115 | |
116 void didAddInsertionPoint(InsertionPoint*); | 104 void didAddInsertionPoint(InsertionPoint*); |
117 void didRemoveInsertionPoint(InsertionPoint*); | 105 void didRemoveInsertionPoint(InsertionPoint*); |
118 const HeapVector<Member<InsertionPoint>>& descendantInsertionPoints(); | 106 const HeapVector<Member<InsertionPoint>>& descendantInsertionPoints(); |
119 | 107 |
120 ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); } | 108 // For Internals, don't use this. |
| 109 unsigned childShadowRootCount() const { return m_childShadowRootCount; } |
| 110 unsigned numberOfStyles() const { return m_numberOfStyles; } |
| 111 |
| 112 void recalcStyle(StyleRecalcChange); |
| 113 |
| 114 void registerScopedHTMLStyleChild(); |
| 115 void unregisterScopedHTMLStyleChild(); |
| 116 |
| 117 SlotAssignment& ensureSlotAssignment(); |
121 | 118 |
122 void didAddSlot(); | 119 void didAddSlot(); |
123 void didRemoveSlot(); | 120 void didRemoveSlot(); |
124 const HeapVector<Member<HTMLSlotElement>>& descendantSlots(); | 121 const HeapVector<Member<HTMLSlotElement>>& descendantSlots(); |
125 | 122 |
126 void assignV1(); | 123 void assignV1(); |
127 void distributeV1(); | 124 void distributeV1(); |
128 | 125 |
129 HTMLSlotElement* assignedSlotFor(const Node& node) const | 126 HTMLSlotElement* assignedSlotFor(const Node&) const; |
130 { | |
131 DCHECK(m_slotAssignment); | |
132 return m_slotAssignment->assignedSlotFor(node); | |
133 } | |
134 | |
135 // Make protected methods from base class public here. | |
136 using TreeScope::setDocument; | |
137 using TreeScope::setParentTreeScope; | |
138 | 127 |
139 Element* activeElement() const; | 128 Element* activeElement() const; |
140 | 129 |
141 String innerHTML() const; | 130 String innerHTML() const; |
142 void setInnerHTML(const String&, ExceptionState&); | 131 void setInnerHTML(const String&, ExceptionState&); |
143 | 132 |
144 Node* cloneNode(bool, ExceptionState&); | 133 Node* cloneNode(bool, ExceptionState&); |
145 | 134 |
146 StyleSheetList* styleSheets(); | |
147 | |
148 void setDelegatesFocus(bool flag) { m_delegatesFocus = flag; } | 135 void setDelegatesFocus(bool flag) { m_delegatesFocus = flag; } |
149 bool delegatesFocus() const { return m_delegatesFocus; } | 136 bool delegatesFocus() const { return m_delegatesFocus; } |
150 | 137 |
| 138 bool containsShadowRoots() const { return m_childShadowRootCount; } |
| 139 |
| 140 StyleSheetList& styleSheets(); |
| 141 void setStyleSheets(StyleSheetList* styleSheetList) { m_styleSheetList = sty
leSheetList; } |
| 142 |
151 DECLARE_VIRTUAL_TRACE(); | 143 DECLARE_VIRTUAL_TRACE(); |
152 | 144 |
153 private: | 145 private: |
154 ShadowRoot(Document&, ShadowRootType); | 146 ShadowRoot(Document&, ShadowRootType); |
155 ~ShadowRoot() override; | 147 ~ShadowRoot() override; |
156 | 148 |
157 void childrenChanged(const ChildrenChange&) override; | 149 void childrenChanged(const ChildrenChange&) override; |
158 | 150 |
159 ShadowRootRareData& ensureShadowRootRareData(); | |
160 ShadowRootRareDataV0& ensureShadowRootRareDataV0(); | 151 ShadowRootRareDataV0& ensureShadowRootRareDataV0(); |
161 | 152 |
162 void addChildShadowRoot(); | 153 void addChildShadowRoot() { ++m_childShadowRootCount; } |
163 void removeChildShadowRoot(); | 154 void removeChildShadowRoot() { DCHECK_GT(m_childShadowRootCount, 0u); --m_ch
ildShadowRootCount; } |
164 void invalidateDescendantInsertionPoints(); | 155 void invalidateDescendantInsertionPoints(); |
165 | 156 |
166 // ShadowRoots should never be cloned. | 157 // ShadowRoots should never be cloned. |
167 Node* cloneNode(bool) override { return nullptr; } | 158 Node* cloneNode(bool) override { return nullptr; } |
168 | 159 |
169 // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=888
34 | 160 // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=888
34 |
170 bool isOrphan() const { return !host(); } | 161 bool isOrphan() const { return !host(); } |
171 | 162 |
172 void invalidateDescendantSlots(); | 163 void invalidateDescendantSlots(); |
173 unsigned descendantSlotCount() const; | 164 unsigned descendantSlotCount() const; |
174 | 165 |
175 Member<ShadowRootRareData> m_shadowRootRareData; | |
176 Member<ShadowRootRareDataV0> m_shadowRootRareDataV0; | 166 Member<ShadowRootRareDataV0> m_shadowRootRareDataV0; |
| 167 Member<StyleSheetList> m_styleSheetList; |
177 Member<SlotAssignment> m_slotAssignment; | 168 Member<SlotAssignment> m_slotAssignment; |
178 unsigned m_numberOfStyles : 26; | 169 unsigned m_numberOfStyles : 13; |
| 170 unsigned m_childShadowRootCount : 13; |
179 unsigned m_type : 2; | 171 unsigned m_type : 2; |
180 unsigned m_registeredWithParentShadowRoot : 1; | 172 unsigned m_registeredWithParentShadowRoot : 1; |
181 unsigned m_descendantInsertionPointsIsValid : 1; | 173 unsigned m_descendantInsertionPointsIsValid : 1; |
182 unsigned m_delegatesFocus : 1; | 174 unsigned m_delegatesFocus : 1; |
183 unsigned m_descendantSlotsIsValid : 1; | 175 unsigned m_descendantSlotsIsValid : 1; |
184 }; | 176 }; |
185 | 177 |
186 inline Element* ShadowRoot::activeElement() const | 178 inline Element* ShadowRoot::activeElement() const |
187 { | 179 { |
188 return adjustedFocusedElement(); | 180 return adjustedFocusedElement(); |
189 } | 181 } |
190 | 182 |
191 inline ShadowRoot* Element::shadowRootIfV1() const | 183 inline ShadowRoot* Element::shadowRootIfV1() const |
192 { | 184 { |
193 ShadowRoot* root = this->shadowRoot(); | 185 ShadowRoot* root = this->shadowRoot(); |
194 if (root && root->isV1()) | 186 if (root && root->isV1()) |
195 return root; | 187 return root; |
196 return nullptr; | 188 return nullptr; |
197 } | 189 } |
198 | 190 |
199 DEFINE_NODE_TYPE_CASTS(ShadowRoot, isShadowRoot()); | 191 DEFINE_NODE_TYPE_CASTS(ShadowRoot, isShadowRoot()); |
200 DEFINE_TYPE_CASTS(ShadowRoot, TreeScope, treeScope, treeScope->rootNode().isShad
owRoot(), treeScope.rootNode().isShadowRoot()); | 192 DEFINE_TYPE_CASTS(ShadowRoot, TreeScope, treeScope, treeScope->rootNode().isShad
owRoot(), treeScope.rootNode().isShadowRoot()); |
201 DEFINE_TYPE_CASTS(TreeScope, ShadowRoot, shadowRoot, true, true); | 193 DEFINE_TYPE_CASTS(TreeScope, ShadowRoot, shadowRoot, true, true); |
202 | 194 |
203 CORE_EXPORT std::ostream& operator<<(std::ostream&, const ShadowRootType&); | 195 CORE_EXPORT std::ostream& operator<<(std::ostream&, const ShadowRootType&); |
204 | 196 |
205 } // namespace blink | 197 } // namespace blink |
206 | 198 |
207 #endif // ShadowRoot_h | 199 #endif // ShadowRoot_h |
OLD | NEW |