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 +++++++++ 5 files changed, 64 insertions(+) (limited to 'dom/base') 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. -- cgit v1.2.3