Chromium Code Reviews| 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 32dc346ea99baab57c6066e6f681d9a44a86826b..d52c13d5b21300d7035aa102cd7fc3ba3ff43db5 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp |
| +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinition.cpp |
| @@ -9,11 +9,13 @@ |
| #include "bindings/core/v8/V8BindingMacros.h" |
| #include "bindings/core/v8/V8CustomElementsRegistry.h" |
| #include "bindings/core/v8/V8Element.h" |
| +#include "bindings/core/v8/V8ErrorHandler.h" |
| #include "bindings/core/v8/V8HiddenValue.h" |
| #include "bindings/core/v8/V8ScriptRunner.h" |
| #include "bindings/core/v8/V8ThrowException.h" |
| #include "core/dom/ExceptionCode.h" |
| #include "core/dom/custom/CustomElement.h" |
| +#include "core/events/ErrorEvent.h" |
| #include "core/html/HTMLElement.h" |
| #include "v8.h" |
| #include "wtf/Allocator.h" |
| @@ -105,6 +107,7 @@ ScriptCustomElementDefinition* ScriptCustomElementDefinition::create( |
| const v8::Local<v8::Object>& prototype, |
| const v8::Local<v8::Function>& connectedCallback, |
| const v8::Local<v8::Function>& disconnectedCallback, |
| + const v8::Local<v8::Function>& adoptedCallback, |
| const v8::Local<v8::Function>& attributeChangedCallback, |
| const HashSet<AtomicString>& observedAttributes) |
| { |
| @@ -116,6 +119,7 @@ ScriptCustomElementDefinition* ScriptCustomElementDefinition::create( |
| prototype, |
| connectedCallback, |
| disconnectedCallback, |
| + adoptedCallback, |
| attributeChangedCallback, |
| observedAttributes); |
| @@ -129,11 +133,12 @@ ScriptCustomElementDefinition* ScriptCustomElementDefinition::create( |
| // We add the prototype and callbacks here to keep them alive. We use the |
| // name as the key because it is unique per-registry. |
| - v8::Local<v8::Array> array = v8::Array::New(scriptState->isolate(), 4); |
| + v8::Local<v8::Array> array = v8::Array::New(scriptState->isolate(), 5); |
| keepAlive(array, 0, prototype, definition->m_prototype, scriptState); |
| keepAlive(array, 1, connectedCallback, definition->m_connectedCallback, scriptState); |
| keepAlive(array, 2, disconnectedCallback, definition->m_disconnectedCallback, scriptState); |
| keepAlive(array, 3, attributeChangedCallback, definition->m_attributeChangedCallback, scriptState); |
| + keepAlive(array, 4, adoptedCallback, definition->m_adoptedCallback, scriptState); |
| v8CallOrCrash(map->Set(scriptState->context(), nameValue, array)); |
| return definition; |
| @@ -146,6 +151,7 @@ ScriptCustomElementDefinition::ScriptCustomElementDefinition( |
| const v8::Local<v8::Object>& prototype, |
| const v8::Local<v8::Function>& connectedCallback, |
| const v8::Local<v8::Function>& disconnectedCallback, |
| + const v8::Local<v8::Function>& adoptedCallback, |
| const v8::Local<v8::Function>& attributeChangedCallback, |
| const HashSet<AtomicString>& observedAttributes) |
| : CustomElementDefinition(descriptor, observedAttributes) |
| @@ -224,18 +230,23 @@ bool ScriptCustomElementDefinition::runConstructor(Element* element) |
| tryCatch.SetVerbose(true); |
| Element* result = runConstructor(); |
| - if (!result) |
| + |
| + // To report exception thrown from runConstructor() |
| + if (tryCatch.HasCaught()) |
| return false; |
| + // To report InvalidStateError Exception, when the constructor returns some differnt object |
|
dominicc (has gone to gerrit)
2016/08/02 07:48:57
Spelling: different
|
| if (result != element) { |
| - V8ThrowException::throwException( |
| - V8ThrowException::createDOMException( |
| - m_scriptState->isolate(), |
| - InvalidStateError, |
| - "custom element constructors must call super() first and must " |
| - "not return a different object", |
| - constructor()), |
| - m_scriptState->isolate()); |
| + const String& message = "custom element constructors must call super() first and must " |
| + "not return a different object"; |
| + |
|
dominicc (has gone to gerrit)
2016/08/02 07:48:57
Maybe delete this blank line; since the message an
|
| + std::unique_ptr<SourceLocation> location = SourceLocation::fromFunction(constructor().As<v8::Function>()); |
| + v8::Local<v8::Value> exception = V8ThrowException::createDOMException( |
| + m_scriptState->isolate(), |
| + InvalidStateError, |
| + message, |
| + constructor()); |
| + fireErrorEvent(m_scriptState.get(), message, exception, std::move(location)); |
| return false; |
| } |
| @@ -260,6 +271,14 @@ Element* ScriptCustomElementDefinition::runConstructor() |
| return V8Element::toImplWithTypeCheck(isolate, result); |
| } |
| +void ScriptCustomElementDefinition::fireErrorEvent(ScriptState* scriptState, const String& message, v8::Local<v8::Value> exception, std::unique_ptr<SourceLocation> location) |
| +{ |
| + ErrorEvent* event = ErrorEvent::create(message, std::move(location), &scriptState->world()); |
| + V8ErrorHandler::storeExceptionOnErrorEventWrapper(scriptState, event, exception, scriptState->context()->Global()); |
| + ExecutionContext* executionContext = scriptState->getExecutionContext(); |
| + executionContext->reportException(event, NotSharableCrossOrigin); |
| +} |
| + |
| v8::Local<v8::Object> ScriptCustomElementDefinition::constructor() const |
| { |
| DCHECK(!m_constructor.isEmpty()); |
| @@ -288,6 +307,11 @@ bool ScriptCustomElementDefinition::hasDisconnectedCallback() const |
| return !m_disconnectedCallback.isEmpty(); |
| } |
| +bool ScriptCustomElementDefinition::hasAdoptedCallback() const |
| +{ |
| + return !m_adoptedCallback.isEmpty(); |
| +} |
| + |
| void ScriptCustomElementDefinition::runCallback( |
| v8::Local<v8::Function> callback, |
| Element* element, int argc, v8::Local<v8::Value> argv[]) |
| @@ -329,6 +353,15 @@ void ScriptCustomElementDefinition::runDisconnectedCallback(Element* element) |
| runCallback(m_disconnectedCallback.newLocal(isolate), element); |
| } |
| +void ScriptCustomElementDefinition::runAdoptedCallback(Element* element) |
| +{ |
| + if (!m_scriptState->contextIsValid()) |
| + return; |
| + ScriptState::Scope scope(m_scriptState.get()); |
| + v8::Isolate* isolate = m_scriptState->isolate(); |
| + runCallback(m_adoptedCallback.newLocal(isolate), element); |
| +} |
| + |
| void ScriptCustomElementDefinition::runAttributeChangedCallback( |
| Element* element, const QualifiedName& name, |
| const AtomicString& oldValue, const AtomicString& newValue) |