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 c2f1b9fbf407fc31c6156cca733619f0c0b23032..89383e9a0fba15a2c8536f10b39d39d891e2441b 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp |
+++ b/third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp |
@@ -2,6 +2,8 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "bindings/core/v8/V8HTMLConstructor.h" |
+ |
#include "bindings/core/v8/DOMWrapperWorld.h" |
#include "bindings/core/v8/ExceptionState.h" |
#include "bindings/core/v8/ScriptCustomElementDefinition.h" |
@@ -9,6 +11,7 @@ |
#include "bindings/core/v8/V8BindingMacros.h" |
#include "bindings/core/v8/V8DOMWrapper.h" |
#include "bindings/core/v8/V8HTMLElement.h" |
+#include "bindings/core/v8/V8PerContextData.h" |
#include "bindings/core/v8/V8ThrowException.h" |
#include "core/dom/Document.h" |
#include "core/dom/Element.h" |
@@ -19,13 +22,16 @@ |
namespace blink { |
-// https://html.spec.whatwg.org/#html-element-constructors |
-void V8HTMLElement::HTMLConstructor( |
- const v8::FunctionCallbackInfo<v8::Value>& info) { |
+// https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors |
+void V8HTMLConstructor::htmlConstructor( |
+ const v8::FunctionCallbackInfo<v8::Value>& info, |
+ const WrapperTypeInfo& wrapperTypeInfo, |
+ const HTMLElementType elementInterfaceName) { |
DCHECK(info.IsConstructCall()); |
v8::Isolate* isolate = info.GetIsolate(); |
ScriptState* scriptState = ScriptState::current(isolate); |
+ v8::Local<v8::Value> newTarget = info.NewTarget(); |
if (!scriptState->contextIsValid()) { |
V8ThrowException::throwError(isolate, "The context has been destroyed"); |
@@ -43,28 +49,53 @@ void V8HTMLElement::HTMLConstructor( |
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(); |
+ CustomElementRegistry* registry = window->customElements(); |
+ |
+ // 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. |
ScriptCustomElementDefinition* definition = |
- ScriptCustomElementDefinition::forConstructor( |
- scriptState, window->customElements(), newTarget); |
+ ScriptCustomElementDefinition::forConstructor(scriptState, registry, |
+ newTarget); |
if (!definition) { |
V8ThrowException::throwTypeError(isolate, "Illegal constructor"); |
return; |
} |
- ExceptionState exceptionState(ExceptionState::ConstructionContext, |
- "HTMLElement", info.Holder(), isolate); |
+ const AtomicString& localName = definition->descriptor().localName(); |
+ const AtomicString& name = definition->descriptor().name(); |
+ |
+ if (localName == name) { |
+ // Autonomous custom element |
+ // 4.1. If the active function object is not HTMLElement, then throw a |
+ // TypeError |
+ if (!V8HTMLElement::wrapperTypeInfo.equals(&wrapperTypeInfo)) { |
+ V8ThrowException::throwTypeError(isolate, |
+ "Illegal constructor: autonomous custom " |
+ "elements must extend HTMLElement"); |
+ return; |
+ } |
+ } else { |
+ // Customized built-in element |
+ // 5. If local name is not valid for interface, throw TypeError |
+ if (htmlElementTypeForTag(localName) != elementInterfaceName) { |
+ V8ThrowException::throwTypeError(isolate, |
+ "Illegal constructor: localName does " |
+ "not match the HTML element interface"); |
+ return; |
+ } |
+ } |
- // TODO(dominicc): Implement steps 4-5. |
+ ExceptionState exceptionState(isolate, ExceptionState::ConstructionContext, |
+ "HTMLElement"); |
+ v8::TryCatch tryCatch(isolate); |
// 6. Let prototype be Get(NewTarget, "prototype"). Rethrow any exceptions. |
v8::Local<v8::Value> prototype; |
@@ -87,6 +118,7 @@ void V8HTMLElement::HTMLConstructor( |
} |
} |
+ // 8. If definition's construction stack is empty... |
Element* element; |
if (definition->constructionStack().isEmpty()) { |
// This is an element being created with 'new' from script |
@@ -117,5 +149,4 @@ void V8HTMLElement::HTMLConstructor( |
wrapper->SetPrototype(scriptState->context(), prototype.As<v8::Object>()) |
.ToChecked(); |
} |
- |
} // namespace blink |