| 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( |
| 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 Loading... |
| 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 |
| OLD | NEW |