nested-with-contenteditable-true.html (8643B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="timeout" content="long"> 6 <title>Testing contenteditable=plaintext-only which is nested with contenteditable=true</title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/resources/testdriver.js"></script> 10 <script src="/resources/testdriver-vendor.js"></script> 11 <script src="/resources/testdriver-actions.js"></script> 12 <script src="../include/editor-test-utils.js"></script> 13 <script> 14 "use strict"; 15 16 addEventListener("load", () => { 17 const editingHost = document.createElement("div"); 18 editingHost.setAttribute("contenteditable", ""); 19 document.body.appendChild(editingHost); 20 editingHost.focus(); 21 const utils = new EditorTestUtils(editingHost); 22 for (const trueOrEmpty of ["", "true"]) { 23 for (const explicitlySetFocus of [false, true]) { 24 for (const data of [ 25 { 26 desc: `contenteditable="plaintext-only" in contenteditable="${trueOrEmpty}" should support style edit`, 27 init: `<div contenteditable="plaintext-only">[abc]</div>`, 28 run: function () { 29 document.execCommand("bold"); 30 }, 31 expected: `<div contenteditable="plaintext-only"><b>abc</b></div>` 32 }, 33 { 34 desc: `contenteditable="plaintext-only" in contenteditable="${ 35 trueOrEmpty 36 }" and contenteditable="false" should not support style edit`, 37 init: `<div contenteditable="false"><div contenteditable="plaintext-only">[abc]</div></div>`, 38 run: function () { 39 document.execCommand("bold"); 40 }, 41 expected: `<div contenteditable="false"><div contenteditable="plaintext-only">abc</div></div>`, 42 }, 43 { 44 desc: `contenteditable="plaintext-only" in contenteditable="${trueOrEmpty}" should insert paragraph at typing Enter`, 45 init: `<div contenteditable="plaintext-only"><p>a[b]c</p></div>`, 46 run: function () { 47 return utils.sendEnterKey(); 48 }, 49 expected: `<div contenteditable="plaintext-only"><p>a</p><p>c</p></div>` 50 }, 51 { 52 desc: `contenteditable="plaintext-only" in contenteditable="${ 53 trueOrEmpty 54 }" and contenteditable="false" should insert line break at typing Enter`, 55 init: `<div contenteditable="false"><div contenteditable="plaintext-only"><p>a[b]c</p></div></div>`, 56 run: function () { 57 return utils.sendEnterKey(); 58 }, 59 expected: `<div contenteditable="false"><div contenteditable="plaintext-only"><p>a<br>c</p></div></div>`, 60 }, 61 { 62 desc: `styling start boundary of contenteditable="plaintext-only" in contenteditable="${ 63 trueOrEmpty 64 }" should apply the style to entire the range`, 65 init: `A[B<div contenteditable="plaintext-only">C]D</div>EF`, 66 run: function () { 67 document.execCommand("bold"); 68 }, 69 expected: `A<b>B</b><div contenteditable="plaintext-only"><b>C</b>D</div>EF`, 70 }, 71 { 72 desc: `styling end boundary of contenteditable="plaintext-only" in contenteditable="${ 73 trueOrEmpty 74 }" should apply the style to entire the range`, 75 init: `AB<div contenteditable="plaintext-only">C[D</div>E]F`, 76 run: function () { 77 document.execCommand("bold"); 78 }, 79 expected: `AB<div contenteditable="plaintext-only">C<b>D</b></div><b>E</b>F`, 80 }, 81 { 82 desc: `even after moving selection into contenteditable="plaintext-only" in contenteditable="${ 83 trueOrEmpty 84 }" and contenteditable="false" from parent editing host should not support style edit`, 85 init: `A[]B<div contenteditable="false"><div contenteditable="plaintext-only">CD</div></div>EF`, 86 run: function () { 87 getSelection().selectAllChildren(editingHost.querySelector("div[contenteditable=plaintext-only]")); 88 document.execCommand("bold"); 89 }, 90 expected: `AB<div contenteditable="false"><div contenteditable="plaintext-only">CD</div></div>EF`, 91 }, 92 ]) { 93 promise_test(async () => { 94 editingHost.setAttribute("contenteditable", trueOrEmpty); 95 utils.setupEditingHost(data.init); 96 if (explicitlySetFocus) { 97 editingHost.querySelector("[contenteditable=plaintext-only]").focus(); 98 } 99 await data.run(); 100 assert_equals(editingHost.outerHTML, `<div contenteditable="${trueOrEmpty}">${data.expected}</div>`); 101 }, data.desc + (explicitlySetFocus ? " (explicitly setting focus to the nested one)" : "")); 102 } 103 104 for (const data of [ 105 { 106 desc: `contenteditable="${trueOrEmpty}" in contenteditable="plaintext-only" should not support style edit`, 107 init: `<div contenteditable="${trueOrEmpty}">[abc]</div>`, 108 run: function () { 109 document.execCommand("bold"); 110 }, 111 expected: `<div contenteditable="${trueOrEmpty}">abc</div>` 112 }, 113 { 114 desc: `contenteditable="${ 115 trueOrEmpty 116 }" in contenteditable="plaintext-only" and contenteditable="false" should support style edit`, 117 init: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}">[abc]</div></div>`, 118 run: function () { 119 document.execCommand("bold"); 120 }, 121 expected: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><b>abc</b></div></div>`, 122 }, 123 { 124 desc: `contenteditable="${trueOrEmpty}" in contenteditable="plaintext-only" should insert line break at typing Enter`, 125 init: `<div contenteditable="${trueOrEmpty}"><p>a[b]c</p></div>`, 126 run: function () { 127 return utils.sendEnterKey(); 128 }, 129 expected: `<div contenteditable="${trueOrEmpty}"><p>a<br>c</p></div>` 130 }, 131 { 132 desc: `contenteditable="${ 133 trueOrEmpty 134 }" in contenteditable="plaintext-only" and contenteditable="false" should insert paragraph at typing Enter`, 135 init: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><p>a[b]c</p></div></div>`, 136 run: function () { 137 return utils.sendEnterKey(); 138 }, 139 expected: `<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><p>a</p><p>c</p></div></div>`, 140 }, 141 { 142 desc: `styling start boundary of contenteditable="${ 143 trueOrEmpty 144 }" in contenteditable="plaintext-only" should not apply the style`, 145 init: `A[B<div contenteditable="${trueOrEmpty}">C]D</div>EF`, 146 run: function () { 147 document.execCommand("bold"); 148 }, 149 expected: `AB<div contenteditable="${trueOrEmpty}">CD</div>EF`, 150 }, 151 { 152 desc: `styling end boundary of contenteditable="${ 153 trueOrEmpty 154 }" in contenteditable="plaintext-only" should not apply the style`, 155 init: `AB<div contenteditable="${trueOrEmpty}">C[D</div>E]F`, 156 run: function () { 157 document.execCommand("bold"); 158 }, 159 expected: `AB<div contenteditable="${trueOrEmpty}">CD</div>EF`, 160 }, 161 { 162 desc: `even after moving selection into contenteditable="${ 163 trueOrEmpty 164 }" in contenteditable="plaintext-only" and contenteditable="false" from parent editing host should support style edit`, 165 init: `A[]B<div contenteditable="false"><div contenteditable="${trueOrEmpty}">CD</div></div>EF`, 166 run: function () { 167 getSelection().selectAllChildren(editingHost.querySelector(`div[contenteditable="${trueOrEmpty}"]`)); 168 document.execCommand("bold"); 169 }, 170 expected: `AB<div contenteditable="false"><div contenteditable="${trueOrEmpty}"><b>CD</b></div></div>EF`, 171 }, 172 ]) { 173 promise_test(async () => { 174 editingHost.setAttribute("contenteditable", "plaintext-only"); 175 utils.setupEditingHost(data.init); 176 if (explicitlySetFocus) { 177 editingHost.querySelector(`[contenteditable='${trueOrEmpty}']`).focus(); 178 } 179 await data.run(); 180 assert_equals(editingHost.outerHTML, `<div contenteditable="plaintext-only">${data.expected}</div>`); 181 }, data.desc + (explicitlySetFocus ? " (explicitly setting focus to the nested one)" : "")); 182 } 183 } 184 } 185 }, {once: true}); 186 </script> 187 </head> 188 <body></body> 189 </html>