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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp

Issue 2443543002: createElement should not transmit exceptions but report them. (Closed)
Patch Set: Rebaseline tests. Created 4 years, 1 month 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
OLDNEW
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
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(
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 if (!m_scriptState->contextIsValid())
158 DCHECK(ScriptState::current(m_scriptState->isolate()) == m_scriptState); 181 return CustomElement::createFailedElement(document, tagName);
182 ScriptState::Scope scope(m_scriptState.get());
183 v8::Isolate* isolate = m_scriptState->isolate();
159 184
160 // Create an element 185 ExceptionState exceptionState(ExceptionState::ConstructionContext,
186 "CustomElement", constructor(), isolate);
187
188 // Create an element with the synchronous custom elements flag set.
161 // https://dom.spec.whatwg.org/#concept-create-element 189 // 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 190
166 // Create an element and push to the construction stack. 191 // Create an element and push to the construction stack.
167 // V8HTMLElement::constructorCustom() can only refer to 192 // V8HTMLElement::constructorCustom() can only refer to
168 // window.document(), but it is different from the document here 193 // window.document(), but it is different from the document here
169 // when it is an import document. This is not exactly what the 194 // when it is an import document. This is not exactly what the
170 // spec defines, but the public behavior matches to the spec. 195 // spec defines, but the non-imports behavior matches to the spec.
171 Element* element = createElementForConstructor(document); 196 Element* element = createElementForConstructor(document);
172 { 197 {
173 ConstructionStackScope constructionStackScope(this, element); 198 ConstructionStackScope constructionStackScope(this, element);
174 v8::TryCatch tryCatch(m_scriptState->isolate()); 199 v8::TryCatch tryCatch(m_scriptState->isolate());
175 element = runConstructor(); 200 element = runConstructor();
176 if (tryCatch.HasCaught()) { 201 if (tryCatch.HasCaught()) {
177 exceptionState.rethrowV8Exception(tryCatch.Exception()); 202 exceptionState.rethrowV8Exception(tryCatch.Exception());
178 return nullptr; 203 return handleCreateElementSyncException(document, tagName, isolate,
204 exceptionState);
179 } 205 }
180 } 206 }
181 207
182 // 6.1.3. through 6.1.9. 208 // 6.1.3. through 6.1.9.
183 checkConstructorResult(element, document, tagName, exceptionState); 209 checkConstructorResult(element, document, tagName, exceptionState);
184 if (exceptionState.hadException()) 210 if (exceptionState.hadException()) {
185 return nullptr; 211 return handleCreateElementSyncException(document, tagName, isolate,
186 212 exceptionState);
213 }
187 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom); 214 DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom);
188 return toHTMLElement(element); 215 return toHTMLElement(element);
189 } 216 }
190 217
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 218 // https://html.spec.whatwg.org/multipage/scripting.html#upgrades
226 bool ScriptCustomElementDefinition::runConstructor(Element* element) { 219 bool ScriptCustomElementDefinition::runConstructor(Element* element) {
227 if (!m_scriptState->contextIsValid()) 220 if (!m_scriptState->contextIsValid())
228 return false; 221 return false;
229 ScriptState::Scope scope(m_scriptState.get()); 222 ScriptState::Scope scope(m_scriptState.get());
230 v8::Isolate* isolate = m_scriptState->isolate(); 223 v8::Isolate* isolate = m_scriptState->isolate();
231 224
232 // Step 5 says to rethrow the exception; but there is no one to 225 // Step 5 says to rethrow the exception; but there is no one to
233 // catch it. The side effect is to report the error. 226 // catch it. The side effect is to report the error.
234 v8::TryCatch tryCatch(isolate); 227 v8::TryCatch tryCatch(isolate);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 v8::Local<v8::Value> argv[] = { 351 v8::Local<v8::Value> argv[] = {
359 v8String(isolate, name.localName()), v8StringOrNull(isolate, oldValue), 352 v8String(isolate, name.localName()), v8StringOrNull(isolate, oldValue),
360 v8StringOrNull(isolate, newValue), 353 v8StringOrNull(isolate, newValue),
361 v8StringOrNull(isolate, name.namespaceURI()), 354 v8StringOrNull(isolate, name.namespaceURI()),
362 }; 355 };
363 runCallback(m_attributeChangedCallback.newLocal(isolate), element, 356 runCallback(m_attributeChangedCallback.newLocal(isolate), element,
364 WTF_ARRAY_LENGTH(argv), argv); 357 WTF_ARRAY_LENGTH(argv), argv);
365 } 358 }
366 359
367 } // namespace blink 360 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698