From a2b56b295b8bd089b74c5d93148edafe7e6da912 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Wed, 1 Jan 2020 14:56:19 -0500 Subject: Bug 1276438 part 1. Move the implementation of the .body getter from nsHTMLDocument to nsIDocument. Tag UXP Issue #1344 Tag UXP Issue #252 --- dom/base/nsDocument.cpp | 20 ++++++++++++++++++++ dom/base/nsIDocument.h | 4 ++++ dom/html/nsHTMLDocument.cpp | 20 -------------------- dom/html/nsHTMLDocument.h | 2 +- 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index afe88a454..83c2e5bb7 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -6536,6 +6536,26 @@ nsIDocument::GetHtmlChildElement(nsIAtom* aTag) return nullptr; } +nsGenericHTMLElement* +nsIDocument::GetBody() +{ + Element* html = GetHtmlElement(); + if (!html) { + return nullptr; + } + + for (nsIContent* child = html->GetFirstChild(); + child; + child = child->GetNextSibling()) { + if (child->IsHTMLElement(nsGkAtoms::body) || + child->IsHTMLElement(nsGkAtoms::frameset)) { + return static_cast(child); + } + } + + return nullptr; +} + Element* nsDocument::GetTitleElement() { diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index fdaee39ca..b3879c624 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -61,6 +61,7 @@ class nsFrameLoader; class nsHTMLCSSStyleSheet; class nsHTMLDocument; class nsHTMLStyleSheet; +class nsGenericHTMLElement; class nsIAtom; class nsIBFCacheEntry; class nsIChannel; @@ -1036,6 +1037,9 @@ public: Element* GetHeadElement() { return GetHtmlChildElement(nsGkAtoms::head); } + // Get the "body" in the sense of document.body: The first or + // that's a child of a root + nsGenericHTMLElement* GetBody(); /** * Accessors to the collection of stylesheets owned by this document. diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index 0f2d90673..23c73298d 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -1013,26 +1013,6 @@ nsHTMLDocument::SetDomain(const nsAString& aDomain, ErrorResult& rv) rv = NodePrincipal()->SetDomain(newURI); } -nsGenericHTMLElement* -nsHTMLDocument::GetBody() -{ - Element* html = GetHtmlElement(); - if (!html) { - return nullptr; - } - - for (nsIContent* child = html->GetFirstChild(); - child; - child = child->GetNextSibling()) { - if (child->IsHTMLElement(nsGkAtoms::body) || - child->IsHTMLElement(nsGkAtoms::frameset)) { - return static_cast(child); - } - } - - return nullptr; -} - NS_IMETHODIMP nsHTMLDocument::GetBody(nsIDOMHTMLElement** aBody) { diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h index 1fa81f6cd..02fc22d42 100644 --- a/dom/html/nsHTMLDocument.h +++ b/dom/html/nsHTMLDocument.h @@ -175,7 +175,7 @@ public: JS::MutableHandle aRetval, mozilla::ErrorResult& rv); void GetSupportedNames(nsTArray& aNames); - nsGenericHTMLElement *GetBody(); + using nsIDocument::GetBody; void SetBody(nsGenericHTMLElement* aBody, mozilla::ErrorResult& rv); mozilla::dom::HTMLSharedElement *GetHead() { return static_cast(GetHeadElement()); -- cgit v1.2.3 From 32f3f8826f396fd17c1c77770d073d0abf15c904 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Wed, 1 Jan 2020 15:04:58 -0500 Subject: Bug 1276438 part 2. Move the implementation of the .body setter from nsHTMLDocument to nsIDocument. Tag UXP Issue #1344 Tag UXP Issue #252 --- dom/base/nsDocument.cpp | 25 +++++++++++++++++++++++++ dom/base/nsIDocument.h | 2 ++ dom/html/nsHTMLDocument.cpp | 25 ------------------------- dom/html/nsHTMLDocument.h | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 83c2e5bb7..69cbff16c 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -6556,6 +6556,31 @@ nsIDocument::GetBody() return nullptr; } +void +nsIDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv) +{ + nsCOMPtr root = GetRootElement(); + + // The body element must be either a body tag or a frameset tag. And we must + // have a html root tag, otherwise GetBody will not return the newly set + // body. + if (!newBody || + !newBody->IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset) || + !root || !root->IsHTMLElement() || + !root->IsHTMLElement(nsGkAtoms::html)) { + rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); + return; + } + + // Use DOM methods so that we pass through the appropriate security checks. + nsCOMPtr currentBody = GetBodyElement(); + if (currentBody) { + root->ReplaceChild(*newBody, *currentBody, rv); + } else { + root->AppendChild(*newBody, rv); + } +} + Element* nsDocument::GetTitleElement() { diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index b3879c624..e44ab047e 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -1040,6 +1040,8 @@ public: // Get the "body" in the sense of document.body: The first or // that's a child of a root nsGenericHTMLElement* GetBody(); + // Set the "body" in the sense of document.body. + void SetBody(nsGenericHTMLElement* aBody, mozilla::ErrorResult& rv); /** * Accessors to the collection of stylesheets owned by this document. diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index 23c73298d..1eeef737a 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -1034,31 +1034,6 @@ nsHTMLDocument::SetBody(nsIDOMHTMLElement* aBody) return rv.StealNSResult(); } -void -nsHTMLDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv) -{ - nsCOMPtr root = GetRootElement(); - - // The body element must be either a body tag or a frameset tag. And we must - // have a html root tag, otherwise GetBody will not return the newly set - // body. - if (!newBody || - !newBody->IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset) || - !root || !root->IsHTMLElement() || - !root->IsHTMLElement(nsGkAtoms::html)) { - rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); - return; - } - - // Use DOM methods so that we pass through the appropriate security checks. - nsCOMPtr currentBody = GetBodyElement(); - if (currentBody) { - root->ReplaceChild(*newBody, *currentBody, rv); - } else { - root->AppendChild(*newBody, rv); - } -} - NS_IMETHODIMP nsHTMLDocument::GetHead(nsIDOMHTMLHeadElement** aHead) { diff --git a/dom/html/nsHTMLDocument.h b/dom/html/nsHTMLDocument.h index 02fc22d42..c9e46b3fa 100644 --- a/dom/html/nsHTMLDocument.h +++ b/dom/html/nsHTMLDocument.h @@ -176,7 +176,7 @@ public: mozilla::ErrorResult& rv); void GetSupportedNames(nsTArray& aNames); using nsIDocument::GetBody; - void SetBody(nsGenericHTMLElement* aBody, mozilla::ErrorResult& rv); + using nsIDocument::SetBody; mozilla::dom::HTMLSharedElement *GetHead() { return static_cast(GetHeadElement()); } -- cgit v1.2.3 From ce285b6f2d48ce945b194fd7982cd6a5a306e939 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Wed, 1 Jan 2020 15:08:37 -0500 Subject: Bug 1276438 part 3. Align the .body setter with the spec a bit better. There are two changes here: 1) We allow setting .body even if the root element is not an . This is what the spec says to do, and what we used to do before the changes in bug 366200. No tests for this yet, pending https://github.com/whatwg/html/issues/3403 getting resolved. 2) We use GetBody(), not GetBodyElement(), to look for an existing thing to replace. This matters if there are s involved. Tag UXP Issue #1344 Tag UXP Issue #252 --- dom/base/nsDocument.cpp | 8 ++-- .../dom-tree-accessors/Document.body.html | 50 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 69cbff16c..3faa39ab3 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -6562,18 +6562,16 @@ nsIDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv) nsCOMPtr root = GetRootElement(); // The body element must be either a body tag or a frameset tag. And we must - // have a html root tag, otherwise GetBody will not return the newly set - // body. + // have a root element to be able to add kids to it. if (!newBody || !newBody->IsAnyOfHTMLElements(nsGkAtoms::body, nsGkAtoms::frameset) || - !root || !root->IsHTMLElement() || - !root->IsHTMLElement(nsGkAtoms::html)) { + !root) { rv.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); return; } // Use DOM methods so that we pass through the appropriate security checks. - nsCOMPtr currentBody = GetBodyElement(); + nsCOMPtr currentBody = GetBody(); if (currentBody) { root->ReplaceChild(*newBody, *currentBody, rv); } else { diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html index 07f1edf93..7d8548885 100644 --- a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html +++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html @@ -166,4 +166,54 @@ test(function() { doc.body = new_frameset; assert_equals(doc.body, new_frameset, "test6-3, append frameset to a new document"); }, "Setting document.body to a new frameset element."); + +test(function() { + var doc = createDocument(); + var html = doc.appendChild(doc.createElement("html")); + var f = + html.appendChild(doc.createElement("frameset")); + assert_equals(doc.body, f); + + var b = doc.createElement("body"); + doc.body = b; + + assert_equals(f.parentNode, null, + "Frameset should have been removed from the tree"); + assert_equals(doc.body, b, "Body should be the new doc.body"); +}, "Setting document.body to a body will replace an existing frameset if there is one."); + +test(function() { + var doc = createDocument(); + var html = doc.appendChild(doc.createElement("html")); + var b = + html.appendChild(doc.createElement("body")); + assert_equals(doc.body, b); + + var f = doc.createElement("frameset"); + doc.body = f; + + assert_equals(b.parentNode, null, + "Body should have been removed from the tree"); + assert_equals(doc.body, f, "Frameset should be the new doc.body"); +}, "Setting document.body to a frameset will replace an existing body if there is one."); + +test(function() { + var doc = createDocument(); + var html = doc.appendChild(doc.createElement("html")); + var b = + html.appendChild(doc.createElement("body")); + var f1 = html.appendChild(doc.createElement("frameset")); + assert_equals(doc.body, b); + + var f2 = doc.createElement("frameset"); + doc.body = f2; + + assert_equals(b.parentNode, null, + "Body should have been removed from the tree"); + assert_equals(f1.parentNode, html, + "Frameset following body should still be in the tree."); + assert_equals(doc.body, f2, "New frameset should be the new doc.body"); + assert_equals(f2.nextSibling, f1, "New frameset should have replaced the body"); +}, "Setting document.body to a frameset will replace the first existing body/frameset."); + -- cgit v1.2.3 From bc8543bf793b5c203600c57565214b5e20f54592 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Tue, 7 Jan 2020 20:27:27 -0500 Subject: Bug 1271549 - Remove details and summary preference. Tag UXP Issue #1344 --- dom/html/HTMLDetailsElement.cpp | 30 +--------------------- dom/html/HTMLDetailsElement.h | 2 -- dom/html/HTMLSummaryElement.cpp | 12 +-------- dom/webidl/EventHandler.webidl | 1 - dom/webidl/HTMLDetailsElement.webidl | 1 - layout/base/nsCSSFrameConstructor.cpp | 8 ++---- layout/generic/crashtests/crashtests.list | 16 ++++++------ layout/generic/nsContainerFrame.cpp | 10 +++----- .../details-summary/disabled-no-summary-ref.html | 11 -------- .../disabled-single-summary-ref.html | 12 --------- layout/reftests/details-summary/reftest-stylo.list | 6 ----- layout/reftests/details-summary/reftest.list | 7 ----- layout/style/nsLayoutStylesheetCache.cpp | 10 ++------ modules/libpref/init/all.js | 3 --- .../web-platform/meta/html/dom/interfaces.html.ini | 2 +- .../meta/html/dom/reflection-misc.html.ini | 2 +- .../the-details-element/details.html.ini | 3 --- .../the-details-element/toggleEvent.html.ini | 3 --- .../meta/html/semantics/interfaces.html.ini | 2 +- testing/web-platform/meta/svg/interfaces.html.ini | 1 - 20 files changed, 21 insertions(+), 121 deletions(-) delete mode 100644 layout/reftests/details-summary/disabled-no-summary-ref.html delete mode 100644 layout/reftests/details-summary/disabled-single-summary-ref.html delete mode 100644 testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini delete mode 100644 testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini diff --git a/dom/html/HTMLDetailsElement.cpp b/dom/html/HTMLDetailsElement.cpp index ed20b50ca..8619b1450 100644 --- a/dom/html/HTMLDetailsElement.cpp +++ b/dom/html/HTMLDetailsElement.cpp @@ -6,39 +6,11 @@ #include "mozilla/dom/HTMLDetailsElement.h" #include "mozilla/dom/HTMLDetailsElementBinding.h" -#include "mozilla/dom/HTMLUnknownElement.h" -#include "mozilla/Preferences.h" - -// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Details) to add pref check. -nsGenericHTMLElement* -NS_NewHTMLDetailsElement(already_AddRefed&& aNodeInfo, - mozilla::dom::FromParser aFromParser) -{ - if (!mozilla::dom::HTMLDetailsElement::IsDetailsEnabled()) { - return new mozilla::dom::HTMLUnknownElement(aNodeInfo); - } - - return new mozilla::dom::HTMLDetailsElement(aNodeInfo); -} +NS_IMPL_NS_NEW_HTML_ELEMENT(Details) namespace mozilla { namespace dom { -/* static */ bool -HTMLDetailsElement::IsDetailsEnabled() -{ - static bool isDetailsEnabled = false; - static bool added = false; - - if (!added) { - Preferences::AddBoolVarCache(&isDetailsEnabled, - "dom.details_element.enabled"); - added = true; - } - - return isDetailsEnabled; -} - HTMLDetailsElement::~HTMLDetailsElement() { } diff --git a/dom/html/HTMLDetailsElement.h b/dom/html/HTMLDetailsElement.h index 5a3af27b4..6adf567bf 100644 --- a/dom/html/HTMLDetailsElement.h +++ b/dom/html/HTMLDetailsElement.h @@ -23,8 +23,6 @@ class HTMLDetailsElement final : public nsGenericHTMLElement public: using NodeInfo = mozilla::dom::NodeInfo; - static bool IsDetailsEnabled(); - explicit HTMLDetailsElement(already_AddRefed& aNodeInfo) : nsGenericHTMLElement(aNodeInfo) { diff --git a/dom/html/HTMLSummaryElement.cpp b/dom/html/HTMLSummaryElement.cpp index ee3c07b20..42ead6b87 100644 --- a/dom/html/HTMLSummaryElement.cpp +++ b/dom/html/HTMLSummaryElement.cpp @@ -14,17 +14,7 @@ #include "mozilla/TextEvents.h" #include "nsFocusManager.h" -// Expand NS_IMPL_NS_NEW_HTML_ELEMENT(Summary) to add pref check. -nsGenericHTMLElement* -NS_NewHTMLSummaryElement(already_AddRefed&& aNodeInfo, - mozilla::dom::FromParser aFromParser) -{ - if (!mozilla::dom::HTMLDetailsElement::IsDetailsEnabled()) { - return new mozilla::dom::HTMLUnknownElement(aNodeInfo); - } - - return new mozilla::dom::HTMLSummaryElement(aNodeInfo); -} +NS_IMPL_NS_NEW_HTML_ELEMENT(Summary) namespace mozilla { namespace dom { diff --git a/dom/webidl/EventHandler.webidl b/dom/webidl/EventHandler.webidl index b92e3a2bb..484a8e95c 100644 --- a/dom/webidl/EventHandler.webidl +++ b/dom/webidl/EventHandler.webidl @@ -94,7 +94,6 @@ interface GlobalEventHandlers { [Pref="dom.select_events.enabled"] attribute EventHandler onselectstart; - [Pref="dom.details_element.enabled"] attribute EventHandler ontoggle; // Pointer events handlers diff --git a/dom/webidl/HTMLDetailsElement.webidl b/dom/webidl/HTMLDetailsElement.webidl index 133ecf125..104606eb1 100644 --- a/dom/webidl/HTMLDetailsElement.webidl +++ b/dom/webidl/HTMLDetailsElement.webidl @@ -11,7 +11,6 @@ * and create derivative works of this document. */ -[Pref="dom.details_element.enabled"] interface HTMLDetailsElement : HTMLElement { [SetterThrows] attribute boolean open; diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index ec676ca92..34cfc6b59 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3563,10 +3563,6 @@ nsCSSFrameConstructor::FindHTMLData(Element* aElement, return nullptr; } - if (aTag == nsGkAtoms::details && !HTMLDetailsElement::IsDetailsEnabled()) { - return nullptr; - } - static const FrameConstructionDataByTag sHTMLData[] = { SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData), SIMPLE_TAG_CHAIN(mozgeneratedcontentimage, @@ -5788,7 +5784,7 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState // ::before and ::after); we always want to create "internal" anonymous // content. auto* details = HTMLDetailsElement::FromContentOrNull(parent); - if (details && details->IsDetailsEnabled() && !details->Open() && + if (details && !details->Open() && (!aContent->IsRootOfNativeAnonymousSubtree() || aContent->IsGeneratedContentContainerForBefore() || aContent->IsGeneratedContentContainerForAfter())) { @@ -5956,7 +5952,7 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState } FrameConstructionItem* item = nullptr; - if (details && details->IsDetailsEnabled() && details->Open()) { + if (details && details->Open()) { auto* summary = HTMLSummaryElement::FromContentOrNull(aContent); if (summary && summary->IsMainSummary()) { // If details is open, the main summary needs to be rendered as if it is diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list index 183556ab9..a3c0d62c6 100644 --- a/layout/generic/crashtests/crashtests.list +++ b/layout/generic/crashtests/crashtests.list @@ -606,19 +606,19 @@ pref(layout.css.grid.enabled,true) load 1225376.html pref(layout.css.grid.enabled,true) load 1225592.html load 1229437-1.html load 1229437-2.html -pref(dom.details_element.enabled,true) load details-containing-only-text.html -pref(dom.details_element.enabled,true) load details-display-none-summary-1.html -pref(dom.details_element.enabled,true) load details-display-none-summary-2.html -pref(dom.details_element.enabled,true) load details-display-none-summary-3.html -pref(dom.details_element.enabled,true) load details-open-overflow-auto.html -pref(dom.details_element.enabled,true) load details-open-overflow-hidden.html -pref(dom.details_element.enabled,true) load details-three-columns.html +load details-containing-only-text.html +load details-display-none-summary-1.html +load details-display-none-summary-2.html +load details-display-none-summary-3.html +load details-open-overflow-auto.html +load details-open-overflow-hidden.html +load details-three-columns.html load first-letter-638937-1.html load first-letter-638937-2.html load flex-nested-abspos-1.html pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) asserts(0-100) load font-inflation-762332.html # bug 762332 load outline-on-frameset.xhtml -pref(dom.details_element.enabled,true) load summary-position-out-of-flow.html +load summary-position-out-of-flow.html load text-overflow-bug666751-1.html load text-overflow-bug666751-2.html load text-overflow-bug670564.xhtml diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index abf687c9b..afc4ed96f 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -1890,12 +1890,10 @@ nsContainerFrame::RenumberFrameAndDescendants(int32_t* aOrdinal, } // Do not renumber list for summary elements. - if (HTMLDetailsElement::IsDetailsEnabled()) { - HTMLSummaryElement* summary = - HTMLSummaryElement::FromContent(kid->GetContent()); - if (summary && summary->IsMainSummary()) { - return false; - } + HTMLSummaryElement* summary = + HTMLSummaryElement::FromContent(kid->GetContent()); + if (summary && summary->IsMainSummary()) { + return false; } bool kidRenumberedABullet = false; diff --git a/layout/reftests/details-summary/disabled-no-summary-ref.html b/layout/reftests/details-summary/disabled-no-summary-ref.html deleted file mode 100644 index 6ecdbcdc0..000000000 --- a/layout/reftests/details-summary/disabled-no-summary-ref.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - -
-

