зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1675779 - HandleDeleteAtomicContent should handle non-editable text node. r=masayuki
Since `WSScanResult` can return non-editable/non-removable text node, `HandleDeleteAtomicContent` is called with non editable text node, then it cannot remove atomic content. This fix doesn't follow other block case such as added newer test. Differential Revision: https://phabricator.services.mozilla.com/D96298
This commit is contained in:
Родитель
93b37bfebb
Коммит
6d173e8282
|
@ -257,6 +257,23 @@ class MOZ_STACK_CLASS HTMLEditor::AutoDeleteRangesHandler final {
|
|||
const HTMLEditor& aHTMLEditor, const nsIContent& aAtomicContent,
|
||||
AutoRangeArray& aRangesToDelete) const;
|
||||
|
||||
/**
|
||||
* GetAtomicContnetToDelete() returns better content that is deletion of
|
||||
* atomic element. If aScanFromCaretPointResult is special, since this
|
||||
* point may not be editable, we look for better point to remove atomic
|
||||
* content.
|
||||
*
|
||||
* @param aDirectionAndAmount Direction of the deletion.
|
||||
* @param aWSRunScannerAtCaret WSRunScanner instance which was
|
||||
* initialized with the caret point.
|
||||
* @param aScanFromCaretPointResult Scan result of aWSRunScannerAtCaret
|
||||
* toward aDirectionAndAmount.
|
||||
*/
|
||||
static nsIContent* GetAtomicContentToDelete(
|
||||
nsIEditor::EDirection aDirectionAndAmount,
|
||||
const WSRunScanner& aWSRunScannerAtCaret,
|
||||
const WSScanResult& aScanFromCaretPointResult) MOZ_NONNULL_RETURN;
|
||||
|
||||
/**
|
||||
* HandleDeleteHRElement() handles deletion around `<hr>` element. If
|
||||
* aDirectionAndAmount is nsIEditor::ePrevious, aHTElement is removed only
|
||||
|
@ -1637,8 +1654,16 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAroundCollapsedRanges(
|
|||
aWSRunScannerAtCaret.GetEditingHost()) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsIContent* atomicContent = GetAtomicContentToDelete(
|
||||
aDirectionAndAmount, aWSRunScannerAtCaret, aScanFromCaretPointResult);
|
||||
if (!HTMLEditUtils::IsRemovableNode(*atomicContent)) {
|
||||
NS_WARNING(
|
||||
"AutoDeleteRangesHandler::GetAtomicContentToDelete() cannot find "
|
||||
"removable atomic content");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsresult rv = ComputeRangesToDeleteAtomicContent(
|
||||
aHTMLEditor, *aScanFromCaretPointResult.GetContent(), aRangesToDelete);
|
||||
aHTMLEditor, *atomicContent, aRangesToDelete);
|
||||
NS_WARNING_ASSERTION(
|
||||
NS_SUCCEEDED(rv),
|
||||
"AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent() failed");
|
||||
|
@ -1665,6 +1690,10 @@ HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAroundCollapsedRanges(
|
|||
if (NS_WARN_IF(!aScanFromCaretPointResult.GetContent()->IsElement())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// TODO(m_kato):
|
||||
// When aScanFromCaretPointResult.GetContent isn't editable and is
|
||||
// removable, PrepareToDeleteAtOtherBlockBoundary will return false.
|
||||
// But this should be removed.
|
||||
AutoBlockElementsJoiner joiner(*this);
|
||||
if (!joiner.PrepareToDeleteAtOtherBlockBoundary(
|
||||
aHTMLEditor, aDirectionAndAmount,
|
||||
|
@ -1764,9 +1793,17 @@ HTMLEditor::AutoDeleteRangesHandler::HandleDeleteAroundCollapsedRanges(
|
|||
aWSRunScannerAtCaret.GetEditingHost()) {
|
||||
return EditActionHandled();
|
||||
}
|
||||
nsCOMPtr<nsIContent> atomicContent = GetAtomicContentToDelete(
|
||||
aDirectionAndAmount, aWSRunScannerAtCaret, aScanFromCaretPointResult);
|
||||
if (!HTMLEditUtils::IsRemovableNode(*atomicContent)) {
|
||||
NS_WARNING(
|
||||
"AutoDeleteRangesHandler::GetAtomicContentToDelete() cannot find "
|
||||
"removable atomic content");
|
||||
return EditActionResult(NS_ERROR_FAILURE);
|
||||
}
|
||||
EditActionResult result = HandleDeleteAtomicContent(
|
||||
aHTMLEditor, MOZ_KnownLive(*aScanFromCaretPointResult.GetContent()),
|
||||
aWSRunScannerAtCaret.ScanStartRef(), aWSRunScannerAtCaret);
|
||||
aHTMLEditor, *atomicContent, aWSRunScannerAtCaret.ScanStartRef(),
|
||||
aWSRunScannerAtCaret);
|
||||
NS_WARNING_ASSERTION(
|
||||
result.Succeeded(),
|
||||
"AutoDeleteRangesHandler::HandleDeleteAtomicContent() failed");
|
||||
|
@ -2264,6 +2301,38 @@ EditActionResult HTMLEditor::AutoDeleteRangesHandler::HandleDeleteHRElement(
|
|||
return EditActionHandled(rv);
|
||||
}
|
||||
|
||||
// static
|
||||
nsIContent* HTMLEditor::AutoDeleteRangesHandler::GetAtomicContentToDelete(
|
||||
nsIEditor::EDirection aDirectionAndAmount,
|
||||
const WSRunScanner& aWSRunScannerAtCaret,
|
||||
const WSScanResult& aScanFromCaretPointResult) {
|
||||
MOZ_ASSERT(aScanFromCaretPointResult.GetContent());
|
||||
|
||||
if (!aScanFromCaretPointResult.ReachedSpecialContent()) {
|
||||
return aScanFromCaretPointResult.GetContent();
|
||||
}
|
||||
|
||||
if (!aScanFromCaretPointResult.GetContent()->IsText() ||
|
||||
HTMLEditUtils::IsRemovableNode(*aScanFromCaretPointResult.GetContent())) {
|
||||
return aScanFromCaretPointResult.GetContent();
|
||||
}
|
||||
|
||||
// aScanFromCaretPointResult is non-removable text node.
|
||||
// Since we try removing atomic content, we look for removable node from
|
||||
// scanned point that is non-removable text.
|
||||
nsIContent* removableRoot = aScanFromCaretPointResult.GetContent();
|
||||
while (removableRoot && !HTMLEditUtils::IsRemovableNode(*removableRoot)) {
|
||||
removableRoot = removableRoot->GetParent();
|
||||
}
|
||||
|
||||
if (removableRoot) {
|
||||
return removableRoot;
|
||||
}
|
||||
|
||||
// Not found better content. This content may not be removable.
|
||||
return aScanFromCaretPointResult.GetContent();
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDeleteAtomicContent(
|
||||
const HTMLEditor& aHTMLEditor, const nsIContent& aAtomicContent,
|
||||
|
|
|
@ -697,3 +697,6 @@
|
|||
[[["delete",""\]\] "<div> a[\]bc</div>" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
[[["delete",""\]\] "foo<div contenteditable=false>bar</div>[\]baz" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -506,8 +506,8 @@
|
|||
|
||||
|
||||
[forwarddelete.html?6001-last]
|
||||
max-asserts: 3
|
||||
min-asserts: 3
|
||||
max-asserts: 6
|
||||
min-asserts: 6
|
||||
[[["forwarddelete",""\]\] "<ol><li>foo</ol><p>{}<br></p><ol><li>bar</ol>" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@
|
|||
|
||||
|
||||
[insertparagraph.html?5001-6000]
|
||||
min-asserts: 14 # Retrieving meaningless raw DOM point from WSScannerResult
|
||||
min-asserts: 10 # Retrieving meaningless raw DOM point from WSScannerResult
|
||||
max-asserts: 16 # Only on W-fis on Linux1804-64-qr and on Android, there are 2 additional assertions.
|
||||
[[["defaultparagraphseparator","p"\],["insertparagraph",""\]\] "<ul><li><div>foo[\]</ul>" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
|
|
@ -52,6 +52,3 @@
|
|||
[Backspace at "<div>abc <ul><li>[\] def </li></ul> ghi</div>" - comparing innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
[Backspace at "<p>abc<span contenteditable=\"false\">def</span>[\]ghi</p>"]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -2560,4 +2560,29 @@ var browserTests = [
|
|||
"foo{}bar",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["foo<span contenteditable=false>bar</span>[]baz",
|
||||
[["delete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["foo<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>[]baz",
|
||||
[["delete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["foo<div contenteditable=false>bar</div>[]baz",
|
||||
[["delete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["foo<span contenteditable=false><b>bar</b></span>[]baz",
|
||||
[["delete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["foo<span>bar<span contenteditable=false>baz</span></span>[]qux",
|
||||
[["delete",""]],
|
||||
"foo<span>bar{}</span>qux",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
]
|
||||
|
|
|
@ -2445,4 +2445,29 @@ var browserTests = [
|
|||
"foo{}bar",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["foo[]<span contenteditable=false>bar</span>baz",
|
||||
[["forwarddelete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["foo[]<span contenteditable=false><span>b</span><span>a</span><span>r</span></span>baz",
|
||||
[["forwarddelete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["foo[]<div contenteditable=false>bar</div>baz",
|
||||
[["forwarddelete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["foo[]<span contenteditable=false><b>bar</b></span>baz",
|
||||
[["forwarddelete",""]],
|
||||
"foo{}baz",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["foo<span>bar[]<span contenteditable=false>baz</span></span>qux",
|
||||
[["forwarddelete",""]],
|
||||
"foo<span>bar{}</span>qux",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче