Index: third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp |
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp |
index 61c510dfcedf60697fed258683bf9d166488be92..c2f1b9fbf407fc31c6156cca733619f0c0b23032 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp |
+++ b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp |
@@ -19,6 +19,7 @@ |
namespace blink { |
+// https://html.spec.whatwg.org/#html-element-constructors |
void V8HTMLElement::HTMLConstructor( |
const v8::FunctionCallbackInfo<v8::Value>& info) { |
DCHECK(info.IsConstructCall()); |
@@ -26,16 +27,35 @@ void V8HTMLElement::HTMLConstructor( |
v8::Isolate* isolate = info.GetIsolate(); |
ScriptState* scriptState = ScriptState::current(isolate); |
+ if (!scriptState->contextIsValid()) { |
+ V8ThrowException::throwError(isolate, "The context has been destroyed"); |
+ return; |
+ } |
+ |
if (!RuntimeEnabledFeatures::customElementsV1Enabled() || |
!scriptState->world().isMainWorld()) { |
- V8ThrowException::throwTypeError(info.GetIsolate(), "Illegal constructor"); |
+ V8ThrowException::throwTypeError(isolate, "Illegal constructor"); |
return; |
} |
+ // 2. If NewTarget is equal to the active function object, then |
+ // throw a TypeError and abort these steps. |
+ v8::Local<v8::Function> activeFunctionObject = |
+ scriptState->perContextData()->constructorForType( |
+ &V8HTMLElement::wrapperTypeInfo); |
+ v8::Local<v8::Value> newTarget = info.NewTarget(); |
+ if (newTarget == activeFunctionObject) { |
+ V8ThrowException::throwTypeError(isolate, "Illegal constructor"); |
+ return; |
+ } |
+ |
+ // 3. Let definition be the entry in registry with constructor equal |
+ // to NewTarget. If there is no such definition, then throw a |
+ // TypeError and abort these steps. |
LocalDOMWindow* window = scriptState->domWindow(); |
ScriptCustomElementDefinition* definition = |
ScriptCustomElementDefinition::forConstructor( |
- scriptState, window->customElements(), info.NewTarget()); |
+ scriptState, window->customElements(), newTarget); |
if (!definition) { |
V8ThrowException::throwTypeError(isolate, "Illegal constructor"); |
return; |
@@ -44,6 +64,29 @@ void V8HTMLElement::HTMLConstructor( |
ExceptionState exceptionState(ExceptionState::ConstructionContext, |
"HTMLElement", info.Holder(), isolate); |
+ // TODO(dominicc): Implement steps 4-5. |
+ |
+ // 6. Let prototype be Get(NewTarget, "prototype"). Rethrow any exceptions. |
+ v8::Local<v8::Value> prototype; |
+ v8::Local<v8::String> prototypeString = v8AtomicString(isolate, "prototype"); |
+ if (!v8Call(newTarget.As<v8::Object>()->Get(scriptState->context(), |
+ prototypeString), |
+ prototype)) { |
+ return; |
+ } |
+ |
+ // 7. If Type(prototype) is not Object, then: ... |
+ if (!prototype->IsObject()) { |
+ if (V8PerContextData* perContextData = V8PerContextData::from( |
+ newTarget.As<v8::Object>()->CreationContext())) { |
+ prototype = |
+ perContextData->prototypeForType(&V8HTMLElement::wrapperTypeInfo); |
+ } else { |
+ V8ThrowException::throwError(isolate, "The context has been destroyed"); |
+ return; |
+ } |
+ } |
+ |
Element* element; |
if (definition->constructionStack().isEmpty()) { |
// This is an element being created with 'new' from script |
@@ -69,7 +112,9 @@ void V8HTMLElement::HTMLConstructor( |
// instead. |
v8SetReturnValue(info, wrapper); |
- wrapper->SetPrototype(scriptState->context(), definition->prototype()) |
+ // 11. Perform element.[[SetPrototypeOf]](prototype). Rethrow any exceptions. |
+ // Note: I don't think this prototype set *can* throw exceptions. |
+ wrapper->SetPrototype(scriptState->context(), prototype.As<v8::Object>()) |
.ToChecked(); |
} |