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 "bindings/core/v8/ScriptCustomElementDefinition.h" | 5 #include "bindings/core/v8/ScriptCustomElementDefinition.h" |
6 | 6 |
7 #include "bindings/core/v8/ScriptState.h" | 7 #include "bindings/core/v8/ScriptState.h" |
8 #include "bindings/core/v8/V8Binding.h" | 8 #include "bindings/core/v8/V8Binding.h" |
9 #include "bindings/core/v8/V8BindingMacros.h" | 9 #include "bindings/core/v8/V8BindingMacros.h" |
10 #include "bindings/core/v8/V8CustomElementRegistry.h" | 10 #include "bindings/core/v8/V8CustomElementRegistry.h" |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
144 const v8::Local<v8::Object>& prototype, | 144 const v8::Local<v8::Object>& prototype, |
145 const v8::Local<v8::Function>& connectedCallback, | 145 const v8::Local<v8::Function>& connectedCallback, |
146 const v8::Local<v8::Function>& disconnectedCallback, | 146 const v8::Local<v8::Function>& disconnectedCallback, |
147 const v8::Local<v8::Function>& adoptedCallback, | 147 const v8::Local<v8::Function>& adoptedCallback, |
148 const v8::Local<v8::Function>& attributeChangedCallback, | 148 const v8::Local<v8::Function>& attributeChangedCallback, |
149 const HashSet<AtomicString>& observedAttributes) | 149 const HashSet<AtomicString>& observedAttributes) |
150 : CustomElementDefinition(descriptor, observedAttributes), | 150 : CustomElementDefinition(descriptor, observedAttributes), |
151 m_scriptState(scriptState), | 151 m_scriptState(scriptState), |
152 m_constructor(scriptState->isolate(), constructor) {} | 152 m_constructor(scriptState->isolate(), constructor) {} |
153 | 153 |
154 static void dispatchErrorEvent(v8::Isolate* isolate, | |
155 v8::Local<v8::Value> exception, | |
156 v8::Local<v8::Object> constructor) { | |
157 v8::TryCatch tryCatch(isolate); | |
158 tryCatch.SetVerbose(true); | |
159 V8ScriptRunner::throwException( | |
160 isolate, exception, constructor.As<v8::Function>()->GetScriptOrigin()); | |
161 } | |
162 | |
163 HTMLElement* ScriptCustomElementDefinition::handleCreateElementSyncException( | |
haraken
2016/10/23 22:49:20
Do you know why the spec requires to throw the exc
dominicc (has gone to gerrit)
2016/10/24 01:15:05
What in particular is the problem?
Re: the spec--
| |
164 Document& document, | |
165 const QualifiedName& tagName, | |
166 v8::Isolate* isolate, | |
167 ExceptionState& exceptionState) { | |
168 DCHECK(exceptionState.hadException()); | |
169 // 6.1."If any of these subsubsteps threw an exception".1 | |
170 // Report the exception. | |
171 dispatchErrorEvent(isolate, exceptionState.getException(), constructor()); | |
172 exceptionState.clearException(); | |
173 // ... .2 Return HTMLUnknownElement. | |
174 return CustomElement::createFailedElement(document, tagName); | |
175 } | |
176 | |
154 HTMLElement* ScriptCustomElementDefinition::createElementSync( | 177 HTMLElement* ScriptCustomElementDefinition::createElementSync( |
155 Document& document, | 178 Document& document, |
156 const QualifiedName& tagName, | 179 const QualifiedName& tagName) { |
157 ExceptionState& exceptionState) { | 180 ScriptState::Scope scope(m_scriptState.get()); |
haraken
2016/10/23 22:49:19
Don't you need to check:
if (!m_scriptState->co
dominicc (has gone to gerrit)
2016/10/24 01:15:05
Good catch, ty, fixed.
| |
158 DCHECK(ScriptState::current(m_scriptState->isolate()) == m_scriptState); | 181 v8::Isolate* isolate = m_scriptState->isolate(); |
159 | 182 |
160 // Create an element | 183 ExceptionState exceptionState(ExceptionState::ConstructionContext, |
184 "CustomElement", constructor(), isolate); | |
185 | |
186 // Create an element with the synchronous custom elements flag set. | |
161 // https://dom.spec.whatwg.org/#concept-create-element | 187 // https://dom.spec.whatwg.org/#concept-create-element |
162 // 6. If definition is non-null | |
163 // 6.1. If the synchronous custom elements flag is set: | |
164 // 6.1.2. Set result to Construct(C). Rethrow any exceptions. | |
165 | 188 |
166 // Create an element and push to the construction stack. | 189 // Create an element and push to the construction stack. |
167 // V8HTMLElement::constructorCustom() can only refer to | 190 // V8HTMLElement::constructorCustom() can only refer to |
168 // window.document(), but it is different from the document here | 191 // window.document(), but it is different from the document here |
169 // when it is an import document. This is not exactly what the | 192 // when it is an import document. This is not exactly what the |
170 // spec defines, but the public behavior matches to the spec. | 193 // spec defines, but the non-imports behavior matches to the spec. |
171 Element* element = createElementForConstructor(document); | 194 Element* element = createElementForConstructor(document); |
172 { | 195 { |
173 ConstructionStackScope constructionStackScope(this, element); | 196 ConstructionStackScope constructionStackScope(this, element); |
174 v8::TryCatch tryCatch(m_scriptState->isolate()); | 197 v8::TryCatch tryCatch(m_scriptState->isolate()); |
175 element = runConstructor(); | 198 element = runConstructor(); |
176 if (tryCatch.HasCaught()) { | 199 if (tryCatch.HasCaught()) { |
177 exceptionState.rethrowV8Exception(tryCatch.Exception()); | 200 exceptionState.rethrowV8Exception(tryCatch.Exception()); |
178 return nullptr; | 201 return handleCreateElementSyncException(document, tagName, isolate, |
202 exceptionState); | |
179 } | 203 } |
180 } | 204 } |
181 | 205 |
182 // 6.1.3. through 6.1.9. | 206 // 6.1.3. through 6.1.9. |
183 checkConstructorResult(element, document, tagName, exceptionState); | 207 checkConstructorResult(element, document, tagName, exceptionState); |
184 if (exceptionState.hadException()) | 208 if (exceptionState.hadException()) { |
185 return nullptr; | 209 return handleCreateElementSyncException(document, tagName, isolate, |
186 | 210 exceptionState); |
211 } | |
187 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom); | 212 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom); |
188 return toHTMLElement(element); | 213 return toHTMLElement(element); |
189 } | 214 } |
190 | 215 |
191 static void dispatchErrorEvent(v8::Isolate* isolate, | |
192 v8::Local<v8::Value> exception, | |
193 v8::Local<v8::Object> constructor) { | |
194 v8::TryCatch tryCatch(isolate); | |
195 tryCatch.SetVerbose(true); | |
196 V8ScriptRunner::throwException( | |
197 isolate, exception, constructor.As<v8::Function>()->GetScriptOrigin()); | |
198 } | |
199 | |
200 HTMLElement* ScriptCustomElementDefinition::createElementSync( | |
201 Document& document, | |
202 const QualifiedName& tagName) { | |
203 ScriptState::Scope scope(m_scriptState.get()); | |
204 v8::Isolate* isolate = m_scriptState->isolate(); | |
205 | |
206 // When invoked from "create an element for a token": | |
207 // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-th e-token | |
208 | |
209 ExceptionState exceptionState(ExceptionState::ConstructionContext, | |
210 "CustomElement", constructor(), isolate); | |
211 HTMLElement* element = createElementSync(document, tagName, exceptionState); | |
212 | |
213 if (exceptionState.hadException()) { | |
214 DCHECK(!element); | |
215 // 7. If this step throws an exception, then report the exception, ... | |
216 dispatchErrorEvent(isolate, exceptionState.getException(), constructor()); | |
217 exceptionState.clearException(); | |
218 // and return HTMLUnknownElement. | |
219 return CustomElement::createFailedElement(document, tagName); | |
220 } | |
221 DCHECK(element); | |
222 return element; | |
223 } | |
224 | |
225 // https://html.spec.whatwg.org/multipage/scripting.html#upgrades | 216 // https://html.spec.whatwg.org/multipage/scripting.html#upgrades |
226 bool ScriptCustomElementDefinition::runConstructor(Element* element) { | 217 bool ScriptCustomElementDefinition::runConstructor(Element* element) { |
227 if (!m_scriptState->contextIsValid()) | 218 if (!m_scriptState->contextIsValid()) |
228 return false; | 219 return false; |
229 ScriptState::Scope scope(m_scriptState.get()); | 220 ScriptState::Scope scope(m_scriptState.get()); |
230 v8::Isolate* isolate = m_scriptState->isolate(); | 221 v8::Isolate* isolate = m_scriptState->isolate(); |
231 | 222 |
232 // Step 5 says to rethrow the exception; but there is no one to | 223 // Step 5 says to rethrow the exception; but there is no one to |
233 // catch it. The side effect is to report the error. | 224 // catch it. The side effect is to report the error. |
234 v8::TryCatch tryCatch(isolate); | 225 v8::TryCatch tryCatch(isolate); |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 v8::Local<v8::Value> argv[] = { | 349 v8::Local<v8::Value> argv[] = { |
359 v8String(isolate, name.localName()), v8StringOrNull(isolate, oldValue), | 350 v8String(isolate, name.localName()), v8StringOrNull(isolate, oldValue), |
360 v8StringOrNull(isolate, newValue), | 351 v8StringOrNull(isolate, newValue), |
361 v8StringOrNull(isolate, name.namespaceURI()), | 352 v8StringOrNull(isolate, name.namespaceURI()), |
362 }; | 353 }; |
363 runCallback(m_attributeChangedCallback.newLocal(isolate), element, | 354 runCallback(m_attributeChangedCallback.newLocal(isolate), element, |
364 WTF_ARRAY_LENGTH(argv), argv); | 355 WTF_ARRAY_LENGTH(argv), argv); |
365 } | 356 } |
366 | 357 |
367 } // namespace blink | 358 } // namespace blink |
OLD | NEW |