This is the details.

-
- - diff --git a/layout/reftests/details-summary/disabled-single-summary-ref.html b/layout/reftests/details-summary/disabled-single-summary-ref.html deleted file mode 100644 index f643af6dc..000000000 --- a/layout/reftests/details-summary/disabled-single-summary-ref.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - -
-
Summary
-

This is the details.

-
- - diff --git a/layout/reftests/details-summary/reftest-stylo.list b/layout/reftests/details-summary/reftest-stylo.list index e23b1206b..2c6ec0d7b 100644 --- a/layout/reftests/details-summary/reftest-stylo.list +++ b/layout/reftests/details-summary/reftest-stylo.list @@ -1,10 +1,4 @@ # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing -default-preferences pref(dom.details_element.enabled,true) - -# Disable
and -pref(dom.details_element.enabled,false) == single-summary.html single-summary.html -pref(dom.details_element.enabled,false) == open-single-summary.html open-single-summary.html -pref(dom.details_element.enabled,false) == no-summary.html no-summary.html # Basic handling == multiple-summary.html multiple-summary.html diff --git a/layout/reftests/details-summary/reftest.list b/layout/reftests/details-summary/reftest.list index 92b1404b5..e96581ad4 100644 --- a/layout/reftests/details-summary/reftest.list +++ b/layout/reftests/details-summary/reftest.list @@ -1,10 +1,3 @@ -default-preferences pref(dom.details_element.enabled,true) - -# Disable
and -pref(dom.details_element.enabled,false) == single-summary.html disabled-single-summary-ref.html -pref(dom.details_element.enabled,false) == open-single-summary.html disabled-single-summary-ref.html -pref(dom.details_element.enabled,false) == no-summary.html disabled-no-summary-ref.html - # Basic handling == multiple-summary.html single-summary.html == open-multiple-summary.html open-multiple-summary-ref.html diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index e8c6d09d7..0e6bc35ee 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -122,11 +122,6 @@ nsLayoutStylesheetCache::UASheet() StyleSheet* nsLayoutStylesheetCache::HTMLSheet() { - if (!mHTMLSheet) { - LoadSheetURL("resource://gre-resources/html.css", - &mHTMLSheet, eAgentSheetFeatures, eCrash); - } - return mHTMLSheet; } @@ -322,6 +317,8 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache(StyleBackendType aType) // per-profile, since they're profile-invariant. LoadSheetURL("resource://gre-resources/counterstyles.css", &mCounterStylesSheet, eAgentSheetFeatures, eCrash); + LoadSheetURL("resource://gre-resources/html.css", + &mHTMLSheet, eAgentSheetFeatures, eCrash); LoadSheetURL("chrome://global/content/minimal-xul.css", &mMinimalXULSheet, eAgentSheetFeatures, eCrash); LoadSheetURL("resource://gre-resources/quirk.css", @@ -382,8 +379,6 @@ nsLayoutStylesheetCache::For(StyleBackendType aType) // "layout.css.example-pref.enabled"); Preferences::RegisterCallback(&DependentPrefChanged, "layout.css.grid.enabled"); - Preferences::RegisterCallback(&DependentPrefChanged, - "dom.details_element.enabled"); } return cache; @@ -555,7 +550,6 @@ nsLayoutStylesheetCache::DependentPrefChanged(const char* aPref, void* aData) gStyleCache_Servo ? &gStyleCache_Servo->sheet_ : nullptr); INVALIDATE(mUASheet); // for layout.css.grid.enabled - INVALIDATE(mHTMLSheet); // for dom.details_element.enabled #undef INVALIDATE } diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index c5daf9213..dacfe6e49 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5328,9 +5328,6 @@ pref("dom.audiochannel.mutedByDefault", false); // HTML element pref("dom.dialog_element.enabled", false); -// Enable
and tags. -pref("dom.details_element.enabled", true); - // Secure Element API #ifdef MOZ_SECUREELEMENT pref("dom.secureelement.enabled", false); diff --git a/testing/web-platform/meta/html/dom/interfaces.html.ini b/testing/web-platform/meta/html/dom/interfaces.html.ini index 16a03337e..db6a464d0 100644 --- a/testing/web-platform/meta/html/dom/interfaces.html.ini +++ b/testing/web-platform/meta/html/dom/interfaces.html.ini @@ -1,6 +1,6 @@ [interfaces.html] type: testharness - prefs: [dom.forms.inputmode:true, dom.details_element.enabled:true, dom.dialog_element.enabled:true] + prefs: [dom.forms.inputmode:true, dom.dialog_element.enabled:true] [Document interface: attribute domain] expected: FAIL diff --git a/testing/web-platform/meta/html/dom/reflection-misc.html.ini b/testing/web-platform/meta/html/dom/reflection-misc.html.ini index b0909cc6d..bc65d4191 100644 --- a/testing/web-platform/meta/html/dom/reflection-misc.html.ini +++ b/testing/web-platform/meta/html/dom/reflection-misc.html.ini @@ -1,6 +1,6 @@ [reflection-misc.html] type: testharness - prefs: [dom.details_element.enabled: true, dom.dialog_element.enabled: true] + prefs: [dom.dialog_element.enabled: true] [html.tabIndex: setAttribute() to object "3" followed by getAttribute()] expected: FAIL diff --git a/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini b/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini deleted file mode 100644 index 6ffca742c..000000000 --- a/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/details.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[details.html] - type: testharness - prefs: [dom.details_element.enabled:true] diff --git a/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini b/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini deleted file mode 100644 index 335ffd5b3..000000000 --- a/testing/web-platform/meta/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[toggleEvent.html] - type: testharness - prefs: [dom.details_element.enabled:true] diff --git a/testing/web-platform/meta/html/semantics/interfaces.html.ini b/testing/web-platform/meta/html/semantics/interfaces.html.ini index 23f55fbe4..f191cad52 100644 --- a/testing/web-platform/meta/html/semantics/interfaces.html.ini +++ b/testing/web-platform/meta/html/semantics/interfaces.html.ini @@ -1,6 +1,6 @@ [interfaces.html] type: testharness - prefs: [dom.details_element.enabled: true, dom.dialog_element.enabled: true] + prefs: [dom.dialog_element.enabled: true] [Interfaces for image] expected: FAIL diff --git a/testing/web-platform/meta/svg/interfaces.html.ini b/testing/web-platform/meta/svg/interfaces.html.ini index 292ca6b74..410f20f69 100644 --- a/testing/web-platform/meta/svg/interfaces.html.ini +++ b/testing/web-platform/meta/svg/interfaces.html.ini @@ -1,6 +1,5 @@ [interfaces.html] type: testharness - prefs: [dom.details_element.enabled:true] [SVGGeometryElement interface: existence and properties of interface object] expected: FAIL -- cgit v1.2.3 From 2d31ebf6b6bba8c1b90982f687346e5c6a0ff6ef Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 21:24:22 -0500 Subject: Bug 1274159 - Part 1: Support looking up definitions by using constructor as a key; Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.cpp | 37 +++++++++++++++++++--- dom/base/CustomElementRegistry.h | 15 ++++++++- dom/bindings/test/test_bug560072.html | 5 +-- .../custom-elements/CustomElementRegistry.html.ini | 3 -- .../custom-element-registry/define.html.ini | 26 --------------- 5 files changed, 50 insertions(+), 36 deletions(-) delete mode 100644 testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 3f202d33b..43e4e7e2a 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -103,6 +103,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(CustomElementRegistry) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CustomElementRegistry) tmp->mCustomDefinitions.Clear(); + tmp->mConstructors.clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mWhenDefinedPromiseMap) NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER @@ -149,6 +150,11 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CustomElementRegistry) "mCustomDefinitions prototype", aClosure); } + for (ConstructorMap::Enum iter(tmp->mConstructors); !iter.empty(); iter.popFront()) { + aCallbacks.Trace(&iter.front().mutableKey(), + "mConstructors key", + aClosure); + } NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRACE_END @@ -183,6 +189,11 @@ CustomElementRegistry::Create(nsPIDOMWindowInner* aWindow) RefPtr customElementRegistry = new CustomElementRegistry(aWindow); + + if (!customElementRegistry->Init()) { + return nullptr; + } + return customElementRegistry.forget(); } @@ -241,6 +252,12 @@ CustomElementRegistry::~CustomElementRegistry() mozilla::DropJSObjects(this); } +bool +CustomElementRegistry::Init() +{ + return mConstructors.init(); +} + CustomElementDefinition* CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName, const nsAString* aIs) const @@ -609,9 +626,13 @@ CustomElementRegistry::Define(const nsAString& aName, * 4. If this CustomElementRegistry contains an entry with constructor constructor, * then throw a "NotSupportedError" DOMException and abort these steps. */ - // TODO: Step 3 of HTMLConstructor also needs a way to look up definition by - // using constructor. So I plans to figure out a solution to support both of - // them in bug 1274159. + const auto& ptr = mConstructors.lookup(constructorUnwrapped); + if (ptr) { + MOZ_ASSERT(mCustomDefinitions.Get(ptr->value()), + "Definition must be found in mCustomDefinitions"); + aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return; + } /** * 5. Let localName be name. @@ -767,8 +788,16 @@ CustomElementRegistry::Define(const nsAString& aName, /** * 12. Add definition to this CustomElementRegistry. */ + if (!mConstructors.put(constructorUnwrapped, nameAtom)) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + mCustomDefinitions.Put(nameAtom, definition); + MOZ_ASSERT(mCustomDefinitions.Count() == mConstructors.count(), + "Number of entries should be the same"); + /** * 13. 14. 15. Upgrade candidates */ @@ -853,4 +882,4 @@ CustomElementDefinition::CustomElementDefinition(nsIAtom* aType, } } // namespace dom -} // namespace mozilla \ No newline at end of file +} // namespace mozilla diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index ff803a054..9034dd7ea 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -7,13 +7,14 @@ #ifndef mozilla_dom_CustomElementRegistry_h #define mozilla_dom_CustomElementRegistry_h +#include "js/GCHashTable.h" #include "js/TypeDecls.h" #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/dom/FunctionBinding.h" #include "nsCycleCollectionParticipant.h" #include "nsWrapperCache.h" -#include "mozilla/dom/FunctionBinding.h" class nsDocument; @@ -173,6 +174,8 @@ private: explicit CustomElementRegistry(nsPIDOMWindowInner* aWindow); ~CustomElementRegistry(); + bool Init(); + /** * Registers an unresolved custom element that is a candidate for * upgrade when the definition is registered via registerElement. @@ -192,15 +195,25 @@ private: DefinitionMap; typedef nsClassHashtable> CandidateMap; + typedef JS::GCHashMap, + nsCOMPtr, + js::MovableCellHasher>, + js::SystemAllocPolicy> ConstructorMap; // Hashtable for custom element definitions in web components. // Custom prototypes are stored in the compartment where // registerElement was called. DefinitionMap mCustomDefinitions; + // Hashtable for looking up definitions by using constructor as key. + // Custom elements' name are stored here and we need to lookup + // mCustomDefinitions again to get definitions. + ConstructorMap mConstructors; + typedef nsRefPtrHashtable WhenDefinedPromiseMap; WhenDefinedPromiseMap mWhenDefinedPromiseMap; + // The "upgrade candidates map" from the web components spec. Maps from a // namespace id and local name to a list of elements to upgrade if that // element is registered as a custom element. diff --git a/dom/bindings/test/test_bug560072.html b/dom/bindings/test/test_bug560072.html index 82bb1c2c6..0eebff116 100644 --- a/dom/bindings/test/test_bug560072.html +++ b/dom/bindings/test/test_bug560072.html @@ -20,11 +20,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=560072 /** Test for Bug 560072 **/ is(document.body, - Object.getOwnPropertyDescriptor(HTMLDocument.prototype, "body").get.call(document), + Object.getOwnPropertyDescriptor(Document.prototype, "body").get.call(document), "Should get body out of property descriptor"); is(document.body, - Object.getOwnPropertyDescriptor(Object.getPrototypeOf(document), "body").get.call(document), + Object.getOwnPropertyDescriptor( + Object.getPrototypeOf(Object.getPrototypeOf(document)), "body").get.call(document), "Should get body out of property descriptor this way too"); diff --git a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini index 9e2bf7385..f62b64dfb 100644 --- a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini +++ b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini @@ -1,8 +1,5 @@ [CustomElementRegistry.html] type: testharness - [customElements.define must throw a NotSupportedError when there is already a custom element with the same class] - expected: FAIL - [customElements.define must get callbacks of the constructor prototype] expected: FAIL diff --git a/testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini b/testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini deleted file mode 100644 index 122abccd3..000000000 --- a/testing/web-platform/meta/custom-elements/custom-element-registry/define.html.ini +++ /dev/null @@ -1,26 +0,0 @@ -[define.html] - type: testharness - [If constructor is HTMLElement, should throw a TypeError] - expected: FAIL - - [If constructor is HTMLButtonElement, should throw a TypeError] - expected: FAIL - - [If constructor is HTMLImageElement, should throw a TypeError] - expected: FAIL - - [If constructor is HTMLMediaElement, should throw a TypeError] - expected: FAIL - - [If constructor is Image, should throw a TypeError] - expected: FAIL - - [If constructor is Audio, should throw a TypeError] - expected: FAIL - - [If constructor is Option, should throw a TypeError] - expected: FAIL - - [If the constructor is already defined, should throw a NotSupportedError] - expected: FAIL - -- cgit v1.2.3 From 244277a3fa428b70ba46cf611dbe1905733515eb Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Tue, 7 Jan 2020 20:45:38 -0500 Subject: Bug 1274159 - Part 2-1: Include the name of relevant interface in nsHTMLTagList.h; Tag UXP Issue #1344 --- dom/html/nsHTMLContentSink.cpp | 4 +- parser/htmlparser/nsHTMLTagList.h | 192 ++++++++++++++++++++------------------ parser/htmlparser/nsHTMLTags.cpp | 12 +-- parser/htmlparser/nsHTMLTags.h | 4 +- 4 files changed, 104 insertions(+), 108 deletions(-) diff --git a/dom/html/nsHTMLContentSink.cpp b/dom/html/nsHTMLContentSink.cpp index 3e8e019b8..6e808f87e 100644 --- a/dom/html/nsHTMLContentSink.cpp +++ b/dom/html/nsHTMLContentSink.cpp @@ -96,14 +96,12 @@ NS_NewHTMLNOTUSEDElement(already_AddRefed&& aNodeInfo, return nullptr; } -#define HTML_TAG(_tag, _classname) NS_NewHTML##_classname##Element, -#define HTML_HTMLELEMENT_TAG(_tag) NS_NewHTMLElement, +#define HTML_TAG(_tag, _classname, _interfacename) NS_NewHTML##_classname##Element, #define HTML_OTHER(_tag) NS_NewHTMLNOTUSEDElement, static const contentCreatorCallback sContentCreatorCallbacks[] = { NS_NewHTMLUnknownElement, #include "nsHTMLTagList.h" #undef HTML_TAG -#undef HTML_HTMLELEMENT_TAG #undef HTML_OTHER NS_NewHTMLUnknownElement }; diff --git a/parser/htmlparser/nsHTMLTagList.h b/parser/htmlparser/nsHTMLTagList.h index 7e1e207cc..f5e1da6c1 100644 --- a/parser/htmlparser/nsHTMLTagList.h +++ b/parser/htmlparser/nsHTMLTagList.h @@ -10,8 +10,8 @@ This file contains the list of all HTML tags. See nsHTMLTags.h for access to the enum values for tags. - It is designed to be used as inline input to nsHTMLTags.cpp and - nsHTMLContentSink *only* through the magic of C preprocessing. + It is designed to be used as input to various places that will define the + HTML_TAG macro in useful ways through the magic of C preprocessing. All entries must be enclosed in the macro HTML_TAG which will have cruel and unusual things done to it. @@ -19,11 +19,13 @@ It is recommended (but not strictly necessary) to keep all entries in alphabetical order. - The first argument to HTML_TAG is both the enum identifier of the - property and the string value. The second argument is the "creator" - method of the form NS_New$TAGNAMEElement, that will be used by + The first argument to HTML_TAG is the tag name. The second argument is the + "creator" method of the form NS_New$TAGNAMEElement, that will be used by nsHTMLContentSink.cpp to create a content object for a tag of that type. Use NOTUSED, if the particular tag has a non-standard creator. + The third argument is the interface name specified for this element + in the HTML specification. It can be empty if the relevant interface name + is "HTMLElement". The HTML_OTHER macro is for values in the nsHTMLTag enum that are not strictly tags. @@ -35,104 +37,106 @@ ** Break these invariants and bad things will happen. ** ******/ -HTML_TAG(a, Anchor) +#define HTML_HTMLELEMENT_TAG(_tag) HTML_TAG(_tag, , ) + +HTML_TAG(a, Anchor, Anchor) HTML_HTMLELEMENT_TAG(abbr) HTML_HTMLELEMENT_TAG(acronym) HTML_HTMLELEMENT_TAG(address) -HTML_TAG(applet, SharedObject) -HTML_TAG(area, Area) +HTML_TAG(applet, SharedObject, Applet) +HTML_TAG(area, Area, Area) HTML_HTMLELEMENT_TAG(article) HTML_HTMLELEMENT_TAG(aside) -HTML_TAG(audio, Audio) +HTML_TAG(audio, Audio, Audio) HTML_HTMLELEMENT_TAG(b) -HTML_TAG(base, Shared) +HTML_TAG(base, Shared, Base) HTML_HTMLELEMENT_TAG(basefont) HTML_HTMLELEMENT_TAG(bdo) -HTML_TAG(bgsound, Unknown) +HTML_TAG(bgsound, Unknown, Unknown) HTML_HTMLELEMENT_TAG(big) -HTML_TAG(blockquote, Shared) -HTML_TAG(body, Body) -HTML_TAG(br, BR) -HTML_TAG(button, Button) -HTML_TAG(canvas, Canvas) -HTML_TAG(caption, TableCaption) +HTML_TAG(blockquote, Shared, Quote) +HTML_TAG(body, Body, Body) +HTML_TAG(br, BR, BR) +HTML_TAG(button, Button, Button) +HTML_TAG(canvas, Canvas, Canvas) +HTML_TAG(caption, TableCaption, TableCaption) HTML_HTMLELEMENT_TAG(center) HTML_HTMLELEMENT_TAG(cite) HTML_HTMLELEMENT_TAG(code) -HTML_TAG(col, TableCol) -HTML_TAG(colgroup, TableCol) -HTML_TAG(content, Content) -HTML_TAG(data, Data) -HTML_TAG(datalist, DataList) +HTML_TAG(col, TableCol, TableCol) +HTML_TAG(colgroup, TableCol, TableCol) +HTML_TAG(content, Content, Content) +HTML_TAG(data, Data, Data) +HTML_TAG(datalist, DataList, DataList) HTML_HTMLELEMENT_TAG(dd) -HTML_TAG(del, Mod) -HTML_TAG(details, Details) +HTML_TAG(del, Mod, Mod) +HTML_TAG(details, Details, Details) HTML_HTMLELEMENT_TAG(dfn) -HTML_TAG(dialog, Dialog) -HTML_TAG(dir, Shared) -HTML_TAG(div, Div) -HTML_TAG(dl, SharedList) +HTML_TAG(dialog, Dialog, Dialog) +HTML_TAG(dir, Shared, Directory) +HTML_TAG(div, Div, Div) +HTML_TAG(dl, SharedList, DList) HTML_HTMLELEMENT_TAG(dt) HTML_HTMLELEMENT_TAG(em) -HTML_TAG(embed, SharedObject) -HTML_TAG(fieldset, FieldSet) +HTML_TAG(embed, SharedObject, Embed) +HTML_TAG(fieldset, FieldSet, FieldSet) HTML_HTMLELEMENT_TAG(figcaption) HTML_HTMLELEMENT_TAG(figure) -HTML_TAG(font, Font) +HTML_TAG(font, Font, Font) HTML_HTMLELEMENT_TAG(footer) -HTML_TAG(form, Form) -HTML_TAG(frame, Frame) -HTML_TAG(frameset, FrameSet) -HTML_TAG(h1, Heading) -HTML_TAG(h2, Heading) -HTML_TAG(h3, Heading) -HTML_TAG(h4, Heading) -HTML_TAG(h5, Heading) -HTML_TAG(h6, Heading) -HTML_TAG(head, Shared) +HTML_TAG(form, Form, Form) +HTML_TAG(frame, Frame, Frame) +HTML_TAG(frameset, FrameSet, FrameSet) +HTML_TAG(h1, Heading, Heading) +HTML_TAG(h2, Heading, Heading) +HTML_TAG(h3, Heading, Heading) +HTML_TAG(h4, Heading, Heading) +HTML_TAG(h5, Heading, Heading) +HTML_TAG(h6, Heading, Heading) +HTML_TAG(head, Shared, Head) HTML_HTMLELEMENT_TAG(header) HTML_HTMLELEMENT_TAG(hgroup) -HTML_TAG(hr, HR) -HTML_TAG(html, Shared) +HTML_TAG(hr, HR, HR) +HTML_TAG(html, Shared, Html) HTML_HTMLELEMENT_TAG(i) -HTML_TAG(iframe, IFrame) +HTML_TAG(iframe, IFrame, IFrame) HTML_HTMLELEMENT_TAG(image) -HTML_TAG(img, Image) -HTML_TAG(input, Input) -HTML_TAG(ins, Mod) +HTML_TAG(img, Image, Image) +HTML_TAG(input, Input, Input) +HTML_TAG(ins, Mod, Mod) HTML_HTMLELEMENT_TAG(kbd) -HTML_TAG(keygen, Span) -HTML_TAG(label, Label) -HTML_TAG(legend, Legend) -HTML_TAG(li, LI) -HTML_TAG(link, Link) -HTML_TAG(listing, Pre) +HTML_TAG(keygen, Span, Span) +HTML_TAG(label, Label, Label) +HTML_TAG(legend, Legend, Legend) +HTML_TAG(li, LI, LI) +HTML_TAG(link, Link, Link) +HTML_TAG(listing, Pre, Pre) HTML_HTMLELEMENT_TAG(main) -HTML_TAG(map, Map) +HTML_TAG(map, Map, Map) HTML_HTMLELEMENT_TAG(mark) -HTML_TAG(marquee, Div) -HTML_TAG(menu, Menu) -HTML_TAG(menuitem, MenuItem) -HTML_TAG(meta, Meta) -HTML_TAG(meter, Meter) -HTML_TAG(multicol, Unknown) +HTML_TAG(marquee, Div, Div) +HTML_TAG(menu, Menu, Menu) +HTML_TAG(menuitem, MenuItem, MenuItem) +HTML_TAG(meta, Meta, Meta) +HTML_TAG(meter, Meter, Meter) +HTML_TAG(multicol, Unknown, Unknown) HTML_HTMLELEMENT_TAG(nav) HTML_HTMLELEMENT_TAG(nobr) HTML_HTMLELEMENT_TAG(noembed) HTML_HTMLELEMENT_TAG(noframes) HTML_HTMLELEMENT_TAG(noscript) -HTML_TAG(object, Object) -HTML_TAG(ol, SharedList) -HTML_TAG(optgroup, OptGroup) -HTML_TAG(option, Option) -HTML_TAG(output, Output) -HTML_TAG(p, Paragraph) -HTML_TAG(param, Shared) -HTML_TAG(picture, Picture) +HTML_TAG(object, Object, Object) +HTML_TAG(ol, SharedList, OList) +HTML_TAG(optgroup, OptGroup, OptGroup) +HTML_TAG(option, Option, Option) +HTML_TAG(output, Output, Output) +HTML_TAG(p, Paragraph, Paragraph) +HTML_TAG(param, Shared, Param) +HTML_TAG(picture, Picture, Picture) HTML_HTMLELEMENT_TAG(plaintext) -HTML_TAG(pre, Pre) -HTML_TAG(progress, Progress) -HTML_TAG(q, Shared) +HTML_TAG(pre, Pre, Pre) +HTML_TAG(progress, Progress, Progress) +HTML_TAG(q, Shared, Quote) HTML_HTMLELEMENT_TAG(rb) HTML_HTMLELEMENT_TAG(rp) HTML_HTMLELEMENT_TAG(rt) @@ -140,38 +144,38 @@ HTML_HTMLELEMENT_TAG(rtc) HTML_HTMLELEMENT_TAG(ruby) HTML_HTMLELEMENT_TAG(s) HTML_HTMLELEMENT_TAG(samp) -HTML_TAG(script, Script) +HTML_TAG(script, Script, Script) HTML_HTMLELEMENT_TAG(section) -HTML_TAG(select, Select) -HTML_TAG(shadow, Shadow) +HTML_TAG(select, Select, Select) +HTML_TAG(shadow, Shadow, Shadow) HTML_HTMLELEMENT_TAG(small) -HTML_TAG(source, Source) -HTML_TAG(span, Span) +HTML_TAG(source, Source, Source) +HTML_TAG(span, Span, Span) HTML_HTMLELEMENT_TAG(strike) HTML_HTMLELEMENT_TAG(strong) -HTML_TAG(style, Style) +HTML_TAG(style, Style, Style) HTML_HTMLELEMENT_TAG(sub) -HTML_TAG(summary, Summary) +HTML_TAG(summary, Summary, ) HTML_HTMLELEMENT_TAG(sup) -HTML_TAG(table, Table) -HTML_TAG(tbody, TableSection) -HTML_TAG(td, TableCell) -HTML_TAG(textarea, TextArea) -HTML_TAG(tfoot, TableSection) -HTML_TAG(th, TableCell) -HTML_TAG(thead, TableSection) -HTML_TAG(template, Template) -HTML_TAG(time, Time) -HTML_TAG(title, Title) -HTML_TAG(tr, TableRow) -HTML_TAG(track, Track) +HTML_TAG(table, Table, Table) +HTML_TAG(tbody, TableSection, TableSection) +HTML_TAG(td, TableCell, TableCell) +HTML_TAG(textarea, TextArea, TextArea) +HTML_TAG(tfoot, TableSection, TableSection) +HTML_TAG(th, TableCell, TableCell) +HTML_TAG(thead, TableSection, TableSection) +HTML_TAG(template, Template, Template) +HTML_TAG(time, Time, Time) +HTML_TAG(title, Title, Title) +HTML_TAG(tr, TableRow, TableRow) +HTML_TAG(track, Track, Track) HTML_HTMLELEMENT_TAG(tt) HTML_HTMLELEMENT_TAG(u) -HTML_TAG(ul, SharedList) +HTML_TAG(ul, SharedList, UList) HTML_HTMLELEMENT_TAG(var) -HTML_TAG(video, Video) +HTML_TAG(video, Video, Video) HTML_HTMLELEMENT_TAG(wbr) -HTML_TAG(xmp, Pre) +HTML_TAG(xmp, Pre, Pre) /* These are not for tags. But they will be included in the nsHTMLTag @@ -185,3 +189,5 @@ HTML_OTHER(entity) HTML_OTHER(doctypeDecl) HTML_OTHER(markupDecl) HTML_OTHER(instruction) + +#undef HTML_HTMLELEMENT_TAG diff --git a/parser/htmlparser/nsHTMLTags.cpp b/parser/htmlparser/nsHTMLTags.cpp index d5a68d46a..e98d2c4cd 100644 --- a/parser/htmlparser/nsHTMLTags.cpp +++ b/parser/htmlparser/nsHTMLTags.cpp @@ -15,14 +15,12 @@ using namespace mozilla; // static array of unicode tag names -#define HTML_TAG(_tag, _classname) (u"" #_tag), -#define HTML_HTMLELEMENT_TAG(_tag) (u"" #_tag), +#define HTML_TAG(_tag, _classname, _interfacename) (u"" #_tag), #define HTML_OTHER(_tag) const char16_t* const nsHTMLTags::sTagUnicodeTable[] = { #include "nsHTMLTagList.h" }; #undef HTML_TAG -#undef HTML_HTMLELEMENT_TAG #undef HTML_OTHER // static array of tag atoms @@ -62,23 +60,19 @@ HTMLTagsHashCodeAtom(const void *key) void nsHTMLTags::RegisterAtoms(void) { -#define HTML_TAG(_tag, _classname) NS_STATIC_ATOM_BUFFER(Atombuffer_##_tag, #_tag) -#define HTML_HTMLELEMENT_TAG(_tag) NS_STATIC_ATOM_BUFFER(Atombuffer_##_tag, #_tag) +#define HTML_TAG(_tag, _classname, _interfacename) NS_STATIC_ATOM_BUFFER(Atombuffer_##_tag, #_tag) #define HTML_OTHER(_tag) #include "nsHTMLTagList.h" #undef HTML_TAG -#undef HTML_HTMLELEMENT_TAG #undef HTML_OTHER // static array of tag StaticAtom structs -#define HTML_TAG(_tag, _classname) NS_STATIC_ATOM(Atombuffer_##_tag, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1]), -#define HTML_HTMLELEMENT_TAG(_tag) NS_STATIC_ATOM(Atombuffer_##_tag, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1]), +#define HTML_TAG(_tag, _classname, _interfacename) NS_STATIC_ATOM(Atombuffer_##_tag, &nsHTMLTags::sTagAtomTable[eHTMLTag_##_tag - 1]), #define HTML_OTHER(_tag) static const nsStaticAtom sTagAtoms_info[] = { #include "nsHTMLTagList.h" }; #undef HTML_TAG -#undef HTML_HTMLELEMENT_TAG #undef HTML_OTHER // Fill in our static atom pointers diff --git a/parser/htmlparser/nsHTMLTags.h b/parser/htmlparser/nsHTMLTags.h index 8f0c86b4b..a2800df07 100644 --- a/parser/htmlparser/nsHTMLTags.h +++ b/parser/htmlparser/nsHTMLTags.h @@ -18,8 +18,7 @@ class nsIAtom; To change the list of tags, see nsHTMLTagList.h */ -#define HTML_TAG(_tag, _classname) eHTMLTag_##_tag, -#define HTML_HTMLELEMENT_TAG(_tag) eHTMLTag_##_tag, +#define HTML_TAG(_tag, _classname, _interfacename) eHTMLTag_##_tag, #define HTML_OTHER(_tag) eHTMLTag_##_tag, enum nsHTMLTag { /* this enum must be first and must be zero */ @@ -31,7 +30,6 @@ enum nsHTMLTag { eHTMLTag_userdefined }; #undef HTML_TAG -#undef HTML_HTMLELEMENT_TAG #undef HTML_OTHER // All tags before eHTMLTag_text are HTML tags -- cgit v1.2.3 From 5222f6e9daa4cb74b404f769b23510b3d600efd9 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 21:25:47 -0500 Subject: Bug 1274159 - Part 2-2: Support HTMLConstructor WebIDL extended attribute for custom elements; Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.cpp | 17 +++ dom/base/CustomElementRegistry.h | 7 + dom/bindings/BindingUtils.cpp | 153 +++++++++++++++++++ dom/bindings/BindingUtils.h | 8 + dom/bindings/Bindings.conf | 5 + dom/bindings/Codegen.py | 132 +++++++++++++--- dom/bindings/parser/WebIDL.py | 29 +++- dom/bindings/parser/tests/test_constructor.py | 166 ++++++++++++++++++++- .../tests/test_constructor_no_interface_object.py | 33 ++++ dom/bindings/test/TestBindingHeader.h | 6 + dom/bindings/test/TestCodeGen.webidl | 4 + parser/htmlparser/nsHTMLTags.h | 4 + 12 files changed, 534 insertions(+), 30 deletions(-) diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 43e4e7e2a..6cd213210 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -273,6 +273,23 @@ CustomElementRegistry::LookupCustomElementDefinition(const nsAString& aLocalName return nullptr; } +CustomElementDefinition* +CustomElementRegistry::LookupCustomElementDefinition(JSContext* aCx, + JSObject* aConstructor) const +{ + JS::Rooted constructor(aCx, js::CheckedUnwrap(aConstructor)); + + const auto& ptr = mConstructors.lookup(constructor); + if (!ptr) { + return nullptr; + } + + CustomElementDefinition* definition = mCustomDefinitions.Get(ptr->value()); + MOZ_ASSERT(definition, "Definition must be found in mCustomDefinitions"); + + return definition; +} + void CustomElementRegistry::RegisterUnresolvedElement(Element* aElement, nsIAtom* aTypeName) { diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index 9034dd7ea..8ef0785af 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -128,6 +128,10 @@ struct CustomElementDefinition // The document custom element order. uint32_t mDocOrder; + + bool IsCustomBuiltIn() { + return mType != mLocalName; + } }; class CustomElementRegistry final : public nsISupports, @@ -155,6 +159,9 @@ public: CustomElementDefinition* LookupCustomElementDefinition( const nsAString& aLocalName, const nsAString* aIs = nullptr) const; + CustomElementDefinition* LookupCustomElementDefinition( + JSContext* aCx, JSObject *aConstructor) const; + /** * Enqueue created callback or register upgrade candidate for * newly created custom elements, possibly extending an existing type. diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index b244d4d2a..6bc6b7143 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -19,10 +19,12 @@ #include "AccessCheck.h" #include "jsfriendapi.h" +#include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" #include "nsGlobalWindow.h" #include "nsIDocShell.h" #include "nsIDOMGlobalPropertyInitializer.h" +#include "nsIParserService.h" #include "nsIPermissionManager.h" #include "nsIPrincipal.h" #include "nsIXPConnect.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 }, @@ -3377,6 +3405,131 @@ GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs, return true; } +// https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor +already_AddRefed +CreateHTMLElement(const GlobalObject& aGlobal, const JS::CallArgs& aCallArgs, + ErrorResult& aRv) +{ + // Step 1. + nsCOMPtr 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 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 newTarget(cx, &aCallArgs.newTarget().toObject()); + CustomElementDefinition* definition = + registry->LookupCustomElementDefinition(cx, newTarget); + if (!definition) { + aRv.ThrowTypeError(); + return nullptr; + } + + // The callee might be an Xray. Unwrap it to get actual callee. + JS::Rooted 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 constructor(cx, HTMLElementBinding::GetConstructorObject(cx)); + if (!constructor) { + aRv.NoteJSContextException(cx); + return nullptr; + } + + if (callee != constructor) { + aRv.ThrowTypeError(); + return nullptr; + } + } else { + // Step 5. + // If the definition is for a customized built-in element, the localName + // should be defined in the specification. + nsIParserService* parserService = nsContentUtils::GetParserService(); + if (!parserService) { + aRv.Throw(NS_ERROR_UNEXPECTED); + return nullptr; + } + + tag = parserService->HTMLCaseSensitiveAtomTagToId(definition->mLocalName); + if (tag == eHTMLTag_userdefined) { + aRv.ThrowTypeError(); + 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(); + return nullptr; + } + + JS::Rooted constructor(cx, cb(cx)); + if (!constructor) { + aRv.NoteJSContextException(cx); + return nullptr; + } + + if (callee != constructor) { + aRv.ThrowTypeError(); + return nullptr; + } + } + + RefPtr 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. + // Construction stack will be implemented in bug 1287348. So we always run + // "construction stack is empty" case for now. + RefPtr element; + if (tag == eHTMLTag_userdefined) { + // Autonomous custom element. + element = NS_NewHTMLElement(nodeInfo.forget()); + } else { + // Customized built-in element. + element = CreateHTMLElement(tag, nodeInfo.forget(), NOT_FROM_PARSER); + } + + return element.forget(); +} + #ifdef DEBUG namespace binding_detail { void diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 5cab835b3..2563c5fee 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -42,6 +42,7 @@ #include "nsWrapperCacheInlines.h" +class nsGenericHTMLElement; class nsIJSID; namespace mozilla { @@ -3420,6 +3421,13 @@ bool GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs, JS::MutableHandle aDesiredProto); +// This function is expected to be called from the constructor function for an +// HTML element interface; the global/callargs need to be whatever was passed to +// that constructor function. +already_AddRefed +CreateHTMLElement(const GlobalObject& aGlobal, const JS::CallArgs& aCallArgs, + ErrorResult& aRv); + void SetDocumentAndPageUseCounter(JSContext* aCx, JSObject* aObject, UseCounter aUseCounter); diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index b00af2085..6eebaf60c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1638,6 +1638,11 @@ DOMInterfaces = { 'register': False, }, +'TestHTMLConstructorInterface' : { + 'headerFile': 'TestBindingHeader.h', + 'register': False, + }, + } # These are temporary, until they've been converted to use new DOM bindings diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 6b23e8225..676d91793 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1747,6 +1747,71 @@ class CGClassConstructor(CGAbstractStaticMethod): else: ctorName = self.descriptor.interface.identifier.name + # [HTMLConstructor] for custom element + # This needs to live in bindings code because it directly examines + # newtarget and the callee function to do HTMLConstructor specific things. + if self._ctor.isHTMLConstructor(): + htmlConstructorSanityCheck = dedent(""" + // The newTarget might be a cross-compartment wrapper. Get the underlying object + // so we can do the spec's object-identity checks. + JS::Rooted newTarget(cx, js::CheckedUnwrap(&args.newTarget().toObject())); + if (!newTarget) { + return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR); + } + + // Step 2 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor. + // Enter the compartment of our underlying newTarget object, so we end + // up comparing to the constructor object for our interface from that global. + { + JSAutoCompartment ac(cx, newTarget); + JS::Handle constructor(GetConstructorObjectHandle(cx)); + if (!constructor) { + return false; + } + if (newTarget == constructor) { + return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR); + } + } + + """) + + # If we are unable to get desired prototype from newTarget, then we + # fall back to the interface prototype object from newTarget's realm. + htmlConstructorFallback = dedent(""" + if (!desiredProto) { + // Step 7 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor. + // This fallback behavior is designed to match analogous behavior for the + // JavaScript built-ins. So we enter the compartment of our underlying + // newTarget object and fall back to the prototype object from that global. + // XXX The spec says to use GetFunctionRealm(), which is not actually + // the same thing as what we have here (e.g. in the case of scripted callable proxies + // whose target is not same-compartment with the proxy, or bound functions, etc). + // https://bugzilla.mozilla.org/show_bug.cgi?id=1317658 + { + JSAutoCompartment ac(cx, newTarget); + desiredProto = GetProtoObjectHandle(cx); + if (!desiredProto) { + return false; + } + } + + // desiredProto is in the compartment of the underlying newTarget object. + // Wrap it into the context compartment. + if (!JS_WrapObject(cx, &desiredProto)) { + return false; + } + } + """) + else: + htmlConstructorSanityCheck = "" + htmlConstructorFallback = "" + + + # If we're a constructor, "obj" may not be a function, so calling + # XrayAwareCalleeGlobal() on it is not safe. Of course in the + # constructor case either "obj" is an Xray or we're already in the + # content compartment, not the Xray compartment, so just + # constructing the GlobalObject from "obj" is fine. preamble = fill( """ JS::CallArgs args = JS::CallArgsFromVp(argc, vp); @@ -1757,19 +1822,41 @@ class CGClassConstructor(CGAbstractStaticMethod): // Adding more relocations return ThrowConstructorWithoutNew(cx, "${ctorName}"); } + + GlobalObject global(cx, obj); + if (global.Failed()) { + return false; + } + + $*{htmlConstructorSanityCheck} JS::Rooted desiredProto(cx); if (!GetDesiredProto(cx, args, &desiredProto)) { return false; } + $*{htmlConstructorFallback} """, chromeOnlyCheck=chromeOnlyCheck, - ctorName=ctorName) - - name = self._ctor.identifier.name - nativeName = MakeNativeName(self.descriptor.binaryNameFor(name)) - callGenerator = CGMethodCall(nativeName, True, self.descriptor, - self._ctor, isConstructor=True, - constructorName=ctorName) + ctorName=ctorName, + htmlConstructorSanityCheck=htmlConstructorSanityCheck, + htmlConstructorFallback=htmlConstructorFallback) + + if self._ctor.isHTMLConstructor(): + signatures = self._ctor.signatures() + assert len(signatures) == 1 + # Given that HTMLConstructor takes no args, we can just codegen a + # call to CreateHTMLElement() in BindingUtils which reuses the + # factory thing in HTMLContentSink. Then we don't have to implement + # Constructor on all the HTML elements. + callGenerator = CGPerSignatureCall(signatures[0][0], signatures[0][1], + "CreateHTMLElement", True, + self.descriptor, self._ctor, + isConstructor=True) + else: + name = self._ctor.identifier.name + nativeName = MakeNativeName(self.descriptor.binaryNameFor(name)) + callGenerator = CGMethodCall(nativeName, True, self.descriptor, + self._ctor, isConstructor=True, + constructorName=ctorName) return preamble + "\n" + callGenerator.define() @@ -7440,26 +7527,23 @@ class CGPerSignatureCall(CGThing): argsPre = [] if idlNode.isStatic(): - # If we're a constructor, "obj" may not be a function, so calling - # XrayAwareCalleeGlobal() on it is not safe. Of course in the - # constructor case either "obj" is an Xray or we're already in the - # content compartment, not the Xray compartment, so just - # constructing the GlobalObject from "obj" is fine. - if isConstructor: - objForGlobalObject = "obj" - else: - objForGlobalObject = "xpc::XrayAwareCalleeGlobal(obj)" - cgThings.append(CGGeneric(fill( - """ - GlobalObject global(cx, ${obj}); - if (global.Failed()) { - return false; - } + # If we're a constructor, the GlobalObject struct will be created in + # CGClassConstructor. + if not isConstructor: + cgThings.append(CGGeneric(dedent( + """ + GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj)); + if (global.Failed()) { + return false; + } + + """))) - """, - obj=objForGlobalObject))) argsPre.append("global") + if isConstructor and idlNode.isHTMLConstructor(): + argsPre.append("args") + # For JS-implemented interfaces we do not want to base the # needsCx decision on the types involved, just on our extended # attributes. Also, JSContext is not needed for the static case diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 4f602365b..a89620a9f 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -1582,7 +1582,7 @@ class IDLInterface(IDLInterfaceOrNamespace): [self.location]) self._noInterfaceObject = True - elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor": + elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor": if identifier == "Constructor" and not self.hasInterfaceObject(): raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", [self.location]) @@ -1595,11 +1595,20 @@ class IDLInterface(IDLInterfaceOrNamespace): raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", [self.location]) + if identifier == "HTMLConstructor": + if not self.hasInterfaceObject(): + raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", + [self.location]) + + if not attr.noArguments(): + raise WebIDLError(str(identifier) + " must take no arguments", + [attr.location]) + args = attr.args() if attr.hasArgs() else [] retType = IDLWrapperType(self.location, self) - if identifier == "Constructor" or identifier == "ChromeConstructor": + if identifier == "Constructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor": name = "constructor" allowForbidden = True else: @@ -1610,7 +1619,8 @@ class IDLInterface(IDLInterfaceOrNamespace): allowForbidden=allowForbidden) method = IDLMethod(self.location, methodIdentifier, retType, - args, static=True) + args, static=True, + htmlConstructor=(identifier == "HTMLConstructor")) # Constructors are always NewObject and are always # assumed to be able to throw (since there's no way to # indicate otherwise) and never have any other @@ -1622,7 +1632,7 @@ class IDLInterface(IDLInterfaceOrNamespace): method.addExtendedAttributes( [IDLExtendedAttribute(self.location, ("ChromeOnly",))]) - if identifier == "Constructor" or identifier == "ChromeConstructor": + if identifier == "Constructor" or identifier == "ChromeConstructor" or identifier == "HTMLConstructor": method.resolve(self) else: # We need to detect conflicts for NamedConstructors across @@ -4537,7 +4547,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope): static=False, getter=False, setter=False, creator=False, deleter=False, specialType=NamedOrIndexed.Neither, legacycaller=False, stringifier=False, jsonifier=False, - maplikeOrSetlikeOrIterable=None): + maplikeOrSetlikeOrIterable=None, htmlConstructor=False): # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up. IDLInterfaceMember.__init__(self, location, identifier, IDLInterfaceMember.Tags.Method) @@ -4567,6 +4577,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope): self._jsonifier = jsonifier assert maplikeOrSetlikeOrIterable is None or isinstance(maplikeOrSetlikeOrIterable, IDLMaplikeOrSetlikeOrIterableBase) self.maplikeOrSetlikeOrIterable = maplikeOrSetlikeOrIterable + assert isinstance(htmlConstructor, bool) + # The identifier of a HTMLConstructor must be 'constructor'. + assert not htmlConstructor or identifier.name == "constructor" + self._htmlConstructor = htmlConstructor self._specialType = specialType self._unforgeable = False self.dependsOn = "Everything" @@ -4667,6 +4681,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope): self.isStringifier() or self.isJsonifier()) + def isHTMLConstructor(self): + return self._htmlConstructor + def hasOverloads(self): return self._hasOverloads @@ -4722,6 +4739,8 @@ class IDLMethod(IDLInterfaceMember, IDLScope): assert not method.isStringifier() assert not self.isJsonifier() assert not method.isJsonifier() + assert not self.isHTMLConstructor() + assert not method.isHTMLConstructor() return self diff --git a/dom/bindings/parser/tests/test_constructor.py b/dom/bindings/parser/tests/test_constructor.py index 348204c7d..fb651c08d 100644 --- a/dom/bindings/parser/tests/test_constructor.py +++ b/dom/bindings/parser/tests/test_constructor.py @@ -13,7 +13,7 @@ def WebIDLTest(parser, harness): def checkMethod(method, QName, name, signatures, static=True, getter=False, setter=False, creator=False, deleter=False, legacycaller=False, stringifier=False, - chromeOnly=False): + chromeOnly=False, htmlConstructor=False): harness.ok(isinstance(method, WebIDL.IDLMethod), "Should be an IDLMethod") harness.ok(method.isMethod(), "Method is a method") @@ -29,6 +29,7 @@ def WebIDLTest(parser, harness): harness.check(method.isLegacycaller(), legacycaller, "Method has the correct legacycaller value") harness.check(method.isStringifier(), stringifier, "Method has the correct stringifier value") harness.check(method.getExtendedAttribute("ChromeOnly") is not None, chromeOnly, "Method has the correct value for ChromeOnly") + harness.check(method.isHTMLConstructor(), htmlConstructor, "Method has the correct htmlConstructor value") harness.check(len(method.signatures()), len(signatures), "Method has the correct number of signatures") sigpairs = zip(method.signatures(), signatures) @@ -78,6 +79,21 @@ def WebIDLTest(parser, harness): ("TestConstructorOverloads (Wrapper)", [("::TestConstructorOverloads::constructor::bar", "bar", "Boolean", False, False)])]) + parser = parser.reset() + parser.parse(""" + [HTMLConstructor] + interface TestHTMLConstructor { + }; + """) + results = parser.finish() + harness.check(len(results), 1, "Should be one production") + harness.ok(isinstance(results[0], WebIDL.IDLInterface), + "Should be an IDLInterface") + + checkMethod(results[0].ctor(), "::TestHTMLConstructor::constructor", + "constructor", [("TestHTMLConstructor (Wrapper)", [])], + htmlConstructor=True) + parser = parser.reset() parser.parse(""" [ChromeConstructor()] @@ -107,3 +123,151 @@ def WebIDLTest(parser, harness): threw = True harness.ok(threw, "Can't have both a Constructor and a ChromeConstructor") + + # Test HTMLConstructor with argument + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor(DOMString a)] + interface TestHTMLConstructorWithArgs { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "HTMLConstructor should take no argument") + + # Test HTMLConstructor on a callback interface + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor] + callback interface TestHTMLConstructorOnCallbackInterface { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "HTMLConstructor can't be used on a callback interface") + + # Test HTMLConstructor and Constructor + parser = parser.reset() + threw = False + try: + parser.parse(""" + [Constructor, + HTMLConstructor] + interface TestHTMLConstructorAndConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a Constructor and a HTMLConstructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + Constructor] + interface TestHTMLConstructorAndConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + Constructor(DOMString a)] + interface TestHTMLConstructorAndConstructor { + }; + """) + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [Constructor(DOMString a), + HTMLConstructor] + interface TestHTMLConstructorAndConstructor { + }; + """) + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a Constructor") + + # Test HTMLConstructor and ChromeConstructor + parser = parser.reset() + threw = False + try: + parser.parse(""" + [ChromeConstructor, + HTMLConstructor] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + ChromeConstructor] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor") + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [ChromeConstructor(DOMString a), + HTMLConstructor] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + parser = parser.reset() + threw = False + try: + parser.parse(""" + [HTMLConstructor, + ChromeConstructor(DOMString a)] + interface TestHTMLConstructorAndChromeConstructor { + }; + """) + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Can't have both a HTMLConstructor and a ChromeConstructor") \ No newline at end of file diff --git a/dom/bindings/parser/tests/test_constructor_no_interface_object.py b/dom/bindings/parser/tests/test_constructor_no_interface_object.py index 2b09ae71e..af7b73d67 100644 --- a/dom/bindings/parser/tests/test_constructor_no_interface_object.py +++ b/dom/bindings/parser/tests/test_constructor_no_interface_object.py @@ -34,3 +34,36 @@ def WebIDLTest(parser, harness): interface TestNamedConstructorNoInterfaceObject { }; """) + + # Test HTMLConstructor and NoInterfaceObject + parser = parser.reset() + + threw = False + try: + parser.parse(""" + [NoInterfaceObject, HTMLConstructor] + interface TestHTMLConstructorNoInterfaceObject { + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown.") + + parser = parser.reset() + + threw = False + try: + parser.parse(""" + [HTMLConstructor, NoInterfaceObject] + interface TestHTMLConstructorNoInterfaceObject { + }; + """) + + results = parser.finish() + except: + threw = True + + harness.ok(threw, "Should have thrown.") \ No newline at end of file diff --git a/dom/bindings/test/TestBindingHeader.h b/dom/bindings/test/TestBindingHeader.h index ca5aafdc5..9bd3e407f 100644 --- a/dom/bindings/test/TestBindingHeader.h +++ b/dom/bindings/test/TestBindingHeader.h @@ -1425,6 +1425,12 @@ public: void SetNeedsCallerTypeAttr(bool, CallerType); }; +class TestHTMLConstructorInterface : public nsGenericHTMLElement +{ +public: + virtual nsISupports* GetParentObject(); +}; + } // namespace dom } // namespace mozilla diff --git a/dom/bindings/test/TestCodeGen.webidl b/dom/bindings/test/TestCodeGen.webidl index 4fb9be270..35777f6aa 100644 --- a/dom/bindings/test/TestCodeGen.webidl +++ b/dom/bindings/test/TestCodeGen.webidl @@ -1262,3 +1262,7 @@ interface TestWorkerExposedInterface { [NeedsCallerType] void needsCallerTypeMethod(); [NeedsCallerType] attribute boolean needsCallerTypeAttr; }; + +[HTMLConstructor] +interface TestHTMLConstructorInterface { +}; diff --git a/parser/htmlparser/nsHTMLTags.h b/parser/htmlparser/nsHTMLTags.h index a2800df07..27a23b89f 100644 --- a/parser/htmlparser/nsHTMLTags.h +++ b/parser/htmlparser/nsHTMLTags.h @@ -17,6 +17,10 @@ class nsIAtom; To change the list of tags, see nsHTMLTagList.h + These enum values are used as the index of array in various places. + If we change the structure of the enum by adding entries to it or removing + entries from it _directly_, not via nsHTMLTagList.h, don't forget to update + dom/bindings/BindingUtils.cpp and dom/html/nsHTMLContentSink.cpp as well. */ #define HTML_TAG(_tag, _classname, _interfacename) eHTMLTag_##_tag, #define HTML_OTHER(_tag) eHTMLTag_##_tag, -- cgit v1.2.3 From 6ea0acf750ea7ba38b86cae1f3c6ba8d239c6e9e Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 21:46:47 -0500 Subject: Bug 1274159 - Part 3-1: Add HTMLConstructor to HTMLElement and its subclass; Tag UXP Issue #1344 --- dom/webidl/HTMLAnchorElement.webidl | 1 + dom/webidl/HTMLAreaElement.webidl | 1 + dom/webidl/HTMLAudioElement.webidl | 2 +- dom/webidl/HTMLBRElement.webidl | 1 + dom/webidl/HTMLBaseElement.webidl | 1 + dom/webidl/HTMLBodyElement.webidl | 1 + dom/webidl/HTMLButtonElement.webidl | 1 + dom/webidl/HTMLCanvasElement.webidl | 1 + dom/webidl/HTMLDListElement.webidl | 1 + dom/webidl/HTMLDataElement.webidl | 1 + dom/webidl/HTMLDataListElement.webidl | 1 + dom/webidl/HTMLDetailsElement.webidl | 1 + dom/webidl/HTMLDirectoryElement.webidl | 1 + dom/webidl/HTMLDivElement.webidl | 1 + dom/webidl/HTMLElement.webidl | 1 + dom/webidl/HTMLEmbedElement.webidl | 2 +- dom/webidl/HTMLFieldSetElement.webidl | 1 + dom/webidl/HTMLFontElement.webidl | 1 + dom/webidl/HTMLFormElement.webidl | 2 +- dom/webidl/HTMLFrameElement.webidl | 1 + dom/webidl/HTMLFrameSetElement.webidl | 1 + dom/webidl/HTMLHRElement.webidl | 1 + dom/webidl/HTMLHeadElement.webidl | 1 + dom/webidl/HTMLHeadingElement.webidl | 1 + dom/webidl/HTMLHtmlElement.webidl | 1 + dom/webidl/HTMLIFrameElement.webidl | 1 + dom/webidl/HTMLImageElement.webidl | 3 ++- dom/webidl/HTMLInputElement.webidl | 1 + dom/webidl/HTMLLIElement.webidl | 1 + dom/webidl/HTMLLabelElement.webidl | 1 + dom/webidl/HTMLLegendElement.webidl | 1 + dom/webidl/HTMLLinkElement.webidl | 1 + dom/webidl/HTMLMapElement.webidl | 1 + dom/webidl/HTMLMenuElement.webidl | 1 + dom/webidl/HTMLMenuItemElement.webidl | 1 + dom/webidl/HTMLMetaElement.webidl | 1 + dom/webidl/HTMLMeterElement.webidl | 1 + dom/webidl/HTMLModElement.webidl | 1 + dom/webidl/HTMLOListElement.webidl | 1 + dom/webidl/HTMLObjectElement.webidl | 2 +- dom/webidl/HTMLOptGroupElement.webidl | 1 + dom/webidl/HTMLOptionElement.webidl | 2 +- dom/webidl/HTMLOutputElement.webidl | 1 + dom/webidl/HTMLParagraphElement.webidl | 1 + dom/webidl/HTMLParamElement.webidl | 1 + dom/webidl/HTMLPictureElement.webidl | 1 + dom/webidl/HTMLPreElement.webidl | 1 + dom/webidl/HTMLProgressElement.webidl | 1 + dom/webidl/HTMLQuoteElement.webidl | 1 + dom/webidl/HTMLScriptElement.webidl | 1 + dom/webidl/HTMLSelectElement.webidl | 1 + dom/webidl/HTMLSourceElement.webidl | 1 + dom/webidl/HTMLSpanElement.webidl | 1 + dom/webidl/HTMLStyleElement.webidl | 1 + dom/webidl/HTMLTableCaptionElement.webidl | 1 + dom/webidl/HTMLTableCellElement.webidl | 1 + dom/webidl/HTMLTableColElement.webidl | 1 + dom/webidl/HTMLTableElement.webidl | 1 + dom/webidl/HTMLTableRowElement.webidl | 1 + dom/webidl/HTMLTableSectionElement.webidl | 1 + dom/webidl/HTMLTemplateElement.webidl | 1 + dom/webidl/HTMLTextAreaElement.webidl | 1 + dom/webidl/HTMLTimeElement.webidl | 1 + dom/webidl/HTMLTitleElement.webidl | 1 + dom/webidl/HTMLTrackElement.webidl | 1 + dom/webidl/HTMLUListElement.webidl | 1 + dom/webidl/HTMLVideoElement.webidl | 1 + 67 files changed, 68 insertions(+), 6 deletions(-) diff --git a/dom/webidl/HTMLAnchorElement.webidl b/dom/webidl/HTMLAnchorElement.webidl index 0b8ded6d7..aa8e7d082 100644 --- a/dom/webidl/HTMLAnchorElement.webidl +++ b/dom/webidl/HTMLAnchorElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-a-element +[HTMLConstructor] interface HTMLAnchorElement : HTMLElement { [SetterThrows] attribute DOMString target; diff --git a/dom/webidl/HTMLAreaElement.webidl b/dom/webidl/HTMLAreaElement.webidl index be3f37885..113f1822e 100644 --- a/dom/webidl/HTMLAreaElement.webidl +++ b/dom/webidl/HTMLAreaElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-area-element +[HTMLConstructor] interface HTMLAreaElement : HTMLElement { [SetterThrows] attribute DOMString alt; diff --git a/dom/webidl/HTMLAudioElement.webidl b/dom/webidl/HTMLAudioElement.webidl index 8537453c0..725669839 100644 --- a/dom/webidl/HTMLAudioElement.webidl +++ b/dom/webidl/HTMLAudioElement.webidl @@ -11,6 +11,6 @@ * and create derivative works of this document. */ -[NamedConstructor=Audio(optional DOMString src)] +[HTMLConstructor, NamedConstructor=Audio(optional DOMString src)] interface HTMLAudioElement : HTMLMediaElement {}; diff --git a/dom/webidl/HTMLBRElement.webidl b/dom/webidl/HTMLBRElement.webidl index cf5cb8a67..07b8d9f0d 100644 --- a/dom/webidl/HTMLBRElement.webidl +++ b/dom/webidl/HTMLBRElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-br-element +[HTMLConstructor] interface HTMLBRElement : HTMLElement {}; // http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis diff --git a/dom/webidl/HTMLBaseElement.webidl b/dom/webidl/HTMLBaseElement.webidl index d982f4654..bc43e0570 100644 --- a/dom/webidl/HTMLBaseElement.webidl +++ b/dom/webidl/HTMLBaseElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-base-element +[HTMLConstructor] interface HTMLBaseElement : HTMLElement { [SetterThrows, Pure] attribute DOMString href; diff --git a/dom/webidl/HTMLBodyElement.webidl b/dom/webidl/HTMLBodyElement.webidl index 95df2d43a..e17758491 100644 --- a/dom/webidl/HTMLBodyElement.webidl +++ b/dom/webidl/HTMLBodyElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLBodyElement : HTMLElement { }; diff --git a/dom/webidl/HTMLButtonElement.webidl b/dom/webidl/HTMLButtonElement.webidl index 579efa39c..5d7965cfb 100644 --- a/dom/webidl/HTMLButtonElement.webidl +++ b/dom/webidl/HTMLButtonElement.webidl @@ -11,6 +11,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-button-element +[HTMLConstructor] interface HTMLButtonElement : HTMLElement { [SetterThrows, Pure] attribute boolean autofocus; diff --git a/dom/webidl/HTMLCanvasElement.webidl b/dom/webidl/HTMLCanvasElement.webidl index 15e94f154..4a0c4499b 100644 --- a/dom/webidl/HTMLCanvasElement.webidl +++ b/dom/webidl/HTMLCanvasElement.webidl @@ -13,6 +13,7 @@ interface nsISupports; interface Variant; +[HTMLConstructor] interface HTMLCanvasElement : HTMLElement { [Pure, SetterThrows] attribute unsigned long width; diff --git a/dom/webidl/HTMLDListElement.webidl b/dom/webidl/HTMLDListElement.webidl index 08020a497..4e3fa88d8 100644 --- a/dom/webidl/HTMLDListElement.webidl +++ b/dom/webidl/HTMLDListElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-dl-element +[HTMLConstructor] interface HTMLDListElement : HTMLElement { }; diff --git a/dom/webidl/HTMLDataElement.webidl b/dom/webidl/HTMLDataElement.webidl index 821b8b483..6b9a7f19a 100644 --- a/dom/webidl/HTMLDataElement.webidl +++ b/dom/webidl/HTMLDataElement.webidl @@ -7,6 +7,7 @@ * http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-data-element */ +[HTMLConstructor] interface HTMLDataElement : HTMLElement { [SetterThrows] attribute DOMString value; diff --git a/dom/webidl/HTMLDataListElement.webidl b/dom/webidl/HTMLDataListElement.webidl index 83b20cd2b..4c38fddf3 100644 --- a/dom/webidl/HTMLDataListElement.webidl +++ b/dom/webidl/HTMLDataListElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLDataListElement : HTMLElement { readonly attribute HTMLCollection options; }; diff --git a/dom/webidl/HTMLDetailsElement.webidl b/dom/webidl/HTMLDetailsElement.webidl index 104606eb1..f57f5c93c 100644 --- a/dom/webidl/HTMLDetailsElement.webidl +++ b/dom/webidl/HTMLDetailsElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLDetailsElement : HTMLElement { [SetterThrows] attribute boolean open; diff --git a/dom/webidl/HTMLDirectoryElement.webidl b/dom/webidl/HTMLDirectoryElement.webidl index 9d5160af1..d50b4d330 100644 --- a/dom/webidl/HTMLDirectoryElement.webidl +++ b/dom/webidl/HTMLDirectoryElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis +[HTMLConstructor] interface HTMLDirectoryElement : HTMLElement { [SetterThrows, Pure] attribute boolean compact; diff --git a/dom/webidl/HTMLDivElement.webidl b/dom/webidl/HTMLDivElement.webidl index f50e2aad0..584c01e0e 100644 --- a/dom/webidl/HTMLDivElement.webidl +++ b/dom/webidl/HTMLDivElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLDivElement : HTMLElement {}; partial interface HTMLDivElement { diff --git a/dom/webidl/HTMLElement.webidl b/dom/webidl/HTMLElement.webidl index 5ce5024e6..890341ec0 100644 --- a/dom/webidl/HTMLElement.webidl +++ b/dom/webidl/HTMLElement.webidl @@ -12,6 +12,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLElement : Element { // metadata attributes attribute DOMString title; diff --git a/dom/webidl/HTMLEmbedElement.webidl b/dom/webidl/HTMLEmbedElement.webidl index 36668595b..d4e678011 100644 --- a/dom/webidl/HTMLEmbedElement.webidl +++ b/dom/webidl/HTMLEmbedElement.webidl @@ -13,7 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-embed-element -[NeedResolve] +[HTMLConstructor, NeedResolve] interface HTMLEmbedElement : HTMLElement { [Pure, SetterThrows] attribute DOMString src; diff --git a/dom/webidl/HTMLFieldSetElement.webidl b/dom/webidl/HTMLFieldSetElement.webidl index 6c9eee52b..f61cdbf5b 100644 --- a/dom/webidl/HTMLFieldSetElement.webidl +++ b/dom/webidl/HTMLFieldSetElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLFieldSetElement : HTMLElement { [SetterThrows] attribute boolean disabled; diff --git a/dom/webidl/HTMLFontElement.webidl b/dom/webidl/HTMLFontElement.webidl index 781dabb88..09c0eae9b 100644 --- a/dom/webidl/HTMLFontElement.webidl +++ b/dom/webidl/HTMLFontElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLFontElement : HTMLElement { [TreatNullAs=EmptyString, SetterThrows] attribute DOMString color; [SetterThrows] attribute DOMString face; diff --git a/dom/webidl/HTMLFormElement.webidl b/dom/webidl/HTMLFormElement.webidl index 8d248e1a5..dcc909483 100644 --- a/dom/webidl/HTMLFormElement.webidl +++ b/dom/webidl/HTMLFormElement.webidl @@ -11,7 +11,7 @@ * and create derivative works of this document. */ -[OverrideBuiltins, LegacyUnenumerableNamedProperties] +[OverrideBuiltins, LegacyUnenumerableNamedProperties, HTMLConstructor] interface HTMLFormElement : HTMLElement { [Pure, SetterThrows] attribute DOMString acceptCharset; diff --git a/dom/webidl/HTMLFrameElement.webidl b/dom/webidl/HTMLFrameElement.webidl index 9c5aca7c4..e7d702143 100644 --- a/dom/webidl/HTMLFrameElement.webidl +++ b/dom/webidl/HTMLFrameElement.webidl @@ -11,6 +11,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#htmlframeelement +[HTMLConstructor] interface HTMLFrameElement : HTMLElement { [SetterThrows] attribute DOMString name; diff --git a/dom/webidl/HTMLFrameSetElement.webidl b/dom/webidl/HTMLFrameSetElement.webidl index ce00d487f..cf4e34bcf 100644 --- a/dom/webidl/HTMLFrameSetElement.webidl +++ b/dom/webidl/HTMLFrameSetElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLFrameSetElement : HTMLElement { [SetterThrows] attribute DOMString cols; diff --git a/dom/webidl/HTMLHRElement.webidl b/dom/webidl/HTMLHRElement.webidl index 0495e43b3..9359d74b9 100644 --- a/dom/webidl/HTMLHRElement.webidl +++ b/dom/webidl/HTMLHRElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-hr-element +[HTMLConstructor] interface HTMLHRElement : HTMLElement { }; diff --git a/dom/webidl/HTMLHeadElement.webidl b/dom/webidl/HTMLHeadElement.webidl index 0ad45e384..b649712a6 100644 --- a/dom/webidl/HTMLHeadElement.webidl +++ b/dom/webidl/HTMLHeadElement.webidl @@ -12,5 +12,6 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-head-element +[HTMLConstructor] interface HTMLHeadElement : HTMLElement {}; diff --git a/dom/webidl/HTMLHeadingElement.webidl b/dom/webidl/HTMLHeadingElement.webidl index c07e5cb99..97e471025 100644 --- a/dom/webidl/HTMLHeadingElement.webidl +++ b/dom/webidl/HTMLHeadingElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-h1,-h2,-h3,-h4,-h5,-and-h6-elements +[HTMLConstructor] interface HTMLHeadingElement : HTMLElement { }; diff --git a/dom/webidl/HTMLHtmlElement.webidl b/dom/webidl/HTMLHtmlElement.webidl index b06de7761..f9174a185 100644 --- a/dom/webidl/HTMLHtmlElement.webidl +++ b/dom/webidl/HTMLHtmlElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-html-element +[HTMLConstructor] interface HTMLHtmlElement : HTMLElement {}; // http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis diff --git a/dom/webidl/HTMLIFrameElement.webidl b/dom/webidl/HTMLIFrameElement.webidl index 0a1b49aff..4b9d1ce4c 100644 --- a/dom/webidl/HTMLIFrameElement.webidl +++ b/dom/webidl/HTMLIFrameElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLIFrameElement : HTMLElement { [SetterThrows, Pure] attribute DOMString src; diff --git a/dom/webidl/HTMLImageElement.webidl b/dom/webidl/HTMLImageElement.webidl index 243c65509..c6bc3e4c8 100644 --- a/dom/webidl/HTMLImageElement.webidl +++ b/dom/webidl/HTMLImageElement.webidl @@ -16,7 +16,8 @@ interface imgIRequest; interface URI; interface nsIStreamListener; -[NamedConstructor=Image(optional unsigned long width, optional unsigned long height)] +[HTMLConstructor, + NamedConstructor=Image(optional unsigned long width, optional unsigned long height)] interface HTMLImageElement : HTMLElement { [SetterThrows] attribute DOMString alt; diff --git a/dom/webidl/HTMLInputElement.webidl b/dom/webidl/HTMLInputElement.webidl index cf3e9a4c7..deb5b5faf 100644 --- a/dom/webidl/HTMLInputElement.webidl +++ b/dom/webidl/HTMLInputElement.webidl @@ -21,6 +21,7 @@ enum SelectionMode { interface nsIControllers; +[HTMLConstructor] interface HTMLInputElement : HTMLElement { [Pure, SetterThrows] attribute DOMString accept; diff --git a/dom/webidl/HTMLLIElement.webidl b/dom/webidl/HTMLLIElement.webidl index c20e00846..d36b96a0f 100644 --- a/dom/webidl/HTMLLIElement.webidl +++ b/dom/webidl/HTMLLIElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-li-element +[HTMLConstructor] interface HTMLLIElement : HTMLElement { [SetterThrows, Pure] attribute long value; diff --git a/dom/webidl/HTMLLabelElement.webidl b/dom/webidl/HTMLLabelElement.webidl index f44a56219..8a5c67fbc 100644 --- a/dom/webidl/HTMLLabelElement.webidl +++ b/dom/webidl/HTMLLabelElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLLabelElement : HTMLElement { readonly attribute HTMLFormElement? form; attribute DOMString htmlFor; diff --git a/dom/webidl/HTMLLegendElement.webidl b/dom/webidl/HTMLLegendElement.webidl index 0ce4ae88b..8feb70dcb 100644 --- a/dom/webidl/HTMLLegendElement.webidl +++ b/dom/webidl/HTMLLegendElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-legend-element +[HTMLConstructor] interface HTMLLegendElement : HTMLElement { readonly attribute HTMLFormElement? form; }; diff --git a/dom/webidl/HTMLLinkElement.webidl b/dom/webidl/HTMLLinkElement.webidl index ec094e55e..c5d8eec4f 100644 --- a/dom/webidl/HTMLLinkElement.webidl +++ b/dom/webidl/HTMLLinkElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-link-element +[HTMLConstructor] interface HTMLLinkElement : HTMLElement { [Pure] attribute boolean disabled; diff --git a/dom/webidl/HTMLMapElement.webidl b/dom/webidl/HTMLMapElement.webidl index 88fe4e54c..cf4d40426 100644 --- a/dom/webidl/HTMLMapElement.webidl +++ b/dom/webidl/HTMLMapElement.webidl @@ -11,6 +11,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-map-element +[HTMLConstructor] interface HTMLMapElement : HTMLElement { [SetterThrows, Pure] attribute DOMString name; diff --git a/dom/webidl/HTMLMenuElement.webidl b/dom/webidl/HTMLMenuElement.webidl index ff81a7c80..7658d8380 100644 --- a/dom/webidl/HTMLMenuElement.webidl +++ b/dom/webidl/HTMLMenuElement.webidl @@ -15,6 +15,7 @@ interface MenuBuilder; // http://www.whatwg.org/specs/web-apps/current-work/#the-menu-element +[HTMLConstructor] interface HTMLMenuElement : HTMLElement { [SetterThrows] attribute DOMString type; diff --git a/dom/webidl/HTMLMenuItemElement.webidl b/dom/webidl/HTMLMenuItemElement.webidl index 7064885a1..1a7750483 100644 --- a/dom/webidl/HTMLMenuItemElement.webidl +++ b/dom/webidl/HTMLMenuItemElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-menuitem-element +[HTMLConstructor] interface HTMLMenuItemElement : HTMLElement { [SetterThrows] attribute DOMString type; diff --git a/dom/webidl/HTMLMetaElement.webidl b/dom/webidl/HTMLMetaElement.webidl index 5b7b0f92c..171f67305 100644 --- a/dom/webidl/HTMLMetaElement.webidl +++ b/dom/webidl/HTMLMetaElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-meta-element +[HTMLConstructor] interface HTMLMetaElement : HTMLElement { [SetterThrows, Pure] attribute DOMString name; diff --git a/dom/webidl/HTMLMeterElement.webidl b/dom/webidl/HTMLMeterElement.webidl index 104e00353..484ece85c 100644 --- a/dom/webidl/HTMLMeterElement.webidl +++ b/dom/webidl/HTMLMeterElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-meter-element +[HTMLConstructor] interface HTMLMeterElement : HTMLElement { [SetterThrows] attribute double value; diff --git a/dom/webidl/HTMLModElement.webidl b/dom/webidl/HTMLModElement.webidl index 45086cceb..654aca272 100644 --- a/dom/webidl/HTMLModElement.webidl +++ b/dom/webidl/HTMLModElement.webidl @@ -11,6 +11,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#attributes-common-to-ins-and-del-elements +[HTMLConstructor] interface HTMLModElement : HTMLElement { [SetterThrows, Pure] attribute DOMString cite; diff --git a/dom/webidl/HTMLOListElement.webidl b/dom/webidl/HTMLOListElement.webidl index f41abf3ea..5b10d4807 100644 --- a/dom/webidl/HTMLOListElement.webidl +++ b/dom/webidl/HTMLOListElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-ol-element +[HTMLConstructor] interface HTMLOListElement : HTMLElement { [SetterThrows] attribute boolean reversed; diff --git a/dom/webidl/HTMLObjectElement.webidl b/dom/webidl/HTMLObjectElement.webidl index ebb95ab09..797b04119 100644 --- a/dom/webidl/HTMLObjectElement.webidl +++ b/dom/webidl/HTMLObjectElement.webidl @@ -13,7 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-object-element -[NeedResolve, UnsafeInPrerendering] +[HTMLConstructor, NeedResolve, UnsafeInPrerendering] interface HTMLObjectElement : HTMLElement { [Pure, SetterThrows] attribute DOMString data; diff --git a/dom/webidl/HTMLOptGroupElement.webidl b/dom/webidl/HTMLOptGroupElement.webidl index a23aee30d..18d2e5dfa 100644 --- a/dom/webidl/HTMLOptGroupElement.webidl +++ b/dom/webidl/HTMLOptGroupElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLOptGroupElement : HTMLElement { [SetterThrows] attribute boolean disabled; diff --git a/dom/webidl/HTMLOptionElement.webidl b/dom/webidl/HTMLOptionElement.webidl index c80bedeef..34e6e6c23 100644 --- a/dom/webidl/HTMLOptionElement.webidl +++ b/dom/webidl/HTMLOptionElement.webidl @@ -11,7 +11,7 @@ * and create derivative works of this document. */ -[NamedConstructor=Option(optional DOMString text, optional DOMString value, optional boolean defaultSelected, optional boolean selected)] +[HTMLConstructor, NamedConstructor=Option(optional DOMString text, optional DOMString value, optional boolean defaultSelected, optional boolean selected)] interface HTMLOptionElement : HTMLElement { [SetterThrows] attribute boolean disabled; diff --git a/dom/webidl/HTMLOutputElement.webidl b/dom/webidl/HTMLOutputElement.webidl index d0e4ecbe6..698fd08d1 100644 --- a/dom/webidl/HTMLOutputElement.webidl +++ b/dom/webidl/HTMLOutputElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-output-element +[HTMLConstructor] interface HTMLOutputElement : HTMLElement { [PutForwards=value, Constant] readonly attribute DOMTokenList htmlFor; diff --git a/dom/webidl/HTMLParagraphElement.webidl b/dom/webidl/HTMLParagraphElement.webidl index 2a626d257..b72f627d1 100644 --- a/dom/webidl/HTMLParagraphElement.webidl +++ b/dom/webidl/HTMLParagraphElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-p-element +[HTMLConstructor] interface HTMLParagraphElement : HTMLElement { }; diff --git a/dom/webidl/HTMLParamElement.webidl b/dom/webidl/HTMLParamElement.webidl index e2c7e8d7f..b9f17d6f5 100644 --- a/dom/webidl/HTMLParamElement.webidl +++ b/dom/webidl/HTMLParamElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-param-element +[HTMLConstructor] interface HTMLParamElement : HTMLElement { [SetterThrows, Pure] attribute DOMString name; diff --git a/dom/webidl/HTMLPictureElement.webidl b/dom/webidl/HTMLPictureElement.webidl index eff30f750..387eee78d 100644 --- a/dom/webidl/HTMLPictureElement.webidl +++ b/dom/webidl/HTMLPictureElement.webidl @@ -4,5 +4,6 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ +[HTMLConstructor] interface HTMLPictureElement : HTMLElement { }; diff --git a/dom/webidl/HTMLPreElement.webidl b/dom/webidl/HTMLPreElement.webidl index db220b74c..b128e824d 100644 --- a/dom/webidl/HTMLPreElement.webidl +++ b/dom/webidl/HTMLPreElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-pre-element +[HTMLConstructor] interface HTMLPreElement : HTMLElement { }; diff --git a/dom/webidl/HTMLProgressElement.webidl b/dom/webidl/HTMLProgressElement.webidl index 028728e22..5729829cd 100644 --- a/dom/webidl/HTMLProgressElement.webidl +++ b/dom/webidl/HTMLProgressElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLProgressElement : HTMLElement { [SetterThrows] attribute double value; diff --git a/dom/webidl/HTMLQuoteElement.webidl b/dom/webidl/HTMLQuoteElement.webidl index a266dd353..5cf9c4c29 100644 --- a/dom/webidl/HTMLQuoteElement.webidl +++ b/dom/webidl/HTMLQuoteElement.webidl @@ -12,6 +12,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-blockquote-element +[HTMLConstructor] interface HTMLQuoteElement : HTMLElement { [SetterThrows, Pure] attribute DOMString cite; diff --git a/dom/webidl/HTMLScriptElement.webidl b/dom/webidl/HTMLScriptElement.webidl index 5b64c42d7..8bcffe8d7 100644 --- a/dom/webidl/HTMLScriptElement.webidl +++ b/dom/webidl/HTMLScriptElement.webidl @@ -8,6 +8,7 @@ * http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis */ +[HTMLConstructor] interface HTMLScriptElement : HTMLElement { [SetterThrows] attribute DOMString src; diff --git a/dom/webidl/HTMLSelectElement.webidl b/dom/webidl/HTMLSelectElement.webidl index b18ca3634..9a9b33040 100644 --- a/dom/webidl/HTMLSelectElement.webidl +++ b/dom/webidl/HTMLSelectElement.webidl @@ -7,6 +7,7 @@ * http://www.whatwg.org/html/#the-select-element */ +[HTMLConstructor] interface HTMLSelectElement : HTMLElement { [SetterThrows, Pure] attribute boolean autofocus; diff --git a/dom/webidl/HTMLSourceElement.webidl b/dom/webidl/HTMLSourceElement.webidl index 10b8e6fd5..402b4491a 100644 --- a/dom/webidl/HTMLSourceElement.webidl +++ b/dom/webidl/HTMLSourceElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLSourceElement : HTMLElement { [SetterThrows] attribute DOMString src; diff --git a/dom/webidl/HTMLSpanElement.webidl b/dom/webidl/HTMLSpanElement.webidl index 43a2d97f2..6f65cdfb3 100644 --- a/dom/webidl/HTMLSpanElement.webidl +++ b/dom/webidl/HTMLSpanElement.webidl @@ -12,4 +12,5 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-span-element +[HTMLConstructor] interface HTMLSpanElement : HTMLElement {}; diff --git a/dom/webidl/HTMLStyleElement.webidl b/dom/webidl/HTMLStyleElement.webidl index 7ed01a8f1..b547d6976 100644 --- a/dom/webidl/HTMLStyleElement.webidl +++ b/dom/webidl/HTMLStyleElement.webidl @@ -8,6 +8,7 @@ * http://www.whatwg.org/specs/web-apps/current-work/#other-elements,-attributes-and-apis */ +[HTMLConstructor] interface HTMLStyleElement : HTMLElement { [Pure] attribute boolean disabled; diff --git a/dom/webidl/HTMLTableCaptionElement.webidl b/dom/webidl/HTMLTableCaptionElement.webidl index 688b9f925..e9d01527e 100644 --- a/dom/webidl/HTMLTableCaptionElement.webidl +++ b/dom/webidl/HTMLTableCaptionElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLTableCaptionElement : HTMLElement {}; partial interface HTMLTableCaptionElement { diff --git a/dom/webidl/HTMLTableCellElement.webidl b/dom/webidl/HTMLTableCellElement.webidl index e970a5040..f0a251d27 100644 --- a/dom/webidl/HTMLTableCellElement.webidl +++ b/dom/webidl/HTMLTableCellElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLTableCellElement : HTMLElement { [SetterThrows] attribute unsigned long colSpan; diff --git a/dom/webidl/HTMLTableColElement.webidl b/dom/webidl/HTMLTableColElement.webidl index c927541a3..cf217548a 100644 --- a/dom/webidl/HTMLTableColElement.webidl +++ b/dom/webidl/HTMLTableColElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLTableColElement : HTMLElement { [SetterThrows] attribute unsigned long span; diff --git a/dom/webidl/HTMLTableElement.webidl b/dom/webidl/HTMLTableElement.webidl index a06f590e0..2653524d6 100644 --- a/dom/webidl/HTMLTableElement.webidl +++ b/dom/webidl/HTMLTableElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLTableElement : HTMLElement { [SetterThrows] attribute HTMLTableCaptionElement? caption; diff --git a/dom/webidl/HTMLTableRowElement.webidl b/dom/webidl/HTMLTableRowElement.webidl index 2a356a20e..7d63bcc04 100644 --- a/dom/webidl/HTMLTableRowElement.webidl +++ b/dom/webidl/HTMLTableRowElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLTableRowElement : HTMLElement { readonly attribute long rowIndex; readonly attribute long sectionRowIndex; diff --git a/dom/webidl/HTMLTableSectionElement.webidl b/dom/webidl/HTMLTableSectionElement.webidl index 310d0ece6..881972ac2 100644 --- a/dom/webidl/HTMLTableSectionElement.webidl +++ b/dom/webidl/HTMLTableSectionElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLTableSectionElement : HTMLElement { readonly attribute HTMLCollection rows; [Throws] diff --git a/dom/webidl/HTMLTemplateElement.webidl b/dom/webidl/HTMLTemplateElement.webidl index c518995f6..f77eeaa42 100644 --- a/dom/webidl/HTMLTemplateElement.webidl +++ b/dom/webidl/HTMLTemplateElement.webidl @@ -9,6 +9,7 @@ * liability, trademark and document use rules apply. */ +[HTMLConstructor] interface HTMLTemplateElement : HTMLElement { readonly attribute DocumentFragment content; }; diff --git a/dom/webidl/HTMLTextAreaElement.webidl b/dom/webidl/HTMLTextAreaElement.webidl index 4df687a0b..8c5dc0fb9 100644 --- a/dom/webidl/HTMLTextAreaElement.webidl +++ b/dom/webidl/HTMLTextAreaElement.webidl @@ -14,6 +14,7 @@ interface nsIEditor; interface MozControllers; +[HTMLConstructor] interface HTMLTextAreaElement : HTMLElement { // attribute DOMString autocomplete; [SetterThrows, Pure] diff --git a/dom/webidl/HTMLTimeElement.webidl b/dom/webidl/HTMLTimeElement.webidl index 517ca9981..ea37405bf 100644 --- a/dom/webidl/HTMLTimeElement.webidl +++ b/dom/webidl/HTMLTimeElement.webidl @@ -7,6 +7,7 @@ * http://www.whatwg.org/specs/web-apps/current-work/multipage/text-level-semantics.html#the-time-element */ +[HTMLConstructor] interface HTMLTimeElement : HTMLElement { [SetterThrows] attribute DOMString dateTime; diff --git a/dom/webidl/HTMLTitleElement.webidl b/dom/webidl/HTMLTitleElement.webidl index e6c8f2c61..c8fe3e46a 100644 --- a/dom/webidl/HTMLTitleElement.webidl +++ b/dom/webidl/HTMLTitleElement.webidl @@ -7,6 +7,7 @@ * http://www.whatwg.org/specs/web-apps/current-work/#the-title-element */ +[HTMLConstructor] interface HTMLTitleElement : HTMLElement { [Throws] attribute DOMString text; diff --git a/dom/webidl/HTMLTrackElement.webidl b/dom/webidl/HTMLTrackElement.webidl index dd88e9beb..e6d366f10 100644 --- a/dom/webidl/HTMLTrackElement.webidl +++ b/dom/webidl/HTMLTrackElement.webidl @@ -7,6 +7,7 @@ * http://www.whatwg.org/specs/web-apps/current-work/#the-track-element */ +[HTMLConstructor] interface HTMLTrackElement : HTMLElement { [SetterThrows, Pure] attribute DOMString kind; diff --git a/dom/webidl/HTMLUListElement.webidl b/dom/webidl/HTMLUListElement.webidl index 0528198c9..01ca7afce 100644 --- a/dom/webidl/HTMLUListElement.webidl +++ b/dom/webidl/HTMLUListElement.webidl @@ -13,6 +13,7 @@ */ // http://www.whatwg.org/specs/web-apps/current-work/#the-ul-element +[HTMLConstructor] interface HTMLUListElement : HTMLElement { }; diff --git a/dom/webidl/HTMLVideoElement.webidl b/dom/webidl/HTMLVideoElement.webidl index af28d5418..fd552f7e0 100644 --- a/dom/webidl/HTMLVideoElement.webidl +++ b/dom/webidl/HTMLVideoElement.webidl @@ -11,6 +11,7 @@ * and create derivative works of this document. */ +[HTMLConstructor] interface HTMLVideoElement : HTMLMediaElement { [SetterThrows] attribute unsigned long width; -- cgit v1.2.3 From 5b814fffd697bf16a4ac0a1242547b175b969411 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 21:47:43 -0500 Subject: Bug 1274159 - Part 3-2: Update web-platform-test expected result; Tag UXP Issue #1344 --- .../meta/custom-elements/CustomElementRegistry.html.ini | 3 --- .../meta/custom-elements/HTMLElement-constructor.html.ini | 11 ----------- .../custom-elements/htmlconstructor/newtarget.html.ini | 14 -------------- 3 files changed, 28 deletions(-) delete mode 100644 testing/web-platform/meta/custom-elements/HTMLElement-constructor.html.ini delete mode 100644 testing/web-platform/meta/custom-elements/htmlconstructor/newtarget.html.ini diff --git a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini index f62b64dfb..29be90bea 100644 --- a/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini +++ b/testing/web-platform/meta/custom-elements/CustomElementRegistry.html.ini @@ -18,9 +18,6 @@ [customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on observedAttributes] expected: FAIL - [customElements.define must define an instantiatable custom element] - expected: FAIL - [customElements.define must upgrade elements in the shadow-including tree order] expected: FAIL diff --git a/testing/web-platform/meta/custom-elements/HTMLElement-constructor.html.ini b/testing/web-platform/meta/custom-elements/HTMLElement-constructor.html.ini deleted file mode 100644 index 0d2d4374f..000000000 --- a/testing/web-platform/meta/custom-elements/HTMLElement-constructor.html.ini +++ /dev/null @@ -1,11 +0,0 @@ -[HTMLElement-constructor.html] - type: testharness - [HTMLElement constructor must infer the tag name from the element interface] - expected: FAIL - - [HTMLElement constructor must allow subclassing a custom element] - expected: FAIL - - [HTMLElement constructor must allow subclassing an user-defined subclass of HTMLElement] - expected: FAIL - diff --git a/testing/web-platform/meta/custom-elements/htmlconstructor/newtarget.html.ini b/testing/web-platform/meta/custom-elements/htmlconstructor/newtarget.html.ini deleted file mode 100644 index f77a64e1d..000000000 --- a/testing/web-platform/meta/custom-elements/htmlconstructor/newtarget.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[newtarget.html] - type: testharness - [Use NewTarget's prototype, not the one stored at definition time] - expected: FAIL - - [Rethrow any exceptions thrown while getting the prototype] - expected: FAIL - - [If prototype is not object, derives the fallback from NewTarget's realm (autonomous custom elements)] - expected: FAIL - - [If prototype is not object, derives the fallback from NewTarget's realm (customized built-in elements)] - expected: FAIL - -- cgit v1.2.3 From bac01e30fda6b9efc6a6545cbb982ec87ac9f2e9 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 21:48:12 -0500 Subject: Bug 1274159 - Part 4: Add test cases for HTMLConstructor; Tag UXP Issue #1344 --- dom/tests/mochitest/webcomponents/chrome.ini | 9 + dom/tests/mochitest/webcomponents/dummy_page.html | 10 + .../htmlconstructor_autonomous_tests.js | 81 +++++++ .../webcomponents/htmlconstructor_builtin_tests.js | 247 +++++++++++++++++++++ dom/tests/mochitest/webcomponents/mochitest.ini | 6 + .../test_custom_element_htmlconstructor.html | 42 ++++ ...test_custom_element_htmlconstructor_chrome.html | 41 ++++ dom/tests/moz.build | 1 + 8 files changed, 437 insertions(+) create mode 100644 dom/tests/mochitest/webcomponents/chrome.ini create mode 100644 dom/tests/mochitest/webcomponents/dummy_page.html create mode 100644 dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js create mode 100644 dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js create mode 100644 dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html create mode 100644 dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html diff --git a/dom/tests/mochitest/webcomponents/chrome.ini b/dom/tests/mochitest/webcomponents/chrome.ini new file mode 100644 index 000000000..5e25c2123 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/chrome.ini @@ -0,0 +1,9 @@ +[DEFAULT] +support-files = + dummy_page.html + +[test_custom_element_htmlconstructor_chrome.html] +skip-if = os == 'android' # bug 1323645 +support-files = + htmlconstructor_autonomous_tests.js + htmlconstructor_builtin_tests.js diff --git a/dom/tests/mochitest/webcomponents/dummy_page.html b/dom/tests/mochitest/webcomponents/dummy_page.html new file mode 100644 index 000000000..fd238954c --- /dev/null +++ b/dom/tests/mochitest/webcomponents/dummy_page.html @@ -0,0 +1,10 @@ + + + +Dummy test page + + + +

