зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1731005 - HTMLEditor::GetActiveEditingHost() does not return editing host if selection is collapsed in `<input>` r=m_kato
If we flush pending notifications before calling `execCommand` in `insert-*-in-void-element.tentative.html`, `HTMLEditor` does not work because `GetActiveEditingHost()` returns `nullptr`. This is wrong because `Selection` cannot cross native anonymous subtree boundaries and the selection collapsed in `<input>` element is valid. Therefore, it should not check whether the content has independent selection or not. Differential Revision: https://phabricator.services.mozilla.com/D125791
This commit is contained in:
Родитель
fe3e424e83
Коммит
f7705eac76
|
@ -5845,12 +5845,14 @@ Element* HTMLEditor::GetActiveEditingHost(
|
|||
}
|
||||
nsIContent* content = focusNode->AsContent();
|
||||
|
||||
// If the active content isn't editable, or it has independent selection,
|
||||
// we're not active.
|
||||
if (!content->HasFlag(NODE_IS_EDITABLE) ||
|
||||
content->HasIndependentSelection()) {
|
||||
// If the active content isn't editable, we're not active.
|
||||
if (!content->HasFlag(NODE_IS_EDITABLE)) {
|
||||
return nullptr;
|
||||
}
|
||||
// Note that `Selection` shouldn't be in the native anonymous subtree of
|
||||
// <input>/<textarea>, but can be in them (e.g., collapsed at {<input> - 0}).
|
||||
// Even in such case, we need to look for an ancestor which does not have
|
||||
// editable parent.
|
||||
Element* candidateEditingHost = content->GetEditingHost();
|
||||
if (!candidateEditingHost) {
|
||||
return nullptr;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
[Inserting paragraph when selection is collapsed in <hr> in <div> which is only child]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> in <div> which is only child (explicitly flushes maybe pending layout)]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> which follows a text node in <div>]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -11,12 +14,18 @@
|
|||
[Inserting paragraph when selection is collapsed in <embed> in <h1> which is only child]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <embed> in <h1> which is only child (explicitly flushes maybe pending layout)]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <embed> which follows a text node in <h1>]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> in <h1> which is only child]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> in <h1> which is only child (explicitly flushes maybe pending layout)]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> which follows a text node in <h1>]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -26,15 +35,24 @@
|
|||
[Inserting paragraph when selection is collapsed in <wbr> in <h1> which is only child]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <wbr> in <h1> which is only child (explicitly flushes maybe pending layout)]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <wbr> which follows a text node in <h1>]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <br> in <li> which is only child]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <br> in <li> which is only child (explicitly flushes maybe pending layout)]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> in <li> which is only child]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> in <li> which is only child (explicitly flushes maybe pending layout)]
|
||||
expected: FAIL
|
||||
|
||||
[Inserting paragraph when selection is collapsed in <hr> which follows a text node in <li>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -89,6 +89,49 @@ for (const container of ["div", "h1", "li"]) {
|
|||
}
|
||||
}, `Inserting paragraph when selection is collapsed in <${tag}> in <${container}> which is only child`);
|
||||
|
||||
test(() => {
|
||||
editor.innerHTML = `${openTagOfContainer}<${tag}>${closeTagOfContainer}`;
|
||||
const element = editor.querySelector(tag);
|
||||
editor.focus();
|
||||
const selection = getSelection();
|
||||
selection.collapse(element, 0);
|
||||
element.getBoundingClientRect();
|
||||
document.execCommand("insertParagraph");
|
||||
if (tag == "br") {
|
||||
if (!visibleTag && container == "h1") {
|
||||
assert_in_array(
|
||||
editor.innerHTML,
|
||||
`${openTagOfContainer}<br>${closeTagOfContainer}<div><br></div>`,
|
||||
`The paragraph should be inserted before the <${tag}> element`
|
||||
);
|
||||
} else {
|
||||
assert_in_array(
|
||||
editor.innerHTML,
|
||||
`${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`,
|
||||
`The paragraph should be inserted before the <${tag}> element`
|
||||
);
|
||||
}
|
||||
} else if (!visibleTag && container == "h1") {
|
||||
assert_in_array(
|
||||
editor.innerHTML,
|
||||
[
|
||||
`${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}></div>`,
|
||||
`${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}><br></div>`,
|
||||
],
|
||||
`The paragraph should be inserted before the <${tag}> element`
|
||||
);
|
||||
} else {
|
||||
assert_in_array(
|
||||
editor.innerHTML,
|
||||
[
|
||||
`${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`,
|
||||
`${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`,
|
||||
],
|
||||
`The paragraph should be inserted before the <${tag}> element`
|
||||
);
|
||||
}
|
||||
}, `Inserting paragraph when selection is collapsed in <${tag}> in <${container}> which is only child (explicitly flushes maybe pending layout)`);
|
||||
|
||||
test(() => {
|
||||
editor.innerHTML = `${openTagOfContainer}abc<${tag}>${closeTagOfContainer}`;
|
||||
const element = editor.querySelector(tag);
|
||||
|
|
|
@ -56,6 +56,36 @@ for (const tag of voidElements) {
|
|||
}
|
||||
}, `Inserting text when selection is collapsed in <${tag}> which is only child`);
|
||||
|
||||
test(() => {
|
||||
editor.innerHTML = `<div></div>`;
|
||||
const element = document.createElement(tag);
|
||||
editor.firstChild.appendChild(element);
|
||||
editor.focus();
|
||||
const selection = getSelection();
|
||||
selection.collapse(element, 0);
|
||||
element.getBoundingClientRect();
|
||||
document.execCommand("insertText", false, "abc");
|
||||
if (tag == "br") {
|
||||
assert_in_array(
|
||||
editor.innerHTML,
|
||||
[
|
||||
"<div>abc</div>",
|
||||
"<div>abc<br></div>",
|
||||
],
|
||||
`The text should be inserted before the <br> element`
|
||||
);
|
||||
} else {
|
||||
assert_in_array(
|
||||
editor.innerHTML,
|
||||
[
|
||||
`<div>abc<${tag}></div>`,
|
||||
`<div>abc<${tag}><br></div>`,
|
||||
],
|
||||
`The text should be inserted before the <${tag}> element`
|
||||
);
|
||||
}
|
||||
}, `Inserting text when selection is collapsed in <${tag}> which is only child (explicitly flushes maybe pending layout)`);
|
||||
|
||||
test(() => {
|
||||
editor.innerHTML = `<div>abc</div>`;
|
||||
const element = document.createElement(tag);
|
||||
|
|
Загрузка…
Ссылка в новой задаче