Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: Source/core/dom/CustomElementRegistrationContext.cpp

Issue 23009004: Process Custom Elements in post-order. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Patch for landing. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 if (!definition) 52 if (!definition)
53 return; 53 return;
54 54
55 // Upgrade elements that were waiting for this definition. 55 // Upgrade elements that were waiting for this definition.
56 const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_ca ndidates.takeUpgradeCandidatesFor(definition->descriptor()); 56 const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_ca ndidates.takeUpgradeCandidatesFor(definition->descriptor());
57 for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgra deCandidates.begin(); it != upgradeCandidates.end(); ++it) 57 for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgra deCandidates.begin(); it != upgradeCandidates.end(); ++it)
58 didResolveElement(definition, *it); 58 didResolveElement(definition, *it);
59 } 59 }
60 60
61 PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Doc ument* document, const QualifiedName& tagName) 61 PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Doc ument* document, const QualifiedName& tagName, CreationMode mode)
62 { 62 {
63 ASSERT(CustomElement::isCustomTagName(tagName.localName())); 63 ASSERT(CustomElement::isCustomTagName(tagName.localName()));
64 64
65 if (!document) 65 if (!document)
66 return 0; 66 return 0;
67 67
68 RefPtr<Element> element; 68 RefPtr<Element> element;
69 69
70 if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI()) { 70 if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI()) {
71 element = HTMLElement::create(tagName, document); 71 element = HTMLElement::create(tagName, document);
72 } else if (SVGNames::svgNamespaceURI == tagName.namespaceURI()) { 72 } else if (SVGNames::svgNamespaceURI == tagName.namespaceURI()) {
73 element = SVGUnknownElement::create(tagName, document); 73 element = SVGUnknownElement::create(tagName, document);
74 } else { 74 } else {
75 // XML elements are not custom elements, so return early. 75 // XML elements are not custom elements, so return early.
76 return Element::create(tagName, document); 76 return Element::create(tagName, document);
77 } 77 }
78 78
79 element->setCustomElementState(Element::WaitingForUpgrade); 79 element->setCustomElementState(mode == CreatedByParser ? Element::WaitingFor Parser : Element::WaitingForUpgrade);
80 resolve(element.get(), nullAtom); 80 resolve(element.get(), nullAtom);
81 return element.release(); 81 return element.release();
82 } 82 }
83 83
84 void CustomElementRegistrationContext::didGiveTypeExtension(Element* element, co nst AtomicString& type) 84 void CustomElementRegistrationContext::didGiveTypeExtension(Element* element, co nst AtomicString& type)
85 { 85 {
86 resolve(element, type); 86 resolve(element, type);
87 } 87 }
88 88
89 void CustomElementRegistrationContext::resolve(Element* element, const AtomicStr ing& typeExtension) 89 void CustomElementRegistrationContext::resolve(Element* element, const AtomicStr ing& typeExtension)
90 { 90 {
91 // If an element has a custom tag name it takes precedence over 91 // If an element has a custom tag name it takes precedence over
92 // the "is" attribute (if any). 92 // the "is" attribute (if any).
93 const AtomicString& type = CustomElement::isCustomTagName(element->localName ()) 93 const AtomicString& type = CustomElement::isCustomTagName(element->localName ())
94 ? element->localName() 94 ? element->localName()
95 : typeExtension; 95 : typeExtension;
96 ASSERT(!type.isNull()); 96 ASSERT(!type.isNull());
97 97
98 CustomElementDescriptor descriptor(type, element->namespaceURI(), element->l ocalName()); 98 CustomElementDescriptor descriptor(type, element->namespaceURI(), element->l ocalName());
99 CustomElementDefinition* definition = m_registry.find(descriptor); 99 CustomElementDefinition* definition = m_registry.find(descriptor);
100 if (definition) 100 if (definition)
101 didResolveElement(definition, element); 101 didResolveElement(definition, element);
102 else 102 else
103 didCreateUnresolvedElement(descriptor, element); 103 didCreateUnresolvedElement(descriptor, element);
104 } 104 }
105 105
106 void CustomElementRegistrationContext::didResolveElement(CustomElementDefinition * definition, Element* element) 106 void CustomElementRegistrationContext::didResolveElement(CustomElementDefinition * definition, Element* element)
107 { 107 {
108 CustomElement::define(element, definition); 108 CustomElement::define(element, definition);
109
110 switch (element->customElementState()) {
111 case Element::NotCustomElement:
112 case Element::Upgraded:
113 ASSERT_NOT_REACHED();
114 break;
115
116 case Element::WaitingForUpgrade:
117 CustomElementCallbackScheduler::scheduleCreatedCallback(definition->call backs(), element);
118 break;
119 }
120 } 109 }
121 110
122 void CustomElementRegistrationContext::didCreateUnresolvedElement(const CustomEl ementDescriptor& descriptor, Element* element) 111 void CustomElementRegistrationContext::didCreateUnresolvedElement(const CustomEl ementDescriptor& descriptor, Element* element)
123 { 112 {
124 ASSERT(element->customElementState() == Element::WaitingForUpgrade); 113 ASSERT(element->customElementState() == Element::WaitingForParser || element ->customElementState() == Element::WaitingForUpgrade);
125 m_candidates.add(descriptor, element); 114 m_candidates.add(descriptor, element);
126 } 115 }
127 116
128 void CustomElementRegistrationContext::customElementWasDestroyed(Element* elemen t)
129 {
130 m_candidates.remove(element);
131 }
132
133 PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::c reate() 117 PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::c reate()
134 { 118 {
135 return adoptRef(new CustomElementRegistrationContext()); 119 return adoptRef(new CustomElementRegistrationContext());
136 } 120 }
137 121
138 void CustomElementRegistrationContext::setIsAttributeAndTypeExtension(Element* e lement, const AtomicString& type) 122 void CustomElementRegistrationContext::setIsAttributeAndTypeExtension(Element* e lement, const AtomicString& type)
139 { 123 {
140 ASSERT(element); 124 ASSERT(element);
141 ASSERT(!type.isEmpty()); 125 ASSERT(!type.isEmpty());
142 element->setAttribute(HTMLNames::isAttr, type); 126 element->setAttribute(HTMLNames::isAttr, type);
143 setTypeExtension(element, type); 127 setTypeExtension(element, type);
144 } 128 }
145 129
146 void CustomElementRegistrationContext::setTypeExtension(Element* element, const AtomicString& type) 130 void CustomElementRegistrationContext::setTypeExtension(Element* element, const AtomicString& type, CreationMode mode)
147 { 131 {
148 if (!element->isHTMLElement() && !element->isSVGElement()) 132 if (!element->isHTMLElement() && !element->isSVGElement())
149 return; 133 return;
150 134
151 if (element->isCustomElement()) { 135 if (element->isCustomElement()) {
152 // This can happen if: 136 // This can happen if:
153 // 1. The element has a custom tag, which takes precedence over 137 // 1. The element has a custom tag, which takes precedence over
154 // type extensions. 138 // type extensions.
155 // 2. Undoing a command (eg ReplaceNodeWithSpan) recycles an 139 // 2. Undoing a command (eg ReplaceNodeWithSpan) recycles an
156 // element but tries to overwrite its attribute list. 140 // element but tries to overwrite its attribute list.
157 return; 141 return;
158 } 142 }
159 143
160 // Custom tags take precedence over type extensions 144 // Custom tags take precedence over type extensions
161 ASSERT(!CustomElement::isCustomTagName(element->localName())); 145 ASSERT(!CustomElement::isCustomTagName(element->localName()));
162 146
163 element->setCustomElementState(Element::WaitingForUpgrade); 147 element->setCustomElementState(mode == CreatedByParser ? Element::WaitingFor Parser : Element::WaitingForUpgrade);
164 148
165 if (CustomElementRegistrationContext* context = element->document()->registr ationContext()) 149 if (CustomElementRegistrationContext* context = element->document()->registr ationContext())
166 context->didGiveTypeExtension(element, type); 150 context->didGiveTypeExtension(element, type);
167 } 151 }
168 152
169 } // namespace WebCore 153 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/dom/CustomElementRegistrationContext.h ('k') | Source/core/dom/CustomElementUpgradeCandidateMap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698