summaryrefslogtreecommitdiffstats
path: root/dom/bindings/BindingUtils.cpp
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2021-01-19 08:08:18 +0000
committerMoonchild <moonchild@palemoon.org>2021-01-19 08:08:18 +0000
commitc76214f0b54cf74b69d0fb4afa0d2eca2e898a98 (patch)
tree15ee2e9776727ecabcdc52d06de55dfd576485c1 /dom/bindings/BindingUtils.cpp
parent810c2bf8080da2bc8ec4efb05223fea31817944b (diff)
parent75286e68d703b1d8a4e0a7c72ce45d089024c124 (diff)
downloadUXP-c76214f0b54cf74b69d0fb4afa0d2eca2e898a98.tar
UXP-c76214f0b54cf74b69d0fb4afa0d2eca2e898a98.tar.gz
UXP-c76214f0b54cf74b69d0fb4afa0d2eca2e898a98.tar.lz
UXP-c76214f0b54cf74b69d0fb4afa0d2eca2e898a98.tar.xz
UXP-c76214f0b54cf74b69d0fb4afa0d2eca2e898a98.zip
Master merge
This merges master into release to replace Redwood. # Conflicts: # CLOBBER # build/moz.configure/old.configure # config/milestone.txt # config/moz.build # config/system-headers # dom/abort/AbortController.cpp # dom/abort/AbortController.h # dom/abort/AbortSignal.cpp # dom/abort/AbortSignal.h # dom/abort/moz.build # dom/abort/tests/moz.build # dom/animation/KeyframeEffect.cpp # dom/base/CustomElementRegistry.cpp # dom/base/DocGroup.cpp # dom/base/ResizeObserverController.cpp # dom/base/ResizeObserverController.h # dom/base/nsContentUtils.cpp # dom/base/nsContentUtils.h # dom/base/nsDocument.cpp # dom/base/nsIDocument.h # dom/fetch/FetchObserver.cpp # dom/fetch/FetchObserver.h # dom/heapsnapshot/AutoMemMap.cpp # dom/heapsnapshot/AutoMemMap.h # dom/heapsnapshot/CoreDump.proto # dom/heapsnapshot/HeapSnapshot.cpp # dom/heapsnapshot/HeapSnapshotTempFileHelperChild.h # dom/heapsnapshot/HeapSnapshotTempFileHelperParent.cpp # dom/heapsnapshot/HeapSnapshotTempFileHelperParent.h # dom/heapsnapshot/PHeapSnapshotTempFileHelper.ipdl # dom/heapsnapshot/moz.build # dom/heapsnapshot/tests/gtest/moz.build # dom/html/nsGenericHTMLElement.h # dom/media/platforms/PlatformDecoderModule.h # dom/media/platforms/moz.build # dom/script/ModuleLoadRequest.cpp # dom/script/ModuleLoadRequest.h # dom/script/ModuleScript.cpp # dom/script/ModuleScript.h # dom/script/ScriptElement.cpp # dom/script/ScriptElement.h # dom/script/ScriptLoadHandler.cpp # dom/script/ScriptLoadHandler.h # dom/script/ScriptLoader.cpp # dom/script/ScriptLoader.h # dom/script/ScriptSettings.cpp # dom/script/ScriptSettings.h # dom/script/nsIScriptElement.h # dom/script/nsIScriptLoaderObserver.idl # dom/webidl/HTMLLinkElement.webidl # gfx/gl/moz.build # gfx/graphite2/src/moz.build # gfx/layers/moz.build # js/ductwork/inspector/moz.build # js/ductwork/moz.build # js/src/gc/Heap.h # js/src/moz.build # js/src/vm/UnboxedObject-inl.h # js/src/vm/UnboxedObject.cpp # js/src/vm/UnboxedObject.h # layout/base/crashtests/crashtests.list # layout/build/moz.build # layout/generic/AspectRatio.h # layout/generic/crashtests/crashtests.list # layout/reftests/bidi/reftest-stylo.list # layout/reftests/reftest-stylo.list # layout/reftests/table-bordercollapse/reftest.list # layout/reftests/writing-mode/reftest-stylo.list # layout/style/StyleSheet.cpp # layout/style/nsRuleNode.cpp # layout/style/nsStyleStruct.cpp # layout/style/nsStyleStruct.h # modules/libpref/init/all.js # nsprpub/pr/src/linking/prlink.c # parser/html/java/htmlparser/src/nu/validator/htmlparser/impl/AttributeName.java # parser/html/java/htmlparser/src/nu/validator/htmlparser/impl/ElementName.java # parser/html/nsHtml5AtomList.h # parser/html/nsHtml5AttributeName.cpp # parser/html/nsHtml5AttributeName.h # parser/html/nsHtml5ElementName.cpp # parser/html/nsHtml5ElementName.h # parser/html/nsHtml5TreeBuilderCppSupplement.h # parser/htmlparser/nsElementTable.cpp # parser/htmlparser/nsHTMLTagList.h # security/nss/lib/nss/nss.h # security/nss/lib/softoken/pkcs11.c # security/nss/lib/softoken/softkver.h # security/nss/lib/util/nssutil.h # testing/web-platform/tests/tools/html5lib/html5lib/html5parser.py # testing/web-platform/tests/tools/html5lib/html5lib/treebuilders/_base.py # toolkit/modules/AppConstants.jsm
Diffstat (limited to 'dom/bindings/BindingUtils.cpp')
-rw-r--r--dom/bindings/BindingUtils.cpp185
1 files changed, 184 insertions, 1 deletions
diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp
index 41ca6a629..a8884d6a4 100644
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -16,11 +15,14 @@
#include "mozilla/SizePrintfMacros.h"
#include "mozilla/Unused.h"
#include "mozilla/UseCounter.h"
+#include "mozilla/dom/DocGroup.h"
#include "AccessCheck.h"
#include "jsfriendapi.h"
+#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
+#include "nsHTMLTags.h"
#include "nsIDocShell.h"
#include "nsIDOMGlobalPropertyInitializer.h"
#include "nsIPermissionManager.h"
@@ -37,6 +39,7 @@
#include "nsGlobalWindow.h"
#include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/CustomElementRegistry.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/DOMErrorBinding.h"
#include "mozilla/dom/DOMException.h"
@@ -44,6 +47,7 @@
#include "mozilla/dom/HTMLObjectElement.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLSharedObjectElement.h"
+#include "mozilla/dom/HTMLElementBinding.h"
#include "mozilla/dom/HTMLEmbedElementBinding.h"
#include "mozilla/dom/HTMLAppletElementBinding.h"
#include "mozilla/dom/Promise.h"
@@ -62,6 +66,30 @@ namespace dom {
using namespace workers;
+// Forward declare GetConstructorObject methods.
+#define HTML_TAG(_tag, _classname, _interfacename) \
+namespace HTML##_interfacename##ElementBinding { \
+ JSObject* GetConstructorObject(JSContext*); \
+}
+#define HTML_OTHER(_tag)
+#include "nsHTMLTagList.h"
+#undef HTML_TAG
+#undef HTML_OTHER
+
+typedef JSObject* (*constructorGetterCallback)(JSContext*);
+
+// Mapping of html tag and GetConstructorObject methods.
+#define HTML_TAG(_tag, _classname, _interfacename) HTML##_interfacename##ElementBinding::GetConstructorObject,
+#define HTML_OTHER(_tag) nullptr,
+// We use eHTMLTag_foo (where foo is the tag) which is defined in nsHTMLTags.h
+// to index into this array.
+static const constructorGetterCallback sConstructorGetterCallback[] = {
+ HTMLUnknownElementBinding::GetConstructorObject,
+#include "nsHTMLTagList.h"
+#undef HTML_TAG
+#undef HTML_OTHER
+};
+
const JSErrorFormatString ErrorFormatString[] = {
#define MSG_DEF(_name, _argc, _exn, _str) \
{ #_name, _str, _argc, _exn },
@@ -3382,6 +3410,161 @@ GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
return true;
}
+// https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor
+already_AddRefed<nsGenericHTMLElement>
+CreateHTMLElement(const GlobalObject& aGlobal, const JS::CallArgs& aCallArgs,
+ JS::Handle<JSObject*> aGivenProto, ErrorResult& aRv)
+{
+ // Step 1.
+ nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
+ }
+
+ nsIDocument* doc = window->GetExtantDoc();
+ if (!doc) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
+ }
+
+ RefPtr<mozilla::dom::CustomElementRegistry> registry(window->CustomElements());
+ if (!registry) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
+ }
+
+ // Step 2 is in the code output by CGClassConstructor.
+ // Step 3.
+ JSContext* cx = aGlobal.Context();
+ JS::Rooted<JSObject*> newTarget(cx, &aCallArgs.newTarget().toObject());
+ CustomElementDefinition* definition =
+ registry->LookupCustomElementDefinition(cx, newTarget);
+ if (!definition) {
+ aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
+ return nullptr;
+ }
+
+ // The callee might be an Xray. Unwrap it to get actual callee.
+ JS::Rooted<JSObject*> callee(cx, js::CheckedUnwrap(&aCallArgs.callee()));
+ if (!callee) {
+ aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
+ return nullptr;
+ }
+
+ // And the actual callee might be in different compartment, so enter its
+ // compartment before getting the standard constructor object to compare to,
+ // so we get it from the same global as callee itself.
+ JSAutoCompartment ac(cx, callee);
+ int32_t tag = eHTMLTag_userdefined;
+ if (!definition->IsCustomBuiltIn()) {
+ // Step 4.
+ // If the definition is for an autonomous custom element, the active
+ // function should be HTMLElement.
+ JS::Rooted<JSObject*> constructor(cx, HTMLElementBinding::GetConstructorObject(cx));
+ if (!constructor) {
+ aRv.NoteJSContextException(cx);
+ return nullptr;
+ }
+
+ if (callee != constructor) {
+ aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
+ return nullptr;
+ }
+ } else {
+ // Step 5.
+ // If the definition is for a customized built-in element, the localName
+ // should be defined in the specification.
+ tag = nsHTMLTags::CaseSensitiveAtomTagToId(definition->mLocalName);
+ if (tag == eHTMLTag_userdefined) {
+ aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
+ return nullptr;
+ }
+
+ MOZ_ASSERT(tag <= NS_HTML_TAG_MAX, "tag is out of bounds");
+
+ // If the definition is for a customized built-in element, the active
+ // function should be the localname's element interface.
+ constructorGetterCallback cb = sConstructorGetterCallback[tag];
+ if (!cb) {
+ aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
+ return nullptr;
+ }
+
+ JS::Rooted<JSObject*> constructor(cx, cb(cx));
+ if (!constructor) {
+ aRv.NoteJSContextException(cx);
+ return nullptr;
+ }
+
+ if (callee != constructor) {
+ aRv.ThrowTypeError<MSG_ILLEGAL_CONSTRUCTOR>();
+ return nullptr;
+ }
+ }
+
+ RefPtr<mozilla::dom::NodeInfo> nodeInfo =
+ doc->NodeInfoManager()->GetNodeInfo(definition->mLocalName,
+ nullptr,
+ kNameSpaceID_XHTML,
+ nsIDOMNode::ELEMENT_NODE);
+ if (!nodeInfo) {
+ aRv.Throw(NS_ERROR_UNEXPECTED);
+ return nullptr;
+ }
+
+ // Step 6 and Step 7 are in the code output by CGClassConstructor.
+ // Step 8.
+ nsTArray<RefPtr<nsGenericHTMLElement>>& constructionStack =
+ definition->mConstructionStack;
+ if (constructionStack.IsEmpty()) {
+ RefPtr<nsGenericHTMLElement> newElement;
+ if (tag == eHTMLTag_userdefined) {
+ // Autonomous custom element.
+ newElement = NS_NewHTMLElement(nodeInfo.forget());
+ } else {
+ // Customized built-in element.
+ newElement = CreateHTMLElement(tag, nodeInfo.forget(), NOT_FROM_PARSER);
+ }
+
+ newElement->SetCustomElementData(
+ new CustomElementData(definition->mType, CustomElementData::State::eCustom));
+
+ newElement->SetCustomElementDefinition(definition);
+
+ return newElement.forget();
+ }
+
+ // Step 9.
+ RefPtr<nsGenericHTMLElement>& element = constructionStack.LastElement();
+
+ // Step 10.
+ if (element == ALEADY_CONSTRUCTED_MARKER) {
+ aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return nullptr;
+ }
+
+ // Step 11.
+ // Do prototype swizzling for upgrading a custom element here, for cases when
+ // we have a reflector already. If we don't have one yet, our caller will
+ // create it with the right proto (by calling DoGetOrCreateDOMReflector with
+ // that proto).
+ JS::Rooted<JSObject*> reflector(cx, element->GetWrapper());
+ if (reflector) {
+ // reflector might be in different compartment.
+ JSAutoCompartment ac(cx, reflector);
+ JS::Rooted<JSObject*> givenProto(cx, aGivenProto);
+ if (!JS_WrapObject(cx, &givenProto) ||
+ !JS_SetPrototype(cx, reflector, givenProto)) {
+ aRv.NoteJSContextException(cx);
+ return nullptr;
+ }
+ }
+
+ // Step 12 and Step 13.
+ return element.forget();
+}
+
#ifdef DEBUG
namespace binding_detail {
void