From 3a74795a56e92313c1b33a54500917794ba09b72 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 17 Apr 2020 07:05:27 -0400 Subject: Bug 1411878 - Support Element.shadowRoot and Element.assignedSlot / TextNode.assignedSlot on closed shadow root Tag #1375 --- dom/base/Element.cpp | 19 ++++++++++++++ dom/base/Element.h | 1 + dom/base/FragmentOrElement.cpp | 30 ++++++++++++++++++++++ dom/base/ShadowRoot.h | 5 ++++ dom/base/nsIContent.h | 9 +++++++ dom/webidl/Element.webidl | 4 +-- dom/webidl/Text.webidl | 2 +- ...Element-interface-shadowRoot-attribute.html.ini | 8 ------ 8 files changed, 67 insertions(+), 11 deletions(-) delete mode 100644 testing/web-platform/meta/shadow-dom/Element-interface-shadowRoot-attribute.html.ini diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 638d6674d..cd803a60f 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1104,6 +1104,25 @@ Element::GetSlot(nsAString& aName) GetAttr(kNameSpaceID_None, nsGkAtoms::slot, aName); } +// https://dom.spec.whatwg.org/#dom-element-shadowroot +ShadowRoot* +Element::GetShadowRootByMode() const +{ + /** + * 1. Let shadow be context object’s shadow root. + * 2. If shadow is null or its mode is "closed", then return null. + */ + ShadowRoot* shadowRoot = GetShadowRoot(); + if (!shadowRoot || shadowRoot->IsClosed()) { + return nullptr; + } + + /** + * 3. Return shadow. + */ + return shadowRoot; +} + // https://dom.spec.whatwg.org/#dom-element-attachshadow already_AddRefed Element::AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError) diff --git a/dom/base/Element.h b/dom/base/Element.h index 6169fbdab..23a9fee52 100644 --- a/dom/base/Element.h +++ b/dom/base/Element.h @@ -927,6 +927,7 @@ public: // Shadow DOM v1 already_AddRefed AttachShadow(const ShadowRootInit& aInit, ErrorResult& aError); + ShadowRoot* GetShadowRootByMode() const; void SetSlot(const nsAString& aName, ErrorResult& aError); void GetSlot(nsAString& aName); diff --git a/dom/base/FragmentOrElement.cpp b/dom/base/FragmentOrElement.cpp index 486bbc88c..766e2b115 100644 --- a/dom/base/FragmentOrElement.cpp +++ b/dom/base/FragmentOrElement.cpp @@ -152,6 +152,36 @@ nsIContent::FindFirstNonChromeOnlyAccessContent() const return nullptr; } +// https://dom.spec.whatwg.org/#dom-slotable-assignedslot +HTMLSlotElement* +nsIContent::GetAssignedSlotByMode() const +{ + /** + * Get slotable's assigned slot for the result of + * find a slot with open flag UNSET [1]. + * + * [1] https://dom.spec.whatwg.org/#assign-a-slot + */ + HTMLSlotElement* slot = GetAssignedSlot(); + if (!slot) { + return nullptr; + } + + MOZ_ASSERT(GetParent()); + MOZ_ASSERT(GetParent()->GetShadowRoot()); + + /** + * Additional check for open flag SET: + * If slotable’s parent’s shadow root's mode is not "open", + * then return null. + */ + if (GetParent()->GetShadowRoot()->IsClosed()) { + return nullptr; + } + + return slot; +} + nsINode* nsIContent::GetFlattenedTreeParentNodeInternal(FlattenedParentType aType) const { diff --git a/dom/base/ShadowRoot.h b/dom/base/ShadowRoot.h index f061735e2..4a5b54e85 100644 --- a/dom/base/ShadowRoot.h +++ b/dom/base/ShadowRoot.h @@ -51,6 +51,11 @@ public: { return mMode; } + bool IsClosed() + { + return mMode == ShadowRootMode::Closed; + } + // [deprecated] Shadow DOM v0 void AddToIdTable(Element* aElement, nsIAtom* aId); diff --git a/dom/base/nsIContent.h b/dom/base/nsIContent.h index f368497f4..8da0ba7f2 100644 --- a/dom/base/nsIContent.h +++ b/dom/base/nsIContent.h @@ -724,6 +724,15 @@ public: */ virtual void SetAssignedSlot(mozilla::dom::HTMLSlotElement* aSlot) = 0; + /** + * Gets the assigned slot associated with this content based on parent's + * shadow root mode. Returns null if parent's shadow root is "closed". + * https://dom.spec.whatwg.org/#dom-slotable-assignedslot + * + * @return The assigned slot element or null. + */ + mozilla::dom::HTMLSlotElement* GetAssignedSlotByMode() const; + /** * Gets the insertion parent element of the XBL binding. * The insertion parent is our one true parent in the transformed DOM. diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl index ddc548442..f6d0f7f93 100644 --- a/dom/webidl/Element.webidl +++ b/dom/webidl/Element.webidl @@ -238,9 +238,9 @@ partial interface Element { // Shadow DOM v1 [Throws, Pref="nsDocument::IsWebComponentsEnabled"] ShadowRoot attachShadow(ShadowRootInit shadowRootInitDict); - [Func="nsDocument::IsWebComponentsEnabled"] + [BinaryName="shadowRootByMode", Func="nsDocument::IsWebComponentsEnabled"] readonly attribute ShadowRoot? shadowRoot; - [Pref="nsDocument::IsWebComponentsEnabled"] + [BinaryName="assignedSlotByMode", Pref="nsDocument::IsWebComponentsEnabled"] readonly attribute HTMLSlotElement? assignedSlot; [CEReactions, Unscopable, SetterThrows, Pref="nsDocument::IsWebComponentsEnabled"] attribute DOMString slot; diff --git a/dom/webidl/Text.webidl b/dom/webidl/Text.webidl index f7bd1a971..c40b71cc5 100644 --- a/dom/webidl/Text.webidl +++ b/dom/webidl/Text.webidl @@ -19,7 +19,7 @@ interface Text : CharacterData { }; partial interface Text { - [Pref="dom.webcomponents.enabled"] + [BinaryName="assignedSlotByMode", Pref="dom.webcomponents.enabled"] readonly attribute HTMLSlotElement? assignedSlot; }; diff --git a/testing/web-platform/meta/shadow-dom/Element-interface-shadowRoot-attribute.html.ini b/testing/web-platform/meta/shadow-dom/Element-interface-shadowRoot-attribute.html.ini deleted file mode 100644 index 66573a688..000000000 --- a/testing/web-platform/meta/shadow-dom/Element-interface-shadowRoot-attribute.html.ini +++ /dev/null @@ -1,8 +0,0 @@ -[Element-interface-shadowRoot-attribute.html] - type: testharness - [shadowRoot attribute must return the open shadow root associated with the element] - expected: FAIL - - [shadowRoot attribute must return null if the shadow root attached to the element is closed] - expected: FAIL - -- cgit v1.2.3