test_nsITableEditor_deleteTableCell.html (39112B)
1 <!DOCTYPE> 2 <html> 3 <head> 4 <title>Test for nsITableEditor.deleteTableCell()</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 be ${aEvent.type === "beforeinput" ? "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 beforeInputEvents = []; 77 inputEvents = []; 78 selection.collapse(editor.firstChild, 0); 79 getTableEditor().deleteTableCell(1); 80 is(editor.innerHTML, "out of table<table><tbody><tr><td>default content</td></tr></tbody></table>", 81 "nsITableEditor.deleteTableCell(1) 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.deleteTableCell(1) 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.deleteTableCell(1) does nothing'); 88 89 selection.removeAllRanges(); 90 try { 91 beforeInputEvents = []; 92 inputEvents = []; 93 getTableEditor().deleteTableCell(1); 94 ok(false, "getTableEditor().deleteTableCell(1) without selection ranges should throw exception"); 95 } catch (e) { 96 ok(true, "getTableEditor().deleteTableCell(1) without selection ranges should throw exception"); 97 is(beforeInputEvents.length, 0, 98 'No "beforeinput" event should be fired when nsITableEditor.deleteTableCell(1) causes exception due to no selection range'); 99 is(inputEvents.length, 0, 100 'No "input" event should be fired when nsITableEditor.deleteTableCell(1) 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><td>cell1-3</td></tr>' + 106 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 107 "</table>"; 108 beforeInputEvents = []; 109 inputEvents = []; 110 let range = document.createRange(); 111 range.selectNode(document.getElementById("select")); 112 selection.addRange(range); 113 getTableEditor().deleteTableCell(1); 114 is(editor.innerHTML, "<table><tbody>" + 115 "<tr><td>cell1-2</td><td>cell1-3</td></tr>" + 116 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 117 "</tbody></table>", 118 "nsITableEditor.deleteTableCellContents(1) should remove only selected cell when only one cell is selected #1-1"); 119 is(beforeInputEvents.length, 1, 120 'Only one "beforeinput" event should be fired when only one cell is selected #1-1'); 121 checkInputEvent(beforeInputEvents[0], "when only one cell is selected #1-1"); 122 is(inputEvents.length, 1, 123 'Only one "input" event should be fired when only one cell is selected #1-1'); 124 checkInputEvent(inputEvents[0], "when only one cell is selected #1-1"); 125 126 selection.removeAllRanges(); 127 editor.innerHTML = "<table>" + 128 '<tr><td>cell1-1</td><td id="select">cell1-2</td><td>cell1-3</td></tr>' + 129 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 130 "</table>"; 131 beforeInputEvents = []; 132 inputEvents = []; 133 range = document.createRange(); 134 range.selectNode(document.getElementById("select")); 135 selection.addRange(range); 136 getTableEditor().deleteTableCell(1); 137 is(editor.innerHTML, "<table><tbody>" + 138 "<tr><td>cell1-1</td><td>cell1-3</td></tr>" + 139 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 140 "</tbody></table>", 141 "nsITableEditor.deleteTableCellContents(1) should remove only selected cell when only one cell is selected #1-2"); 142 is(beforeInputEvents.length, 1, 143 'Only one "beforeinput" event should be fired when only one cell is selected #1-2'); 144 checkInputEvent(beforeInputEvents[0], "when only one cell is selected #1-2"); 145 is(inputEvents.length, 1, 146 'Only one "input" event should be fired when only one cell is selected #1-2'); 147 checkInputEvent(inputEvents[0], "when only one cell is selected #1-2"); 148 149 selection.removeAllRanges(); 150 editor.innerHTML = "<table>" + 151 '<tr><td>cell1-1</td><td>cell1-2</td><td id="select">cell1-3</td></tr>' + 152 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 153 "</table>"; 154 beforeInputEvents = []; 155 inputEvents = []; 156 range = document.createRange(); 157 range.selectNode(document.getElementById("select")); 158 selection.addRange(range); 159 getTableEditor().deleteTableCell(1); 160 is(editor.innerHTML, "<table><tbody>" + 161 "<tr><td>cell1-1</td><td>cell1-2</td></tr>" + 162 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 163 "</tbody></table>", 164 "nsITableEditor.deleteTableCellContents(1) should remove only selected cell when only one cell is selected #1-3"); 165 is(beforeInputEvents.length, 1, 166 'Only one "beforeinput" event should be fired when only one cell is selected #1-3'); 167 checkInputEvent(beforeInputEvents[0], "when only one cell is selected #1-3"); 168 is(inputEvents.length, 1, 169 'Only one "input" event should be fired when only one cell is selected #1-3'); 170 checkInputEvent(inputEvents[0], "when only one cell is selected #1-3"); 171 172 // When only one cell element is selected, the argument should be used. 173 selection.removeAllRanges(); 174 editor.innerHTML = "<table>" + 175 '<tr><td id="select">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>' + 176 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 177 "</table>"; 178 beforeInputEvents = []; 179 inputEvents = []; 180 range = document.createRange(); 181 range.selectNode(document.getElementById("select")); 182 selection.addRange(range); 183 getTableEditor().deleteTableCell(2); 184 is(editor.innerHTML, "<table><tbody>" + 185 "<tr><td>cell1-3</td></tr>" + 186 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 187 "</tbody></table>", 188 "nsITableEditor.deleteTableCellContents(2) should remove selected cell element and next cell element in same row #1-4"); 189 is(beforeInputEvents.length, 1, 190 'Only one "beforeinput" event should be fired when only one cell is selected #1-4'); 191 checkInputEvent(beforeInputEvents[0], "when only one cell is selected #1-4"); 192 is(inputEvents.length, 1, 193 'Only one "input" event should be fired when only one cell is selected #1-4'); 194 checkInputEvent(inputEvents[0], "when only one cell is selected #1-4"); 195 196 // When the argument is larger than remaining cell elements from selected 197 // cell element, the behavior is really buggy. 198 selection.removeAllRanges(); 199 editor.innerHTML = "<table>" + 200 '<tr><td>cell1-1</td><td>cell1-2</td><td id="select">cell1-3</td></tr>' + 201 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 202 "</table>"; 203 beforeInputEvents = []; 204 inputEvents = []; 205 range = document.createRange(); 206 range.selectNode(document.getElementById("select")); 207 selection.addRange(range); 208 getTableEditor().deleteTableCell(2); 209 is(editor.innerHTML, "<table><tbody>" + 210 "<tr><td>cell1-1</td></tr>" + 211 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 212 "</tbody></table>", 213 "nsITableEditor.deleteTableCellContents(2) should remove selected cell element and its previous cell element when it reaches the last cell element in the row"); 214 is(beforeInputEvents.length, 1, 215 'Only one "beforeinput" event should be fired when the argument is larger than remaining cell elements from selected cell element'); 216 checkInputEvent(beforeInputEvents[0], "when the argument is larger than remaining cell elements from selected cell element"); 217 is(inputEvents.length, 1, 218 'Only one "input" event should be fired when the argument is larger than remaining cell elements from selected cell element'); 219 checkInputEvent(inputEvents[0], "when the argument is larger than remaining cell elements from selected cell element"); 220 221 // XXX If the former case is expected, first row should be removed in this 222 // case, but it removes only selected cell and its previous cell. 223 selection.removeAllRanges(); 224 editor.innerHTML = "<table>" + 225 '<tr><td>cell1-1</td><td>cell1-2</td><td id="select">cell1-3</td></tr>' + 226 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 227 "</table>"; 228 beforeInputEvents = []; 229 inputEvents = []; 230 range = document.createRange(); 231 range.selectNode(document.getElementById("select")); 232 selection.addRange(range); 233 getTableEditor().deleteTableCell(4); 234 todo_is(editor.innerHTML, "<table><tbody>" + 235 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 236 "</tbody></table>", 237 "nsITableEditor.deleteTableCellContents(4) should remove the first row when a cell in it is selected and the argument is larger than number of cells in the row"); 238 is(beforeInputEvents.length, 1, 239 'Only one "beforeinput" event should be fired when the argument is larger than number of cells in the row'); 240 checkInputEvent(beforeInputEvents[0], "when the argument is larger than number of cells in the row"); 241 is(inputEvents.length, 1, 242 'Only one "input" event should be fired when the argument is larger than number of cells in the row'); 243 checkInputEvent(inputEvents[0], "when the argument is larger than number of cells in the row"); 244 245 // If 2 or more cells are selected, the argument should be ignored. 246 selection.removeAllRanges(); 247 editor.innerHTML = "<table>" + 248 '<tr><td id="select1">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>' + 249 '<tr><td>cell2-1</td><td id="select2">cell2-2</td><td>cell2-3</td></tr>' + 250 "</table>"; 251 beforeInputEvents = []; 252 inputEvents = []; 253 range = document.createRange(); 254 range.selectNode(document.getElementById("select1")); 255 selection.addRange(range); 256 range = document.createRange(); 257 range.selectNode(document.getElementById("select2")); 258 selection.addRange(range); 259 getTableEditor().deleteTableCell(1); 260 is(editor.innerHTML, "<table><tbody>" + 261 "<tr><td>cell1-2</td><td>cell1-3</td></tr>" + 262 "<tr><td>cell2-1</td><td>cell2-3</td></tr>" + 263 "</tbody></table>", 264 "nsITableEditor.deleteTableCellContents(1) should remove selected cell elements even if the argument is smaller than number of selected cells"); 265 is(beforeInputEvents.length, 1, 266 'Only one "beforeinput" event should be fired even if the argument is smaller than number of selected cells'); 267 checkInputEvent(beforeInputEvents[0], "even if the argument is smaller than number of selected cells"); 268 is(inputEvents.length, 1, 269 'Only one "input" event should be fired even if the argument is smaller than number of selected cells'); 270 checkInputEvent(inputEvents[0], "even if the argument is smaller than number of selected cells"); 271 272 // If all cells in a row are selected, the <tr> element should also be removed. 273 selection.removeAllRanges(); 274 editor.innerHTML = "<table>" + 275 '<tr><td id="select1">cell1-1</td><td id="select2">cell1-2</td><td id="select3">cell1-3</td></tr>' + 276 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 277 "</table>"; 278 beforeInputEvents = []; 279 inputEvents = []; 280 range = document.createRange(); 281 range.selectNode(document.getElementById("select1")); 282 selection.addRange(range); 283 range = document.createRange(); 284 range.selectNode(document.getElementById("select2")); 285 selection.addRange(range); 286 range = document.createRange(); 287 range.selectNode(document.getElementById("select3")); 288 selection.addRange(range); 289 getTableEditor().deleteTableCell(1); 290 is(editor.innerHTML, "<table><tbody>" + 291 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 292 "</tbody></table>", 293 "nsITableEditor.deleteTableCellContents(1) should remove also <tr> element when all cell elements in a row is selected"); 294 is(beforeInputEvents.length, 1, 295 'Only one "beforeinput" event should be fired when all cell elements in a row is selected'); 296 checkInputEvent(beforeInputEvents[0], "when all cell elements in a row is selected"); 297 is(inputEvents.length, 1, 298 'Only one "input" event should be fired when all cell elements in a row is selected'); 299 checkInputEvent(inputEvents[0], "when all cell elements in a row is selected"); 300 301 selection.removeAllRanges(); 302 editor.innerHTML = "<table>" + 303 '<tr><td id="select">cell1-1</td></tr>' + 304 "<tr><td>cell2-1</td></tr>" + 305 "</table>"; 306 beforeInputEvents = []; 307 inputEvents = []; 308 range = document.createRange(); 309 range.selectNode(document.getElementById("select")); 310 selection.addRange(range); 311 getTableEditor().deleteTableCell(1); 312 is(editor.innerHTML, "<table><tbody>" + 313 "<tr><td>cell2-1</td></tr>" + 314 "</tbody></table>", 315 "nsITableEditor.deleteTableCellContents(1) should remove also <tr> element when a cell element which is only child of a row is selected"); 316 is(beforeInputEvents.length, 1, 317 'Only one "beforeinput" event should be fired when a cell element which is only child of a row is selected'); 318 checkInputEvent(beforeInputEvents[0], "when a cell element which is only child of a row is selected"); 319 is(inputEvents.length, 1, 320 'Only one "input" event should be fired when a cell element which is only child of a row is selected'); 321 checkInputEvent(inputEvents[0], "when a cell element which is only child of a row is selected"); 322 323 // If all cells are removed, the <table> element should be removed. 324 selection.removeAllRanges(); 325 editor.innerHTML = "<table>" + 326 '<tr><td id="select1">cell1-1</td><td id="select2">cell1-2</td></tr>' + 327 '<tr><td id="select3">cell2-1</td><td id="select4">cell2-2</td></tr>' + 328 "</table>"; 329 beforeInputEvents = []; 330 inputEvents = []; 331 range = document.createRange(); 332 range.selectNode(document.getElementById("select1")); 333 selection.addRange(range); 334 range = document.createRange(); 335 range.selectNode(document.getElementById("select2")); 336 selection.addRange(range); 337 range = document.createRange(); 338 range.selectNode(document.getElementById("select3")); 339 selection.addRange(range); 340 range = document.createRange(); 341 range.selectNode(document.getElementById("select4")); 342 selection.addRange(range); 343 getTableEditor().deleteTableCell(1); 344 is(editor.innerHTML, "", 345 "nsITableEditor.deleteTableCellContents(1) should remove also <table> element when all cell elements are selected"); 346 is(beforeInputEvents.length, 1, 347 'Only one "beforeinput" event should be fired when all cell elements are selected'); 348 checkInputEvent(beforeInputEvents[0], "when all cell elements are selected"); 349 is(inputEvents.length, 1, 350 'Only one "input" event should be fired when all cell elements are selected'); 351 checkInputEvent(inputEvents[0], "when all cell elements are selected"); 352 353 selection.removeAllRanges(); 354 editor.innerHTML = "<table>" + 355 '<tr><td id="select">cell1-1</td></tr>' + 356 "</table>"; 357 beforeInputEvents = []; 358 inputEvents = []; 359 range = document.createRange(); 360 range.selectNode(document.getElementById("select")); 361 selection.addRange(range); 362 getTableEditor().deleteTableCell(1); 363 is(editor.innerHTML, "", 364 "nsITableEditor.deleteTableCellContents(1) should remove also <table> element when a cell element which is only child of <table> is selected"); 365 is(beforeInputEvents.length, 1, 366 'Only one "beforeinput" event should be fired when a cell element which is only child of <table> is selected'); 367 checkInputEvent(beforeInputEvents[0], "when a cell element which is only child of <table> is selected"); 368 is(inputEvents.length, 1, 369 'Only one "input" event should be fired when a cell element which is only child of <table> is selected'); 370 checkInputEvent(inputEvents[0], "when a cell element which is only child of <table> is selected"); 371 372 // rowspan 373 selection.removeAllRanges(); 374 editor.innerHTML = "<table>" + 375 '<tr><td id="select" rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 376 "<tr><td>cell2-2</td></tr>" + 377 "<tr><td>cell3-1</td><td>cell3-2</td></tr>" + 378 "</table>"; 379 beforeInputEvents = []; 380 inputEvents = []; 381 range = document.createRange(); 382 range.selectNode(document.getElementById("select")); 383 selection.addRange(range); 384 getTableEditor().deleteTableCell(1); 385 is(editor.innerHTML, "<table><tbody>" + 386 "<tr><td>cell1-2</td></tr>" + 387 "<tr><td>cell2-2</td></tr>" + 388 "<tr><td>cell3-1</td><td>cell3-2</td></tr>" + 389 "</tbody></table>", 390 "nsITableEditor.deleteTableCellContents(1) should just remove the cell spanning rows"); 391 is(beforeInputEvents.length, 1, 392 'Only one "beforeinput" event should be fired when removing the cell spanning rows'); 393 checkInputEvent(beforeInputEvents[0], "when removing the cell spanning rows"); 394 is(inputEvents.length, 1, 395 'Only one "input" event should be fired when removing the cell spanning rows'); 396 checkInputEvent(inputEvents[0], "when removing the cell spanning rows"); 397 398 // XXX cell3-1 is also removed even though it's not selected. 399 selection.removeAllRanges(); 400 editor.innerHTML = "<table>" + 401 '<tr><td id="select1" rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 402 "<tr><td>cell2-2</td></tr>" + 403 '<tr><td>cell3-1</td><td id="select2">cell3-2</td></tr>' + 404 "</table>"; 405 beforeInputEvents = []; 406 inputEvents = []; 407 range = document.createRange(); 408 range.selectNode(document.getElementById("select1")); 409 selection.addRange(range); 410 range = document.createRange(); 411 range.selectNode(document.getElementById("select2")); 412 selection.addRange(range); 413 getTableEditor().deleteTableCell(1); 414 todo_is(editor.innerHTML, "<table><tbody>" + 415 "<tr><td>cell1-2</td></tr>" + 416 "<tr><td>cell2-2</td></tr>" + 417 "<tr><td>cell3-1</td></tr>" + 418 "</tbody></table>", 419 "nsITableEditor.deleteTableCellContents(1) should just remove the cell spanning rows (when 2 cell elements are selected)"); 420 is(beforeInputEvents.length, 1, 421 'Only one "beforeinput" event should be fired when removing the cell spanning rows (when 2 cell elements are selected)'); 422 checkInputEvent(beforeInputEvents[0], "when removing the cell spanning rows (when 2 cell elements are selected)"); 423 is(inputEvents.length, 1, 424 'Only one "input" event should be fired when removing the cell spanning rows (when 2 cell elements are selected)'); 425 checkInputEvent(inputEvents[0], "when removing the cell spanning rows (when 2 cell elements are selected)"); 426 427 selection.removeAllRanges(); 428 editor.innerHTML = "<table>" + 429 '<tr><td rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 430 '<tr><td id="select">cell2-2</td></tr>' + 431 "<tr><td>cell3-1</td><td>cell3-2</td></tr>" + 432 "</table>"; 433 beforeInputEvents = []; 434 inputEvents = []; 435 range = document.createRange(); 436 range.selectNode(document.getElementById("select")); 437 selection.addRange(range); 438 getTableEditor().deleteTableCell(1); 439 is(editor.innerHTML, "<table><tbody>" + 440 '<tr><td rowspan="1">cell1-1</td><td>cell1-2</td></tr>' + 441 "<tr><td>cell3-1</td><td>cell3-2</td></tr>" + 442 "</tbody></table>", 443 "nsITableEditor.deleteTableCellContents(1) should adjust rowspan when spanned <tr>'s last child cell element is removed"); 444 is(beforeInputEvents.length, 1, 445 'Only one "beforeinput" event should be fired when spanned <tr>\'s last child cell element is removed'); 446 checkInputEvent(beforeInputEvents[0], "when spanned <tr>'s last child cell element is removed"); 447 is(inputEvents.length, 1, 448 'Only one "input" event should be fired when spanned <tr>\'s last child cell element is removed'); 449 checkInputEvent(inputEvents[0], "when spanned <tr>'s last child cell element is removed"); 450 451 // XXX broken case, the second row isn't removed. 452 selection.removeAllRanges(); 453 editor.innerHTML = "<table>" + 454 '<tr><td rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 455 '<tr><td id="select1">cell2-2</td></tr>' + 456 '<tr><td>cell3-1</td><td id="select2">cell3-2</td></tr>' + 457 "</table>"; 458 beforeInputEvents = []; 459 inputEvents = []; 460 range = document.createRange(); 461 range.selectNode(document.getElementById("select1")); 462 selection.addRange(range); 463 range = document.createRange(); 464 range.selectNode(document.getElementById("select2")); 465 selection.addRange(range); 466 getTableEditor().deleteTableCell(1); 467 todo_is(editor.innerHTML, "<table><tbody>" + 468 '<tr><td rowspan="1">cell1-1</td><td>cell1-2</td></tr>' + 469 "<tr><td>cell3-1</td></tr>" + 470 "</tbody></table>", 471 "nsITableEditor.deleteTableCellContents(1) should adjust rowspan when spanned <tr>'s last child cell element is removed (when 2 cell elements are selected)"); 472 is(beforeInputEvents.length, 1, 473 'Only one "beforeinput" event should be fired when spanned <tr>\'s last child cell element is removed (when 2 cell elements are selected)'); 474 checkInputEvent(beforeInputEvents[0], "when spanned <tr>'s last child cell element is removed (when 2 cell elements are selected)"); 475 is(inputEvents.length, 1, 476 'Only one "input" event should be fired when spanned <tr>\'s last child cell element is removed (when 2 cell elements are selected)'); 477 checkInputEvent(inputEvents[0], "when spanned <tr>'s last child cell element is removed (when 2 cell elements are selected)"); 478 479 // XXX broken case, neither the selected cell nor the second row is removed. 480 selection.removeAllRanges(); 481 editor.innerHTML = "<table>" + 482 '<tr><td rowspan="3">cell1-1</td><td>cell1-2</td></tr>' + 483 '<tr><td id="select">cell2-2</td></tr>' + 484 "<tr><td>cell3-1</td><td>cell3-2</td></tr>" + 485 "</table>"; 486 beforeInputEvents = []; 487 inputEvents = []; 488 range = document.createRange(); 489 range.selectNode(document.getElementById("select")); 490 selection.addRange(range); 491 getTableEditor().deleteTableCell(1); 492 todo_is(editor.innerHTML, "<table><tbody>" + 493 '<tr><td rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 494 "<tr><td>cell3-2</td></tr>" + 495 "</tbody></table>", 496 "nsITableEditor.deleteTableCellContents(1) should adjust rowspan when spanned <tr>'s last child cell element is removed (removing middle row)"); 497 is(beforeInputEvents.length, 1, 498 'Only one "beforeinput" event should be fired when spanned <tr>\'s last child cell element is removed (removing middle row)'); 499 checkInputEvent(beforeInputEvents[0], "when spanned <tr>'s last child cell element is removed (removing middle row)"); 500 todo_is(inputEvents.length, 1, 501 'Only one "input" event should be fired when spanned <tr>\'s last child cell element is removed (removing middle row)'); 502 if (inputEvents.length) { 503 checkInputEvent(inputEvents[0], "when spanned <tr>'s last child cell element is removed (removing middle row)"); 504 } 505 506 selection.removeAllRanges(); 507 editor.innerHTML = "<table>" + 508 '<tr><td rowspan="3">cell1-1</td><td>cell1-2</td></tr>' + 509 '<tr><td id="select1">cell2-2</td></tr>' + 510 '<tr><td>cell3-1</td><td id="select2">cell3-2</td></tr>' + 511 "</table>"; 512 beforeInputEvents = []; 513 inputEvents = []; 514 range = document.createRange(); 515 range.selectNode(document.getElementById("select1")); 516 selection.addRange(range); 517 range = document.createRange(); 518 range.selectNode(document.getElementById("select2")); 519 selection.addRange(range); 520 getTableEditor().deleteTableCell(1); 521 todo_is(editor.innerHTML, "<table><tbody>" + 522 '<tr><td rowspan="2">cell1-1</td><td>cell1-2</td></tr>' + 523 "</tbody></table>", 524 "nsITableEditor.deleteTableCellContents(1) should adjust rowspan when spanned <tr>'s last child cell element and remove the last row"); 525 is(beforeInputEvents.length, 1, 526 'Only one "beforeinput" event should be fired when spanned <tr>\'s last child cell element and remove the last row'); 527 checkInputEvent(beforeInputEvents[0], "when spanned <tr>'s last child cell element and remove the last row"); 528 is(inputEvents.length, 1, 529 'Only one "input" event should be fired when spanned <tr>\'s last child cell element and remove the last row'); 530 checkInputEvent(inputEvents[0], "when spanned <tr>'s last child cell element and remove the last row"); 531 532 // colspan 533 selection.removeAllRanges(); 534 editor.innerHTML = "<table>" + 535 '<tr><td id="select" colspan="2">cell1-1</td><td>cell1-3</td></tr>' + 536 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 537 "</table>"; 538 beforeInputEvents = []; 539 inputEvents = []; 540 range = document.createRange(); 541 range.selectNode(document.getElementById("select")); 542 selection.addRange(range); 543 getTableEditor().deleteTableCell(1); 544 is(editor.innerHTML, "<table><tbody>" + 545 "<tr><td>cell1-3</td></tr>" + 546 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 547 "</tbody></table>", 548 "nsITableEditor.deleteTableCellContents(1) should just remove the cell spanning columns"); 549 is(beforeInputEvents.length, 1, 550 'Only one "beforeinput" event should be fired when removing the cell spanning columns'); 551 checkInputEvent(beforeInputEvents[0], "when removing the cell spanning columns"); 552 is(inputEvents.length, 1, 553 'Only one "input" event should be fired when removing the cell spanning columns'); 554 checkInputEvent(inputEvents[0], "when removing the cell spanning columns"); 555 556 selection.removeAllRanges(); 557 editor.innerHTML = "<table>" + 558 '<tr><td id="select1" colspan="2">cell1-1</td><td>cell1-3</td></tr>' + 559 '<tr><td>cell2-1</td><td id="select2">cell2-2</td><td>cell2-3</td></tr>' + 560 "</table>"; 561 beforeInputEvents = []; 562 inputEvents = []; 563 range = document.createRange(); 564 range.selectNode(document.getElementById("select1")); 565 selection.addRange(range); 566 range = document.createRange(); 567 range.selectNode(document.getElementById("select2")); 568 selection.addRange(range); 569 getTableEditor().deleteTableCell(1); 570 is(editor.innerHTML, "<table><tbody>" + 571 "<tr><td>cell1-3</td></tr>" + 572 "<tr><td>cell2-1</td><td>cell2-3</td></tr>" + 573 "</tbody></table>", 574 "nsITableEditor.deleteTableCellContents(1) should just remove the cell spanning columns and the other selected cell element"); 575 is(beforeInputEvents.length, 1, 576 'Only one "beforeinput" event should be fired when removing the cell spanning columns and the other selected cell element'); 577 checkInputEvent(beforeInputEvents[0], "when removing the cell spanning columns and the other selected cell element"); 578 is(inputEvents.length, 1, 579 'Only one "input" event should be fired when removing the cell spanning columns and the other selected cell element'); 580 checkInputEvent(inputEvents[0], "when removing the cell spanning columns and the other selected cell element"); 581 582 // XXX broken case, colspan is not adjusted. 583 selection.removeAllRanges(); 584 editor.innerHTML = "<table>" + 585 '<tr><td colspan="2">cell1-1</td><td>cell1-3</td></tr>' + 586 '<tr><td>cell2-1</td><td id="select">cell2-2</td><td>cell2-3</td></tr>' + 587 "</table>"; 588 beforeInputEvents = []; 589 inputEvents = []; 590 range = document.createRange(); 591 range.selectNode(document.getElementById("select")); 592 selection.addRange(range); 593 getTableEditor().deleteTableCell(1); 594 todo_is(editor.innerHTML, "<table><tbody>" + 595 '<tr><td colspan="1">cell1-1</td><td>cell1-3</td></tr>' + 596 "<tr><td>cell2-1</td><td>cell2-3</td></tr>" + 597 "</tbody></table>", 598 "nsITableEditor.deleteTableCellContents(1) should adjust different row's colspan when corresponding cell element is removed"); 599 is(beforeInputEvents.length, 1, 600 'Only one "beforeinput" event should be fired when corresponding cell element is removed'); 601 checkInputEvent(beforeInputEvents[0], "when corresponding cell element is removed"); 602 is(inputEvents.length, 1, 603 'Only one "input" event should be fired when corresponding cell element is removed'); 604 checkInputEvent(inputEvents[0], "when corresponding cell element is removed"); 605 606 selection.removeAllRanges(); 607 editor.innerHTML = "<table>" + 608 '<tr><td colspan="2">cell1-1</td><td>cell1-3</td></tr>' + 609 '<tr><td>cell2-1</td><td id="select1">cell2-2</td><td id="select2">cell2-3</td></tr>' + 610 "</table>"; 611 beforeInputEvents = []; 612 inputEvents = []; 613 range = document.createRange(); 614 range.selectNode(document.getElementById("select1")); 615 selection.addRange(range); 616 range = document.createRange(); 617 range.selectNode(document.getElementById("select2")); 618 selection.addRange(range); 619 getTableEditor().deleteTableCell(1); 620 todo_is(editor.innerHTML, "<table><tbody>" + 621 '<tr><td colspan="1">cell1-1</td><td>cell1-3</td></tr>' + 622 "<tr><td>cell2-1</td></tr>" + 623 "</tbody></table>", 624 "nsITableEditor.deleteTableCellContents(1) should adjust different row's colspan when corresponding cell element is removed (when 2 cell elements are selected)"); 625 is(beforeInputEvents.length, 1, 626 'Only one "beforeinput" event should be fired when corresponding cell element is removed (when 2 cell elements are selected)'); 627 checkInputEvent(beforeInputEvents[0], "when corresponding cell element is removed (when 2 cell elements are selected)"); 628 is(inputEvents.length, 1, 629 'Only one "input" event should be fired when corresponding cell element is removed (when 2 cell elements are selected)'); 630 checkInputEvent(inputEvents[0], "when corresponding cell element is removed (when 2 cell elements are selected)"); 631 632 selection.removeAllRanges(); 633 editor.innerHTML = "<table>" + 634 '<tr><td>cell1-1</td><td id="select1">cell1-2</td><td>cell1-4</td></tr>' + 635 '<tr><td id="select2" colspan="2">cell2-1</td><td>cell2-3</td><td>cell2-4</td></tr>' + 636 "</table>"; 637 beforeInputEvents = []; 638 inputEvents = []; 639 range = document.createRange(); 640 range.selectNode(document.getElementById("select1")); 641 selection.addRange(range); 642 range = document.createRange(); 643 range.selectNode(document.getElementById("select2")); 644 selection.addRange(range); 645 getTableEditor().deleteTableCell(1); 646 is(editor.innerHTML, "<table><tbody>" + 647 "<tr><td>cell1-1</td><td>cell1-4</td></tr>" + 648 "<tr><td>cell2-3</td><td>cell2-4</td></tr>" + 649 "</tbody></table>", 650 "nsITableEditor.deleteTableCellContents(1) should adjust different row's colspan when corresponding cell element is removed (when 2 cell elements are selected)"); 651 is(beforeInputEvents.length, 1, 652 'Only one "beforeinput" event should be fired when corresponding cell element is removed (when 2 cell elements are selected)'); 653 checkInputEvent(beforeInputEvents[0], "when corresponding cell element is removed (when 2 cell elements are selected)"); 654 is(inputEvents.length, 1, 655 'Only one "input" event should be fired when corresponding cell element is removed (when 2 cell elements are selected)'); 656 checkInputEvent(inputEvents[0], "when corresponding cell element is removed (when 2 cell elements are selected)"); 657 658 // When a cell contains first selection range, it should be removed. 659 selection.removeAllRanges(); 660 editor.innerHTML = "<table>" + 661 '<tr><td id="select">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>' + 662 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 663 "</table>"; 664 beforeInputEvents = []; 665 inputEvents = []; 666 selection.setBaseAndExtent(document.getElementById("select").firstChild, 0, 667 document.getElementById("select").firstChild, 1); 668 getTableEditor().deleteTableCell(1); 669 is(editor.innerHTML, "<table><tbody>" + 670 "<tr><td>cell1-2</td><td>cell1-3</td></tr>" + 671 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 672 "</tbody></table>", 673 "nsITableEditor.deleteTableCellContents(1) should remove only a cell containing first selection range when there is no selected cell element"); 674 is(beforeInputEvents.length, 1, 675 'Only one "beforeinput" event should be fired when there is no selected cell element'); 676 checkInputEvent(beforeInputEvents[0], "when there is no selected cell element"); 677 is(inputEvents.length, 1, 678 'Only one "input" event should be fired when there is no selected cell element'); 679 checkInputEvent(inputEvents[0], "when there is no selected cell element"); 680 681 selection.removeAllRanges(); 682 editor.innerHTML = "<table>" + 683 '<tr><td id="select">cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>' + 684 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 685 "</table>"; 686 beforeInputEvents = []; 687 inputEvents = []; 688 selection.setBaseAndExtent(document.getElementById("select").firstChild, 0, 689 document.getElementById("select").firstChild, 1); 690 getTableEditor().deleteTableCell(2); 691 is(editor.innerHTML, "<table><tbody>" + 692 "<tr><td>cell1-3</td></tr>" + 693 "<tr><td>cell2-1</td><td>cell2-2</td><td>cell2-3</td></tr>" + 694 "</tbody></table>", 695 "nsITableEditor.deleteTableCellContents(2) should remove only 2 cell elements starting from a cell containing first selection range when there is no selected cell element"); 696 is(beforeInputEvents.length, 1, 697 'Only one "beforeinput" event should be fired when there is no selected cell element'); 698 checkInputEvent(beforeInputEvents[0], "when there is no selected cell element"); 699 is(inputEvents.length, 1, 700 'Only one "input" event should be fired when there is no selected cell element'); 701 checkInputEvent(inputEvents[0], "when there is no selected cell element"); 702 703 editor.removeEventListener("input", onInput); 704 705 SimpleTest.finish(); 706 }); 707 708 function getTableEditor() { 709 var editingSession = SpecialPowers.wrap(window).docShell.editingSession; 710 return editingSession.getEditorForWindow(window).QueryInterface(SpecialPowers.Ci.nsITableEditor); 711 } 712 713 </script> 714 </body> 715 716 </html>