Bug 1932150 - Fix some inconsistency about indicating whether the selection is allowed to cross the shadow boundary r=jjaschke,dom-core

Differential Revision: https://phabricator.services.mozilla.com/D246949
This commit is contained in:
Sean Feng
2025-05-09 17:16:36 +00:00
committed by sefeng@mozilla.com
parent 0422c9dc82
commit 322a5282b6
6 changed files with 117 additions and 96 deletions

View File

@@ -249,14 +249,10 @@ nsINode* AbstractRange::GetClosestCommonInclusiveAncestor(
if (!mIsPositioned) {
return nullptr;
}
nsINode* startContainer =
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes
? GetMayCrossShadowBoundaryStartContainer()
: GetStartContainer();
nsINode* endContainer =
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes
? GetMayCrossShadowBoundaryEndContainer()
: GetEndContainer();
nsINode* startContainer = ShadowDOMSelectionHelpers::GetStartContainer(
this, aAllowCrossShadowBoundary);
nsINode* endContainer = ShadowDOMSelectionHelpers::GetEndContainer(
this, aAllowCrossShadowBoundary);
if (MayCrossShadowBoundary() &&
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {

View File

@@ -550,7 +550,8 @@ nsINode* ContentIteratorBase<NodeType>::GetDeepFirstChild(nsINode* aRoot) {
// static
template <typename NodeType>
nsIContent* ContentIteratorBase<NodeType>::GetDeepFirstChild(
nsIContent* aRoot, bool aAllowCrossShadowBoundary) {
nsIContent* aRoot,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
if (NS_WARN_IF(!aRoot)) {
return nullptr;
}
@@ -567,7 +568,7 @@ nsIContent* ContentIteratorBase<NodeType>::GetDeepFirstChild(
// shadowRoot->GetFirstChild() should be able to return the <slot> element.
// It's probably correct I think. Then it's up to the caller of this
// iterator to decide whether to use the slot's assigned nodes or not.
MOZ_ASSERT(aAllowCrossShadowBoundary);
MOZ_ASSERT(aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes);
child = shadowRoot->GetFirstChild();
} else {
child = node->GetFirstChild();
@@ -607,7 +608,8 @@ nsINode* ContentIteratorBase<NodeType>::GetDeepLastChild(nsINode* aRoot) {
// static
template <typename NodeType>
nsIContent* ContentIteratorBase<NodeType>::GetDeepLastChild(
nsIContent* aRoot, bool aAllowCrossShadowBoundary) {
nsIContent* aRoot,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
if (NS_WARN_IF(!aRoot)) {
return nullptr;
}
@@ -640,7 +642,7 @@ nsIContent* ContentIteratorBase<NodeType>::GetDeepLastChild(
//
template <typename NodeType>
nsIContent* ContentIteratorBase<NodeType>::GetNextSibling(
nsINode* aNode, bool aAllowCrossShadowBoundary) {
nsINode* aNode, AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary,
if (NS_WARN_IF(!aNode)) {
return nullptr;
}
@@ -655,7 +657,7 @@ nsIContent* ContentIteratorBase<NodeType>::GetNextSibling(
return nullptr;
}
if (aAllowCrossShadowBoundary) {
if (aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
// 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
@@ -674,7 +676,7 @@ nsIContent* ContentIteratorBase<NodeType>::GetNextSibling(
// (when aAllowCrossShadowBoundary is true), or grandpa's prev sibling... static
template <typename NodeType>
nsIContent* ContentIteratorBase<NodeType>::GetPrevSibling(
nsINode* aNode, bool aAllowCrossShadowBoundary) {
nsINode* aNode, AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
if (NS_WARN_IF(!aNode)) {
return nullptr;
}
@@ -947,7 +949,7 @@ nsresult ContentSubtreeIterator::InitWithAllowCrossShadowBoundary(
void ContentSubtreeIterator::CacheInclusiveAncestorsOfEndContainer() {
mInclusiveAncestorsOfEndContainer.Clear();
nsINode* const endContainer = ShadowDOMSelectionHelpers::GetEndContainer(
mRange, IterAllowCrossShadowBoundary());
mRange, mAllowCrossShadowBoundary);
nsIContent* endNode =
endContainer->IsContent() ? endContainer->AsContent() : nullptr;
while (endNode) {
@@ -964,7 +966,7 @@ void ContentSubtreeIterator::CacheInclusiveAncestorsOfEndContainer() {
nsIContent* ContentSubtreeIterator::DetermineCandidateForFirstContent() const {
nsINode* startContainer = ShadowDOMSelectionHelpers::GetStartContainer(
mRange, IterAllowCrossShadowBoundary());
mRange, mAllowCrossShadowBoundary);
nsIContent* firstCandidate = nullptr;
// find first node in range
nsINode* node = nullptr;
@@ -979,7 +981,7 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForFirstContent() const {
MOZ_ASSERT(child == startContainer->GetChildAt_Deprecated(
ShadowDOMSelectionHelpers::StartOffset(
mRange, IterAllowCrossShadowBoundary())));
mRange, mAllowCrossShadowBoundary)));
if (!child) {
// offset after last child
node = startContainer;
@@ -990,13 +992,13 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForFirstContent() const {
if (!firstCandidate) {
// then firstCandidate is next node after node
firstCandidate = ContentIteratorBase::GetNextSibling(
node, IterAllowCrossShadowBoundary());
firstCandidate =
ContentIteratorBase::GetNextSibling(node, mAllowCrossShadowBoundary);
}
if (firstCandidate) {
firstCandidate = ContentIteratorBase::GetDeepFirstChild(
firstCandidate, IterAllowCrossShadowBoundary());
firstCandidate, mAllowCrossShadowBoundary);
}
return firstCandidate;
@@ -1026,10 +1028,10 @@ nsIContent* ContentSubtreeIterator::DetermineFirstContent() const {
nsIContent* ContentSubtreeIterator::DetermineCandidateForLastContent() const {
nsIContent* lastCandidate{nullptr};
nsINode* endContainer = ShadowDOMSelectionHelpers::GetEndContainer(
mRange, IterAllowCrossShadowBoundary());
mRange, mAllowCrossShadowBoundary);
// now to find the last node
int32_t offset = ShadowDOMSelectionHelpers::EndOffset(
mRange, IterAllowCrossShadowBoundary());
int32_t offset =
ShadowDOMSelectionHelpers::EndOffset(mRange, mAllowCrossShadowBoundary);
int32_t numChildren = endContainer->GetChildCount();
@@ -1044,20 +1046,21 @@ nsIContent* ContentSubtreeIterator::DetermineCandidateForLastContent() const {
lastCandidate = IterAllowCrossShadowBoundary()
? mRange->MayCrossShadowBoundaryEndRef().Ref()
: mRange->EndRef().Ref();
MOZ_ASSERT(lastCandidate == endContainer->GetChildAt_Deprecated(--offset));
MOZ_ASSERT(lastCandidate ==
endContainer->GetChildAt_Deprecated(offset - 1));
NS_ASSERTION(lastCandidate,
"tree traversal trouble in ContentSubtreeIterator::Init");
}
if (!lastCandidate) {
// then lastCandidate is prev node before node
lastCandidate = ContentIteratorBase::GetPrevSibling(
node, IterAllowCrossShadowBoundary());
lastCandidate =
ContentIteratorBase::GetPrevSibling(node, mAllowCrossShadowBoundary);
}
if (lastCandidate) {
lastCandidate = ContentIteratorBase::GetDeepLastChild(
lastCandidate, IterAllowCrossShadowBoundary());
lastCandidate, mAllowCrossShadowBoundary);
}
return lastCandidate;
@@ -1072,13 +1075,13 @@ nsresult ContentSubtreeIterator::InitWithRange() {
mRange->GetClosestCommonInclusiveAncestor(mAllowCrossShadowBoundary);
nsINode* startContainer = ShadowDOMSelectionHelpers::GetStartContainer(
mRange, IterAllowCrossShadowBoundary());
const int32_t startOffset = ShadowDOMSelectionHelpers::StartOffset(
mRange, IterAllowCrossShadowBoundary());
mRange, mAllowCrossShadowBoundary);
const int32_t startOffset =
ShadowDOMSelectionHelpers::StartOffset(mRange, mAllowCrossShadowBoundary);
nsINode* endContainer = ShadowDOMSelectionHelpers::GetEndContainer(
mRange, IterAllowCrossShadowBoundary());
const int32_t endOffset = ShadowDOMSelectionHelpers::EndOffset(
mRange, IterAllowCrossShadowBoundary());
mRange, mAllowCrossShadowBoundary);
const int32_t endOffset =
ShadowDOMSelectionHelpers::EndOffset(mRange, mAllowCrossShadowBoundary);
MOZ_ASSERT(mClosestCommonInclusiveAncestor && startContainer && endContainer);
// Bug 767169
MOZ_ASSERT(uint32_t(startOffset) <= startContainer->Length() &&
@@ -1156,8 +1159,8 @@ void ContentSubtreeIterator::Next() {
return;
}
nsINode* nextNode = ContentIteratorBase::GetNextSibling(
mCurNode, IterAllowCrossShadowBoundary());
nsINode* nextNode =
ContentIteratorBase::GetNextSibling(mCurNode, mAllowCrossShadowBoundary);
NS_ASSERTION(nextNode, "No next sibling!?! This could mean deadlock!");
@@ -1223,7 +1226,7 @@ nsresult ContentSubtreeIterator::PositionAt(nsINode* aCurNode) {
nsIContent* ContentSubtreeIterator::GetTopAncestorInRange(
nsINode* aNode) const {
if (!aNode || !ShadowDOMSelectionHelpers::GetParentNodeInSameSelection(
*aNode, IterAllowCrossShadowBoundary())) {
*aNode, mAllowCrossShadowBoundary)) {
return nullptr;
}
@@ -1242,7 +1245,7 @@ nsIContent* ContentSubtreeIterator::GetTopAncestorInRange(
nsIContent* lastContentInShadowTree = nullptr;
while (content) {
nsINode* parent = ShadowDOMSelectionHelpers::GetParentNodeInSameSelection(
*content, IterAllowCrossShadowBoundary());
*content, mAllowCrossShadowBoundary);
// 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
@@ -1255,7 +1258,7 @@ nsIContent* ContentSubtreeIterator::GetTopAncestorInRange(
// We have to special-case this because CompareNodeToRange treats the root
// node differently -- see bug 765205.
if (!parent || !ShadowDOMSelectionHelpers::GetParentNodeInSameSelection(
*parent, IterAllowCrossShadowBoundary())) {
*parent, mAllowCrossShadowBoundary)) {
return content;
}

View File

@@ -87,13 +87,15 @@ class ContentIteratorBase {
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,
dom::AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
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,
dom::AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
// 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
@@ -101,10 +103,14 @@ class ContentIteratorBase {
//
// 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,
dom::AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary =
dom::AllowRangeCrossShadowBoundary::No,
static nsIContent* GetPrevSibling(
nsINode* aNode,
dom::AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary =
dom::AllowRangeCrossShadowBoundary::No);
nsINode* NextNode(nsINode* aNode);
nsINode* PrevNode(nsINode* aNode);

View File

@@ -266,47 +266,52 @@ nsresult RangeUtils::CompareNodeToRangeBoundaries(
// static
nsINode* ShadowDOMSelectionHelpers::GetStartContainer(
const AbstractRange* aRange, bool aAllowCrossShadowBoundary) {
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
MOZ_ASSERT(aRange);
return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
aAllowCrossShadowBoundary)
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes)
? aRange->GetMayCrossShadowBoundaryStartContainer()
: aRange->GetStartContainer();
}
// static
uint32_t ShadowDOMSelectionHelpers::StartOffset(
const AbstractRange* aRange, bool aAllowCrossShadowBoundary) {
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
MOZ_ASSERT(aRange);
return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
aAllowCrossShadowBoundary)
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes)
? aRange->MayCrossShadowBoundaryStartOffset()
: aRange->StartOffset();
}
// static
nsINode* ShadowDOMSelectionHelpers::GetEndContainer(
const AbstractRange* aRange, bool aAllowCrossShadowBoundary) {
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
MOZ_ASSERT(aRange);
return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
aAllowCrossShadowBoundary)
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes)
? aRange->GetMayCrossShadowBoundaryEndContainer()
: aRange->GetEndContainer();
}
// static
uint32_t ShadowDOMSelectionHelpers::EndOffset(const AbstractRange* aRange,
bool aAllowCrossShadowBoundary) {
uint32_t ShadowDOMSelectionHelpers::EndOffset(
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
MOZ_ASSERT(aRange);
return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
aAllowCrossShadowBoundary)
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes)
? aRange->MayCrossShadowBoundaryEndOffset()
: aRange->EndOffset();
}
// static
nsINode* ShadowDOMSelectionHelpers::GetParentNodeInSameSelection(
nsINode& aNode, bool aAllowCrossShadowBoundary) {
const nsINode& aNode,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
if (!ParentNodeIsInSameSelection(aNode)) {
return nullptr;
}
@@ -318,10 +323,11 @@ nsINode* ShadowDOMSelectionHelpers::GetParentNodeInSameSelection(
// static
ShadowRoot* ShadowDOMSelectionHelpers::GetShadowRoot(
const nsINode* aNode, bool aAllowCrossShadowBoundary) {
const nsINode* aNode,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
MOZ_ASSERT(aNode);
return (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
aAllowCrossShadowBoundary)
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes)
? aNode->GetShadowRootForSelection()
: nullptr;
} // namespace dom

View File

@@ -25,23 +25,29 @@ class AbstractRange;
struct ShadowDOMSelectionHelpers {
ShadowDOMSelectionHelpers() = delete;
static nsINode* GetStartContainer(const AbstractRange* aRange,
bool aAllowCrossShadowBoundary);
static nsINode* GetStartContainer(
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
static uint32_t StartOffset(const AbstractRange* aRange,
bool aAllowCrossShadowBoundary);
static uint32_t StartOffset(
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
static nsINode* GetEndContainer(const AbstractRange* aRange,
bool aAllowCrossShadowBoundary);
static nsINode* GetEndContainer(
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
static uint32_t EndOffset(const AbstractRange* aRange,
bool aAllowCrossShadowBoundary);
static uint32_t EndOffset(
const AbstractRange* aRange,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
static nsINode* GetParentNodeInSameSelection(nsINode& aNode,
bool aAllowCrossShadowBoundary);
static nsINode* GetParentNodeInSameSelection(
const nsINode& aNode,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
static ShadowRoot* GetShadowRoot(const nsINode* aNode,
bool aAllowCrossShadowBoundary);
static ShadowRoot* GetShadowRoot(
const nsINode* aNode,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
};
} // namespace dom

View File

@@ -47,6 +47,7 @@
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/AbstractRange.h"
#include "mozilla/dom/Text.h"
#include "mozilla/dom/AbstractRange.h"
#include "mozilla/Encoding.h"
#include "mozilla/IntegerRange.h"
#include "mozilla/Maybe.h"
@@ -245,7 +246,8 @@ class nsDocumentEncoder : public nsIDocumentEncoder {
virtual ~nsDocumentEncoder();
void Initialize(bool aClearCachedSerializer = true,
bool aAllowCrossShadowBoundary = false);
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary =
AllowRangeCrossShadowBoundary::No);
/**
* @param aMaxLength As described at
@@ -431,7 +433,7 @@ class nsDocumentEncoder : public nsIDocumentEncoder {
mNodeSerializer{aNodeSerializer},
mRangeContextSerializer{aRangeContextSerializer} {}
void Initialize(bool aAllowCrossShadowBoundary);
void Initialize(AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary);
/**
* @param aDepth the distance (number of `GetParent` calls) from aNode to
@@ -498,14 +500,15 @@ class nsDocumentEncoder : public nsIDocumentEncoder {
const NodeSerializer& mNodeSerializer;
RangeContextSerializer& mRangeContextSerializer;
bool mAllowCrossShadowBoundary = false;
AllowRangeCrossShadowBoundary mAllowCrossShadowBoundary =
AllowRangeCrossShadowBoundary::No;
};
RangeSerializer mRangeSerializer;
};
void nsDocumentEncoder::RangeSerializer::Initialize(
bool aAllowCrossShadowBoundary) {
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
mContextInfoDepth = {};
mStartRootIndex = 0;
mEndRootIndex = 0;
@@ -548,8 +551,9 @@ nsDocumentEncoder::nsDocumentEncoder(
nsDocumentEncoder::nsDocumentEncoder()
: nsDocumentEncoder(MakeUnique<RangeNodeContext>()) {}
void nsDocumentEncoder::Initialize(bool aClearCachedSerializer,
bool aAllowCrossShadowBoundary) {
void nsDocumentEncoder::Initialize(
bool aClearCachedSerializer,
AllowRangeCrossShadowBoundary aAllowCrossShadowBoundary) {
mFlags = 0;
mWrapColumn = 72;
mRangeSerializer.Initialize(aAllowCrossShadowBoundary);
@@ -570,6 +574,13 @@ static bool ParentIsTR(nsIContent* aContent) {
return parent->IsHTMLElement(nsGkAtoms::tr);
}
static AllowRangeCrossShadowBoundary GetAllowRangeCrossShadowBoundary(
const uint32_t aFlags) {
return (aFlags & nsIDocumentEncoder::AllowCrossShadowBoundary)
? AllowRangeCrossShadowBoundary::Yes
: AllowRangeCrossShadowBoundary::No;
}
nsresult nsDocumentEncoder::SerializeDependingOnScope(uint32_t aMaxLength) {
nsresult rv = NS_OK;
if (mEncodingScope.mSelection) {
@@ -608,7 +619,7 @@ nsresult nsDocumentEncoder::SerializeSelection() {
// by the immediate context. This assumes that you can't select cells that
// are multiple selections from two tables simultaneously.
node = ShadowDOMSelectionHelpers::GetStartContainer(
range, mFlags & nsIDocumentEncoder::AllowCrossShadowBoundary);
range, GetAllowRangeCrossShadowBoundary(mFlags));
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
if (node != prevNode) {
if (prevNode) {
@@ -725,7 +736,7 @@ nsDocumentEncoder::NativeInit(Document* aDocument, const nsAString& aMimeType,
if (!aDocument) return NS_ERROR_INVALID_ARG;
Initialize(!mMimeType.Equals(aMimeType),
aFlags & nsIDocumentEncoder::AllowCrossShadowBoundary);
GetAllowRangeCrossShadowBoundary(aFlags));
mDocument = aDocument;
@@ -959,7 +970,7 @@ nsresult nsDocumentEncoder::NodeSerializer::SerializeToStringRecursive(
}
ShadowRoot* shadowRoot = ShadowDOMSelectionHelpers::GetShadowRoot(
aNode, mFlags & nsIDocumentEncoder::AllowCrossShadowBoundary);
aNode, GetAllowRangeCrossShadowBoundary(mFlags));
if (shadowRoot) {
MOZ_ASSERT(StaticPrefs::dom_shadowdom_selection_across_boundary_enabled());
@@ -1314,8 +1325,10 @@ bool nsDocumentEncoder::RangeSerializer::HasInvisibleParentAndShouldBeSkipped(
nsresult nsDocumentEncoder::RangeSerializer::SerializeRangeToString(
const nsRange* aRange) {
if (!aRange || (aRange->Collapsed() && (!mAllowCrossShadowBoundary ||
!aRange->MayCrossShadowBoundary()))) {
if (!aRange ||
(aRange->Collapsed() &&
(mAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::No ||
!aRange->MayCrossShadowBoundary()))) {
return NS_OK;
}
@@ -1325,9 +1338,7 @@ nsresult nsDocumentEncoder::RangeSerializer::SerializeRangeToString(
// boundary can return the host element as the container.
// SerializeRangeContextStart doesn't support this case.
mClosestCommonInclusiveAncestorOfRange =
aRange->GetClosestCommonInclusiveAncestor(
mAllowCrossShadowBoundary ? AllowRangeCrossShadowBoundary::Yes
: AllowRangeCrossShadowBoundary::No);
aRange->GetClosestCommonInclusiveAncestor(mAllowCrossShadowBoundary);
if (!mClosestCommonInclusiveAncestorOfRange) {
return NS_OK;
@@ -1362,7 +1373,7 @@ nsresult nsDocumentEncoder::RangeSerializer::SerializeRangeToString(
nsContentUtils::GetInclusiveAncestors(mClosestCommonInclusiveAncestorOfRange,
mCommonInclusiveAncestors);
if (mAllowCrossShadowBoundary) {
if (mAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
nsContentUtils::GetShadowIncludingAncestorsAndOffsets(
startContainer, startOffset, inclusiveAncestorsOfStart,
inclusiveAncestorsOffsetsOfStart);
@@ -1611,7 +1622,7 @@ nsHTMLCopyEncoder::Init(Document* aDocument, const nsAString& aMimeType,
if (!aDocument) return NS_ERROR_INVALID_ARG;
mIsTextWidget = false;
Initialize(true, aFlags & nsIDocumentEncoder::AllowCrossShadowBoundary);
Initialize(true, GetAllowRangeCrossShadowBoundary(aFlags));
mIsCopying = true;
mDocument = aDocument;
@@ -1856,19 +1867,13 @@ nsresult nsHTMLCopyEncoder::PromoteRange(nsRange* inRange) {
// set the range to the new values
ErrorResult err;
const bool allowRangeCrossShadowBoundary =
mFlags & nsIDocumentEncoder::AllowCrossShadowBoundary;
inRange->SetStart(*opStartNode, static_cast<uint32_t>(opStartOffset), err,
allowRangeCrossShadowBoundary
? AllowRangeCrossShadowBoundary::Yes
: AllowRangeCrossShadowBoundary::No);
GetAllowRangeCrossShadowBoundary(mFlags));
if (NS_WARN_IF(err.Failed())) {
return err.StealNSResult();
}
inRange->SetEnd(*opEndNode, static_cast<uint32_t>(opEndOffset), err,
allowRangeCrossShadowBoundary
? AllowRangeCrossShadowBoundary::Yes
: AllowRangeCrossShadowBoundary::No);
GetAllowRangeCrossShadowBoundary(mFlags));
if (NS_WARN_IF(err.Failed())) {
return err.StealNSResult();
}
@@ -2057,8 +2062,7 @@ nsresult nsHTMLCopyEncoder::GetPromotedPoint(Endpoint aWhere, nsINode* aNode,
const bool isGeneratedContent =
offset == -1 &&
ShadowDOMSelectionHelpers::GetShadowRoot(
parent,
mFlags & nsIDocumentEncoder::AllowCrossShadowBoundary) != node;
parent, GetAllowRangeCrossShadowBoundary(mFlags)) != node;
if (isGeneratedContent) // we hit generated content; STOP
{
// back up a bit