diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /dom/events/test/test_selection_after_right_click.html | |
parent | Initial commit. (diff) | |
download | firefox-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.html | 499 |
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> |