| <!doctype html> |
| <html> |
| <head> |
| <meta charset="utf-8"> |
| <title>Testing default action of `mousedown` of primary button and `mouseup` of primary button</title> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/resources/testdriver.js"></script> |
| <script src="/resources/testdriver-vendor.js"></script> |
| <script src="/resources/testdriver-actions.js"></script> |
| <style> |
| span { |
| white-space: nowrap; |
| } |
| </style> |
| </head> |
| <body> |
| <div contenteditable></div> |
| <script> |
| "use strict"; |
| |
| var editor = document.querySelector("div[contenteditable]"); |
| var span1, span2, link; |
| var selection = getSelection(); |
| |
| function preventDefault(event) { |
| event.preventDefault(); |
| } |
| editor.addEventListener("paste", preventDefault, {capture: true}); |
| |
| function resetEditor() { |
| editor.innerHTML = |
| '<span id="span1">first span.</span><br><span id="span2">second span.</span><br><a id="link" href="#top">link.</a>'; |
| span1 = document.getElementById("span1"); |
| span2 = document.getElementById("span2"); |
| link = document.getElementById("link"); |
| } |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.blur(); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: span1}) |
| .pointerDown({button: actions.ButtonType.LEFT}) |
| .pointerUp({button: actions.ButtonType.LEFT}) |
| .send(); |
| |
| assert_equals(document.activeElement, editor, |
| "The clicked editor should get focus"); |
| assert_true(selection.isCollapsed, |
| "Selection should be collapsed after primary button click"); |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should be collapsed in the first <span> element which was clicked by primary button"); |
| }, "Primary click should set focus to clicked editable element and collapse selection around the clicked point"); |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.focus(); |
| selection.collapse(span1.firstChild, 2); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: span2}) |
| .pointerDown({button: actions.ButtonType.LEFT}) |
| .pointerUp({button: actions.ButtonType.LEFT}) |
| .send(); |
| |
| assert_equals(document.activeElement, editor, |
| "The clicked editor should keep having focus"); |
| assert_true(selection.isCollapsed, |
| "Selection should be collapsed after primary button click"); |
| assert_equals(selection.focusNode, span2.firstChild, |
| "Selection should be collapsed in the second <span> element which was clicked by primary button"); |
| }, "Primary click should move caret in an editable element"); |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.focus(); |
| selection.collapse(span1.firstChild, 2); |
| addEventListener("mousedown", preventDefault); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: span2}) |
| .pointerDown({button: actions.ButtonType.LEFT}) |
| .pointerUp({button: actions.ButtonType.LEFT}) |
| .send(); |
| removeEventListener("mousedown", preventDefault); |
| |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should keep collapsed selection in the first <span> element"); |
| assert_equals(selection.focusOffset, 2, |
| "Selection should keep collapsed selection at 2 of the first <span> element"); |
| }, "Primary click shouldn't move caret in an editable element if the default of mousedown event is prevented"); |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.focus(); |
| selection.collapse(span1.firstChild, 2); |
| addEventListener("pointerdown", preventDefault); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: span2}) |
| .pointerDown({button: actions.ButtonType.LEFT}) |
| .pointerUp({button: actions.ButtonType.LEFT}) |
| .send(); |
| removeEventListener("pointerdown", preventDefault); |
| |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should keep collapsed selection in the first <span> element"); |
| assert_equals(selection.focusOffset, 2, |
| "Selection should keep collapsed selection at 2 of the first <span> element"); |
| }, "Primary click shouldn't move caret in an editable element if the default of pointerdown event is prevented"); |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.focus(); |
| selection.collapse(span1.firstChild, 2); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: span2}) |
| .keyDown("\uE008") |
| .pointerDown({button: actions.ButtonType.LEFT}) |
| .pointerUp({button: actions.ButtonType.LEFT}) |
| .keyUp("\uE008") |
| .send(); |
| |
| assert_equals(selection.anchorNode, span1.firstChild, |
| "Selection#anchorNode should keep in the first <span> element"); |
| assert_equals(selection.anchorOffset, 2, |
| "Selection#anchorNode should keep at 2 of the first <span> element"); |
| assert_equals(selection.focusNode, span2.firstChild, |
| "Selection#focusNode should be in the second <span> element which was clicked by primary button"); |
| }, "Shift + Primary click should extend the selection"); |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.focus(); |
| selection.collapse(span1.firstChild, 2); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: link}) |
| .keyDown("\uE008") |
| .pointerDown({button: actions.ButtonType.MIDDLE}) |
| .pointerUp({button: actions.ButtonType.MIDDLE}) |
| .keyUp("\uE008") |
| .send(); |
| |
| assert_equals(selection.focusNode, link.firstChild, |
| "Selection#focusNode should be in the <a href> element which was clicked by primary button"); |
| assert_true(selection.isCollapsed, |
| "Selection#isCollapsed should be true"); |
| }, "Shift + Primary click in a link shouldn't extend the selection"); |
| |
| promise_test(async () => { |
| resetEditor(); |
| editor.focus(); |
| selection.collapse(span1.firstChild, 2); |
| editor.addEventListener("pointerdown", () => { |
| assert_true(selection.isCollapsed, |
| "Selection shouldn't be modified before pointerdown event"); |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should stay in the first <span> element when pointerdown event is fired (focusNode)"); |
| assert_equals(selection.focusOffset, 2, |
| "Selection should stay in the first <span> element when pointerdown event is fired (focusOffset)"); |
| }, {once: true}); |
| editor.addEventListener("mousedown", () => { |
| assert_true(selection.isCollapsed, |
| "Selection shouldn't be modified before mousedown event"); |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should stay in the first <span> element when mousedown event is fired (focusNode)"); |
| assert_equals(selection.focusOffset, 2, |
| "Selection should stay in the first <span> element when mousedown event is fired (focusOffset)"); |
| }, {once: true}); |
| editor.addEventListener("pointerup", () => { |
| assert_true(!selection.isCollapsed, |
| "Selection should be modified before pointerup event"); |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should be modified to extend the range before pointerup event "); |
| }, {once: true}); |
| let anchorOffsetAtMouseUp; |
| editor.addEventListener("mouseup", () => { |
| assert_true(!selection.isCollapsed, |
| "Selection should be modified before mouseup event"); |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection should be modified to extend the range before mouseup event "); |
| anchorOffsetAtMouseUp = selection.anchorOffset; |
| }, {once: true}); |
| let actions = new test_driver.Actions(); |
| await actions |
| .pointerMove(0, 0) |
| .pointerMove(0, 0, {origin: span2}) |
| .pointerDown({button: actions.ButtonType.LEFT}) |
| .pointerMove(0, 0, {origin: span1}) |
| .pointerUp({button: actions.ButtonType.LEFT}) |
| .send(); |
| |
| assert_equals(selection.anchorNode, span2.firstChild, |
| "Selection#anchorNode should stay in the second <span> element which mousedown occurred on"); |
| assert_equals(selection.anchorOffset, anchorOffsetAtMouseUp, |
| "Selection#anchorOffset should stay in the second <span> element which mousedown occurred on"); |
| assert_equals(selection.focusNode, span1.firstChild, |
| "Selection#focusNode should be in the first <span> element which mouseup occurred on"); |
| }, "Primary mouse button down should move caret, and primary mouse button up should extend the selection"); |
| </script> |
| </body> |
| </html> |