зеркало из https://github.com/mozilla/gecko-dev.git
312 строки
16 KiB
HTML
312 строки
16 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Test for expanding selection per page</title>
|
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
</head>
|
|
<body>
|
|
|
|
<pre id="test">
|
|
<script class="testbody" type="text/javascript">
|
|
SimpleTest.waitForExplicitFinish();
|
|
addLoadEvent(() => {
|
|
open("window_empty_document.html", "_blank", "width=500,height=500");
|
|
});
|
|
|
|
async function doTests(aWindow) {
|
|
const IS_WIN = navigator.platform.includes("Win");
|
|
// On macOS and Linux, Shift + PageUp/PageDown requires native event to
|
|
// resolve default action of PageDown and PageUp. Although macOS widget has
|
|
// nsIWidget::AttachNativeKeyEvent(), we cannot use synthesizeKey() for the
|
|
// following tests. So, use nsISelectionController.pageMove() instead on
|
|
// non-Windows platforms.
|
|
const kUseKeyboardEvent = IS_WIN;
|
|
let selectionController;
|
|
if (!kUseKeyboardEvent) {
|
|
selectionController = SpecialPowers.wrap(aWindow)
|
|
.docShell
|
|
.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
|
|
.getInterface(SpecialPowers.Ci.nsISelectionDisplay)
|
|
.QueryInterface(SpecialPowers.Ci.nsISelectionController);
|
|
}
|
|
// On Windows, per-page selection to start or end expands selection to same
|
|
// column of first or last line. On the other platforms, it expands selection
|
|
// to start or end of first or last line.
|
|
const kSelectToStartOrEnd = !IS_WIN;
|
|
|
|
await SpecialPowers.pushPrefEnv({"set": [["general.smoothScroll", false]]});
|
|
await SimpleTest.promiseFocus(aWindow);
|
|
|
|
function getNodeDescription(aNode) {
|
|
function getElementDescription(aElement) {
|
|
if (aElement.getAttribute("id") !== null) {
|
|
return `${aElement.tagName.toLowerCase()}#${aElement.getAttribute("id")}`;
|
|
}
|
|
if (aElement.tagName === "BR") {
|
|
return `${getElementDescription(aElement.previousSibling)} + br`;
|
|
}
|
|
return aElement.tagName.toLowerCase();
|
|
}
|
|
switch (aNode.nodeType) {
|
|
case aNode.TEXT_NODE:
|
|
return `text node in ${getElementDescription(aNode.parentElement)}`;
|
|
case aNode.ELEMENT_NODE:
|
|
return getElementDescription(aNode);
|
|
default:
|
|
return "unknown node";
|
|
}
|
|
}
|
|
|
|
function doSelectPageDown() {
|
|
if (kUseKeyboardEvent) {
|
|
synthesizeKey("KEY_PageDown", {shiftKey: true}, aWindow);
|
|
} else {
|
|
selectionController.pageMove(true, true);
|
|
}
|
|
}
|
|
|
|
function doSelectPageUp() {
|
|
if (kUseKeyboardEvent) {
|
|
synthesizeKey("KEY_PageUp", {shiftKey: true}, aWindow);
|
|
} else {
|
|
selectionController.pageMove(false, true);
|
|
}
|
|
}
|
|
|
|
let doc = aWindow.document;
|
|
let body = doc.body;
|
|
let selection = doc.getSelection();
|
|
let container;
|
|
|
|
body.innerHTML = '<span id="s1">first line</span><br>' +
|
|
'<span id="s2">second line</span><br>' +
|
|
'<span id="s3">last line</span>';
|
|
container = doc.documentElement;
|
|
|
|
let description = "Expanding selection to forward in non-scrollable body: ";
|
|
is(container.scrollTop, 0, description + "scrollTop should be 0 at initialization");
|
|
selection.collapse(doc.getElementById("s1").firstChild, 3);
|
|
doSelectPageDown();
|
|
is(container.scrollTop, 0, description + "this test shouldn't create scrollable document");
|
|
let range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s1").firstChild,
|
|
`${description} selection should be expanded from the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
is(range.startOffset, 3,
|
|
`${description} selection should be expanded from the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s3").firstChild,
|
|
`${description} selection should be expanded into the last line (got: ${getNodeDescription(range.endContainer)})`);
|
|
if (kSelectToStartOrEnd) {
|
|
is(range.endOffset, range.endContainer.length,
|
|
`${description} selection should be expanded to end of the last line`);
|
|
} else {
|
|
isfuzzy(range.endOffset, 3, 2,
|
|
`${description} selection should be expanded to around the last line's 3rd insertion point`);
|
|
}
|
|
|
|
description = "Expanding selection to backward in non-scrollable body: ";
|
|
selection.collapse(doc.getElementById("s3").firstChild, 3);
|
|
doSelectPageUp();
|
|
is(container.scrollTop, 0, description + "this test shouldn't create scrollable document");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s1").firstChild,
|
|
`${description} selection should be expanded into the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
if (kSelectToStartOrEnd) {
|
|
is(range.startOffset, 0,
|
|
`${description} selection should be expanded to start of the first line`);
|
|
} else {
|
|
isfuzzy(range.startOffset, 3, 2,
|
|
`${description} selection should be expanded to around the first line's 3rd insertion point`);
|
|
}
|
|
is(range.endContainer, doc.getElementById("s3").firstChild,
|
|
`${description} selection should be expanded from the last line (got: ${getNodeDescription(range.endContainer)})`);
|
|
is(range.endOffset, 3,
|
|
`${description} selection should be expanded from the last line's 3rd insertion point`);
|
|
|
|
body.innerHTML = '<span id="s1">first line in the body</span>' +
|
|
'<div id="d1" style="height: 2em; line-height: 1em; overflow: auto;">' +
|
|
'<span id="s2">first line</span><br>' +
|
|
'<span id="s3">second line</span><br>' +
|
|
'<span id="s4">third line</span><br>' +
|
|
'<span id="s5">last line</span>' +
|
|
"</div>" +
|
|
'<span id="s6">last line in the body</span>';
|
|
container = doc.getElementById("d1");
|
|
|
|
description = "Expanding selection to forward in scrollable area in the body: ";
|
|
is(container.scrollTop, 0, description + "scrollTop should be 0 at initialization");
|
|
selection.collapse(doc.getElementById("s2").firstChild, 3);
|
|
doSelectPageDown();
|
|
isnot(container.scrollTop, 0, description + "should be scrolled down");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded from the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
is(range.startOffset, 3,
|
|
`${description} selection should be expanded from the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s4").firstChild,
|
|
`${description} selection should be expanded into the 3rd line (got: ${getNodeDescription(range.endContainer)})`);
|
|
isfuzzy(range.endOffset, 3, 2,
|
|
`${description} selection should be expanded to around the 3rd line's 3rd insertion point`);
|
|
|
|
description = "Expanding selection to backward in scrollable area in the body: ";
|
|
selection.collapse(doc.getElementById("s4").firstChild, 3);
|
|
let previousScrollTop = container.scrollTop;
|
|
doSelectPageUp();
|
|
ok(container.scrollTop < previousScrollTop, description + "should be scrolled up");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded into the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
isfuzzy(range.startOffset, 3, 2,
|
|
`${description} selection should be expanded to around the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s4").firstChild,
|
|
`${description} selection should be expanded from the 3rd line (got: ${getNodeDescription(range.endContainer)})`);
|
|
is(range.endOffset, 3,
|
|
`${description} selection should be expanded from the 3rd line's 3rd insertion point`);
|
|
|
|
body.innerHTML = '<span id="s1">first line in the body</span>' +
|
|
'<div id="d1" contenteditable style="height: 2em; line-height: 1em; overflow: auto;">' +
|
|
'<span id="s2">first line</span><br>' +
|
|
'<span id="s3">second line</span><br>' +
|
|
'<span id="s4">third line</span><br>' +
|
|
'<span id="s5">last line</span>' +
|
|
"</div>" +
|
|
'<span id="s6">last line in the body</span>';
|
|
container = doc.getElementById("d1");
|
|
|
|
description = "Expanding selection to forward in scrollable editable div in the body: ";
|
|
is(container.scrollTop, 0, description + "scrollTop should be 0 at initialization");
|
|
selection.collapse(doc.getElementById("s2").firstChild, 3);
|
|
doSelectPageDown();
|
|
isnot(container.scrollTop, 0, description + "should be scrolled down");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded from the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
is(range.startOffset, 3,
|
|
`${description} selection should be expanded from the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s4").firstChild,
|
|
`${description} selection should be expanded into the 3rd line (got: ${getNodeDescription(range.endContainer)})`);
|
|
isfuzzy(range.endOffset, 3, 2,
|
|
`${description} selection should be expanded to around the 3rd line's 3rd insertion point`);
|
|
|
|
description = "Expanding selection to backward in scrollable editable div in the body: ";
|
|
selection.collapse(doc.getElementById("s4").firstChild, 3);
|
|
previousScrollTop = container.scrollTop;
|
|
doSelectPageUp();
|
|
ok(container.scrollTop < previousScrollTop, description + "should be scrolled up");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded into the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
isfuzzy(range.startOffset, 3, 2,
|
|
`${description} selection should be expanded to around the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s4").firstChild,
|
|
`${description} selection should be expanded from the 3rd line (got: ${getNodeDescription(range.endContainer)})`);
|
|
is(range.endOffset, 3,
|
|
`${description} selection should be expanded from the 3rd line's 3rd insertion point`);
|
|
|
|
body.innerHTML = '<span id="s1">first line in the body</span>' +
|
|
'<div id="d1" contenteditable>' +
|
|
'<span id="s2">first line</span><br>' +
|
|
'<span id="s3">second line</span><br>' +
|
|
'<span id="s4">third line</span><br>' +
|
|
'<span id="s5">last line</span>' +
|
|
"</div>" +
|
|
'<span id="s6">last line in the body</span>';
|
|
container = doc.getElementById("d1");
|
|
|
|
description = "Expanding selection to forward in non-scrollable editable div in the body: ";
|
|
is(container.scrollTop, 0, description + "scrollTop should be 0 at initialization");
|
|
selection.collapse(doc.getElementById("s2").firstChild, 3);
|
|
doSelectPageDown();
|
|
is(container.scrollTop, 0, description + "editable div shouldn't be scrollable");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded from the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
is(range.startOffset, 3,
|
|
`${description} selection should be expanded from the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s5").firstChild,
|
|
`${description} selection should be expanded into the last line (got: ${getNodeDescription(range.endContainer)})`);
|
|
if (kSelectToStartOrEnd) {
|
|
is(range.endOffset, range.endContainer.length,
|
|
`${description} selection should be expanded to end of the last line`);
|
|
} else {
|
|
isfuzzy(range.endOffset, 3, 2,
|
|
`${description} selection should be expanded to around the last line's 3rd insertion point`);
|
|
}
|
|
|
|
description = "Expanding selection to backward in non-scrollable editable div in the body: ";
|
|
selection.collapse(doc.getElementById("s5").firstChild, 3);
|
|
doSelectPageUp();
|
|
is(container.scrollTop, 0, description + "editable div shouldn't be scrollable");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded into the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
if (kSelectToStartOrEnd) {
|
|
is(range.startOffset, 0,
|
|
`${description} selection should be expanded to start of the first line`);
|
|
} else {
|
|
isfuzzy(range.startOffset, 3, 2,
|
|
`${description} selection should be expanded to around the first line's 3rd insertion point`);
|
|
}
|
|
is(range.endContainer, doc.getElementById("s5").firstChild,
|
|
`${description} selection should be expanded from the last line (got: ${getNodeDescription(range.endContainer)})`);
|
|
is(range.endOffset, 3,
|
|
`${description} selection should be expanded from the last line's 3rd insertion point`);
|
|
|
|
body.innerHTML = '<span id="s1">first line in the body</span>' +
|
|
'<div id="d1" contenteditable>' +
|
|
'<span id="s2">first editable line</span><br>' +
|
|
'<div id="d2" style="height: 3em; line-height: 1em; overflow: auto;">' +
|
|
'<span id="s3">first line</span><br>' +
|
|
'<span id="s4">second line</span>' +
|
|
"</div>" +
|
|
'<span id="s5">last editable line</span>' +
|
|
"</div>" +
|
|
'<span id="s6">last line in the body</span>';
|
|
container = doc.getElementById("d2");
|
|
|
|
description = "Expanding selection to forward in scrollable div (but not scrollable along y-axis) in the editable div: ";
|
|
is(container.scrollTop, 0, description + "scrollTop should be 0 at initialization");
|
|
selection.collapse(doc.getElementById("s3").firstChild, 3);
|
|
doSelectPageDown();
|
|
is(container.scrollTop, 0, description + "scrollable div in the editable div (but not scrollable along y-axis) shouldn't be scrollable");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s3").firstChild,
|
|
`${description} selection should be expanded from the first line (got: ${getNodeDescription(range.startContainer)})`);
|
|
is(range.startOffset, 3,
|
|
`${description} selection should be expanded from the first line's 3rd insertion point`);
|
|
is(range.endContainer, doc.getElementById("s5").firstChild,
|
|
`${description} selection should be expanded into the last editable line (got: ${getNodeDescription(range.endContainer)})`);
|
|
if (kSelectToStartOrEnd) {
|
|
is(range.endOffset, range.endContainer.length,
|
|
`${description} selection should be expanded to end of the last editable line`);
|
|
} else {
|
|
isfuzzy(range.endOffset, 3, 2,
|
|
`${description} selection should be expanded to around the last editable line's 3rd insertion point`);
|
|
}
|
|
|
|
description = "Expanding selection to backward in scrollable div (but not scrollable along y-axis) in the editable div: ";
|
|
selection.collapse(doc.getElementById("s4").firstChild, 3);
|
|
doSelectPageUp();
|
|
is(container.scrollTop, 0, description + "scrollable div (but not scrollable along y-axis) in the editable div shouldn't be scrollable");
|
|
range = selection.getRangeAt(0);
|
|
is(range.startContainer, doc.getElementById("s2").firstChild,
|
|
`${description} selection should be expanded into the first editable line (got: ${getNodeDescription(range.startContainer)})`);
|
|
if (kSelectToStartOrEnd) {
|
|
is(range.startOffset, 0,
|
|
`${description} selection should be expanded to start of the first editable line`);
|
|
} else {
|
|
isfuzzy(range.startOffset, 3, 2,
|
|
`${description} selection should be expanded to around the first editable line's 3rd insertion point`);
|
|
}
|
|
is(range.endContainer, doc.getElementById("s4").firstChild,
|
|
`${description} selection should be expanded from the last line (got: ${getNodeDescription(range.endContainer)})`);
|
|
is(range.endOffset, 3,
|
|
`${description} selection should be expanded from the last line's 3rd insertion point`);
|
|
|
|
aWindow.close();
|
|
SimpleTest.finish();
|
|
}
|
|
</script>
|
|
</html>
|