author | Brian Grinstead <bgrinstead@mozilla.com> |
Thu, 29 Mar 2018 09:34:56 -0700 | |
changeset 411556 | e220521c6ff6ff9a45e19b3917ba95e678fd9932 |
parent 411555 | 8f3d33f7c72babbf232f1938e982d4dd5f54f142 |
child 411557 | 1fb1569b61d292785497c3f662b8a387c638695a |
push id | 101686 |
push user | aciure@mozilla.com |
push date | Tue, 03 Apr 2018 21:59:31 +0000 |
treeherder | mozilla-inbound@8d846598d35d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | e7358d9c |
bugs | 1446247, 590837 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -677,18 +677,20 @@ CustomElementRegistry::Define(const nsAS aRv.ThrowTypeError<MSG_NOT_CONSTRUCTOR>(NS_LITERAL_STRING("Argument 2 of CustomElementRegistry.define")); return; } /** * 2. If name is not a valid custom element name, then throw a "SyntaxError" * DOMException and abort these steps. */ + nsIDocument* doc = mWindow->GetExtantDoc(); + uint32_t nameSpaceID = doc ? doc->GetDefaultNamespaceID() : kNameSpaceID_XHTML; RefPtr<nsAtom> nameAtom(NS_Atomize(aName)); - if (!nsContentUtils::IsCustomElementName(nameAtom)) { + if (!nsContentUtils::IsCustomElementName(nameAtom, nameSpaceID)) { aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); return; } /** * 3. If this CustomElementRegistry contains an entry with name name, then * throw a "NotSupportedError" DOMException and abort these steps. */ @@ -720,17 +722,17 @@ CustomElementRegistry::Define(const nsAS * HTMLUnknownElement (e.g., if extends does not indicate an element * definition in this specification), then throw a "NotSupportedError" * DOMException. * 3. Set localName to extends. */ nsAutoString localName(aName); if (aOptions.mExtends.WasPassed()) { RefPtr<nsAtom> extendsAtom(NS_Atomize(aOptions.mExtends.Value())); - if (nsContentUtils::IsCustomElementName(extendsAtom)) { + if (nsContentUtils::IsCustomElementName(extendsAtom, nameSpaceID)) { aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return; } // bgsound and multicol are unknown html element. int32_t tag = nsHTMLTags::CaseSensitiveAtomTagToId(extendsAtom); if (tag == eHTMLTag_userdefined || tag == eHTMLTag_bgsound || @@ -960,17 +962,19 @@ CustomElementRegistry::WhenDefined(const nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow); RefPtr<Promise> promise = Promise::Create(global, aRv); if (aRv.Failed()) { return nullptr; } RefPtr<nsAtom> nameAtom(NS_Atomize(aName)); - if (!nsContentUtils::IsCustomElementName(nameAtom)) { + nsIDocument* doc = mWindow->GetExtantDoc(); + uint32_t nameSpaceID = doc ? doc->GetDefaultNamespaceID() : kNameSpaceID_XHTML; + if (!nsContentUtils::IsCustomElementName(nameAtom, nameSpaceID)) { promise->MaybeReject(NS_ERROR_DOM_SYNTAX_ERR); return promise.forget(); } if (mCustomDefinitions.GetWeak(nameAtom)) { promise->MaybeResolve(JS::UndefinedHandleValue); return promise.forget(); }
--- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1191,17 +1191,17 @@ Element::AttachShadow(const ShadowRootIn /** * 2. If context object’s local name is not * a valid custom element name, "article", "aside", "blockquote", * "body", "div", "footer", "h1", "h2", "h3", "h4", "h5", "h6", * "header", "main" "nav", "p", "section", or "span", * then throw a "NotSupportedError" DOMException. */ nsAtom* nameAtom = NodeInfo()->NameAtom(); - if (!(nsContentUtils::IsCustomElementName(nameAtom) || + if (!(nsContentUtils::IsCustomElementName(nameAtom, NodeInfo()->NamespaceID()) || nameAtom == nsGkAtoms::article || nameAtom == nsGkAtoms::aside || nameAtom == nsGkAtoms::blockquote || nameAtom == nsGkAtoms::body || nameAtom == nsGkAtoms::div || nameAtom == nsGkAtoms::footer || nameAtom == nsGkAtoms::h1 || nameAtom == nsGkAtoms::h2 || @@ -4303,17 +4303,17 @@ Element::ClearServoData(nsIDocument* aDo void Element::SetCustomElementData(CustomElementData* aData) { nsExtendedDOMSlots *slots = ExtendedDOMSlots(); MOZ_ASSERT(!slots->mCustomElementData, "Custom element data may not be changed once set."); #if DEBUG nsAtom* name = NodeInfo()->NameAtom(); nsAtom* type = aData->GetCustomElementType(); - if (nsContentUtils::IsCustomElementName(name)) { + if (nsContentUtils::IsCustomElementName(name, NodeInfo()->NamespaceID())) { MOZ_ASSERT(type == name); } else { MOZ_ASSERT(type != name); } #endif slots->mCustomElementData = aData; }
--- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3189,18 +3189,23 @@ nsContentUtils::NewURIWithDocumentCharse aDocument->GetDocumentCharacterSet(), aBaseURI, sIOService); } return NS_NewURI(aResult, aSpec, nullptr, aBaseURI, sIOService); } // static bool -nsContentUtils::IsCustomElementName(nsAtom* aName) -{ +nsContentUtils::IsCustomElementName(nsAtom* aName, uint32_t aNameSpaceID) +{ + // Allow non-dashed names in XUL for XBL to Custom Element migrations. + if (aNameSpaceID == kNameSpaceID_XUL) { + return true; + } + // A valid custom element name is a sequence of characters name which // must match the PotentialCustomElementName production: // PotentialCustomElementName ::= [a-z] (PCENChar)* '-' (PCENChar)* const char16_t* name = aName->GetUTF16String(); uint32_t len = aName->GetLength(); bool hasDash = false; if (!len || name[0] < 'a' || name[0] > 'z') { @@ -9981,19 +9986,19 @@ nsContentUtils::NewXULOrHTMLElement(Elem "Can only create XUL or XHTML elements."); nsAtom *name = nodeInfo->NameAtom(); int32_t tag = eHTMLTag_unknown; bool isCustomElementName = false; if (nodeInfo->NamespaceEquals(kNameSpaceID_XHTML)) { tag = nsHTMLTags::CaseSensitiveAtomTagToId(name); isCustomElementName = (tag == eHTMLTag_userdefined && - nsContentUtils::IsCustomElementName(name)); + nsContentUtils::IsCustomElementName(name, kNameSpaceID_XHTML)); } else { - isCustomElementName = nsContentUtils::IsCustomElementName(name); + isCustomElementName = nsContentUtils::IsCustomElementName(name, kNameSpaceID_XUL); } RefPtr<nsAtom> tagAtom = nodeInfo->NameAtom(); RefPtr<nsAtom> typeAtom; bool isCustomElement = isCustomElementName || aIsAtom; if (isCustomElement) { typeAtom = isCustomElementName ? tagAtom.get() : aIsAtom; }
--- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -705,17 +705,17 @@ public: const nsAString& aSpec, nsIDocument* aDocument, nsIURI* aBaseURI); /** * Returns true if |aName| is a valid name to be registered via * customElements.define. */ - static bool IsCustomElementName(nsAtom* aName); + static bool IsCustomElementName(nsAtom* aName, uint32_t aNameSpaceID); static nsresult CheckQName(const nsAString& aQualifiedName, bool aNamespaceAware = true, const char16_t** aColon = nullptr); static nsresult SplitQName(const nsIContent* aNamespaceResolver, const nsString& aQName, int32_t *aNamespace, nsAtom **aLocalName);
--- a/dom/tests/mochitest/webcomponents/test_xul_custom_element.xul +++ b/dom/tests/mochitest/webcomponents/test_xul_custom_element.xul @@ -21,16 +21,19 @@ connectedCallback() { this.textContent = "foo"; } } customElements.define("test-custom-element", TestCustomElement); + class TestWithoutDash extends XULElement { } + customElements.define("testwithoutdash", TestWithoutDash); + function runTest() { const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; let element = document.createElementNS(XUL_NS, "test-custom-element"); document.querySelector("#content").appendChild(element); is(element.textContent, "foo", "Should have set the textContent"); ok(element instanceof TestCustomElement, "Should be an instance of TestCustomElement"); @@ -48,21 +51,25 @@ is(element3.textContent, "foo", "Should have set the textContent"); ok(element3 instanceof TestCustomElement, "Should be an instance of TestCustomElement"); let element4 = document.getElementById("element4"); is(element4.textContent, "foo", "Parser should have instantiated the custom element."); ok(element4 instanceof TestCustomElement, "Should be an instance of TestCustomElement"); + let element5 = document.getElementById("element5"); + ok(element5 instanceof TestWithoutDash, "Should be an instance of TestWithoutDash"); + SimpleTest.finish(); } ]]> </script> <body xmlns="http://www.w3.org/1999/xhtml"> <p id="display"></p> <div id="content" style="display: none"> <test-custom-element id="element4" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/> + <testwithoutdash id="element5" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/> </div> <pre id="test"></pre> </body> </window>