| <!doctype html> |
| <meta charset=utf-8> |
| <title>Test insertParagraph when selection collapsed in void element</title> |
| <meta name="timeout" content="long"> |
| <script src=/resources/testharness.js></script> |
| <script src=/resources/testharnessreport.js></script> |
| <div contenteditable></div> |
| <script> |
| "use strict"; |
| |
| const voidElements = [ |
| "br", |
| "embed", |
| "hr", |
| "img", |
| "input", |
| "wbr", |
| ]; |
| |
| // This test tests whether the inserted text is inserted into, when selection |
| // is collapsed in the void element. The expected results are based on Blink, |
| // but the results of <hr>, <embed> and <wbr> elements are not consistent with |
| // the other elements'. Therefore, Blink also does not pass some of the |
| // following tests. |
| // FYI: This cannot be tested by editing/run because there is no way to collapse |
| // selection into a void element with the framework. |
| |
| const editor = document.querySelector("div[contenteditable]"); |
| for (const container of ["div", "h1", "li"]) { |
| const openTagOfContainer = (() => { |
| if (container == "li") { |
| return "<ol><li>"; |
| } |
| return `<${container}>`; |
| })(); |
| const closeTagOfContainer = (() => { |
| if (container == "li") { |
| return "</li></ol>"; |
| } |
| return `</${container}>`; |
| })(); |
| const closeAndOpenTagsOfSplitPoint = (() => { |
| if (container == "li") { |
| return "</li><li>"; |
| } |
| return `</${container}><${container}>`; |
| })(); |
| for (const tag of voidElements) { |
| const visibleTag = tag == "hr" || tag == "img" || tag == "input"; |
| test(() => { |
| editor.innerHTML = `${openTagOfContainer}<${tag}>${closeTagOfContainer}`; |
| const element = editor.querySelector(tag); |
| editor.focus(); |
| const selection = getSelection(); |
| selection.collapse(element, 0); |
| 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`); |
| |
| 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); |
| editor.focus(); |
| const selection = getSelection(); |
| selection.collapse(element, 0); |
| document.execCommand("insertParagraph"); |
| if (tag == "br") { |
| if (!visibleTag && container == "h1") { |
| assert_in_array( |
| editor.innerHTML, |
| [ |
| `${openTagOfContainer}abc${closeTagOfContainer}<div><br></div>`, |
| `${openTagOfContainer}abc<br>${closeTagOfContainer}<div><br></div>`, |
| ], |
| `The paragraph should be split before the <${tag}> element` |
| ); |
| } else { |
| assert_in_array( |
| editor.innerHTML, |
| [ |
| `${openTagOfContainer}abc${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`, |
| `${openTagOfContainer}abc<br>${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`, |
| ], |
| `The paragraph should be split before the <${tag}> element` |
| ); |
| } |
| } else if (!visibleTag && container == "h1") { |
| assert_in_array( |
| editor.innerHTML, |
| [ |
| `${openTagOfContainer}abc${closeTagOfContainer}<div><${tag}></div>`, |
| `${openTagOfContainer}abc<br>${closeTagOfContainer}<div><${tag}></div>`, |
| `${openTagOfContainer}abc${closeTagOfContainer}<div><${tag}><br></div>`, |
| `${openTagOfContainer}abc<br>${closeTagOfContainer}<div><${tag}><br></div>`, |
| ], |
| `The paragraph should be split before the <${tag}> element` |
| ); |
| } else { |
| assert_in_array( |
| editor.innerHTML, |
| [ |
| `${openTagOfContainer}abc${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`, |
| `${openTagOfContainer}abc<br>${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`, |
| `${openTagOfContainer}abc${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`, |
| `${openTagOfContainer}abc<br>${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`, |
| ], |
| `The paragraph should be split before the <${tag}> element` |
| ); |
| } |
| }, `Inserting paragraph when selection is collapsed in <${tag}> which follows a text node in <${container}>`); |
| |
| test(() => { |
| editor.innerHTML = `${openTagOfContainer}<${tag}>abc${closeTagOfContainer}`; |
| const element = editor.querySelector(tag); |
| editor.focus(); |
| const selection = getSelection(); |
| selection.collapse(element, 0); |
| document.execCommand("insertParagraph"); |
| assert_in_array( |
| editor.innerHTML, |
| [ |
| `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>abc${closeTagOfContainer}`, |
| `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>abc<br>${closeTagOfContainer}`, |
| ], |
| `The paragraph should be inserted before the <${tag}> element` |
| ); |
| }, `Inserting paragraph when selection is collapsed in <${tag}> which is followed by a text node in <${container}>`); |
| } |
| } |
| |
| </script> |