Bug 1812170 - Make `HTMLEditor::ClearStyleAt` should return `pointToPutCaret` if next node of first split is not split r=m_kato

The new path added in bug 1807829 hits the odd result case of `ClearStyleAt`.
`pointToPutCaret` may be updated if the preceding split occurs.  Therefore,
it should be returned if it does not split next nodes after the first split
instead of returning unset point (because of not splitting the point,
`unwrappedSplitNodeResult.AtSplitPoint` may return unset point, therefore,
it may return unset point in the case).

Additionally, I forgot to split delete `SplitNodeResult::mCaretPoint` in
bug 1792654, and it causes `SplitNodeDeepWithTransaction` returns unset caret
point.  This patch fixes this bug too.

Differential Revision: https://phabricator.services.mozilla.com/D168179
This commit is contained in:
Masayuki Nakano 2023-02-02 05:09:15 +00:00
Родитель 140235a6f7
Коммит 81fbf55970
4 изменённых файлов: 41 добавлений и 11 удалений

Просмотреть файл

@ -373,7 +373,7 @@ class MOZ_STACK_CLASS SplitNodeResult final : public CaretPoint {
mDirection(aDirection) {}
SplitNodeResult ToHandledResult() const {
mHandledCaretPoint = true;
CaretPointHandled();
SplitNodeResult result(mDirection);
result.mPreviousNode = GetPreviousContent();
result.mNextNode = GetNextContent();
@ -381,7 +381,7 @@ class MOZ_STACK_CLASS SplitNodeResult final : public CaretPoint {
// Don't recompute the caret position because in this case, split has not
// occurred yet. In the case, the caller shouldn't need to update
// selection.
result.mCaretPoint = mCaretPoint;
result.SetCaretPoint(CaretPointRef());
return result;
}
@ -448,7 +448,7 @@ class MOZ_STACK_CLASS SplitNodeResult final : public CaretPoint {
aSplitNodeResult.UnmarkAsHandledCaretPoint();
aDeeperSplitNodeResult.IgnoreCaretPointSuggestion();
if (aSplitNodeResult.DidSplit() ||
!aDeeperSplitNodeResult.mCaretPoint.IsSet()) {
!aDeeperSplitNodeResult.HasCaretPointSuggestion()) {
return std::move(aSplitNodeResult);
}
SplitNodeResult result(std::move(aSplitNodeResult));
@ -495,12 +495,7 @@ class MOZ_STACK_CLASS SplitNodeResult final : public CaretPoint {
// for representing the point.
EditorDOMPoint mGivenSplitPoint;
// The point which is a good point to put caret from point of view the
// splitter.
EditorDOMPoint mCaretPoint;
SplitNodeDirection mDirection;
bool mutable mHandledCaretPoint = false;
};
/*****************************************************************************

Просмотреть файл

@ -6108,6 +6108,7 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::CreateStyleForInsertText(
return pointToPutCaretOrError;
}
pointToPutCaret = pointToPutCaretOrError.unwrap();
MOZ_ASSERT(pointToPutCaret.IsSet());
pendingStyle = mPendingStylesToApplyToNewContent->TakeClearingStyle();
}
}

Просмотреть файл

@ -2373,11 +2373,14 @@ Result<EditorDOMPoint, nsresult> HTMLEditor::ClearStyleAt(
}
}
if (!unwrappedSplitResultAtStartOfNextNode.Handled()) {
return std::move(pointToPutCaret);
}
// If there is no content, we should return here.
// XXX Is this possible case without mutation event listener?
if (NS_WARN_IF(!unwrappedSplitResultAtStartOfNextNode.Handled()) ||
!unwrappedSplitResultAtStartOfNextNode.GetPreviousContent()) {
// XXX This is really odd, but we retrun this value...
if (!unwrappedSplitResultAtStartOfNextNode.GetPreviousContent()) {
// XXX This is really odd, but we return this value...
const auto splitPoint =
unwrappedSplitNodeResult.AtSplitPoint<EditorRawDOMPoint>();
const auto splitPointAtStartOfNextNode =

Просмотреть файл

@ -0,0 +1,31 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
document.addEventListener("DOMContentLoaded", () => {
getSelection().collapse(document.querySelector("code[contenteditable]").firstChild, 0);
window.top.find("A");
document.querySelector("table").insertRow(1);
document.querySelector("table").insertRow(1);
document.execCommand("subscript");
document.execCommand("foreColor", false, "currentColor");
document.execCommand("insertHTML", false, document.querySelector("h5").outerHTML);
document.execCommand("subscript");
document.execCommand("foreColor", false, "currentColor");
document.execCommand("insertHTML", false, document.querySelector("h5").outerHTML);
document.execCommand("insertText", false, "A");
});
</script>
</head>
<body>
<table>
<tr>
<td>
<code contenteditable>
A
<h5>
</h5>
</code>
</body>
</html>