Dummy test page

+ + diff --git a/dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js b/dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js new file mode 100644 index 000000000..636d9aff6 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/htmlconstructor_autonomous_tests.js @@ -0,0 +1,81 @@ +promises.push(test_with_new_window((testWindow) => { + // Test calling the HTMLElement constructor. + (() => { + SimpleTest.doesThrow(() => { + testWindow.HTMLElement(); + }, 'calling the HTMLElement constructor should throw a TypeError'); + })(); + + // Test constructing a HTMLELement. + (() => { + SimpleTest.doesThrow(() => { + new testWindow.HTMLElement(); + }, 'constructing a HTMLElement should throw a TypeError'); + })(); + + // Test constructing a custom element with defining HTMLElement as entry. + (() => { + testWindow.customElements.define('x-defining-html-element', + testWindow.HTMLElement); + SimpleTest.doesThrow(() => { + new testWindow.HTMLElement(); + }, 'constructing a custom element with defining HTMLElement as registry ' + + 'entry should throw a TypeError'); + })(); + + // Test calling a custom element constructor and constructing an autonomous + // custom element. + (() => { + let num_constructor_invocations = 0; + class X extends testWindow.HTMLElement { + constructor() { + super(); + num_constructor_invocations++; + } + } + testWindow.customElements.define('x-element', X); + SimpleTest.doesThrow(() => { + X(); + }, 'calling an autonomous custom element constructor should throw a TypeError'); + + let element = new X(); + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype, + 'constructing an autonomous custom element; ' + + 'the element should be a registered constructor'); + SimpleTest.is(element.localName, 'x-element', + 'constructing an autonomous custom element; ' + + 'the element tag name should be "x-element"'); + SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml', + 'constructing an autonomous custom element; ' + + 'the element should be in the HTML namespace'); + SimpleTest.is(element.prefix, null, + 'constructing an autonomous custom element; ' + + 'the element name should not have a prefix'); + SimpleTest.is(element.ownerDocument, testWindow.document, + 'constructing an autonomous custom element; ' + + 'the element should be owned by the registry\'s associated ' + + 'document'); + SimpleTest.is(num_constructor_invocations, 1, + 'constructing an autonomous custom element; ' + + 'the constructor should have been invoked once'); + })(); + + // Test if prototype is no an object. + (() => { + function ElementWithNonObjectPrototype() { + let o = Reflect.construct(testWindow.HTMLElement, [], new.target); + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window.HTMLElement.prototype, + 'constructing an autonomous custom element; ' + + 'if prototype is not object, fallback from NewTarget\'s realm'); + } + + // Prototype have to be an object during define(), otherwise define will + // throw an TypeError exception. + ElementWithNonObjectPrototype.prototype = {}; + testWindow.customElements.define('x-non-object-prototype', + ElementWithNonObjectPrototype); + + ElementWithNonObjectPrototype.prototype = "string"; + new ElementWithNonObjectPrototype(); + })(); +})); diff --git a/dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js b/dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js new file mode 100644 index 000000000..dd6515148 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/htmlconstructor_builtin_tests.js @@ -0,0 +1,247 @@ +[ + // [TagName, InterfaceName] + ['a', 'Anchor'], + ['abbr', ''], + ['acronym', ''], + ['address', ''], + ['area', 'Area'], + ['article', ''], + ['aside', ''], + ['audio', 'Audio'], + ['b', ''], + ['base', 'Base'], + ['basefont', ''], + ['bdo', ''], + ['big', ''], + ['blockquote', 'Quote'], + ['body', 'Body'], + ['br', 'BR'], + ['button', 'Button'], + ['canvas', 'Canvas'], + ['caption', 'TableCaption'], + ['center', ''], + ['cite', ''], + ['code', ''], + ['col', 'TableCol'], + ['colgroup', 'TableCol'], + ['data', 'Data'], + ['datalist', 'DataList'], + ['dd', ''], + ['del', 'Mod'], + ['details', 'Details'], + ['dfn', ''], + ['dir', 'Directory'], + ['div', 'Div'], + ['dl', 'DList'], + ['dt', ''], + ['em', ''], + ['embed', 'Embed'], + ['fieldset', 'FieldSet'], + ['figcaption', ''], + ['figure', ''], + ['font', 'Font'], + ['footer', ''], + ['form', 'Form'], + ['frame', 'Frame'], + ['frameset', 'FrameSet'], + ['h1', 'Heading'], + ['h2', 'Heading'], + ['h3', 'Heading'], + ['h4', 'Heading'], + ['h5', 'Heading'], + ['h6', 'Heading'], + ['head', 'Head'], + ['header', ''], + ['hgroup', ''], + ['hr', 'HR'], + ['html', 'Html'], + ['i', ''], + ['iframe', 'IFrame'], + ['image', ''], + ['img', 'Image'], + ['input', 'Input'], + ['ins', 'Mod'], + ['kbd', ''], + ['label', 'Label'], + ['legend', 'Legend'], + ['li', 'LI'], + ['link', 'Link'], + ['listing', 'Pre'], + ['main', ''], + ['map', 'Map'], + ['mark', ''], + ['marquee', 'Div'], + ['menu', 'Menu'], + ['menuitem', 'MenuItem'], + ['meta', 'Meta'], + ['meter', 'Meter'], + ['nav', ''], + ['nobr', ''], + ['noembed', ''], + ['noframes', ''], + ['noscript', ''], + ['object', 'Object'], + ['ol', 'OList'], + ['optgroup', 'OptGroup'], + ['option', 'Option'], + ['output', 'Output'], + ['p', 'Paragraph'], + ['param', 'Param'], + ['picture', 'Picture'], + ['plaintext', ''], + ['pre', 'Pre'], + ['progress', 'Progress'], + ['q', 'Quote'], + ['rb', ''], + ['rp', ''], + ['rt', ''], + ['rtc', ''], + ['ruby', ''], + ['s', ''], + ['samp', ''], + ['script', 'Script'], + ['section', ''], + ['select', 'Select'], + ['small', ''], + ['source', 'Source'], + ['span', 'Span'], + ['strike', ''], + ['strong', ''], + ['style', 'Style'], + ['sub', ''], + ['summary', ''], + ['sup', ''], + ['table', 'Table'], + ['tbody', 'TableSection'], + ['td', 'TableCell'], + ['textarea', 'TextArea'], + ['tfoot', 'TableSection'], + ['th', 'TableCell'], + ['thead', 'TableSection'], + ['template', 'Template'], + ['time', 'Time'], + ['title', 'Title'], + ['tr', 'TableRow'], + ['track', 'Track'], + ['tt', ''], + ['u', ''], + ['ul', 'UList'], + ['var', ''], + ['video', 'Video'], + ['wbr', ''], + ['xmp', 'Pre'], +].forEach((e) => { + let tagName = e[0]; + let interfaceName = 'HTML' + e[1] + 'Element'; + promises.push(test_with_new_window((testWindow) => { + // Use window from iframe to isolate the test. + // Test calling the HTML*Element constructor. + (() => { + SimpleTest.doesThrow(() => { + testWindow[interfaceName](); + }, 'calling the ' + interfaceName + ' constructor should throw a TypeError'); + })(); + + // Test constructing a HTML*ELement. + (() => { + SimpleTest.doesThrow(() => { + new testWindow[interfaceName](); + }, 'constructing a ' + interfaceName + ' should throw a TypeError'); + })(); + + // Test constructing a custom element with defining HTML*Element as entry. + (() => { + testWindow.customElements.define('x-defining-' + tagName, + testWindow[interfaceName]); + SimpleTest.doesThrow(() => { + new testWindow[interfaceName](); + }, 'constructing a custom element with defining ' + interfaceName + + ' as registry entry should throw a TypeError'); + })(); + + // Since HTMLElement can be registered without specifying "extends", skip + // testing HTMLElement tags. + if (interfaceName !== "HTMLElement") { + // Test constructing a customized HTML*Element with defining a registry entry + // without specifying "extends". + (() => { + class X extends testWindow[interfaceName] {} + testWindow.customElements.define('x-defining-invalid-' + tagName, X); + SimpleTest.doesThrow(() => { + new X(); + }, 'constructing a customized ' + interfaceName + ' with defining a ' + + 'registry entry without specifying "extends" should throw a TypeError'); + })(); + } + + // Test constructing a built-in custom element with defining a registry entry + // with incorrect "extends" information. + (() => { + class X extends testWindow[interfaceName] {} + testWindow.customElements.define('x-defining-incorrect-' + tagName, X, + { extends: tagName === 'img' ? 'p' : 'img' }); + SimpleTest.doesThrow(() => { + new X(); + }, 'constructing a customized ' + interfaceName + ' with defining a ' + + 'registry entry with incorrect "extends" should throw a TypeError'); + })(); + + // Test calling a custom element constructor and constructing a built-in + // custom element. + (() => { + let num_constructor_invocations = 0; + class X extends testWindow[interfaceName] { + constructor() { + super(); + num_constructor_invocations++; + } + } + testWindow.customElements.define('x-' + tagName, X, { extends: tagName }); + SimpleTest.doesThrow(() => { + X(); + }, 'calling a customized ' + interfaceName + ' constructor should throw a TypeError'); + + let element = new X(); + + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(element)), X.prototype, + 'constructing a customized ' + interfaceName + + '; the element should be a registered constructor'); + SimpleTest.is(element.localName, tagName, + 'constructing a customized ' + interfaceName + + '; the element tag name should be "' + tagName + '"'); + SimpleTest.is(element.namespaceURI, 'http://www.w3.org/1999/xhtml', + 'constructing a customized ' + interfaceName + + '; the element should be in the HTML namespace'); + SimpleTest.is(element.prefix, null, + 'constructing a customized ' + interfaceName + + '; the element name should not have a prefix'); + SimpleTest.is(element.ownerDocument, testWindow.document, + 'constructing a customized ' + interfaceName + + '; the element should be owned by the registry\'s associated ' + + 'document'); + SimpleTest.is(num_constructor_invocations, 1, + 'constructing a customized ' + interfaceName + + '; the constructor should have been invoked once'); + })(); + + // Test if prototype is no an object. + (() => { + function ElementWithNonObjectPrototype() { + let o = Reflect.construct(testWindow[interfaceName], [], new.target); + SimpleTest.is(Object.getPrototypeOf(Cu.waiveXrays(o)), window[interfaceName].prototype, + 'constructing a customized ' + interfaceName + + '; if prototype is not object, fallback from NewTarget\'s realm'); + } + + // Prototype have to be an object during define(), otherwise define will + // throw an TypeError exception. + ElementWithNonObjectPrototype.prototype = {}; + testWindow.customElements.define('x-non-object-prototype-' + tagName, + ElementWithNonObjectPrototype, + { extends: tagName }); + + ElementWithNonObjectPrototype.prototype = "string"; + new ElementWithNonObjectPrototype(); + })(); + })); +}); diff --git a/dom/tests/mochitest/webcomponents/mochitest.ini b/dom/tests/mochitest/webcomponents/mochitest.ini index 496f7ea4d..3ab56de95 100644 --- a/dom/tests/mochitest/webcomponents/mochitest.ini +++ b/dom/tests/mochitest/webcomponents/mochitest.ini @@ -1,6 +1,7 @@ [DEFAULT] support-files = inert_style.css + dummy_page.html [test_bug900724.html] [test_bug1017896.html] @@ -11,6 +12,11 @@ support-files = [test_custom_element_callback_innerhtml.html] [test_custom_element_clone_callbacks.html] [test_custom_element_clone_callbacks_extended.html] +[test_custom_element_htmlconstructor.html] +skip-if = os == 'android' # bug 1323645 +support-files = + htmlconstructor_autonomous_tests.js + htmlconstructor_builtin_tests.js [test_custom_element_import_node_created_callback.html] [test_custom_element_in_shadow.html] [test_custom_element_register_invalid_callbacks.html] diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html new file mode 100644 index 000000000..b022a7887 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor.html @@ -0,0 +1,42 @@ + + + + + Test HTMLConstructor for custom elements. + + + + +Bug 1274159 + + + + + + + + diff --git a/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html new file mode 100644 index 000000000..8c7ec0ac6 --- /dev/null +++ b/dom/tests/mochitest/webcomponents/test_custom_element_htmlconstructor_chrome.html @@ -0,0 +1,41 @@ + + + + + Test HTMLConstructor for custom elements. + + + + +Bug 1274159 + + + + + + + + diff --git a/dom/tests/moz.build b/dom/tests/moz.build index f7c3e2437..7fc81abbd 100644 --- a/dom/tests/moz.build +++ b/dom/tests/moz.build @@ -37,6 +37,7 @@ MOCHITEST_CHROME_MANIFESTS += [ 'mochitest/geolocation/chrome.ini', 'mochitest/localstorage/chrome.ini', 'mochitest/sessionstorage/chrome.ini', + 'mochitest/webcomponents/chrome.ini', 'mochitest/whatwg/chrome.ini', ] -- cgit v1.2.3 From 3a97503b361b0b5ff1b5d8948a74497710f2a095 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Thu, 2 Jan 2020 22:04:11 -0500 Subject: Bug 1309184 - Implement upgrade reaction for custom element reactions. Tag UXP Issue #1344 --- dom/base/CustomElementRegistry.cpp | 186 +++++++++++++++++++++++++++++++------ dom/base/CustomElementRegistry.h | 110 ++++++++++++++++++++++ 2 files changed, 267 insertions(+), 29 deletions(-) diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 6cd213210..20eb59e94 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -137,6 +137,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CustomElementRegistry) cb.NoteXPCOMChild(callbacks->mDetachedCallback.Value()); } } + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWhenDefinedPromiseMap) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -237,6 +238,7 @@ CustomElementRegistry::sProcessingStack; CustomElementRegistry::CustomElementRegistry(nsPIDOMWindowInner* aWindow) : mWindow(aWindow) , mIsCustomDefinitionRunning(false) + , mIsBackupQueueProcessing(false) { mozilla::HoldJSObjects(this); @@ -502,35 +504,7 @@ CustomElementRegistry::UpgradeCandidates(JSContext* aCx, continue; } - elem->RemoveStates(NS_EVENT_STATE_UNRESOLVED); - - // Make sure that the element name matches the name in the definition. - // (e.g. a definition for x-button extending button should match - //