Bug 1600267: part 9) Call ComparePoints instead of ComparePoints_Deprecated in parts of nsRange. r=smaug

The remaining callers of `ComparePoints_Deprecated` in `nsRange`
presumably require changing the semantics of `ComparePoints` to support
comparison across Shadow DOM boundary.

Differential Revision: https://phabricator.services.mozilla.com/D57959

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mirko Brodesser 2020-01-06 14:35:27 +00:00
parent 75f5cd0cef
commit 67d6b2b072

View File

@ -11,6 +11,7 @@
#include "nscore.h"
#include "nsRange.h"
#include "nsDebug.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsIContent.h"
@ -873,11 +874,18 @@ int16_t nsRange::ComparePoint(nsINode& aContainer, uint32_t aOffset,
MOZ_ASSERT(point.IsSetAndValid());
const int32_t cmp = nsContentUtils::ComparePoints_Deprecated(point, mStart);
if (cmp <= 0) {
return cmp;
Maybe<int32_t> order = nsContentUtils::ComparePoints(point, mStart);
// `order` must contain a value, because `IsPointComparableToRange()` was
// checked above.
if (*order <= 0) {
return *order;
}
if (nsContentUtils::ComparePoints_Deprecated(mEnd, point) == -1) {
order = nsContentUtils::ComparePoints(mEnd, point);
// `order` must contain a value, because `IsPointComparableToRange()` was
// checked above.
if (*order == -1) {
return 1;
}
@ -890,34 +898,26 @@ bool nsRange::IntersectsNode(nsINode& aNode, ErrorResult& aRv) {
return false;
}
// Step 3.
nsINode* parent = aNode.GetParentNode();
if (!parent) {
// Steps 2 and 4.
// |parent| is null, so |node|'s root is |node| itself.
return GetRoot() == &aNode;
}
// Step 5.
int32_t nodeIndex = parent->ComputeIndexOf(&aNode);
const int32_t nodeIndex = parent->ComputeIndexOf(&aNode);
// Steps 6-7.
// Note: if disconnected is true, ComparePoints returns 1.
bool disconnected = false;
bool result = nsContentUtils::ComparePoints_Deprecated(
mStart.Container(),
*mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
parent, nodeIndex + 1, &disconnected) < 0 &&
nsContentUtils::ComparePoints_Deprecated(
parent, nodeIndex, mEnd.Container(),
*mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
&disconnected) < 0;
// Step 2.
if (disconnected) {
result = false;
const Maybe<int32_t> startOrder = nsContentUtils::ComparePoints(
mStart.Container(),
*mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets), parent,
nodeIndex + 1);
if (startOrder && (*startOrder < 0)) {
const Maybe<int32_t> endOrder = nsContentUtils::ComparePoints(
parent, nodeIndex, mEnd.Container(),
*mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets));
return endOrder && (*endOrder < 0);
}
return result;
return false;
}
void nsRange::NotifySelectionListenersAfterRangeSet() {
@ -1122,8 +1122,21 @@ void nsRange::SetStart(const RawRangeBoundary& aPoint, ErrorResult& aRv) {
// Collapse if not positioned yet, if positioned in another doc or
// if the new start is after end.
if (!mIsPositioned || newRoot != mRoot ||
nsContentUtils::ComparePoints_Deprecated(aPoint, mEnd) == 1) {
const bool collapse = [&]() {
if (!mIsPositioned || (newRoot != mRoot)) {
return true;
}
const Maybe<int32_t> order = nsContentUtils::ComparePoints(aPoint, mEnd);
if (order) {
return *order == 1;
}
MOZ_ASSERT_UNREACHABLE();
return true;
}();
if (collapse) {
DoSetRange(aPoint, aPoint, newRoot);
return;
}
@ -1198,8 +1211,21 @@ void nsRange::SetEnd(const RawRangeBoundary& aPoint, ErrorResult& aRv) {
// Collapse if not positioned yet, if positioned in another doc or
// if the new end is before start.
if (!mIsPositioned || newRoot != mRoot ||
nsContentUtils::ComparePoints_Deprecated(mStart, aPoint) == 1) {
const bool collapse = [&]() {
if (!mIsPositioned || (newRoot != mRoot)) {
return true;
}
const Maybe<int32_t> order = nsContentUtils::ComparePoints(mStart, aPoint);
if (order) {
return *order == 1;
}
MOZ_ASSERT_UNREACHABLE();
return true;
}();
if (collapse) {
DoSetRange(aPoint, aPoint, newRoot);
return;
}
@ -1684,11 +1710,12 @@ nsresult nsRange::CutContents(DocumentFragment** aFragment) {
// of Range gravity during our edits!
nsCOMPtr<nsINode> startContainer = mStart.Container();
// `GetCommonAncestorContainer()` above ensures the range is positioned, hence
// there have to be valid offsets.
uint32_t startOffset =
*mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
*mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
nsCOMPtr<nsINode> endContainer = mEnd.Container();
uint32_t endOffset =
*mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
uint32_t endOffset = *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
if (retval) {
// For extractContents(), abort early if there's a doctype (bug 719533).
@ -1699,12 +1726,16 @@ nsresult nsRange::CutContents(DocumentFragment** aFragment) {
if (commonAncestorDocument) {
RefPtr<DocumentType> doctype = commonAncestorDocument->GetDoctype();
// `GetCommonAncestorContainer()` above ensured the range is positioned.
// Hence, start and end are both set and valid. If available, `doctype`
// has a common ancestor with start and end, hence both have to be
// comparable to it.
if (doctype &&
nsContentUtils::ComparePoints_Deprecated(
startContainer, static_cast<int32_t>(startOffset), doctype, 0) <
0 &&
nsContentUtils::ComparePoints_Deprecated(
doctype, 0, endContainer, static_cast<int32_t>(endOffset)) < 0) {
*nsContentUtils::ComparePoints(startContainer,
static_cast<int32_t>(startOffset),
doctype, 0) < 0 &&
*nsContentUtils::ComparePoints(doctype, 0, endContainer,
static_cast<int32_t>(endOffset)) < 0) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
}
@ -2020,9 +2051,14 @@ int16_t nsRange::CompareBoundaryPoints(uint16_t aHow, nsRange& aOtherRange,
return 0;
}
return nsContentUtils::ComparePoints_Deprecated(
const Maybe<int32_t> order = nsContentUtils::ComparePoints(
ourNode, static_cast<int32_t>(ourOffset), otherNode,
static_cast<int32_t>(otherOffset));
// `this` and `aOtherRange` share the same root and (ourNode, ourOffset),
// (otherNode, otherOffset) correspond to some of their boundaries. Hence,
// (ourNode, ourOffset) and (otherNode, otherOffset) have to be comparable.
return *order;
}
/* static */