Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!doctype html>
<meta charset=utf-8>
<title>Deletion tests</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div contenteditable></div>
<script>
var div = document.querySelector("div");
// Format: [start html, start pos, expected html, expected pos, command]
// Positions are a sequence of offsets starting from div, e.g., "1,2,0"
// translates to node = div.childNodes[1].childNodes[2], offset = 0. For a
// non-collapsed selection, use a hyphen, like "0,0-1,0". The selections are
// created with collapse() followed by extend() to allow reverse selections, so
// order is significant.
//
// Expected values can be arrays, in which case any is acceptable.
var tests = [
["<p><br></p><p><br></p>", "1,0", "<p><br></p>", "0,0", "delete"],
["<p><br></p><p><br></p>", "0,0", "<p><br></p>", "0,0", "forwarddelete"],
// Range
["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "delete"],
["<p><br></p><p><br></p>", "0,0-1,0", "<p><br></p>", "0,0", "forwarddelete"],
["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "delete"],
["<p><br></p><p><br></p>", "1,0-0,0", "<p><br></p>", "0,0", "forwarddelete"],
// Different start values
["<p>x<br></p><p><br></p>", "1,0",
// WebKit/Blink like to get rid of the extra <br>
["<p>x<br></p>", "<p>x</p>"],
// The selection should really be collapsed inside the text node, but in the
// parent is close enough.
["0,0,1", "0,1"], "delete"],
["<p><br><br></p><p><br></p>", "1,0", "<p><br><br></p>", "0,1", "delete"],
["<p><br></p><p><br><br></p>", "1,1",
"<p><br></p><p><br></p>", "1,0", "delete"],
["<p><br><br><br></p>", "0,2", "<p><br><br></p>", "0,1", "delete"],
["<p><br></p><p><br><br><br></p>", "1,2",
"<p><br></p><p><br><br></p>", "1,1", "delete"],
["<p><br><br></p><p><br><br></p>", "1,1",
"<p><br><br></p><p><br></p>", "1,0", "delete"],
["<p><br></p><br>", "1", "<p><br></p>", "0,0", "delete"],
// The trailing \n in these cases is actually significant, because it was
// necessary to trigger an actual Gecko bug (somehow!).
["<p><br></p><p><br></p>\n", "1,0", "<p><br></p>\n", "0,0", "delete"],
["<p><br></p><p><br></p>\n", "0,0", "<p><br></p>\n", "0,0", "forwarddelete"],
["\n<p><tt>x</tt></p><p><tt><br></tt></p><p><tt><br></tt></p>\n", "3,0,0",
"\n<p><tt>x</tt></p><p><tt><br></tt></p>\n", "2,0,0", "delete"],
];
div.focus();
for (var i = 0; i < tests.length; i++) {
test(function() {
var test = tests[i];
div.innerHTML = test[0];
setSelection(test[1]);
document.execCommand(test[4], false, "");
if (typeof test[2] == "string") {
assert_equals(div.innerHTML, test[2], "innerHTML");
} else {
assert_in_array(div.innerHTML, test[2], "innerHTML");
}
var actualSel = recordSelection();
var expectedSel = [];
if (typeof test[3] == "string") {
test[3] = [test[3]];
}
for (var j = 0; j < test[3].length; j++) {
setSelection(test[3][j]);
expectedSel.push(recordSelection());
}
assertSelectionEquals(actualSel, expectedSel, test[2]);
}, i + ": " + format_value(tests[i][0]) + " " + tests[i][1] +
" " + tests[i][4]);
}
function setSelection(selstr) {
var parts = selstr.split("-");
var collapsePoint = getPointFromArray(parts[0].split(","));
getSelection().collapse(collapsePoint[0], collapsePoint[1]);
if (parts[1]) {
var extendPoint = getPointFromArray(parts[1].split(","));
getSelection().extend(extendPoint[0], extendPoint[1]);
}
}
function getPointFromArray(offsets) {
var retNode = div, retOffset;
var offset;
while (offset = offsets.shift()) {
if (!offsets.length) {
retOffset = offset;
} else {
retNode = retNode.childNodes[offset];
}
}
return [retNode, retOffset];
}
function recordSelection() {
return [getSelection().anchorNode, getSelection().anchorOffset,
getSelection().focusNode, getSelection().focusOffset];
}
function assertSelectionEquals(actual, expected, html) {
if (typeof expected == "string") {
expected = [expected];
}
var pass = false;
for (var i = 0; i < expected.length; i++) {
if (expected[i][0] === actual[0] &&
expected[i][1] === actual[1] &&
expected[i][2] === actual[2] &&
expected[i][3] === actual[3]) {
pass = true;
break;
}
}
assert_true(pass, "Wrong selection, expected " + formatSel(expected) +
", got " + formatSel(actual) +
" (in HTML " + format_value(html) + ")");
}
function formatSel(arr) {
if (arr.length == 1) {
arr = arr[0];
}
if (Array.isArray(arr[0])) {
var ret = [];
for (var i = 0; i < arr.length; i++) {
ret.push(formatSel(arr[i]));
}
return ret.join(" or ");
}
if (arr[0] == arr[2] && arr[1] == arr[3]) {
return "collapsed (" + format_value(arr[0]) + ", " + arr[1] + ")";
}
return "(" + format_value(arr[0]) + ", " + arr[1] +
")-(" + format_value(arr[2]) + ", " + arr[3] + ")";
}
</script>