Index: third_party/WebKit/Source/bindings/core/v8/custom/V8HTMLElementCustom.cpp |
diff --git a/third_party/WebKit/Source/bindings/core/v8/custom/V8HTMLElementCustom.cpp b/third_party/WebKit/Source/bindings/core/v8/custom/V8HTMLElementCustom.cpp |
index 622621df4af221cf0d4d53b8a1e6ae8d626d536d..a7251482a4aae8584ef14e2f54ed45c409a0f41b 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/custom/V8HTMLElementCustom.cpp |
+++ b/third_party/WebKit/Source/bindings/core/v8/custom/V8HTMLElementCustom.cpp |
@@ -12,6 +12,7 @@ |
#include "bindings/core/v8/V8DOMWrapper.h" |
#include "bindings/core/v8/V8ThrowException.h" |
#include "core/dom/Document.h" |
+#include "core/dom/ExceptionCode.h" |
#include "core/dom/custom/CustomElementsRegistry.h" |
#include "core/frame/LocalDOMWindow.h" |
#include "platform/RuntimeEnabledFeatures.h" |
@@ -28,48 +29,76 @@ void V8HTMLElement::constructorCustom( |
if (!RuntimeEnabledFeatures::customElementsV1Enabled() |
|| !scriptState->world().isMainWorld()) { |
- V8ThrowException::throwTypeError(info.GetIsolate(), "Illegal constructor"); |
+ V8ThrowException::throwTypeError( |
+ info.GetIsolate(), |
+ "Illegal constructor"); |
return; |
} |
LocalDOMWindow* window = scriptState->domWindow(); |
- ScriptCustomElementDefinition* def = |
+ ScriptCustomElementDefinition* definition = |
ScriptCustomElementDefinition::forConstructor( |
scriptState, |
window->customElements(), |
info.NewTarget()); |
- if (!def) { |
+ if (!definition) { |
V8ThrowException::throwTypeError(isolate, "Illegal constructor"); |
return; |
} |
- // TODO(dominicc): Implement cases where the definition's |
- // construction stack is not empty when parser-creation is |
- // implemented. |
- |
ExceptionState exceptionState( |
ExceptionState::ConstructionContext, |
"HTMLElement", |
info.Holder(), |
isolate); |
- Element* element = window->document()->createElement( |
- def->descriptor().localName(), |
- AtomicString(), |
- exceptionState); |
- if (exceptionState.throwIfNeeded()) |
- return; |
+ |
+ Element* element; |
+ if (definition->constructionStack().isEmpty()) { |
+ // This is an element being created with 'new' from script |
+ element = window->document()->createElement( |
+ definition->descriptor().localName(), |
+ AtomicString(), |
+ exceptionState); |
+ if (exceptionState.throwIfNeeded()) |
+ return; |
+ } else { |
+ element = definition->constructionStack().last(); |
+ if (element) { |
+ // This is an element being upgraded that has called super |
+ definition->constructionStack().last().clear(); |
+ } else { |
+ // During upgrade an element has invoked the same constructor |
+ // before calling 'super' and that invocation has poached the |
+ // element. |
+ exceptionState.throwDOMException( |
+ InvalidStateError, |
+ "this instance is already constructed"); |
+ exceptionState.throwIfNeeded(); |
+ return; |
+ } |
+ } |
const WrapperTypeInfo* wrapperType = element->wrapperTypeInfo(); |
v8::Local<v8::Object> wrapper = V8DOMWrapper::associateObjectWithWrapper( |
isolate, |
element, |
wrapperType, |
info.This()); |
+ // If the element had a wrapper, we now update and return that |
+ // instead. |
+ v8SetReturnValue(info, wrapper); |
- if (!v8CallBoolean(wrapper->SetPrototype( |
+ v8CallOrCrash(wrapper->SetPrototype( |
scriptState->context(), |
- def->prototype()))) { |
- return; |
- } |
+ definition->prototype())); |
+ |
+ // TODO(dominicc): These elements should be 'undefined', not |
+ // 'uncustomized', on creation. Investigate why some elements are |
+ // running around uncustomized. |
+ if (element->getCustomElementState() == CustomElementState::Uncustomized) |
+ element->setCustomElementState(CustomElementState::Undefined); |
+ // TODO(dominicc): Move this to the exactly correct place when |
+ // https://github.com/whatwg/html/issues/1297 is closed. |
+ element->setCustomElementState(CustomElementState::Custom); |
} |
} // namespace blink |