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/CustomElementsRegistry.h" | 5 #include "core/dom/custom/CustomElementsRegistry.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
8 #include "bindings/core/v8/ScriptCustomElementDefinitionBuilder.h" | 8 #include "bindings/core/v8/ScriptCustomElementDefinitionBuilder.h" |
9 #include "bindings/core/v8/ScriptPromise.h" | |
10 #include "bindings/core/v8/ScriptPromiseResolver.h" | |
9 #include "core/dom/Document.h" | 11 #include "core/dom/Document.h" |
10 #include "core/dom/Element.h" | 12 #include "core/dom/Element.h" |
11 #include "core/dom/ElementRegistrationOptions.h" | 13 #include "core/dom/ElementRegistrationOptions.h" |
12 #include "core/dom/ExceptionCode.h" | 14 #include "core/dom/ExceptionCode.h" |
13 #include "core/dom/custom/CEReactionsScope.h" | 15 #include "core/dom/custom/CEReactionsScope.h" |
14 #include "core/dom/custom/CustomElement.h" | 16 #include "core/dom/custom/CustomElement.h" |
15 #include "core/dom/custom/CustomElementDefinition.h" | 17 #include "core/dom/custom/CustomElementDefinition.h" |
16 #include "core/dom/custom/CustomElementDefinitionBuilder.h" | 18 #include "core/dom/custom/CustomElementDefinitionBuilder.h" |
17 #include "core/dom/custom/CustomElementDescriptor.h" | 19 #include "core/dom/custom/CustomElementDescriptor.h" |
18 #include "core/dom/custom/CustomElementUpgradeReaction.h" | 20 #include "core/dom/custom/CustomElementUpgradeReaction.h" |
19 #include "core/dom/custom/CustomElementUpgradeSorter.h" | 21 #include "core/dom/custom/CustomElementUpgradeSorter.h" |
20 #include "core/dom/custom/V0CustomElementRegistrationContext.h" | 22 #include "core/dom/custom/V0CustomElementRegistrationContext.h" |
21 #include "wtf/Allocator.h" | 23 #include "wtf/Allocator.h" |
22 | 24 |
23 namespace blink { | 25 namespace blink { |
24 | 26 |
27 namespace { | |
28 // Returns true if |name| is invalid. | |
29 bool throwIfInvalidName( | |
30 const AtomicString& name, | |
31 ExceptionState& exceptionState) | |
32 { | |
33 if (CustomElement::isValidName(name)) | |
34 return false; | |
35 exceptionState.throwDOMException( | |
36 SyntaxError, | |
37 "\"" + name + "\" is not a valid custom element name"); | |
38 return true; | |
39 } | |
40 } // namespace | |
dominicc (has gone to gerrit)
2016/06/10 06:20:57
Blank lines before }, after namespace { maybe? Tha
yosin_UTC9
2016/06/10 07:52:28
Done.
Use static function instead of anonymous nam
| |
41 | |
25 class CustomElementsRegistry::NameIsBeingDefined final { | 42 class CustomElementsRegistry::NameIsBeingDefined final { |
26 STACK_ALLOCATED(); | 43 STACK_ALLOCATED(); |
27 DISALLOW_IMPLICIT_CONSTRUCTORS(NameIsBeingDefined); | 44 DISALLOW_IMPLICIT_CONSTRUCTORS(NameIsBeingDefined); |
28 public: | 45 public: |
29 NameIsBeingDefined( | 46 NameIsBeingDefined( |
30 CustomElementsRegistry* registry, | 47 CustomElementsRegistry* registry, |
31 const AtomicString& name) | 48 const AtomicString& name) |
32 : m_registry(registry) | 49 : m_registry(registry) |
33 , m_name(name) | 50 , m_name(name) |
34 { | 51 { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 // http://w3c.github.io/webcomponents/spec/custom/#dfn-element-definition | 103 // http://w3c.github.io/webcomponents/spec/custom/#dfn-element-definition |
87 void CustomElementsRegistry::define( | 104 void CustomElementsRegistry::define( |
88 const AtomicString& name, | 105 const AtomicString& name, |
89 CustomElementDefinitionBuilder& builder, | 106 CustomElementDefinitionBuilder& builder, |
90 const ElementRegistrationOptions& options, | 107 const ElementRegistrationOptions& options, |
91 ExceptionState& exceptionState) | 108 ExceptionState& exceptionState) |
92 { | 109 { |
93 if (!builder.checkConstructorIntrinsics()) | 110 if (!builder.checkConstructorIntrinsics()) |
94 return; | 111 return; |
95 | 112 |
96 if (!CustomElement::isValidName(name)) { | 113 if (throwIfInvalidName(name, exceptionState)) |
97 exceptionState.throwDOMException( | |
98 SyntaxError, | |
99 "\"" + name + "\" is not a valid custom element name"); | |
100 return; | 114 return; |
101 } | |
102 | 115 |
103 if (m_namesBeingDefined.contains(name)) { | 116 if (m_namesBeingDefined.contains(name)) { |
104 exceptionState.throwDOMException( | 117 exceptionState.throwDOMException( |
105 NotSupportedError, | 118 NotSupportedError, |
106 "this name is already being defined in this registry"); | 119 "this name is already being defined in this registry"); |
107 return; | 120 return; |
108 } | 121 } |
109 NameIsBeingDefined defining(this, name); | 122 NameIsBeingDefined defining(this, name); |
110 | 123 |
111 if (nameIsDefined(name) || v0NameIsDefined(name)) { | 124 if (nameIsDefined(name) || v0NameIsDefined(name)) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 CHECK(definition->descriptor() == descriptor); | 162 CHECK(definition->descriptor() == descriptor); |
150 DefinitionMap::AddResult result = | 163 DefinitionMap::AddResult result = |
151 m_definitions.add(descriptor.name(), definition); | 164 m_definitions.add(descriptor.name(), definition); |
152 CHECK(result.isNewEntry); | 165 CHECK(result.isNewEntry); |
153 | 166 |
154 HeapVector<Member<Element>> candidates; | 167 HeapVector<Member<Element>> candidates; |
155 collectCandidates(descriptor, &candidates); | 168 collectCandidates(descriptor, &candidates); |
156 for (Element* candidate : candidates) | 169 for (Element* candidate : candidates) |
157 CustomElement::enqueueUpgradeReaction(candidate, definition); | 170 CustomElement::enqueueUpgradeReaction(candidate, definition); |
158 | 171 |
159 // TODO(dominicc): Implement steps: | 172 // 19: when-defined promise processing |
160 // 20: when-defined promise processing | 173 const auto& entry = m_whenDefinedPromiseMap.find(name); |
174 if (entry == m_whenDefinedPromiseMap.end()) | |
175 return; | |
176 entry->value->resolve(); | |
177 m_whenDefinedPromiseMap.remove(entry); | |
161 } | 178 } |
162 | 179 |
163 // https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregis try-get | 180 // https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregis try-get |
164 ScriptValue CustomElementsRegistry::get(const AtomicString& name) | 181 ScriptValue CustomElementsRegistry::get(const AtomicString& name) |
165 { | 182 { |
166 CustomElementDefinition* definition = definitionForName(name); | 183 CustomElementDefinition* definition = definitionForName(name); |
167 if (!definition) { | 184 if (!definition) { |
168 // Binding layer converts |ScriptValue()| to script specific value, | 185 // Binding layer converts |ScriptValue()| to script specific value, |
169 // e.g. |undefined| for v8. | 186 // e.g. |undefined| for v8. |
170 return ScriptValue(); | 187 return ScriptValue(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 if (it != m_upgradeCandidates->end()) { | 222 if (it != m_upgradeCandidates->end()) { |
206 set = it->value; | 223 set = it->value; |
207 } else { | 224 } else { |
208 set = m_upgradeCandidates->add(name, new UpgradeCandidateSet()) | 225 set = m_upgradeCandidates->add(name, new UpgradeCandidateSet()) |
209 .storedValue | 226 .storedValue |
210 ->value; | 227 ->value; |
211 } | 228 } |
212 set->add(candidate); | 229 set->add(candidate); |
213 } | 230 } |
214 | 231 |
232 // https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregis try-whendefined | |
233 ScriptPromise CustomElementsRegistry::whenDefined( | |
234 ScriptState* scriptState, | |
235 const AtomicString& name, | |
236 ExceptionState& exceptionState) | |
237 { | |
238 if (throwIfInvalidName(name, exceptionState)) | |
239 return ScriptPromise(); | |
240 CustomElementDefinition* definition = definitionForName(name); | |
241 if (definition) | |
242 return ScriptPromise::castUndefined(scriptState); | |
243 ScriptPromiseResolver* resolver = m_whenDefinedPromiseMap.get(name); | |
244 if (resolver) | |
245 return resolver->promise(); | |
246 ScriptPromiseResolver* newResolver = | |
247 ScriptPromiseResolver::create(scriptState); | |
248 m_whenDefinedPromiseMap.add(name, newResolver); | |
249 return newResolver->promise(); | |
250 } | |
251 | |
215 void CustomElementsRegistry::collectCandidates( | 252 void CustomElementsRegistry::collectCandidates( |
216 const CustomElementDescriptor& desc, | 253 const CustomElementDescriptor& desc, |
217 HeapVector<Member<Element>>* elements) | 254 HeapVector<Member<Element>>* elements) |
218 { | 255 { |
219 UpgradeCandidateMap::iterator it = m_upgradeCandidates->find(desc.name()); | 256 UpgradeCandidateMap::iterator it = m_upgradeCandidates->find(desc.name()); |
220 if (it == m_upgradeCandidates->end()) | 257 if (it == m_upgradeCandidates->end()) |
221 return; | 258 return; |
222 CustomElementUpgradeSorter sorter; | 259 CustomElementUpgradeSorter sorter; |
223 for (Element* element : *it.get()->value) { | 260 for (Element* element : *it.get()->value) { |
224 if (!element || !desc.matches(*element)) | 261 if (!element || !desc.matches(*element)) |
225 continue; | 262 continue; |
226 sorter.add(element); | 263 sorter.add(element); |
227 } | 264 } |
228 | 265 |
229 m_upgradeCandidates->remove(it); | 266 m_upgradeCandidates->remove(it); |
230 sorter.sorted(elements, m_document.get()); | 267 sorter.sorted(elements, m_document.get()); |
231 } | 268 } |
232 | 269 |
233 } // namespace blink | 270 } // namespace blink |
OLD | NEW |