forked from mirrors/gecko-dev
Bug 1818339 - Make AutoRangeArray set mAnchorFocusRange correctly r=m_kato
There are some paths which do not set `mAnchorFocusRange` correctly. Therefore, even if its `RangeCount()` returns 1 or larger, `GetAnchorFocusRange()` may return `nullptr`. Differential Revision: https://phabricator.services.mozilla.com/D171045
This commit is contained in:
parent
3d617b7f9e
commit
31b7027bb9
2 changed files with 51 additions and 13 deletions
|
|
@ -50,6 +50,7 @@ AutoRangeArray::AutoRangeArray(const AutoRangeArray& aOther)
|
||||||
RefPtr<nsRange> clonedRange = range->CloneRange();
|
RefPtr<nsRange> clonedRange = range->CloneRange();
|
||||||
mRanges.AppendElement(std::move(clonedRange));
|
mRanges.AppendElement(std::move(clonedRange));
|
||||||
}
|
}
|
||||||
|
mAnchorFocusRange = aOther.mAnchorFocusRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename PointType>
|
template <typename PointType>
|
||||||
|
|
@ -59,7 +60,8 @@ AutoRangeArray::AutoRangeArray(const EditorDOMRangeBase<PointType>& aRange) {
|
||||||
if (NS_WARN_IF(!range) || NS_WARN_IF(!range->IsPositioned())) {
|
if (NS_WARN_IF(!range) || NS_WARN_IF(!range->IsPositioned())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mRanges.AppendElement(std::move(range));
|
mRanges.AppendElement(*range);
|
||||||
|
mAnchorFocusRange = std::move(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename PT, typename CT>
|
template <typename PT, typename CT>
|
||||||
|
|
@ -69,7 +71,8 @@ AutoRangeArray::AutoRangeArray(const EditorDOMPointBase<PT, CT>& aPoint) {
|
||||||
if (NS_WARN_IF(!range) || NS_WARN_IF(!range->IsPositioned())) {
|
if (NS_WARN_IF(!range) || NS_WARN_IF(!range->IsPositioned())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mRanges.AppendElement(std::move(range));
|
mRanges.AppendElement(*range);
|
||||||
|
mAnchorFocusRange = std::move(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoRangeArray::~AutoRangeArray() {
|
AutoRangeArray::~AutoRangeArray() {
|
||||||
|
|
@ -843,6 +846,13 @@ void AutoRangeArray::ExtendRangesToWrapLinesToHandleBlockLevelEditAction(
|
||||||
mRanges.RemoveElementAt(i);
|
mRanges.RemoveElementAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!mAnchorFocusRange || !mAnchorFocusRange->IsPositioned()) {
|
||||||
|
if (mRanges.IsEmpty()) {
|
||||||
|
mAnchorFocusRange = nullptr;
|
||||||
|
} else {
|
||||||
|
mAnchorFocusRange = mRanges.LastElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -951,17 +961,22 @@ AutoRangeArray::SplitTextAtEndBoundariesAndInlineAncestorsAtBothBoundaries(
|
||||||
|
|
||||||
// FYI: The following code is originated in
|
// FYI: The following code is originated in
|
||||||
// https://searchfox.org/mozilla-central/rev/c8e15e17bc6fd28f558c395c948a6251b38774ff/editor/libeditor/HTMLEditSubActionHandler.cpp#7023
|
// https://searchfox.org/mozilla-central/rev/c8e15e17bc6fd28f558c395c948a6251b38774ff/editor/libeditor/HTMLEditSubActionHandler.cpp#7023
|
||||||
nsTArray<OwningNonNull<RangeItem>> rangeItemArray;
|
AutoTArray<OwningNonNull<RangeItem>, 8> rangeItemArray;
|
||||||
rangeItemArray.AppendElements(mRanges.Length());
|
rangeItemArray.AppendElements(mRanges.Length());
|
||||||
|
|
||||||
// First register ranges for special editor gravity
|
// First register ranges for special editor gravity
|
||||||
for (OwningNonNull<RangeItem>& rangeItem : rangeItemArray) {
|
Maybe<size_t> anchorFocusRangeIndex;
|
||||||
rangeItem = new RangeItem();
|
for (size_t index : IntegerRange(rangeItemArray.Length())) {
|
||||||
rangeItem->StoreRange(*mRanges[0]);
|
rangeItemArray[index] = new RangeItem();
|
||||||
aHTMLEditor.RangeUpdaterRef().RegisterRangeItem(*rangeItem);
|
rangeItemArray[index]->StoreRange(*mRanges[index]);
|
||||||
// TODO: We should keep the array, and just update the ranges.
|
aHTMLEditor.RangeUpdaterRef().RegisterRangeItem(*rangeItemArray[index]);
|
||||||
mRanges.RemoveElementAt(0);
|
if (mRanges[index] == mAnchorFocusRange) {
|
||||||
|
anchorFocusRangeIndex = Some(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: We should keep the array, and just update the ranges.
|
||||||
|
mRanges.Clear();
|
||||||
|
mAnchorFocusRange = nullptr;
|
||||||
// Now bust up inlines.
|
// Now bust up inlines.
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
for (OwningNonNull<RangeItem>& item : Reversed(rangeItemArray)) {
|
for (OwningNonNull<RangeItem>& item : Reversed(rangeItemArray)) {
|
||||||
|
|
@ -980,13 +995,19 @@ AutoRangeArray::SplitTextAtEndBoundariesAndInlineAncestorsAtBothBoundaries(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Then unregister the ranges
|
// Then unregister the ranges
|
||||||
for (OwningNonNull<RangeItem>& item : rangeItemArray) {
|
for (size_t index : IntegerRange(rangeItemArray.Length())) {
|
||||||
aHTMLEditor.RangeUpdaterRef().DropRangeItem(item);
|
aHTMLEditor.RangeUpdaterRef().DropRangeItem(rangeItemArray[index]);
|
||||||
RefPtr<nsRange> range = item->GetRange();
|
RefPtr<nsRange> range = rangeItemArray[index]->GetRange();
|
||||||
if (range) {
|
if (range && range->IsPositioned()) {
|
||||||
|
if (anchorFocusRangeIndex.isSome() && index == *anchorFocusRangeIndex) {
|
||||||
|
mAnchorFocusRange = range;
|
||||||
|
}
|
||||||
mRanges.AppendElement(std::move(range));
|
mRanges.AppendElement(std::move(range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!mAnchorFocusRange && !mRanges.IsEmpty()) {
|
||||||
|
mAnchorFocusRange = mRanges.LastElement();
|
||||||
|
}
|
||||||
|
|
||||||
// XXX Why do we ignore the other errors here??
|
// XXX Why do we ignore the other errors here??
|
||||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script>
|
||||||
|
addEventListener("load", () => {
|
||||||
|
const dialog = document.querySelector("dialog");
|
||||||
|
dialog.showModal();
|
||||||
|
dialog.close();
|
||||||
|
document.execCommand("justifyLeft");
|
||||||
|
document.execCommand("delete");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body><dialog contenteditable>
|
||||||
|
</dialog></body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in a new issue