From 715a8e1d098ba1b1e781cc314417a7b052f39cc0 Mon Sep 17 00:00:00 2001 From: pstanciu Date: Sat, 23 Mar 2024 02:24:26 +0200 Subject: [PATCH] Backed out 12 changesets (bug 1867058) for causing bustages on AbstractRange.cpp Backed out changeset 6254c9c51033 (bug 1867058) Backed out changeset 2ad556d56736 (bug 1867058) Backed out changeset a8bc41291ab3 (bug 1867058) Backed out changeset c30869c03a70 (bug 1867058) Backed out changeset 39c5816dff6b (bug 1867058) Backed out changeset 42e226158dc9 (bug 1867058) Backed out changeset 67bb7158a09f (bug 1867058) Backed out changeset 7b5a689dc7fd (bug 1867058) Backed out changeset 3cf108eb13a6 (bug 1867058) Backed out changeset 8efda4cce80c (bug 1867058) Backed out changeset 0837e15babab (bug 1867058) Backed out changeset 8ce7972ea4df (bug 1867058) --- dom/base/AbstractRange.cpp | 181 +-------- dom/base/AbstractRange.h | 30 +- dom/base/ContentIterator.cpp | 271 ++------------ dom/base/ContentIterator.h | 50 +-- dom/base/Element.cpp | 16 - dom/base/RangeBoundary.h | 29 -- dom/base/RangeUtils.cpp | 7 +- dom/base/ScriptableContentIterator.cpp | 16 - dom/base/Selection.cpp | 259 +++---------- dom/base/Selection.h | 51 +-- dom/base/StaticRange.cpp | 10 - dom/base/StaticRange.h | 16 - dom/base/nsINode.cpp | 66 +--- dom/base/nsINode.h | 10 +- dom/base/nsIScriptableContentIterator.idl | 5 - dom/base/nsRange.cpp | 350 +++--------------- dom/base/nsRange.h | 149 +------- dom/base/test/mochitest.toml | 2 - ..._content_iterator_subtree_shadow_tree.html | 286 -------------- dom/serializers/nsDocumentEncoder.cpp | 8 +- dom/webidl/Range.webidl | 9 - dom/webidl/Selection.webidl | 5 - layout/generic/nsFrameSelection.cpp | 22 +- layout/generic/nsFrameSelection.h | 32 +- layout/generic/nsIFrame.cpp | 17 +- layout/generic/test/mochitest.toml | 25 -- .../selection_cross_shadow_boundary_helper.js | 28 -- ...ross_shadow_boundary_1_backward_click.html | 36 -- ...cross_shadow_boundary_1_backward_drag.html | 40 -- ...cross_shadow_boundary_1_forward_click.html | 35 -- ..._cross_shadow_boundary_1_forward_drag.html | 39 -- ...ross_shadow_boundary_2_backward_click.html | 47 --- ...cross_shadow_boundary_2_backward_drag.html | 48 --- ...cross_shadow_boundary_2_forward_click.html | 46 --- ..._cross_shadow_boundary_2_forward_drag.html | 48 --- ..._boundary_multi_ranges_backward_click.html | 61 --- ...w_boundary_multi_ranges_backward_drag.html | 65 ---- ...w_boundary_multi_ranges_forward_click.html | 59 --- ...ow_boundary_multi_ranges_forward_drag.html | 65 ---- modules/libpref/init/StaticPrefList.yaml | 8 - .../meta/selection/idlharness.window.js.ini | 15 + ...ion-collapse-and-extend.tentative.html.ini | 12 + .../selection-direction.tentative.html.ini | 21 ++ ...ction-getComposedRanges.tentative.html.ini | 30 ++ .../cross-shadow-boundary-1-ref.html | 6 - .../shadow-dom/cross-shadow-boundary-1.html | 10 - .../cross-shadow-boundary-2-ref.html | 7 - .../shadow-dom/cross-shadow-boundary-2.html | 11 - .../cross-shadow-boundary-3-ref.html | 12 - .../shadow-dom/cross-shadow-boundary-3.html | 17 - .../shadow-dom/cross-shadow-boundary-4.html | 21 -- .../cross-shadow-boundary-5-ref.html | 13 - .../shadow-dom/cross-shadow-boundary-5.html | 20 - .../cross-shadow-boundary-img-ref.html | 9 - .../shadow-dom/cross-shadow-boundary-img.html | 26 -- ...s-shadow-boundary-select-document-ref.html | 9 - ...cross-shadow-boundary-select-document.html | 12 - ...cross-shadow-boundary-select-root-ref.html | 11 - .../cross-shadow-boundary-select-root.html | 24 -- .../selection-direction.tentative.html | 46 --- 60 files changed, 297 insertions(+), 2582 deletions(-) delete mode 100644 dom/base/test/test_content_iterator_subtree_shadow_tree.html delete mode 100644 layout/generic/test/selection_cross_shadow_boundary_helper.js delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_backward_click.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_backward_drag.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_forward_click.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_1_forward_drag.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_backward_click.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_backward_drag.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_forward_click.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_2_forward_drag.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_click.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_backward_drag.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_click.html delete mode 100644 layout/generic/test/test_selection_cross_shadow_boundary_multi_ranges_forward_drag.html create mode 100644 testing/web-platform/meta/shadow-dom/selection-collapse-and-extend.tentative.html.ini create mode 100644 testing/web-platform/meta/shadow-dom/selection-direction.tentative.html.ini create mode 100644 testing/web-platform/meta/shadow-dom/selection-getComposedRanges.tentative.html.ini delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-1-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-1.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-2-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-2.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-3-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-3.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-4.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-5-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-5.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-img-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-img.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-select-document-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-select-document.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-select-root-ref.html delete mode 100644 testing/web-platform/tests/selection/shadow-dom/cross-shadow-boundary-select-root.html diff --git a/dom/base/AbstractRange.cpp b/dom/base/AbstractRange.cpp index 2c9d9040758a..91234bf0a7e4 100644 --- a/dom/base/AbstractRange.cpp +++ b/dom/base/AbstractRange.cpp @@ -10,7 +10,6 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/RangeUtils.h" -#include "mozilla/dom/ChildIterator.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/StaticRange.h" #include "mozilla/dom/Selection.h" @@ -88,29 +87,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AbstractRange) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRegisteredClosestCommonInclusiveAncestor) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -// When aMarkDesendants is true, Set -// DescendantOfClosestCommonInclusiveAncestorForRangeInSelection flag for the -// flattened children of aNode. When aMarkDesendants is false, unset that flag -// for the flattened children of aNode. -void UpdateDescendantsInFlattenedTree(const nsIContent& aNode, - bool aMarkDesendants) { - if (!aNode.IsElement() || aNode.IsHTMLElement(nsGkAtoms::slot)) { - return; - } - - FlattenedChildIterator iter(&aNode); - for (nsIContent* child = iter.GetNextChild(); child; - child = iter.GetNextChild()) { - if (aMarkDesendants) { - child->SetDescendantOfClosestCommonInclusiveAncestorForRangeInSelection(); - } else { - child - ->ClearDescendantOfClosestCommonInclusiveAncestorForRangeInSelection(); - } - UpdateDescendantsInFlattenedTree(*child, aMarkDesendants); - } -} - void AbstractRange::MarkDescendants(const nsINode& aNode) { // Set NodeIsDescendantOfClosestCommonInclusiveAncestorForRangeInSelection on // aNode's descendants unless aNode is already marked as a range common @@ -119,22 +95,10 @@ void AbstractRange::MarkDescendants(const nsINode& aNode) { if (!aNode.IsMaybeSelected()) { // don't set the Descendant bit on |aNode| itself nsINode* node = aNode.GetNextNode(&aNode); - if (!node) { - if (const ShadowRoot* shadowRoot = aNode.GetShadowRootForSelection()) { - UpdateDescendantsInFlattenedTree(*aNode.AsContent(), true); - } - return; - } while (node) { node->SetDescendantOfClosestCommonInclusiveAncestorForRangeInSelection(); if (!node->IsClosestCommonInclusiveAncestorForRangeInSelection()) { - if (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) { - UpdateDescendantsInFlattenedTree(*node->AsContent(), true); - // sub-tree of node has been marked already - node = node->GetNextNonChildNode(&aNode); - } else { - node = node->GetNextNode(&aNode); - } + node = node->GetNextNode(&aNode); } else { // optimize: skip this sub-tree since it's marked already. node = node->GetNextNonChildNode(&aNode); @@ -152,22 +116,10 @@ void AbstractRange::UnmarkDescendants(const nsINode& aNode) { .IsDescendantOfClosestCommonInclusiveAncestorForRangeInSelection()) { // we know |aNode| doesn't have any bit set nsINode* node = aNode.GetNextNode(&aNode); - if (!node) { - if (const ShadowRoot* shadowRoot = aNode.GetShadowRootForSelection()) { - UpdateDescendantsInFlattenedTree(*aNode.AsContent(), false); - } - return; - } while (node) { node->ClearDescendantOfClosestCommonInclusiveAncestorForRangeInSelection(); if (!node->IsClosestCommonInclusiveAncestorForRangeInSelection()) { - if (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) { - UpdateDescendantsInFlattenedTree(*node->AsContent(), false); - // sub-tree has been marked already - node = node->GetNextNonChildNode(&aNode); - } else { - node = node->GetNextNode(&aNode); - } + node = node->GetNextNode(&aNode); } else { // We found an ancestor of an overlapping range, skip its descendants. node = node->GetNextNonChildNode(&aNode); @@ -233,54 +185,10 @@ bool AbstractRange::MaybeCacheToReuse(RangeType& aInstance) { return true; } -nsINode* AbstractRange::GetClosestCommonInclusiveAncestor( - AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) const { - if (!mIsPositioned) { - return nullptr; - } - nsINode* startContainer = - aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes - ? GetMayCrossShadowBoundaryStartContainer() - : GetStartContainer(); - nsINode* endContainer = - aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes - ? GetMayCrossShadowBoundaryEndContainer() - : GetEndContainer(); - - if (MayCrossShadowBoundary() && - aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) { - // Since both the start container and the end container are - // guaranteed to be in the same composed document. - // If one of the boundary is a document, use that document - // as the common ancestor since both nodes. - const bool oneBoundaryIsDocument = - (startContainer && startContainer->IsDocument()) || - (endContainer && endContainer->IsDocument()); - if (oneBoundaryIsDocument) { - MOZ_ASSERT_IF( - startContainer && startContainer->IsDocument(), - !endContainer || endContainer->GetComposedDoc() == startContainer); - MOZ_ASSERT_IF( - endContainer && endContainer->IsDocument(), - !startContainer || startContainer->GetComposedDoc() == endContainer); - - return startContainer ? startContainer->GetComposedDoc() - : endContainer->GetComposedDoc(); - } - // RangeBoundary allows the container to be shadow roots; When - // this happens, we should use the shadow host here. - if (startContainer->IsShadowRoot()) { - startContainer = startContainer->GetContainingShadowHost(); - } - if (endContainer->IsShadowRoot()) { - endContainer = endContainer->GetContainingShadowHost(); - } - return nsContentUtils::GetCommonFlattenedTreeAncestor( - startContainer ? startContainer->AsContent() : nullptr, - endContainer ? endContainer->AsContent() : nullptr); - } - return nsContentUtils::GetClosestCommonInclusiveAncestor(startContainer, - endContainer); +nsINode* AbstractRange::GetClosestCommonInclusiveAncestor() const { + return mIsPositioned ? nsContentUtils::GetClosestCommonInclusiveAncestor( + mStart.Container(), mEnd.Container()) + : nullptr; } // static @@ -329,21 +237,9 @@ nsresult AbstractRange::SetStartAndEndInternal( return NS_ERROR_DOM_INDEX_SIZE_ERR; } - // Different root + // If they have different root, this should be collapsed at the end point. if (newStartRoot != newEndRoot) { - if (aRange->IsStaticRange()) { - // StaticRange allows nodes in different trees, so set start and end - // accordingly - aRange->DoSetRange(aStartBoundary, aEndBoundary, newEndRoot); - } else { - MOZ_ASSERT(aRange->IsDynamicRange()); - // In contrast, nsRange keeps both. It has a pair of start and end - // which they have been collapsed to one end, and it also may have a pair - // of start and end which are the original value. - aRange->DoSetRange(aEndBoundary, aEndBoundary, newEndRoot); - aRange->AsDynamicRange()->CreateOrUpdateCrossShadowBoundaryRangeIfNeeded( - aStartBoundary, aEndBoundary); - } + aRange->DoSetRange(aEndBoundary, aEndBoundary, newEndRoot); return NS_OK; } @@ -378,10 +274,7 @@ void AbstractRange::RegisterSelection(Selection& aSelection) { bool isFirstSelection = mSelections.IsEmpty(); mSelections.AppendElement(&aSelection); if (isFirstSelection && !mRegisteredClosestCommonInclusiveAncestor) { - nsINode* commonAncestor = GetClosestCommonInclusiveAncestor( - StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() - ? AllowRangeCrossShadowBoundary::Yes - : AllowRangeCrossShadowBoundary::No); + nsINode* commonAncestor = GetClosestCommonInclusiveAncestor(); MOZ_ASSERT(commonAncestor, "unexpected disconnected nodes"); RegisterClosestCommonInclusiveAncestor(commonAncestor); } @@ -465,8 +358,7 @@ void AbstractRange::UnregisterClosestCommonInclusiveAncestor( void AbstractRange::UpdateCommonAncestorIfNecessary() { nsINode* oldCommonAncestor = mRegisteredClosestCommonInclusiveAncestor; - nsINode* newCommonAncestor = - GetClosestCommonInclusiveAncestor(AllowRangeCrossShadowBoundary::Yes); + nsINode* newCommonAncestor = GetClosestCommonInclusiveAncestor(); if (newCommonAncestor != oldCommonAncestor) { if (oldCommonAncestor) { UnregisterClosestCommonInclusiveAncestor(oldCommonAncestor, false); @@ -487,59 +379,6 @@ void AbstractRange::UpdateCommonAncestorIfNecessary() { } } -const RangeBoundary& AbstractRange::MayCrossShadowBoundaryStartRef() const { - return IsDynamicRange() ? AsDynamicRange()->MayCrossShadowBoundaryStartRef() - : mStart; -} - -const RangeBoundary& AbstractRange::MayCrossShadowBoundaryEndRef() const { - return IsDynamicRange() ? AsDynamicRange()->MayCrossShadowBoundaryEndRef() - : mEnd; -} - -nsIContent* AbstractRange::GetMayCrossShadowBoundaryChildAtStartOffset() const { - return IsDynamicRange() - ? AsDynamicRange()->GetMayCrossShadowBoundaryChildAtStartOffset() - : mStart.GetChildAtOffset(); -} - -nsIContent* AbstractRange::GetMayCrossShadowBoundaryChildAtEndOffset() const { - return IsDynamicRange() - ? AsDynamicRange()->GetMayCrossShadowBoundaryChildAtEndOffset() - : mEnd.GetChildAtOffset(); -} - -nsINode* AbstractRange::GetMayCrossShadowBoundaryStartContainer() const { - return IsDynamicRange() - ? AsDynamicRange()->GetMayCrossShadowBoundaryStartContainer() - : mStart.Container(); -} - -nsINode* AbstractRange::GetMayCrossShadowBoundaryEndContainer() const { - return IsDynamicRange() - ? AsDynamicRange()->GetMayCrossShadowBoundaryEndContainer() - : mEnd.Container(); -} - -bool AbstractRange::MayCrossShadowBoundary() const { - return IsDynamicRange() ? !!AsDynamicRange()->GetCrossShadowBoundaryRange() - : false; -} - -uint32_t AbstractRange::MayCrossShadowBoundaryStartOffset() const { - return IsDynamicRange() - ? AsDynamicRange()->MayCrossShadowBoundaryStartOffset() - : static_cast(*mStart.Offset( - RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)); -} - -uint32_t AbstractRange::MayCrossShadowBoundaryEndOffset() const { - return IsDynamicRange() - ? AsDynamicRange()->MayCrossShadowBoundaryEndOffset() - : static_cast(*mEnd.Offset( - RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)); -} - nsINode* AbstractRange::GetParentObject() const { return mOwner; } JSObject* AbstractRange::WrapObject(JSContext* aCx, diff --git a/dom/base/AbstractRange.h b/dom/base/AbstractRange.h index 8cedb5c0fa9d..c70aaf19ec8d 100644 --- a/dom/base/AbstractRange.h +++ b/dom/base/AbstractRange.h @@ -31,15 +31,10 @@ class Document; class Selection; class StaticRange; -enum class AllowRangeCrossShadowBoundary : bool { No, Yes }; - class AbstractRange : public nsISupports, public nsWrapperCache, // For linking together selection-associated ranges. public mozilla::LinkedListElement { - using AllowRangeCrossShadowBoundary = - mozilla::dom::AllowRangeCrossShadowBoundary; - protected: explicit AbstractRange(nsINode* aNode, bool aIsDynamicRange); virtual ~AbstractRange(); @@ -56,33 +51,18 @@ class AbstractRange : public nsISupports, NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(AbstractRange) - /** - * All of the MayCrossShadowBoundary* methods are used to get the boundary - * endpoints that cross shadow boundaries. They would return - * the same value as the non-MayCrossShadowBoundary* methods if the range - * boundaries don't cross shadow boundaries. - */ const RangeBoundary& StartRef() const { return mStart; } - const RangeBoundary& MayCrossShadowBoundaryStartRef() const; - const RangeBoundary& EndRef() const { return mEnd; } - const RangeBoundary& MayCrossShadowBoundaryEndRef() const; nsIContent* GetChildAtStartOffset() const { return mStart.GetChildAtOffset(); } - nsIContent* GetMayCrossShadowBoundaryChildAtStartOffset() const; - nsIContent* GetChildAtEndOffset() const { return mEnd.GetChildAtOffset(); } - nsIContent* GetMayCrossShadowBoundaryChildAtEndOffset() const; - bool IsPositioned() const { return mIsPositioned; } /** * https://dom.spec.whatwg.org/#concept-tree-inclusive-ancestor */ - nsINode* GetClosestCommonInclusiveAncestor( - AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary = - AllowRangeCrossShadowBoundary::No) const; + nsINode* GetClosestCommonInclusiveAncestor() const; // WebIDL @@ -95,12 +75,7 @@ class AbstractRange : public nsISupports, // `IsPositioned()` directly. nsINode* GetStartContainer() const { return mStart.Container(); } - nsINode* GetMayCrossShadowBoundaryStartContainer() const; - nsINode* GetEndContainer() const { return mEnd.Container(); } - nsINode* GetMayCrossShadowBoundaryEndContainer() const; - - bool MayCrossShadowBoundary() const; Document* GetComposedDocOfContainers() const { return mStart.Container() ? mStart.Container()->GetComposedDoc() : nullptr; @@ -111,15 +86,12 @@ class AbstractRange : public nsISupports, return static_cast( *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)); } - uint32_t MayCrossShadowBoundaryStartOffset() const; // FYI: Returns 0 if it's not positioned. uint32_t EndOffset() const { return static_cast( *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)); } - uint32_t MayCrossShadowBoundaryEndOffset() const; - bool Collapsed() const { return !mIsPositioned || (mStart.Container() == mEnd.Container() && StartOffset() == EndOffset()); diff --git a/dom/base/ContentIterator.cpp b/dom/base/ContentIterator.cpp index 6381885fc11a..681935352031 100644 --- a/dom/base/ContentIterator.cpp +++ b/dom/base/ContentIterator.cpp @@ -7,7 +7,6 @@ #include "ContentIterator.h" #include "mozilla/Assertions.h" -#include "mozilla/dom/ShadowRoot.h" #include "mozilla/DebugOnly.h" #include "mozilla/RangeBoundary.h" #include "mozilla/RangeUtils.h" @@ -27,69 +26,6 @@ using namespace dom; __VA_ARGS__); \ template aResultType ContentIteratorBase::aMethodName(__VA_ARGS__) -/** - * IteratorHelpers contains the static methods to help extra values - * based on whether or not the iterator allows to iterate nodes cross the shadow - * boundary. - */ -struct IteratorHelpers { - IteratorHelpers() = delete; - - static nsINode* GetStartContainer(AbstractRange* aRange, - bool aAllowCrossShadowBoundary) { - MOZ_ASSERT(aRange); - return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aAllowCrossShadowBoundary) - ? aRange->GetMayCrossShadowBoundaryStartContainer() - : aRange->GetStartContainer(); - } - - static int32_t StartOffset(AbstractRange* aRange, - bool aAllowCrossShadowBoundary) { - MOZ_ASSERT(aRange); - return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aAllowCrossShadowBoundary) - ? aRange->MayCrossShadowBoundaryStartOffset() - : aRange->StartOffset(); - } - - static nsINode* GetEndContainer(AbstractRange* aRange, - bool aAllowCrossShadowBoundary) { - MOZ_ASSERT(aRange); - return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aAllowCrossShadowBoundary) - ? aRange->GetMayCrossShadowBoundaryEndContainer() - : aRange->GetEndContainer(); - } - - static int32_t EndOffset(AbstractRange* aRange, - bool aAllowCrossShadowBoundary) { - MOZ_ASSERT(aRange); - return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aAllowCrossShadowBoundary) - ? aRange->MayCrossShadowBoundaryEndOffset() - : aRange->EndOffset(); - } - - // FIXME(sefeng): This doesn't work with slots / flattened tree. - static nsINode* GetParentNode(nsINode& aNode, - bool aAllowCrossShadowBoundary) { - return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aAllowCrossShadowBoundary) - ? aNode.GetParentOrShadowHostNode() - : aNode.GetParentNode(); - } - - static ShadowRoot* GetShadowRoot(const nsINode* aNode, - bool aAllowCrossShadowBoundary) { - MOZ_ASSERT(aNode); - return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aAllowCrossShadowBoundary) - ? aNode->GetShadowRootForSelection() - : nullptr; - } -}; - static bool ComparePostMode(const RawRangeBoundary& aStart, const RawRangeBoundary& aEnd, nsINode& aNode) { nsINode* parent = aNode.GetParentNode(); @@ -605,7 +541,7 @@ nsINode* ContentIteratorBase::GetDeepFirstChild(nsINode* aRoot) { // static template nsIContent* ContentIteratorBase::GetDeepFirstChild( - nsIContent* aRoot, bool aAllowCrossShadowBoundary) { + nsIContent* aRoot) { if (NS_WARN_IF(!aRoot)) { return nullptr; } @@ -613,25 +549,9 @@ nsIContent* ContentIteratorBase::GetDeepFirstChild( nsIContent* node = aRoot; nsIContent* child = node->GetFirstChild(); - if (!child) { - if (ShadowRoot* shadowRoot = - IteratorHelpers::GetShadowRoot(node, aAllowCrossShadowBoundary)) { - // If this node doesn't have a child, but it's also a shadow host - // that can be selected, we go into this shadow tree. - child = shadowRoot->GetFirstChild(); - } - } - - // FIXME(sefeng): This is problematic for slotted contents while (child) { node = child; child = node->GetFirstChild(); - if (!child) { - if (ShadowRoot* shadowRoot = - IteratorHelpers::GetShadowRoot(node, aAllowCrossShadowBoundary)) { - child = shadowRoot->GetFirstChild(); - } - } } return node; @@ -649,41 +569,23 @@ nsINode* ContentIteratorBase::GetDeepLastChild(nsINode* aRoot) { // static template -nsIContent* ContentIteratorBase::GetDeepLastChild( - nsIContent* aRoot, bool aAllowCrossShadowBoundary) { +nsIContent* ContentIteratorBase::GetDeepLastChild(nsIContent* aRoot) { if (NS_WARN_IF(!aRoot)) { return nullptr; } nsIContent* node = aRoot; - - ShadowRoot* shadowRoot = - IteratorHelpers::GetShadowRoot(node, aAllowCrossShadowBoundary); - // FIXME(sefeng): This doesn't work with slots / flattened tree. - while (node->HasChildren() || (shadowRoot && shadowRoot->HasChildren())) { - if (node->HasChildren()) { - node = node->GetLastChild(); - } else { - MOZ_ASSERT(shadowRoot); - // If this node doesn't have a child, but it's also a shadow host - // that can be selected, we go into this shadow tree. - node = shadowRoot->GetLastChild(); - } - shadowRoot = - IteratorHelpers::GetShadowRoot(node, aAllowCrossShadowBoundary); + while (node->HasChildren()) { + nsIContent* child = node->GetLastChild(); + node = child; } return node; } -// Get the next sibling, or parent's next sibling, or shadow host's next -// sibling (when aAllowCrossShadowBoundary is true), or grandpa's next -// sibling... -// +// Get the next sibling, or parent's next sibling, or grandpa's next sibling... // static -// template -nsIContent* ContentIteratorBase::GetNextSibling( - nsINode* aNode, bool aAllowCrossShadowBoundary) { +nsIContent* ContentIteratorBase::GetNextSibling(nsINode* aNode) { if (NS_WARN_IF(!aNode)) { return nullptr; } @@ -692,32 +594,18 @@ nsIContent* ContentIteratorBase::GetNextSibling( return next; } - nsINode* parent = - IteratorHelpers::GetParentNode(*aNode, aAllowCrossShadowBoundary); + nsINode* parent = aNode->GetParentNode(); if (NS_WARN_IF(!parent)) { return nullptr; } - if (aAllowCrossShadowBoundary) { - // This is temporary solution. - // For shadow root, instead of getting to the sibling of the parent - // directly, we need to get into the light tree of the parent to handle - // slotted contents. - if (ShadowRoot* shadowRoot = ShadowRoot::FromNode(aNode)) { - if (nsIContent* child = parent->GetFirstChild()) { - return child; - } - } - } - - return ContentIteratorBase::GetNextSibling(parent, aAllowCrossShadowBoundary); + return ContentIteratorBase::GetNextSibling(parent); } -// Get the prev sibling, or parent's prev sibling, or shadow host's prev sibling -// (when aAllowCrossShadowBoundary is true), or grandpa's prev sibling... static +// Get the prev sibling, or parent's prev sibling, or grandpa's prev sibling... +// static template -nsIContent* ContentIteratorBase::GetPrevSibling( - nsINode* aNode, bool aAllowCrossShadowBoundary) { +nsIContent* ContentIteratorBase::GetPrevSibling(nsINode* aNode) { if (NS_WARN_IF(!aNode)) { return nullptr; } @@ -726,13 +614,12 @@ nsIContent* ContentIteratorBase::GetPrevSibling( return prev; } - nsINode* parent = - IteratorHelpers::GetParentNode(*aNode, aAllowCrossShadowBoundary); + nsINode* parent = aNode->GetParentNode(); if (NS_WARN_IF(!parent)) { return nullptr; } - return ContentIteratorBase::GetPrevSibling(parent, aAllowCrossShadowBoundary); + return ContentIteratorBase::GetPrevSibling(parent); } template @@ -973,41 +860,19 @@ nsresult ContentSubtreeIterator::Init(const RawRangeBoundary& aStartBoundary, return InitWithRange(); } -nsresult ContentSubtreeIterator::InitWithAllowCrossShadowBoundary( - AbstractRange* aRange) { - MOZ_ASSERT(aRange); - - if (NS_WARN_IF(!aRange->IsPositioned())) { - return NS_ERROR_INVALID_ARG; - } - - mRange = aRange; - - mAllowCrossShadowBoundary = AllowRangeCrossShadowBoundary::Yes; - return InitWithRange(); -} - void ContentSubtreeIterator::CacheInclusiveAncestorsOfEndContainer() { mInclusiveAncestorsOfEndContainer.Clear(); - nsINode* const endContainer = - IteratorHelpers::GetEndContainer(mRange, IterAllowCrossShadowBoundary()); + nsINode* const endContainer = mRange->GetEndContainer(); nsIContent* endNode = endContainer->IsContent() ? endContainer->AsContent() : nullptr; while (endNode) { mInclusiveAncestorsOfEndContainer.AppendElement(endNode); - // Cross the boundary for contents in shadow tree. - nsINode* parent = IteratorHelpers::GetParentNode( - *endNode, IterAllowCrossShadowBoundary()); - if (!parent || !parent->IsContent()) { - break; - } - endNode = parent->AsContent(); + endNode = endNode->GetParent(); } } nsIContent* ContentSubtreeIterator::DetermineCandidateForFirstContent() const { - nsINode* startContainer = IteratorHelpers::GetStartContainer( - mRange, IterAllowCrossShadowBoundary()); + nsINode* startContainer = mRange->GetStartContainer(); nsIContent* firstCandidate = nullptr; // find first node in range nsINode* node = nullptr; @@ -1015,14 +880,9 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForFirstContent() const { // no children, start at the node itself node = startContainer; } else { - nsIContent* child = - IterAllowCrossShadowBoundary() - ? mRange->GetMayCrossShadowBoundaryChildAtStartOffset() - : mRange->GetChildAtStartOffset(); - - MOZ_ASSERT(child == startContainer->GetChildAt_Deprecated( - IteratorHelpers::StartOffset( - mRange, IterAllowCrossShadowBoundary()))); + nsIContent* child = mRange->GetChildAtStartOffset(); + MOZ_ASSERT(child == + startContainer->GetChildAt_Deprecated(mRange->StartOffset())); if (!child) { // offset after last child node = startContainer; @@ -1033,13 +893,11 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForFirstContent() const { if (!firstCandidate) { // then firstCandidate is next node after node - firstCandidate = ContentIteratorBase::GetNextSibling( - node, IterAllowCrossShadowBoundary()); + firstCandidate = ContentIteratorBase::GetNextSibling(node); } if (firstCandidate) { - firstCandidate = ContentIteratorBase::GetDeepFirstChild( - firstCandidate, IterAllowCrossShadowBoundary()); + firstCandidate = ContentIteratorBase::GetDeepFirstChild(firstCandidate); } return firstCandidate; @@ -1068,12 +926,9 @@ nsIContent* ContentSubtreeIterator::DetermineFirstContent() const { nsIContent* ContentSubtreeIterator::DetermineCandidateForLastContent() const { nsIContent* lastCandidate{nullptr}; - nsINode* endContainer = - IteratorHelpers::GetEndContainer(mRange, IterAllowCrossShadowBoundary()); + nsINode* endContainer = mRange->GetEndContainer(); // now to find the last node - int32_t offset = - IteratorHelpers::EndOffset(mRange, IterAllowCrossShadowBoundary()); - + int32_t offset = mRange->EndOffset(); int32_t numChildren = endContainer->GetChildCount(); nsINode* node = nullptr; @@ -1084,9 +939,7 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForLastContent() const { if (!offset || !numChildren) { node = endContainer; } else { - lastCandidate = IterAllowCrossShadowBoundary() - ? mRange->MayCrossShadowBoundaryEndRef().Ref() - : mRange->EndRef().Ref(); + lastCandidate = mRange->EndRef().Ref(); MOZ_ASSERT(lastCandidate == endContainer->GetChildAt_Deprecated(--offset)); NS_ASSERTION(lastCandidate, "tree traversal trouble in ContentSubtreeIterator::Init"); @@ -1094,13 +947,11 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForLastContent() const { if (!lastCandidate) { // then lastCandidate is prev node before node - lastCandidate = ContentIteratorBase::GetPrevSibling( - node, IterAllowCrossShadowBoundary()); + lastCandidate = ContentIteratorBase::GetPrevSibling(node); } if (lastCandidate) { - lastCandidate = ContentIteratorBase::GetDeepLastChild( - lastCandidate, IterAllowCrossShadowBoundary()); + lastCandidate = ContentIteratorBase::GetDeepLastChild(lastCandidate); } return lastCandidate; @@ -1111,17 +962,11 @@ nsresult ContentSubtreeIterator::InitWithRange() { MOZ_ASSERT(mRange->IsPositioned()); // get the start node and offset, convert to nsINode - mClosestCommonInclusiveAncestor = - mRange->GetClosestCommonInclusiveAncestor(mAllowCrossShadowBoundary); - - nsINode* startContainer = IteratorHelpers::GetStartContainer( - mRange, IterAllowCrossShadowBoundary()); - const int32_t startOffset = - IteratorHelpers::StartOffset(mRange, IterAllowCrossShadowBoundary()); - nsINode* endContainer = - IteratorHelpers::GetEndContainer(mRange, IterAllowCrossShadowBoundary()); - const int32_t endOffset = - IteratorHelpers::EndOffset(mRange, IterAllowCrossShadowBoundary()); + mClosestCommonInclusiveAncestor = mRange->GetClosestCommonInclusiveAncestor(); + nsINode* startContainer = mRange->GetStartContainer(); + const int32_t startOffset = mRange->StartOffset(); + nsINode* endContainer = mRange->GetEndContainer(); + const int32_t endOffset = mRange->EndOffset(); MOZ_ASSERT(mClosestCommonInclusiveAncestor && startContainer && endContainer); // Bug 767169 MOZ_ASSERT(uint32_t(startOffset) <= startContainer->Length() && @@ -1199,24 +1044,15 @@ void ContentSubtreeIterator::Next() { return; } - nsINode* nextNode = ContentIteratorBase::GetNextSibling( - mCurNode, IterAllowCrossShadowBoundary()); - - MOZ_ASSERT(nextNode, "No next sibling!?! This could mean deadlock!"); + nsINode* nextNode = ContentIteratorBase::GetNextSibling(mCurNode); + NS_ASSERTION(nextNode, "No next sibling!?! This could mean deadlock!"); int32_t i = mInclusiveAncestorsOfEndContainer.IndexOf(nextNode); while (i != -1) { // as long as we are finding ancestors of the endpoint of the range, // dive down into their children - ShadowRoot* root = IteratorHelpers::GetShadowRoot( - Element::FromNode(nextNode), IterAllowCrossShadowBoundary()); - if (!root) { - nextNode = nextNode->GetFirstChild(); - } else { - nextNode = mRange->MayCrossShadowBoundary() ? root->GetFirstChild() - : nextNode->GetFirstChild(); - } - MOZ_ASSERT(nextNode, "Iterator error, expected a child node!"); + nextNode = nextNode->GetFirstChild(); + NS_ASSERTION(nextNode, "Iterator error, expected a child node!"); // should be impossible to get a null pointer. If we went all the way // down the child chain to the bottom without finding an interior node, @@ -1262,8 +1098,7 @@ nsresult ContentSubtreeIterator::PositionAt(nsINode* aCurNode) { nsIContent* ContentSubtreeIterator::GetTopAncestorInRange( nsINode* aNode) const { - if (!aNode || - !IteratorHelpers::GetParentNode(*aNode, IterAllowCrossShadowBoundary())) { + if (!aNode || !aNode->GetParentNode()) { return nullptr; } @@ -1279,23 +1114,15 @@ nsIContent* ContentSubtreeIterator::GetTopAncestorInRange( return nullptr; } - nsIContent* lastContentInShadowTree = nullptr; while (content) { - nsINode* parent = IteratorHelpers::GetParentNode( - *content, IterAllowCrossShadowBoundary()); - + nsIContent* parent = content->GetParent(); // content always has a parent. If its parent is the root, however -- // i.e., either it's not content, or it is content but its own parent is // null -- then we're finished, since we don't go up to the root. // - // Caveat: If iteration crossing shadow boundary is allowed - // and the root is a shadow root, we keep going up to the - // shadow host and continue. - // // We have to special-case this because CompareNodeToRange treats the root // node differently -- see bug 765205. - if (!parent || !IteratorHelpers::GetParentNode( - *parent, IterAllowCrossShadowBoundary())) { + if (!parent || !parent->GetParentNode()) { return content; } @@ -1303,28 +1130,10 @@ nsIContent* ContentSubtreeIterator::GetTopAncestorInRange( RangeUtils::IsNodeContainedInRange(*parent, mRange); MOZ_ALWAYS_TRUE(isNodeContainedInRange); if (!isNodeContainedInRange.value()) { - if (IterAllowCrossShadowBoundary() && content->IsShadowRoot()) { - MOZ_ASSERT(parent->GetShadowRoot() == content); - // host element is not in range, the last content in tree - // should be the ancestor. - MOZ_ASSERT(lastContentInShadowTree); - return lastContentInShadowTree; - } return content; } - // When we cross the boundary, we keep a reference to the - // last content that is in tree, because if we later - // find the shadow host element is not in the range, that means - // the last content in the tree should be top ancestor in range. - // - // Using shadow root doesn't make sense here because it doesn't - // represent a actual content. - if (IterAllowCrossShadowBoundary() && parent->IsShadowRoot()) { - lastContentInShadowTree = content; - } - - content = parent->AsContent(); + content = parent; } MOZ_CRASH("This should only be possible if aNode was null"); diff --git a/dom/base/ContentIterator.h b/dom/base/ContentIterator.h index 67962d41d540..b645c4147ed5 100644 --- a/dom/base/ContentIterator.h +++ b/dom/base/ContentIterator.h @@ -82,26 +82,15 @@ class ContentIteratorBase { // Recursively get the deepest first/last child of aRoot. This will return // aRoot itself if it has no children. static nsINode* GetDeepFirstChild(nsINode* aRoot); - // If aAllowCrossShadowBoundary is true, it'll continue with the shadow tree - // when it reaches to a shadow host. - static nsIContent* GetDeepFirstChild(nsIContent* aRoot, - bool aAllowCrossShadowBoundary); + static nsIContent* GetDeepFirstChild(nsIContent* aRoot); static nsINode* GetDeepLastChild(nsINode* aRoot); - // If aAllowCrossShadowBoundary is true, it'll continue with the shadow tree - // when it reaches to a shadow host. - static nsIContent* GetDeepLastChild(nsIContent* aRoot, - bool aAllowCrossShadowBoundary); + static nsIContent* GetDeepLastChild(nsIContent* aRoot); // Get the next/previous sibling of aNode, or its parent's, or grandparent's, // etc. Returns null if aNode and all its ancestors have no next/previous // sibling. - // - // If aAllowCrossShadowBoundary is true, it'll continue with the shadow host - // when it reaches to a shadow root. - static nsIContent* GetNextSibling(nsINode* aNode, - bool aAllowCrossShadowBoundary = false); - static nsIContent* GetPrevSibling(nsINode* aNode, - bool aAllowCrossShadowBoundary = false); + static nsIContent* GetNextSibling(nsINode* aNode); + static nsIContent* GetPrevSibling(nsINode* aNode); nsINode* NextNode(nsINode* aNode); nsINode* PrevNode(nsINode* aNode); @@ -230,29 +219,6 @@ class ContentSubtreeIterator final : public SafeContentIteratorBase { virtual nsresult Init(nsINode* aRoot) override; virtual nsresult Init(dom::AbstractRange* aRange) override; - - /** - * Initialize the iterator with aRange that does correct things - * when the aRange's start and/or the end containers are - * in shadow dom. - * - * If both start and end containers are in light dom, the iterator - * won't do anything special. - * - * When the start container is in shadow dom, the iterator can - * find the correct start node by crossing the shadow - * boundary when needed. - * - * When the end container is in shadow dom, the iterator can find - * the correct end node by crossing the shadow boundary when - * needed. Also when the next node is an ancestor of - * the end node, it can correctly iterate into the - * subtree of it by crossing the shadow boundary. - * - * Examples of what nodes will be returned can be found - * at test_content_iterator_subtree_shadow_tree.html. - */ - nsresult InitWithAllowCrossShadowBoundary(dom::AbstractRange* aRange); virtual nsresult Init(nsINode* aStartContainer, uint32_t aStartOffset, nsINode* aEndContainer, uint32_t aEndOffset) override; virtual nsresult Init(const RawRangeBoundary& aStartBoundary, @@ -310,18 +276,10 @@ class ContentSubtreeIterator final : public SafeContentIteratorBase { // the range's start and end nodes will never be considered "in" it. nsIContent* GetTopAncestorInRange(nsINode* aNode) const; - bool IterAllowCrossShadowBoundary() const { - return mAllowCrossShadowBoundary == dom::AllowRangeCrossShadowBoundary::Yes; - } - RefPtr mRange; // See . AutoTArray mInclusiveAncestorsOfEndContainer; - - // Whether this iterator allows to iterate nodes across shadow boundary. - dom::AllowRangeCrossShadowBoundary mAllowCrossShadowBoundary = - dom::AllowRangeCrossShadowBoundary::No; }; } // namespace mozilla diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 1324d9f64b89..87829b2e6a7e 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1347,22 +1347,6 @@ already_AddRefed Element::AttachShadowWithoutNameChecks( dispatcher->PostDOMEvent(); } - const LinkedList* ranges = - GetExistingClosestCommonInclusiveAncestorRanges(); - if (ranges) { - for (const AbstractRange* range : *ranges) { - if (range->MayCrossShadowBoundary()) { - MOZ_ASSERT(range->IsDynamicRange()); - StaticRange* crossBoundaryRange = - range->AsDynamicRange()->GetCrossShadowBoundaryRange(); - MOZ_ASSERT(crossBoundaryRange); - // We may have previously selected this node before it - // becomes a shadow host, so we need to reset the values - // in RangeBoundaries to accommodate the change. - crossBoundaryRange->NotifyNodeBecomesShadowHost(this); - } - } - } /** * 10. Return shadow. */ diff --git a/dom/base/RangeBoundary.h b/dom/base/RangeBoundary.h index 4c5a70fb6a11..2e4ab4239731 100644 --- a/dom/base/RangeBoundary.h +++ b/dom/base/RangeBoundary.h @@ -9,7 +9,6 @@ #include "nsCOMPtr.h" #include "nsIContent.h" -#include "mozilla/dom/ShadowRoot.h" #include "mozilla/Assertions.h" #include "mozilla/Maybe.h" @@ -352,34 +351,6 @@ class RangeBoundaryBase { } public: - void NotifyParentBecomesShadowHost() { - MOZ_ASSERT(mParent); - MOZ_ASSERT(mParent->IsContainerNode(), - "Range is positioned on a text node!"); - if (!StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) { - return; - } - - if (!mIsMutationObserved) { - // RangeBoundaries that are not used in the context of a - // `MutationObserver` use the offset as main source of truth to compute - // `mRef`. Therefore, it must not be updated or invalidated. - return; - } - - if (!mRef) { - MOZ_ASSERT(mOffset.isSome() && mOffset.value() == 0, - "Invalidating offset of invalid RangeBoundary?"); - return; - } - - if (dom::ShadowRoot* shadowRoot = mParent->GetShadowRootForSelection()) { - mParent = shadowRoot; - } - - mOffset = Some(0); - } - bool IsSet() const { return mParent && (mRef || mOffset.isSome()); } bool IsSetAndValid() const { diff --git a/dom/base/RangeUtils.cpp b/dom/base/RangeUtils.cpp index 2383cc18aa12..28283054b88e 100644 --- a/dom/base/RangeUtils.cpp +++ b/dom/base/RangeUtils.cpp @@ -147,10 +147,9 @@ nsresult RangeUtils::CompareNodeToRange(nsINode* aNode, NS_WARN_IF(!aAbstractRange->IsPositioned())) { return NS_ERROR_INVALID_ARG; } - return CompareNodeToRangeBoundaries( - aNode, aAbstractRange->MayCrossShadowBoundaryStartRef(), - aAbstractRange->MayCrossShadowBoundaryEndRef(), aNodeIsBeforeRange, - aNodeIsAfterRange); + return CompareNodeToRangeBoundaries(aNode, aAbstractRange->StartRef(), + aAbstractRange->EndRef(), + aNodeIsBeforeRange, aNodeIsAfterRange); } template nsresult RangeUtils::CompareNodeToRangeBoundaries( diff --git a/dom/base/ScriptableContentIterator.cpp b/dom/base/ScriptableContentIterator.cpp index ab04053c292b..d10c4e68f81f 100644 --- a/dom/base/ScriptableContentIterator.cpp +++ b/dom/base/ScriptableContentIterator.cpp @@ -108,22 +108,6 @@ ScriptableContentIterator::InitWithRange(IteratorType aType, nsRange* aRange) { return mContentIterator->Init(aRange); } -NS_IMETHODIMP -ScriptableContentIterator::InitWithRangeAllowCrossShadowBoundary( - IteratorType aType, nsRange* aRange) { - if (aType == NOT_INITIALIZED || - (mIteratorType != NOT_INITIALIZED && aType != mIteratorType) || - aType != SUBTREE_ITERATOR) { - return NS_ERROR_INVALID_ARG; - } - - mIteratorType = aType; - MOZ_ASSERT(mIteratorType == SUBTREE_ITERATOR); - EnsureContentIterator(); - return static_cast(mContentIterator.get()) - ->InitWithAllowCrossShadowBoundary(aRange); -} - NS_IMETHODIMP ScriptableContentIterator::InitWithPositions(IteratorType aType, nsINode* aStartContainer, diff --git a/dom/base/Selection.cpp b/dom/base/Selection.cpp index 7983ef98f90b..1f38f8e09904 100644 --- a/dom/base/Selection.cpp +++ b/dom/base/Selection.cpp @@ -22,11 +22,9 @@ #include "mozilla/CaretAssociationHint.h" #include "mozilla/ContentIterator.h" #include "mozilla/dom/Element.h" -#include "mozilla/dom/ChildIterator.h" #include "mozilla/dom/SelectionBinding.h" #include "mozilla/dom/ShadowRoot.h" #include "mozilla/dom/StaticRange.h" -#include "mozilla/dom/ShadowIncludingTreeIterator.h" #include "mozilla/ErrorResult.h" #include "mozilla/HTMLEditor.h" #include "mozilla/IntegerRange.h" @@ -780,39 +778,30 @@ NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(Selection) NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(Selection, Disconnect()) -const RangeBoundary& Selection::AnchorRef( - AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) const { +const RangeBoundary& Selection::AnchorRef() const { if (!mAnchorFocusRange) { static RangeBoundary sEmpty; return sEmpty; } if (GetDirection() == eDirNext) { - return aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes - ? mAnchorFocusRange->MayCrossShadowBoundaryStartRef() - : mAnchorFocusRange->StartRef(); + return mAnchorFocusRange->StartRef(); } - return aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes - ? mAnchorFocusRange->MayCrossShadowBoundaryEndRef() - : mAnchorFocusRange->EndRef(); + return mAnchorFocusRange->EndRef(); } -const RangeBoundary& Selection::FocusRef( - AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) const { +const RangeBoundary& Selection::FocusRef() const { if (!mAnchorFocusRange) { static RangeBoundary sEmpty; return sEmpty; } if (GetDirection() == eDirNext) { - return aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes - ? mAnchorFocusRange->MayCrossShadowBoundaryEndRef() - : mAnchorFocusRange->EndRef(); + return mAnchorFocusRange->EndRef(); } - return aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes - ? mAnchorFocusRange->MayCrossShadowBoundaryStartRef() - : mAnchorFocusRange->StartRef(); + + return mAnchorFocusRange->StartRef(); } void Selection::SetAnchorFocusRange(size_t aIndex) { @@ -829,8 +818,8 @@ static int32_t CompareToRangeStart(const nsINode& aCompareNode, uint32_t aCompareOffset, const AbstractRange& aRange, nsContentUtils::NodeIndexCache* aCache) { - MOZ_ASSERT(aRange.GetMayCrossShadowBoundaryStartContainer()); - nsINode* start = aRange.GetMayCrossShadowBoundaryStartContainer(); + MOZ_ASSERT(aRange.GetStartContainer()); + nsINode* start = aRange.GetStartContainer(); // If the nodes that we're comparing are not in the same document, assume that // aCompareNode will fall at the end of the ranges. if (aCompareNode.GetComposedDoc() != start->GetComposedDoc() || @@ -841,9 +830,8 @@ static int32_t CompareToRangeStart(const nsINode& aCompareNode, } // The points are in the same subtree, hence there has to be an order. - return *nsContentUtils::ComparePoints( - &aCompareNode, aCompareOffset, start, - aRange.MayCrossShadowBoundaryStartOffset(), aCache); + return *nsContentUtils::ComparePoints(&aCompareNode, aCompareOffset, start, + aRange.StartOffset(), aCache); } static int32_t CompareToRangeStart(const nsINode& aCompareNode, @@ -856,7 +844,7 @@ static int32_t CompareToRangeEnd(const nsINode& aCompareNode, uint32_t aCompareOffset, const AbstractRange& aRange) { MOZ_ASSERT(aRange.IsPositioned()); - nsINode* end = aRange.GetMayCrossShadowBoundaryEndContainer(); + nsINode* end = aRange.GetEndContainer(); // If the nodes that we're comparing are not in the same document or in the // same subtree, assume that aCompareNode will fall at the end of the ranges. if (aCompareNode.GetComposedDoc() != end->GetComposedDoc() || @@ -867,9 +855,8 @@ static int32_t CompareToRangeEnd(const nsINode& aCompareNode, } // The points are in the same subtree, hence there has to be an order. - return *nsContentUtils::ComparePoints( - &aCompareNode, aCompareOffset, end, - aRange.MayCrossShadowBoundaryEndOffset()); + return *nsContentUtils::ComparePoints(&aCompareNode, aCompareOffset, end, + aRange.EndOffset()); } // static @@ -1336,18 +1323,7 @@ nsresult Selection::RemoveCollapsedRanges() { nsresult Selection::StyledRanges::RemoveCollapsedRanges() { uint32_t i = 0; while (i < mRanges.Length()) { - const AbstractRange* range = mRanges[i].mRange; - // If nsRange::mCrossShadowBoundaryRange exists, it means - // there's a cross boundary selection, so obviously - // we shouldn't remove this range. - const bool collapsed = - range->Collapsed() && !range->MayCrossShadowBoundary(); - // Cross boundary range should always be uncollapsed. - MOZ_ASSERT_IF( - range->MayCrossShadowBoundary(), - !range->AsDynamicRange()->CrossShadowBoundaryRangeCollapsed()); - - if (collapsed) { + if (mRanges[i].mRange->Collapsed()) { nsresult rv = RemoveRangeAndUnregisterSelection(*mRanges[i].mRange); NS_ENSURE_SUCCESS(rv, rv); } else { @@ -1640,8 +1616,7 @@ nsresult Selection::StyledRanges::GetIndicesForInterval( // the given interval's start point, but that range isn't collapsed (a // collapsed range should be included in the returned results). const AbstractRange* beginRange = mRanges[beginsAfterIndex].mRange; - if (beginRange->MayCrossShadowBoundaryEndRef().Equals(aBeginNode, - aBeginOffset) && + if (beginRange->EndRef().Equals(aBeginNode, aBeginOffset) && !beginRange->Collapsed()) { beginsAfterIndex++; } @@ -1652,8 +1627,7 @@ nsresult Selection::StyledRanges::GetIndicesForInterval( // included if (endsBeforeIndex < mRanges.Length()) { const AbstractRange* endRange = mRanges[endsBeforeIndex].mRange; - if (endRange->MayCrossShadowBoundaryStartRef().Equals(aEndNode, - aEndOffset) && + if (endRange->StartRef().Equals(aEndNode, aEndOffset) && endRange->Collapsed()) { endsBeforeIndex++; } @@ -1736,16 +1710,6 @@ nsresult Selection::SelectFramesOfInclusiveDescendantsOfContent( return NS_OK; } -void Selection::SelectFramesOfShadowIncludingDescendantsOfContent( - nsIContent* aContent, bool aSelected) const { - MOZ_ASSERT(aContent); - MOZ_ASSERT(StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()); - for (nsINode* node : ShadowIncludingTreeIterator(*aContent)) { - nsIContent* innercontent = node->IsContent() ? node->AsContent() : nullptr; - SelectFramesOf(innercontent, aSelected); - } -} - void Selection::SelectFramesInAllRanges(nsPresContext* aPresContext) { // this method is currently only called in a user-initiated context. // therefore it is safe to assume that we are not in a Highlight selection @@ -1784,22 +1748,16 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, if (mFrameSelection->IsInTableSelectionMode()) { const nsIContent* const commonAncestorContent = - nsIContent::FromNodeOrNull(aRange.GetClosestCommonInclusiveAncestor( - StaticPrefs::dom_select_events_textcontrols_selectstart_enabled() - ? AllowRangeCrossShadowBoundary::Yes - : AllowRangeCrossShadowBoundary::No)); + nsIContent::FromNodeOrNull(aRange.GetClosestCommonInclusiveAncestor()); nsIFrame* const frame = commonAncestorContent ? commonAncestorContent->GetPrimaryFrame() : aPresContext->PresShell()->GetRootFrame(); if (frame) { if (frame->IsTextFrame()) { - MOZ_ASSERT(commonAncestorContent == - aRange.GetMayCrossShadowBoundaryStartContainer()); - MOZ_ASSERT(commonAncestorContent == - aRange.GetMayCrossShadowBoundaryEndContainer()); + MOZ_ASSERT(commonAncestorContent == aRange.GetStartContainer()); + MOZ_ASSERT(commonAncestorContent == aRange.GetEndContainer()); static_cast(frame)->SelectionStateChanged( - aRange.MayCrossShadowBoundaryStartOffset(), - aRange.MayCrossShadowBoundaryEndOffset(), aSelect, mSelectionType); + aRange.StartOffset(), aRange.EndOffset(), aSelect, mSelectionType); } else { frame->SelectionStateChanged(); } @@ -1810,8 +1768,8 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, // Loop through the content iterator for each content node; for each text // node, call SetSelected on it: - nsIContent* const startContent = nsIContent::FromNodeOrNull( - aRange.GetMayCrossShadowBoundaryStartContainer()); + nsIContent* const startContent = + nsIContent::FromNodeOrNull(aRange.GetStartContainer()); if (MOZ_UNLIKELY(!startContent)) { // Don't warn, bug 1055722 // XXX The range can start from a document node and such range can be @@ -1822,7 +1780,7 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, MOZ_DIAGNOSTIC_ASSERT(startContent->IsInComposedDoc()); // We must call first one explicitly - nsINode* const endNode = aRange.GetMayCrossShadowBoundaryEndContainer(); + nsINode* const endNode = aRange.GetEndContainer(); if (NS_WARN_IF(!endNode)) { // We null-checked start node above, therefore, end node should also be // non-null here. @@ -1834,10 +1792,10 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, // The frame could be an SVG text frame, in which case we don't treat it // as a text frame. if (frame->IsTextFrame()) { - const uint32_t startOffset = aRange.MayCrossShadowBoundaryStartOffset(); - const uint32_t endOffset = - endNode == startContent ? aRange.MayCrossShadowBoundaryEndOffset() - : startContent->Length(); + const uint32_t startOffset = aRange.StartOffset(); + const uint32_t endOffset = endNode == startContent + ? aRange.EndOffset() + : startContent->Length(); static_cast(frame)->SelectionStateChanged( startOffset, endOffset, aSelect, mSelectionType); } else { @@ -1848,7 +1806,7 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, // If the range is in a node and the node is a leaf node, we don't need to // walk the subtree. - if ((aRange.Collapsed() && !aRange.MayCrossShadowBoundary()) || + if (aRange.Collapsed() || (startContent == endNode && !startContent->HasChildren())) { if (!isFirstContentTextNode) { SelectFramesOf(startContent, aSelect); @@ -1857,7 +1815,7 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, } ContentSubtreeIterator subtreeIter; - subtreeIter.InitWithAllowCrossShadowBoundary(&aRange); + subtreeIter.Init(&aRange); if (isFirstContentTextNode && !subtreeIter.IsDone() && subtreeIter.GetCurrentNode() == startContent) { subtreeIter.Next(); // first content has already been handled. @@ -1867,12 +1825,8 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, MOZ_DIAGNOSTIC_ASSERT(subtreeIter.GetCurrentNode()); if (nsIContent* const content = nsIContent::FromNodeOrNull(subtreeIter.GetCurrentNode())) { - if (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) { - SelectFramesOfShadowIncludingDescendantsOfContent(content, aSelect); - } else { - SelectFramesOfInclusiveDescendantsOfContent(postOrderIter, content, - aSelect); - } + SelectFramesOfInclusiveDescendantsOfContent(postOrderIter, content, + aSelect); } } @@ -1885,7 +1839,7 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, // The frame could be an SVG text frame, in which case we'll ignore it. if (frame->IsTextFrame()) { static_cast(frame)->SelectionStateChanged( - 0, aRange.MayCrossShadowBoundaryEndOffset(), aSelect, mSelectionType); + 0, aRange.EndOffset(), aSelect, mSelectionType); } } return NS_OK; @@ -1947,11 +1901,10 @@ UniquePtr Selection::LookUpSelection( if (range->IsStaticRange() && !range->AsStaticRange()->IsValid()) { continue; } - - nsINode* startNode = range->GetMayCrossShadowBoundaryStartContainer(); - nsINode* endNode = range->GetMayCrossShadowBoundaryEndContainer(); - uint32_t startOffset = range->MayCrossShadowBoundaryStartOffset(); - uint32_t endOffset = range->MayCrossShadowBoundaryEndOffset(); + nsINode* startNode = range->GetStartContainer(); + nsINode* endNode = range->GetEndContainer(); + uint32_t startOffset = range->StartOffset(); + uint32_t endOffset = range->EndOffset(); Maybe start, end; if (startNode == aContent && endNode == aContent) { @@ -2231,67 +2184,6 @@ void Selection::RemoveAllRanges(ErrorResult& aRv) { RemoveAllRangesInternal(aRv); } -already_AddRefed Selection::GetComposedRange( - const AbstractRange* aRange, - const Sequence>& aShadowRoots) const { - // If aIsEndNode is true, this method does the Step 5.1 and 5.2 - // in https://www.w3.org/TR/selection-api/#dom-selection-getcomposedranges, - // otherwise it does the Step 3.1 and 3.2. - auto reScope = [&aShadowRoots](nsINode*& aNode, uint32_t& aOffset, - bool aIsEndNode) { - MOZ_ASSERT(aNode); - while (aNode) { - const ShadowRoot* shadowRootOfNode = aNode->GetContainingShadow(); - if (!shadowRootOfNode) { - return; - } - - for (const OwningNonNull& shadowRoot : aShadowRoots) { - if (shadowRoot->IsShadowIncludingInclusiveDescendantOf( - shadowRootOfNode)) { - return; - } - } - - const nsIContent* host = aNode->GetContainingShadowHost(); - const Maybe maybeIndex = host->ComputeIndexInParentContent(); - MOZ_ASSERT(maybeIndex.isSome(), "not parent or anonymous child?"); - if (MOZ_UNLIKELY(maybeIndex.isNothing())) { - // Unlikely to happen, but still set aNode to nullptr to avoid - // leaking information about the shadow tree. - aNode = nullptr; - return; - } - aOffset = maybeIndex.value(); - if (aIsEndNode) { - aOffset += 1; - } - aNode = host->GetParentNode(); - } - }; - - nsINode* startNode = aRange->GetMayCrossShadowBoundaryStartContainer(); - uint32_t startOffset = aRange->MayCrossShadowBoundaryStartOffset(); - nsINode* endNode = aRange->GetMayCrossShadowBoundaryEndContainer(); - uint32_t endOffset = aRange->MayCrossShadowBoundaryEndOffset(); - - reScope(startNode, startOffset, false /* aIsEndNode */); - reScope(endNode, endOffset, true /* aIsEndNode */); - - RefPtr composedRange = StaticRange::Create( - startNode, startOffset, endNode, endOffset, IgnoreErrors()); - return composedRange.forget(); -} - -void Selection::GetComposedRanges( - const Sequence>& aShadowRoots, - nsTArray>& aComposedRanges) { - aComposedRanges.SetCapacity(mStyledRanges.mRanges.Length()); - for (const auto& range : mStyledRanges.mRanges) { - aComposedRanges.AppendElement(GetComposedRange(range.mRange, aShadowRoots)); - } -} - void Selection::RemoveAllRangesInternal(ErrorResult& aRv) { if (!mFrameSelection) { aRv.Throw(NS_ERROR_NOT_INITIALIZED); @@ -2784,19 +2676,6 @@ AbstractRange* Selection::GetAbstractRangeAt(uint32_t aIndex) const { return mStyledRanges.mRanges.SafeElementAt(aIndex, empty).mRange; } -void Selection::GetDirection(nsAString& aDirection) const { - if (mStyledRanges.mRanges.IsEmpty() || - (mFrameSelection && (mFrameSelection->IsDoubleClickSelection() || - mFrameSelection->IsTripleClickSelection()))) { - // Empty range and double/triple clicks result a directionless selection. - aDirection.AssignLiteral("none"); - } else if (mDirection == nsDirection::eDirPrevious) { - aDirection.AssignLiteral("backward"); - } else { - aDirection.AssignLiteral("forward"); - } -} - nsRange* Selection::GetRangeAt(uint32_t aIndex) const { // This method per IDL spec returns a dynamic range. // Therefore, it must be ensured that it is only called @@ -2961,17 +2840,17 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, #ifdef DEBUG_SELECTION nsDirection oldDirection = GetDirection(); #endif - nsINode* anchorNode = GetMayCrossShadowBoundaryAnchorNode(); - nsINode* focusNode = GetMayCrossShadowBoundaryFocusNode(); - const uint32_t anchorOffset = MayCrossShadowBoundaryAnchorOffset(); - const uint32_t focusOffset = MayCrossShadowBoundaryFocusOffset(); + nsINode* anchorNode = GetAnchorNode(); + nsINode* focusNode = GetFocusNode(); + const uint32_t anchorOffset = AnchorOffset(); + const uint32_t focusOffset = FocusOffset(); RefPtr range = mAnchorFocusRange->CloneRange(); - nsINode* startNode = range->GetMayCrossShadowBoundaryStartContainer(); - nsINode* endNode = range->GetMayCrossShadowBoundaryEndContainer(); - const uint32_t startOffset = range->MayCrossShadowBoundaryStartOffset(); - const uint32_t endOffset = range->MayCrossShadowBoundaryEndOffset(); + nsINode* startNode = range->GetStartContainer(); + nsINode* endNode = range->GetEndContainer(); + const uint32_t startOffset = range->StartOffset(); + const uint32_t endOffset = range->EndOffset(); bool shouldClearRange = false; const Maybe anchorOldFocusOrder = nsContentUtils::ComparePoints( @@ -3007,8 +2886,7 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, (*anchorOldFocusOrder <= 0 && *oldFocusNewFocusOrder < 0)) { // a1,2 a,1,2 // select from 1 to 2 unless they are collapsed - range->SetEnd(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetEnd(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } @@ -3029,8 +2907,7 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, *anchorNewFocusOrder > 0) { // 2, a1 // select from 2 to 1a SetDirection(eDirPrevious); - range->SetStart(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetStart(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } @@ -3050,8 +2927,7 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, return; } - range->SetEnd(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetEnd(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } @@ -3061,33 +2937,27 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, return; } SelectFrames(presContext, *difRange, false); // deselect now - difRange->SetEnd(range->GetMayCrossShadowBoundaryEndContainer(), - range->MayCrossShadowBoundaryEndOffset(), - AllowRangeCrossShadowBoundary::Yes); + difRange->SetEnd(range->GetEndContainer(), range->EndOffset()); SelectFrames(presContext, *difRange, true); // must reselect last node // maybe more } else if (*anchorOldFocusOrder >= 0 && *anchorNewFocusOrder <= 0) { // 1,a,2 or 1a,2 or 1,a2 or 1a2 if (GetDirection() == eDirPrevious) { - res = range->SetStart(endNode, endOffset, - AllowRangeCrossShadowBoundary::Yes); + res = range->SetStart(endNode, endOffset); if (NS_FAILED(res)) { aRv.Throw(res); return; } } SetDirection(eDirNext); - range->SetEnd(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetEnd(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } if (focusNode != anchorNode || focusOffset != anchorOffset) { // if collapsed diff dont do anything - res = difRange->SetStart(focusNode, focusOffset, - AllowRangeCrossShadowBoundary::Yes); - nsresult tmp = difRange->SetEnd(anchorNode, anchorOffset, - AllowRangeCrossShadowBoundary::Yes); + res = difRange->SetStart(focusNode, focusOffset); + nsresult tmp = difRange->SetEnd(anchorNode, anchorOffset); if (NS_FAILED(tmp)) { res = tmp; } @@ -3121,8 +2991,7 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, return; } SetDirection(eDirPrevious); - range->SetStart(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetStart(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } @@ -3133,19 +3002,15 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, return; } SelectFrames(presContext, *difRange, false); - difRange->SetStart(range->GetMayCrossShadowBoundaryStartContainer(), - range->MayCrossShadowBoundaryStartOffset(), - AllowRangeCrossShadowBoundary::Yes); + difRange->SetStart(range->GetStartContainer(), range->StartOffset()); SelectFrames(presContext, *difRange, true); // must reselect last node } else if (*anchorNewFocusOrder >= 0 && *anchorOldFocusOrder <= 0) { // 2,a,1 or 2a,1 or 2,a1 or 2a1 if (GetDirection() == eDirNext) { - range->SetEnd(startNode, startOffset, - AllowRangeCrossShadowBoundary::Yes); + range->SetEnd(startNode, startOffset); } SetDirection(eDirPrevious); - range->SetStart(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetStart(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } @@ -3175,8 +3040,7 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset, } else if (*oldFocusNewFocusOrder >= 0 && *anchorOldFocusOrder >= 0) { // 2,1,a or 21,a or 2,1a or 21a // select from 2 to 1 - range->SetStart(aContainer, aOffset, aRv, - AllowRangeCrossShadowBoundary::Yes); + range->SetStart(aContainer, aOffset, aRv); if (aRv.Failed()) { return; } @@ -3744,10 +3608,9 @@ void Selection::NotifySelectionListeners() { RefPtr frameSelection = mFrameSelection; - // This flag will be set to Double or Triple if a selection by double click or - // triple click is detected. As soon as the selection is modified, it needs to - // be reset to NotApplicable. - frameSelection->SetClickSelectionType(ClickSelectionType::NotApplicable); + // This flag will be set to true if a selection by double click is detected. + // As soon as the selection is modified, it needs to be set to false. + frameSelection->SetIsDoubleClickSelection(false); if (frameSelection->IsBatching()) { frameSelection->SetChangesDuringBatchingFlag(); diff --git a/dom/base/Selection.h b/dom/base/Selection.h index 08563993acad..9f031ab3cffd 100644 --- a/dom/base/Selection.h +++ b/dom/base/Selection.h @@ -64,9 +64,6 @@ namespace dom { class Selection final : public nsSupportsWeakReference, public nsWrapperCache, public SupportsWeakPtr { - using AllowRangeCrossShadowBoundary = - mozilla::dom::AllowRangeCrossShadowBoundary; - protected: virtual ~Selection(); @@ -208,10 +205,6 @@ class Selection final : public nsSupportsWeakReference, nsRange* aRange, Maybe* aOutIndex, DispatchSelectstartEvent aDispatchSelectstartEvent); - already_AddRefed GetComposedRange( - const AbstractRange* aRange, - const Sequence>& aShadowRoots) const; - public: nsresult RemoveCollapsedRanges(); void Clear(nsPresContext* aPresContext); @@ -253,8 +246,6 @@ class Selection final : public nsSupportsWeakReference, // anchor and which end is focus. const nsRange* GetAnchorFocusRange() const { return mAnchorFocusRange; } - void GetDirection(nsAString& aDirection) const; - nsDirection GetDirection() const { return mDirection; } void SetDirection(nsDirection aDir) { mDirection = aDir; } @@ -330,30 +321,6 @@ class Selection final : public nsSupportsWeakReference, return offset ? *offset : 0; } - nsINode* GetMayCrossShadowBoundaryAnchorNode() const { - const RangeBoundary& anchor = AnchorRef(AllowRangeCrossShadowBoundary::Yes); - return anchor.IsSet() ? anchor.Container() : nullptr; - } - - uint32_t MayCrossShadowBoundaryAnchorOffset() const { - const RangeBoundary& anchor = AnchorRef(AllowRangeCrossShadowBoundary::Yes); - const Maybe offset = - anchor.Offset(RangeBoundary::OffsetFilter::kValidOffsets); - return offset ? *offset : 0; - } - - nsINode* GetMayCrossShadowBoundaryFocusNode() const { - const RangeBoundary& focus = FocusRef(AllowRangeCrossShadowBoundary::Yes); - return focus.IsSet() ? focus.Container() : nullptr; - } - - uint32_t MayCrossShadowBoundaryFocusOffset() const { - const RangeBoundary& focus = FocusRef(AllowRangeCrossShadowBoundary::Yes); - const Maybe offset = - focus.Offset(RangeBoundary::OffsetFilter::kValidOffsets); - return offset ? *offset : 0; - } - nsIContent* GetChildAtAnchorOffset() { const RangeBoundary& anchor = AnchorRef(); return anchor.IsSet() ? anchor.GetChildAtOffset() : nullptr; @@ -363,12 +330,8 @@ class Selection final : public nsSupportsWeakReference, return focus.IsSet() ? focus.GetChildAtOffset() : nullptr; } - const RangeBoundary& AnchorRef( - AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary = - AllowRangeCrossShadowBoundary::No) const; - const RangeBoundary& FocusRef( - AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary = - AllowRangeCrossShadowBoundary::No) const; + const RangeBoundary& AnchorRef() const; + const RangeBoundary& FocusRef() const; /* * IsCollapsed -- is the whole selection just one point, or unset? @@ -422,10 +385,6 @@ class Selection final : public nsSupportsWeakReference, MOZ_CAN_RUN_SCRIPT void RemoveAllRanges(mozilla::ErrorResult& aRv); - void GetComposedRanges( - const Sequence>& aShadowRoots, - nsTArray>& aComposedRanges); - /** * Whether Stringify should flush layout or not. */ @@ -851,12 +810,6 @@ class Selection final : public nsSupportsWeakReference, PostContentIterator& aPostOrderIter, nsIContent* aContent, bool aSelected) const; - /** - * https://dom.spec.whatwg.org/#concept-shadow-including-descendant - */ - void SelectFramesOfShadowIncludingDescendantsOfContent(nsIContent* aContent, - bool aSelected) const; - nsresult SelectFrames(nsPresContext* aPresContext, AbstractRange& aRange, bool aSelect) const; diff --git a/dom/base/StaticRange.cpp b/dom/base/StaticRange.cpp index 73ff04c038e3..0946e8f9bfeb 100644 --- a/dom/base/StaticRange.cpp +++ b/dom/base/StaticRange.cpp @@ -100,13 +100,6 @@ bool StaticRange::IsValid() const { return false; } - MOZ_ASSERT(mAreStartAndEndInSameTree == - (RangeUtils::ComputeRootNode(mStart.Container()) == - RangeUtils::ComputeRootNode(mEnd.Container()))); - if (!mAreStartAndEndInSameTree) { - return false; - } - const Maybe pointOrder = nsContentUtils::ComparePoints(mStart, mEnd); return pointOrder.isSome() && *pointOrder <= 0; } @@ -126,9 +119,6 @@ void StaticRange::DoSetRange(const RangeBoundaryBase& aStartBoundary, if (checkCommonAncestor) { UpdateCommonAncestorIfNecessary(); } - - mAreStartAndEndInSameTree = RangeUtils::ComputeRootNode(mStart.Container()) == - RangeUtils::ComputeRootNode(mEnd.Container()); } /* static */ diff --git a/dom/base/StaticRange.h b/dom/base/StaticRange.h index af7054f843c6..a6f677130da9 100644 --- a/dom/base/StaticRange.h +++ b/dom/base/StaticRange.h @@ -8,7 +8,6 @@ #define mozilla_dom_StaticRange_h #include "mozilla/RangeBoundary.h" -#include "mozilla/RangeUtils.h" #include "mozilla/dom/AbstractRange.h" #include "mozilla/dom/StaticRangeBinding.h" #include "nsTArray.h" @@ -71,21 +70,6 @@ class StaticRange final : public AbstractRange { */ bool IsValid() const; - void NotifyNodeBecomesShadowHost(nsINode* aNode) { - if (aNode == mStart.Container()) { - mStart.NotifyParentBecomesShadowHost(); - } - - if (aNode == mEnd.Container()) { - mEnd.NotifyParentBecomesShadowHost(); - } - } - - private: - // Whether the start and end points are in the same tree. - // They could be in different trees, i.e, cross shadow boundaries. - bool mAreStartAndEndInSameTree = false; - protected: explicit StaticRange(nsINode* aNode) : AbstractRange(aNode, /* aIsDynamicRange = */ false) {} diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp index 6c77574df797..d5455e559639 100644 --- a/dom/base/nsINode.cpp +++ b/dom/base/nsINode.cpp @@ -287,17 +287,11 @@ static const nsINode* GetClosestCommonInclusiveAncestorForRangeInSelection( const nsINode* aNode) { while (aNode && !aNode->IsClosestCommonInclusiveAncestorForRangeInSelection()) { - const bool isNodeInShadowTree = - StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() && - aNode->IsInShadowTree(); if (!aNode - ->IsDescendantOfClosestCommonInclusiveAncestorForRangeInSelection() && - !isNodeInShadowTree) { + ->IsDescendantOfClosestCommonInclusiveAncestorForRangeInSelection()) { return nullptr; } - aNode = StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() - ? aNode->GetParentOrShadowHostNode() - : aNode->GetParentNode(); + aNode = aNode->GetParentNode(); } return aNode; } @@ -321,12 +315,12 @@ class IsItemInRangeComparator { int operator()(const AbstractRange* const aRange) const { int32_t cmp = nsContentUtils::ComparePoints_Deprecated( - &mNode, mEndOffset, aRange->GetMayCrossShadowBoundaryStartContainer(), - aRange->MayCrossShadowBoundaryStartOffset(), nullptr, mCache); + &mNode, mEndOffset, aRange->GetStartContainer(), aRange->StartOffset(), + nullptr, mCache); if (cmp == 1) { cmp = nsContentUtils::ComparePoints_Deprecated( - &mNode, mStartOffset, aRange->GetMayCrossShadowBoundaryEndContainer(), - aRange->MayCrossShadowBoundaryEndOffset(), nullptr, mCache); + &mNode, mStartOffset, aRange->GetEndContainer(), aRange->EndOffset(), + nullptr, mCache); if (cmp == -1) { return 0; } @@ -392,18 +386,6 @@ bool nsINode::IsSelected(const uint32_t aStartOffset, return true; } - if (range->MayCrossShadowBoundary()) { - MOZ_ASSERT(range->IsDynamicRange(), - "range->MayCrossShadowBoundary() can only return true for " - "dynamic range"); - StaticRange* crossBoundaryRange = - range->AsDynamicRange()->GetCrossShadowBoundaryRange(); - MOZ_ASSERT(crossBoundaryRange); - if (!crossBoundaryRange->Collapsed()) { - return true; - } - } - const AbstractRange* middlePlus1; const AbstractRange* middleMinus1; // if node end > start of middle+1, result = 1 @@ -570,8 +552,7 @@ static nsIContent* GetRootForContentSubtree(nsIContent* aContent) { return nsIContent::FromNode(aContent->SubtreeRoot()); } -nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell, - bool aAllowCrossShadowBoundary) { +nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) { NS_ENSURE_TRUE(aPresShell, nullptr); if (IsDocument()) return AsDocument()->GetRootElement(); @@ -615,7 +596,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell, } RefPtr fs = aPresShell->FrameSelection(); - nsCOMPtr content = fs->GetLimiter(); + nsIContent* content = fs->GetLimiter(); if (!content) { content = fs->GetAncestorLimiter(); if (!content) { @@ -635,10 +616,6 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell, // Use the host as the root. if (ShadowRoot* shadowRoot = ShadowRoot::FromNode(content)) { content = shadowRoot->GetHost(); - if (content && aAllowCrossShadowBoundary) { - content = content->GetSelectionRootContent(aPresShell, - aAllowCrossShadowBoundary); - } } } @@ -3849,33 +3826,6 @@ void nsINode::FireNodeRemovedForChildren() { } } -ShadowRoot* nsINode::GetShadowRoot() const { - return IsContent() ? AsContent()->GetShadowRoot() : nullptr; -} - -ShadowRoot* nsINode::GetShadowRootForSelection() const { - if (!StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) { - return nullptr; - } - - ShadowRoot* shadowRoot = GetShadowRoot(); - if (!shadowRoot) { - return nullptr; - } - - // ie.
and