| 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" | |
| 8 #include "core/dom/ExceptionCode.h" | 7 #include "core/dom/ExceptionCode.h" |
| 9 #include "core/dom/custom/CEReactionsScope.h" | 8 #include "core/dom/custom/CEReactionsScope.h" |
| 10 #include "core/dom/custom/CustomElement.h" | 9 #include "core/dom/custom/CustomElement.h" |
| 11 #include "core/dom/custom/CustomElementAttributeChangedCallbackReaction.h" | 10 #include "core/dom/custom/CustomElementAttributeChangedCallbackReaction.h" |
| 12 #include "core/dom/custom/CustomElementConnectedCallbackReaction.h" | 11 #include "core/dom/custom/CustomElementConnectedCallbackReaction.h" |
| 13 #include "core/dom/custom/CustomElementDisconnectedCallbackReaction.h" | 12 #include "core/dom/custom/CustomElementDisconnectedCallbackReaction.h" |
| 14 #include "core/dom/custom/CustomElementUpgradeReaction.h" | 13 #include "core/dom/custom/CustomElementUpgradeReaction.h" |
| 15 #include "core/html/HTMLElement.h" | 14 #include "core/html/HTMLElement.h" |
| 16 | 15 |
| 17 namespace blink { | 16 namespace blink { |
| 18 | 17 |
| 19 CustomElementDefinition::CustomElementDefinition( | 18 CustomElementDefinition::CustomElementDefinition( |
| 20 const CustomElementDescriptor& descriptor) | 19 const CustomElementDescriptor& descriptor) |
| 21 : m_descriptor(descriptor) | 20 : m_descriptor(descriptor) |
| 22 { | 21 { |
| 23 } | 22 } |
| 24 | 23 |
| 25 CustomElementDefinition::CustomElementDefinition( | |
| 26 const CustomElementDescriptor& descriptor, | |
| 27 const HashSet<AtomicString>& observedAttributes) | |
| 28 : m_observedAttributes(observedAttributes) | |
| 29 , m_descriptor(descriptor) | |
| 30 { | |
| 31 } | |
| 32 | |
| 33 CustomElementDefinition::~CustomElementDefinition() | 24 CustomElementDefinition::~CustomElementDefinition() |
| 34 { | 25 { |
| 35 } | 26 } |
| 36 | 27 |
| 37 DEFINE_TRACE(CustomElementDefinition) | 28 DEFINE_TRACE(CustomElementDefinition) |
| 38 { | 29 { |
| 39 visitor->trace(m_constructionStack); | 30 visitor->trace(m_constructionStack); |
| 40 } | 31 } |
| 41 | 32 |
| 42 static String errorMessageForConstructorResult(Element* element, | 33 static String errorMessageForConstructorResult(Element* element, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 element->setCustomElementState(CustomElementState::Undefined); | 86 element->setCustomElementState(CustomElementState::Undefined); |
| 96 // 6.2.2. Enqueue a custom element upgrade reaction given result and | 87 // 6.2.2. Enqueue a custom element upgrade reaction given result and |
| 97 // definition. | 88 // definition. |
| 98 enqueueUpgradeReaction(element); | 89 enqueueUpgradeReaction(element); |
| 99 return element; | 90 return element; |
| 100 } | 91 } |
| 101 | 92 |
| 102 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent | 93 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent |
| 103 void CustomElementDefinition::upgrade(Element* element) | 94 void CustomElementDefinition::upgrade(Element* element) |
| 104 { | 95 { |
| 105 if (!m_observedAttributes.isEmpty()) | 96 // TODO(kojii): This should be reversed by exposing observedAttributes from |
| 106 enqueueAttributeChangedCallbackForAllAttributes(element); | 97 // ScriptCustomElementDefinition, because Element::attributes() requires |
| 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 } |
| 107 | 104 |
| 108 if (element->inShadowIncludingDocument() && hasConnectedCallback()) | 105 if (element->inShadowIncludingDocument() && hasConnectedCallback()) |
| 109 enqueueConnectedCallback(element); | 106 enqueueConnectedCallback(element); |
| 110 | 107 |
| 111 m_constructionStack.append(element); | 108 m_constructionStack.append(element); |
| 112 size_t depth = m_constructionStack.size(); | 109 size_t depth = m_constructionStack.size(); |
| 113 | 110 |
| 114 bool succeeded = runConstructor(element); | 111 bool succeeded = runConstructor(element); |
| 115 | 112 |
| 116 // Pop the construction stack. | 113 // Pop the construction stack. |
| 117 if (m_constructionStack.last().get()) | 114 if (m_constructionStack.last().get()) |
| 118 DCHECK_EQ(m_constructionStack.last(), element); | 115 DCHECK_EQ(m_constructionStack.last(), element); |
| 119 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. | 116 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. |
| 120 m_constructionStack.removeLast(); | 117 m_constructionStack.removeLast(); |
| 121 | 118 |
| 122 if (!succeeded) | 119 if (!succeeded) |
| 123 return; | 120 return; |
| 124 | 121 |
| 125 CHECK(element->getCustomElementState() == CustomElementState::Custom); | 122 CHECK(element->getCustomElementState() == CustomElementState::Custom); |
| 126 } | 123 } |
| 127 | 124 |
| 128 bool CustomElementDefinition::hasAttributeChangedCallback( | |
| 129 const QualifiedName& name) | |
| 130 { | |
| 131 return m_observedAttributes.contains(name.localName()); | |
| 132 } | |
| 133 | |
| 134 static void enqueueReaction(Element* element, CustomElementReaction* reaction) | 125 static void enqueueReaction(Element* element, CustomElementReaction* reaction) |
| 135 { | 126 { |
| 136 // CEReactionsScope must be created by [CEReactions] in IDL, | 127 // CEReactionsScope must be created by [CEReactions] in IDL, |
| 137 // or callers must setup explicitly if it does not go through bindings. | 128 // or callers must setup explicitly if it does not go through bindings. |
| 138 DCHECK(CEReactionsScope::current()); | 129 DCHECK(CEReactionsScope::current()); |
| 139 CEReactionsScope::current()->enqueue(element, reaction); | 130 CEReactionsScope::current()->enqueue(element, reaction); |
| 140 } | 131 } |
| 141 | 132 |
| 142 void CustomElementDefinition::enqueueUpgradeReaction(Element* element) | 133 void CustomElementDefinition::enqueueUpgradeReaction(Element* element) |
| 143 { | 134 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 154 enqueueReaction(element, new CustomElementDisconnectedCallbackReaction(this)
); | 145 enqueueReaction(element, new CustomElementDisconnectedCallbackReaction(this)
); |
| 155 } | 146 } |
| 156 | 147 |
| 157 void CustomElementDefinition::enqueueAttributeChangedCallback(Element* element, | 148 void CustomElementDefinition::enqueueAttributeChangedCallback(Element* element, |
| 158 const QualifiedName& name, | 149 const QualifiedName& name, |
| 159 const AtomicString& oldValue, const AtomicString& newValue) | 150 const AtomicString& oldValue, const AtomicString& newValue) |
| 160 { | 151 { |
| 161 enqueueReaction(element, new CustomElementAttributeChangedCallbackReaction(t
his, name, oldValue, newValue)); | 152 enqueueReaction(element, new CustomElementAttributeChangedCallbackReaction(t
his, name, oldValue, newValue)); |
| 162 } | 153 } |
| 163 | 154 |
| 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 | |
| 180 } // namespace blink | 155 } // namespace blink |
| OLD | NEW |