mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-31 19:10:36 +00:00
Bug 1753786 - Make nsRange::ExcludeNonSelectableNodes
stop using ErrorResult
r=mbrodesser
It never returns error since its return type is `void` and it does not take out param whose type is `ErrorResult`. Therefore, `ErrorResult` in it is used only for checking whether an error occurs in the calling methods, but neither `SuppressException()` nor `StealNSResult()` is called for avoiding assertions at destructing the instance. For avoiding the assertion, and in this case, it should not use `ErrorResult`. When the result is completely ignored, `IgnoreErrors()` should be used instead. Otherwise, when it just needs to know whether an API call failed or not, it should use `IgnoreErrors` to avoid the redundant calls of `ErrorResult` and for the performance (`ErrorResult`'s destruction may appear in the profile if it's used in a hot path). Differential Revision: https://phabricator.services.mozilla.com/D138231
This commit is contained in:
parent
19da6bccd0
commit
c9bf3f5dee
@ -2985,7 +2985,6 @@ void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
|
||||
// the outer loop.
|
||||
nsIContent* firstNonSelectableContent = nullptr;
|
||||
while (true) {
|
||||
ErrorResult err;
|
||||
nsINode* node = preOrderIter.GetCurrentNode();
|
||||
preOrderIter.Next();
|
||||
bool selectable = true;
|
||||
@ -3013,63 +3012,71 @@ void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
|
||||
if (!firstNonSelectableContent) {
|
||||
firstNonSelectableContent = content;
|
||||
}
|
||||
if (preOrderIter.IsDone() && seenSelectable) {
|
||||
// The tail end of the initial range is non-selectable - truncate the
|
||||
// current range before the first non-selectable node.
|
||||
range->SetEndBefore(*firstNonSelectableContent, err);
|
||||
if (preOrderIter.IsDone()) {
|
||||
if (seenSelectable) {
|
||||
// The tail end of the initial range is non-selectable - truncate
|
||||
// the current range before the first non-selectable node.
|
||||
range->SetEndBefore(*firstNonSelectableContent, IgnoreErrors());
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (firstNonSelectableContent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (firstNonSelectableContent) {
|
||||
if (range == this && !seenSelectable) {
|
||||
// This is the initial range and all its nodes until now are
|
||||
// non-selectable so just trim them from the start.
|
||||
IgnoredErrorResult err;
|
||||
range->SetStartBefore(*node, err);
|
||||
if (err.Failed()) {
|
||||
return;
|
||||
}
|
||||
break; // restart the same range with a new iterator
|
||||
} else {
|
||||
// Save the end point before truncating the range.
|
||||
nsINode* endContainer = range->mEnd.Container();
|
||||
const uint32_t endOffset =
|
||||
*range->mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
|
||||
|
||||
// Truncate the current range before the first non-selectable node.
|
||||
range->SetEndBefore(*firstNonSelectableContent, err);
|
||||
|
||||
// Store it in the result (strong ref) - do this before creating
|
||||
// a new range in |newRange| below so we don't drop the last ref
|
||||
// to the range created in the previous iteration.
|
||||
if (!added && !err.Failed()) {
|
||||
aOutRanges->AppendElement(range);
|
||||
}
|
||||
|
||||
// Create a new range for the remainder.
|
||||
nsINode* startContainer = node;
|
||||
Maybe<uint32_t> startOffset = Some(0);
|
||||
// Don't start *inside* a node with independent selection though
|
||||
// (e.g. <input>).
|
||||
if (content && content->HasIndependentSelection()) {
|
||||
nsINode* parent = startContainer->GetParent();
|
||||
if (parent) {
|
||||
startOffset = parent->ComputeIndexOf(startContainer);
|
||||
startContainer = parent;
|
||||
}
|
||||
}
|
||||
newRange =
|
||||
nsRange::Create(startContainer, startOffset.valueOr(UINT32_MAX),
|
||||
endContainer, endOffset, IgnoreErrors());
|
||||
if (!newRange || newRange->Collapsed()) {
|
||||
newRange = nullptr;
|
||||
}
|
||||
range = newRange;
|
||||
break; // create a new iterator for the new range, if any
|
||||
}
|
||||
} else {
|
||||
seenSelectable = true;
|
||||
if (!added) {
|
||||
added = true;
|
||||
|
||||
// Save the end point before truncating the range.
|
||||
nsINode* endContainer = range->mEnd.Container();
|
||||
const uint32_t endOffset =
|
||||
*range->mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
|
||||
|
||||
// Truncate the current range before the first non-selectable node.
|
||||
IgnoredErrorResult err;
|
||||
range->SetEndBefore(*firstNonSelectableContent, err);
|
||||
|
||||
// Store it in the result (strong ref) - do this before creating
|
||||
// a new range in |newRange| below so we don't drop the last ref
|
||||
// to the range created in the previous iteration.
|
||||
if (!added && !err.Failed()) {
|
||||
aOutRanges->AppendElement(range);
|
||||
}
|
||||
|
||||
// Create a new range for the remainder.
|
||||
nsINode* startContainer = node;
|
||||
Maybe<uint32_t> startOffset = Some(0);
|
||||
// Don't start *inside* a node with independent selection though
|
||||
// (e.g. <input>).
|
||||
if (content && content->HasIndependentSelection()) {
|
||||
nsINode* parent = startContainer->GetParent();
|
||||
if (parent) {
|
||||
startOffset = parent->ComputeIndexOf(startContainer);
|
||||
startContainer = parent;
|
||||
}
|
||||
}
|
||||
newRange =
|
||||
nsRange::Create(startContainer, startOffset.valueOr(UINT32_MAX),
|
||||
endContainer, endOffset, IgnoreErrors());
|
||||
if (!newRange || newRange->Collapsed()) {
|
||||
newRange = nullptr;
|
||||
}
|
||||
range = newRange;
|
||||
break; // create a new iterator for the new range, if any
|
||||
}
|
||||
|
||||
seenSelectable = true;
|
||||
if (!added) {
|
||||
added = true;
|
||||
aOutRanges->AppendElement(range);
|
||||
}
|
||||
if (preOrderIter.IsDone()) {
|
||||
return;
|
||||
|
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
onload = () => {
|
||||
document.querySelector("canvas[contenteditable]").blur();
|
||||
document.execCommand("selectAll", false);
|
||||
getSelection().modify("move", "forward", "lineboundary");
|
||||
document.execCommand("selectAll", false);
|
||||
};
|
||||
</script>
|
||||
<canvas contenteditable="true">
|
||||
<audio controls>
|
Loading…
x
Reference in New Issue
Block a user