Index: third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp |
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp |
index de725ff62ad418e8ad81b48123a14d602e1e0ba3..dd3d1cb04ee8e4a5536936d419ebb9a884a9f894 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp |
+++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp |
@@ -13,6 +13,8 @@ |
#include "bindings/core/v8/V8ScriptRunner.h" |
#include "bindings/core/v8/V8ThrowException.h" |
#include "core/dom/ExceptionCode.h" |
+#include "core/html/HTMLElement.h" |
+#include "core/html/HTMLUnknownElement.h" |
#include "v8.h" |
#include "wtf/Allocator.h" |
@@ -152,6 +154,61 @@ ScriptCustomElementDefinition::ScriptCustomElementDefinition( |
{ |
} |
+HTMLElement* ScriptCustomElementDefinition::createElementSync( |
+ Document& document, const QualifiedName& tagName, |
+ ExceptionState& exceptionState) |
+{ |
+ // Create an element |
haraken
2016/06/13 09:05:35
Is it guaranteed that you're already in m_scriptSt
kojii
2016/06/13 10:28:25
Yes, that's the assumption atm; we assume DOM crea
|
+ // https://dom.spec.whatwg.org/#concept-create-element |
+ // 6. If definition is non-null |
+ // 6.1. If the synchronous custom elements flag is set: |
+ // 6.1.2. Set result to Construct(C). Rethrow any exceptions. |
+ Element* element; |
haraken
2016/06/13 09:05:35
element = nullptr
kojii
2016/06/13 10:28:25
Will fix in the next CL.
|
+ { |
+ v8::TryCatch tryCatch(m_scriptState->isolate()); |
+ element = runConstructor(); |
+ if (tryCatch.HasCaught()) { |
+ exceptionState.rethrowV8Exception(tryCatch.Exception()); |
+ return nullptr; |
+ } |
+ } |
+ |
+ // 6.1.3. through 6.1.9. |
+ checkConstructorResult(element, document, tagName, exceptionState); |
+ if (exceptionState.hadException()) |
+ return nullptr; |
+ |
+ DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom); |
+ return toHTMLElement(element); |
+} |
+ |
+HTMLElement* ScriptCustomElementDefinition::createElementSync( |
+ Document& document, const QualifiedName& tagName) |
+{ |
+ // When invoked from "create an element for a token": |
+ // https://html.spec.whatwg.org/multipage/syntax.html#create-an-element-for-the-token |
+ // 7. If this step throws an exception, then report the exception, and |
+ // let element be instead a new element that implements HTMLUnknownElement, |
+ // with no attributes, namespace set to given namespace, namespace prefix |
+ // set to null, custom element state "undefined", and node document set to |
+ // document. |
+ ScriptState::Scope scope(m_scriptState.get()); |
+ v8::Isolate* isolate = m_scriptState->isolate(); |
+ v8::TryCatch tryCatch(isolate); |
haraken
2016/06/13 09:05:35
Why do you need this TryCatch?
|
+ tryCatch.SetVerbose(true); |
haraken
2016/06/13 09:05:35
Remove this line unless you really want to make it
kojii
2016/06/13 10:28:25
The spec (copied in the comment above) says catch
|
+ ExceptionState exceptionState(ExceptionState::ConstructionContext, "CustomElement", constructor(), isolate); |
+ |
+ HTMLElement* element = createElementSync(document, tagName, exceptionState); |
+ DCHECK(!tryCatch.HasCaught()); |
haraken
2016/06/13 09:05:35
Instead, you can check DCHECK(!exceptionState.hadE
kojii
2016/06/13 10:28:25
There are errors here when JS throws. The purpose
|
+ |
+ exceptionState.throwIfNeeded(); |
+ if (tryCatch.HasCaught() || !element) { |
+ element = HTMLUnknownElement::create(tagName, document); |
+ element->setCustomElementState(CustomElementState::Undefined); |
+ } |
+ return element; |
+} |
+ |
// https://html.spec.whatwg.org/multipage/scripting.html#upgrades |
bool ScriptCustomElementDefinition::runConstructor(Element* element) |
{ |
@@ -165,18 +222,11 @@ bool ScriptCustomElementDefinition::runConstructor(Element* element) |
v8::TryCatch tryCatch(isolate); |
tryCatch.SetVerbose(true); |
haraken
2016/06/13 09:05:35
Remove this line.
kojii
2016/06/13 10:28:25
The spec requires to "report the error" here, as i
|
- ExecutionContext* executionContext = m_scriptState->getExecutionContext(); |
- v8::Local<v8::Value> result; |
- if (!v8Call(V8ScriptRunner::callAsConstructor( |
- isolate, |
- constructor(), |
- executionContext, |
- 0, |
- nullptr), |
- result)) |
+ Element* result = runConstructor(); |
+ if (!result) |
return false; |
- if (V8Element::toImplWithTypeCheck(isolate, result) != element) { |
+ if (result != element) { |
V8ThrowException::throwException( |
V8ThrowException::createDOMException( |
m_scriptState->isolate(), |
@@ -191,6 +241,23 @@ bool ScriptCustomElementDefinition::runConstructor(Element* element) |
return true; |
} |
+Element* ScriptCustomElementDefinition::runConstructor() |
+{ |
+ v8::Isolate* isolate = m_scriptState->isolate(); |
haraken
2016/06/13 09:05:35
Is it guaranteed that you're already in m_scriptSt
kojii
2016/06/13 10:28:25
Yes, this is called from either:
1. createElement
|
+ ExecutionContext* executionContext = m_scriptState->getExecutionContext(); |
+ v8::Local<v8::Value> result; |
+ if (!v8Call(V8ScriptRunner::callAsConstructor( |
+ isolate, |
+ constructor(), |
+ executionContext, |
+ 0, |
+ nullptr), |
+ result)) { |
+ return nullptr; |
+ } |
+ return V8Element::toImplWithTypeCheck(isolate, result); |
+} |
+ |
v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const |
{ |
DCHECK(!m_constructor.isEmpty()); |