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"
21 class RangeUtils final
{
22 typedef dom::AbstractRange AbstractRange
;
26 * GetRawRangeBoundaryBefore() and GetRawRangeBoundaryAfter() retrieve
27 * RawRangeBoundary which points before or after aNode.
29 static const RawRangeBoundary
GetRawRangeBoundaryAfter(nsINode
* aNode
) {
32 if (NS_WARN_IF(!aNode
->IsContent())) {
33 return RawRangeBoundary();
36 nsINode
* parentNode
= aNode
->GetParentNode();
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.
45 !afterNode
.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets
))) {
46 return RawRangeBoundary();
51 static const RawRangeBoundary
GetRawRangeBoundaryBefore(nsINode
* aNode
) {
54 if (NS_WARN_IF(!aNode
->IsContent())) {
55 return RawRangeBoundary();
58 nsINode
* parentNode
= aNode
->GetParentNode();
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 int32_t indexInParent
= parentNode
->ComputeIndexOf(aNode
);
66 if (NS_WARN_IF(indexInParent
< 0)) {
67 return RawRangeBoundary();
69 return RawRangeBoundary(parentNode
, indexInParent
);
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
);
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() 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
; }
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
);
119 } // namespace mozilla
121 #endif // #ifndef mozilla_RangeUtils_h