diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/bindings/js/JSHTMLElementCustom.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/bindings/js/JSHTMLElementCustom.cpp')
-rw-r--r-- | Source/WebCore/bindings/js/JSHTMLElementCustom.cpp | 95 |
1 files changed, 88 insertions, 7 deletions
diff --git a/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp b/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp index 4ee3fd9ef..43792a9d8 100644 --- a/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp +++ b/Source/WebCore/bindings/js/JSHTMLElementCustom.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,10 +10,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -26,27 +26,108 @@ #include "config.h" #include "JSHTMLElement.h" +#include "CustomElementRegistry.h" +#include "DOMWindow.h" #include "Document.h" #include "HTMLFormElement.h" +#include "JSCustomElementInterface.h" +#include "JSDOMConstructorBase.h" +#include "JSNodeCustom.h" +#include "ScriptExecutionContext.h" +#include <runtime/InternalFunction.h> #include <runtime/JSWithScope.h> namespace WebCore { using namespace JSC; +EncodedJSValue JSC_HOST_CALL constructJSHTMLElement(ExecState& exec) +{ + VM& vm = exec.vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + + auto* jsConstructor = jsCast<JSDOMConstructorBase*>(exec.jsCallee()); + ASSERT(jsConstructor); + + auto* context = jsConstructor->scriptExecutionContext(); + if (!context) + return throwConstructorScriptExecutionContextUnavailableError(exec, scope, "HTMLElement"); + ASSERT(context->isDocument()); + + JSValue newTargetValue = exec.thisValue(); + auto* globalObject = jsConstructor->globalObject(); + JSValue htmlElementConstructorValue = JSHTMLElement::getConstructor(vm, globalObject); + if (newTargetValue == htmlElementConstructorValue) + return throwVMTypeError(&exec, scope, ASCIILiteral("new.target is not a valid custom element constructor")); + + auto& document = downcast<Document>(*context); + + auto* window = document.domWindow(); + if (!window) + return throwVMTypeError(&exec, scope, ASCIILiteral("new.target is not a valid custom element constructor")); + + auto* registry = window->customElementRegistry(); + if (!registry) + return throwVMTypeError(&exec, scope, ASCIILiteral("new.target is not a valid custom element constructor")); + + JSObject* newTarget = newTargetValue.getObject(); + auto* elementInterface = registry->findInterface(newTarget); + if (!elementInterface) + return throwVMTypeError(&exec, scope, ASCIILiteral("new.target does not define a custom element")); + + if (!elementInterface->isUpgradingElement()) { + Structure* baseStructure = getDOMStructure<JSHTMLElement>(vm, *globalObject); + auto* newElementStructure = InternalFunction::createSubclassStructure(&exec, newTargetValue, baseStructure); + RETURN_IF_EXCEPTION(scope, encodedJSValue()); + + Ref<HTMLElement> element = HTMLElement::create(elementInterface->name(), document); + element->setIsDefinedCustomElement(*elementInterface); + auto* jsElement = JSHTMLElement::create(newElementStructure, globalObject, element.get()); + cacheWrapper(globalObject->world(), element.ptr(), jsElement); + return JSValue::encode(jsElement); + } + + Element* elementToUpgrade = elementInterface->lastElementInConstructionStack(); + if (!elementToUpgrade) { + throwInvalidStateError(exec, scope, ASCIILiteral("Cannot instantiate a custom element inside its own constrcutor during upgrades")); + return JSValue::encode(jsUndefined()); + } + + JSValue elementWrapperValue = toJS(&exec, jsConstructor->globalObject(), *elementToUpgrade); + ASSERT(elementWrapperValue.isObject()); + + JSValue newPrototype = newTarget->get(&exec, vm.propertyNames->prototype); + RETURN_IF_EXCEPTION(scope, encodedJSValue()); + + JSObject* elementWrapperObject = asObject(elementWrapperValue); + JSObject::setPrototype(elementWrapperObject, &exec, newPrototype, true /* shouldThrowIfCantSet */); + RETURN_IF_EXCEPTION(scope, encodedJSValue()); + + elementInterface->didUpgradeLastElementInConstructionStack(); + + return JSValue::encode(elementWrapperValue); +} + JSScope* JSHTMLElement::pushEventHandlerScope(ExecState* exec, JSScope* scope) const { - HTMLElement& element = impl(); + HTMLElement& element = wrapped(); // The document is put on first, fall back to searching it only after the element and form. - scope = JSWithScope::create(exec, asObject(toJS(exec, globalObject(), &element.document())), scope); + // FIXME: This probably may use the wrong global object. If this is called from a native + // function, then it would be correct but not optimal since the native function would *know* + // the global object. But, it may be that globalObject() is more correct. + // https://bugs.webkit.org/show_bug.cgi?id=134932 + VM& vm = exec->vm(); + JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); + + scope = JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), element.document())), scope); // The form is next, searched before the document, but after the element itself. if (HTMLFormElement* form = element.form()) - scope = JSWithScope::create(exec, asObject(toJS(exec, globalObject(), form)), scope); + scope = JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), *form)), scope); // The element is on top, searched first. - return JSWithScope::create(exec, asObject(toJS(exec, globalObject(), &element)), scope); + return JSWithScope::create(vm, lexicalGlobalObject, asObject(toJS(exec, globalObject(), element)), scope); } } // namespace WebCore |