test_nsITableEditor_deleteTableCellContents.html (14753B)
1 <!DOCTYPE> 2 <html> 3 <head> 4 <title>Test for nsITableEditor.deleteTableCellContents()</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 7 </head> 8 <body> 9 <div id="display"> 10 </div> 11 <div id="content" contenteditable>out of table<table><tr><td>default content</td></tr></table></div> 12 <pre id="test"> 13 </pre> 14 15 <script class="testbody" type="application/javascript"> 16 "use strict"; 17 18 SimpleTest.waitForExplicitFinish(); 19 SimpleTest.waitForFocus(() => { 20 let editor = document.getElementById("content"); 21 let selection = document.getSelection(); 22 let selectionRanges = []; 23 24 function checkInputEvent(aEvent, aDescription) { 25 ok(aEvent instanceof InputEvent, 26 `"${aEvent.type}" event should be dispatched with InputEvent interface ${aDescription}`); 27 is(aEvent.cancelable, aEvent.type === "beforeinput", 28 `"${aEvent.type}" event should ${aEvent.type === "beforeinput" ? "be" : "be never"} cancelable ${aDescription}`); 29 is(aEvent.bubbles, true, 30 `"${aEvent.type}" event should always bubble ${aDescription}`); 31 is(aEvent.inputType, "deleteContent", 32 `inputType of "${aEvent.type}" event should be "deleteContent" ${aDescription}`); 33 is(aEvent.data, null, 34 `data of "${aEvent.type}" event should be null ${aDescription}`); 35 is(aEvent.dataTransfer, null, 36 `dataTransfer of "${aEvent.type}" event should be null ${aDescription}`); 37 let targetRanges = aEvent.getTargetRanges(); 38 if (aEvent.type === "beforeinput") { 39 is(targetRanges.length, selectionRanges.length, 40 `getTargetRanges() of "beforeinput" event should return selection ranges ${aDescription}`); 41 if (targetRanges.length === selectionRanges.length) { 42 for (let i = 0; i < selectionRanges.length; i++) { 43 is(targetRanges[i].startContainer, selectionRanges[i].startContainer, 44 `startContainer of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); 45 is(targetRanges[i].startOffset, selectionRanges[i].startOffset, 46 `startOffset of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); 47 is(targetRanges[i].endContainer, selectionRanges[i].endContainer, 48 `endContainer of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); 49 is(targetRanges[i].endOffset, selectionRanges[i].endOffset, 50 `endOffset of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`); 51 } 52 } 53 } else { 54 is(targetRanges.length, 0, 55 `getTargetRanges() of "${aEvent.type}" event should return empty array ${aDescription}`); 56 } 57 } 58 59 let beforeInputEvents = []; 60 let inputEvents = []; 61 function onBeforeInput(aEvent) { 62 beforeInputEvents.push(aEvent); 63 selectionRanges = []; 64 for (let i = 0; i < selection.rangeCount; i++) { 65 let range = selection.getRangeAt(i); 66 selectionRanges.push({startContainer: range.startContainer, startOffset: range.startOffset, 67 endContainer: range.endContainer, endOffset: range.endOffset}); 68 } 69 } 70 function onInput(aEvent) { 71 inputEvents.push(aEvent); 72 } 73 editor.addEventListener("beforeinput", onBeforeInput); 74 editor.addEventListener("input", onInput); 75 76 selection.collapse(editor.firstChild, 0); 77 beforeInputEvents = []; 78 inputEvents = []; 79 getTableEditor().deleteTableCellContents(); 80 is(editor.innerHTML, "out of table<table><tbody><tr><td>default content</td></tr></tbody></table>", 81 "nsITableEditor.deleteTableCellContents() should do nothing if selection is not in <table>"); 82 // If there were specific inputType value for this API, we should dispatch cancelable "beforeinput", though. 83 is(beforeInputEvents.length, 1, 84 '"beforeinput" event should be fired when a call of nsITableEditor.deleteTableCellContents() even though it will do nothing'); 85 checkInputEvent(beforeInputEvents[0], "when selection is collapsed outside table element"); 86 is(inputEvents.length, 0, 87 'No "input" event should be fired when a call of nsITableEditor.deleteTableCellContents() does nothing'); 88 89 selection.removeAllRanges(); 90 try { 91 beforeInputEvents = []; 92 inputEvents = []; 93 getTableEditor().deleteTableCellContents(); 94 ok(false, "getTableEditor().deleteTableCellContents() without selection ranges should throw exception"); 95 } catch (e) { 96 ok(true, "getTableEditor().deleteTableCellContents() without selection ranges should throw exception"); 97 is(beforeInputEvents.length, 0, 98 'No "beforeinput" event should be fired when nsITableEditor.deleteTableCellContents() causes exception due to no selection range'); 99 is(inputEvents.length, 0, 100 'No "input" event should be fired when nsITableEditor.deleteTableCellContents() causes exception due to no selection range'); 101 } 102 103 selection.removeAllRanges(); 104 editor.innerHTML = "<table>" + 105 '<tr><td id="select">cell1-1</td><td>cell1-2</td></tr>' + 106 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 107 "</table>"; 108 editor.focus(); 109 beforeInputEvents = []; 110 inputEvents = []; 111 let range = document.createRange(); 112 range.selectNode(document.getElementById("select")); 113 selection.addRange(range); 114 getTableEditor().deleteTableCellContents(); 115 is(editor.innerHTML, "<table><tbody>" + 116 '<tr><td id="select"><br></td><td>cell1-2</td></tr>' + 117 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 118 "</tbody></table>", 119 "nsITableEditor.deleteTableCellContents() should replace the selected cell's text with <br> element"); 120 is(beforeInputEvents.length, 1, 121 'Only one "beforeinput" event should be fired when all text in a cell is selected'); 122 checkInputEvent(beforeInputEvents[0], "when all text in a cell is selected"); 123 is(inputEvents.length, 1, 124 'Only one "input" event should be fired when all text in a cell is selected'); 125 checkInputEvent(inputEvents[0], "when all text in a cell is selected"); 126 127 selection.removeAllRanges(); 128 editor.innerHTML = "<table>" + 129 '<tr><td id="select"><ul><li>list1</li></ul></td><td>cell1-2</td></tr>' + 130 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 131 "</table>"; 132 editor.focus(); 133 beforeInputEvents = []; 134 inputEvents = []; 135 range = document.createRange(); 136 range.selectNode(document.getElementById("select")); 137 selection.addRange(range); 138 getTableEditor().deleteTableCellContents(); 139 is(editor.innerHTML, "<table><tbody>" + 140 '<tr><td id="select"><br></td><td>cell1-2</td></tr>' + 141 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 142 "</tbody></table>", 143 "nsITableEditor.deleteTableCellContents() should replace the selected cell's <ul> element with <br> element"); 144 is(beforeInputEvents.length, 1, 145 'Only one "beforeinput" event should be fired when <ul> element in a cell is selected'); 146 checkInputEvent(beforeInputEvents[0], "when <ul> element in a cell is selected"); 147 is(inputEvents.length, 1, 148 'Only one "input" event should be fired when <ul> element in a cell is selected'); 149 checkInputEvent(inputEvents[0], "when <ul> element in a cell is selected"); 150 151 selection.removeAllRanges(); 152 editor.innerHTML = "<table>" + 153 '<tr><td id="select1">cell1-1</td><td>cell1-2</td></tr>' + 154 '<tr><td id="select2">cell2-1</td><td>cell2-2</td></tr>' + 155 "</table>"; 156 editor.focus(); 157 beforeInputEvents = []; 158 inputEvents = []; 159 range = document.createRange(); 160 range.selectNode(document.getElementById("select1")); 161 selection.addRange(range); 162 range = document.createRange(); 163 range.selectNode(document.getElementById("select2")); 164 selection.addRange(range); 165 getTableEditor().deleteTableCellContents(); 166 is(editor.innerHTML, "<table><tbody>" + 167 '<tr><td id="select1"><br></td><td>cell1-2</td></tr>' + 168 '<tr><td id="select2"><br></td><td>cell2-2</td></tr>' + 169 "</tbody></table>", 170 "nsITableEditor.deleteTableCellContents() should replace the selected 2 cells' text with <br> element"); 171 is(beforeInputEvents.length, 1, 172 'Only one "beforeinput" event should be fired when 2 cell elements are selected'); 173 checkInputEvent(beforeInputEvents[0], "when 2 cell elements are selected"); 174 is(inputEvents.length, 1, 175 'Only one "input" event should be fired when 2 cell elements are selected'); 176 checkInputEvent(inputEvents[0], "when 2 cell elements are selected"); 177 178 selection.removeAllRanges(); 179 editor.innerHTML = "<table>" + 180 '<tr><td id="select1">cell1-1</td><td id="select2">cell1-2</td></tr>' + 181 '<tr><td id="select3">cell2-1</td><td id="select4">cell2-2</td></tr>' + 182 "</table>"; 183 editor.focus(); 184 beforeInputEvents = []; 185 inputEvents = []; 186 range = document.createRange(); 187 range.selectNode(document.getElementById("select1")); 188 selection.addRange(range); 189 range = document.createRange(); 190 range.selectNode(document.getElementById("select2")); 191 selection.addRange(range); 192 range = document.createRange(); 193 range.selectNode(document.getElementById("select3")); 194 selection.addRange(range); 195 range = document.createRange(); 196 range.selectNode(document.getElementById("select4")); 197 selection.addRange(range); 198 getTableEditor().deleteTableCellContents(); 199 is(editor.innerHTML, "<table><tbody>" + 200 '<tr><td id="select1"><br></td><td id="select2"><br></td></tr>' + 201 '<tr><td id="select3"><br></td><td id="select4"><br></td></tr>' + 202 "</tbody></table>", 203 "nsITableEditor.deleteTableCellContents() should replace the selected 4 cells' text with <br> element"); 204 is(beforeInputEvents.length, 1, 205 'Only one "beforeinput" event should be fired when 4 cell elements are selected'); 206 checkInputEvent(beforeInputEvents[0], "when 4 cell elements are selected"); 207 is(inputEvents.length, 1, 208 'Only one "input" event should be fired when 4 cell elements are selected'); 209 checkInputEvent(inputEvents[0], "when 4 cell elements are selected"); 210 211 selection.removeAllRanges(); 212 editor.innerHTML = "<table>" + 213 '<tr><td id="select" rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 214 "<tr><td>cell2-2</td></tr>" + 215 "</table>"; 216 editor.focus(); 217 beforeInputEvents = []; 218 inputEvents = []; 219 range = document.createRange(); 220 range.selectNode(document.getElementById("select")); 221 selection.addRange(range); 222 getTableEditor().deleteTableCellContents(); 223 is(editor.innerHTML, "<table><tbody>" + 224 '<tr><td id="select" rowspan="2"><br></td><td>cell1-2</td></tr>' + 225 "<tr><td>cell2-2</td></tr>" + 226 "</tbody></table>", 227 "nsITableEditor.deleteTableCellContents() should replace the selected cell's text with <br> element (even if the cell is row-spanning)"); 228 is(beforeInputEvents.length, 1, 229 'Only one "beforeinput" event should be fired when a cell element are selected (even if the cell is row-spanning)'); 230 checkInputEvent(beforeInputEvents[0], "when a cell element are selected (even if the cell is row-spanning)"); 231 is(inputEvents.length, 1, 232 'Only one "input" event should be fired when a cell element are selected (even if the cell is row-spanning)'); 233 checkInputEvent(inputEvents[0], "when a cell element are selected (even if the cell is row-spanning)"); 234 235 selection.removeAllRanges(); 236 editor.innerHTML = "<table>" + 237 '<tr><td id="select" colspan="2">cell1-1</td></tr>' + 238 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 239 "</table>"; 240 editor.focus(); 241 beforeInputEvents = []; 242 inputEvents = []; 243 range = document.createRange(); 244 range.selectNode(document.getElementById("select")); 245 selection.addRange(range); 246 getTableEditor().deleteTableCellContents(); 247 is(editor.innerHTML, "<table><tbody>" + 248 '<tr><td id="select" colspan="2"><br></td></tr>' + 249 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 250 "</tbody></table>", 251 "nsITableEditor.deleteTableCellContents() should replace the selected cell's text with <br> element (even if the cell is column-spanning)"); 252 is(beforeInputEvents.length, 1, 253 'Only one "beforeinput" event should be fired when a cell element are selected (even if the cell is column-spanning)'); 254 checkInputEvent(beforeInputEvents[0], "when a cell element are selected (even if the cell is column-spanning)"); 255 is(inputEvents.length, 1, 256 'Only one "input" event should be fired when a cell element are selected (even if the cell is column-spanning)'); 257 checkInputEvent(inputEvents[0], "when a cell element are selected (even if the cell is column-spanning)"); 258 259 selection.removeAllRanges(); 260 editor.innerHTML = "<table>" + 261 '<tr><td id="select">cell1-1</td><td>cell1-2</td></tr>' + 262 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 263 "</table>"; 264 editor.focus(); 265 beforeInputEvents = []; 266 inputEvents = []; 267 selection.setBaseAndExtent(document.getElementById("select").firstChild, 0, 268 document.getElementById("select").firstChild, 0); 269 getTableEditor().deleteTableCellContents(); 270 is(editor.innerHTML, "<table><tbody>" + 271 '<tr><td id="select"><br></td><td>cell1-2</td></tr>' + 272 "<tr><td>cell2-1</td><td>cell2-2</td></tr>" + 273 "</tbody></table>", 274 "nsITableEditor.deleteTableCellContents() should replace a cell's text with <br> element when the cell contains selection range"); 275 is(beforeInputEvents.length, 1, 276 'Only one "beforeinput" event should be fired when the cell contains selection range'); 277 checkInputEvent(beforeInputEvents[0], "when the cell contains selection range"); 278 is(inputEvents.length, 1, 279 'Only one "input" event should be fired when the cell contains selection range'); 280 checkInputEvent(inputEvents[0], "when the cell contains selection range"); 281 282 editor.removeEventListener("beforeinput", onBeforeInput); 283 editor.removeEventListener("input", onInput); 284 285 SimpleTest.finish(); 286 }); 287 288 function getTableEditor() { 289 var editingSession = SpecialPowers.wrap(window).docShell.editingSession; 290 return editingSession.getEditorForWindow(window).QueryInterface(SpecialPowers.Ci.nsITableEditor); 291 } 292 293 </script> 294 </body> 295 296 </html>