Bug 1990586 - Make WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt track given caret point a=pascalc
It's used as the result in some cases. However, it's not tracked in some cases when touching the DOM. This modifies the API of `AutoTrackDOMPoint` to flush the tracking point but can keep tracking. We should use the new API in every place later. (This manually merges `WhiteSpaceVisibilityKeeper.cpp` because ESR140 still has the pref to take the legacy mode back and that blocks applying the patch cleanly.) Differential Revision: https://phabricator.services.mozilla.com/D270643
This commit is contained in:
committed by
pchevrel@mozilla.com
parent
3c22b4c56f
commit
0c6404cf72
@@ -46,6 +46,7 @@ enum class EditorCommandParamType : uint16_t; // mozilla/EditorCommands.h
|
||||
enum class EditSubAction : int32_t; // mozilla/EditAction.h
|
||||
enum class ParagraphSeparator; // mozilla/HTMLEditor.h
|
||||
enum class SpecifiedStyle : uint8_t; // mozilla/PendingStyles.h
|
||||
enum class StopTracking : bool; // mozilla/SelectionState.h
|
||||
enum class SuggestCaret; // EditorUtils.h
|
||||
enum class WithTransaction; // HTMLEditHelpers.h
|
||||
|
||||
|
||||
@@ -284,6 +284,8 @@ class MOZ_STACK_CLASS RangeUpdater final {
|
||||
bool mLocked;
|
||||
};
|
||||
|
||||
enum class StopTracking : bool { No, Yes };
|
||||
|
||||
/**
|
||||
* Helper class for using SelectionState. Stack based class for doing
|
||||
* preservation of dom points across editor actions.
|
||||
@@ -331,11 +333,13 @@ class MOZ_STACK_CLASS AutoTrackDOMPoint final {
|
||||
|
||||
~AutoTrackDOMPoint() { FlushAndStopTracking(); }
|
||||
|
||||
void FlushAndStopTracking() {
|
||||
void Flush(StopTracking aStopTracking) {
|
||||
if (!mIsTracking) {
|
||||
return;
|
||||
}
|
||||
if (static_cast<bool>(aStopTracking)) {
|
||||
mIsTracking = false;
|
||||
}
|
||||
if (mPoint.isSome()) {
|
||||
mRangeUpdater.DropRangeItem(mRangeItem);
|
||||
// Setting `mPoint` with invalid DOM point causes hitting `NS_ASSERTION()`
|
||||
@@ -378,6 +382,8 @@ class MOZ_STACK_CLASS AutoTrackDOMPoint final {
|
||||
}
|
||||
}
|
||||
|
||||
void FlushAndStopTracking() { Flush(StopTracking::Yes); }
|
||||
|
||||
void StopTracking() { mIsTracking = false; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -3450,6 +3450,11 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
MOZ_ASSERT(
|
||||
StaticPrefs::editor_white_space_normalization_blink_compatible());
|
||||
|
||||
Maybe<AutoTrackDOMPoint> trackPointToPutCaret;
|
||||
if (aCaretPoint.IsSet()) {
|
||||
trackPointToPutCaret.emplace(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToPutCaret);
|
||||
}
|
||||
// If we're removing a block, it may be surrounded by invisible
|
||||
// white-spaces. We should remove them to avoid to make them accidentally
|
||||
// visible.
|
||||
@@ -3459,8 +3464,6 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
AutoTrackDOMPoint trackAtContent(aHTMLEditor.RangeUpdaterRef(),
|
||||
&atContent);
|
||||
{
|
||||
AutoTrackDOMPoint trackPointToPutCaret(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToPutCaret);
|
||||
nsresult rv =
|
||||
WhiteSpaceVisibilityKeeper::EnsureNoInvisibleWhiteSpacesBefore(
|
||||
aHTMLEditor, EditorDOMPoint(aContentToDelete.AsElement()));
|
||||
@@ -3484,6 +3487,9 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
if (NS_WARN_IF(!aContentToDelete.IsInComposedDoc())) {
|
||||
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
|
||||
}
|
||||
if (trackPointToPutCaret.isSome()) {
|
||||
trackPointToPutCaret->Flush(StopTracking::No);
|
||||
}
|
||||
}
|
||||
if (pointToPutCaret.IsInContentNode()) {
|
||||
// Additionally, we may put caret into the preceding block (this is the
|
||||
@@ -3558,7 +3564,7 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
}
|
||||
}
|
||||
}
|
||||
trackAtContent.FlushAndStopTracking();
|
||||
trackAtContent.Flush(StopTracking::Yes);
|
||||
if (NS_WARN_IF(!atContent.IsInContentNodeAndValidInComposedDoc())) {
|
||||
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
|
||||
}
|
||||
@@ -3584,7 +3590,7 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
"failed");
|
||||
return afterLastVisibleThingOrError.propagateErr();
|
||||
}
|
||||
trackAtContent.FlushAndStopTracking();
|
||||
trackAtContent.Flush(StopTracking::Yes);
|
||||
if (NS_WARN_IF(!atContent.IsInContentNodeAndValidInComposedDoc())) {
|
||||
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
|
||||
}
|
||||
@@ -3604,7 +3610,7 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
"WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesBefore() failed");
|
||||
return atFirstVisibleThingOrError.propagateErr();
|
||||
}
|
||||
trackAtContent.FlushAndStopTracking();
|
||||
trackAtContent.Flush(StopTracking::Yes);
|
||||
if (NS_WARN_IF(!atContent.IsInContentNodeAndValidInComposedDoc())) {
|
||||
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
|
||||
}
|
||||
@@ -3616,13 +3622,22 @@ WhiteSpaceVisibilityKeeper::DeleteContentNodeAndJoinTextNodesAroundIt(
|
||||
aContentToDelete, {WalkTreeOption::IgnoreNonEditableNode});
|
||||
// Delete the node, and join like nodes if appropriate
|
||||
{
|
||||
AutoTrackDOMPoint trackPointToPutCaret(aHTMLEditor.RangeUpdaterRef(),
|
||||
Maybe<AutoTrackDOMPoint> trackPointToPutCaret;
|
||||
if (pointToPutCaret.IsSet()) {
|
||||
trackPointToPutCaret.emplace(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToPutCaret);
|
||||
}
|
||||
nsresult rv = aHTMLEditor.DeleteNodeWithTransaction(aContentToDelete);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("EditorBase::DeleteNodeWithTransaction() failed");
|
||||
return Err(rv);
|
||||
}
|
||||
if (trackPointToPutCaret.isSome()) {
|
||||
trackPointToPutCaret->Flush(StopTracking::Yes);
|
||||
if (NS_WARN_IF(!pointToPutCaret.IsInContentNode())) {
|
||||
return Err(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Are they both text nodes? If so, join them!
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
addEventListener("DOMContentLoaded", () => {
|
||||
document.documentElement.contentEditable = "plaintext-only";
|
||||
document.execCommand("delete");
|
||||
}, {once: true});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<track></track>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user