mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 1726064 - part 13: Make AutoEmptyBlockAncestorDeleter::ScanEmptyBlockInclusiveAncestor()
use HTMLEditUtils::Get(Inclusive)AncestorElement()
r=m_kato
Additionally, the given content may be in a nested editing host. Then, this method may delete a nested-block editing host if it's empty. Therefore, this patch get rid of `aEditingHost` and check same thing with `HTMLEditUtils::IsRemovableFromParentNode()`. Depends on D123066 Differential Revision: https://phabricator.services.mozilla.com/D123067
This commit is contained in:
parent
125fa92a05
commit
368e3f0587
@ -966,11 +966,9 @@ class MOZ_STACK_CLASS HTMLEditor::AutoDeleteRangesHandler final {
|
||||
*
|
||||
* @param aHTMLEditor The HTMLEditor.
|
||||
* @param aStartContent Start content to look for empty ancestors.
|
||||
* @param aEditingHostElement Current editing host.
|
||||
*/
|
||||
[[nodiscard]] Element* ScanEmptyBlockInclusiveAncestor(
|
||||
const HTMLEditor& aHTMLEditor, nsIContent& aStartContent,
|
||||
Element& aEditingHostElement);
|
||||
const HTMLEditor& aHTMLEditor, nsIContent& aStartContent);
|
||||
|
||||
/**
|
||||
* ComputeTargetRanges() computes "target ranges" for deleting
|
||||
@ -1184,7 +1182,7 @@ nsresult HTMLEditor::AutoDeleteRangesHandler::ComputeRangesToDelete(
|
||||
if (startPoint.GetContainerAsContent()) {
|
||||
AutoEmptyBlockAncestorDeleter deleter;
|
||||
if (deleter.ScanEmptyBlockInclusiveAncestor(
|
||||
aHTMLEditor, *startPoint.GetContainerAsContent(), *editingHost)) {
|
||||
aHTMLEditor, *startPoint.GetContainerAsContent())) {
|
||||
nsresult rv = deleter.ComputeTargetRanges(
|
||||
aHTMLEditor, aDirectionAndAmount, *editingHost, aRangesToDelete);
|
||||
NS_WARNING_ASSERTION(
|
||||
@ -1432,7 +1430,7 @@ EditActionResult HTMLEditor::AutoDeleteRangesHandler::Run(
|
||||
#endif // #ifdef DEBUG
|
||||
AutoEmptyBlockAncestorDeleter deleter;
|
||||
if (deleter.ScanEmptyBlockInclusiveAncestor(
|
||||
aHTMLEditor, *startPoint.GetContainerAsContent(), *editingHost)) {
|
||||
aHTMLEditor, *startPoint.GetContainerAsContent())) {
|
||||
EditActionResult result = deleter.Run(aHTMLEditor, aDirectionAndAmount);
|
||||
if (result.Failed() || result.Handled()) {
|
||||
NS_WARNING_ASSERTION(result.Succeeded(),
|
||||
@ -5029,28 +5027,29 @@ nsresult HTMLEditor::DeleteMostAncestorMailCiteElementIfEmpty(
|
||||
|
||||
Element* HTMLEditor::AutoDeleteRangesHandler::AutoEmptyBlockAncestorDeleter::
|
||||
ScanEmptyBlockInclusiveAncestor(const HTMLEditor& aHTMLEditor,
|
||||
nsIContent& aStartContent,
|
||||
Element& aEditingHostElement) {
|
||||
nsIContent& aStartContent) {
|
||||
MOZ_ASSERT(aHTMLEditor.IsEditActionDataAvailable());
|
||||
|
||||
// If the editing host is an inline element, bail out early.
|
||||
if (HTMLEditUtils::IsInlineElement(aEditingHostElement)) {
|
||||
// If we are inside an empty block, delete it.
|
||||
// Note: do NOT delete table elements this way.
|
||||
// Note: do NOT delete non-editable block element.
|
||||
Element* editableBlockElement = HTMLEditUtils::GetInclusiveAncestorElement(
|
||||
aStartContent, HTMLEditUtils::ClosestEditableBlockElement);
|
||||
if (!editableBlockElement) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If we are inside an empty block, delete it. Note: do NOT delete table
|
||||
// elements this way.
|
||||
Element* blockElement =
|
||||
HTMLEditUtils::GetInclusiveAncestorBlockElement(aStartContent);
|
||||
if (!blockElement) {
|
||||
return nullptr;
|
||||
}
|
||||
while (blockElement && blockElement != &aEditingHostElement &&
|
||||
!HTMLEditUtils::IsAnyTableElement(blockElement) &&
|
||||
HTMLEditUtils::IsEmptyNode(*blockElement)) {
|
||||
mEmptyInclusiveAncestorBlockElement = blockElement;
|
||||
blockElement = HTMLEditUtils::GetAncestorBlockElement(
|
||||
*mEmptyInclusiveAncestorBlockElement);
|
||||
// XXX Perhaps, this is slow loop. If empty blocks are nested, then,
|
||||
// each block checks whether it's empty or not. However, descendant
|
||||
// blocks are checked again and again by IsEmptyNode(). Perhaps, it
|
||||
// should be able to take "known empty element" for avoiding same checks.
|
||||
while (editableBlockElement &&
|
||||
HTMLEditUtils::IsRemovableFromParentNode(*editableBlockElement) &&
|
||||
!HTMLEditUtils::IsAnyTableElement(editableBlockElement) &&
|
||||
HTMLEditUtils::IsEmptyNode(*editableBlockElement)) {
|
||||
mEmptyInclusiveAncestorBlockElement = editableBlockElement;
|
||||
editableBlockElement = HTMLEditUtils::GetAncestorElement(
|
||||
*mEmptyInclusiveAncestorBlockElement,
|
||||
HTMLEditUtils::ClosestEditableBlockElement);
|
||||
}
|
||||
if (!mEmptyInclusiveAncestorBlockElement) {
|
||||
return nullptr;
|
||||
|
@ -622,3 +622,6 @@
|
||||
[[["forwarddelete",""\]\] "<p><span>[abc\]</span></p>" compare innerHTML]
|
||||
expected: FAIL
|
||||
|
||||
[[["forwarddelete",""\]\] "<div><div contenteditable=false><span contenteditable>{}<br></span></div></div>": execCommand("forwarddelete", false, "") return value]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -2616,4 +2616,21 @@ var browserTests = [
|
||||
"<p contenteditable=\"false\"><span contenteditable=\"true\"></span></p>",
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["<div><div>{}<br></div></div>",
|
||||
[["delete",""]],
|
||||
["", "<br>"],
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["<div><div contenteditable=false><div contenteditable><div>{}<br></div></div></div></div>",
|
||||
[["delete",""]],
|
||||
["<div><div contenteditable=\"false\"><div contenteditable=\"\"></div></div></div>",
|
||||
"<div><div contenteditable=\"false\"><div contenteditable=\"\"><br></div></div></div>"],
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
["<div><div contenteditable=false><span contenteditable>{}<br></span></div></div></div>",
|
||||
[["delete",""]],
|
||||
["<div><div contenteditable=\"false\"><span contenteditable=\"\"></span></div></div>",
|
||||
"<div><div contenteditable=\"false\"><span contenteditable=\"\"><br></span></div></div>"],
|
||||
[true],
|
||||
{"delete":[false,false,"",false,false,""]}],
|
||||
]
|
||||
|
@ -2501,4 +2501,21 @@ var browserTests = [
|
||||
"<p contenteditable=\"false\"><span contenteditable=\"true\"></span></p>",
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["<div><div>{}<br></div></div>",
|
||||
[["forwarddelete",""]],
|
||||
["", "<br>"],
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["<div><div contenteditable=false><div contenteditable><div>{}<br></div></div></div></div>",
|
||||
[["forwarddelete",""]],
|
||||
["<div><div contenteditable=\"false\"><div contenteditable=\"\"></div></div></div>",
|
||||
"<div><div contenteditable=\"false\"><div contenteditable=\"\"><br></div></div></div>"],
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
["<div><div contenteditable=false><span contenteditable>{}<br></span></div></div>",
|
||||
[["forwarddelete",""]],
|
||||
["<div><div contenteditable=\"false\"><span contenteditable=\"\"></span></div></div>",
|
||||
"<div><div contenteditable=\"false\"><span contenteditable=\"\"><br></span></div></div>"],
|
||||
[true],
|
||||
{"forwarddelete":[false,false,"",false,false,""]}],
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user