From 0f26d40142fa40042b139bd5c5117db85e7a38f0 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 17 Apr 2020 07:10:54 -0400 Subject: Bug 1409975 - Implement node distribution for shadow tree slots * Implementation for assignedNodes * Include slots in the flat tree * Fix event get-the-parent algorithm for a node * Update and add reftests for Shadow DOM v1 * Update web platform tests expectations Tag mcp-graveyard/UXP%1375 --- dom/base/ChildIterator.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'dom/base/ChildIterator.cpp') diff --git a/dom/base/ChildIterator.cpp b/dom/base/ChildIterator.cpp index dc356fc01..ae5f4665d 100644 --- a/dom/base/ChildIterator.cpp +++ b/dom/base/ChildIterator.cpp @@ -6,6 +6,7 @@ #include "ChildIterator.h" #include "nsContentUtils.h" +#include "mozilla/dom/HTMLSlotElement.h" #include "mozilla/dom/XBLChildrenElement.h" #include "mozilla/dom/ShadowRoot.h" #include "nsIAnonymousContentCreator.h" @@ -57,15 +58,34 @@ GetMatchedNodesForPoint(nsIContent* aContent) // XXX handle element? } +ExplicitChildIterator::ExplicitChildIterator(const nsIContent* aParent, + bool aStartAtBeginning) + : mParent(aParent), + mChild(nullptr), + mDefaultChild(nullptr), + mIsFirst(aStartAtBeginning), + mIndexInInserted(0) +{ + mParentAsSlot = HTMLSlotElement::FromContent(mParent); +} + nsIContent* ExplicitChildIterator::GetNextChild() { // If we're already in the inserted-children array, look there first if (mIndexInInserted) { MOZ_ASSERT(mChild); - MOZ_ASSERT(nsContentUtils::IsContentInsertionPoint(mChild)); MOZ_ASSERT(!mDefaultChild); + if (mParentAsSlot) { + const nsTArray>& assignedNodes = + mParentAsSlot->AssignedNodes(); + + mChild = (mIndexInInserted < assignedNodes.Length()) ? + assignedNodes[mIndexInInserted++]->AsContent() : nullptr; + return mChild; + } + MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild); if (mIndexInInserted < assignedChildren.Length()) { return assignedChildren[mIndexInInserted++]; @@ -84,6 +104,19 @@ ExplicitChildIterator::GetNextChild() mChild = mChild->GetNextSibling(); } else if (mIsFirst) { // at the beginning of the child list + // For slot parent, iterate over assigned nodes if not empty, otherwise + // fall through and iterate over direct children (fallback content). + if (mParentAsSlot) { + const nsTArray>& assignedNodes = + mParentAsSlot->AssignedNodes(); + if (!assignedNodes.IsEmpty()) { + mIndexInInserted = 1; + mChild = assignedNodes[0]->AsContent(); + mIsFirst = false; + return mChild; + } + } + mChild = mParent->GetFirstChild(); mIsFirst = false; } else if (mChild) { // in the middle of the child list @@ -185,6 +218,12 @@ ExplicitChildIterator::Get() const { MOZ_ASSERT(!mIsFirst); + // When mParentAsSlot is set, mChild is always set to the current child. It + // does not matter whether mChild is an assigned node or a fallback content. + if (mParentAsSlot) { + return mChild; + } + if (mIndexInInserted) { MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild); return assignedChildren[mIndexInInserted - 1]; @@ -198,6 +237,20 @@ ExplicitChildIterator::GetPreviousChild() { // If we're already in the inserted-children array, look there first if (mIndexInInserted) { + + if (mParentAsSlot) { + const nsTArray>& assignedNodes = + mParentAsSlot->AssignedNodes(); + + mChild = (--mIndexInInserted) ? + assignedNodes[mIndexInInserted - 1]->AsContent() : nullptr; + + if (!mChild) { + mIsFirst = true; + } + return mChild; + } + // NB: mIndexInInserted points one past the last returned child so we need // to look *two* indices back in order to return the previous child. MatchedNodes assignedChildren = GetMatchedNodesForPoint(mChild); @@ -218,6 +271,18 @@ ExplicitChildIterator::GetPreviousChild() } else if (mChild) { // in the middle of the child list mChild = mChild->GetPreviousSibling(); } else { // at the end of the child list + // For slot parent, iterate over assigned nodes if not empty, otherwise + // fall through and iterate over direct children (fallback content). + if (mParentAsSlot) { + const nsTArray>& assignedNodes = + mParentAsSlot->AssignedNodes(); + if (!assignedNodes.IsEmpty()) { + mIndexInInserted = assignedNodes.Length(); + mChild = assignedNodes[mIndexInInserted - 1]->AsContent(); + return mChild; + } + } + mChild = mParent->GetLastChild(); } -- cgit v1.2.3