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/Attr.h" |
8 #include "core/dom/ExceptionCode.h" | 8 #include "core/dom/ExceptionCode.h" |
9 #include "core/dom/custom/CustomElement.h" | 9 #include "core/dom/custom/CustomElement.h" |
10 #include "core/dom/custom/CustomElementAdoptedCallbackReaction.h" | 10 #include "core/dom/custom/CustomElementAdoptedCallbackReaction.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 exceptionState.throwTypeError("The result must implement HTMLElement int
erface"); | 77 exceptionState.throwTypeError("The result must implement HTMLElement int
erface"); |
78 return; | 78 return; |
79 } | 79 } |
80 | 80 |
81 // 6.1.4. through 6.1.9. | 81 // 6.1.4. through 6.1.9. |
82 const String message = errorMessageForConstructorResult(element, document, t
agName); | 82 const String message = errorMessageForConstructorResult(element, document, t
agName); |
83 if (!message.isEmpty()) | 83 if (!message.isEmpty()) |
84 exceptionState.throwDOMException(NotSupportedError, message); | 84 exceptionState.throwDOMException(NotSupportedError, message); |
85 } | 85 } |
86 | 86 |
| 87 HTMLElement* CustomElementDefinition::createElementForConstructor( |
| 88 Document& document) |
| 89 { |
| 90 // TODO(kojii): When HTMLElementFactory has an option not to queue |
| 91 // upgrade, call that instead of HTMLElement. HTMLElement is enough |
| 92 // for now, but type extension will require HTMLElementFactory. |
| 93 HTMLElement* element = HTMLElement::create( |
| 94 QualifiedName(nullAtom, descriptor().localName(), |
| 95 HTMLNames::xhtmlNamespaceURI), |
| 96 document); |
| 97 // TODO(davaajav): write this as one call to setCustomElementState instead o
f two |
| 98 element->setCustomElementState(CustomElementState::Undefined); |
| 99 element->setCustomElementDefinition(this); |
| 100 return element; |
| 101 } |
| 102 |
87 HTMLElement* CustomElementDefinition::createElementAsync(Document& document, con
st QualifiedName& tagName) | 103 HTMLElement* CustomElementDefinition::createElementAsync(Document& document, con
st QualifiedName& tagName) |
88 { | 104 { |
89 // https://dom.spec.whatwg.org/#concept-create-element | 105 // https://dom.spec.whatwg.org/#concept-create-element |
90 // 6. If definition is non-null, then: | 106 // 6. If definition is non-null, then: |
91 // 6.2. If the synchronous custom elements flag is not set: | 107 // 6.2. If the synchronous custom elements flag is not set: |
92 // 6.2.1. Set result to a new element that implements the HTMLElement | 108 // 6.2.1. Set result to a new element that implements the HTMLElement |
93 // interface, with no attributes, namespace set to the HTML namespace, | 109 // interface, with no attributes, namespace set to the HTML namespace, |
94 // namespace prefix set to prefix, local name set to localName, custom | 110 // namespace prefix set to prefix, local name set to localName, custom |
95 // element state set to "undefined", and node document set to document. | 111 // element state set to "undefined", and node document set to document. |
96 HTMLElement* element = HTMLElement::create(tagName, document); | 112 HTMLElement* element = HTMLElement::create(tagName, document); |
97 element->setCustomElementState(CustomElementState::Undefined); | 113 element->setCustomElementState(CustomElementState::Undefined); |
98 // 6.2.2. Enqueue a custom element upgrade reaction given result and | 114 // 6.2.2. Enqueue a custom element upgrade reaction given result and |
99 // definition. | 115 // definition. |
100 enqueueUpgradeReaction(element); | 116 enqueueUpgradeReaction(element); |
101 return element; | 117 return element; |
102 } | 118 } |
103 | 119 |
| 120 CustomElementDefinition::ConstructionStackScope::ConstructionStackScope( |
| 121 CustomElementDefinition* definition, Element* element) |
| 122 : m_constructionStack(definition->m_constructionStack) |
| 123 , m_element(element) |
| 124 { |
| 125 // Push the construction stack. |
| 126 m_constructionStack.append(element); |
| 127 m_depth = m_constructionStack.size(); |
| 128 } |
| 129 |
| 130 CustomElementDefinition::ConstructionStackScope::~ConstructionStackScope() |
| 131 { |
| 132 // Pop the construction stack. |
| 133 if (m_constructionStack.last().get()) |
| 134 DCHECK_EQ(m_constructionStack.last(), m_element); |
| 135 DCHECK_EQ(m_constructionStack.size(), m_depth); // It's a *stack*. |
| 136 m_constructionStack.removeLast(); |
| 137 } |
| 138 |
104 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent | 139 // https://html.spec.whatwg.org/multipage/scripting.html#concept-upgrade-an-elem
ent |
105 void CustomElementDefinition::upgrade(Element* element) | 140 void CustomElementDefinition::upgrade(Element* element) |
106 { | 141 { |
107 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Undefined); | 142 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Undefined); |
108 | 143 |
109 if (!m_observedAttributes.isEmpty()) | 144 if (!m_observedAttributes.isEmpty()) |
110 enqueueAttributeChangedCallbackForAllAttributes(element); | 145 enqueueAttributeChangedCallbackForAllAttributes(element); |
111 | 146 |
112 if (element->isConnected() && hasConnectedCallback()) | 147 if (element->isConnected() && hasConnectedCallback()) |
113 enqueueConnectedCallback(element); | 148 enqueueConnectedCallback(element); |
114 | 149 |
115 m_constructionStack.append(element); | 150 bool succeeded = false; |
116 size_t depth = m_constructionStack.size(); | 151 { |
117 | 152 ConstructionStackScope constructionStackScope(this, element); |
118 bool succeeded = runConstructor(element); | 153 succeeded = runConstructor(element); |
119 | 154 } |
120 // Pop the construction stack. | |
121 if (m_constructionStack.last().get()) | |
122 DCHECK_EQ(m_constructionStack.last(), element); | |
123 DCHECK_EQ(m_constructionStack.size(), depth); // It's a *stack*. | |
124 m_constructionStack.removeLast(); | |
125 | |
126 if (!succeeded) { | 155 if (!succeeded) { |
127 element->setCustomElementState(CustomElementState::Failed); | 156 element->setCustomElementState(CustomElementState::Failed); |
128 return; | 157 return; |
129 } | 158 } |
130 | 159 |
131 element->setCustomElementDefinition(this); | 160 element->setCustomElementDefinition(this); |
132 } | 161 } |
133 | 162 |
134 bool CustomElementDefinition::hasAttributeChangedCallback( | 163 bool CustomElementDefinition::hasAttributeChangedCallback( |
135 const QualifiedName& name) const | 164 const QualifiedName& name) const |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 element->synchronizeAttribute(name); | 214 element->synchronizeAttribute(name); |
186 for (const auto& attribute : element->attributesWithoutUpdate()) { | 215 for (const auto& attribute : element->attributesWithoutUpdate()) { |
187 if (hasAttributeChangedCallback(attribute.name())) { | 216 if (hasAttributeChangedCallback(attribute.name())) { |
188 enqueueAttributeChangedCallback(element, attribute.name(), | 217 enqueueAttributeChangedCallback(element, attribute.name(), |
189 nullAtom, attribute.value()); | 218 nullAtom, attribute.value()); |
190 } | 219 } |
191 } | 220 } |
192 } | 221 } |
193 | 222 |
194 } // namespace blink | 223 } // namespace blink |
OLD | NEW |