OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 #include "HTMLNames.h" | 35 #include "HTMLNames.h" |
36 #include "RuntimeEnabledFeatures.h" | 36 #include "RuntimeEnabledFeatures.h" |
37 #include "bindings/v8/CustomElementHelpers.h" | 37 #include "bindings/v8/CustomElementHelpers.h" |
38 #include "bindings/v8/Dictionary.h" | 38 #include "bindings/v8/Dictionary.h" |
39 #include "bindings/v8/ScriptValue.h" | 39 #include "bindings/v8/ScriptValue.h" |
40 #include "core/dom/CustomElementDefinition.h" | 40 #include "core/dom/CustomElementDefinition.h" |
41 #include "core/dom/Document.h" | 41 #include "core/dom/Document.h" |
42 #include "core/dom/Element.h" | 42 #include "core/dom/Element.h" |
43 #include "core/html/HTMLElement.h" | 43 #include "core/html/HTMLElement.h" |
44 #include <wtf/HashSet.h> | |
45 | 44 |
46 #if ENABLE(SVG) | 45 #if ENABLE(SVG) |
47 #include "SVGNames.h" | 46 #include "SVGNames.h" |
48 #include "core/svg/SVGElement.h" | 47 #include "core/svg/SVGElement.h" |
49 #endif | 48 #endif |
50 | 49 |
51 namespace WebCore { | 50 namespace WebCore { |
52 | 51 |
53 CustomElementInvocation::CustomElementInvocation(PassRefPtr<Element> element) | 52 CustomElementInvocation::CustomElementInvocation(PassRefPtr<Element> element) |
54 : m_element(element) | 53 : m_element(element) |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 RefPtr<CustomElementDefinition> definition = CustomElementDefinition::create
(state, type, name, namespaceURI, prototypeValue); | 159 RefPtr<CustomElementDefinition> definition = CustomElementDefinition::create
(state, type, name, namespaceURI, prototypeValue); |
161 | 160 |
162 RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::cre
ate(document(), definition->tagQName(), definition->isTypeExtension() ? definiti
on->type() : nullAtom); | 161 RefPtr<CustomElementConstructor> constructor = CustomElementConstructor::cre
ate(document(), definition->tagQName(), definition->isTypeExtension() ? definiti
on->type() : nullAtom); |
163 if (!CustomElementHelpers::initializeConstructorWrapper(constructor.get(), p
rototypeValue, state)) { | 162 if (!CustomElementHelpers::initializeConstructorWrapper(constructor.get(), p
rototypeValue, state)) { |
164 ec = INVALID_STATE_ERR; | 163 ec = INVALID_STATE_ERR; |
165 return 0; | 164 return 0; |
166 } | 165 } |
167 | 166 |
168 m_definitions.add(definition->type(), definition); | 167 m_definitions.add(definition->type(), definition); |
169 | 168 |
| 169 // Upgrade elements that were waiting for this definition. |
| 170 CustomElementUpgradeCandidateMap::ElementSet upgradeCandidates = m_candidate
s.takeUpgradeCandidatesFor(definition.get()); |
| 171 CustomElementHelpers::upgradeWrappers(document(), upgradeCandidates, definit
ion->prototype()); |
| 172 for (CustomElementUpgradeCandidateMap::ElementSet::iterator it = upgradeCand
idates.begin(); it != upgradeCandidates.end(); ++it) { |
| 173 (*it)->setNeedsStyleRecalc(); // :unresolved has changed |
| 174 activate(CustomElementInvocation(*it)); |
| 175 } |
| 176 |
170 return constructor.release(); | 177 return constructor.release(); |
171 } | 178 } |
172 | 179 |
173 bool CustomElementRegistry::isUnresolved(Element* element) const | 180 bool CustomElementRegistry::isUnresolved(Element* element) const |
174 { | 181 { |
175 return m_unresolvedElements.contains(element); | 182 return m_candidates.contains(element); |
176 } | 183 } |
177 | 184 |
178 PassRefPtr<CustomElementDefinition> CustomElementRegistry::findFor(Element* elem
ent) const | 185 PassRefPtr<CustomElementDefinition> CustomElementRegistry::findFor(Element* elem
ent) const |
179 { | 186 { |
180 ASSERT(element->document()->registry() == this); | 187 ASSERT(element->document()->registry() == this); |
181 | 188 |
182 if (!element->isCustomElement()) | 189 if (!element->isCustomElement()) |
183 return 0; | 190 return 0; |
184 | 191 |
185 // When a custom tag and a type extension are provided as element | 192 // When a custom tag and a type extension are provided as element |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 #endif | 234 #endif |
228 else | 235 else |
229 return Element::create(tagName, document()); | 236 return Element::create(tagName, document()); |
230 | 237 |
231 element->setIsCustomElement(); | 238 element->setIsCustomElement(); |
232 | 239 |
233 RefPtr<CustomElementDefinition> definition = findAndCheckNamespace(tagName.l
ocalName(), tagName.namespaceURI()); | 240 RefPtr<CustomElementDefinition> definition = findAndCheckNamespace(tagName.l
ocalName(), tagName.namespaceURI()); |
234 if (!definition || definition->isTypeExtension()) { | 241 if (!definition || definition->isTypeExtension()) { |
235 // If a definition for a type extension was available, this | 242 // If a definition for a type extension was available, this |
236 // custom tag element will be unresolved in perpetuity. | 243 // custom tag element will be unresolved in perpetuity. |
237 didCreateUnresolvedElement(element.get()); | 244 didCreateUnresolvedElement(CustomElementDefinition::CustomTag, tagName.l
ocalName(), element.get()); |
238 } else { | 245 } else { |
239 didCreateCustomTagElement(element.get()); | 246 didCreateCustomTagElement(element.get()); |
240 } | 247 } |
241 | 248 |
242 return element.release(); | 249 return element.release(); |
243 } | 250 } |
244 | 251 |
245 void CustomElementRegistry::didGiveTypeExtension(Element* element) | 252 void CustomElementRegistry::didGiveTypeExtension(Element* element, const AtomicS
tring& type) |
246 { | 253 { |
247 if (!element->isHTMLElement() && !element->isSVGElement()) | 254 if (!element->isHTMLElement() && !element->isSVGElement()) |
248 return; | 255 return; |
249 element->setIsCustomElement(); | 256 element->setIsCustomElement(); |
250 RefPtr<CustomElementDefinition> definition = findFor(element); | 257 RefPtr<CustomElementDefinition> definition = findFor(element); |
251 if (!definition || !definition->isTypeExtension()) { | 258 if (!definition || !definition->isTypeExtension()) { |
252 // If a definition for a custom tag was available, this type | 259 // If a definition for a custom tag was available, this type |
253 // extension element will be unresolved in perpetuity. | 260 // extension element will be unresolved in perpetuity. |
254 didCreateUnresolvedElement(element); | 261 didCreateUnresolvedElement(CustomElementDefinition::TypeExtension, type,
element); |
255 } else { | 262 } else { |
256 activate(CustomElementInvocation(element)); | 263 activate(CustomElementInvocation(element)); |
257 } | 264 } |
258 } | 265 } |
259 | 266 |
260 void CustomElementRegistry::didCreateCustomTagElement(Element* element) | 267 void CustomElementRegistry::didCreateCustomTagElement(Element* element) |
261 { | 268 { |
262 activate(CustomElementInvocation(element)); | 269 activate(CustomElementInvocation(element)); |
263 } | 270 } |
264 | 271 |
265 void CustomElementRegistry::didCreateUnresolvedElement(Element* element) | 272 void CustomElementRegistry::didCreateUnresolvedElement(CustomElementDefinition::
CustomElementKind kind, const AtomicString& type, Element* element) |
266 { | 273 { |
267 m_unresolvedElements.add(element); | 274 m_candidates.add(kind, type, element); |
268 } | 275 } |
269 | 276 |
270 void CustomElementRegistry::customElementWasDestroyed(Element* element) | 277 void CustomElementRegistry::customElementWasDestroyed(Element* element) |
271 { | 278 { |
272 ASSERT(element->isCustomElement()); | 279 ASSERT(element->isCustomElement()); |
273 m_unresolvedElements.remove(element); | 280 m_candidates.remove(element); |
274 } | 281 } |
275 | 282 |
276 void CustomElementRegistry::activate(const CustomElementInvocation& invocation) | 283 void CustomElementRegistry::activate(const CustomElementInvocation& invocation) |
277 { | 284 { |
278 bool wasInactive = m_invocations.isEmpty(); | 285 bool wasInactive = m_invocations.isEmpty(); |
279 m_invocations.append(invocation); | 286 m_invocations.append(invocation); |
280 if (wasInactive) | 287 if (wasInactive) |
281 activeCustomElementRegistries().add(this); | 288 activeCustomElementRegistries().add(this); |
282 } | 289 } |
283 | 290 |
(...skipping 28 matching lines...) Expand all Loading... |
312 while (!activeCustomElementRegistries().isEmpty()) { | 319 while (!activeCustomElementRegistries().isEmpty()) { |
313 Vector<RefPtr<CustomElementRegistry> > registries; | 320 Vector<RefPtr<CustomElementRegistry> > registries; |
314 copyToVector(activeCustomElementRegistries(), registries); | 321 copyToVector(activeCustomElementRegistries(), registries); |
315 activeCustomElementRegistries().clear(); | 322 activeCustomElementRegistries().clear(); |
316 for (size_t i = 0; i < registries.size(); ++i) | 323 for (size_t i = 0; i < registries.size(); ++i) |
317 registries[i]->deliverLifecycleCallbacks(); | 324 registries[i]->deliverLifecycleCallbacks(); |
318 } | 325 } |
319 } | 326 } |
320 | 327 |
321 } | 328 } |
OLD | NEW |