mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
It refers the layout information for getting row/column index of selected cell element or a cell element which contains selection. However, it can stop referring it if all callers can specify insertion point of new cells, and it's possible. Therefore, we can make it free from layout information. Note that this blocks legacy mutation events during inserting table cell elements, but perhaps this does not cause problems in the wild. `DOMNodeInserted` will be fired after all cell elements are inserted, so from point of view of the event listeners, editor content is different from traditional behavior, but this works only when user uses inline table editor which is disabled by default. I.e., in the wild, this path is rarely run. Additionally, this patch makes it return `CreateElementResult` for the latter changes which want to put caret to first inserted cell element. Note that the changes are tested by `test_nsITableEditor_insertTableColumn.html` and `test_nsITableEditor_insertTableCell.html`. Differential Revision: https://phabricator.services.mozilla.com/D146361
559 lines
27 KiB
HTML
559 lines
27 KiB
HTML
<!DOCTYPE>
|
|
<html>
|
|
<head>
|
|
<title>Test for nsITableEditor.insertTableCell()</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, false,
|
|
`"${aEvent.type}" event should be never cancelable ${aDescription}`);
|
|
is(aEvent.bubbles, true,
|
|
`"${aEvent.type}" event should always bubble ${aDescription}`);
|
|
is(aEvent.inputType, "",
|
|
`inputType of "${aEvent.type}" event should be empty string ${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().insertTableCell(1, false);
|
|
is(editor.innerHTML, "out of table<table><tbody><tr><td>default content</td></tr></tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, false) should do nothing if selection is not in <table>");
|
|
is(beforeInputEvents.length, 1,
|
|
'"beforeinput" event should be fired when a call of nsITableEditor.insertTableCell(1, false) even though it will do nothing');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed outside table element (nsITableEditor.insertTableCell(1, false))");
|
|
is(inputEvents.length, 0,
|
|
'No "input" event should be fired when a call of nsITableEditor.insertTableCell(1, false) does nothing');
|
|
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
getTableEditor().insertTableCell(1, true);
|
|
is(editor.innerHTML, "out of table<table><tbody><tr><td>default content</td></tr></tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, true) should do nothing if selection is not in <table>");
|
|
is(beforeInputEvents.length, 1,
|
|
'"beforeinput" event should be fired when a call of nsITableEditor.insertTableCell(1, true) even though it will do nothing');
|
|
checkInputEvent(beforeInputEvents[0], "when selection is collapsed outside table element (nsITableEditor.insertTableCell(1, true))");
|
|
is(inputEvents.length, 0,
|
|
'No "input" event should be fired when a call of nsITableEditor.insertTableCell(1, true) does nothing');
|
|
|
|
selection.removeAllRanges();
|
|
try {
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
getTableEditor().insertTableCell(1, false);
|
|
ok(false, "getTableEditor().insertTableCell(1, false) without selection ranges should throw exception");
|
|
} catch (e) {
|
|
ok(true, "getTableEditor().insertTableCell(1, false) without selection ranges should throw exception");
|
|
is(beforeInputEvents.length, 0,
|
|
'No "beforeinput" event should be fired when nsITableEditor.insertTableCell(1, false) causes exception due to no selection range');
|
|
is(inputEvents.length, 0,
|
|
'No "input" event should be fired when nsITableEditor.insertTableCell(1, false) causes exception due to no selection range');
|
|
}
|
|
try {
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
getTableEditor().insertTableCell(1, true);
|
|
ok(false, "getTableEditor().insertTableCell(1, true) without selection ranges should throw exception");
|
|
} catch (e) {
|
|
ok(true, "getTableEditor().insertTableCell(1, true) without selection ranges should throw exception");
|
|
is(beforeInputEvents.length, 0,
|
|
'No "beforeinput" event should be fired when nsITableEditor.insertTableCell(1, true) causes exception due to no selection range');
|
|
is(inputEvents.length, 0,
|
|
'No "input" event should be fired when nsITableEditor.insertTableCell(1, true) causes exception due to no selection range');
|
|
}
|
|
|
|
(function testInsertZeroCellsBefore() {
|
|
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>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(
|
|
document.getElementById("select").firstChild,
|
|
0,
|
|
document.getElementById("select").firstChild,
|
|
0
|
|
);
|
|
getTableEditor().insertTableCell(0, false);
|
|
is(
|
|
editor.innerHTML,
|
|
"<table><tbody>" +
|
|
"<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>" +
|
|
"</tbody></table>",
|
|
"testInsertZeroCellsBefore: nsITableEditor.insertTableCell(0, false) should do nothing without throwing exception"
|
|
);
|
|
is(
|
|
beforeInputEvents.length,
|
|
0,
|
|
'testInsertZeroCellsBefore: No "beforeinput" event should be fired'
|
|
);
|
|
is(
|
|
inputEvents.length,
|
|
0,
|
|
'testInsertZeroCellsBefore: No "input" event should be fired'
|
|
);
|
|
})();
|
|
|
|
(function testInsertZeroCellsAfter() {
|
|
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>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(
|
|
document.getElementById("select").firstChild,
|
|
0,
|
|
document.getElementById("select").firstChild,
|
|
0
|
|
);
|
|
getTableEditor().insertTableCell(0, true);
|
|
is(
|
|
editor.innerHTML,
|
|
"<table><tbody>" +
|
|
"<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>" +
|
|
"</tbody></table>",
|
|
"testInsertZeroCellsAfter: nsITableEditor.insertTableCell(0, true) should do nothing without throwing exception"
|
|
);
|
|
is(
|
|
beforeInputEvents.length,
|
|
0,
|
|
'testInsertZeroCellsAfter: No "beforeinput" event should be fired'
|
|
);
|
|
is(
|
|
inputEvents.length,
|
|
0,
|
|
'testInsertZeroCellsAfter: No "input" event should be fired'
|
|
);
|
|
})();
|
|
|
|
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>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 0);
|
|
getTableEditor().insertTableCell(1, false);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
"<tr><td>cell1-1</td><td>cell1-2</td></tr>" +
|
|
'<tr><td valign="top"><br></td><td id="select">cell2-1</td><td>cell2-2</td></tr>' +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, false) should insert a cell before the cell containing selection");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell in middle row (before)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell in middle row (before)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell in middle row (before)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell in middle row (before)");
|
|
|
|
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>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 0);
|
|
getTableEditor().insertTableCell(1, true);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
"<tr><td>cell1-1</td><td>cell1-2</td></tr>" +
|
|
'<tr><td id="select">cell2-1</td><td valign="top"><br></td><td>cell2-2</td></tr>' +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, true) should insert a cell after the cell containing selection");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell in middle row (after)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell in middle row (after)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell in middle row (after)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell in middle row (after)");
|
|
|
|
(function testInsertBeforeCellFollowingTextNode() {
|
|
selection.removeAllRanges();
|
|
editor.innerHTML =
|
|
"<table>" +
|
|
"<tr><td>cell1-1</td> <td>cell1-2</td> <td>cell1-3</td></tr>" +
|
|
'<tr><td>cell2-1</td> <td id="select">cell2-2</td> <td>cell2-3</tr>' +
|
|
"<tr><td>cell3-1</td> <td>cell3-2</td> <td>cell3-3</td></tr>" +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(
|
|
document.getElementById("select").firstChild,
|
|
0,
|
|
document.getElementById("select").firstChild,
|
|
0
|
|
);
|
|
getTableEditor().insertTableCell(1, false);
|
|
is(
|
|
editor.innerHTML,
|
|
"<table><tbody>" +
|
|
"<tr><td>cell1-1</td> <td>cell1-2</td> <td>cell1-3</td></tr>" +
|
|
'<tr><td>cell2-1</td> <td valign="top"><br></td><td id="select">cell2-2</td> <td>cell2-3</td></tr>' +
|
|
"<tr><td>cell3-1</td> <td>cell3-2</td> <td>cell3-3</td></tr>" +
|
|
"</tbody></table>",
|
|
"testInsertBeforeCellFollowingTextNode: nsITableEditor.insertTableCell(1, false) should insert a cell before the cell containing selection"
|
|
);
|
|
is(
|
|
beforeInputEvents.length,
|
|
1,
|
|
'testInsertBeforeCellFollowingTextNode: Only one "beforeinput" event should be fired'
|
|
);
|
|
checkInputEvent(
|
|
beforeInputEvents[0],
|
|
"when selection collapsed in a cell following a text node (testInsertBeforeCellFollowingTextNode)"
|
|
);
|
|
is(
|
|
inputEvents.length,
|
|
1,
|
|
'testInsertBeforeCellFollowingTextNode: Only one "input" event should be fired'
|
|
);
|
|
checkInputEvent(
|
|
inputEvents[0],
|
|
"when selection collapsed in a cell following a text node (testInsertBeforeCellFollowingTextNode)"
|
|
);
|
|
})();
|
|
|
|
(function testInsertAfterCellFollowedByTextNode() {
|
|
selection.removeAllRanges();
|
|
editor.innerHTML =
|
|
"<table>" +
|
|
"<tr><td>cell1-1</td> <td>cell1-2</td> <td>cell1-3</td></tr>" +
|
|
'<tr><td>cell2-1</td> <td id="select">cell2-2</td> <td>cell2-3</tr>' +
|
|
"<tr><td>cell3-1</td> <td>cell3-2</td> <td>cell3-3</td></tr>" +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(
|
|
document.getElementById("select").firstChild,
|
|
0,
|
|
document.getElementById("select").firstChild,
|
|
0
|
|
);
|
|
getTableEditor().insertTableCell(1, true);
|
|
is(
|
|
editor.innerHTML,
|
|
"<table><tbody>" +
|
|
"<tr><td>cell1-1</td> <td>cell1-2</td> <td>cell1-3</td></tr>" +
|
|
'<tr><td>cell2-1</td> <td id="select">cell2-2</td><td valign="top"><br></td> <td>cell2-3</td></tr>' +
|
|
"<tr><td>cell3-1</td> <td>cell3-2</td> <td>cell3-3</td></tr>" +
|
|
"</tbody></table>",
|
|
"testInsertAfterCellFollowedByTextNode: nsITableEditor.insertTableCell(1, true) should insert a cell after the cell containing selection"
|
|
);
|
|
is(
|
|
beforeInputEvents.length,
|
|
1,
|
|
'testInsertAfterCellFollowedByTextNode: Only one "beforeinput" event should be fired'
|
|
);
|
|
checkInputEvent(
|
|
beforeInputEvents[0],
|
|
"when selection collapsed in a cell followed by a text node (testInsertAfterCellFollowedByTextNode)"
|
|
);
|
|
is(
|
|
inputEvents.length,
|
|
1,
|
|
'testInsertAfterCellFollowedByTextNode: Only one "input" event should be fired'
|
|
);
|
|
checkInputEvent(
|
|
inputEvents[0],
|
|
"when selection collapsed in a cell followed by a text node (testInsertAfterCellFollowedByTextNode)"
|
|
);
|
|
})();
|
|
|
|
// with rowspan.
|
|
|
|
// Odd case. This puts the cell containing selection moves right of row-spanning cell.
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
'<tr><td>cell1-1</td><td rowspan="2">cell1-2</td></tr>' +
|
|
'<tr><td id="select">cell2-1</td></tr>' +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 0);
|
|
getTableEditor().insertTableCell(1, false);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
'<tr><td>cell1-1</td><td rowspan="2">cell1-2</td></tr>' +
|
|
'<tr><td valign="top"><br></td><td id="select">cell2-1</td></tr>' +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, false) should insert a cell before the cell containing selection and moves the cell to right of the row-spanning cell element");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell in middle row and it has row-spanned cell (before)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell in middle row and it has row-spanned cell (before)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell in middle row and it has row-spanned cell (before)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell in middle row and it has row-spanned cell (before)");
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
'<tr><td>cell1-1</td><td rowspan="3">cell1-2</td></tr>' +
|
|
'<tr><td id="select">cell2-1</td></tr>' +
|
|
"<tr><td>cell3-1</td></tr>" +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 0);
|
|
getTableEditor().insertTableCell(1, true);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
'<tr><td>cell1-1</td><td rowspan="3">cell1-2</td></tr>' +
|
|
'<tr><td id="select">cell2-1</td><td valign="top"><br></td></tr>' +
|
|
"<tr><td>cell3-1</td></tr>" +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, true) should insert a cell after the cell containing selection and moves the cell to right of the row-spanning cell element");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell in middle row and it has row-spanned cell (after)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell in middle row and it has row-spanned cell (after)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell in middle row and it has row-spanned cell (after)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell in middle row and it has row-spanned cell (after)");
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
'<tr><td>cell1-1</td><td id="select" rowspan="2">cell1-2</td></tr>' +
|
|
"<tr><td>cell2-1</td></tr>" +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 1);
|
|
getTableEditor().insertTableCell(2, false);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
'<tr><td>cell1-1</td><td valign="top"><br></td><td valign="top"><br></td><td id="select" rowspan="2">cell1-2</td></tr>' +
|
|
"<tr><td>cell2-1</td></tr>" +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(2, false) should insert 2 cells before the row-spanning cell containing selection");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell in row-spanning (before)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell in row-spanning (before)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell in row-spanning (before)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell in row-spanning (before)");
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
'<tr><td>cell1-1</td><td id="select" rowspan="2">cell1-2</td></tr>' +
|
|
"<tr><td>cell2-1</td></tr>" +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 1);
|
|
getTableEditor().insertTableCell(2, true);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
'<tr><td>cell1-1</td><td id="select" rowspan="2">cell1-2</td><td valign="top"><br></td><td valign="top"><br></td></tr>' +
|
|
"<tr><td>cell2-1</td></tr>" +
|
|
"<tr><td>cell3-1</td><td>cell3-2</td></tr>" +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(2, false) should insert 2 cells after the row-spanning cell containing selection");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell in row-spanning (after)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell in row-spanning (after)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell in row-spanning (after)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell in row-spanning (after)");
|
|
|
|
// with colspan
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
'<tr><td>cell1-1</td><td id="select">cell1-2</td><td>cell1-3</td></tr>' +
|
|
'<tr><td colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 0);
|
|
getTableEditor().insertTableCell(1, false);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
'<tr><td>cell1-1</td><td valign="top"><br></td><td id="select">cell1-2</td><td>cell1-3</td></tr>' +
|
|
'<tr><td colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, false) should insert a cell before the cell containing selection but do not modify col-spanning cell");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell whose next row cell is col-spanned (before)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell whose next row cell is col-spanned (before)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell whose next row cell is col-spanned (before)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell whose next row cell is col-spanned (before)");
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
'<tr><td>cell1-1</td><td id="select">cell1-2</td><td>cell1-3</td></tr>' +
|
|
'<tr><td colspan="3">cell2-1</td></tr>' +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 0);
|
|
getTableEditor().insertTableCell(1, true);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
'<tr><td>cell1-1</td><td id="select">cell1-2</td><td valign="top"><br></td><td>cell1-3</td></tr>' +
|
|
'<tr><td colspan="3">cell2-1</td></tr>' +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(1, true) should insert a cell after the cell containing selection but do not modify col-spanning cell");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell whose next row cell is col-spanned (after)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell whose next row cell is col-spanned (after)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell whose next row cell is col-spanned (after)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell whose next row cell is col-spanned (after)");
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
"<tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>" +
|
|
'<tr><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 1);
|
|
getTableEditor().insertTableCell(2, false);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
"<tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>" +
|
|
'<tr><td valign="top"><br></td><td valign="top"><br></td><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(2, false) should insert 2 cells before the col-spanning cell containing selection");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell which is col-spanning (before)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell which is col-spanning (before)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell which is col-spanning (before)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell which is col-spanning (before)");
|
|
|
|
selection.removeAllRanges();
|
|
editor.innerHTML = "<table>" +
|
|
"<tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>" +
|
|
'<tr><td id="select" colspan="2">cell2-1</td><td>cell2-3</td></tr>' +
|
|
"</table>";
|
|
editor.focus();
|
|
beforeInputEvents = [];
|
|
inputEvents = [];
|
|
selection.setBaseAndExtent(document.getElementById("select").firstChild, 0,
|
|
document.getElementById("select").firstChild, 1);
|
|
getTableEditor().insertTableCell(2, true);
|
|
is(editor.innerHTML, "<table><tbody>" +
|
|
"<tr><td>cell1-1</td><td>cell1-2</td><td>cell1-3</td></tr>" +
|
|
'<tr><td id="select" colspan="2">cell2-1</td><td valign="top"><br></td><td valign="top"><br></td><td>cell2-3</td></tr>' +
|
|
"</tbody></table>",
|
|
"nsITableEditor.insertTableCell(2, false) should insert 2 cells after the col-spanning cell containing selection");
|
|
is(beforeInputEvents.length, 1,
|
|
'Only one "beforeinput" event should be fired when selection collapsed in a cell which is col-spanning (after)');
|
|
checkInputEvent(beforeInputEvents[0], "when selection collapsed in a cell which is col-spanning (after)");
|
|
is(inputEvents.length, 1,
|
|
'Only one "input" event should be fired when selection collapsed in a cell which is col-spanning (after)');
|
|
checkInputEvent(inputEvents[0], "when selection collapsed in a cell which is col-spanning (after)");
|
|
|
|
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>
|