Files
firefox/editor/libeditor/tests/test_nsITableEditor_deleteTableRow.html
Emilio Cobos Álvarez a1007b18c6 Bug 1839223 - Remove nsMappedAttributes. r=smaug
Instead, lazily schedule evaluation of them before styling, much like we
were doing for SVG.

A subtle tweak is that we only remain scheduled while in the document.
This allows us to use the "in document" bit plus the "mapped attributes
dirty" bit to know our scheduled status. It also prevents doing silly
work for disconnected elements, and having to do hashmap lookups on
adoption and node destruction.

Differential Revision: https://phabricator.services.mozilla.com/D181549
2023-06-22 17:22:03 +00:00

523 lines
29 KiB
HTML

<!DOCTYPE>
<html>
<head>
<title>Test for nsITableEditor.deleteTableRow()</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<div id="display">
</div>
<div id="content" contenteditable>out of table<table><tr><td>default content</td></tr></table></div>
<pre id="test">
</pre>
<script class="testbody" type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(() => {
let editor = document.getElementById("content");
let selection = document.getSelection();
let selectionRanges = [];
function checkInputEvent(aEvent, aDescription) {
ok(aEvent instanceof InputEvent,
`"${aEvent.type}" event should be dispatched with InputEvent interface ${aDescription}`);
is(aEvent.cancelable, aEvent.type === "beforeinput",
`"${aEvent.type}" event should ${aEvent.type === "beforeinput" ? "be" : "be never"} cancelable ${aDescription}`);
is(aEvent.bubbles, true,
`"${aEvent.type}" event should always bubble ${aDescription}`);
is(aEvent.inputType, "deleteContent",
`inputType of "${aEvent.type}" event should be "deleteContent" ${aDescription}`);
is(aEvent.data, null,
`data of "${aEvent.type}" event should be null ${aDescription}`);
is(aEvent.dataTransfer, null,
`dataTransfer of "${aEvent.type}" event should be null ${aDescription}`);
let targetRanges = aEvent.getTargetRanges();
if (aEvent.type === "beforeinput") {
is(targetRanges.length, selectionRanges.length,
`getTargetRanges() of "beforeinput" event should return selection ranges ${aDescription}`);
if (targetRanges.length === selectionRanges.length) {
for (let i = 0; i < selectionRanges.length; i++) {
is(targetRanges[i].startContainer, selectionRanges[i].startContainer,
`startContainer of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`);
is(targetRanges[i].startOffset, selectionRanges[i].startOffset,
`startOffset of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`);
is(targetRanges[i].endContainer, selectionRanges[i].endContainer,
`endContainer of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`);
is(targetRanges[i].endOffset, selectionRanges[i].endOffset,
`endOffset of getTargetRanges()[${i}] of "beforeinput" event does not match ${aDescription}`);
}
}
} else {
is(targetRanges.length, 0,
`getTargetRanges() of "${aEvent.type}" event should return empty array ${aDescription}`);
}
}
let beforeInputEvents = [];
let inputEvents = [];
function onBeforeInput(aEvent) {
beforeInputEvents.push(aEvent);
selectionRanges = [];
for (let i = 0; i < selection.rangeCount; i++) {
let range = selection.getRangeAt(i);
selectionRanges.push({startContainer: range.startContainer, startOffset: range.startOffset,
endContainer: range.endContainer, endOffset: range.endOffset});
}
}
function onInput(aEvent) {
inputEvents.push(aEvent);
}
editor.addEventListener("beforeinput", onBeforeInput);
editor.addEventListener("input", onInput);
beforeInputEvents = [];
inputEvents = [];
selection.collapse(editor.firstChild, 0);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "out of table<table><tbody><tr><td>default content</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should do nothing if selection is not in <table>");
is(beforeInputEvents.length, 1,
'"beforeinput" event should be fired when a call of nsITableEditor.deleteTableRow(1) even though it will do nothing');
checkInputEvent(beforeInputEvents[0], "when selection is collapsed outside table element (nsITableEditor.deleteTableRow(1))");
is(inputEvents.length, 0,
'No "input" event should be fired when a call of nsITableEditor.deleteTableRow(1) does nothing');
selection.removeAllRanges();
try {
beforeInputEvents = [];
inputEvents = [];
getTableEditor().deleteTableRow(1);
ok(false, "getTableEditor().deleteTableRow(1) without selection ranges should throw exception");
} catch (e) {
ok(true, "getTableEditor().deleteTableRow(1) without selection ranges should throw exception");
is(beforeInputEvents.length, 0,
'No "beforeinput" event should be fired when nsITableEditor.deleteTableRow(1) causes exception due to no selection range');
is(inputEvents.length, 0,
'No "input" event should be fired when nsITableEditor.deleteTableRow(1) causes exception due to no selection range');
}
// If a cell is selected and the argument is less than number of rows,
// specified number of rows should be removed starting from the row
// containing the selected cell. But if the argument is same or
// larger than actual number of rows when a cell in the first row is
// selected, the <table> should be removed.
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
let range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody><tr><td>cell2-1</td><td>cell2-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete the first row when a cell in the first row is selected");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in the first row is selected');
checkInputEvent(beforeInputEvents[0], "when a cell in the first row is selected");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in the first row is selected');
checkInputEvent(inputEvents[0], "when a cell in the first row is selected");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody><tr><td>cell1-1</td><td>cell1-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete the second row when a cell in the second row is selected");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in the second row is selected');
checkInputEvent(beforeInputEvents[0], "when a cell in the second row is selected");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in the second row is selected');
checkInputEvent(inputEvents[0], "when a cell in the second row is selected");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(2);
is(editor.innerHTML, "",
"nsITableEditor.deleteTableRow(2) should delete the <table> since there is only 2 rows");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in first row is selected and argument is same as number of rows');
checkInputEvent(beforeInputEvents[0], "when a cell in first row is selected and argument is same as number of rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in first row is selected and argument is same as number of rows');
checkInputEvent(inputEvents[0], "when a cell in first row is selected and argument is same as number of rows");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(3);
is(editor.innerHTML, "",
"nsITableEditor.deleteTableRow(3) should delete the <table> when argument is larger than actual number of rows");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when argument is larger than actual number of rows');
checkInputEvent(beforeInputEvents[0], "when argument is larger than actual number of rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when argument is larger than actual number of rows');
checkInputEvent(inputEvents[0], "when argument is larger than actual number of rows");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(2);
is(editor.innerHTML, "<table><tbody><tr><td>cell1-1</td><td>cell1-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(2) should delete the second row containing selected cell and next row");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in second row and argument is same as the remaining rows');
checkInputEvent(beforeInputEvents[0], "when a cell in second row and argument is same as the remaining rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in second row and argument is same as the remaining rows');
checkInputEvent(inputEvents[0], "when a cell in second row and argument is same as the remaining rows");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(3);
is(editor.innerHTML, "<table><tbody><tr><td>cell1-1</td><td>cell1-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(3) should delete the second row (containing selected cell) and the third row even though the argument is larger than the rows");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in second row and argument is larger than the remaining rows');
checkInputEvent(beforeInputEvents[0], "when a cell in second row and argument is larger than the remaining rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in second row and argument is larger than the remaining rows');
checkInputEvent(inputEvents[0], "when a cell in second row and argument is larger than the remaining rows");
// Similar to selected a cell, when selection is in a cell, the cell should
// treated as selected.
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody><tr><td>cell2-1</td><td>cell2-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete the first row when a cell in the first row contains selection range");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in the first row contains selection range');
checkInputEvent(beforeInputEvents[0], "when a cell in the first row contains selection range");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in the first row contains selection range');
checkInputEvent(inputEvents[0], "when a cell in the first row contains selection range");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody><tr><td>cell1-1</td><td>cell1-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete the second row when a cell in the second row contains selection range");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in the second row contains selection range');
checkInputEvent(beforeInputEvents[0], "when a cell in the second row contains selection range");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in the second row contains selection range');
checkInputEvent(inputEvents[0], "when a cell in the second row contains selection range");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
getTableEditor().deleteTableRow(2);
is(editor.innerHTML, "",
"nsITableEditor.deleteTableRow(2) should delete the <table> since there is only 2 rows");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when all text in a cell in first row is selected and argument includes next row');
checkInputEvent(beforeInputEvents[0], "when all text in a cell in first row is selected and argument includes next row");
is(inputEvents.length, 1,
'Only one "input" event should be fired when all text in a cell in first row is selected and argument includes next row');
checkInputEvent(inputEvents[0], "when all text in a cell in first row is selected and argument includes next row");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
getTableEditor().deleteTableRow(3);
is(editor.innerHTML, "",
"nsITableEditor.deleteTableRow(3) should delete the <table> when argument is larger than actual number of rows");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when all text in a cell in first row is selected and argument is same as number of all rows');
checkInputEvent(beforeInputEvents[0], "when all text in a cell in first row is selected and argument is same as number of all rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when all text in a cell in first row is selected and argument is same as number of all rows');
checkInputEvent(inputEvents[0], "when all text in a cell in first row is selected and argument is same as number of all rows");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
getTableEditor().deleteTableRow(2);
is(editor.innerHTML, "<table><tbody><tr><td>cell1-1</td><td>cell1-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(2) should delete the second row containing a cell containing selection range and next row");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when all text in a cell is selected and argument is same than renaming number of rows');
checkInputEvent(beforeInputEvents[0], "when all text in a cell is selected and argument is same than renaming number of rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when all text in a cell is selected and argument is same than renaming number of rows');
checkInputEvent(inputEvents[0], "when all text in a cell is selected and argument is same than renaming number of rows");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td>cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select").firstChild);
selection.addRange(range);
getTableEditor().deleteTableRow(3);
is(editor.innerHTML, "<table><tbody><tr><td>cell1-1</td><td>cell1-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(3) should delete the second row (containing selection range) and the third row even though the argument is larger than the rows");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when all text in a cell in the second row and argument is larger than renaming number of rows');
checkInputEvent(beforeInputEvents[0], "when all text in a cell in the second row and argument is larger than renaming number of rows");
is(inputEvents.length, 1,
'Only one "input" event should be fired when all text in a cell in the second row and argument is larger than renaming number of rows');
checkInputEvent(inputEvents[0], "when all text in a cell in the second row and argument is larger than renaming number of rows");
// The argument should be ignored when 2 or more cells are selected.
// XXX If the argument is less than number of rows and cells in all rows are
// selected, only all rows are removed. However, this leaves empty <table>
// element. Is this expected?
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select1">cell1-1</td><td>cell1-2</td></tr><tr><td id="select2">cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select1"));
selection.addRange(range);
range = document.createRange();
range.selectNode(document.getElementById("select2"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete all rows if every row's cell is selected");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when cells in every row are selected #1');
checkInputEvent(beforeInputEvents[0], "when cells in every row are selected #1");
is(inputEvents.length, 1,
'Only one "input" event should be fired when cells in every row are selected #1');
checkInputEvent(inputEvents[0], "when cells in every row are selected #1");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select1">cell1-1</td><td>cell1-2</td></tr><tr><td id="select2">cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select1"));
selection.addRange(range);
range = document.createRange();
range.selectNode(document.getElementById("select2"));
selection.addRange(range);
getTableEditor().deleteTableRow(2);
is(editor.innerHTML, "",
"nsITableEditor.deleteTableRow(2) should delete the <table> since 2 is number of rows of the <table>");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when cells in every row are selected #2');
checkInputEvent(beforeInputEvents[0], "when cells in every row are selected #2");
is(inputEvents.length, 1,
'Only one "input" event should be fired when cells in every row are selected #2');
checkInputEvent(inputEvents[0], "when cells in every row are selected #2");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select1">cell1-1</td><td id="select2">cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select1"));
selection.addRange(range);
range = document.createRange();
range.selectNode(document.getElementById("select2"));
selection.addRange(range);
getTableEditor().deleteTableRow(2);
is(editor.innerHTML, "",
"nsITableEditor.deleteTableRow(2) should delete the <table> since 2 is number of rows of the <table>");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when 2 cells in same row are selected');
checkInputEvent(beforeInputEvents[0], "when 2 cells in same row are selected");
is(inputEvents.length, 1,
'Only one "input" event should be fired when 2 cells in same row are selected');
checkInputEvent(inputEvents[0], "when 2 cells in same row are selected");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select1">cell1-1</td><td>cell1-2</td></tr><tr><td id="select2">cell2-1</td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select1"));
selection.addRange(range);
range = document.createRange();
range.selectNode(document.getElementById("select2"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody><tr><td>cell3-1</td><td>cell3-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete first 2 rows because cells in the both rows are selected");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when 2 cell elements in different rows are selected #1');
checkInputEvent(beforeInputEvents[0], "when 2 cell elements in different rows are selected #1");
is(inputEvents.length, 1,
'Only one "input" event should be fired when 2 cell elements in different rows are selected #1');
checkInputEvent(inputEvents[0], "when 2 cell elements in different rows are selected #1");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select1">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-1</td><td>cell2-2</td></tr><tr><td id="select2">cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select1"));
selection.addRange(range);
range = document.createRange();
range.selectNode(document.getElementById("select2"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, "<table><tbody><tr><td>cell2-1</td><td>cell2-2</td></tr></tbody></table>",
"nsITableEditor.deleteTableRow(1) should delete the first and the last rows because cells in the both rows are selected");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when 2 cell elements in different rows are selected #2');
checkInputEvent(beforeInputEvents[0], "when 2 cell elements in different rows are selected #2");
is(inputEvents.length, 1,
'Only one "input" event should be fired when 2 cell elements in different rows are selected #2');
checkInputEvent(inputEvents[0], "when 2 cell elements in different rows are selected #2");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select" rowspan="2">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, '<table><tbody><tr><td valign="top"><br></td><td>cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></tbody></table>',
"nsITableEditor.deleteTableRow(1) with a selected cell is rowspan=\"2\" should delete the first row and add empty cell to the second row");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell is selected and its rowspan is 2');
checkInputEvent(beforeInputEvents[0], "when a cell is selected and its rowspan is 2");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell is selected and its rowspan is 2');
checkInputEvent(inputEvents[0], "when a cell is selected and its rowspan is 2");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td id="select" rowspan="3">cell1-1</td><td>cell1-2</td></tr><tr><td>cell2-2</td></tr><tr><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, '<table><tbody><tr><td valign="top" rowspan="2"><br></td><td>cell2-2</td></tr><tr><td>cell3-2</td></tr></tbody></table>',
"nsITableEditor.deleteTableRow(1) with a selected cell is rowspan=\"3\" should delete the first row and add empty cell whose rowspan is 2 to the second row");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell is selected and its rowspan is 3');
checkInputEvent(beforeInputEvents[0], "when a cell is selected and its rowspan is 3");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell is selected and its rowspan is 3');
checkInputEvent(inputEvents[0], "when a cell is selected and its rowspan is 3");
// XXX Must be buggy case. When removing a row which does not have a cell due
// to rowspan, the rowspan is not changed properly.
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td rowspan="3">cell1-1</td><td>cell1-2</td></tr><tr><td id="select1">cell2-2</td></tr><tr><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select1"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, '<table><tbody><tr><td rowspan="1">cell1-1</td><td>cell1-2</td></tr><tr><td>cell3-2</td></tr></tbody></table>',
"nsITableEditor.deleteTableRow(1) with selected cell in the second row should delete the second row and the row span should be adjusted");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in 2nd row which is only cell defined by the row #1');
checkInputEvent(beforeInputEvents[0], "when a cell in 2nd row which is only cell defined by the row #1");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in 2nd row which is only cell defined by the row #1');
checkInputEvent(inputEvents[0], "when a cell in 2nd row which is only cell defined by the row #1");
selection.removeAllRanges();
editor.innerHTML =
'<table><tr><td rowspan="2">cell1-1</td><td>cell1-2</td></tr><tr><td id="select">cell2-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></table>';
beforeInputEvents = [];
inputEvents = [];
range = document.createRange();
range.selectNode(document.getElementById("select"));
selection.addRange(range);
getTableEditor().deleteTableRow(1);
is(editor.innerHTML, '<table><tbody><tr><td rowspan="1">cell1-1</td><td>cell1-2</td></tr><tr><td>cell3-1</td><td>cell3-2</td></tr></tbody></table>',
"nsITableEditor.deleteTableRow(1) with selected cell in the second row should delete the second row and the row span should be adjusted");
is(beforeInputEvents.length, 1,
'Only one "beforeinput" event should be fired when a cell in 2nd row which is only cell defined by the row #2');
checkInputEvent(beforeInputEvents[0], "when a cell in 2nd row which is only cell defined by the row #2");
is(inputEvents.length, 1,
'Only one "input" event should be fired when a cell in 2nd row which is only cell defined by the row #2');
checkInputEvent(inputEvents[0], "when a cell in 2nd row which is only cell defined by the row #2");
editor.removeEventListener("beforeinput", onBeforeInput);
editor.removeEventListener("input", onInput);
SimpleTest.finish();
});
function getTableEditor() {
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
return editingSession.getEditorForWindow(window).QueryInterface(SpecialPowers.Ci.nsITableEditor);
}
</script>
</body>
</html>