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

Unified Diff: third_party/WebKit/Source/bindings/core/v8/V8HTMLConstructor.cpp

Issue 2424693002: Custom Elements: Complete HTMLConstructor Algorithm (Closed)
Patch Set: Updated expected test results Created 4 years, 2 months 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 side-by-side diff with in-line comments
Download patch
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..09a30c07531378d8160cdc2527ff2133ea9d6105 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,18 @@
namespace blink {
-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();
+ // Behind runtime enabled flag
if (!RuntimeEnabledFeatures::customElementsV1Enabled() ||
!scriptState->world().isMainWorld()) {
V8ThrowException::throwTypeError(info.GetIsolate(), "Illegal constructor");
@@ -33,17 +41,73 @@ void V8HTMLElement::HTMLConstructor(
}
LocalDOMWindow* window = scriptState->domWindow();
+ CustomElementRegistry* registry = window->customElements();
+
+ // 2. If NewTarget is equal to the active function object, throw a TypeError
+ v8::Local<v8::Function> activeFunctionObject =
+ scriptState->perContextData()->constructorForType(&wrapperTypeInfo);
+ if (newTarget->Equals(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.
ScriptCustomElementDefinition* definition =
- ScriptCustomElementDefinition::forConstructor(
- scriptState, window->customElements(), info.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
+ v8::Local<v8::Function> htmlElement =
dominicc (has gone to gerrit) 2016/10/21 02:30:07 I think the spec is not referring to any particula
+ scriptState->perContextData()->constructorForType(
+ &V8HTMLElement::wrapperTypeInfo);
+ if (activeFunctionObject != htmlElement) {
+ V8ThrowException::throwTypeError(isolate, "Illegal constructor");
dominicc (has gone to gerrit) 2016/10/21 02:30:07 You want to return at this point! The algorithm is
+ }
+ } 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");
+ return;
+ }
+ }
+
+ ExceptionState exceptionState(isolate, ExceptionState::ConstructionContext,
+ "HTMLConstructor");
+ v8::TryCatch tryCatch(isolate);
+
+ // 6. Let prototype be Get(NewTarget, "prototype"). Rethrow any exceptions.
+ v8::Local<v8::String> nameString = v8AtomicString(isolate, "prototype");
+ v8::Local<v8::Value> prototypeValue;
+ if (!v8Call(
+ newTarget.As<v8::Object>()->Get(scriptState->context(), nameString),
+ prototypeValue, tryCatch)) {
+ exceptionState.rethrowV8Exception(tryCatch.Exception());
+ return;
+ }
+
+ // 7. If Type(prototype) is not Object...
+ if (!prototypeValue->IsObject()) {
+ v8::Local<v8::Context> context =
+ newTarget.As<v8::Object>()->CreationContext();
+ V8PerContextData* perContextData = V8PerContextData::from(context);
+ prototypeValue = perContextData->prototypeForType(&wrapperTypeInfo);
+ }
+
+ // 8. If definition's construction stack is empty...
Element* element;
if (definition->constructionStack().isEmpty()) {
// This is an element being created with 'new' from script
@@ -69,8 +133,6 @@ void V8HTMLElement::HTMLConstructor(
// instead.
v8SetReturnValue(info, wrapper);
- wrapper->SetPrototype(scriptState->context(), definition->prototype())
- .ToChecked();
+ wrapper->SetPrototype(scriptState->context(), prototypeValue).ToChecked();
}
-
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698