summaryrefslogtreecommitdiffstats
path: root/dom/events/test/test_selection_after_right_click.html
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /dom/events/test/test_selection_after_right_click.html
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/events/test/test_selection_after_right_click.html')
-rw-r--r--dom/events/test/test_selection_after_right_click.html499
1 files changed, 499 insertions, 0 deletions
diff --git a/dom/events/test/test_selection_after_right_click.html b/dom/events/test/test_selection_after_right_click.html
new file mode 100644
index 0000000000..3661db9c69
--- /dev/null
+++ b/dom/events/test/test_selection_after_right_click.html
@@ -0,0 +1,499 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<title>Tests for checking the behavior of right click clicking outside selection</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<div>Non editable text</div>
+<div contenteditable>Editable text</div>
+<input value="input value" style="width: 100%" />
+<iframe srcdoc="<span>abc</span>"></iframe>
+<script>
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(async () => {
+ function getRangeDescription(range) {
+ function getNodeDescription(node) {
+ if (!node) {
+ return "null";
+ }
+ switch (node.nodeType) {
+ case Node.TEXT_NODE:
+ case Node.COMMENT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ return `${node.nodeName} "${node.data}"`;
+ case Node.ELEMENT_NODE:
+ return `<${node.nodeName.toLowerCase()}>`;
+ default:
+ return `${node.nodeName}`;
+ }
+ }
+ if (range === null) {
+ return "null";
+ }
+ if (range === undefined) {
+ return "undefined";
+ }
+ return range.startContainer == range.endContainer &&
+ range.startOffset == range.endOffset
+ ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})`
+ : `(${getNodeDescription(range.startContainer)}, ${
+ range.startOffset
+ }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`;
+ }
+
+ document.addEventListener(
+ "contextmenu",
+ event => event.preventDefault(),
+ { capture: true }
+ );
+ const nonEditableDiv = document.querySelector("div");
+ const editableDiv = document.querySelector("div[contenteditable]");
+ const input = document.querySelector("input");
+
+ // See also modifying-selection-with-non-primary-mouse-button.tentative.html?secondary for the basic behavior check.
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", false],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ],
+ });
+
+ getSelection().setBaseAndExtent(
+ nonEditableDiv.firstChild, "Non editable ".length,
+ nonEditableDiv.firstChild, "Non editable text".length
+ );
+ synthesizeMouse(nonEditableDiv, 10, 10, {button: 2});
+ ok(
+ getSelection().isCollapsed,
+ `Selection should be collapsed by a right click when stop_if_non_collapsed_selection pref is false in non-editable text node (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ getSelection().setBaseAndExtent(
+ editableDiv.firstChild, "Editable ".length,
+ editableDiv.firstChild, "Editable text".length
+ );
+ synthesizeMouse(editableDiv, 10, 10, {button: 2});
+ ok(
+ getSelection().isCollapsed,
+ `Selection should be collapsed by a right click when stop_if_non_collapsed_selection pref is false in editable text node (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ input.focus();
+ input.setSelectionRange("input ".length, "input value".length);
+ synthesizeMouse(input, 10, 10, {button: 2});
+ ok(
+ input.selectionStart == input.selectionEnd,
+ `Selection in <input> should be collapsed by a right click when stop_if_non_collapsed_selection pref is false (got: ${input.selectionStart} - ${input.selectionEnd})`
+ );
+ input.blur();
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", false],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", true],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ],
+ });
+
+ getSelection().setBaseAndExtent(
+ nonEditableDiv.firstChild, "Non editable ".length,
+ nonEditableDiv.firstChild, "Non editable text".length
+ );
+ synthesizeMouse(nonEditableDiv, 10, 10, {button: 2});
+ ok(
+ !getSelection().isCollapsed,
+ `Selection should not be collapsed by a right click when stop_if_non_editable_node pref is true in non-editable text node (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ getSelection().setBaseAndExtent(
+ editableDiv.firstChild, "Editable ".length,
+ editableDiv.firstChild, "Editable text".length
+ );
+ synthesizeMouse(editableDiv, 10, 10, {button: 2});
+ ok(
+ getSelection().isCollapsed,
+ `Selection should be collapsed by a right click even when stop_if_non_editable_node pref is true in editable text node (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ input.focus();
+ input.setSelectionRange("input ".length, "input value".length);
+ synthesizeMouse(input, 10, 10, {button: 2});
+ ok(
+ input.selectionStart == input.selectionEnd,
+ `Selection in <input> should be collapsed by a right click even when stop_if_non_editable_node pref is true (got: ${input.selectionStart} - ${input.selectionEnd})`
+ );
+ input.blur();
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", true],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ],
+ });
+
+ getSelection().setBaseAndExtent(
+ nonEditableDiv.firstChild, "Non editable ".length,
+ nonEditableDiv.firstChild, "Non editable text".length
+ );
+ synthesizeMouse(nonEditableDiv, 10, 10, {button: 2});
+ ok(
+ !getSelection().isCollapsed,
+ `Selection should not be collapsed by a right click when stop_if_non_collapsed_selection pref is true in non-editable text node (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ getSelection().setBaseAndExtent(
+ editableDiv.firstChild, "Editable ".length,
+ editableDiv.firstChild, "Editable text".length
+ );
+ synthesizeMouse(editableDiv, 10, 10, {button: 2});
+ ok(
+ !getSelection().isCollapsed,
+ `Selection should be collapsed by a right click when stop_if_non_collapsed_selection pref is true in editable text node (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ input.focus();
+ input.setSelectionRange("input ".length, "input value".length);
+ synthesizeMouse(input, 10, 10, {button: 2});
+ ok(
+ input.selectionStart != input.selectionEnd,
+ `Selection in <input> should not be collapsed by a right click when stop_if_non_collapsed_selection pref is true (got: ${input.selectionStart} - ${input.selectionEnd})`
+ );
+ input.blur();
+
+ // When the right click changes the selection ancestor limit, it should be
+ // handled correctly after nsIFrame does nothing.
+ getSelection().setBaseAndExtent(
+ nonEditableDiv.firstChild, "Non editable ".length,
+ nonEditableDiv.firstChild, "Non editable text".length
+ );
+ synthesizeMouse(editableDiv, 10, 10, {button: 2});
+ is(
+ document.activeElement,
+ editableDiv,
+ "Right clicking in editable <div> when selection selects some text outside the <div> should move focus into the editor"
+ );
+ ok(
+ getSelection().focusNode == editableDiv.firstChild &&
+ getSelection().focusOffset > 0,
+ `Right clicking in editable <div> when selection selects some text outside the <div> should not cause collapsing selection to start of the editor (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ getSelection().setBaseAndExtent(
+ editableDiv.firstChild, "Editable ".length,
+ editableDiv.firstChild, "Editable text".length
+ );
+ synthesizeMouse(nonEditableDiv, 10, 10, {button: 2});
+ isnot(
+ document.activeElement,
+ editableDiv,
+ "Right clicking outside the editable <div> should blur from it"
+ );
+ ok(
+ getSelection().focusNode == nonEditableDiv.firstChild &&
+ getSelection().focusOffset > 0,
+ `Right clicking outside the editable <div> should collapse selection at the clicked content (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ // If clicking in a selection range, the range should never be collapsed.
+ const iframe = document.querySelector("iframe");
+ const doc = iframe.contentDocument;
+ doc.addEventListener("contextmenu", event => event.preventDefault(), {capture: true});
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", false],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ],
+ });
+ iframe.focus();
+ doc.getSelection().selectAllChildren(doc.body);
+ synthesizeMouseAtCenter(doc.body.firstChild, {button: 2}, iframe.contentWindow);
+ ok(
+ !doc.getSelection().isCollapsed,
+ "Right click in a selection range should not cause collapsing selection"
+ );
+ iframe.blur();
+ doc.activeElement?.blur();
+
+ doc.documentElement.setAttribute("contenteditable", "");
+ iframe.focus();
+ doc.getSelection().selectAllChildren(doc.body);
+ synthesizeMouseAtCenter(doc.body.firstChild, {button: 2}, iframe.contentWindow);
+ ok(
+ !doc.getSelection().isCollapsed,
+ "Right click in a selection range in a editable-root-element should not cause collapsing selection"
+ );
+ iframe.blur();
+ doc.activeElement?.blur();
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", true],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ],
+ });
+ doc.designMode = "on";
+ iframe.focus();
+ doc.getSelection().selectAllChildren(doc.body);
+ synthesizeMouseAtCenter(doc.body.firstChild, {button: 2}, iframe.contentWindow);
+ ok(
+ !doc.getSelection().isCollapsed,
+ "Right click in a selection range in a sub-editable-document should not cause collapsing selection"
+ );
+ doc.designMode = "off";
+
+ // If selection is collapsed and `ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node` is
+ // false, the caret should be moved at clicked point.
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", true],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ],
+ });
+ editableDiv.innerHTML = "<b>Bold text</b><i>Italic text</i>";
+ editableDiv.focus();
+ getSelection().collapse(
+ editableDiv.querySelector("b").firstChild,
+ "Bold".length
+ );
+ synthesizeMouseAtCenter(editableDiv.querySelector("i"), {button: 2});
+ ok(
+ getSelection().isCollapsed,
+ "Right clicking in editable <div> should keep Selection collapsed if the pref is unset"
+ );
+ is(
+ getSelection().focusNode.parentNode,
+ editableDiv.querySelector("i"),
+ `Right clicking in editable <div> should collapse Selection at the clicked point (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ }) if the pref is unset`
+ );
+
+ input.focus();
+ input.setSelectionRange(0, 0);
+ synthesizeMouseAtCenter(input, {button: 2});
+ ok(
+ input.selectionStart == input.selectionEnd,
+ "Right click in <input> should keep Selection collapsed if the pref is unset"
+ );
+ ok(
+ input.selectionStart > 0,
+ "Right click in <input> should move caret if the pref is unset"
+ );
+ input.blur();
+
+ // If selection is collapsed and `ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node` is
+ // true, the caret should not be moved at clicked point unless focus is changed by the click.
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", true],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", true],
+ ],
+ });
+ editableDiv.innerHTML = "<b>Bold text</b><i>Italic text</i>";
+ editableDiv.focus();
+ getSelection().collapse(
+ editableDiv.querySelector("b").firstChild,
+ "Bold".length
+ );
+ synthesizeMouseAtCenter(editableDiv.querySelector("i"), {button: 2});
+ ok(
+ getSelection().isCollapsed,
+ "Right clicking in editable <div> should keep Selection collapsed even if the pref is set"
+ );
+ is(
+ getSelection().focusNode.parentNode,
+ editableDiv.querySelector("b"),
+ `Right clicking in editable <div> should not move caret to the clicked point (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ }) if the pref is set`
+ );
+
+ input.focus();
+ input.setSelectionRange(0, 0);
+ synthesizeMouseAtCenter(input, {button: 2});
+ ok(
+ input.selectionStart == input.selectionEnd,
+ "Right click in <input> should keep Selection collapsed even if the pref is set"
+ );
+ is(
+ input.selectionStart,
+ 0,
+ "Right click in <input> should not move caret if the pref is set"
+ );
+ input.blur();
+
+ input.setSelectionRange(0, 0);
+ editableDiv.focus();
+ synthesizeMouseAtCenter(input, {button: 2});
+ ok(
+ input.selectionStart == input.selectionEnd,
+ "Right click in <input> which is not focused should keep Selection collapsed"
+ );
+ ok(
+ input.selectionStart > 0,
+ "Right click in <input> which is not focused should move caret"
+ );
+
+ editableDiv.focus();
+ getSelection().collapse(
+ editableDiv.querySelector("b").firstChild,
+ "Bold".length
+ );
+ input.focus();
+ synthesizeMouseAtCenter(editableDiv.querySelector("i"), {button: 2});
+ ok(
+ getSelection().isCollapsed,
+ "Right clicking in editable <div> which is not focused should collapse selection"
+ );
+ is(
+ getSelection().focusNode.parentNode,
+ editableDiv.querySelector("i"),
+ `Right clicking in editable <div> which is not focused should collapse Selection at the clicked point (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ // If Shift + right click should forcibly open context menu, users may want the click to work as
+ // same as without Shift.
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", true],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ["dom.event.contextmenu.shift_suppresses_event", true],
+ ],
+ });
+ nonEditableDiv.innerHTML = "<b>bold</b> <i>italic</i>";
+ getSelection().collapse(nonEditableDiv.querySelector("b").firstChild, 0);
+ synthesizeMouseAtCenter(nonEditableDiv.querySelector("i"), {shiftKey: true, button: 2});
+ ok(
+ getSelection().isCollapsed,
+ `Selection should be collapsed by a Shift + right click on non-editable node when it does not open context menu (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+ is(
+ getSelection().focusNode,
+ nonEditableDiv.querySelector("i").firstChild,
+ `Selection should be collapsed at the click point by a Shift + right click on non-editable node when it does not open context menu (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ editableDiv.innerHTML = "<b>bold</b> <i>italic</i>";
+ getSelection().collapse(editableDiv.querySelector("b").firstChild, 0);
+ synthesizeMouseAtCenter(editableDiv.querySelector("i"), {shiftKey: true, button: 2});
+ ok(
+ getSelection().isCollapsed,
+ `Selection should be collapsed by a Shift + right click on editable node when it does not open context menu (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+ is(
+ getSelection().focusNode,
+ editableDiv.querySelector("i").firstChild,
+ `Selection should be collapsed at the click point by a Shift + right click on editable node when it does not open context menu (${
+ getRangeDescription(getSelection().getRangeAt(0))
+ })`
+ );
+
+ input.focus();
+ input.setSelectionRange(0, 0);
+ synthesizeMouseAtCenter(input, {shiftKey: true, button: 2});
+ ok(
+ input.selectionStart == input.selectionEnd,
+ `Selection in <input> should be collapsed by a Shift + right click when it does not open context menu (got: ${
+ input.selectionStart
+ } - ${input.selectionEnd})`
+ );
+ isnot(
+ input.selectionStart,
+ 0,
+ `Selection in <input> should be collapsed at the click point by a Shift + right click when it does not open context menu (got: ${
+ input.selectionStart
+ } - ${input.selectionEnd})`
+ );
+ input.blur();
+
+ // If Shift + right click should open context menu, users may want the click to work as
+ // same as a left click.
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection", true],
+ ["ui.mouse.right_click.collapse_selection.stop_if_non_editable_node", false],
+ ["ui.mouse.right_click.move_caret.stop_if_in_focused_editable_node", false],
+ ["dom.event.contextmenu.shift_suppresses_event", false],
+ ],
+ });
+ nonEditableDiv.innerHTML = "<b>bold</b> <i>italic</i>";
+ getSelection().collapse(nonEditableDiv.querySelector("b").firstChild, 0);
+ synthesizeMouseAtCenter(nonEditableDiv.querySelector("i"), {shiftKey: true, button: 2});
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: nonEditableDiv.querySelector("b").firstChild,
+ startOffset: 0,
+ endContainer: nonEditableDiv.querySelector("i").firstChild,
+ endOffset: getSelection().focusOffset,
+ }),
+ `Selection should be extended by a Shift + right click on non-editable node when it should open context menu`
+ );
+
+ editableDiv.innerHTML = "<b>bold</b> <i>italic</i>";
+ getSelection().collapse(editableDiv.querySelector("b").firstChild, 0);
+ synthesizeMouseAtCenter(editableDiv.querySelector("i"), {shiftKey: true, button: 2});
+ is(
+ getRangeDescription(getSelection().getRangeAt(0)),
+ getRangeDescription({
+ startContainer: editableDiv.querySelector("b").firstChild,
+ startOffset: 0,
+ endContainer: editableDiv.querySelector("i").firstChild,
+ endOffset: getSelection().focusOffset,
+ }),
+ `Selection should be extended by a Shift + right click on editable node when it should open context menu`
+ );
+
+ input.focus();
+ input.setSelectionRange(0, 0);
+ synthesizeMouseAtCenter(input, {shiftKey: true, button: 2});
+ isnot(
+ input.selectionStart,
+ input.selectionEnd,
+ `Selection in <input> should be extended by a Shift + right click when it should open context menu (got: ${
+ input.selectionStart
+ } - ${input.selectionEnd})`
+ );
+ input.blur();
+
+ SimpleTest.finish();
+});
+</script>
+</body>
+</html>