diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 08e130744069..6a6726acd10d 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1200,26 +1200,15 @@ Element::GetShadowRootByMode() const return shadowRoot; } -// https://dom.spec.whatwg.org/#dom-element-attachshadow -already_AddRefed -Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError) +bool +Element::CanAttachShadowDOM() const { /** - * 1. If context object’s namespace is not the HTML namespace, - * then throw a "NotSupportedError" DOMException. - */ - if (!IsHTMLElement() && - !(XRE_IsParentProcess() && IsXULElement() && nsContentUtils::AllowXULXBLForPrincipal(NodePrincipal()))) { - aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); - return nullptr; - } - - /** - * 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. + * 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", + * return false. */ nsAtom* nameAtom = NodeInfo()->NameAtom(); if (!(nsContentUtils::IsCustomElementName(nameAtom, NodeInfo()->NamespaceID()) || @@ -1241,12 +1230,37 @@ Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError) nameAtom == nsGkAtoms::p || nameAtom == nsGkAtoms::section || nameAtom == nsGkAtoms::span)) { + return false; + } + + return true; +} + +// https://dom.spec.whatwg.org/#dom-element-attachshadow +already_AddRefed +Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError) +{ + /** + * 1. If context object’s namespace is not the HTML namespace, + * then throw a "NotSupportedError" DOMException. + */ + if (!IsHTMLElement() && + !(XRE_IsParentProcess() && IsXULElement() && nsContentUtils::AllowXULXBLForPrincipal(NodePrincipal()))) { aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); return nullptr; } /** - * 3. If context object is a shadow host, then throw + * 2. If context object’s local name is not valid to attach shadow DOM to, + * then throw a "NotSupportedError" DOMException. + */ + if (!CanAttachShadowDOM()) { + aError.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return nullptr; + } + + /** + * 2. If context object is a shadow host, then throw * an "InvalidStateError" DOMException. */ if (GetShadowRoot() || GetXBLBinding()) { diff --git a/dom/base/Element.h b/dom/base/Element.h index 06461bab39dc..527800aa572a 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -1267,6 +1267,7 @@ public: // Shadow DOM v1 already_AddRefed AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError); + bool CanAttachShadowDOM() const; already_AddRefed AttachShadowWithoutNameChecks(ShadowRootMode aMode); void UnattachShadow(); diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index d72772c55a71..2f8db4817024 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -4932,20 +4932,6 @@ HTMLMediaElement::AssertReadyStateIsNothing() #endif } -void -HTMLMediaElement::AttachAndSetUAShadowRoot() -{ - if (GetShadowRoot()) { - MOZ_ASSERT(GetShadowRoot()->IsUAWidget()); - return; - } - - // Add a closed shadow root to host video controls - RefPtr shadowRoot = - AttachShadowWithoutNameChecks(ShadowRootMode::Closed); - shadowRoot->SetIsUAWidget(); -} - nsresult HTMLMediaElement::InitializeDecoderAsClone(ChannelMediaDecoder* aOriginal) { diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index 7ecebec658f7..d12a6416b83c 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -1903,9 +1903,6 @@ private: // For debugging bug 1407148. void AssertReadyStateIsNothing(); - // Attach UA Shadow Root if it is not attached. - void AttachAndSetUAShadowRoot(); - // Contains the unique id of the sink device and the device info. // The initial value is ("", nullptr) and the default output device is used. // It can contain an invalid id and info if the device has been diff --git a/dom/html/nsGenericHTMLElement.cpp b/dom/html/nsGenericHTMLElement.cpp index b4de2b38872e..ec023505dac2 100644 --- a/dom/html/nsGenericHTMLElement.cpp +++ b/dom/html/nsGenericHTMLElement.cpp @@ -2892,6 +2892,21 @@ nsGenericHTMLElement::IsEventAttributeNameInternal(nsAtom *aName) return nsContentUtils::IsEventAttributeName(aName, EventNameType_HTML); } +void +nsGenericHTMLElement::AttachAndSetUAShadowRoot() +{ + MOZ_DIAGNOSTIC_ASSERT(!CanAttachShadowDOM(), + "Cannot be used to attach UI shadow DOM"); + if (GetShadowRoot()) { + MOZ_ASSERT(GetShadowRoot()->IsUAWidget()); + return; + } + + RefPtr shadowRoot = + AttachShadowWithoutNameChecks(ShadowRootMode::Closed); + shadowRoot->SetIsUAWidget(); +} + /** * Construct a URI from a string, as an element.src attribute * would be set to. Helper for the media elements. diff --git a/dom/html/nsGenericHTMLElement.h b/dom/html/nsGenericHTMLElement.h index 4bd3be4e7a9e..37d068c6daa0 100644 --- a/dom/html/nsGenericHTMLElement.h +++ b/dom/html/nsGenericHTMLElement.h @@ -256,6 +256,9 @@ public: return IsNodeInternal(aFirst, aArgs...); } + // Attach UA Shadow Root if it is not attached. + void AttachAndSetUAShadowRoot(); + protected: virtual ~nsGenericHTMLElement() {}