| Index: third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
|
| diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
|
| index 3a4d686dc4ef14b2ab0168d66e18eb396a6650ae..158a6dfe6008f250db694e66517f97cd2e86a60c 100644
|
| --- a/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
|
| +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptCustomElementDefinitionBuilder.cpp
|
| @@ -81,17 +81,26 @@ bool ScriptCustomElementDefinitionBuilder::checkConstructorNotRegistered()
|
| return true;
|
| }
|
|
|
| -bool ScriptCustomElementDefinitionBuilder::checkPrototype()
|
| +bool ScriptCustomElementDefinitionBuilder::valueForName(
|
| + const v8::Local<v8::Object>& object, const String& name,
|
| + v8::Local<v8::Value>& value) const
|
| {
|
| v8::Isolate* isolate = m_scriptState->isolate();
|
| v8::Local<v8::Context> context = m_scriptState->context();
|
| - v8::Local<v8::String> prototypeString =
|
| - v8AtomicString(isolate, "prototype");
|
| - v8::Local<v8::Value> prototypeValue;
|
| - if (!v8Call(
|
| - m_constructor->Get(context, prototypeString), prototypeValue)) {
|
| + v8::Local<v8::String> nameString = v8String(isolate, name);
|
| + v8::TryCatch tryCatch(isolate);
|
| + if (!v8Call(object->Get(context, nameString), value, tryCatch)) {
|
| + m_exceptionState.rethrowV8Exception(tryCatch.Exception());
|
| return false;
|
| }
|
| + return true;
|
| +}
|
| +
|
| +bool ScriptCustomElementDefinitionBuilder::checkPrototype()
|
| +{
|
| + v8::Local<v8::Value> prototypeValue;
|
| + if (!valueForName(m_constructor, "prototype", prototypeValue))
|
| + return false;
|
| if (!prototypeValue->IsObject()) {
|
| m_exceptionState.throwTypeError(
|
| "constructor prototype is not an object");
|
| @@ -103,6 +112,62 @@ bool ScriptCustomElementDefinitionBuilder::checkPrototype()
|
| return true;
|
| }
|
|
|
| +bool ScriptCustomElementDefinitionBuilder::callableForName(const String& name,
|
| + v8::Local<v8::Object>& callback) const
|
| +{
|
| + v8::Local<v8::Value> value;
|
| + if (!valueForName(m_prototype, name, value))
|
| + return false;
|
| + // "undefined" means "omitted", so return true.
|
| + if (value->IsUndefined())
|
| + return true;
|
| + if (!value->IsObject()) {
|
| + m_exceptionState.throwTypeError(
|
| + String::format("\"%s\" is not an object", name.ascii().data()));
|
| + return false;
|
| + }
|
| + callback = value.As<v8::Object>();
|
| + if (!callback->IsCallable()) {
|
| + m_exceptionState.throwTypeError(
|
| + String::format("\"%s\" is not callable", name.ascii().data()));
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool ScriptCustomElementDefinitionBuilder::retrieveObservedAttributes()
|
| +{
|
| + const String kObservedAttributes = "observedAttributes";
|
| + v8::Local<v8::Value> observedAttributesValue;
|
| + if (!valueForName(m_constructor, kObservedAttributes, observedAttributesValue))
|
| + return false;
|
| + if (observedAttributesValue->IsUndefined())
|
| + return true;
|
| + Vector<AtomicString> list = toImplArray<Vector<AtomicString>>(
|
| + observedAttributesValue, 0, m_scriptState->isolate(), m_exceptionState);
|
| + if (m_exceptionState.hadException())
|
| + return false;
|
| + if (list.isEmpty())
|
| + return true;
|
| + m_observedAttributes.reserveCapacityForSize(list.size());
|
| + for (const auto& attribute : list)
|
| + m_observedAttributes.add(attribute);
|
| + return true;
|
| +}
|
| +
|
| +bool ScriptCustomElementDefinitionBuilder::rememberOriginalProperties()
|
| +{
|
| + // Spec requires to use values of these properties at the point
|
| + // CustomElementDefinition is built, even if JS changes them afterwards.
|
| + const String kConnectedCallback = "connectedCallback";
|
| + const String kDisconnectedCallback = "disconnectedCallback";
|
| + const String kAttributeChangedCallback = "attributeChangedCallback";
|
| + return retrieveObservedAttributes()
|
| + && callableForName(kConnectedCallback, m_connectedCallback)
|
| + && callableForName(kDisconnectedCallback, m_disconnectedCallback)
|
| + && callableForName(kAttributeChangedCallback, m_attributeChangedCallback);
|
| +}
|
| +
|
| CustomElementDefinition* ScriptCustomElementDefinitionBuilder::build(
|
| const CustomElementDescriptor& descriptor)
|
| {
|
| @@ -111,7 +176,11 @@ CustomElementDefinition* ScriptCustomElementDefinitionBuilder::build(
|
| m_registry,
|
| descriptor,
|
| m_constructor,
|
| - m_prototype);
|
| + m_prototype,
|
| + m_connectedCallback,
|
| + m_disconnectedCallback,
|
| + m_attributeChangedCallback,
|
| + m_observedAttributes);
|
| }
|
|
|
| } // namespace blink
|
|
|