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:
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);
};