tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit ae1d88575cd979e19290b166e0c3bf0ed3bab6a6
parent 4e1b9a331ad0b3977f327fc26fb5ae06195c7a80
Author: Masayuki Nakano <masayuki@d-toybox.com>
Date:   Mon, 15 Dec 2025 07:50:39 +0000

Bug 2000978 - Make `ContentIteratorBase::Init()` take `const AbstractRange*` instead of `AbstractRange*` r=smaug

`ContentIterator` shouldn't modify the range.  Therefore, its users
should be able to initialize its instance with `const AbstractRange*`.

Unfortunately, the range is stored by `ContentSubtreeIterator` and
needs to be managed by the cycle collector.  Therefore, only
`ContentSubtreeIterator` requires non-const range so that it requires to
clone the given range if and only if initialized with a const range.

Differential Revision: https://phabricator.services.mozilla.com/D274093

Diffstat:
Mdom/base/ContentIterator.h | 38+++++++++++++++++++++++++++++---------
Mdom/base/RangeUtils.cpp | 87+++++++++++++++++++++++++++++++++----------------------------------------------
Mdom/base/RangeUtils.h | 10+++++-----
3 files changed, 70 insertions(+), 65 deletions(-)

diff --git a/dom/base/ContentIterator.h b/dom/base/ContentIterator.h @@ -41,6 +41,12 @@ class ContentIteratorBase { */ [[nodiscard]] virtual nsresult Init(nsINode* aRoot); + /** + * If you want to use `const AbstractRange*`, you can use an overload which + * takes RawRangeBoundary instances or InitWithoutValidatingPoints(). + * If your range is dynamic, i.e., an nsRange, you can use + * InitWithoutValidatingPoints() which skips comparing the boundary points. + */ [[nodiscard]] virtual nsresult Init(dom::AbstractRange* aRange); [[nodiscard]] virtual nsresult Init(nsINode* aStartContainer, uint32_t aStartOffset, @@ -251,9 +257,13 @@ class ContentSubtreeIterator final : public SafeContentIteratorBase { /** * Not supported. */ - [[nodiscard]] virtual nsresult Init(nsINode* aRoot) override; + [[nodiscard]] nsresult Init(nsINode* aRoot) override; - [[nodiscard]] virtual nsresult Init(dom::AbstractRange* aRange) override; + /** + * If you need to use const AbstractRange, use an overload which take + * RawRangeBoundary instances. + */ + [[nodiscard]] nsresult Init(dom::AbstractRange* aRange) override; /** * Initialize the iterator with aRange that does correct things @@ -275,16 +285,26 @@ class ContentSubtreeIterator final : public SafeContentIteratorBase { * * Examples of what nodes will be returned can be found * at test_content_iterator_subtree_shadow_tree.html. + * + * FIXME: This doesn't have a overload of this method which takes + * `const RawRangeBoundary`s. That allows the callers to make this with + * `const AbstractRange*`. So, it and its non-validation version (for + * `const nsRange*` should be here. */ [[nodiscard]] nsresult InitWithAllowCrossShadowBoundary( dom::AbstractRange* aRange); - [[nodiscard]] virtual nsresult Init(nsINode* aStartContainer, - uint32_t aStartOffset, - nsINode* aEndContainer, - uint32_t aEndOffset) override; - [[nodiscard]] virtual nsresult Init( - const RawRangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary) override; + + [[nodiscard]] nsresult Init(nsINode* aStartContainer, uint32_t aStartOffset, + nsINode* aEndContainer, + uint32_t aEndOffset) override; + [[nodiscard]] nsresult Init(const RawRangeBoundary& aStartBoundary, + const RawRangeBoundary& aEndBoundary) override; + [[nodiscard]] nsresult InitWithoutValidatingPoints( + const RawRangeBoundary& aStart, const RawRangeBoundary& aEnd) override { + // We need to create an nsRange from aStart and aEnd. Therefore, anyway + // nsRange will validate them. + return Init(aStart, aEnd); + } void Next() override; void Prev() override; diff --git a/dom/base/RangeUtils.cpp b/dom/base/RangeUtils.cpp @@ -18,67 +18,51 @@ namespace mozilla { using namespace dom; -template bool RangeUtils::IsValidPoints(const RangeBoundary& aStartBoundary, - const RangeBoundary& aEndBoundary); -template bool RangeUtils::IsValidPoints(const RangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary); -template bool RangeUtils::IsValidPoints(const RawRangeBoundary& aStartBoundary, - const RangeBoundary& aEndBoundary); -template bool RangeUtils::IsValidPoints(const RawRangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary); +template bool RangeUtils::IsValidPoints(const RangeBoundary&, + const RangeBoundary&); +template bool RangeUtils::IsValidPoints(const RangeBoundary&, + const RawRangeBoundary&); +template bool RangeUtils::IsValidPoints(const RawRangeBoundary&, + const RangeBoundary&); +template bool RangeUtils::IsValidPoints(const RawRangeBoundary&, + const RawRangeBoundary&); template nsresult RangeUtils::CompareNodeToRangeBoundaries<TreeKind::ShadowIncludingDOM>( - nsINode* aNode, const RangeBoundary& aStartBoundary, - const RangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const RangeBoundary&, const RangeBoundary&, bool*, bool*); template nsresult RangeUtils::CompareNodeToRangeBoundaries<TreeKind::Flat>( - nsINode* aNode, const RangeBoundary& aStartBoundary, - const RangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const RangeBoundary&, const RangeBoundary&, bool*, bool*); -template nsresult -RangeUtils::CompareNodeToRangeBoundaries<TreeKind::ShadowIncludingDOM>( - nsINode* aNode, const RangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); +template nsresult RangeUtils::CompareNodeToRangeBoundaries< + TreeKind::ShadowIncludingDOM>(const nsINode*, const RangeBoundary&, + const RawRangeBoundary&, bool*, bool*); template nsresult RangeUtils::CompareNodeToRangeBoundaries<TreeKind::Flat>( - nsINode* aNode, const RangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const RangeBoundary&, const RawRangeBoundary&, bool*, + bool*); -template nsresult -RangeUtils::CompareNodeToRangeBoundaries<TreeKind::ShadowIncludingDOM>( - nsINode* aNode, const RawRangeBoundary& aStartBoundary, - const RangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); +template nsresult RangeUtils::CompareNodeToRangeBoundaries< + TreeKind::ShadowIncludingDOM>(const nsINode*, const RawRangeBoundary&, + const RangeBoundary&, bool*, bool*); template nsresult RangeUtils::CompareNodeToRangeBoundaries<TreeKind::Flat>( - nsINode* aNode, const RawRangeBoundary& aStartBoundary, - const RangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const RawRangeBoundary&, const RangeBoundary&, bool*, + bool*); -template nsresult -RangeUtils::CompareNodeToRangeBoundaries<TreeKind::ShadowIncludingDOM>( - nsINode* aNode, const RawRangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); +template nsresult RangeUtils::CompareNodeToRangeBoundaries< + TreeKind::ShadowIncludingDOM>(const nsINode*, const RawRangeBoundary&, + const RawRangeBoundary&, bool*, bool*); template nsresult RangeUtils::CompareNodeToRangeBoundaries<TreeKind::Flat>( - nsINode* aNode, const RawRangeBoundary& aStartBoundary, - const RawRangeBoundary& aEndBoundary, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const RawRangeBoundary&, const RawRangeBoundary&, bool*, + bool*); template nsresult RangeUtils::CompareNodeToRange<TreeKind::ShadowIncludingDOM>( - nsINode* aNode, AbstractRange* aAbstractRange, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const AbstractRange*, bool*, bool*); template nsresult RangeUtils::CompareNodeToRange<TreeKind::Flat>( - nsINode* aNode, AbstractRange* aAbstractRange, bool* aNodeIsBeforeRange, - bool* aNodeIsAfterRange); + const nsINode*, const AbstractRange*, bool*, bool*); -template Maybe<bool> -RangeUtils::IsNodeContainedInRange<TreeKind::ShadowIncludingDOM>( - nsINode& aNode, AbstractRange* aAbstractRange); +template Maybe<bool> RangeUtils::IsNodeContainedInRange< + TreeKind::ShadowIncludingDOM>(const nsINode&, const AbstractRange*); template Maybe<bool> RangeUtils::IsNodeContainedInRange<TreeKind::Flat>( - nsINode& aNode, AbstractRange* aAbstractRange); + const nsINode&, const AbstractRange*); [[nodiscard]] static inline bool ParentNodeIsInSameSelection( const nsINode& aNode) { @@ -176,8 +160,8 @@ bool RangeUtils::IsValidPoints( // static template <TreeKind aKind, typename Dummy> -Maybe<bool> RangeUtils::IsNodeContainedInRange(nsINode& aNode, - AbstractRange* aAbstractRange) { +Maybe<bool> RangeUtils::IsNodeContainedInRange( + const nsINode& aNode, const AbstractRange* aAbstractRange) { bool nodeIsBeforeRange{false}; bool nodeIsAfterRange{false}; @@ -199,8 +183,8 @@ Maybe<bool> RangeUtils::IsNodeContainedInRange(nsINode& aNode, // static template <TreeKind aKind, typename Dummy> -nsresult RangeUtils::CompareNodeToRange(nsINode* aNode, - AbstractRange* aAbstractRange, +nsresult RangeUtils::CompareNodeToRange(const nsINode* aNode, + const AbstractRange* aAbstractRange, bool* aNodeIsBeforeRange, bool* aNodeIsAfterRange) { if (NS_WARN_IF(!aAbstractRange) || @@ -212,10 +196,11 @@ nsresult RangeUtils::CompareNodeToRange(nsINode* aNode, aAbstractRange->MayCrossShadowBoundaryEndRef(), aNodeIsBeforeRange, aNodeIsAfterRange); } + template <TreeKind aKind, typename SPT, typename SRT, typename EPT, typename ERT, typename Dummy> nsresult RangeUtils::CompareNodeToRangeBoundaries( - nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary, + const nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary, const RangeBoundaryBase<EPT, ERT>& aEndBoundary, bool* aNodeIsBeforeRange, bool* aNodeIsAfterRange) { MOZ_ASSERT(aNodeIsBeforeRange); diff --git a/dom/base/RangeUtils.h b/dom/base/RangeUtils.h @@ -139,8 +139,8 @@ class RangeUtils final { template <TreeKind aKind = TreeKind::ShadowIncludingDOM, typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM || aKind == TreeKind::Flat>> - static Maybe<bool> IsNodeContainedInRange(nsINode& aNode, - AbstractRange* aAbstractRange); + static Maybe<bool> IsNodeContainedInRange( + const nsINode& aNode, const AbstractRange* aAbstractRange); /** * Utility routine to detect if a content node starts before a range and/or @@ -150,8 +150,8 @@ class RangeUtils final { template <TreeKind aKind = TreeKind::ShadowIncludingDOM, typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM || aKind == TreeKind::Flat>> - static nsresult CompareNodeToRange(nsINode* aNode, - AbstractRange* aAbstractRange, + static nsresult CompareNodeToRange(const nsINode* aNode, + const AbstractRange* aAbstractRange, bool* aNodeIsBeforeRange, bool* aNodeIsAfterRange); @@ -160,7 +160,7 @@ class RangeUtils final { typename = std::enable_if_t<aKind == TreeKind::ShadowIncludingDOM || aKind == TreeKind::Flat>> static nsresult CompareNodeToRangeBoundaries( - nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary, + const nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary, const RangeBoundaryBase<EPT, ERT>& aEndBoundary, bool* aNodeIsBeforeRange, bool* aNodeIsAfterRange); };