OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/dom/custom/CustomElementDefinition.h" | 5 #include "core/dom/custom/CustomElementDefinition.h" |
6 | 6 |
| 7 #include "core/dom/Attr.h" |
7 #include "core/dom/ExceptionCode.h" | 8 #include "core/dom/ExceptionCode.h" |
8 #include "core/dom/custom/CEReactionsScope.h" | 9 #include "core/dom/custom/CEReactionsScope.h" |
9 #include "core/dom/custom/CustomElement.h" | 10 #include "core/dom/custom/CustomElement.h" |
10 #include "core/dom/custom/CustomElementAttributeChangedCallbackReaction.h" | 11 #include "core/dom/custom/CustomElementAttributeChangedCallbackReaction.h" |
11 #include "core/dom/custom/CustomElementConnectedCallbackReaction.h" | 12 #include "core/dom/custom/CustomElementConnectedCallbackReaction.h" |
12 #include "core/dom/custom/CustomElementDisconnectedCallbackReaction.h" | 13 #include "core/dom/custom/CustomElementDisconnectedCallbackReaction.h" |
13 #include "core/dom/custom/CustomElementUpgradeReaction.h" | 14 #include "core/dom/custom/CustomElementUpgradeReaction.h" |
14 #include "core/html/HTMLElement.h" | 15 #include "core/html/HTMLElement.h" |
15 | 16 |
16 namespace blink { | 17 namespace blink { |
17 | 18 |
18 CustomElementDefinition::CustomElementDefinition( | 19 CustomElementDefinition::CustomElementDefinition( |
19 const CustomElementDescriptor& descriptor) | 20 const CustomElementDescriptor& descriptor) |
20 : m_descriptor(descriptor) | 21 : m_descriptor(descriptor) |
21 { | 22 { |
22 } | 23 } |
23 | 24 |
| 25 CustomElementDefinition::CustomElementDefinition( |
| 26 const CustomElementDescriptor& descriptor, |
| 27 const HashSet<AtomicString>& observedAttributes) |
| 28 : m_observedAttributes(observedAttributes) |
| 29 , m_descriptor(descriptor) |
| 30 { |
| 31 } |
| 32 |
24 CustomElementDefinition::~CustomElementDefinition() | 33 CustomElementDefinition::~CustomElementDefinition() |
25 { | 34 { |
26 } | 35 } |
27 | 36 |
28 DEFINE_TRACE(CustomElementDefinition) | 37 DEFINE_TRACE(CustomElementDefinition) |
29 { | 38 { |
30 visitor->trace(m_constructionStack); | 39 visitor->trace(m_constructionStack); |
31 } | 40 } |
32 | 41 |
33 static String errorMessageForConstructorResult(Element* element, | 42 static String errorMessageForConstructorResult(Element* element, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 element->setCustomElementState(CustomElementState::Undefined); | 95 element->setCustomElementState(CustomElementState::Undefined); |
87 // 6.2.2. Enqueue a custom element upgrade reaction given result and | 96 // 6.2.2. Enqueue a custom element upgrade reaction given result and |
88 // definition. | 97 // definition. |
89 enqueueUpgradeReaction(element); | 98 enqueueUpgradeReaction(element); |
90 return element; | 99 return element; |
91 } | 100 } |
92 | 101 |
93 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent | 102 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent |
94 void CustomElementDefinition::upgrade(Element* element) | 103 void CustomElementDefinition::upgrade(Element* element) |
95 { | 104 { |
96 // TODO(kojii): This should be reversed by exposing observedAttributes from | 105 if (!m_observedAttributes.isEmpty()) |
97 // ScriptCustomElementDefinition, because Element::attributes() requires | 106 enqueueAttributeChangedCallbackForAllAttributes(element); |
98 // attribute synchronizations, and generally elements have more attributes | |
99 // than custom elements observe. | |
100 for (const auto& attribute : element->attributes()) { | |
101 if (hasAttributeChangedCallback(attribute.name())) | |
102 enqueueAttributeChangedCallback(element, attribute.name(), nullAtom,
attribute.value()); | |
103 } | |
104 | 107 |
105 if (element->inShadowIncludingDocument() && hasConnectedCallback()) | 108 if (element->inShadowIncludingDocument() && hasConnectedCallback()) |
106 enqueueConnectedCallback(element); | 109 enqueueConnectedCallback(element); |
107 | 110 |
108 m_constructionStack.append(element); | 111 m_constructionStack.append(element); |
109 size_t depth = m_constructionStack.size(); | 112 size_t depth = m_constructionStack.size(); |
110 | 113 |
111 bool succeeded = runConstructor(element); | 114 bool succeeded = runConstructor(element); |
112 | 115 |
113 // Pop the construction stack. | 116 // Pop the construction stack. |
114 if (m_constructionStack.last().get()) | 117 if (m_constructionStack.last().get()) |
115 DCHECK_EQ(m_constructionStack.last(), element); | 118 DCHECK_EQ(m_constructionStack.last(), element); |
116 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. | 119 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. |
117 m_constructionStack.removeLast(); | 120 m_constructionStack.removeLast(); |
118 | 121 |
119 if (!succeeded) | 122 if (!succeeded) |
120 return; | 123 return; |
121 | 124 |
122 CHECK(element->getCustomElementState() == CustomElementState::Custom); | 125 CHECK(element->getCustomElementState() == CustomElementState::Custom); |
123 } | 126 } |
124 | 127 |
| 128 bool CustomElementDefinition::hasAttributeChangedCallback( |
| 129 const QualifiedName& name) |
| 130 { |
| 131 return m_observedAttributes.contains(name.localName()); |
| 132 } |
| 133 |
125 static void enqueueReaction(Element* element, CustomElementReaction* reaction) | 134 static void enqueueReaction(Element* element, CustomElementReaction* reaction) |
126 { | 135 { |
127 // CEReactionsScope must be created by [CEReactions] in IDL, | 136 // CEReactionsScope must be created by [CEReactions] in IDL, |
128 // or callers must setup explicitly if it does not go through bindings. | 137 // or callers must setup explicitly if it does not go through bindings. |
129 DCHECK(CEReactionsScope::current()); | 138 DCHECK(CEReactionsScope::current()); |
130 CEReactionsScope::current()->enqueue(element, reaction); | 139 CEReactionsScope::current()->enqueue(element, reaction); |
131 } | 140 } |
132 | 141 |
133 void CustomElementDefinition::enqueueUpgradeReaction(Element* element) | 142 void CustomElementDefinition::enqueueUpgradeReaction(Element* element) |
134 { | 143 { |
(...skipping 10 matching lines...) Expand all Loading... |
145 enqueueReaction(element, new CustomElementDisconnectedCallbackReaction(this)
); | 154 enqueueReaction(element, new CustomElementDisconnectedCallbackReaction(this)
); |
146 } | 155 } |
147 | 156 |
148 void CustomElementDefinition::enqueueAttributeChangedCallback(Element* element, | 157 void CustomElementDefinition::enqueueAttributeChangedCallback(Element* element, |
149 const QualifiedName& name, | 158 const QualifiedName& name, |
150 const AtomicString& oldValue, const AtomicString& newValue) | 159 const AtomicString& oldValue, const AtomicString& newValue) |
151 { | 160 { |
152 enqueueReaction(element, new CustomElementAttributeChangedCallbackReaction(t
his, name, oldValue, newValue)); | 161 enqueueReaction(element, new CustomElementAttributeChangedCallbackReaction(t
his, name, oldValue, newValue)); |
153 } | 162 } |
154 | 163 |
| 164 void CustomElementDefinition::enqueueAttributeChangedCallbackForAllAttributes( |
| 165 Element* element) |
| 166 { |
| 167 // Avoid synchronizing all attributes unless it is needed, while enqueing |
| 168 // callbacks "in order" as defined in the spec. |
| 169 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-
element |
| 170 for (const AtomicString& name : m_observedAttributes) |
| 171 element->synchronizeAttribute(name); |
| 172 for (const auto& attribute : element->attributesWithoutUpdate()) { |
| 173 if (hasAttributeChangedCallback(attribute.name())) { |
| 174 enqueueAttributeChangedCallback(element, attribute.name(), |
| 175 nullAtom, attribute.value()); |
| 176 } |
| 177 } |
| 178 } |
| 179 |
155 } // namespace blink | 180 } // namespace blink |
OLD | NEW |