diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /dom/base/RangeUtils.h | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/base/RangeUtils.h')
-rw-r--r-- | dom/base/RangeUtils.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/dom/base/RangeUtils.h b/dom/base/RangeUtils.h new file mode 100644 index 0000000000..511f5e5092 --- /dev/null +++ b/dom/base/RangeUtils.h @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_RangeUtils_h +#define mozilla_RangeUtils_h + +#include "mozilla/Maybe.h" +#include "mozilla/RangeBoundary.h" +#include "nsIContent.h" +#include "nsINode.h" + +namespace mozilla { + +namespace dom { +class AbstractRange; +} // namespace dom + +class RangeUtils final { + typedef dom::AbstractRange AbstractRange; + + public: + /** + * GetRawRangeBoundaryBefore() and GetRawRangeBoundaryAfter() retrieve + * RawRangeBoundary which points before or after aNode. + */ + static const RawRangeBoundary GetRawRangeBoundaryAfter(nsINode* aNode) { + MOZ_ASSERT(aNode); + + if (NS_WARN_IF(!aNode->IsContent())) { + return RawRangeBoundary(); + } + + nsINode* parentNode = aNode->GetParentNode(); + if (!parentNode) { + return RawRangeBoundary(); + } + RawRangeBoundary afterNode(parentNode, aNode->AsContent()); + // If aNode isn't in the child nodes of its parent node, we hit this case. + // This may occur when we're called by a mutation observer while aNode is + // removed from the parent node. + if (NS_WARN_IF( + !afterNode.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets))) { + return RawRangeBoundary(); + } + return afterNode; + } + + static const RawRangeBoundary GetRawRangeBoundaryBefore(nsINode* aNode) { + MOZ_ASSERT(aNode); + + if (NS_WARN_IF(!aNode->IsContent())) { + return RawRangeBoundary(); + } + + nsINode* parentNode = aNode->GetParentNode(); + if (!parentNode) { + return RawRangeBoundary(); + } + // If aNode isn't in the child nodes of its parent node, we hit this case. + // This may occur when we're called by a mutation observer while aNode is + // removed from the parent node. + const Maybe<uint32_t> indexInParent = parentNode->ComputeIndexOf(aNode); + if (MOZ_UNLIKELY(NS_WARN_IF(indexInParent.isNothing()))) { + return RawRangeBoundary(); + } + return RawRangeBoundary(parentNode, *indexInParent); + } + + /** + * Compute the root node of aNode for initializing range classes. + * When aNode is in an anonymous subtree, this returns the shadow root or + * binding parent. Otherwise, the root node of the document or document + * fragment. If this returns nullptr, that means aNode can be neither the + * start container nor end container of any range. + */ + static nsINode* ComputeRootNode(nsINode* aNode); + + /** + * XXX nsRange should accept 0 - UINT32_MAX as offset. However, users of + * nsRange treat offset as int32_t. Additionally, some other internal + * APIs like nsINode::ComputeIndexOf_Deprecated() use int32_t. Therefore, + * nsRange should accept only 0 - INT32_MAX as valid offset for now. + */ + static bool IsValidOffset(uint32_t aOffset) { return aOffset <= INT32_MAX; } + + /** + * Return true if aStartContainer/aStartOffset and aEndContainer/aEndOffset + * are valid start and end points for a range. Otherwise, return false. + */ + static bool IsValidPoints(nsINode* aStartContainer, uint32_t aStartOffset, + nsINode* aEndContainer, uint32_t aEndOffset) { + return IsValidPoints(RawRangeBoundary(aStartContainer, aStartOffset), + RawRangeBoundary(aEndContainer, aEndOffset)); + } + template <typename SPT, typename SRT, typename EPT, typename ERT> + static bool IsValidPoints(const RangeBoundaryBase<SPT, SRT>& aStartBoundary, + const RangeBoundaryBase<EPT, ERT>& aEndBoundary); + + /** + * The caller needs to ensure aNode is in the same doc like aAbstractRange. + */ + static Maybe<bool> IsNodeContainedInRange(nsINode& aNode, + AbstractRange* aAbstractRange); + + /** + * Utility routine to detect if a content node starts before a range and/or + * ends after a range. If neither it is contained inside the range. + * Note that callers responsibility to ensure node in same doc as range. + */ + static nsresult CompareNodeToRange(nsINode* aNode, + AbstractRange* aAbstractRange, + bool* aNodeIsBeforeRange, + bool* aNodeIsAfterRange); + + template <typename SPT, typename SRT, typename EPT, typename ERT> + static nsresult CompareNodeToRangeBoundaries( + nsINode* aNode, const RangeBoundaryBase<SPT, SRT>& aStartBoundary, + const RangeBoundaryBase<EPT, ERT>& aEndBoundary, bool* aNodeIsBeforeRange, + bool* aNodeIsAfterRange); +}; + +} // namespace mozilla + +#endif // #ifndef mozilla_RangeUtils_h |