Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / base / RangeUtils.h
blob65efc697e0a2fb59ca468ae68cf7788da31060df
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;
20 /**
21 * ShadowDOMSelectionHelpers contains the static methods to help extra values
22 * based on whether or not the iterator allows to iterate nodes cross the shadow
23 * boundary.
25 struct ShadowDOMSelectionHelpers {
26 ShadowDOMSelectionHelpers() = delete;
28 static nsINode* GetStartContainer(const AbstractRange* aRange,
29 bool aAllowCrossShadowBoundary);
31 static uint32_t StartOffset(const AbstractRange* aRange,
32 bool aAllowCrossShadowBoundary);
34 static nsINode* GetEndContainer(const AbstractRange* aRange,
35 bool aAllowCrossShadowBoundary);
37 static uint32_t EndOffset(const AbstractRange* aRange,
38 bool aAllowCrossShadowBoundary);
40 static nsINode* GetParentNode(nsINode& aNode, bool aAllowCrossShadowBoundary);
42 static ShadowRoot* GetShadowRoot(const nsINode* aNode,
43 bool aAllowCrossShadowBoundary);
45 } // namespace dom
47 class RangeUtils final {
48 typedef dom::AbstractRange AbstractRange;
50 public:
51 /**
52 * GetRawRangeBoundaryBefore() and GetRawRangeBoundaryAfter() retrieve
53 * RawRangeBoundary which points before or after aNode.
55 static const RawRangeBoundary GetRawRangeBoundaryAfter(nsINode* aNode) {
56 MOZ_ASSERT(aNode);
58 if (NS_WARN_IF(!aNode->IsContent())) {
59 return RawRangeBoundary();
62 nsINode* parentNode = aNode->GetParentNode();
63 if (!parentNode) {
64 return RawRangeBoundary();
66 RawRangeBoundary afterNode(parentNode, aNode->AsContent());
67 // If aNode isn't in the child nodes of its parent node, we hit this case.
68 // This may occur when we're called by a mutation observer while aNode is
69 // removed from the parent node.
70 if (NS_WARN_IF(
71 !afterNode.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets))) {
72 return RawRangeBoundary();
74 return afterNode;
77 static const RawRangeBoundary GetRawRangeBoundaryBefore(nsINode* aNode) {
78 MOZ_ASSERT(aNode);
80 if (NS_WARN_IF(!aNode->IsContent())) {
81 return RawRangeBoundary();
84 nsINode* parentNode = aNode->GetParentNode();
85 if (!parentNode) {
86 return RawRangeBoundary();
88 // If aNode isn't in the child nodes of its parent node, we hit this case.
89 // This may occur when we're called by a mutation observer while aNode is
90 // removed from the parent node.
91 const Maybe<uint32_t> indexInParent = parentNode->ComputeIndexOf(aNode);
92 if (MOZ_UNLIKELY(NS_WARN_IF(indexInParent.isNothing()))) {
93 return RawRangeBoundary();
95 return RawRangeBoundary(parentNode, *indexInParent);
98 /**
99 * Compute the root node of aNode for initializing range classes.
100 * When aNode is in an anonymous subtree, this returns the shadow root or
101 * binding parent. Otherwise, the root node of the document or document
102 * fragment. If this returns nullptr, that means aNode can be neither the
103 * start container nor end container of any range.
105 static nsINode* ComputeRootNode(nsINode* aNode);
108 * XXX nsRange should accept 0 - UINT32_MAX as offset. However, users of
109 * nsRange treat offset as int32_t. Additionally, some other internal
110 * APIs like nsINode::ComputeIndexOf_Deprecated() use int32_t. Therefore,
111 * nsRange should accept only 0 - INT32_MAX as valid offset for now.
113 static bool IsValidOffset(uint32_t aOffset) { return aOffset <= INT32_MAX; }
116 * Return true if aStartContainer/aStartOffset and aEndContainer/aEndOffset
117 * are valid start and end points for a range. Otherwise, return false.
119 static bool IsValidPoints(nsINode* aStartContainer, uint32_t aStartOffset,
120 nsINode* aEndContainer, uint32_t aEndOffset) {
121 return IsValidPoints(RawRangeBoundary(aStartContainer, aStartOffset),
122 RawRangeBoundary(aEndContainer, aEndOffset));
124 template <typename SPT, typename SRT, typename EPT, typename ERT>
125 static bool IsValidPoints(const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
126 const RangeBoundaryBase<EPT, ERT>& aEndBoundary);
129 * The caller needs to ensure aNode is in the same doc like aAbstractRange.
131 static Maybe<bool> IsNodeContainedInRange(nsINode& aNode,
132 AbstractRange* aAbstractRange);
135 * Utility routine to detect if a content node starts before a range and/or
136 * ends after a range. If neither it is contained inside the range.
137 * Note that callers responsibility to ensure node in same doc as range.
139 static nsresult CompareNodeToRange(nsINode* aNode,
140 AbstractRange* aAbstractRange,
141 bool* aNodeIsBeforeRange,
142 bool* aNodeIsAfterRange);
144 template <typename SPT, typename SRT, typename EPT, typename ERT>
145 static nsresult CompareNodeToRangeBoundaries(
146 nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
147 const RangeBoundaryBase<EPT, ERT>& aEndBoundary, bool* aNodeIsBeforeRange,
148 bool* aNodeIsAfterRange);
151 } // namespace mozilla
153 #endif // #ifndef mozilla_RangeUtils_h