Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / base / RangeUtils.h
blob511f5e5092719eccd00bc02a81847ff4ad0f6053
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_RangeUtils_h
8 #define mozilla_RangeUtils_h
10 #include "mozilla/Maybe.h"
11 #include "mozilla/RangeBoundary.h"
12 #include "nsIContent.h"
13 #include "nsINode.h"
15 namespace mozilla {
17 namespace dom {
18 class AbstractRange;
19 } // namespace dom
21 class RangeUtils final {
22 typedef dom::AbstractRange AbstractRange;
24 public:
25 /**
26 * GetRawRangeBoundaryBefore() and GetRawRangeBoundaryAfter() retrieve
27 * RawRangeBoundary which points before or after aNode.
29 static const RawRangeBoundary GetRawRangeBoundaryAfter(nsINode* aNode) {
30 MOZ_ASSERT(aNode);
32 if (NS_WARN_IF(!aNode->IsContent())) {
33 return RawRangeBoundary();
36 nsINode* parentNode = aNode->GetParentNode();
37 if (!parentNode) {
38 return RawRangeBoundary();
40 RawRangeBoundary afterNode(parentNode, aNode->AsContent());
41 // If aNode isn't in the child nodes of its parent node, we hit this case.
42 // This may occur when we're called by a mutation observer while aNode is
43 // removed from the parent node.
44 if (NS_WARN_IF(
45 !afterNode.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets))) {
46 return RawRangeBoundary();
48 return afterNode;
51 static const RawRangeBoundary GetRawRangeBoundaryBefore(nsINode* aNode) {
52 MOZ_ASSERT(aNode);
54 if (NS_WARN_IF(!aNode->IsContent())) {
55 return RawRangeBoundary();
58 nsINode* parentNode = aNode->GetParentNode();
59 if (!parentNode) {
60 return RawRangeBoundary();
62 // If aNode isn't in the child nodes of its parent node, we hit this case.
63 // This may occur when we're called by a mutation observer while aNode is
64 // removed from the parent node.
65 const Maybe<uint32_t> indexInParent = parentNode->ComputeIndexOf(aNode);
66 if (MOZ_UNLIKELY(NS_WARN_IF(indexInParent.isNothing()))) {
67 return RawRangeBoundary();
69 return RawRangeBoundary(parentNode, *indexInParent);
72 /**
73 * Compute the root node of aNode for initializing range classes.
74 * When aNode is in an anonymous subtree, this returns the shadow root or
75 * binding parent. Otherwise, the root node of the document or document
76 * fragment. If this returns nullptr, that means aNode can be neither the
77 * start container nor end container of any range.
79 static nsINode* ComputeRootNode(nsINode* aNode);
81 /**
82 * XXX nsRange should accept 0 - UINT32_MAX as offset. However, users of
83 * nsRange treat offset as int32_t. Additionally, some other internal
84 * APIs like nsINode::ComputeIndexOf_Deprecated() use int32_t. Therefore,
85 * nsRange should accept only 0 - INT32_MAX as valid offset for now.
87 static bool IsValidOffset(uint32_t aOffset) { return aOffset <= INT32_MAX; }
89 /**
90 * Return true if aStartContainer/aStartOffset and aEndContainer/aEndOffset
91 * are valid start and end points for a range. Otherwise, return false.
93 static bool IsValidPoints(nsINode* aStartContainer, uint32_t aStartOffset,
94 nsINode* aEndContainer, uint32_t aEndOffset) {
95 return IsValidPoints(RawRangeBoundary(aStartContainer, aStartOffset),
96 RawRangeBoundary(aEndContainer, aEndOffset));
98 template <typename SPT, typename SRT, typename EPT, typename ERT>
99 static bool IsValidPoints(const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
100 const RangeBoundaryBase<EPT, ERT>& aEndBoundary);
103 * The caller needs to ensure aNode is in the same doc like aAbstractRange.
105 static Maybe<bool> IsNodeContainedInRange(nsINode& aNode,
106 AbstractRange* aAbstractRange);
109 * Utility routine to detect if a content node starts before a range and/or
110 * ends after a range. If neither it is contained inside the range.
111 * Note that callers responsibility to ensure node in same doc as range.
113 static nsresult CompareNodeToRange(nsINode* aNode,
114 AbstractRange* aAbstractRange,
115 bool* aNodeIsBeforeRange,
116 bool* aNodeIsAfterRange);
118 template <typename SPT, typename SRT, typename EPT, typename ERT>
119 static nsresult CompareNodeToRangeBoundaries(
120 nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
121 const RangeBoundaryBase<EPT, ERT>& aEndBoundary, bool* aNodeIsBeforeRange,
122 bool* aNodeIsAfterRange);
125 } // namespace mozilla
127 #endif // #ifndef mozilla_RangeUtils_h