Bug 1663797 - Make delete handler of `HTMLEditor` not try to join `<html>`, `<head>` and `<body>` r=m_kato

It'll fail to join them when its utility methods actually join them.
However, it should be considered earlier timing because the preparation
DOM tree changes before joining them causes creating odd tree (see the
removed cases of the test).  Therefore, we should make them stop handling
deletion before modifying the DOM tree.

Depends on D89579

Differential Revision: https://phabricator.services.mozilla.com/D89580
This commit is contained in:
Masayuki Nakano 2020-09-15 07:33:58 +00:00
Родитель ec6be89428
Коммит d060d644d6
2 изменённых файлов: 21 добавлений и 19 удалений

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

@ -4459,6 +4459,12 @@ bool HTMLEditor::AutoDeleteRangesHandler::AutoBlockElementsJoiner::
// adjacent block
mMode = Mode::JoinCurrentBlock;
// Don't break the basic structure of the HTML document.
if (aCurrentBlockElement.IsAnyOfHTMLElements(nsGkAtoms::html, nsGkAtoms::head,
nsGkAtoms::body)) {
return false;
}
// Make sure it's not a table element. If so, cancel the operation
// (translation: users cannot backspace or delete across table cells)
if (HTMLEditUtils::IsAnyTableElement(&aCurrentBlockElement)) {
@ -6004,6 +6010,16 @@ Result<bool, nsresult> HTMLEditor::AutoDeleteRangesHandler::
return Err(NS_ERROR_UNEXPECTED);
}
// Don't join the blocks if both of them are basic structure of the HTML
// document (Note that `<body>` can be joined with its children).
if (mLeftBlockElement->IsAnyOfHTMLElements(nsGkAtoms::html, nsGkAtoms::head,
nsGkAtoms::body) &&
mRightBlockElement->IsAnyOfHTMLElements(nsGkAtoms::html, nsGkAtoms::head,
nsGkAtoms::body)) {
mCanJoinBlocks = false;
return false;
}
if (HTMLEditUtils::IsAnyTableElement(mLeftBlockElement) ||
HTMLEditUtils::IsAnyTableElement(mRightBlockElement)) {
// Do not try to merge table elements, cancel the deletion.

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

@ -218,22 +218,13 @@ async function runTests() {
is(beforeInputEvent.data, null, `${aDescription}data of "beforeinput" event for ${action} should be null`);
is(beforeInputEvent.dataTransfer, null, `${aDescription}dataTransfer of "beforeinput" event for ${action} should be null`);
checkTargetRanges(beforeInputEvent, selectionRanges);
if (!isEditTargetIsDescendantOfEditingHost) {
ok(!inputEvent, `${aDescription}"input" event shouldn't be fired at ${action}`);
} else {
todo(!inputEvent, `${aDescription}"input" event should be fired at ${action} but we replace the padding <br> element`);
}
ok(!inputEvent, `${aDescription}"input" event shouldn't be fired at ${action}`);
reset();
cancelBeforeInput = false;
action = 'typing "B"';
synthesizeKey("B", {shiftKey: true}, aWindow);
// XXX This inconsistency must be a bug.
if (!isEditTargetIsDescendantOfEditingHost) {
is(editTarget.innerHTML, "B<br>", `${aDescription}"B" should've been inserted by ${action}`);
} else {
is(editTarget.innerHTML, "B", `${aDescription}"B" should've been inserted by ${action}`);
}
is(editTarget.innerHTML, "B<br>", `${aDescription}"B" should've been inserted by ${action}`);
is(beforeInputEvent.cancelable, true, `${aDescription}"beforeinput" event for ${action} should be cancelable`);
is(beforeInputEvent.inputType, "insertText", `${aDescription}inputType of "beforeinput" event for ${action} should be "insertText"`);
is(beforeInputEvent.data, "B", `${aDescription}data of "beforeinput" event for ${action} should be "B"`);
@ -249,12 +240,7 @@ async function runTests() {
cancelBeforeInput = true;
action = 'typing "Enter"';
synthesizeKey("KEY_Enter", {}, aWindow);
// XXX This inconsistency must be a bug.
if (!isEditTargetIsDescendantOfEditingHost) {
is(editTarget.innerHTML, "B<br>", `${aDescription}shouldn't modify the editor by ${action} since "beforeinput" was canceled`);
} else {
is(editTarget.innerHTML, "B", `${aDescription}shouldn't modify the editor by ${action} since "beforeinput" was canceled`);
}
is(editTarget.innerHTML, "B<br>", `${aDescription}shouldn't modify the editor by ${action} since "beforeinput" was canceled`);
ok(beforeInputEvent, `${aDescription}"beforeinput" event should've been fired at ${action}`);
ok(!inputEvent, `${aDescription}"input" event shouldn't been fired at ${action} since "beforeinput" was canceled`);
@ -1317,10 +1303,10 @@ async function runTests() {
"Editor3, div has contenteditable attribute");
doTests(document.getElementById("editor4").contentDocument,
document.getElementById("editor4").contentWindow,
"Editor4, html and div has contenteditable attribute");
"Editor4, html and div have contenteditable attribute");
doTests(document.getElementById("editor5").contentDocument,
document.getElementById("editor5").contentWindow,
"Editor5, html and div has contenteditable attribute");
"Editor5, html and div have contenteditable attribute");
SimpleTest.finish();
}