From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- dom/events/AnimationEvent.cpp | 66 + dom/events/AnimationEvent.h | 48 + dom/events/AsyncEventDispatcher.cpp | 156 + dom/events/AsyncEventDispatcher.h | 210 + dom/events/BeforeUnloadEvent.cpp | 29 + dom/events/BeforeUnloadEvent.h | 45 + dom/events/Clipboard.cpp | 777 +++ dom/events/Clipboard.h | 81 + dom/events/ClipboardEvent.cpp | 90 + dom/events/ClipboardEvent.h | 48 + dom/events/ClipboardItem.cpp | 333 + dom/events/ClipboardItem.h | 134 + dom/events/CommandEvent.cpp | 42 + dom/events/CommandEvent.h | 40 + dom/events/CompositionEvent.cpp | 108 + dom/events/CompositionEvent.h | 58 + dom/events/ConstructibleEventTarget.cpp | 17 + dom/events/ConstructibleEventTarget.h | 30 + dom/events/ContentEventHandler.cpp | 3482 ++++++++++ dom/events/ContentEventHandler.h | 553 ++ dom/events/CustomEvent.cpp | 83 + dom/events/CustomEvent.h | 52 + dom/events/DOMEventTargetHelper.cpp | 265 + dom/events/DOMEventTargetHelper.h | 168 + dom/events/DataTransfer.cpp | 1512 +++++ dom/events/DataTransfer.h | 531 ++ dom/events/DataTransferItem.cpp | 594 ++ dom/events/DataTransferItem.h | 135 + dom/events/DataTransferItemList.cpp | 642 ++ dom/events/DataTransferItemList.h | 125 + dom/events/DeviceMotionEvent.cpp | 130 + dom/events/DeviceMotionEvent.h | 129 + dom/events/DragEvent.cpp | 98 + dom/events/DragEvent.h | 55 + dom/events/Event.cpp | 903 +++ dom/events/Event.h | 411 ++ dom/events/EventDispatcher.cpp | 1672 +++++ dom/events/EventDispatcher.h | 388 ++ dom/events/EventListenerManager.cpp | 2336 +++++++ dom/events/EventListenerManager.h | 778 +++ dom/events/EventListenerService.cpp | 403 ++ dom/events/EventListenerService.h | 108 + dom/events/EventNameList.h | 603 ++ dom/events/EventStateManager.cpp | 6934 ++++++++++++++++++++ dom/events/EventStateManager.h | 1335 ++++ dom/events/EventTarget.cpp | 270 + dom/events/EventTarget.h | 461 ++ dom/events/FocusEvent.cpp | 61 + dom/events/FocusEvent.h | 47 + dom/events/GlobalKeyListener.cpp | 766 +++ dom/events/GlobalKeyListener.h | 198 + dom/events/IMEContentObserver.cpp | 2221 +++++++ dom/events/IMEContentObserver.h | 551 ++ dom/events/IMEStateManager.cpp | 2451 +++++++ dom/events/IMEStateManager.h | 526 ++ dom/events/ImageCaptureError.cpp | 39 + dom/events/ImageCaptureError.h | 56 + dom/events/InputEvent.cpp | 118 + dom/events/InputEvent.h | 58 + dom/events/InputEventOptions.h | 75 + dom/events/InputTypeList.h | 73 + dom/events/InternalMutationEvent.h | 77 + dom/events/InvokeEvent.cpp | 58 + dom/events/InvokeEvent.h | 50 + dom/events/JSEventHandler.cpp | 229 + dom/events/JSEventHandler.h | 231 + dom/events/KeyEventHandler.cpp | 721 ++ dom/events/KeyEventHandler.h | 176 + dom/events/KeyNameList.h | 437 ++ dom/events/KeyboardEvent.cpp | 422 ++ dom/events/KeyboardEvent.h | 135 + dom/events/MessageEvent.cpp | 162 + dom/events/MessageEvent.h | 102 + dom/events/MouseEvent.cpp | 319 + dom/events/MouseEvent.h | 114 + dom/events/MouseScrollEvent.cpp | 66 + dom/events/MouseScrollEvent.h | 47 + dom/events/MutationEvent.cpp | 75 + dom/events/MutationEvent.h | 53 + dom/events/NotifyPaintEvent.cpp | 133 + dom/events/NotifyPaintEvent.h | 73 + dom/events/PaintRequest.cpp | 60 + dom/events/PaintRequest.h | 77 + dom/events/PendingFullscreenEvent.h | 71 + dom/events/PhysicalKeyCodeNameList.h | 235 + dom/events/PointerEvent.cpp | 306 + dom/events/PointerEvent.h | 79 + dom/events/PointerEventHandler.cpp | 817 +++ dom/events/PointerEventHandler.h | 244 + dom/events/RemoteDragStartData.cpp | 83 + dom/events/RemoteDragStartData.h | 74 + dom/events/ScrollAreaEvent.cpp | 80 + dom/events/ScrollAreaEvent.h | 60 + dom/events/ShortcutKeyDefinitions.cpp | 780 +++ dom/events/ShortcutKeys.cpp | 120 + dom/events/ShortcutKeys.h | 70 + dom/events/SimpleGestureEvent.cpp | 86 + dom/events/SimpleGestureEvent.h | 56 + dom/events/SpeechRecognitionError.cpp | 46 + dom/events/SpeechRecognitionError.h | 48 + dom/events/StorageEvent.cpp | 84 + dom/events/StorageEvent.h | 85 + dom/events/TextClause.cpp | 45 + dom/events/TextClause.h | 53 + dom/events/TextComposition.cpp | 1068 +++ dom/events/TextComposition.h | 622 ++ dom/events/Touch.cpp | 232 + dom/events/Touch.h | 105 + dom/events/TouchEvent.cpp | 338 + dom/events/TouchEvent.h | 121 + dom/events/TransitionEvent.cpp | 68 + dom/events/TransitionEvent.h | 47 + dom/events/UIEvent.cpp | 335 + dom/events/UIEvent.h | 122 + dom/events/VirtualKeyCodeList.h | 245 + dom/events/WheelEvent.cpp | 178 + dom/events/WheelEvent.h | 82 + dom/events/WheelHandlingHelper.cpp | 872 +++ dom/events/WheelHandlingHelper.h | 440 ++ dom/events/XULCommandEvent.cpp | 73 + dom/events/XULCommandEvent.h | 66 + dom/events/crashtests/1033343.html | 5 + dom/events/crashtests/1035654-1.html | 21 + dom/events/crashtests/1035654-2.html | 20 + dom/events/crashtests/104310-1.html | 22 + dom/events/crashtests/1072137-1.html | 18 + dom/events/crashtests/1143972-1.html | 12 + dom/events/crashtests/116206-1.html | 23 + dom/events/crashtests/1190036-1.html | 15 + dom/events/crashtests/135345-1.html | 14 + dom/events/crashtests/1397711.html | 11 + dom/events/crashtests/1856737.html | 19 + dom/events/crashtests/457776-1.html | 9 + dom/events/crashtests/496308-1.html | 3 + dom/events/crashtests/682637-1.html | 22 + dom/events/crashtests/938341.html | 7 + dom/events/crashtests/crashtests.list | 19 + .../crashtests/eventctor-nulldictionary.html | 4 + dom/events/crashtests/eventctor-nullstorage.html | 4 + .../crashtests/recursive-DOMNodeInserted.html | 17 + dom/events/crashtests/recursive-onload.html | 1 + dom/events/moz.build | 189 + dom/events/nsIEventListenerService.idl | 128 + dom/events/test/browser.toml | 33 + dom/events/test/browser_alt_keyup_in_content.js | 333 + ..._beforeinput_by_execCommand_in_contentscript.js | 195 + dom/events/test/browser_bug1539497.js | 25 + dom/events/test/browser_dragimage.js | 65 + ...vent_init_key_event_enabled_in_contentscript.js | 80 + .../test/browser_mouse_enterleave_switch_tab.js | 158 + .../test/browser_mouseout_notification_panel.js | 145 + ...er_conflicts_with_content_accesskey_modifier.js | 102 + dom/events/test/bug1017086_inner.html | 39 + dom/events/test/bug226361_iframe.xhtml | 47 + dom/events/test/bug299673.js | 150 + dom/events/test/bug322588-popup.html | 1 + dom/events/test/bug415498-doc1.html | 15 + dom/events/test/bug415498-doc2.html | 15 + dom/events/test/bug418986-3.js | 85 + dom/events/test/bug426082.html | 116 + dom/events/test/bug545268.html | 1 + dom/events/test/bug574663.html | 3 + dom/events/test/bug591249_iframe.xhtml | 33 + dom/events/test/bug602962.xhtml | 8 + dom/events/test/bug607464.html | 3 + dom/events/test/bug656379-1.html | 186 + dom/events/test/chrome.toml | 48 + dom/events/test/clipboard/browser.toml | 40 + .../browser_navigator_clipboard_clickjacking.js | 69 + ..._navigator_clipboard_contextmenu_suppression.js | 264 + ...igator_clipboard_contextmenu_suppression_ext.js | 156 + .../clipboard/browser_navigator_clipboard_read.js | 228 + .../browser_navigator_clipboard_readText.js | 241 + ...rowser_navigator_clipboard_readText_multiple.js | 316 + .../clipboard/browser_navigator_clipboard_touch.js | 114 + dom/events/test/clipboard/chrome.toml | 3 + dom/events/test/clipboard/file_iframe.html | 2 + dom/events/test/clipboard/file_toplevel.html | 10 + dom/events/test/clipboard/head.js | 185 + dom/events/test/clipboard/mochitest.toml | 7 + .../simple_navigator_clipboard_keydown.html | 15 + .../clipboard/simple_navigator_clipboard_read.html | 64 + .../simple_navigator_clipboard_readText.html | 47 + .../test/clipboard/test_async_clipboard.xhtml | 124 + dom/events/test/clipboard/test_paste_image.html | 213 + dom/events/test/dragimage.html | 10 + dom/events/test/empty.js | 0 dom/events/test/error_event_worker.js | 19 + dom/events/test/event_leak_utils.js | 84 + ...eforeinput_by_execCommand_in_contentscript.html | 9 + dom/events/test/file_bug1446834.html | 96 + dom/events/test/file_bug1484371.html | 94 + dom/events/test/file_bug1692052.html | 25 + dom/events/test/file_bug679494.html | 8 + .../test/file_coalesce_touchmove_browserchild.html | 117 + .../file_coalesce_touchmove_browserchild2.html | 193 + dom/events/test/file_coalesce_touchmove_ipc.html | 193 + dom/events/test/file_empty.html | 15 + dom/events/test/file_event_screenXY.html | 23 + ...focus_blur_on_click_in_cross_origin_iframe.html | 28 + ...on_click_in_deep_cross_origin_iframe_inner.html | 28 + ...n_click_in_deep_cross_origin_iframe_middle.html | 37 + ...nt_init_key_event_enabled_in_contentscript.html | 21 + dom/events/test/file_mouse_enterleave.html | 45 + dom/events/test/green.png | Bin 0 -> 255 bytes .../test/gtest/TestShortcutKeyDefinitions.cpp | 634 ++ dom/events/test/gtest/moz.build | 18 + dom/events/test/mochitest.toml | 523 ++ ...93174_implicit_pointer_capture_for_touch_1.html | 63 + ...93174_implicit_pointer_capture_for_touch_2.html | 64 + dom/events/test/pointerevents/bug968148_inner.html | 316 + .../test/pointerevents/bug968148_inner2.html | 315 + .../test/pointerevents/bug_1420589_iframe1.html | 17 + .../test/pointerevents/bug_1420589_iframe2.html | 17 + dom/events/test/pointerevents/chrome.toml | 3 + .../file_pointercapture_xorigin_iframe.html | 62 + ..._pointercapture_xorigin_iframe_pointerlock.html | 111 + .../file_pointercapture_xorigin_iframe_touch.html | 69 + .../file_test_trigger_fullscreen.html | 1 + dom/events/test/pointerevents/iframe.html | 7 + dom/events/test/pointerevents/mochitest.toml | 250 + .../pointerevents/mochitest_support_external.js | 270 + .../pointerevents/mochitest_support_internal.js | 125 + .../test/pointerevents/pointerevent_utils.js | 60 + dom/events/test/pointerevents/readme.md | 9 + dom/events/test/pointerevents/test_bug1285128.html | 51 + ...93174_implicit_pointer_capture_for_touch_1.html | 30 + ...93174_implicit_pointer_capture_for_touch_2.html | 30 + dom/events/test/pointerevents/test_bug1303704.html | 135 + dom/events/test/pointerevents/test_bug1315862.html | 66 + dom/events/test/pointerevents/test_bug1323158.html | 91 + dom/events/test/pointerevents/test_bug1403055.html | 90 + .../test/pointerevents/test_bug1420589_1.html | 105 + .../test/pointerevents/test_bug1420589_2.html | 122 + .../test/pointerevents/test_bug1420589_3.html | 115 + .../test/pointerevents/test_bug1697769.xhtml | 74 + dom/events/test/pointerevents/test_bug1725416.html | 37 + dom/events/test/pointerevents/test_bug968148.html | 46 + .../pointerevents/test_getCoalescedEvents.html | 88 + .../test_getCoalescedEvents_touch.html | 111 + .../test/pointerevents/test_multiple_touches.html | 196 + .../test_pointercapture_remove_iframe.html | 80 + .../test_pointercapture_xorigin_iframe.html | 55 + .../test_pointermove_drag_scrollbar.html | 77 + ...test_remove_frame_when_got_pointer_capture.html | 166 + .../test/pointerevents/test_synthesized_touch.html | 47 + .../test_trigger_fullscreen_by_pointer_events.html | 54 + ...event_attributes_hoverable_pointers-manual.html | 53 + ...erevent_attributes_nohover_pointers-manual.html | 26 + ...revent_boundary_events_in_capturing-manual.html | 46 + ...ge-touch-action-onpointerdown_touch-manual.html | 39 + .../test_wpt_pointerevent_constructor.html | 26 + ...t_wpt_pointerevent_drag_interaction-manual.html | 38 + .../test_wpt_pointerevent_movementxy-manual.html | 53 + ...le_primary_pointers_boundary_events-manual.html | 31 + ...st_wpt_pointerevent_pointerId_scope-manual.html | 27 + ...pt_pointerevent_pointercancel_touch-manual.html | 30 + ...nterleave_after_pointercancel_touch-manual.html | 30 + ...t_wpt_pointerevent_pointerleave_pen-manual.html | 28 + ...ointerout_after_pointercancel_touch-manual.html | 30 + ...est_wpt_pointerevent_pointerout_pen-manual.html | 28 + ...ercapture_events_to_original_target-manual.html | 49 + ...ointercapture_onpointercancel_touch-manual.html | 30 + ...equence_at_implicit_release_on_drag-manual.html | 27 + .../test/pointerevents/test_wpt_touch_action.html | 98 + .../test/pointerevents/touch_action_helpers.js | 243 + ...touch-action_two-finger_interaction-manual.html | 102 + .../html/pointerevent_drag_interaction-manual.html | 103 + dom/events/test/pointerevents/wpt/idlharness.html | 104 + ...event_attributes_hoverable_pointers-manual.html | 143 + ...erevent_attributes_nohover_pointers-manual.html | 126 + ...revent_boundary_events_in_capturing-manual.html | 97 + ...ge-touch-action-onpointerdown_touch-manual.html | 135 + .../wpt/pointerevent_constructor.html | 106 + ...le_primary_pointers_boundary_events-manual.html | 145 + .../wpt/pointerevent_pointerId_scope-manual.html | 82 + .../pointerevent_pointercancel_touch-manual.html | 77 + ...nterleave_after_pointercancel_touch-manual.html | 66 + .../wpt/pointerevent_pointerleave_pen-manual.html | 58 + ...ointerout_after_pointercancel_touch-manual.html | 67 + .../wpt/pointerevent_pointerout_pen-manual.html | 57 + ...ercapture_events_to_original_target-manual.html | 137 + ...ointercapture_onpointercancel_touch-manual.html | 71 + ...quence_at_implicit_release_on_click-manual.html | 83 + ...equence_at_implicit_release_on_drag-manual.html | 84 + .../test/pointerevents/wpt/pointerevent_styles.css | 112 + .../test/pointerevents/wpt/pointerevent_support.js | 333 + ...erevent_touch-action-auto-css_touch-manual.html | 129 + ...vent_touch-action-button-test_touch-manual.html | 110 + .../wpt/pointerevent_touch-action-illegal.html | 67 + ...inherit_child-auto-child-none_touch-manual.html | 117 + ...uch-action-inherit_child-none_touch-manual.html | 112 + ...herit_child-pan-x-child-pan-x_touch-manual.html | 112 + ...herit_child-pan-x-child-pan-y_touch-manual.html | 117 + ...n-inherit_highest-parent-none_touch-manual.html | 133 + ...ch-action-inherit_parent-none_touch-manual.html | 112 + .../pointerevent_touch-action-keyboard-manual.html | 124 + .../pointerevent_touch-action-mouse-manual.html | 130 + ...erevent_touch-action-none-css_touch-manual.html | 111 + ...ent_touch-action-pan-down-css_touch-manual.html | 114 + ...ent_touch-action-pan-left-css_touch-manual.html | 114 + ...nt_touch-action-pan-right-css_touch-manual.html | 114 + ...event_touch-action-pan-up-css_touch-manual.html | 114 + ...revent_touch-action-pan-x-css_touch-manual.html | 106 + ...ouch-action-pan-x-pan-y-pan-y_touch-manual.html | 111 + ...vent_touch-action-pan-x-pan-y_touch-manual.html | 126 + ...revent_touch-action-pan-y-css_touch-manual.html | 106 + ...revent_touch-action-span-test_touch-manual.html | 114 + ...erevent_touch-action-svg-test_touch-manual.html | 122 + ...event_touch-action-table-test_touch-manual.html | 145 + .../pointerevent_touch-action-verification.html | 91 + .../pointerevent_movementxy-manual.html | 99 + .../resources/pointerevent_movementxy-iframe.html | 8 + ...event_attributes_hoverable_pointers-iframe.html | 10 + .../pointerevent_pointerId_scope-iframe.html | 35 + dom/events/test/test_DataTransferItemList.html | 233 + dom/events/test/test_accel_virtual_modifier.html | 90 + dom/events/test/test_accesskey.html | 160 + dom/events/test/test_addEventListenerExtraArg.html | 31 + dom/events/test/test_all_synthetic_events.html | 488 ++ dom/events/test/test_auxclick_autoscroll_off.html | 31 + dom/events/test/test_bug1003432.html | 45 + dom/events/test/test_bug1003432.js | 31 + dom/events/test/test_bug1013412.html | 116 + dom/events/test/test_bug1017086_enable.html | 35 + dom/events/test/test_bug1037990.html | 61 + dom/events/test/test_bug1079236.html | 66 + dom/events/test/test_bug1127588.html | 62 + dom/events/test/test_bug1128787-1.html | 52 + dom/events/test/test_bug1128787-2.html | 54 + dom/events/test/test_bug1128787-3.html | 53 + dom/events/test/test_bug1145910.html | 54 + dom/events/test/test_bug1150308.html | 49 + dom/events/test/test_bug1248459.html | 58 + dom/events/test/test_bug1264380.html | 82 + dom/events/test/test_bug1298970.html | 33 + dom/events/test/test_bug1304044.html | 133 + dom/events/test/test_bug1305458.html | 50 + dom/events/test/test_bug1327798.html | 47 + dom/events/test/test_bug1332699.html | 37 + dom/events/test/test_bug1339758.html | 80 + dom/events/test/test_bug1369072.html | 37 + dom/events/test/test_bug1412775.xhtml | 66 + dom/events/test/test_bug1429572.html | 43 + dom/events/test/test_bug1446834.html | 33 + dom/events/test/test_bug1447993.html | 41 + dom/events/test/test_bug1484371.html | 27 + dom/events/test/test_bug1534562.html | 51 + dom/events/test/test_bug1539497.html | 29 + dom/events/test/test_bug1581192.html | 73 + dom/events/test/test_bug1635018.html | 27 + dom/events/test/test_bug1637259.html | 71 + dom/events/test/test_bug1673434.html | 75 + dom/events/test/test_bug1681800.html | 26 + dom/events/test/test_bug1686716.html | 28 + dom/events/test/test_bug1692052.html | 36 + dom/events/test/test_bug1692277.html | 43 + dom/events/test/test_bug1709832.html | 46 + dom/events/test/test_bug1710509.html | 49 + dom/events/test/test_bug1728171.html | 70 + dom/events/test/test_bug226361.xhtml | 82 + dom/events/test/test_bug238987.html | 280 + dom/events/test/test_bug288392.html | 103 + dom/events/test/test_bug299673-1.html | 61 + dom/events/test/test_bug299673-2.html | 60 + dom/events/test/test_bug322588.html | 66 + dom/events/test/test_bug328885.html | 135 + dom/events/test/test_bug336682.js | 96 + dom/events/test/test_bug336682_1.html | 55 + dom/events/test/test_bug336682_2.xhtml | 58 + dom/events/test/test_bug367781.html | 53 + dom/events/test/test_bug379120.html | 55 + dom/events/test/test_bug402089.html | 67 + dom/events/test/test_bug405632.html | 34 + dom/events/test/test_bug409604.html | 379 ++ dom/events/test/test_bug412567.html | 47 + dom/events/test/test_bug415498.xhtml | 97 + dom/events/test/test_bug418986-3.html | 25 + dom/events/test/test_bug418986-3.xhtml | 27 + dom/events/test/test_bug422132.html | 125 + dom/events/test/test_bug426082.html | 30 + dom/events/test/test_bug427537.html | 61 + dom/events/test/test_bug428988.html | 44 + dom/events/test/test_bug432698.html | 223 + dom/events/test/test_bug443985.html | 76 + dom/events/test/test_bug447736.html | 48 + dom/events/test/test_bug448602.html | 303 + dom/events/test/test_bug450876.html | 47 + dom/events/test/test_bug456273.html | 46 + dom/events/test/test_bug457672.html | 55 + dom/events/test/test_bug489671.html | 56 + dom/events/test/test_bug493251.html | 181 + dom/events/test/test_bug508479.html | 110 + dom/events/test/test_bug517851.html | 122 + dom/events/test/test_bug524674.xhtml | 130 + dom/events/test/test_bug534833.html | 156 + dom/events/test/test_bug545268.html | 129 + dom/events/test/test_bug547996-1.html | 87 + dom/events/test/test_bug547996-2.xhtml | 120 + dom/events/test/test_bug547996-3.xhtml | 66 + dom/events/test/test_bug556493.html | 74 + dom/events/test/test_bug563329.html | 82 + dom/events/test/test_bug574663.html | 194 + dom/events/test/test_bug586961.xhtml | 46 + dom/events/test/test_bug591249.xhtml | 73 + dom/events/test/test_bug591815.html | 68 + dom/events/test/test_bug593959.html | 60 + dom/events/test/test_bug602962.xhtml | 85 + dom/events/test/test_bug603008.html | 559 ++ dom/events/test/test_bug605242.html | 58 + dom/events/test/test_bug607464.html | 84 + dom/events/test/test_bug613634.html | 90 + dom/events/test/test_bug615597.html | 39 + dom/events/test/test_bug617528.xhtml | 96 + dom/events/test/test_bug624127.html | 35 + dom/events/test/test_bug635465.html | 90 + dom/events/test/test_bug641477.html | 37 + dom/events/test/test_bug648573.html | 120 + dom/events/test/test_bug650493.html | 215 + dom/events/test/test_bug656379-1.html | 30 + dom/events/test/test_bug656379-2.html | 115 + dom/events/test/test_bug656954.html | 42 + dom/events/test/test_bug659071.html | 39 + dom/events/test/test_bug659350.html | 111 + dom/events/test/test_bug662678.html | 153 + dom/events/test/test_bug667612.html | 38 + dom/events/test/test_bug667919-1.html | 41 + dom/events/test/test_bug679494.xhtml | 36 + dom/events/test/test_bug684208.html | 80 + dom/events/test/test_bug687787.html | 610 ++ dom/events/test/test_bug689564.html | 65 + dom/events/test/test_bug698929.html | 47 + dom/events/test/test_bug704423.html | 40 + dom/events/test/test_bug741666.html | 185 + dom/events/test/test_bug812744.html | 37 + dom/events/test/test_bug822898.html | 343 + dom/events/test/test_bug855741.html | 90 + dom/events/test/test_bug864040.html | 87 + dom/events/test/test_bug924087.html | 45 + dom/events/test/test_bug930374-chrome.html | 57 + dom/events/test/test_bug930374-content.html | 70 + dom/events/test/test_bug944011.html | 52 + dom/events/test/test_bug944847.html | 42 + dom/events/test/test_bug946632.html | 156 + dom/events/test/test_bug967796.html | 236 + dom/events/test/test_bug985988.html | 89 + dom/events/test/test_bug998809.html | 35 + .../test_click_on_reframed_generated_text.html | 32 + .../test/test_click_on_restyled_element.html | 51 + dom/events/test/test_clickevent_on_input.html | 108 + dom/events/test/test_coalesce_mousewheel.html | 241 + dom/events/test/test_coalesce_touchmove.html | 34 + dom/events/test/test_continuous_wheel_events.html | 3291 ++++++++++ .../test_dblclick_explicit_original_target.html | 52 + .../test/test_deltaMode_lines_always_enabled.html | 40 + dom/events/test/test_deviceSensor.html | 136 + dom/events/test/test_disabled_events.html | 40 + dom/events/test/test_dnd_with_modifiers.html | 78 + dom/events/test/test_dom_activate_event.html | 91 + dom/events/test/test_dom_keyboard_event.html | 541 ++ dom/events/test/test_dom_mouse_event.html | 143 + dom/events/test/test_dom_storage_event.html | 62 + dom/events/test/test_dom_wheel_event.html | 835 +++ dom/events/test/test_drag_coords.html | 52 + dom/events/test/test_drag_image_file.html | 56 + dom/events/test/test_draggableprop.html | 93 + dom/events/test/test_dragstart.html | 716 ++ dom/events/test/test_error_events.html | 71 + dom/events/test/test_eventTimeStamp.html | 116 + dom/events/test/test_event_handler_cc.html | 90 + ...test_event_screenXY_in_cross_origin_iframe.html | 101 + dom/events/test/test_event_screenXY_with_zoom.html | 63 + dom/events/test/test_eventctors.html | 930 +++ dom/events/test/test_eventctors.xhtml | 49 + dom/events/test/test_eventctors_sensors.html | 97 + dom/events/test/test_eventhandler_scoping.html | 17 + dom/events/test/test_focus_abspos.html | 32 + ...focus_blur_on_click_in_cross_origin_iframe.html | 118 + ..._blur_on_click_in_deep_cross_origin_iframe.html | 146 + dom/events/test/test_hover_mouseleave.html | 47 + dom/events/test/test_legacy_event.html | 297 + dom/events/test/test_legacy_touch_api.html | 65 + dom/events/test/test_marquee_events.html | 31 + dom/events/test/test_messageEvent.html | 79 + dom/events/test/test_messageEvent_init.html | 25 + dom/events/test/test_mouse_capture_iframe.html | 70 + dom/events/test/test_mouse_enterleave_iframe.html | 362 + .../test_mouse_over_at_removing_down_target.html | 75 + ...st_moving_and_expanding_selection_per_page.html | 353 + .../test/test_moz_mouse_pixel_scroll_event.html | 478 ++ dom/events/test/test_offsetxy.html | 98 + dom/events/test/test_onerror_handler_args.html | 36 + dom/events/test/test_passive_listeners.html | 118 + dom/events/test/test_scroll_per_page.html | 259 + .../test/test_selection_after_right_click.html | 499 ++ dom/events/test/test_slotted_mouse_event.html | 102 + dom/events/test/test_slotted_text_click.html | 72 + dom/events/test/test_submitevent_on_form.html | 67 + dom/events/test/test_text_event_in_content.html | 68 + .../test/test_unbound_before_in_active_chain.html | 38 + ..._event_model_on_newer_Office_Online_Server.html | 59 + ...lit_keypress_event_model_on_old_Confluence.html | 82 + ...ss_event_model_on_old_Office_Online_Server.html | 69 + dom/events/test/test_wheel_default_action.html | 39 + .../test/test_wheel_zoom_on_form_controls.html | 69 + dom/events/test/window_bug1369072.html | 170 + dom/events/test/window_bug1412775.xhtml | 8 + dom/events/test/window_bug1429572.html | 351 + dom/events/test/window_bug1447993.html | 239 + dom/events/test/window_bug493251.html | 13 + dom/events/test/window_bug617528.xhtml | 9 + dom/events/test/window_bug659071.html | 85 + dom/events/test/window_empty_document.html | 7 + dom/events/test/window_wheel_default_action.html | 3618 ++++++++++ 514 files changed, 92348 insertions(+) create mode 100644 dom/events/AnimationEvent.cpp create mode 100644 dom/events/AnimationEvent.h create mode 100644 dom/events/AsyncEventDispatcher.cpp create mode 100644 dom/events/AsyncEventDispatcher.h create mode 100644 dom/events/BeforeUnloadEvent.cpp create mode 100644 dom/events/BeforeUnloadEvent.h create mode 100644 dom/events/Clipboard.cpp create mode 100644 dom/events/Clipboard.h create mode 100644 dom/events/ClipboardEvent.cpp create mode 100644 dom/events/ClipboardEvent.h create mode 100644 dom/events/ClipboardItem.cpp create mode 100644 dom/events/ClipboardItem.h create mode 100644 dom/events/CommandEvent.cpp create mode 100644 dom/events/CommandEvent.h create mode 100644 dom/events/CompositionEvent.cpp create mode 100644 dom/events/CompositionEvent.h create mode 100644 dom/events/ConstructibleEventTarget.cpp create mode 100644 dom/events/ConstructibleEventTarget.h create mode 100644 dom/events/ContentEventHandler.cpp create mode 100644 dom/events/ContentEventHandler.h create mode 100644 dom/events/CustomEvent.cpp create mode 100644 dom/events/CustomEvent.h create mode 100644 dom/events/DOMEventTargetHelper.cpp create mode 100644 dom/events/DOMEventTargetHelper.h create mode 100644 dom/events/DataTransfer.cpp create mode 100644 dom/events/DataTransfer.h create mode 100644 dom/events/DataTransferItem.cpp create mode 100644 dom/events/DataTransferItem.h create mode 100644 dom/events/DataTransferItemList.cpp create mode 100644 dom/events/DataTransferItemList.h create mode 100644 dom/events/DeviceMotionEvent.cpp create mode 100644 dom/events/DeviceMotionEvent.h create mode 100644 dom/events/DragEvent.cpp create mode 100644 dom/events/DragEvent.h create mode 100644 dom/events/Event.cpp create mode 100644 dom/events/Event.h create mode 100644 dom/events/EventDispatcher.cpp create mode 100644 dom/events/EventDispatcher.h create mode 100644 dom/events/EventListenerManager.cpp create mode 100644 dom/events/EventListenerManager.h create mode 100644 dom/events/EventListenerService.cpp create mode 100644 dom/events/EventListenerService.h create mode 100644 dom/events/EventNameList.h create mode 100644 dom/events/EventStateManager.cpp create mode 100644 dom/events/EventStateManager.h create mode 100644 dom/events/EventTarget.cpp create mode 100644 dom/events/EventTarget.h create mode 100644 dom/events/FocusEvent.cpp create mode 100644 dom/events/FocusEvent.h create mode 100644 dom/events/GlobalKeyListener.cpp create mode 100644 dom/events/GlobalKeyListener.h create mode 100644 dom/events/IMEContentObserver.cpp create mode 100644 dom/events/IMEContentObserver.h create mode 100644 dom/events/IMEStateManager.cpp create mode 100644 dom/events/IMEStateManager.h create mode 100644 dom/events/ImageCaptureError.cpp create mode 100644 dom/events/ImageCaptureError.h create mode 100644 dom/events/InputEvent.cpp create mode 100644 dom/events/InputEvent.h create mode 100644 dom/events/InputEventOptions.h create mode 100644 dom/events/InputTypeList.h create mode 100644 dom/events/InternalMutationEvent.h create mode 100644 dom/events/InvokeEvent.cpp create mode 100644 dom/events/InvokeEvent.h create mode 100644 dom/events/JSEventHandler.cpp create mode 100644 dom/events/JSEventHandler.h create mode 100644 dom/events/KeyEventHandler.cpp create mode 100644 dom/events/KeyEventHandler.h create mode 100644 dom/events/KeyNameList.h create mode 100644 dom/events/KeyboardEvent.cpp create mode 100644 dom/events/KeyboardEvent.h create mode 100644 dom/events/MessageEvent.cpp create mode 100644 dom/events/MessageEvent.h create mode 100644 dom/events/MouseEvent.cpp create mode 100644 dom/events/MouseEvent.h create mode 100644 dom/events/MouseScrollEvent.cpp create mode 100644 dom/events/MouseScrollEvent.h create mode 100644 dom/events/MutationEvent.cpp create mode 100644 dom/events/MutationEvent.h create mode 100644 dom/events/NotifyPaintEvent.cpp create mode 100644 dom/events/NotifyPaintEvent.h create mode 100644 dom/events/PaintRequest.cpp create mode 100644 dom/events/PaintRequest.h create mode 100644 dom/events/PendingFullscreenEvent.h create mode 100644 dom/events/PhysicalKeyCodeNameList.h create mode 100644 dom/events/PointerEvent.cpp create mode 100644 dom/events/PointerEvent.h create mode 100644 dom/events/PointerEventHandler.cpp create mode 100644 dom/events/PointerEventHandler.h create mode 100644 dom/events/RemoteDragStartData.cpp create mode 100644 dom/events/RemoteDragStartData.h create mode 100644 dom/events/ScrollAreaEvent.cpp create mode 100644 dom/events/ScrollAreaEvent.h create mode 100644 dom/events/ShortcutKeyDefinitions.cpp create mode 100644 dom/events/ShortcutKeys.cpp create mode 100644 dom/events/ShortcutKeys.h create mode 100644 dom/events/SimpleGestureEvent.cpp create mode 100644 dom/events/SimpleGestureEvent.h create mode 100644 dom/events/SpeechRecognitionError.cpp create mode 100644 dom/events/SpeechRecognitionError.h create mode 100644 dom/events/StorageEvent.cpp create mode 100644 dom/events/StorageEvent.h create mode 100644 dom/events/TextClause.cpp create mode 100644 dom/events/TextClause.h create mode 100644 dom/events/TextComposition.cpp create mode 100644 dom/events/TextComposition.h create mode 100644 dom/events/Touch.cpp create mode 100644 dom/events/Touch.h create mode 100644 dom/events/TouchEvent.cpp create mode 100644 dom/events/TouchEvent.h create mode 100644 dom/events/TransitionEvent.cpp create mode 100644 dom/events/TransitionEvent.h create mode 100644 dom/events/UIEvent.cpp create mode 100644 dom/events/UIEvent.h create mode 100644 dom/events/VirtualKeyCodeList.h create mode 100644 dom/events/WheelEvent.cpp create mode 100644 dom/events/WheelEvent.h create mode 100644 dom/events/WheelHandlingHelper.cpp create mode 100644 dom/events/WheelHandlingHelper.h create mode 100644 dom/events/XULCommandEvent.cpp create mode 100644 dom/events/XULCommandEvent.h create mode 100644 dom/events/crashtests/1033343.html create mode 100644 dom/events/crashtests/1035654-1.html create mode 100644 dom/events/crashtests/1035654-2.html create mode 100644 dom/events/crashtests/104310-1.html create mode 100644 dom/events/crashtests/1072137-1.html create mode 100644 dom/events/crashtests/1143972-1.html create mode 100644 dom/events/crashtests/116206-1.html create mode 100644 dom/events/crashtests/1190036-1.html create mode 100644 dom/events/crashtests/135345-1.html create mode 100644 dom/events/crashtests/1397711.html create mode 100644 dom/events/crashtests/1856737.html create mode 100644 dom/events/crashtests/457776-1.html create mode 100644 dom/events/crashtests/496308-1.html create mode 100644 dom/events/crashtests/682637-1.html create mode 100644 dom/events/crashtests/938341.html create mode 100644 dom/events/crashtests/crashtests.list create mode 100644 dom/events/crashtests/eventctor-nulldictionary.html create mode 100644 dom/events/crashtests/eventctor-nullstorage.html create mode 100644 dom/events/crashtests/recursive-DOMNodeInserted.html create mode 100644 dom/events/crashtests/recursive-onload.html create mode 100644 dom/events/moz.build create mode 100644 dom/events/nsIEventListenerService.idl create mode 100644 dom/events/test/browser.toml create mode 100644 dom/events/test/browser_alt_keyup_in_content.js create mode 100644 dom/events/test/browser_beforeinput_by_execCommand_in_contentscript.js create mode 100644 dom/events/test/browser_bug1539497.js create mode 100644 dom/events/test/browser_dragimage.js create mode 100644 dom/events/test/browser_keyboard_event_init_key_event_enabled_in_contentscript.js create mode 100644 dom/events/test/browser_mouse_enterleave_switch_tab.js create mode 100644 dom/events/test/browser_mouseout_notification_panel.js create mode 100644 dom/events/test/browser_shortcutkey_modifier_conflicts_with_content_accesskey_modifier.js create mode 100644 dom/events/test/bug1017086_inner.html create mode 100644 dom/events/test/bug226361_iframe.xhtml create mode 100644 dom/events/test/bug299673.js create mode 100644 dom/events/test/bug322588-popup.html create mode 100644 dom/events/test/bug415498-doc1.html create mode 100644 dom/events/test/bug415498-doc2.html create mode 100644 dom/events/test/bug418986-3.js create mode 100644 dom/events/test/bug426082.html create mode 100644 dom/events/test/bug545268.html create mode 100644 dom/events/test/bug574663.html create mode 100644 dom/events/test/bug591249_iframe.xhtml create mode 100644 dom/events/test/bug602962.xhtml create mode 100644 dom/events/test/bug607464.html create mode 100644 dom/events/test/bug656379-1.html create mode 100644 dom/events/test/chrome.toml create mode 100644 dom/events/test/clipboard/browser.toml create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_clickjacking.js create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression.js create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_contextmenu_suppression_ext.js create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_read.js create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_readText.js create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_readText_multiple.js create mode 100644 dom/events/test/clipboard/browser_navigator_clipboard_touch.js create mode 100644 dom/events/test/clipboard/chrome.toml create mode 100644 dom/events/test/clipboard/file_iframe.html create mode 100644 dom/events/test/clipboard/file_toplevel.html create mode 100644 dom/events/test/clipboard/head.js create mode 100644 dom/events/test/clipboard/mochitest.toml create mode 100644 dom/events/test/clipboard/simple_navigator_clipboard_keydown.html create mode 100644 dom/events/test/clipboard/simple_navigator_clipboard_read.html create mode 100644 dom/events/test/clipboard/simple_navigator_clipboard_readText.html create mode 100644 dom/events/test/clipboard/test_async_clipboard.xhtml create mode 100644 dom/events/test/clipboard/test_paste_image.html create mode 100644 dom/events/test/dragimage.html create mode 100644 dom/events/test/empty.js create mode 100644 dom/events/test/error_event_worker.js create mode 100644 dom/events/test/event_leak_utils.js create mode 100644 dom/events/test/file_beforeinput_by_execCommand_in_contentscript.html create mode 100644 dom/events/test/file_bug1446834.html create mode 100644 dom/events/test/file_bug1484371.html create mode 100644 dom/events/test/file_bug1692052.html create mode 100644 dom/events/test/file_bug679494.html create mode 100644 dom/events/test/file_coalesce_touchmove_browserchild.html create mode 100644 dom/events/test/file_coalesce_touchmove_browserchild2.html create mode 100644 dom/events/test/file_coalesce_touchmove_ipc.html create mode 100644 dom/events/test/file_empty.html create mode 100644 dom/events/test/file_event_screenXY.html create mode 100644 dom/events/test/file_focus_blur_on_click_in_cross_origin_iframe.html create mode 100644 dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_inner.html create mode 100644 dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_middle.html create mode 100644 dom/events/test/file_keyboard_event_init_key_event_enabled_in_contentscript.html create mode 100644 dom/events/test/file_mouse_enterleave.html create mode 100644 dom/events/test/green.png create mode 100644 dom/events/test/gtest/TestShortcutKeyDefinitions.cpp create mode 100644 dom/events/test/gtest/moz.build create mode 100644 dom/events/test/mochitest.toml create mode 100644 dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_1.html create mode 100644 dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_2.html create mode 100644 dom/events/test/pointerevents/bug968148_inner.html create mode 100644 dom/events/test/pointerevents/bug968148_inner2.html create mode 100644 dom/events/test/pointerevents/bug_1420589_iframe1.html create mode 100644 dom/events/test/pointerevents/bug_1420589_iframe2.html create mode 100644 dom/events/test/pointerevents/chrome.toml create mode 100644 dom/events/test/pointerevents/file_pointercapture_xorigin_iframe.html create mode 100644 dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_pointerlock.html create mode 100644 dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_touch.html create mode 100644 dom/events/test/pointerevents/file_test_trigger_fullscreen.html create mode 100644 dom/events/test/pointerevents/iframe.html create mode 100644 dom/events/test/pointerevents/mochitest.toml create mode 100644 dom/events/test/pointerevents/mochitest_support_external.js create mode 100644 dom/events/test/pointerevents/mochitest_support_internal.js create mode 100644 dom/events/test/pointerevents/pointerevent_utils.js create mode 100644 dom/events/test/pointerevents/readme.md create mode 100644 dom/events/test/pointerevents/test_bug1285128.html create mode 100644 dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_1.html create mode 100644 dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_2.html create mode 100644 dom/events/test/pointerevents/test_bug1303704.html create mode 100644 dom/events/test/pointerevents/test_bug1315862.html create mode 100644 dom/events/test/pointerevents/test_bug1323158.html create mode 100644 dom/events/test/pointerevents/test_bug1403055.html create mode 100644 dom/events/test/pointerevents/test_bug1420589_1.html create mode 100644 dom/events/test/pointerevents/test_bug1420589_2.html create mode 100644 dom/events/test/pointerevents/test_bug1420589_3.html create mode 100644 dom/events/test/pointerevents/test_bug1697769.xhtml create mode 100644 dom/events/test/pointerevents/test_bug1725416.html create mode 100644 dom/events/test/pointerevents/test_bug968148.html create mode 100644 dom/events/test/pointerevents/test_getCoalescedEvents.html create mode 100644 dom/events/test/pointerevents/test_getCoalescedEvents_touch.html create mode 100644 dom/events/test/pointerevents/test_multiple_touches.html create mode 100644 dom/events/test/pointerevents/test_pointercapture_remove_iframe.html create mode 100644 dom/events/test/pointerevents/test_pointercapture_xorigin_iframe.html create mode 100644 dom/events/test/pointerevents/test_pointermove_drag_scrollbar.html create mode 100644 dom/events/test/pointerevents/test_remove_frame_when_got_pointer_capture.html create mode 100644 dom/events/test/pointerevents/test_synthesized_touch.html create mode 100644 dom/events/test/pointerevents/test_trigger_fullscreen_by_pointer_events.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_attributes_hoverable_pointers-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_attributes_nohover_pointers-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_boundary_events_in_capturing-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_change-touch-action-onpointerdown_touch-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_constructor.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_drag_interaction-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_movementxy-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_multiple_primary_pointers_boundary_events-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_pointerId_scope-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_pointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_after_pointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_pen-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_after_pointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_pen-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_events_to_original_target-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_onpointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_pointerevent_sequence_at_implicit_release_on_drag-manual.html create mode 100644 dom/events/test/pointerevents/test_wpt_touch_action.html create mode 100644 dom/events/test/pointerevents/touch_action_helpers.js create mode 100644 dom/events/test/pointerevents/wpt/compat/pointerevent_touch-action_two-finger_interaction-manual.html create mode 100644 dom/events/test/pointerevents/wpt/html/pointerevent_drag_interaction-manual.html create mode 100644 dom/events/test/pointerevents/wpt/idlharness.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_attributes_hoverable_pointers-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_attributes_nohover_pointers-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_boundary_events_in_capturing-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_change-touch-action-onpointerdown_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_constructor.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_multiple_primary_pointers_boundary_events-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_pointerId_scope-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_pointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_pointerleave_after_pointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_pointerleave_pen-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_pointerout_after_pointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_pointerout_pen-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_events_to_original_target-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_onpointercancel_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_click-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_drag-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_styles.css create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_support.js create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-auto-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-button-test_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-illegal.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-none_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_parent-none_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-keyboard-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-mouse-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-none-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-down-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-left-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-right-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-up-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-y-css_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-span-test_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-svg-test_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-table-test_touch-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerevent_touch-action-verification.html create mode 100644 dom/events/test/pointerevents/wpt/pointerlock/pointerevent_movementxy-manual.html create mode 100644 dom/events/test/pointerevents/wpt/pointerlock/resources/pointerevent_movementxy-iframe.html create mode 100644 dom/events/test/pointerevents/wpt/resources/pointerevent_attributes_hoverable_pointers-iframe.html create mode 100644 dom/events/test/pointerevents/wpt/resources/pointerevent_pointerId_scope-iframe.html create mode 100644 dom/events/test/test_DataTransferItemList.html create mode 100644 dom/events/test/test_accel_virtual_modifier.html create mode 100644 dom/events/test/test_accesskey.html create mode 100644 dom/events/test/test_addEventListenerExtraArg.html create mode 100644 dom/events/test/test_all_synthetic_events.html create mode 100644 dom/events/test/test_auxclick_autoscroll_off.html create mode 100644 dom/events/test/test_bug1003432.html create mode 100644 dom/events/test/test_bug1003432.js create mode 100644 dom/events/test/test_bug1013412.html create mode 100644 dom/events/test/test_bug1017086_enable.html create mode 100644 dom/events/test/test_bug1037990.html create mode 100644 dom/events/test/test_bug1079236.html create mode 100644 dom/events/test/test_bug1127588.html create mode 100644 dom/events/test/test_bug1128787-1.html create mode 100644 dom/events/test/test_bug1128787-2.html create mode 100644 dom/events/test/test_bug1128787-3.html create mode 100644 dom/events/test/test_bug1145910.html create mode 100644 dom/events/test/test_bug1150308.html create mode 100644 dom/events/test/test_bug1248459.html create mode 100644 dom/events/test/test_bug1264380.html create mode 100644 dom/events/test/test_bug1298970.html create mode 100644 dom/events/test/test_bug1304044.html create mode 100644 dom/events/test/test_bug1305458.html create mode 100644 dom/events/test/test_bug1327798.html create mode 100644 dom/events/test/test_bug1332699.html create mode 100644 dom/events/test/test_bug1339758.html create mode 100644 dom/events/test/test_bug1369072.html create mode 100644 dom/events/test/test_bug1412775.xhtml create mode 100644 dom/events/test/test_bug1429572.html create mode 100644 dom/events/test/test_bug1446834.html create mode 100644 dom/events/test/test_bug1447993.html create mode 100644 dom/events/test/test_bug1484371.html create mode 100644 dom/events/test/test_bug1534562.html create mode 100644 dom/events/test/test_bug1539497.html create mode 100644 dom/events/test/test_bug1581192.html create mode 100644 dom/events/test/test_bug1635018.html create mode 100644 dom/events/test/test_bug1637259.html create mode 100644 dom/events/test/test_bug1673434.html create mode 100644 dom/events/test/test_bug1681800.html create mode 100644 dom/events/test/test_bug1686716.html create mode 100644 dom/events/test/test_bug1692052.html create mode 100644 dom/events/test/test_bug1692277.html create mode 100644 dom/events/test/test_bug1709832.html create mode 100644 dom/events/test/test_bug1710509.html create mode 100644 dom/events/test/test_bug1728171.html create mode 100644 dom/events/test/test_bug226361.xhtml create mode 100644 dom/events/test/test_bug238987.html create mode 100644 dom/events/test/test_bug288392.html create mode 100644 dom/events/test/test_bug299673-1.html create mode 100644 dom/events/test/test_bug299673-2.html create mode 100644 dom/events/test/test_bug322588.html create mode 100644 dom/events/test/test_bug328885.html create mode 100644 dom/events/test/test_bug336682.js create mode 100644 dom/events/test/test_bug336682_1.html create mode 100644 dom/events/test/test_bug336682_2.xhtml create mode 100644 dom/events/test/test_bug367781.html create mode 100644 dom/events/test/test_bug379120.html create mode 100644 dom/events/test/test_bug402089.html create mode 100644 dom/events/test/test_bug405632.html create mode 100644 dom/events/test/test_bug409604.html create mode 100644 dom/events/test/test_bug412567.html create mode 100644 dom/events/test/test_bug415498.xhtml create mode 100644 dom/events/test/test_bug418986-3.html create mode 100644 dom/events/test/test_bug418986-3.xhtml create mode 100644 dom/events/test/test_bug422132.html create mode 100644 dom/events/test/test_bug426082.html create mode 100644 dom/events/test/test_bug427537.html create mode 100644 dom/events/test/test_bug428988.html create mode 100644 dom/events/test/test_bug432698.html create mode 100644 dom/events/test/test_bug443985.html create mode 100644 dom/events/test/test_bug447736.html create mode 100644 dom/events/test/test_bug448602.html create mode 100644 dom/events/test/test_bug450876.html create mode 100644 dom/events/test/test_bug456273.html create mode 100644 dom/events/test/test_bug457672.html create mode 100644 dom/events/test/test_bug489671.html create mode 100644 dom/events/test/test_bug493251.html create mode 100644 dom/events/test/test_bug508479.html create mode 100644 dom/events/test/test_bug517851.html create mode 100644 dom/events/test/test_bug524674.xhtml create mode 100644 dom/events/test/test_bug534833.html create mode 100644 dom/events/test/test_bug545268.html create mode 100644 dom/events/test/test_bug547996-1.html create mode 100644 dom/events/test/test_bug547996-2.xhtml create mode 100644 dom/events/test/test_bug547996-3.xhtml create mode 100644 dom/events/test/test_bug556493.html create mode 100644 dom/events/test/test_bug563329.html create mode 100644 dom/events/test/test_bug574663.html create mode 100644 dom/events/test/test_bug586961.xhtml create mode 100644 dom/events/test/test_bug591249.xhtml create mode 100644 dom/events/test/test_bug591815.html create mode 100644 dom/events/test/test_bug593959.html create mode 100644 dom/events/test/test_bug602962.xhtml create mode 100644 dom/events/test/test_bug603008.html create mode 100644 dom/events/test/test_bug605242.html create mode 100644 dom/events/test/test_bug607464.html create mode 100644 dom/events/test/test_bug613634.html create mode 100644 dom/events/test/test_bug615597.html create mode 100644 dom/events/test/test_bug617528.xhtml create mode 100644 dom/events/test/test_bug624127.html create mode 100644 dom/events/test/test_bug635465.html create mode 100644 dom/events/test/test_bug641477.html create mode 100644 dom/events/test/test_bug648573.html create mode 100644 dom/events/test/test_bug650493.html create mode 100644 dom/events/test/test_bug656379-1.html create mode 100644 dom/events/test/test_bug656379-2.html create mode 100644 dom/events/test/test_bug656954.html create mode 100644 dom/events/test/test_bug659071.html create mode 100644 dom/events/test/test_bug659350.html create mode 100644 dom/events/test/test_bug662678.html create mode 100644 dom/events/test/test_bug667612.html create mode 100644 dom/events/test/test_bug667919-1.html create mode 100644 dom/events/test/test_bug679494.xhtml create mode 100644 dom/events/test/test_bug684208.html create mode 100644 dom/events/test/test_bug687787.html create mode 100644 dom/events/test/test_bug689564.html create mode 100644 dom/events/test/test_bug698929.html create mode 100644 dom/events/test/test_bug704423.html create mode 100644 dom/events/test/test_bug741666.html create mode 100644 dom/events/test/test_bug812744.html create mode 100644 dom/events/test/test_bug822898.html create mode 100644 dom/events/test/test_bug855741.html create mode 100644 dom/events/test/test_bug864040.html create mode 100644 dom/events/test/test_bug924087.html create mode 100644 dom/events/test/test_bug930374-chrome.html create mode 100644 dom/events/test/test_bug930374-content.html create mode 100644 dom/events/test/test_bug944011.html create mode 100644 dom/events/test/test_bug944847.html create mode 100644 dom/events/test/test_bug946632.html create mode 100644 dom/events/test/test_bug967796.html create mode 100644 dom/events/test/test_bug985988.html create mode 100644 dom/events/test/test_bug998809.html create mode 100644 dom/events/test/test_click_on_reframed_generated_text.html create mode 100644 dom/events/test/test_click_on_restyled_element.html create mode 100644 dom/events/test/test_clickevent_on_input.html create mode 100644 dom/events/test/test_coalesce_mousewheel.html create mode 100644 dom/events/test/test_coalesce_touchmove.html create mode 100644 dom/events/test/test_continuous_wheel_events.html create mode 100644 dom/events/test/test_dblclick_explicit_original_target.html create mode 100644 dom/events/test/test_deltaMode_lines_always_enabled.html create mode 100644 dom/events/test/test_deviceSensor.html create mode 100644 dom/events/test/test_disabled_events.html create mode 100644 dom/events/test/test_dnd_with_modifiers.html create mode 100644 dom/events/test/test_dom_activate_event.html create mode 100644 dom/events/test/test_dom_keyboard_event.html create mode 100644 dom/events/test/test_dom_mouse_event.html create mode 100644 dom/events/test/test_dom_storage_event.html create mode 100644 dom/events/test/test_dom_wheel_event.html create mode 100644 dom/events/test/test_drag_coords.html create mode 100644 dom/events/test/test_drag_image_file.html create mode 100644 dom/events/test/test_draggableprop.html create mode 100644 dom/events/test/test_dragstart.html create mode 100644 dom/events/test/test_error_events.html create mode 100644 dom/events/test/test_eventTimeStamp.html create mode 100644 dom/events/test/test_event_handler_cc.html create mode 100644 dom/events/test/test_event_screenXY_in_cross_origin_iframe.html create mode 100644 dom/events/test/test_event_screenXY_with_zoom.html create mode 100644 dom/events/test/test_eventctors.html create mode 100644 dom/events/test/test_eventctors.xhtml create mode 100644 dom/events/test/test_eventctors_sensors.html create mode 100644 dom/events/test/test_eventhandler_scoping.html create mode 100644 dom/events/test/test_focus_abspos.html create mode 100644 dom/events/test/test_focus_blur_on_click_in_cross_origin_iframe.html create mode 100644 dom/events/test/test_focus_blur_on_click_in_deep_cross_origin_iframe.html create mode 100644 dom/events/test/test_hover_mouseleave.html create mode 100644 dom/events/test/test_legacy_event.html create mode 100644 dom/events/test/test_legacy_touch_api.html create mode 100644 dom/events/test/test_marquee_events.html create mode 100644 dom/events/test/test_messageEvent.html create mode 100644 dom/events/test/test_messageEvent_init.html create mode 100644 dom/events/test/test_mouse_capture_iframe.html create mode 100644 dom/events/test/test_mouse_enterleave_iframe.html create mode 100644 dom/events/test/test_mouse_over_at_removing_down_target.html create mode 100644 dom/events/test/test_moving_and_expanding_selection_per_page.html create mode 100644 dom/events/test/test_moz_mouse_pixel_scroll_event.html create mode 100644 dom/events/test/test_offsetxy.html create mode 100644 dom/events/test/test_onerror_handler_args.html create mode 100644 dom/events/test/test_passive_listeners.html create mode 100644 dom/events/test/test_scroll_per_page.html create mode 100644 dom/events/test/test_selection_after_right_click.html create mode 100644 dom/events/test/test_slotted_mouse_event.html create mode 100644 dom/events/test/test_slotted_text_click.html create mode 100644 dom/events/test/test_submitevent_on_form.html create mode 100644 dom/events/test/test_text_event_in_content.html create mode 100644 dom/events/test/test_unbound_before_in_active_chain.html create mode 100644 dom/events/test/test_use_conflated_keypress_event_model_on_newer_Office_Online_Server.html create mode 100644 dom/events/test/test_use_split_keypress_event_model_on_old_Confluence.html create mode 100644 dom/events/test/test_use_split_keypress_event_model_on_old_Office_Online_Server.html create mode 100644 dom/events/test/test_wheel_default_action.html create mode 100644 dom/events/test/test_wheel_zoom_on_form_controls.html create mode 100644 dom/events/test/window_bug1369072.html create mode 100644 dom/events/test/window_bug1412775.xhtml create mode 100644 dom/events/test/window_bug1429572.html create mode 100644 dom/events/test/window_bug1447993.html create mode 100644 dom/events/test/window_bug493251.html create mode 100644 dom/events/test/window_bug617528.xhtml create mode 100644 dom/events/test/window_bug659071.html create mode 100644 dom/events/test/window_empty_document.html create mode 100644 dom/events/test/window_wheel_default_action.html (limited to 'dom/events') diff --git a/dom/events/AnimationEvent.cpp b/dom/events/AnimationEvent.cpp new file mode 100644 index 0000000000..62a4c5196c --- /dev/null +++ b/dom/events/AnimationEvent.cpp @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/AnimationEvent.h" +#include "mozilla/ContentEvents.h" +#include "prtime.h" + +namespace mozilla::dom { + +AnimationEvent::AnimationEvent(EventTarget* aOwner, nsPresContext* aPresContext, + InternalAnimationEvent* aEvent) + : Event(aOwner, aPresContext, + aEvent ? aEvent : new InternalAnimationEvent(false, eVoidEvent)) { + if (aEvent) { + mEventIsInternal = false; + } else { + mEventIsInternal = true; + } +} + +// static +already_AddRefed AnimationEvent::Constructor( + const GlobalObject& aGlobal, const nsAString& aType, + const AnimationEventInit& aParam) { + nsCOMPtr t = do_QueryInterface(aGlobal.GetAsSupports()); + RefPtr e = new AnimationEvent(t, nullptr, nullptr); + bool trusted = e->Init(t); + + e->InitEvent(aType, aParam.mBubbles, aParam.mCancelable); + + InternalAnimationEvent* internalEvent = e->mEvent->AsAnimationEvent(); + internalEvent->mAnimationName = aParam.mAnimationName; + internalEvent->mElapsedTime = aParam.mElapsedTime; + internalEvent->mPseudoElement = aParam.mPseudoElement; + + e->SetTrusted(trusted); + e->SetComposed(aParam.mComposed); + return e.forget(); +} + +void AnimationEvent::GetAnimationName(nsAString& aAnimationName) { + aAnimationName = mEvent->AsAnimationEvent()->mAnimationName; +} + +float AnimationEvent::ElapsedTime() { + return mEvent->AsAnimationEvent()->mElapsedTime; +} + +void AnimationEvent::GetPseudoElement(nsAString& aPseudoElement) { + aPseudoElement = mEvent->AsAnimationEvent()->mPseudoElement; +} + +} // namespace mozilla::dom + +using namespace mozilla; +using namespace mozilla::dom; + +already_AddRefed NS_NewDOMAnimationEvent( + EventTarget* aOwner, nsPresContext* aPresContext, + InternalAnimationEvent* aEvent) { + RefPtr it = new AnimationEvent(aOwner, aPresContext, aEvent); + return it.forget(); +} diff --git a/dom/events/AnimationEvent.h b/dom/events/AnimationEvent.h new file mode 100644 index 0000000000..eb40246069 --- /dev/null +++ b/dom/events/AnimationEvent.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef mozilla_dom_AnimationEvent_h_ +#define mozilla_dom_AnimationEvent_h_ + +#include "mozilla/EventForwards.h" +#include "mozilla/dom/Event.h" +#include "mozilla/dom/AnimationEventBinding.h" +#include "nsStringFwd.h" + +namespace mozilla::dom { + +class AnimationEvent : public Event { + public: + AnimationEvent(EventTarget* aOwner, nsPresContext* aPresContext, + InternalAnimationEvent* aEvent); + + NS_INLINE_DECL_REFCOUNTING_INHERITED(AnimationEvent, Event) + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, const nsAString& aType, + const AnimationEventInit& aParam); + + virtual JSObject* WrapObjectInternal( + JSContext* aCx, JS::Handle aGivenProto) override { + return AnimationEvent_Binding::Wrap(aCx, this, aGivenProto); + } + + void GetAnimationName(nsAString& aAnimationName); + + float ElapsedTime(); + + void GetPseudoElement(nsAString& aPseudoElement); + + protected: + ~AnimationEvent() = default; +}; + +} // namespace mozilla::dom + +already_AddRefed NS_NewDOMAnimationEvent( + mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, + mozilla::InternalAnimationEvent* aEvent); + +#endif // mozilla_dom_AnimationEvent_h_ diff --git a/dom/events/AsyncEventDispatcher.cpp b/dom/events/AsyncEventDispatcher.cpp new file mode 100644 index 0000000000..297a03d7cb --- /dev/null +++ b/dom/events/AsyncEventDispatcher.cpp @@ -0,0 +1,156 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/AsyncEventDispatcher.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/EventDispatcher.h" +#include "mozilla/dom/DocumentInlines.h" +#include "mozilla/dom/Event.h" +#include "mozilla/dom/EventTarget.h" +#include "nsContentUtils.h" + +namespace mozilla { + +using namespace dom; + +/****************************************************************************** + * mozilla::AsyncEventDispatcher + ******************************************************************************/ + +AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget, + WidgetEvent& aEvent) + : CancelableRunnable("AsyncEventDispatcher"), + mTarget(aTarget), + mEventMessage(eUnidentifiedEvent) { + MOZ_ASSERT(mTarget); + RefPtr event = + EventDispatcher::CreateEvent(aTarget, nullptr, &aEvent, u""_ns); + mEvent = std::move(event); + mEventType.SetIsVoid(true); + NS_ASSERTION(mEvent, "Should never fail to create an event"); + mEvent->DuplicatePrivateData(); + mEvent->SetTrusted(aEvent.IsTrusted()); +} + +NS_IMETHODIMP +AsyncEventDispatcher::Run() { + if (mCanceled) { + return NS_OK; + } + nsINode* node = nsINode::FromEventTargetOrNull(mTarget); + if (mCheckStillInDoc) { + MOZ_ASSERT(node); + if (!node->IsInComposedDoc()) { + return NS_OK; + } + } + mTarget->AsyncEventRunning(this); + if (mEventMessage != eUnidentifiedEvent) { + MOZ_ASSERT(mComposed == Composed::eDefault); + return nsContentUtils::DispatchTrustedEvent( + node->OwnerDoc(), mTarget, mEventMessage, mCanBubble, Cancelable::eNo, + nullptr /* aDefaultAction */, mOnlyChromeDispatch); + } + // MOZ_KnownLives because this instance shouldn't be touched while running. + if (mEvent) { + DispatchEventOnTarget(MOZ_KnownLive(mTarget), MOZ_KnownLive(mEvent), + mOnlyChromeDispatch, mComposed); + } else { + DispatchEventOnTarget(MOZ_KnownLive(mTarget), mEventType, mCanBubble, + mOnlyChromeDispatch, mComposed); + } + return NS_OK; +} + +// static +void AsyncEventDispatcher::DispatchEventOnTarget( + EventTarget* aTarget, const nsAString& aEventType, CanBubble aCanBubble, + ChromeOnlyDispatch aOnlyChromeDispatch, Composed aComposed) { + RefPtr event = NS_NewDOMEvent(aTarget, nullptr, nullptr); + event->InitEvent(aEventType, aCanBubble, Cancelable::eNo); + event->SetTrusted(true); + DispatchEventOnTarget(aTarget, event, aOnlyChromeDispatch, aComposed); +} + +// static +void AsyncEventDispatcher::DispatchEventOnTarget( + EventTarget* aTarget, Event* aEvent, ChromeOnlyDispatch aOnlyChromeDispatch, + Composed aComposed) { + if (aComposed != Composed::eDefault) { + aEvent->WidgetEventPtr()->mFlags.mComposed = aComposed == Composed::eYes; + } + if (aOnlyChromeDispatch == ChromeOnlyDispatch::eYes) { + MOZ_ASSERT(aEvent->IsTrusted()); + aEvent->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true; + } + aTarget->DispatchEvent(*aEvent); +} + +nsresult AsyncEventDispatcher::Cancel() { + mCanceled = true; + return NS_OK; +} + +nsresult AsyncEventDispatcher::PostDOMEvent() { + RefPtr ensureDeletionWhenFailing = this; + return NS_DispatchToCurrentThread(ensureDeletionWhenFailing.forget()); +} + +void AsyncEventDispatcher::RunDOMEventWhenSafe() { + RefPtr ensureDeletionWhenFailing = this; + nsContentUtils::AddScriptRunner(ensureDeletionWhenFailing.forget()); +} + +// static +void AsyncEventDispatcher::RunDOMEventWhenSafe( + EventTarget& aTarget, const nsAString& aEventType, CanBubble aCanBubble, + ChromeOnlyDispatch aOnlyChromeDispatch /* = ChromeOnlyDispatch::eNo */, + Composed aComposed /* = Composed::eDefault */) { + if (nsContentUtils::IsSafeToRunScript()) { + OwningNonNull target = aTarget; + DispatchEventOnTarget(target, aEventType, aCanBubble, aOnlyChromeDispatch, + aComposed); + return; + } + (new AsyncEventDispatcher(&aTarget, aEventType, aCanBubble, + aOnlyChromeDispatch, aComposed)) + ->RunDOMEventWhenSafe(); +} + +void AsyncEventDispatcher::RunDOMEventWhenSafe( + EventTarget& aTarget, Event& aEvent, + ChromeOnlyDispatch aOnlyChromeDispatch /* = ChromeOnlyDispatch::eNo */) { + if (nsContentUtils::IsSafeToRunScript()) { + DispatchEventOnTarget(&aTarget, &aEvent, aOnlyChromeDispatch, + Composed::eDefault); + return; + } + (new AsyncEventDispatcher(&aTarget, do_AddRef(&aEvent), aOnlyChromeDispatch)) + ->RunDOMEventWhenSafe(); +} + +// static +nsresult AsyncEventDispatcher::RunDOMEventWhenSafe( + nsINode& aTarget, WidgetEvent& aEvent, + nsEventStatus* aEventStatus /* = nullptr */) { + if (nsContentUtils::IsSafeToRunScript()) { + // MOZ_KnownLive due to bug 1832202 + nsPresContext* presContext = aTarget.OwnerDoc()->GetPresContext(); + return EventDispatcher::Dispatch(MOZ_KnownLive(&aTarget), + MOZ_KnownLive(presContext), &aEvent, + nullptr, aEventStatus); + } + (new AsyncEventDispatcher(&aTarget, aEvent))->RunDOMEventWhenSafe(); + return NS_OK; +} + +void AsyncEventDispatcher::RequireNodeInDocument() { + MOZ_ASSERT(mTarget); + MOZ_ASSERT(mTarget->IsNode()); + mCheckStillInDoc = true; +} + +} // namespace mozilla diff --git a/dom/events/AsyncEventDispatcher.h b/dom/events/AsyncEventDispatcher.h new file mode 100644 index 0000000000..d17c0e700c --- /dev/null +++ b/dom/events/AsyncEventDispatcher.h @@ -0,0 +1,210 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_AsyncEventDispatcher_h_ +#define mozilla_AsyncEventDispatcher_h_ + +#include "mozilla/Attributes.h" +#include "mozilla/EventForwards.h" +#include "mozilla/RefPtr.h" +#include "mozilla/dom/Event.h" +#include "nsCOMPtr.h" +#include "mozilla/dom/Document.h" +#include "nsString.h" +#include "nsThreadUtils.h" + +class nsINode; + +namespace mozilla { + +/** + * Use AsyncEventDispatcher to fire a DOM event that requires safe a stable DOM. + * For example, you may need to fire an event from within layout, but + * want to ensure that the event handler doesn't mutate the DOM at + * the wrong time, in order to avoid resulting instability. + */ + +class AsyncEventDispatcher : public CancelableRunnable { + public: + /** + * If aOnlyChromeDispatch is true, the event is dispatched to only + * chrome node. In that case, if aTarget is already a chrome node, + * the event is dispatched to it, otherwise the dispatch path starts + * at the first chrome ancestor of that target. + */ + AsyncEventDispatcher( + dom::EventTarget* aTarget, const nsAString& aEventType, + CanBubble aCanBubble, + ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo, + Composed aComposed = Composed::eDefault) + : CancelableRunnable("AsyncEventDispatcher"), + mTarget(aTarget), + mEventType(aEventType), + mEventMessage(eUnidentifiedEvent), + mCanBubble(aCanBubble), + mOnlyChromeDispatch(aOnlyChromeDispatch), + mComposed(aComposed) {} + + /** + * If aOnlyChromeDispatch is true, the event is dispatched to only + * chrome node. In that case, if aTarget is already a chrome node, + * the event is dispatched to it, otherwise the dispatch path starts + * at the first chrome ancestor of that target. + */ + AsyncEventDispatcher(nsINode* aTarget, mozilla::EventMessage aEventMessage, + CanBubble aCanBubble, + ChromeOnlyDispatch aOnlyChromeDispatch) + : CancelableRunnable("AsyncEventDispatcher"), + mTarget(aTarget), + mEventMessage(aEventMessage), + mCanBubble(aCanBubble), + mOnlyChromeDispatch(aOnlyChromeDispatch) { + mEventType.SetIsVoid(true); + MOZ_ASSERT(mEventMessage != eUnidentifiedEvent); + } + + AsyncEventDispatcher(dom::EventTarget* aTarget, + mozilla::EventMessage aEventMessage, + CanBubble aCanBubble) + : CancelableRunnable("AsyncEventDispatcher"), + mTarget(aTarget), + mEventMessage(aEventMessage), + mCanBubble(aCanBubble) { + mEventType.SetIsVoid(true); + MOZ_ASSERT(mEventMessage != eUnidentifiedEvent); + } + + /** + * aEvent must have been created without Widget*Event and Internal*Event + * because this constructor assumes that it's safe to use aEvent + * asynchronously (i.e., after all objects allocated in the stack are + * destroyed). + */ + AsyncEventDispatcher( + dom::EventTarget* aTarget, already_AddRefed aEvent, + ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo) + : CancelableRunnable("AsyncEventDispatcher"), + mTarget(aTarget), + mEvent(aEvent), + mEventMessage(eUnidentifiedEvent), + mOnlyChromeDispatch(aOnlyChromeDispatch) { + MOZ_ASSERT( + mEvent->IsSafeToBeDispatchedAsynchronously(), + "The DOM event should be created without Widget*Event and " + "Internal*Event " + "because if it needs to be safe to be dispatched asynchronously"); + } + + AsyncEventDispatcher(dom::EventTarget* aTarget, WidgetEvent& aEvent); + + MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override; + nsresult Cancel() override; + nsresult PostDOMEvent(); + + /** + * Dispatch event immediately if it's safe to dispatch the event. + * Otherwise, posting the event into the queue to dispatch it when it's safe. + * + * Note that this method allows callers to call itself with unsafe aTarget + * because its lifetime is guaranteed by this method (in the case of + * synchronous dispatching) or AsyncEventDispatcher (in the case of + * asynchronous dispatching). + */ + MOZ_CAN_RUN_SCRIPT_BOUNDARY static void RunDOMEventWhenSafe( + dom::EventTarget& aTarget, const nsAString& aEventType, + CanBubble aCanBubble, + ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo, + Composed aComposed = Composed::eDefault); + + /** + * Dispatch event immediately if it's safe to dispatch the event. + * Otherwise, posting the event into the queue to dispatch it when it's safe. + * + * NOTE: Only this is now marked as MOZ_CAN_RUN_SCRIPT because all callers + * have already had safe smart pointers for both aTarget and aEvent. + * If you need to use this in a hot path without smart pointers, you may need + * to create unsafe version of this method for avoiding the extra add/release + * refcount cost in the case of asynchronous dispatching. + */ + MOZ_CAN_RUN_SCRIPT static void RunDOMEventWhenSafe( + dom::EventTarget& aTarget, dom::Event& aEvent, + ChromeOnlyDispatch aOnlyChromeDispatch = ChromeOnlyDispatch::eNo); + + /** + * Dispatch event immediately if it's safe to dispatch the event. + * Otherwise, posting the event into the queue to dispatch it when it's safe. + * + * Note that this method allows callers to call itself with unsafe aTarget + * because its lifetime is guaranteed by EventDispatcher (in the case of + * synchronous dispatching) or AsyncEventDispatcher (in the case of + * asynchronous dispatching). + */ + MOZ_CAN_RUN_SCRIPT_BOUNDARY static nsresult RunDOMEventWhenSafe( + nsINode& aTarget, WidgetEvent& aEvent, + nsEventStatus* aEventStatus = nullptr); + + // Calling this causes the Run() method to check that + // mTarget->IsInComposedDoc(). mTarget must be an nsINode or else we'll + // assert. + void RequireNodeInDocument(); + + // NOTE: The static version of this should be preferred when possible, because + // it avoids the allocation but this is useful when used in combination with + // LoadBlockingAsyncEventDispatcher. + void RunDOMEventWhenSafe(); + + protected: + MOZ_CAN_RUN_SCRIPT static void DispatchEventOnTarget( + dom::EventTarget* aTarget, dom::Event* aEvent, + ChromeOnlyDispatch aOnlyChromeDispatch, Composed aComposed); + MOZ_CAN_RUN_SCRIPT static void DispatchEventOnTarget( + dom::EventTarget* aTarget, const nsAString& aEventType, + CanBubble aCanBubble, ChromeOnlyDispatch aOnlyChromeDispatch, + Composed aComposed); + + public: + nsCOMPtr mTarget; + RefPtr mEvent; + // If mEventType is set, mEventMessage will be eUnidentifiedEvent. + // If mEventMessage is set, mEventType will be void. + // They can never both be set at the same time. + nsString mEventType; + EventMessage mEventMessage; + CanBubble mCanBubble = CanBubble::eNo; + ChromeOnlyDispatch mOnlyChromeDispatch = ChromeOnlyDispatch::eNo; + Composed mComposed = Composed::eDefault; + bool mCanceled = false; + bool mCheckStillInDoc = false; +}; + +class LoadBlockingAsyncEventDispatcher final : public AsyncEventDispatcher { + public: + LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, + const nsAString& aEventType, + CanBubble aBubbles, + ChromeOnlyDispatch aDispatchChromeOnly) + : AsyncEventDispatcher(aEventNode, aEventType, aBubbles, + aDispatchChromeOnly), + mBlockedDoc(aEventNode->OwnerDoc()) { + mBlockedDoc->BlockOnload(); + } + + LoadBlockingAsyncEventDispatcher(nsINode* aEventNode, + already_AddRefed aEvent) + : AsyncEventDispatcher(aEventNode, std::move(aEvent)), + mBlockedDoc(aEventNode->OwnerDoc()) { + mBlockedDoc->BlockOnload(); + } + + ~LoadBlockingAsyncEventDispatcher() { mBlockedDoc->UnblockOnload(true); } + + private: + RefPtr mBlockedDoc; +}; + +} // namespace mozilla + +#endif // mozilla_AsyncEventDispatcher_h_ diff --git a/dom/events/BeforeUnloadEvent.cpp b/dom/events/BeforeUnloadEvent.cpp new file mode 100644 index 0000000000..77f41d0010 --- /dev/null +++ b/dom/events/BeforeUnloadEvent.cpp @@ -0,0 +1,29 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/BeforeUnloadEvent.h" + +namespace mozilla::dom { + +void BeforeUnloadEvent::SetReturnValue(const nsAString& aReturnValue) { + mText = aReturnValue; +} + +void BeforeUnloadEvent::GetReturnValue(nsAString& aReturnValue) { + aReturnValue = mText; +} + +} // namespace mozilla::dom + +using namespace mozilla; +using namespace mozilla::dom; + +already_AddRefed NS_NewDOMBeforeUnloadEvent( + EventTarget* aOwner, nsPresContext* aPresContext, WidgetEvent* aEvent) { + RefPtr it = + new BeforeUnloadEvent(aOwner, aPresContext, aEvent); + return it.forget(); +} diff --git a/dom/events/BeforeUnloadEvent.h b/dom/events/BeforeUnloadEvent.h new file mode 100644 index 0000000000..2ffc34cfea --- /dev/null +++ b/dom/events/BeforeUnloadEvent.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_BeforeUnloadEvent_h_ +#define mozilla_dom_BeforeUnloadEvent_h_ + +#include "mozilla/dom/BeforeUnloadEventBinding.h" +#include "mozilla/dom/Event.h" + +namespace mozilla::dom { + +class BeforeUnloadEvent : public Event { + public: + BeforeUnloadEvent(EventTarget* aOwner, nsPresContext* aPresContext, + WidgetEvent* aEvent) + : Event(aOwner, aPresContext, aEvent) {} + + virtual BeforeUnloadEvent* AsBeforeUnloadEvent() override { return this; } + + virtual JSObject* WrapObjectInternal( + JSContext* aCx, JS::Handle aGivenProto) override { + return BeforeUnloadEvent_Binding::Wrap(aCx, this, aGivenProto); + } + + NS_INLINE_DECL_REFCOUNTING_INHERITED(BeforeUnloadEvent, Event) + + void GetReturnValue(nsAString& aReturnValue); + void SetReturnValue(const nsAString& aReturnValue); + + protected: + ~BeforeUnloadEvent() = default; + + nsString mText; +}; + +} // namespace mozilla::dom + +already_AddRefed NS_NewDOMBeforeUnloadEvent( + mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, + mozilla::WidgetEvent* aEvent); + +#endif // mozilla_dom_BeforeUnloadEvent_h_ diff --git a/dom/events/Clipboard.cpp b/dom/events/Clipboard.cpp new file mode 100644 index 0000000000..560002dd68 --- /dev/null +++ b/dom/events/Clipboard.cpp @@ -0,0 +1,777 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/Clipboard.h" + +#include + +#include "mozilla/AbstractThread.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/RefPtr.h" +#include "mozilla/Result.h" +#include "mozilla/ResultVariant.h" +#include "mozilla/dom/BlobBinding.h" +#include "mozilla/dom/ClipboardItem.h" +#include "mozilla/dom/ClipboardBinding.h" +#include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/PromiseNativeHandler.h" +#include "mozilla/dom/DataTransfer.h" +#include "mozilla/dom/DataTransferItemList.h" +#include "mozilla/dom/DataTransferItem.h" +#include "mozilla/dom/Document.h" +#include "mozilla/StaticPrefs_dom.h" +#include "imgIContainer.h" +#include "imgITools.h" +#include "nsArrayUtils.h" +#include "nsComponentManagerUtils.h" +#include "nsContentUtils.h" +#include "nsIClipboard.h" +#include "nsIInputStream.h" +#include "nsIParserUtils.h" +#include "nsISupportsPrimitives.h" +#include "nsITransferable.h" +#include "nsNetUtil.h" +#include "nsServiceManagerUtils.h" +#include "nsStringStream.h" +#include "nsTArray.h" +#include "nsThreadUtils.h" +#include "nsVariant.h" + +static mozilla::LazyLogModule gClipboardLog("Clipboard"); + +namespace mozilla::dom { + +Clipboard::Clipboard(nsPIDOMWindowInner* aWindow) + : DOMEventTargetHelper(aWindow) {} + +Clipboard::~Clipboard() = default; + +// static +bool Clipboard::IsTestingPrefEnabledOrHasReadPermission( + nsIPrincipal& aSubjectPrincipal) { + return IsTestingPrefEnabled() || + nsContentUtils::PrincipalHasPermission(aSubjectPrincipal, + nsGkAtoms::clipboardRead); +} + +namespace { + +/** + * This is a base class for ClipboardGetCallbackForRead and + * ClipboardGetCallbackForReadText. + */ +class ClipboardGetCallback : public nsIAsyncClipboardGetCallback { + public: + explicit ClipboardGetCallback(RefPtr&& aPromise) + : mPromise(std::move(aPromise)) {} + + // nsIAsyncClipboardGetCallback + NS_IMETHOD OnError(nsresult aResult) override final { + MOZ_ASSERT(mPromise); + RefPtr p(std::move(mPromise)); + p->MaybeRejectWithNotAllowedError( + "Clipboard read operation is not allowed."); + return NS_OK; + } + + protected: + virtual ~ClipboardGetCallback() { MOZ_ASSERT(!mPromise); }; + + // Not cycle-collected, because it should be nulled when the request is + // answered, rejected or aborted. + RefPtr mPromise; +}; + +class ClipboardGetCallbackForRead final : public ClipboardGetCallback { + public: + explicit ClipboardGetCallbackForRead(nsIGlobalObject* aGlobal, + RefPtr&& aPromise) + : ClipboardGetCallback(std::move(aPromise)), mGlobal(aGlobal) {} + + // This object will never be held by a cycle-collected object, so it doesn't + // need to be cycle-collected despite holding alive cycle-collected objects. + NS_DECL_ISUPPORTS + + // nsIAsyncClipboardGetCallback + NS_IMETHOD OnSuccess( + nsIAsyncGetClipboardData* aAsyncGetClipboardData) override { + MOZ_ASSERT(mPromise); + MOZ_ASSERT(aAsyncGetClipboardData); + + nsTArray flavorList; + nsresult rv = aAsyncGetClipboardData->GetFlavorList(flavorList); + if (NS_FAILED(rv)) { + return OnError(rv); + } + + AutoTArray, 3> entries; + for (const auto& format : flavorList) { + auto entry = MakeRefPtr( + mGlobal, NS_ConvertUTF8toUTF16(format)); + entry->LoadDataFromSystemClipboard(aAsyncGetClipboardData); + entries.AppendElement(std::move(entry)); + } + + RefPtr p(std::move(mPromise)); + // We currently only support one clipboard item. + p->MaybeResolve( + AutoTArray, 1>{MakeRefPtr( + mGlobal, PresentationStyle::Unspecified, std::move(entries))}); + + return NS_OK; + } + + protected: + ~ClipboardGetCallbackForRead() = default; + + nsCOMPtr mGlobal; +}; + +NS_IMPL_ISUPPORTS(ClipboardGetCallbackForRead, nsIAsyncClipboardGetCallback) + +class ClipboardGetCallbackForReadText final + : public ClipboardGetCallback, + public nsIAsyncClipboardRequestCallback { + public: + explicit ClipboardGetCallbackForReadText(RefPtr&& aPromise) + : ClipboardGetCallback(std::move(aPromise)) {} + + // This object will never be held by a cycle-collected object, so it doesn't + // need to be cycle-collected despite holding alive cycle-collected objects. + NS_DECL_ISUPPORTS + + // nsIAsyncClipboardGetCallback + NS_IMETHOD OnSuccess( + nsIAsyncGetClipboardData* aAsyncGetClipboardData) override { + MOZ_ASSERT(mPromise); + MOZ_ASSERT(!mTransferable); + MOZ_ASSERT(aAsyncGetClipboardData); + + AutoTArray flavors; + nsresult rv = aAsyncGetClipboardData->GetFlavorList(flavors); + if (NS_FAILED(rv)) { + return OnError(rv); + } + + mTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); + if (NS_WARN_IF(!mTransferable)) { + return OnError(NS_ERROR_UNEXPECTED); + } + + mTransferable->Init(nullptr); + mTransferable->AddDataFlavor(kTextMime); + if (!flavors.Contains(kTextMime)) { + return OnComplete(NS_OK); + } + + rv = aAsyncGetClipboardData->GetData(mTransferable, this); + if (NS_FAILED(rv)) { + return OnError(rv); + } + + return NS_OK; + } + + // nsIAsyncClipboardRequestCallback + NS_IMETHOD OnComplete(nsresult aResult) override { + MOZ_ASSERT(mPromise); + MOZ_ASSERT(mTransferable); + + if (NS_FAILED(aResult)) { + return OnError(aResult); + } + + nsAutoString str; + nsCOMPtr data; + nsresult rv = + mTransferable->GetTransferData(kTextMime, getter_AddRefs(data)); + if (!NS_WARN_IF(NS_FAILED(rv))) { + nsCOMPtr supportsstr = do_QueryInterface(data); + MOZ_ASSERT(supportsstr); + if (supportsstr) { + supportsstr->GetData(str); + } + } + + RefPtr p(std::move(mPromise)); + p->MaybeResolve(str); + + return NS_OK; + } + + protected: + ~ClipboardGetCallbackForReadText() = default; + + nsCOMPtr mTransferable; +}; + +NS_IMPL_ISUPPORTS(ClipboardGetCallbackForReadText, nsIAsyncClipboardGetCallback, + nsIAsyncClipboardRequestCallback) + +} // namespace + +void Clipboard::RequestRead(Promise* aPromise, ReadRequestType aType, + nsPIDOMWindowInner* aOwner, + nsIPrincipal& aPrincipal) { + RefPtr p(aPromise); + nsCOMPtr owner(aOwner); + + nsresult rv; + nsCOMPtr clipboardService( + do_GetService("@mozilla.org/widget/clipboard;1", &rv)); + if (NS_FAILED(rv)) { + p->MaybeReject(NS_ERROR_UNEXPECTED); + return; + } + + RefPtr callback; + switch (aType) { + case ReadRequestType::eRead: { + nsCOMPtr global = do_QueryInterface(owner); + if (NS_WARN_IF(!global)) { + p->MaybeReject(NS_ERROR_UNEXPECTED); + return; + } + + callback = MakeRefPtr(global, std::move(p)); + rv = clipboardService->AsyncGetData( + // Mandatory data types defined in + // https://w3c.github.io/clipboard-apis/#mandatory-data-types-x + AutoTArray{nsDependentCString(kHTMLMime), + nsDependentCString(kTextMime), + nsDependentCString(kPNGImageMime)}, + nsIClipboard::kGlobalClipboard, owner->GetWindowContext(), + &aPrincipal, callback); + break; + } + case ReadRequestType::eReadText: { + callback = MakeRefPtr(std::move(p)); + rv = clipboardService->AsyncGetData( + AutoTArray{nsDependentCString(kTextMime)}, + nsIClipboard::kGlobalClipboard, owner->GetWindowContext(), + &aPrincipal, callback); + break; + } + default: { + MOZ_ASSERT_UNREACHABLE("Unknown read type"); + break; + } + } + + if (NS_FAILED(rv)) { + MOZ_ASSERT(callback); + callback->OnError(rv); + return; + } +} + +static bool IsReadTextExposedToContent() { + return StaticPrefs::dom_events_asyncClipboard_readText_DoNotUseDirectly(); +} + +already_AddRefed Clipboard::ReadHelper(nsIPrincipal& aSubjectPrincipal, + ReadRequestType aType, + ErrorResult& aRv) { + // Create a new promise + RefPtr p = dom::Promise::Create(GetOwnerGlobal(), aRv); + if (aRv.Failed() || !p) { + return nullptr; + } + + nsPIDOMWindowInner* owner = GetOwner(); + if (!owner) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + if (IsTestingPrefEnabledOrHasReadPermission(aSubjectPrincipal)) { + MOZ_LOG(GetClipboardLog(), LogLevel::Debug, + ("%s: testing pref enabled or has read permission", __FUNCTION__)); + } else { + // Testing pref is not enabled and no read permission (for extension), so + // need to check user activation. + WindowContext* windowContext = owner->GetWindowContext(); + if (!windowContext) { + MOZ_ASSERT_UNREACHABLE("There should be a WindowContext."); + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + // If no transient user activation, reject the promise and return. + if (!windowContext->HasValidTransientUserGestureActivation()) { + p->MaybeRejectWithNotAllowedError( + "Clipboard read request was blocked due to lack of " + "user activation."); + return p.forget(); + } + } + + RequestRead(p, aType, owner, aSubjectPrincipal); + return p.forget(); +} + +already_AddRefed Clipboard::Read(nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv) { + return ReadHelper(aSubjectPrincipal, ReadRequestType::eRead, aRv); +} + +already_AddRefed Clipboard::ReadText(nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv) { + return ReadHelper(aSubjectPrincipal, ReadRequestType::eReadText, aRv); +} + +namespace { + +struct NativeEntry { + nsString mType; + nsCOMPtr mData; + + NativeEntry(const nsAString& aType, nsIVariant* aData) + : mType(aType), mData(aData) {} +}; +using NativeEntryPromise = MozPromise; + +class BlobTextHandler final : public PromiseNativeHandler { + public: + NS_DECL_THREADSAFE_ISUPPORTS + + explicit BlobTextHandler(const nsAString& aType) : mType(aType) {} + + RefPtr Promise() { return mHolder.Ensure(__func__); } + + void Reject() { + CopyableErrorResult rv; + rv.ThrowUnknownError("Unable to read blob for '"_ns + + NS_ConvertUTF16toUTF8(mType) + "' as text."_ns); + mHolder.Reject(rv, __func__); + } + + void ResolvedCallback(JSContext* aCx, JS::Handle aValue, + ErrorResult& aRv) override { + AssertIsOnMainThread(); + + nsString text; + if (!ConvertJSValueToUSVString(aCx, aValue, "ClipboardItem text", text)) { + Reject(); + return; + } + + RefPtr variant = new nsVariantCC(); + variant->SetAsAString(text); + + NativeEntry native(mType, variant); + mHolder.Resolve(std::move(native), __func__); + } + + void RejectedCallback(JSContext* aCx, JS::Handle aValue, + ErrorResult& aRv) override { + Reject(); + } + + private: + ~BlobTextHandler() = default; + + nsString mType; + MozPromiseHolder mHolder; +}; + +NS_IMPL_ISUPPORTS0(BlobTextHandler) + +static RefPtr GetStringNativeEntry( + const nsAString& aType, const OwningStringOrBlob& aData) { + if (aData.IsString()) { + RefPtr variant = new nsVariantCC(); + variant->SetAsAString(aData.GetAsString()); + NativeEntry native(aType, variant); + return NativeEntryPromise::CreateAndResolve(native, __func__); + } + + RefPtr handler = new BlobTextHandler(aType); + IgnoredErrorResult ignored; + RefPtr promise = aData.GetAsBlob()->Text(ignored); + if (ignored.Failed()) { + CopyableErrorResult rv; + rv.ThrowUnknownError("Unable to read blob for '"_ns + + NS_ConvertUTF16toUTF8(aType) + "' as text."_ns); + return NativeEntryPromise::CreateAndReject(rv, __func__); + } + promise->AppendNativeHandler(handler); + return handler->Promise(); +} + +class ImageDecodeCallback final : public imgIContainerCallback { + public: + NS_DECL_ISUPPORTS + + explicit ImageDecodeCallback(const nsAString& aType) : mType(aType) {} + + RefPtr Promise() { return mHolder.Ensure(__func__); } + + NS_IMETHOD OnImageReady(imgIContainer* aImage, nsresult aStatus) override { + // Request the image's width to force decoding the image header. + int32_t ignored; + if (NS_FAILED(aStatus) || NS_FAILED(aImage->GetWidth(&ignored))) { + CopyableErrorResult rv; + rv.ThrowDataError("Unable to decode blob for '"_ns + + NS_ConvertUTF16toUTF8(mType) + "' as image."_ns); + mHolder.Reject(rv, __func__); + return NS_OK; + } + + RefPtr variant = new nsVariantCC(); + variant->SetAsISupports(aImage); + + // Note: We always put the image as "native" on the clipboard. + NativeEntry native(NS_LITERAL_STRING_FROM_CSTRING(kNativeImageMime), + variant); + mHolder.Resolve(std::move(native), __func__); + return NS_OK; + }; + + private: + ~ImageDecodeCallback() = default; + + nsString mType; + MozPromiseHolder mHolder; +}; + +NS_IMPL_ISUPPORTS(ImageDecodeCallback, imgIContainerCallback) + +static RefPtr GetImageNativeEntry( + const nsAString& aType, const OwningStringOrBlob& aData) { + if (aData.IsString()) { + CopyableErrorResult rv; + rv.ThrowTypeError("DOMString not supported for '"_ns + + NS_ConvertUTF16toUTF8(aType) + "' as image data."_ns); + return NativeEntryPromise::CreateAndReject(rv, __func__); + } + + IgnoredErrorResult ignored; + nsCOMPtr stream; + aData.GetAsBlob()->CreateInputStream(getter_AddRefs(stream), ignored); + if (ignored.Failed()) { + CopyableErrorResult rv; + rv.ThrowUnknownError("Unable to read blob for '"_ns + + NS_ConvertUTF16toUTF8(aType) + "' as image."_ns); + return NativeEntryPromise::CreateAndReject(rv, __func__); + } + + RefPtr callback = new ImageDecodeCallback(aType); + nsCOMPtr imgtool = do_CreateInstance("@mozilla.org/image/tools;1"); + imgtool->DecodeImageAsync(stream, NS_ConvertUTF16toUTF8(aType), callback, + GetMainThreadSerialEventTarget()); + return callback->Promise(); +} + +static Result SanitizeNativeEntry( + const NativeEntry& aEntry) { + MOZ_ASSERT(aEntry.mType.EqualsLiteral(kHTMLMime)); + + nsAutoString string; + aEntry.mData->GetAsAString(string); + + nsCOMPtr parserUtils = + do_GetService(NS_PARSERUTILS_CONTRACTID); + if (!parserUtils) { + ErrorResult rv; + rv.ThrowUnknownError("Error while processing '"_ns + + NS_ConvertUTF16toUTF8(aEntry.mType) + "'."_ns); + return Err(std::move(rv)); + } + + uint32_t flags = nsIParserUtils::SanitizerAllowStyle | + nsIParserUtils::SanitizerAllowComments; + nsAutoString sanitized; + if (NS_FAILED(parserUtils->Sanitize(string, flags, sanitized))) { + ErrorResult rv; + rv.ThrowUnknownError("Error while processing '"_ns + + NS_ConvertUTF16toUTF8(aEntry.mType) + "'."_ns); + return Err(std::move(rv)); + } + + RefPtr variant = new nsVariantCC(); + variant->SetAsAString(sanitized); + return NativeEntry(aEntry.mType, variant); +} + +static RefPtr GetNativeEntry( + const nsAString& aType, const OwningStringOrBlob& aData) { + if (aType.EqualsLiteral(kPNGImageMime)) { + return GetImageNativeEntry(aType, aData); + } + + RefPtr promise = GetStringNativeEntry(aType, aData); + if (aType.EqualsLiteral(kHTMLMime)) { + promise = promise->Then( + GetMainThreadSerialEventTarget(), __func__, + [](const NativeEntryPromise::ResolveOrRejectValue& aValue) + -> RefPtr { + if (aValue.IsReject()) { + return NativeEntryPromise::CreateAndReject(aValue.RejectValue(), + __func__); + } + + auto sanitized = SanitizeNativeEntry(aValue.ResolveValue()); + if (sanitized.isErr()) { + return NativeEntryPromise::CreateAndReject( + CopyableErrorResult(sanitized.unwrapErr()), __func__); + } + return NativeEntryPromise::CreateAndResolve(sanitized.unwrap(), + __func__); + }); + } + return promise; +} + +// Restrict to types allowed by Chrome +// SVG is still disabled by default in Chrome. +static bool IsValidType(const nsAString& aType) { + return aType.EqualsLiteral(kPNGImageMime) || aType.EqualsLiteral(kTextMime) || + aType.EqualsLiteral(kHTMLMime); +} + +using NativeItemPromise = NativeEntryPromise::AllPromiseType; +static RefPtr GetClipboardNativeItem( + const ClipboardItem& aItem) { + nsTArray> promises; + for (const auto& entry : aItem.Entries()) { + const nsAString& type = entry->Type(); + if (!IsValidType(type)) { + CopyableErrorResult rv; + rv.ThrowNotAllowedError("Type '"_ns + NS_ConvertUTF16toUTF8(type) + + "' not supported for write"_ns); + return NativeItemPromise::CreateAndReject(rv, __func__); + } + + using GetDataPromise = ClipboardItem::ItemEntry::GetDataPromise; + promises.AppendElement(entry->GetData()->Then( + GetMainThreadSerialEventTarget(), __func__, + [t = nsString(type)](const GetDataPromise::ResolveOrRejectValue& aValue) + -> RefPtr { + if (aValue.IsReject()) { + return NativeEntryPromise::CreateAndReject( + CopyableErrorResult(aValue.RejectValue()), __func__); + } + + return GetNativeEntry(t, aValue.ResolveValue()); + })); + } + return NativeEntryPromise::All(GetCurrentSerialEventTarget(), promises); +} + +class ClipboardWriteCallback final : public nsIAsyncClipboardRequestCallback { + public: + // This object will never be held by a cycle-collected object, so it doesn't + // need to be cycle-collected despite holding alive cycle-collected objects. + NS_DECL_ISUPPORTS + + explicit ClipboardWriteCallback(Promise* aPromise, + ClipboardItem* aClipboardItem) + : mPromise(aPromise), mClipboardItem(aClipboardItem) {} + + // nsIAsyncClipboardRequestCallback + NS_IMETHOD OnComplete(nsresult aResult) override { + MOZ_ASSERT(mPromise); + + RefPtr promise = std::move(mPromise); + // XXX We need to check state here is because the promise might be rejected + // before the callback is called, we probably could wrap the promise into a + // structure to make it less confused. + if (promise->State() == Promise::PromiseState::Pending) { + if (NS_FAILED(aResult)) { + promise->MaybeRejectWithNotAllowedError( + "Clipboard write is not allowed."); + return NS_OK; + } + + promise->MaybeResolveWithUndefined(); + } + + return NS_OK; + } + + protected: + ~ClipboardWriteCallback() { + // Callback should be notified. + MOZ_ASSERT(!mPromise); + }; + + // It will be reset to nullptr once callback is notified. + RefPtr mPromise; + // Keep ClipboardItem alive until clipboard write is done. + RefPtr mClipboardItem; +}; + +NS_IMPL_ISUPPORTS(ClipboardWriteCallback, nsIAsyncClipboardRequestCallback) + +} // namespace + +already_AddRefed Clipboard::Write( + const Sequence>& aData, + nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { + // Create a promise + RefPtr p = dom::Promise::Create(GetOwnerGlobal(), aRv); + if (aRv.Failed()) { + return nullptr; + } + + RefPtr owner = GetOwner(); + Document* doc = owner ? owner->GetDoc() : nullptr; + if (!doc) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + // We want to disable security check for automated tests that have the pref + // dom.events.testing.asyncClipboard set to true + if (!IsTestingPrefEnabled() && + !nsContentUtils::IsCutCopyAllowed(doc, aSubjectPrincipal)) { + MOZ_LOG(GetClipboardLog(), LogLevel::Debug, + ("Clipboard, Write, Not allowed to write to clipboard\n")); + p->MaybeRejectWithNotAllowedError( + "Clipboard write was blocked due to lack of user activation."); + return p.forget(); + } + + // Get the clipboard service + nsCOMPtr clipboard( + do_GetService("@mozilla.org/widget/clipboard;1")); + if (!clipboard) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + nsCOMPtr context = doc->GetLoadContext(); + if (!context) { + p->MaybeRejectWithUndefined(); + return p.forget(); + } + + if (aData.Length() > 1) { + p->MaybeRejectWithNotAllowedError( + "Clipboard write is only supported with one ClipboardItem at the " + "moment"); + return p.forget(); + } + + if (aData.Length() == 0) { + // Nothing needs to be written to the clipboard. + p->MaybeResolveWithUndefined(); + return p.forget(); + } + + nsCOMPtr request; + RefPtr callback = + MakeRefPtr(p, aData[0]); + nsresult rv = clipboard->AsyncSetData(nsIClipboard::kGlobalClipboard, + callback, getter_AddRefs(request)); + if (NS_FAILED(rv)) { + p->MaybeReject(rv); + return p.forget(); + } + + GetClipboardNativeItem(aData[0])->Then( + GetMainThreadSerialEventTarget(), __func__, + [owner, request, context, principal = RefPtr{&aSubjectPrincipal}]( + const nsTArray& aEntries) { + RefPtr dataTransfer = + new DataTransfer(owner, eCopy, + /* is external */ true, + /* clipboard type */ -1); + + for (const auto& entry : aEntries) { + nsresult rv = dataTransfer->SetDataWithPrincipal( + entry.mType, entry.mData, 0, principal); + + if (NS_FAILED(rv)) { + request->Abort(rv); + return; + } + } + + // Get the transferable + RefPtr transferable = + dataTransfer->GetTransferable(0, context); + if (!transferable) { + request->Abort(NS_ERROR_FAILURE); + return; + } + + // Finally write data to clipboard + request->SetData(transferable, /* clipboard owner */ nullptr); + }, + [p, request](const CopyableErrorResult& aErrorResult) { + p->MaybeReject(CopyableErrorResult(aErrorResult)); + request->Abort(NS_ERROR_ABORT); + }); + + return p.forget(); +} + +already_AddRefed Clipboard::WriteText(const nsAString& aData, + nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv) { + nsCOMPtr global = GetOwnerGlobal(); + if (!global) { + aRv.ThrowInvalidStateError("Unable to get global."); + return nullptr; + } + + // Create a single-element Sequence to reuse Clipboard::Write. + nsTArray> items; + items.AppendElement(MakeRefPtr( + global, NS_LITERAL_STRING_FROM_CSTRING(kTextMime), aData)); + + nsTArray> sequence; + RefPtr item = MakeRefPtr( + GetOwner(), PresentationStyle::Unspecified, std::move(items)); + sequence.AppendElement(*item); + + return Write(std::move(sequence), aSubjectPrincipal, aRv); +} + +JSObject* Clipboard::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return Clipboard_Binding::Wrap(aCx, this, aGivenProto); +} + +/* static */ +LogModule* Clipboard::GetClipboardLog() { return gClipboardLog; } + +/* static */ +bool Clipboard::ReadTextEnabled(JSContext* aCx, JSObject* aGlobal) { + nsIPrincipal* prin = nsContentUtils::SubjectPrincipal(aCx); + return IsReadTextExposedToContent() || + prin->GetIsAddonOrExpandedAddonPrincipal() || + prin->IsSystemPrincipal(); +} + +/* static */ +bool Clipboard::IsTestingPrefEnabled() { + bool clipboardTestingEnabled = + StaticPrefs::dom_events_testing_asyncClipboard_DoNotUseDirectly(); + MOZ_LOG(GetClipboardLog(), LogLevel::Debug, + ("Clipboard, Is testing enabled? %d\n", clipboardTestingEnabled)); + return clipboardTestingEnabled; +} + +NS_IMPL_CYCLE_COLLECTION_CLASS(Clipboard) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(Clipboard, + DOMEventTargetHelper) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(Clipboard, DOMEventTargetHelper) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Clipboard) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +NS_IMPL_ADDREF_INHERITED(Clipboard, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(Clipboard, DOMEventTargetHelper) + +} // namespace mozilla::dom diff --git a/dom/events/Clipboard.h b/dom/events/Clipboard.h new file mode 100644 index 0000000000..2df4df1ec5 --- /dev/null +++ b/dom/events/Clipboard.h @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_Clipboard_h_ +#define mozilla_dom_Clipboard_h_ + +#include "nsString.h" +#include "nsStringFwd.h" +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/Logging.h" +#include "mozilla/RefPtr.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/dom/DataTransfer.h" + +namespace mozilla::dom { + +class Promise; +class ClipboardItem; + +// https://www.w3.org/TR/clipboard-apis/#clipboard-interface +class Clipboard : public DOMEventTargetHelper { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(Clipboard, DOMEventTargetHelper) + + IMPL_EVENT_HANDLER(message) + IMPL_EVENT_HANDLER(messageerror) + + explicit Clipboard(nsPIDOMWindowInner* aWindow); + already_AddRefed Read(nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv); + already_AddRefed ReadText(nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv); + already_AddRefed Write( + const Sequence>& aData, + nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv); + already_AddRefed WriteText(const nsAString& aData, + nsIPrincipal& aSubjectPrincipal, + ErrorResult& aRv); + + static LogModule* GetClipboardLog(); + + // Check if the Clipboard.readText API should be enabled for this context. + // This API is only enabled for Extension and System contexts, as there is no + // way to request the required permission for web content. If the clipboard + // API testing pref is enabled, ReadText is enabled for web content for + // testing purposes. + static bool ReadTextEnabled(JSContext* aCx, JSObject* aGlobal); + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + private: + enum class ReadRequestType { + eRead, + eReadText, + }; + + // Checks if dom.events.testing.asyncClipboard pref is enabled. + // The aforementioned pref allows automated tests to bypass the security + // checks when writing to + // or reading from the clipboard. + static bool IsTestingPrefEnabled(); + + static bool IsTestingPrefEnabledOrHasReadPermission( + nsIPrincipal& aSubjectPrincipal); + + already_AddRefed ReadHelper(nsIPrincipal& aSubjectPrincipal, + ReadRequestType aType, ErrorResult& aRv); + + ~Clipboard(); + + void RequestRead(Promise* aPromise, ReadRequestType aType, + nsPIDOMWindowInner* aOwner, nsIPrincipal& aPrincipal); +}; + +} // namespace mozilla::dom +#endif // mozilla_dom_Clipboard_h_ diff --git a/dom/events/ClipboardEvent.cpp b/dom/events/ClipboardEvent.cpp new file mode 100644 index 0000000000..e678f7c9fd --- /dev/null +++ b/dom/events/ClipboardEvent.cpp @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ClipboardEvent.h" +#include "mozilla/ContentEvents.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/DataTransfer.h" +#include "nsIClipboard.h" + +namespace mozilla::dom { + +ClipboardEvent::ClipboardEvent(EventTarget* aOwner, nsPresContext* aPresContext, + InternalClipboardEvent* aEvent) + : Event(aOwner, aPresContext, + aEvent ? aEvent : new InternalClipboardEvent(false, eVoidEvent)) { + if (aEvent) { + mEventIsInternal = false; + } else { + mEventIsInternal = true; + } +} + +void ClipboardEvent::InitClipboardEvent(const nsAString& aType, bool aCanBubble, + bool aCancelable, + DataTransfer* aClipboardData) { + NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched); + + Event::InitEvent(aType, aCanBubble, aCancelable); + mEvent->AsClipboardEvent()->mClipboardData = aClipboardData; +} + +already_AddRefed ClipboardEvent::Constructor( + const GlobalObject& aGlobal, const nsAString& aType, + const ClipboardEventInit& aParam, ErrorResult& aRv) { + nsCOMPtr t = do_QueryInterface(aGlobal.GetAsSupports()); + RefPtr e = new ClipboardEvent(t, nullptr, nullptr); + bool trusted = e->Init(t); + + RefPtr clipboardData; + if (e->mEventIsInternal) { + InternalClipboardEvent* event = e->mEvent->AsClipboardEvent(); + if (event) { + // Always create a clipboardData for the copy event. If this is changed to + // support other types of events, make sure that read/write privileges are + // checked properly within DataTransfer. + clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1); + clipboardData->SetData(aParam.mDataType, aParam.mData, + *aGlobal.GetSubjectPrincipal(), aRv); + NS_ENSURE_TRUE(!aRv.Failed(), nullptr); + } + } + + e->InitClipboardEvent(aType, aParam.mBubbles, aParam.mCancelable, + clipboardData); + e->SetTrusted(trusted); + e->SetComposed(aParam.mComposed); + return e.forget(); +} + +DataTransfer* ClipboardEvent::GetClipboardData() { + InternalClipboardEvent* event = mEvent->AsClipboardEvent(); + + if (!event->mClipboardData) { + if (mEventIsInternal) { + event->mClipboardData = + new DataTransfer(ToSupports(this), eCopy, false, -1); + } else { + event->mClipboardData = new DataTransfer( + ToSupports(this), event->mMessage, event->mMessage == ePaste, + nsIClipboard::kGlobalClipboard); + } + } + + return event->mClipboardData; +} + +} // namespace mozilla::dom + +using namespace mozilla; +using namespace mozilla::dom; + +already_AddRefed NS_NewDOMClipboardEvent( + EventTarget* aOwner, nsPresContext* aPresContext, + InternalClipboardEvent* aEvent) { + RefPtr it = new ClipboardEvent(aOwner, aPresContext, aEvent); + return it.forget(); +} diff --git a/dom/events/ClipboardEvent.h b/dom/events/ClipboardEvent.h new file mode 100644 index 0000000000..08d96b3772 --- /dev/null +++ b/dom/events/ClipboardEvent.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ClipboardEvent_h_ +#define mozilla_dom_ClipboardEvent_h_ + +#include "mozilla/EventForwards.h" +#include "mozilla/dom/ClipboardEventBinding.h" +#include "mozilla/dom/Event.h" + +namespace mozilla::dom { +class DataTransfer; + +class ClipboardEvent : public Event { + public: + ClipboardEvent(EventTarget* aOwner, nsPresContext* aPresContext, + InternalClipboardEvent* aEvent); + + NS_INLINE_DECL_REFCOUNTING_INHERITED(ClipboardEvent, Event) + + virtual JSObject* WrapObjectInternal( + JSContext* aCx, JS::Handle aGivenProto) override { + return ClipboardEvent_Binding::Wrap(aCx, this, aGivenProto); + } + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, const nsAString& aType, + const ClipboardEventInit& aParam, ErrorResult& aRv); + + DataTransfer* GetClipboardData(); + + void InitClipboardEvent(const nsAString& aType, bool aCanBubble, + bool aCancelable, DataTransfer* aClipboardData); + + protected: + ~ClipboardEvent() = default; +}; + +} // namespace mozilla::dom + +already_AddRefed NS_NewDOMClipboardEvent( + mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, + mozilla::InternalClipboardEvent* aEvent); + +#endif // mozilla_dom_ClipboardEvent_h_ diff --git a/dom/events/ClipboardItem.cpp b/dom/events/ClipboardItem.cpp new file mode 100644 index 0000000000..76196be3b6 --- /dev/null +++ b/dom/events/ClipboardItem.cpp @@ -0,0 +1,333 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ClipboardItem.h" + +#include "mozilla/dom/Promise.h" +#include "mozilla/dom/Record.h" +#include "nsComponentManagerUtils.h" +#include "nsIClipboard.h" +#include "nsIInputStream.h" +#include "nsISupportsPrimitives.h" +#include "nsNetUtil.h" +#include "nsServiceManagerUtils.h" + +namespace mozilla::dom { + +NS_IMPL_CYCLE_COLLECTION(ClipboardItem::ItemEntry, mGlobal, mData, + mPendingGetTypeRequests) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ClipboardItem::ItemEntry) + NS_INTERFACE_MAP_ENTRY(nsIAsyncClipboardRequestCallback) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, PromiseNativeHandler) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(ClipboardItem::ItemEntry) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ClipboardItem::ItemEntry) + +void ClipboardItem::ItemEntry::ResolvedCallback(JSContext* aCx, + JS::Handle aValue, + ErrorResult& aRv) { + MOZ_ASSERT(!mTransferable); + mIsLoadingData = false; + OwningStringOrBlob clipboardData; + if (!clipboardData.Init(aCx, aValue)) { + JS_ClearPendingException(aCx); + RejectPendingPromises(NS_ERROR_DOM_DATA_ERR); + return; + } + + MaybeResolvePendingPromises(std::move(clipboardData)); +} + +void ClipboardItem::ItemEntry::RejectedCallback(JSContext* aCx, + JS::Handle aValue, + ErrorResult& aRv) { + MOZ_ASSERT(!mTransferable); + mIsLoadingData = false; + RejectPendingPromises(NS_ERROR_DOM_DATA_ERR); +} + +RefPtr +ClipboardItem::ItemEntry::GetData() { + // Data is still being loaded, either from the system clipboard or the data + // promise provided to the ClipboardItem constructor. + if (mIsLoadingData) { + MOZ_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + MOZ_ASSERT(mLoadResult.isNothing(), "Should have no load result"); + + MozPromiseHolder holder; + RefPtr promise = holder.Ensure(__func__); + mPendingGetDataRequests.AppendElement(std::move(holder)); + return promise.forget(); + } + + if (NS_FAILED(mLoadResult.value())) { + MOZ_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + // We are not able to load data, so reject the promise directly. + return GetDataPromise::CreateAndReject(mLoadResult.value(), __func__); + } + + MOZ_ASSERT(mData.IsString() || mData.IsBlob(), "Data should be initialized"); + OwningStringOrBlob data(mData); + return GetDataPromise::CreateAndResolve(std::move(data), __func__); +} + +NS_IMETHODIMP ClipboardItem::ItemEntry::OnComplete(nsresult aResult) { + MOZ_ASSERT(mIsLoadingData); + + mIsLoadingData = false; + nsCOMPtr trans = std::move(mTransferable); + + if (NS_FAILED(aResult)) { + RejectPendingPromises(aResult); + return NS_OK; + } + + MOZ_ASSERT(trans); + nsCOMPtr data; + nsresult rv = trans->GetTransferData(NS_ConvertUTF16toUTF8(mType).get(), + getter_AddRefs(data)); + if (NS_WARN_IF(NS_FAILED(rv))) { + RejectPendingPromises(rv); + return NS_OK; + } + + RefPtr blob; + if (nsCOMPtr supportsstr = do_QueryInterface(data)) { + nsAutoString str; + supportsstr->GetData(str); + + blob = Blob::CreateStringBlob(mGlobal, NS_ConvertUTF16toUTF8(str), mType); + } else if (nsCOMPtr istream = do_QueryInterface(data)) { + uint64_t available; + void* data = nullptr; + rv = NS_ReadInputStreamToBuffer(istream, &data, -1, &available); + if (NS_WARN_IF(NS_FAILED(rv))) { + RejectPendingPromises(rv); + return NS_OK; + } + + blob = Blob::CreateMemoryBlob(mGlobal, data, available, mType); + } else if (nsCOMPtr supportscstr = + do_QueryInterface(data)) { + nsAutoCString str; + supportscstr->GetData(str); + + blob = Blob::CreateStringBlob(mGlobal, str, mType); + } + + if (!blob) { + RejectPendingPromises(NS_ERROR_DOM_DATA_ERR); + return NS_OK; + } + + OwningStringOrBlob clipboardData; + clipboardData.SetAsBlob() = std::move(blob); + MaybeResolvePendingPromises(std::move(clipboardData)); + return NS_OK; +} + +void ClipboardItem::ItemEntry::LoadDataFromSystemClipboard( + nsIAsyncGetClipboardData* aDataGetter) { + MOZ_ASSERT(aDataGetter); + // XXX maybe we could consider adding a method to check whether the union + // object is uninitialized or initialized. + MOZ_DIAGNOSTIC_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized."); + MOZ_DIAGNOSTIC_ASSERT(mLoadResult.isNothing(), "Should have no load result"); + MOZ_DIAGNOSTIC_ASSERT(!mIsLoadingData && !mTransferable, + "Should not be in the process of loading data"); + + mIsLoadingData = true; + + mTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); + if (NS_WARN_IF(!mTransferable)) { + OnComplete(NS_ERROR_FAILURE); + return; + } + + mTransferable->Init(nullptr); + mTransferable->AddDataFlavor(NS_ConvertUTF16toUTF8(mType).get()); + + nsresult rv = aDataGetter->GetData(mTransferable, this); + if (NS_FAILED(rv)) { + OnComplete(rv); + return; + } +} + +void ClipboardItem::ItemEntry::LoadDataFromDataPromise(Promise& aDataPromise) { + MOZ_DIAGNOSTIC_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + MOZ_DIAGNOSTIC_ASSERT(mLoadResult.isNothing(), "Should have no load result"); + MOZ_DIAGNOSTIC_ASSERT(!mIsLoadingData && !mTransferable, + "Should not be in the process of loading data"); + + mIsLoadingData = true; + aDataPromise.AppendNativeHandler(this); +} + +void ClipboardItem::ItemEntry::ReactGetTypePromise(Promise& aPromise) { + // Data is still being loaded, either from the system clipboard or the data + // promise provided to the ClipboardItem constructor. + if (mIsLoadingData) { + MOZ_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + MOZ_ASSERT(mLoadResult.isNothing(), "Should have no load result."); + mPendingGetTypeRequests.AppendElement(&aPromise); + return; + } + + if (NS_FAILED(mLoadResult.value())) { + MOZ_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + aPromise.MaybeRejectWithDataError("The data for type '"_ns + + NS_ConvertUTF16toUTF8(mType) + + "' was not found"_ns); + return; + } + + MaybeResolveGetTypePromise(mData, aPromise); +} + +void ClipboardItem::ItemEntry::MaybeResolveGetTypePromise( + const OwningStringOrBlob& aData, Promise& aPromise) { + if (aData.IsBlob()) { + aPromise.MaybeResolve(aData); + return; + } + + // XXX This is for the case that data is from ClipboardItem constructor, + // maybe we should also load that into a Blob earlier. But Safari returns + // different `Blob` instances for each `getTypes` call if the string is from + // ClipboardItem constructor, which is more like our current setup. + if (RefPtr blob = Blob::CreateStringBlob( + mGlobal, NS_ConvertUTF16toUTF8(aData.GetAsString()), mType)) { + aPromise.MaybeResolve(blob); + return; + } + + aPromise.MaybeRejectWithDataError("The data for type '"_ns + + NS_ConvertUTF16toUTF8(mType) + + "' was not found"_ns); +} + +void ClipboardItem::ItemEntry::RejectPendingPromises(nsresult aRv) { + MOZ_ASSERT(NS_FAILED(aRv), "Should have a failure code here"); + MOZ_DIAGNOSTIC_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + MOZ_DIAGNOSTIC_ASSERT(mLoadResult.isNothing(), "Should not have load result"); + MOZ_DIAGNOSTIC_ASSERT(!mIsLoadingData && !mTransferable, + "Should not be in the process of loading data"); + mLoadResult.emplace(aRv); + auto promiseHolders = std::move(mPendingGetDataRequests); + for (auto& promiseHolder : promiseHolders) { + promiseHolder.Reject(aRv, __func__); + } + auto getTypePromises = std::move(mPendingGetTypeRequests); + for (auto& promise : getTypePromises) { + promise->MaybeReject(aRv); + } +} + +void ClipboardItem::ItemEntry::MaybeResolvePendingPromises( + OwningStringOrBlob&& aData) { + MOZ_DIAGNOSTIC_ASSERT(!mData.IsString() && !mData.IsBlob(), + "Data should be uninitialized"); + MOZ_DIAGNOSTIC_ASSERT(mLoadResult.isNothing(), "Should not have load result"); + MOZ_DIAGNOSTIC_ASSERT(!mIsLoadingData && !mTransferable, + "Should not be in the process of loading data"); + mLoadResult.emplace(NS_OK); + mData = std::move(aData); + auto getDataPromiseHolders = std::move(mPendingGetDataRequests); + for (auto& promiseHolder : getDataPromiseHolders) { + OwningStringOrBlob data(mData); + promiseHolder.Resolve(std::move(data), __func__); + } + auto promises = std::move(mPendingGetTypeRequests); + for (auto& promise : promises) { + MaybeResolveGetTypePromise(mData, *promise); + } +} + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ClipboardItem, mOwner, mItems) + +ClipboardItem::ClipboardItem(nsISupports* aOwner, + const dom::PresentationStyle aPresentationStyle, + nsTArray>&& aItems) + : mOwner(aOwner), + mPresentationStyle(aPresentationStyle), + mItems(std::move(aItems)) {} + +// static +already_AddRefed ClipboardItem::Constructor( + const GlobalObject& aGlobal, + const Record>& aItems, + const ClipboardItemOptions& aOptions, ErrorResult& aRv) { + if (aItems.Entries().IsEmpty()) { + aRv.ThrowTypeError("At least one entry required"); + return nullptr; + } + + nsCOMPtr global = do_QueryInterface(aGlobal.GetAsSupports()); + MOZ_ASSERT(global); + + nsTArray> items; + for (const auto& entry : aItems.Entries()) { + RefPtr item = MakeRefPtr(global, entry.mKey); + item->LoadDataFromDataPromise(*entry.mValue); + items.AppendElement(std::move(item)); + } + + RefPtr item = MakeRefPtr( + global, aOptions.mPresentationStyle, std::move(items)); + return item.forget(); +} + +void ClipboardItem::GetTypes(nsTArray& aTypes) const { + for (const auto& item : mItems) { + aTypes.AppendElement(item->Type()); + } +} + +already_AddRefed ClipboardItem::GetType(const nsAString& aType, + ErrorResult& aRv) { + nsCOMPtr global = do_QueryInterface(GetParentObject()); + RefPtr p = Promise::Create(global, aRv); + if (aRv.Failed()) { + return nullptr; + } + + for (auto& item : mItems) { + MOZ_ASSERT(item); + + const nsAString& type = item->Type(); + if (type == aType) { + nsCOMPtr global = do_QueryInterface(GetParentObject()); + if (NS_WARN_IF(!global)) { + p->MaybeReject(NS_ERROR_UNEXPECTED); + return p.forget(); + } + + item->ReactGetTypePromise(*p); + return p.forget(); + } + } + + p->MaybeRejectWithNotFoundError( + "The type '"_ns + NS_ConvertUTF16toUTF8(aType) + "' was not found"_ns); + return p.forget(); +} + +JSObject* ClipboardItem::WrapObject(JSContext* aCx, + JS::Handle aGivenProto) { + return mozilla::dom::ClipboardItem_Binding::Wrap(aCx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/dom/events/ClipboardItem.h b/dom/events/ClipboardItem.h new file mode 100644 index 0000000000..9fe45bf936 --- /dev/null +++ b/dom/events/ClipboardItem.h @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ClipboardItem_h_ +#define mozilla_dom_ClipboardItem_h_ + +#include "mozilla/dom/Blob.h" +#include "mozilla/dom/ClipboardBinding.h" +#include "mozilla/dom/PromiseNativeHandler.h" +#include "mozilla/MozPromise.h" + +#include "nsIClipboard.h" +#include "nsWrapperCache.h" + +class nsITransferable; + +namespace mozilla::dom { + +struct ClipboardItemOptions; +template +class Record; +class Promise; + +class ClipboardItem final : public nsWrapperCache { + public: + class ItemEntry final : public PromiseNativeHandler, + public nsIAsyncClipboardRequestCallback { + public: + using GetDataPromise = + MozPromise; + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_NSIASYNCCLIPBOARDREQUESTCALLBACK + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ItemEntry, PromiseNativeHandler) + + explicit ItemEntry(nsIGlobalObject* aGlobal, const nsAString& aType) + : mGlobal(aGlobal), mType(aType) { + MOZ_ASSERT(mGlobal); + } + ItemEntry(nsIGlobalObject* aGlobal, const nsAString& aType, + const nsAString& aData) + : ItemEntry(aGlobal, aType) { + mLoadResult.emplace(NS_OK); + mData.SetAsString() = aData; + } + + // PromiseNativeHandler + void ResolvedCallback(JSContext* aCx, JS::Handle aValue, + ErrorResult& aRv) override; + void RejectedCallback(JSContext* aCx, JS::Handle aValue, + ErrorResult& aRv) override; + + const nsString& Type() const { return mType; } + RefPtr GetData(); + + // Load data from system clipboard. + void LoadDataFromSystemClipboard(nsIAsyncGetClipboardData* aDataGetter); + void LoadDataFromDataPromise(Promise& aDataPromise); + + // If clipboard data is in the process of loading from either system + // clipboard or data promise, add `aPromise` to the pending list which will + // be resolved/rejected later when process is finished. Otherwise, + // resolve/reject `aPromise` based on cached result and data. + void ReactGetTypePromise(Promise& aPromise); + + private: + ~ItemEntry() { + if (!mPendingGetDataRequests.IsEmpty()) { + RejectPendingPromises(NS_ERROR_FAILURE); + } + }; + + void MaybeResolveGetTypePromise(const OwningStringOrBlob& aData, + Promise& aPromise); + void MaybeResolvePendingPromises(OwningStringOrBlob&& aData); + void RejectPendingPromises(nsresult rv); + + nsCOMPtr mGlobal; + + // MIME type of this entry. + nsString mType; + + // Cache the loading result. + OwningStringOrBlob mData; + Maybe mLoadResult; + + // Indicates if the data is still being loaded. + bool mIsLoadingData = false; + nsCOMPtr mTransferable; + + // Pending promises for data retrieval requests. + nsTArray> mPendingGetDataRequests; + nsTArray> mPendingGetTypeRequests; + }; + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(ClipboardItem) + NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(ClipboardItem) + + ClipboardItem(nsISupports* aOwner, dom::PresentationStyle aPresentationStyle, + nsTArray>&& aItems); + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, + const Record>& aItems, + const ClipboardItemOptions& aOptions, ErrorResult& aRv); + + dom::PresentationStyle PresentationStyle() const { + return mPresentationStyle; + }; + void GetTypes(nsTArray& aTypes) const; + + already_AddRefed GetType(const nsAString& aType, ErrorResult& aRv); + + nsISupports* GetParentObject() const { return mOwner; } + + JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + const nsTArray>& Entries() const { return mItems; } + + private: + ~ClipboardItem() = default; + + nsCOMPtr mOwner; + dom::PresentationStyle mPresentationStyle; + nsTArray> mItems; +}; + +} // namespace mozilla::dom + +#endif // mozilla_dom_ClipboardItem_h_ diff --git a/dom/events/CommandEvent.cpp b/dom/events/CommandEvent.cpp new file mode 100644 index 0000000000..b048a959f8 --- /dev/null +++ b/dom/events/CommandEvent.cpp @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/CommandEvent.h" +#include "mozilla/MiscEvents.h" +#include "prtime.h" + +namespace mozilla::dom { + +CommandEvent::CommandEvent(EventTarget* aOwner, nsPresContext* aPresContext, + WidgetCommandEvent* aEvent) + : Event(aOwner, aPresContext, aEvent ? aEvent : new WidgetCommandEvent()) { + if (aEvent) { + mEventIsInternal = false; + } else { + mEventIsInternal = true; + } +} + +void CommandEvent::GetCommand(nsAString& aCommand) { + nsAtom* command = mEvent->AsCommandEvent()->mCommand; + if (command) { + command->ToString(aCommand); + } else { + aCommand.Truncate(); + } +} + +} // namespace mozilla::dom + +using namespace mozilla; +using namespace mozilla::dom; + +already_AddRefed NS_NewDOMCommandEvent( + EventTarget* aOwner, nsPresContext* aPresContext, + WidgetCommandEvent* aEvent) { + RefPtr it = new CommandEvent(aOwner, aPresContext, aEvent); + return it.forget(); +} diff --git a/dom/events/CommandEvent.h b/dom/events/CommandEvent.h new file mode 100644 index 0000000000..944b708c3a --- /dev/null +++ b/dom/events/CommandEvent.h @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_CommandEvent_h_ +#define mozilla_dom_CommandEvent_h_ + +#include "mozilla/EventForwards.h" +#include "mozilla/dom/CommandEventBinding.h" +#include "mozilla/dom/Event.h" + +namespace mozilla::dom { + +class CommandEvent : public Event { + public: + CommandEvent(EventTarget* aOwner, nsPresContext* aPresContext, + WidgetCommandEvent* aEvent); + + NS_INLINE_DECL_REFCOUNTING_INHERITED(CommandEvent, Event) + + virtual JSObject* WrapObjectInternal( + JSContext* aCx, JS::Handle aGivenProto) override { + return CommandEvent_Binding::Wrap(aCx, this, aGivenProto); + } + + void GetCommand(nsAString& aCommand); + + protected: + ~CommandEvent() = default; +}; + +} // namespace mozilla::dom + +already_AddRefed NS_NewDOMCommandEvent( + mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, + mozilla::WidgetCommandEvent* aEvent); + +#endif // mozilla_dom_CommandEvent_h_ diff --git a/dom/events/CompositionEvent.cpp b/dom/events/CompositionEvent.cpp new file mode 100644 index 0000000000..7e52b9e161 --- /dev/null +++ b/dom/events/CompositionEvent.cpp @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/CompositionEvent.h" +#include "mozilla/TextEvents.h" +#include "prtime.h" + +namespace mozilla::dom { + +CompositionEvent::CompositionEvent(EventTarget* aOwner, + nsPresContext* aPresContext, + WidgetCompositionEvent* aEvent) + : UIEvent(aOwner, aPresContext, + aEvent ? aEvent + : new WidgetCompositionEvent(false, eVoidEvent, nullptr)) { + NS_ASSERTION(mEvent->mClass == eCompositionEventClass, "event type mismatch"); + + if (aEvent) { + mEventIsInternal = false; + } else { + mEventIsInternal = true; + + // XXX compositionstart is cancelable in draft of DOM3 Events. + // However, it doesn't make sence for us, we cannot cancel composition + // when we sends compositionstart event. + mEvent->mFlags.mCancelable = false; + } + + // XXX Do we really need to duplicate the data value? + mData = mEvent->AsCompositionEvent()->mData; + // TODO: Native event should have locale information. +} + +// static +already_AddRefed CompositionEvent::Constructor( + const GlobalObject& aGlobal, const nsAString& aType, + const CompositionEventInit& aParam) { + nsCOMPtr t = do_QueryInterface(aGlobal.GetAsSupports()); + RefPtr e = new CompositionEvent(t, nullptr, nullptr); + bool trusted = e->Init(t); + e->InitCompositionEvent(aType, aParam.mBubbles, aParam.mCancelable, + aParam.mView, aParam.mData, u""_ns); + e->mDetail = aParam.mDetail; + e->SetTrusted(trusted); + e->SetComposed(aParam.mComposed); + return e.forget(); +} + +NS_IMPL_CYCLE_COLLECTION_INHERITED(CompositionEvent, UIEvent, mRanges) + +NS_IMPL_ADDREF_INHERITED(CompositionEvent, UIEvent) +NS_IMPL_RELEASE_INHERITED(CompositionEvent, UIEvent) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompositionEvent) +NS_INTERFACE_MAP_END_INHERITING(UIEvent) + +void CompositionEvent::GetData(nsAString& aData) const { aData = mData; } + +void CompositionEvent::GetLocale(nsAString& aLocale) const { + aLocale = mLocale; +} + +void CompositionEvent::InitCompositionEvent(const nsAString& aType, + bool aCanBubble, bool aCancelable, + nsGlobalWindowInner* aView, + const nsAString& aData, + const nsAString& aLocale) { + NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched); + + UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, 0); + mData = aData; + mLocale = aLocale; +} + +void CompositionEvent::GetRanges(TextClauseArray& aRanges) { + // If the mRanges is not empty, we return the cached value. + if (!mRanges.IsEmpty()) { + aRanges = mRanges.Clone(); + return; + } + RefPtr textRangeArray = mEvent->AsCompositionEvent()->mRanges; + if (!textRangeArray) { + return; + } + nsCOMPtr window = do_QueryInterface(mOwner); + const TextRange* targetRange = textRangeArray->GetTargetClause(); + for (size_t i = 0; i < textRangeArray->Length(); i++) { + const TextRange& range = textRangeArray->ElementAt(i); + mRanges.AppendElement(new TextClause(window, range, targetRange)); + } + aRanges = mRanges.Clone(); +} + +} // namespace mozilla::dom + +using namespace mozilla; +using namespace mozilla::dom; + +already_AddRefed NS_NewDOMCompositionEvent( + EventTarget* aOwner, nsPresContext* aPresContext, + WidgetCompositionEvent* aEvent) { + RefPtr event = + new CompositionEvent(aOwner, aPresContext, aEvent); + return event.forget(); +} diff --git a/dom/events/CompositionEvent.h b/dom/events/CompositionEvent.h new file mode 100644 index 0000000000..400829104a --- /dev/null +++ b/dom/events/CompositionEvent.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_CompositionEvent_h_ +#define mozilla_dom_CompositionEvent_h_ + +#include "mozilla/dom/CompositionEventBinding.h" +#include "mozilla/dom/TextClause.h" +#include "mozilla/dom/TypedArray.h" +#include "mozilla/dom/UIEvent.h" +#include "mozilla/EventForwards.h" + +namespace mozilla::dom { + +using TextClauseArray = nsTArray>; + +class CompositionEvent : public UIEvent { + public: + CompositionEvent(EventTarget* aOwner, nsPresContext* aPresContext, + WidgetCompositionEvent* aEvent); + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CompositionEvent, UIEvent) + + static already_AddRefed Constructor( + const GlobalObject& aGlobal, const nsAString& aType, + const CompositionEventInit& aParam); + + virtual JSObject* WrapObjectInternal( + JSContext* aCx, JS::Handle aGivenProto) override { + return CompositionEvent_Binding::Wrap(aCx, this, aGivenProto); + } + + void InitCompositionEvent(const nsAString& aType, bool aCanBubble, + bool aCancelable, nsGlobalWindowInner* aView, + const nsAString& aData, const nsAString& aLocale); + void GetData(nsAString&) const; + void GetLocale(nsAString&) const; + void GetRanges(TextClauseArray& aRanges); + + protected: + ~CompositionEvent() = default; + + nsString mData; + nsString mLocale; + TextClauseArray mRanges; +}; + +} // namespace mozilla::dom + +already_AddRefed NS_NewDOMCompositionEvent( + mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, + mozilla::WidgetCompositionEvent* aEvent); + +#endif // mozilla_dom_CompositionEvent_h_ diff --git a/dom/events/ConstructibleEventTarget.cpp b/dom/events/ConstructibleEventTarget.cpp new file mode 100644 index 0000000000..827b3faaa8 --- /dev/null +++ b/dom/events/ConstructibleEventTarget.cpp @@ -0,0 +1,17 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/ConstructibleEventTarget.h" +#include "mozilla/dom/EventTargetBinding.h" + +namespace mozilla::dom { + +JSObject* ConstructibleEventTarget::WrapObject( + JSContext* cx, JS::Handle aGivenProto) { + return EventTarget_Binding::Wrap(cx, this, aGivenProto); +} + +} // namespace mozilla::dom diff --git a/dom/events/ConstructibleEventTarget.h b/dom/events/ConstructibleEventTarget.h new file mode 100644 index 0000000000..fbaafac821 --- /dev/null +++ b/dom/events/ConstructibleEventTarget.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ConstructibleEventTarget_h_ +#define mozilla_dom_ConstructibleEventTarget_h_ + +#include "mozilla/DOMEventTargetHelper.h" +#include "js/RootingAPI.h" + +namespace mozilla::dom { + +class ConstructibleEventTarget : public DOMEventTargetHelper { + public: + // Not worrying about isupports and cycle collection here. This does mean + // ConstructibleEventTarget will show up in CC and refcount logs as a + // DOMEventTargetHelper, but that's probably OK. + + explicit ConstructibleEventTarget(nsIGlobalObject* aGlobalObject) + : DOMEventTargetHelper(aGlobalObject) {} + + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle aGivenProto) override; +}; + +} // namespace mozilla::dom + +#endif // mozilla_dom_ConstructibleEventTarget_h_ diff --git a/dom/events/ContentEventHandler.cpp b/dom/events/ContentEventHandler.cpp new file mode 100644 index 0000000000..78371b13e8 --- /dev/null +++ b/dom/events/ContentEventHandler.cpp @@ -0,0 +1,3482 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ContentEventHandler.h" + +#include "mozilla/Assertions.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/ContentIterator.h" +#include "mozilla/IMEStateManager.h" +#include "mozilla/IntegerRange.h" +#include "mozilla/Maybe.h" +#include "mozilla/PresShell.h" +#include "mozilla/RangeBoundary.h" +#include "mozilla/RangeUtils.h" +#include "mozilla/SelectionMovementUtils.h" +#include "mozilla/TextComposition.h" +#include "mozilla/TextEditor.h" +#include "mozilla/TextEvents.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/HTMLBRElement.h" +#include "mozilla/dom/HTMLUnknownElement.h" +#include "mozilla/dom/Selection.h" +#include "mozilla/dom/Text.h" +#include "nsCaret.h" +#include "nsCOMPtr.h" +#include "nsContentUtils.h" +#include "nsCopySupport.h" +#include "nsElementTable.h" +#include "nsFocusManager.h" +#include "nsFontMetrics.h" +#include "nsFrameSelection.h" +#include "nsHTMLTags.h" +#include "nsIFrame.h" +#include "nsLayoutUtils.h" +#include "nsPresContext.h" +#include "nsQueryObject.h" +#include "nsRange.h" +#include "nsTextFragment.h" +#include "nsTextFrame.h" +#include "nsView.h" +#include "mozilla/ViewportUtils.h" + +#include + +// Work around conflicting define in rpcndr.h +#if defined(small) +# undef small +#endif // defined(small) + +#if defined(XP_WIN) && 0 +# define TRANSLATE_NEW_LINES +#endif + +namespace mozilla { + +using namespace dom; +using namespace widget; + +/******************************************************************/ +/* ContentEventHandler::SimpleRangeBase */ +/******************************************************************/ +template <> +ContentEventHandler::SimpleRangeBase< + RefPtr, RangeBoundary>::SimpleRangeBase() = default; + +template <> +ContentEventHandler::SimpleRangeBase::SimpleRangeBase() + : mRoot(nullptr) { +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + mAssertNoGC.emplace(); +#endif // #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED +} + +template <> +template +ContentEventHandler::SimpleRangeBase, RangeBoundary>:: + SimpleRangeBase( + const SimpleRangeBase& aOther) + : mRoot(aOther.GetRoot()), + mStart{aOther.Start().AsRaw()}, + mEnd{aOther.End().AsRaw()} +// Don't use the copy constructor of mAssertNoGC +{} + +template <> +template +ContentEventHandler::SimpleRangeBase:: + SimpleRangeBase( + const SimpleRangeBase& aOther) + : mRoot(aOther.GetRoot()), + mStart{aOther.Start().AsRaw()}, + mEnd{aOther.End().AsRaw()} { +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + mAssertNoGC.emplace(); +#endif // #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED +} + +template <> +ContentEventHandler::SimpleRangeBase, RangeBoundary>:: + SimpleRangeBase( + SimpleRangeBase, RangeBoundary>&& aOther) noexcept + : mRoot(std::move(aOther.GetRoot())), + mStart(std::move(aOther.mStart)), + mEnd(std::move(aOther.mEnd)) {} + +template <> +ContentEventHandler::SimpleRangeBase:: + SimpleRangeBase( + SimpleRangeBase&& aOther) noexcept + : mRoot(std::move(aOther.GetRoot())), + mStart(std::move(aOther.mStart)), + mEnd(std::move(aOther.mEnd)) { +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + mAssertNoGC.emplace(); +#endif // #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED +} + +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED +template <> +ContentEventHandler::SimpleRangeBase< + RefPtr, RangeBoundary>::~SimpleRangeBase() = default; + +template <> +ContentEventHandler::SimpleRangeBase::~SimpleRangeBase() { + MOZ_DIAGNOSTIC_ASSERT(!mMutationGuard.Mutated(0)); +} +#endif // #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + +template +void ContentEventHandler::SimpleRangeBase< + NodeType, RangeBoundaryType>::AssertStartIsBeforeOrEqualToEnd() { + MOZ_ASSERT( + *nsContentUtils::ComparePoints( + mStart.Container(), + *mStart.Offset( + RangeBoundaryType::OffsetFilter::kValidOrInvalidOffsets), + mEnd.Container(), + *mEnd.Offset( + RangeBoundaryType::OffsetFilter::kValidOrInvalidOffsets)) <= 0); +} + +template +nsresult +ContentEventHandler::SimpleRangeBase::SetStart( + const RawRangeBoundary& aStart) { + nsINode* newRoot = RangeUtils::ComputeRootNode(aStart.Container()); + if (!newRoot) { + return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR; + } + + if (!aStart.IsSetAndValid()) { + return NS_ERROR_DOM_INDEX_SIZE_ERR; + } + + // Collapse if not positioned yet, or if positioned in another document. + if (!IsPositioned() || newRoot != mRoot) { + mRoot = newRoot; + mStart.CopyFrom(aStart, RangeBoundaryIsMutationObserved::Yes); + mEnd.CopyFrom(aStart, RangeBoundaryIsMutationObserved::Yes); + return NS_OK; + } + + mStart.CopyFrom(aStart, RangeBoundaryIsMutationObserved::Yes); + AssertStartIsBeforeOrEqualToEnd(); + return NS_OK; +} + +template +nsresult +ContentEventHandler::SimpleRangeBase::SetEnd( + const RawRangeBoundary& aEnd) { + nsINode* newRoot = RangeUtils::ComputeRootNode(aEnd.Container()); + if (!newRoot) { + return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR; + } + + if (!aEnd.IsSetAndValid()) { + return NS_ERROR_DOM_INDEX_SIZE_ERR; + } + + // Collapse if not positioned yet, or if positioned in another document. + if (!IsPositioned() || newRoot != mRoot) { + mRoot = newRoot; + mStart.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + mEnd.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + return NS_OK; + } + + mEnd.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + AssertStartIsBeforeOrEqualToEnd(); + return NS_OK; +} + +template +nsresult +ContentEventHandler::SimpleRangeBase::SetEndAfter( + nsINode* aEndContainer) { + return SetEnd(RangeUtils::GetRawRangeBoundaryAfter(aEndContainer)); +} + +template +void ContentEventHandler::SimpleRangeBase< + NodeType, RangeBoundaryType>::SetStartAndEnd(const nsRange* aRange) { + DebugOnly rv = + SetStartAndEnd(aRange->StartRef().AsRaw(), aRange->EndRef().AsRaw()); + MOZ_ASSERT(!aRange->IsPositioned() || NS_SUCCEEDED(rv)); +} + +template +nsresult ContentEventHandler::SimpleRangeBase< + NodeType, RangeBoundaryType>::SetStartAndEnd(const RawRangeBoundary& aStart, + const RawRangeBoundary& aEnd) { + nsINode* newStartRoot = RangeUtils::ComputeRootNode(aStart.Container()); + if (!newStartRoot) { + return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR; + } + if (!aStart.IsSetAndValid()) { + return NS_ERROR_DOM_INDEX_SIZE_ERR; + } + + if (aStart.Container() == aEnd.Container()) { + if (!aEnd.IsSetAndValid()) { + return NS_ERROR_DOM_INDEX_SIZE_ERR; + } + MOZ_ASSERT(*aStart.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets) <= + *aEnd.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets)); + mRoot = newStartRoot; + mStart.CopyFrom(aStart, RangeBoundaryIsMutationObserved::Yes); + mEnd.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + return NS_OK; + } + + nsINode* newEndRoot = RangeUtils::ComputeRootNode(aEnd.Container()); + if (!newEndRoot) { + return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR; + } + if (!aEnd.IsSetAndValid()) { + return NS_ERROR_DOM_INDEX_SIZE_ERR; + } + + // If they have different root, this should be collapsed at the end point. + if (newStartRoot != newEndRoot) { + mRoot = newEndRoot; + mStart.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + mEnd.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + return NS_OK; + } + + // Otherwise, set the range as specified. + mRoot = newStartRoot; + mStart.CopyFrom(aStart, RangeBoundaryIsMutationObserved::Yes); + mEnd.CopyFrom(aEnd, RangeBoundaryIsMutationObserved::Yes); + AssertStartIsBeforeOrEqualToEnd(); + return NS_OK; +} + +template +nsresult ContentEventHandler::SimpleRangeBase:: + SelectNodeContents(const nsINode* aNodeToSelectContents) { + nsINode* const newRoot = + RangeUtils::ComputeRootNode(const_cast(aNodeToSelectContents)); + if (!newRoot) { + return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR; + } + mRoot = newRoot; + mStart = + RangeBoundaryType(const_cast(aNodeToSelectContents), nullptr); + mEnd = RangeBoundaryType(const_cast(aNodeToSelectContents), + aNodeToSelectContents->GetLastChild()); + return NS_OK; +} + +/******************************************************************/ +/* ContentEventHandler */ +/******************************************************************/ + +// NOTE +// +// ContentEventHandler *creates* ranges as following rules: +// 1. Start of range: +// 1.1. Cases: [textNode or text[Node or textNode[ +// When text node is start of a range, start node is the text node and +// start offset is any number between 0 and the length of the text. +// 1.2. Case: [: +// When start of an element node is start of a range, start node is +// parent of the element and start offset is the element's index in the +// parent. +// 1.3. Case: [ +// When after an empty element node is start of a range, start node is +// parent of the element and start offset is the element's index in the +// parent + 1. +// 1.4. Case: [ +// When start of a non-empty element is start of a range, start node is +// the element and start offset is 0. +// 1.5. Case: [ +// When start of a range is 0 and there are no nodes causing text, +// start node is the root node and start offset is 0. +// 1.6. Case: [ +// When start of a range is out of bounds, start node is the root node +// and start offset is number of the children. +// 2. End of range: +// 2.1. Cases: ]textNode or text]Node or textNode] +// When a text node is end of a range, end node is the text node and +// end offset is any number between 0 and the length of the text. +// 2.2. Case: ] +// When before an element node (meaning before the open tag of the +// element) is end of a range, end node is previous node causing text. +// Note that this case shouldn't be handled directly. If rule 2.1 and +// 2.3 are handled correctly, the loop with ContentIterator shouldn't +// reach the element node since the loop should've finished already at +// handling the last node which caused some text. +// 2.3. Case: ] +// When a line break is caused before a non-empty element node and it's +// end of a range, end node is the element and end offset is 0. +// (i.e., including open tag of the element) +// 2.4. Cases: ] +// When after an empty element node is end of a range, end node is +// parent of the element node and end offset is the element's index in +// the parent + 1. (i.e., including close tag of the element or empty +// element) +// 2.5. Case: ] +// When end of a range is out of bounds, end node is the root node and +// end offset is number of the children. +// +// ContentEventHandler *treats* ranges as following additional rules: +// 1. When the start node is an element node which doesn't have children, +// it includes a line break caused before itself (i.e., includes its open +// tag). For example, if start position is {
, 0 }, the line break +// caused by
should be included into the flatten text. +// 2. When the end node is an element node which doesn't have children, +// it includes the end (i.e., includes its close tag except empty element). +// Although, currently, any close tags don't cause line break, this also +// includes its open tag. For example, if end position is {
, 0 }, the +// line break caused by the
should be included into the flatten text. + +ContentEventHandler::ContentEventHandler(nsPresContext* aPresContext) + : mDocument(aPresContext->Document()) {} + +nsresult ContentEventHandler::InitBasic(bool aRequireFlush) { + NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE); + if (aRequireFlush) { + // If text frame which has overflowing selection underline is dirty, + // we need to flush the pending reflow here. + mDocument->FlushPendingNotifications(FlushType::Layout); + } + return NS_OK; +} + +nsresult ContentEventHandler::InitRootContent( + const Selection& aNormalSelection) { + // Root content should be computed with normal selection because normal + // selection is typically has at least one range but the other selections + // not so. If there is a range, computing its root is easy, but if + // there are no ranges, we need to use ancestor limit instead. + MOZ_ASSERT(aNormalSelection.Type() == SelectionType::eNormal); + + if (!aNormalSelection.RangeCount()) { + // If there is no selection range, we should compute the selection root + // from ancestor limiter or root content of the document. + mRootElement = + Element::FromNodeOrNull(aNormalSelection.GetAncestorLimiter()); + if (!mRootElement) { + mRootElement = mDocument->GetRootElement(); + if (NS_WARN_IF(!mRootElement)) { + return NS_ERROR_NOT_AVAILABLE; + } + } + return NS_OK; + } + + RefPtr range(aNormalSelection.GetRangeAt(0)); + if (NS_WARN_IF(!range)) { + return NS_ERROR_UNEXPECTED; + } + + // If there is a selection, we should retrieve the selection root from + // the range since when the window is inactivated, the ancestor limiter + // of selection was cleared by blur event handler of EditorBase but the + // selection range still keeps storing the nodes. If the active element of + // the deactive window is or + + + diff --git a/dom/events/test/dragimage.html b/dom/events/test/dragimage.html new file mode 100644 index 0000000000..059b1de90f --- /dev/null +++ b/dom/events/test/dragimage.html @@ -0,0 +1,10 @@ + + +Drag Image Test + + + +
+ + diff --git a/dom/events/test/empty.js b/dom/events/test/empty.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dom/events/test/error_event_worker.js b/dom/events/test/error_event_worker.js new file mode 100644 index 0000000000..13422c6974 --- /dev/null +++ b/dom/events/test/error_event_worker.js @@ -0,0 +1,19 @@ +addEventListener("error", function (e) { + var obj = {}; + for (var prop of ["message", "filename", "lineno"]) { + obj[prop] = e[prop]; + } + obj.type = "event"; + postMessage(obj); +}); +onerror = function (message, filename, lineno) { + var obj = { + message, + filename, + lineno, + type: "callback", + }; + postMessage(obj); + return false; +}; +throw new Error("workerhello"); diff --git a/dom/events/test/event_leak_utils.js b/dom/events/test/event_leak_utils.js new file mode 100644 index 0000000000..86b26a4136 --- /dev/null +++ b/dom/events/test/event_leak_utils.js @@ -0,0 +1,84 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// This function runs a number of tests where: +// +// 1. An iframe is created +// 2. The target callback is executed with the iframe's contentWindow as +// an argument. +// 3. The iframe is destroyed and GC is forced. +// 4. Verifies that the iframe's contentWindow has been GC'd. +// +// Different ways of destroying the iframe are checked. Simple +// remove(), destruction via bfcache, or replacement by document.open(). +// +// Please pass a target callback that exercises the API under +// test using the given window. The callback should try to leave the +// API active to increase the liklihood of provoking an API. Any activity +// should be canceled by the destruction of the window. +async function checkForEventListenerLeaks(name, target) { + // Test if we leak in the case where we do nothing special to + // the frame before removing it from the DOM. + await _eventListenerLeakStep(target, `${name} default`); + + // Test the case where we navigate the frame before removing it + // from the DOM so that the window using the target API ends up + // in bfcache. + await _eventListenerLeakStep(target, `${name} bfcache`, frame => { + frame.src = "about:blank"; + return new Promise(resolve => (frame.onload = resolve)); + }); + + // Test the case where we document.open() the frame before removing + // it from the DOM so that the window using the target API ends + // up getting replaced. + await _eventListenerLeakStep(target, `${name} document.open()`, frame => { + frame.contentDocument.open(); + frame.contentDocument.close(); + }); +} + +// ---------------- +// Internal helpers +// ---------------- + +// Utility function to create a loaded iframe. +async function _withFrame(doc, url) { + let frame = doc.createElement("iframe"); + frame.src = url; + doc.body.appendChild(frame); + await new Promise(resolve => (frame.onload = resolve)); + return frame; +} + +// This function defines the basic form of the test cases. We create an +// iframe, execute the target callback to manipulate the DOM, remove the frame +// from the DOM, and then check to see if the frame was GC'd. The caller +// may optionally pass in a callback that will be executed with the +// frame as an argument before removing it from the DOM. +async function _eventListenerLeakStep(target, name, extra) { + let frame = await _withFrame(document, "empty.html"); + + await target(frame.contentWindow); + + let weakRef = SpecialPowers.Cu.getWeakReference(frame.contentWindow); + ok(weakRef.get(), `should be able to create a weak reference - ${name}`); + + if (extra) { + await extra(frame); + } + + frame.remove(); + frame = null; + + // Perform many GC's to avoid intermittent delayed collection. + await new Promise(resolve => SpecialPowers.exactGC(resolve)); + await new Promise(resolve => SpecialPowers.exactGC(resolve)); + await new Promise(resolve => SpecialPowers.exactGC(resolve)); + + ok( + !weakRef.get(), + `iframe content window should be garbage collected - ${name}` + ); +} diff --git a/dom/events/test/file_beforeinput_by_execCommand_in_contentscript.html b/dom/events/test/file_beforeinput_by_execCommand_in_contentscript.html new file mode 100644 index 0000000000..7610f201ae --- /dev/null +++ b/dom/events/test/file_beforeinput_by_execCommand_in_contentscript.html @@ -0,0 +1,9 @@ + +
abcdef
+
abcdef
+ diff --git a/dom/events/test/file_bug1446834.html b/dom/events/test/file_bug1446834.html new file mode 100644 index 0000000000..e3832fd2f0 --- /dev/null +++ b/dom/events/test/file_bug1446834.html @@ -0,0 +1,96 @@ + + + + + + + +
+
+
+ foo +
+
light dom
+ + \ No newline at end of file diff --git a/dom/events/test/file_bug1484371.html b/dom/events/test/file_bug1484371.html new file mode 100644 index 0000000000..56c284b733 --- /dev/null +++ b/dom/events/test/file_bug1484371.html @@ -0,0 +1,94 @@ + + + + + + +
light DOM
+
+ + diff --git a/dom/events/test/file_bug1692052.html b/dom/events/test/file_bug1692052.html new file mode 100644 index 0000000000..23b26d95c7 --- /dev/null +++ b/dom/events/test/file_bug1692052.html @@ -0,0 +1,25 @@ + + + + + + diff --git a/dom/events/test/file_bug679494.html b/dom/events/test/file_bug679494.html new file mode 100644 index 0000000000..a2e47916c5 --- /dev/null +++ b/dom/events/test/file_bug679494.html @@ -0,0 +1,8 @@ + + + Test for Bug 679494 + + + There and back again. + + diff --git a/dom/events/test/file_coalesce_touchmove_browserchild.html b/dom/events/test/file_coalesce_touchmove_browserchild.html new file mode 100644 index 0000000000..28a4ae5252 --- /dev/null +++ b/dom/events/test/file_coalesce_touchmove_browserchild.html @@ -0,0 +1,117 @@ + + + + + + touchmove coalescing + + + + + + + diff --git a/dom/events/test/file_coalesce_touchmove_browserchild2.html b/dom/events/test/file_coalesce_touchmove_browserchild2.html new file mode 100644 index 0000000000..b29ae291c2 --- /dev/null +++ b/dom/events/test/file_coalesce_touchmove_browserchild2.html @@ -0,0 +1,193 @@ + + + + + + touchmove coalescing + + + + + + + diff --git a/dom/events/test/file_coalesce_touchmove_ipc.html b/dom/events/test/file_coalesce_touchmove_ipc.html new file mode 100644 index 0000000000..73e5a1157d --- /dev/null +++ b/dom/events/test/file_coalesce_touchmove_ipc.html @@ -0,0 +1,193 @@ + + + + + + touchmove coalescing + + + + + + + diff --git a/dom/events/test/file_empty.html b/dom/events/test/file_empty.html new file mode 100644 index 0000000000..e75bdc942f --- /dev/null +++ b/dom/events/test/file_empty.html @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/dom/events/test/file_event_screenXY.html b/dom/events/test/file_event_screenXY.html new file mode 100644 index 0000000000..d39e28abc2 --- /dev/null +++ b/dom/events/test/file_event_screenXY.html @@ -0,0 +1,23 @@ + + + + +
+ diff --git a/dom/events/test/file_focus_blur_on_click_in_cross_origin_iframe.html b/dom/events/test/file_focus_blur_on_click_in_cross_origin_iframe.html new file mode 100644 index 0000000000..09eab8fc16 --- /dev/null +++ b/dom/events/test/file_focus_blur_on_click_in_cross_origin_iframe.html @@ -0,0 +1,28 @@ + + + + +
+ diff --git a/dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_inner.html b/dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_inner.html new file mode 100644 index 0000000000..e7127e2397 --- /dev/null +++ b/dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_inner.html @@ -0,0 +1,28 @@ + + + + +
+ diff --git a/dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_middle.html b/dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_middle.html new file mode 100644 index 0000000000..bb128422ae --- /dev/null +++ b/dom/events/test/file_focus_blur_on_click_in_deep_cross_origin_iframe_middle.html @@ -0,0 +1,37 @@ + + + + + + +
+ + diff --git a/dom/events/test/file_keyboard_event_init_key_event_enabled_in_contentscript.html b/dom/events/test/file_keyboard_event_init_key_event_enabled_in_contentscript.html new file mode 100644 index 0000000000..98691bfe69 --- /dev/null +++ b/dom/events/test/file_keyboard_event_init_key_event_enabled_in_contentscript.html @@ -0,0 +1,21 @@ + + + + +Storing type of `KeyboardEvent.initKeyEvent` + + + + + diff --git a/dom/events/test/file_mouse_enterleave.html b/dom/events/test/file_mouse_enterleave.html new file mode 100644 index 0000000000..2a5bc743f7 --- /dev/null +++ b/dom/events/test/file_mouse_enterleave.html @@ -0,0 +1,45 @@ + + + +
+
+ + + diff --git a/dom/events/test/green.png b/dom/events/test/green.png new file mode 100644 index 0000000000..7df25f33bd Binary files /dev/null and b/dom/events/test/green.png differ diff --git a/dom/events/test/gtest/TestShortcutKeyDefinitions.cpp b/dom/events/test/gtest/TestShortcutKeyDefinitions.cpp new file mode 100644 index 0000000000..10adbba49f --- /dev/null +++ b/dom/events/test/gtest/TestShortcutKeyDefinitions.cpp @@ -0,0 +1,634 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "KeyEventHandler.h" +#include "ShortcutKeys.h" + +#include "mozilla/RefPtr.h" +#include "mozilla/TextEvents.h" +#include "mozilla/dom/KeyboardEvent.h" + +namespace mozilla { + +/** + * These tests checks whether the key mapping defined by + * `ShortcutKeyDefinitions.cpp` and its including header files. + * Note that these tests do NOT define how shortcut keys mapped. These tests + * exist for checking unexpected change occurs by cleaning up or changing + * the mapping. + */ + +#ifndef MOZ_WIDGET_COCOA +# define MODIFIER_ACCEL MODIFIER_CONTROL +#else +# define MODIFIER_ACCEL MODIFIER_META +#endif + +struct ShortcutKeyMap final { + uint32_t const mKeyCode; + char32_t const mCharCode; + Modifiers const mModifiers; + const char16ptr_t mCommandWin; + const char16ptr_t mCommandMac; + const char16ptr_t mCommandLinux; + const char16ptr_t mCommandAndroid; + const char16ptr_t mCommandEmacs; +}; + +#if defined(XP_WIN) +# define GetCommandForPlatform(aMap) aMap.mCommandWin +#elif defined(MOZ_WIDGET_COCOA) +# define GetCommandForPlatform(aMap) aMap.mCommandMac +#elif defined(MOZ_WIDGET_GTK) +# define GetCommandForPlatform(aMap) aMap.mCommandLinux +#elif defined(MOZ_WIDGET_ANDROID) +# define GetCommandForPlatform(aMap) aMap.mCommandAndroid +#else +# define GetCommandForPlatform(aMap) aMap.mCommandEmacs +#endif + +static bool GetCommandFor(KeyEventHandler* aFirstHandler, + dom::KeyboardEvent* aDOMEvent, nsAString& aCommand) { + if (!aFirstHandler) { + return false; + } + aCommand.Truncate(); + for (KeyEventHandler* handler = aFirstHandler; handler; + handler = handler->GetNextHandler()) { + if (handler->KeyEventMatched(aDOMEvent, 0, IgnoreModifierState())) { + handler->GetCommand(aCommand); + return true; + } + } + return false; +} + +static char16ptr_t GetExpectedCommandFor( + const nsTArray& aExpectedMap, + const WidgetKeyboardEvent& aWidgetEvent) { + MOZ_ASSERT(!aExpectedMap.IsEmpty()); + for (const ShortcutKeyMap& map : aExpectedMap) { + if (aWidgetEvent.mKeyCode == map.mKeyCode && + aWidgetEvent.mCharCode == map.mCharCode && + aWidgetEvent.mModifiers == map.mModifiers) { + return GetCommandForPlatform(map); + } + } + return nullptr; +} + +struct KeyCodeAndStr final { + uint32_t mKeyCode; + KeyNameIndex mKeyNameIndex; + const char* mStr; +}; +static const KeyCodeAndStr kKeyCodes[] = { + {NS_VK_BACK, KEY_NAME_INDEX_Backspace, "Backspace"}, + {NS_VK_RETURN, KEY_NAME_INDEX_Enter, "Enter"}, + {NS_VK_ESCAPE, KEY_NAME_INDEX_Escape, "Escape"}, + {NS_VK_PAGE_UP, KEY_NAME_INDEX_PageUp, "PageUp"}, + {NS_VK_PAGE_DOWN, KEY_NAME_INDEX_PageDown, "PageDown"}, + {NS_VK_END, KEY_NAME_INDEX_End, "End"}, + {NS_VK_HOME, KEY_NAME_INDEX_Home, "Home"}, + {NS_VK_LEFT, KEY_NAME_INDEX_ArrowLeft, "ArrowLeft"}, + {NS_VK_UP, KEY_NAME_INDEX_ArrowUp, "ArrowUp"}, + {NS_VK_RIGHT, KEY_NAME_INDEX_ArrowRight, "ArrowRight"}, + {NS_VK_DOWN, KEY_NAME_INDEX_ArrowDown, "ArrowDown"}, +#ifndef MOZ_WIDGET_COCOA + // No Insert key on macOS + {NS_VK_INSERT, KEY_NAME_INDEX_Insert, "Insert"}, +#endif + {NS_VK_DELETE, KEY_NAME_INDEX_Delete, "Delete"}, + {NS_VK_F1, KEY_NAME_INDEX_F1, "F1"}, + {NS_VK_F2, KEY_NAME_INDEX_F2, "F2"}, + {NS_VK_F3, KEY_NAME_INDEX_F3, "F3"}, + {NS_VK_F4, KEY_NAME_INDEX_F4, "F4"}, + {NS_VK_F5, KEY_NAME_INDEX_F5, "F5"}, + {NS_VK_F6, KEY_NAME_INDEX_F6, "F6"}, + {NS_VK_F7, KEY_NAME_INDEX_F7, "F7"}, + {NS_VK_F8, KEY_NAME_INDEX_F8, "F8"}, + {NS_VK_F9, KEY_NAME_INDEX_F9, "F9"}, + {NS_VK_F10, KEY_NAME_INDEX_F10, "F10"}, + {NS_VK_F11, KEY_NAME_INDEX_F11, "F11"}, + {NS_VK_F12, KEY_NAME_INDEX_F12, "F12"}, +#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_ANDROID) + {NS_VK_F13, KEY_NAME_INDEX_F13, "F13"}, + {NS_VK_F14, KEY_NAME_INDEX_F14, "F14"}, + {NS_VK_F15, KEY_NAME_INDEX_F15, "F15"}, + {NS_VK_F16, KEY_NAME_INDEX_F16, "F16"}, + {NS_VK_F17, KEY_NAME_INDEX_F17, "F17"}, + {NS_VK_F18, KEY_NAME_INDEX_F18, "F18"}, + {NS_VK_F19, KEY_NAME_INDEX_F19, "F19"}, +#endif +#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK) + {NS_VK_F20, KEY_NAME_INDEX_F20, "F20"}, + {NS_VK_F21, KEY_NAME_INDEX_F21, "F21"}, + {NS_VK_F22, KEY_NAME_INDEX_F22, "F22"}, + {NS_VK_F23, KEY_NAME_INDEX_F23, "F23"}, + {NS_VK_F24, KEY_NAME_INDEX_F24, "F24"}, +#endif +}; + +static const unsigned char kCharCodes[] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + +struct ModifiersAndStr final { + Modifiers mModifiers; + const char* mStr; +}; +static const ModifiersAndStr kModifiers[] = { + {MODIFIER_NONE, ""}, + {MODIFIER_SHIFT, "Shift+"}, + {MODIFIER_CONTROL, "Control+"}, + {MODIFIER_CONTROL | MODIFIER_SHIFT, "Contrl+Shift+"}, + {MODIFIER_ALT, "Alt+"}, + {MODIFIER_ALT | MODIFIER_SHIFT, "Alt+Shift+"}, + {MODIFIER_META, "Meta+"}, + {MODIFIER_META | MODIFIER_SHIFT, "Meta+Shift+"}, + {MODIFIER_META | MODIFIER_ALT | MODIFIER_SHIFT, "Meta+Alt+Shift+"}, + {MODIFIER_CONTROL | MODIFIER_ALT, "Control+Alt+"}, + {MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_SHIFT, "Control+Alt+Shift+"}, +}; + +static void TestAllKeyCodes(KeyEventHandler* aFirstHandler, + const nsTArray& aExpectedMap) { + WidgetKeyboardEvent widgetEvent(true, eKeyPress, nullptr); + RefPtr domEvent = + NS_NewDOMKeyboardEvent(nullptr, nullptr, &widgetEvent); + nsAutoString command; + uint32_t foundCommand = 0; + for (const auto& mod : kModifiers) { + widgetEvent.mModifiers = mod.mModifiers; + for (const auto& keyCode : kKeyCodes) { + widgetEvent.mKeyCode = keyCode.mKeyCode; + widgetEvent.mKeyNameIndex = keyCode.mKeyNameIndex; + const char16ptr_t expectedCommand = + GetExpectedCommandFor(aExpectedMap, widgetEvent); + if (GetCommandFor(aFirstHandler, domEvent, command)) { + foundCommand++; + if (expectedCommand) { + ASSERT_TRUE(command.Equals(expectedCommand)) + << mod.mStr << keyCode.mStr << ": got " + << NS_ConvertUTF16toUTF8(command).get() << ", but expected " + << NS_ConvertUTF16toUTF8(expectedCommand).get(); + } else { + ASSERT_TRUE(false) + << mod.mStr << keyCode.mStr << ": got " + << NS_ConvertUTF16toUTF8(command).get() + << ", but expected no command"; + } + } else if (expectedCommand) { + ASSERT_TRUE(false) + << mod.mStr << keyCode.mStr << ": got no command, but expected " + << NS_ConvertUTF16toUTF8(expectedCommand).get(); + } + } + widgetEvent.mKeyCode = 0; + widgetEvent.mKeyNameIndex = KEY_NAME_INDEX_USE_STRING; + for (unsigned char charCode : kCharCodes) { + widgetEvent.mCharCode = charCode; + widgetEvent.mKeyValue.Assign(charCode); + const char16ptr_t expectedCommand = + GetExpectedCommandFor(aExpectedMap, widgetEvent); + if (GetCommandFor(aFirstHandler, domEvent, command)) { + foundCommand++; + if (expectedCommand) { + ASSERT_TRUE(command.Equals(expectedCommand)) + << mod.mStr << "'" << nsAutoCString(charCode).get() << "': got " + << NS_ConvertUTF16toUTF8(command).get() << ", but expected " + << NS_ConvertUTF16toUTF8(expectedCommand).get(); + } else { + ASSERT_TRUE(false) + << mod.mStr << "'" << nsAutoCString(charCode).get() << "': got " + << NS_ConvertUTF16toUTF8(command).get() + << ", but expected no command"; + } + } else if (expectedCommand) { + ASSERT_TRUE(false) + << mod.mStr << "'" << nsAutoCString(charCode).get() + << "': got no command, but expected " + << NS_ConvertUTF16toUTF8(expectedCommand).get(); + } + } + widgetEvent.mCharCode = 0; + widgetEvent.mKeyValue.Truncate(); + } + uint32_t expectedCommandCount = 0; + for (const auto& map : aExpectedMap) { + if (GetCommandForPlatform(map)) { + expectedCommandCount++; + } + } + ASSERT_EQ(foundCommand, expectedCommandCount) + << "Some expected shortcut keys have not been tested"; + uint32_t countOfHandler = 0; + for (KeyEventHandler* handler = aFirstHandler; handler; + handler = handler->GetNextHandler()) { + countOfHandler++; + } + ASSERT_EQ(countOfHandler, expectedCommandCount) + << "Some unnecessary key handlers found"; +} + +TEST(ShortcutKeyDefinitions, HTMLInputElement) +{ + // clang-format off + const nsTArray expectedMap{ + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_NONE, u"cmd_moveLeft", nullptr, u"cmd_moveLeft", u"cmd_moveLeft", u"cmd_moveLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_NONE, u"cmd_moveRight", nullptr, u"cmd_moveRight", u"cmd_moveRight", u"cmd_moveRight"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT, u"cmd_selectLeft", nullptr, u"cmd_selectLeft", u"cmd_selectLeft", u"cmd_selectLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT, u"cmd_selectRight", nullptr, u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectRight"}, + {NS_VK_LEFT, 0, MODIFIER_CONTROL, u"cmd_moveLeft2", nullptr, nullptr, u"cmd_wordPrevious", u"cmd_wordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2", nullptr, nullptr, u"cmd_wordNext", u"cmd_wordNext"}, + {NS_VK_LEFT, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_beginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_endLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_NONE, u"cmd_moveUp", nullptr, u"cmd_moveUp", u"cmd_moveUp", u"cmd_moveUp"}, + {NS_VK_DOWN, 0, MODIFIER_NONE, u"cmd_moveDown", nullptr, u"cmd_moveDown", u"cmd_moveDown", u"cmd_moveDown"}, + {NS_VK_UP, 0, MODIFIER_SHIFT, u"cmd_selectUp", nullptr, u"cmd_selectUp", u"cmd_selectUp", u"cmd_selectUp"}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectDown", nullptr, u"cmd_selectDown", u"cmd_selectDown", u"cmd_selectDown"}, + {NS_VK_UP, 0, MODIFIER_CONTROL, u"cmd_moveUp2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_CONTROL, u"cmd_moveDown2", nullptr, nullptr, nullptr, nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2", nullptr, nullptr, u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, nullptr, u"cmd_selectWordNext", u"cmd_selectWordNext"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBeginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectEndLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2", nullptr, nullptr, nullptr, nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_NONE, u"cmd_beginLine", nullptr, nullptr, u"cmd_beginLine", u"cmd_beginLine"}, + {NS_VK_END, 0, MODIFIER_NONE, u"cmd_endLine", nullptr, nullptr, u"cmd_endLine", u"cmd_endLine"}, + {NS_VK_HOME, 0, MODIFIER_SHIFT, u"cmd_selectBeginLine", nullptr, nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine"}, + {NS_VK_END, 0, MODIFIER_SHIFT, u"cmd_selectEndLine", nullptr, nullptr, u"cmd_selectEndLine", u"cmd_selectEndLine"}, + {NS_VK_HOME, 0, MODIFIER_CONTROL, u"cmd_moveTop", nullptr, nullptr, nullptr, u"cmd_beginLine"}, + {NS_VK_END, 0, MODIFIER_CONTROL, u"cmd_moveBottom", nullptr, nullptr, nullptr, u"cmd_endLine"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop", nullptr, nullptr, nullptr, u"cmd_selectBeginLine"}, + {NS_VK_END, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, nullptr, nullptr, u"cmd_selectEndLine"}, + + // KeyCode Modifiers Windows macOS Linux Android + {NS_VK_INSERT, 0, MODIFIER_SHIFT, u"cmd_paste", nullptr, nullptr, nullptr, u"cmd_paste"}, + {NS_VK_INSERT, 0, MODIFIER_CONTROL, u"cmd_copy", nullptr, nullptr, nullptr, u"cmd_copy"}, + {NS_VK_DELETE, 0, MODIFIER_SHIFT, u"cmd_cutOrDelete", nullptr, nullptr, nullptr, u"cmd_cutOrDelete"}, + {NS_VK_DELETE, 0, MODIFIER_CONTROL, u"cmd_deleteWordForward", nullptr, nullptr, u"cmd_deleteWordForward", u"cmd_copyOrDelete"}, + {NS_VK_DELETE, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine", nullptr}, + {NS_VK_BACK, 0, MODIFIER_CONTROL, u"cmd_deleteWordBackward", nullptr, nullptr, u"cmd_deleteWordBackward", u"cmd_deleteWordBackward"}, + {NS_VK_BACK, 0, MODIFIER_ALT, u"cmd_undo", nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_BACK, 0, MODIFIER_SHIFT | MODIFIER_ALT, u"cmd_redo", nullptr, nullptr, nullptr, nullptr}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, 'a', MODIFIER_ACCEL, u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", nullptr}, + {0, 'a', MODIFIER_ALT, nullptr, nullptr, nullptr, nullptr, u"cmd_selectAll"}, + {0, 'c', MODIFIER_ACCEL, u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy"}, + {0, 'x', MODIFIER_ACCEL, u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut"}, + {0, 'v', MODIFIER_ACCEL, u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"}, + {0, 'y', MODIFIER_ACCEL, u"cmd_redo", nullptr, u"cmd_redo", nullptr, u"cmd_redo"}, + {0, 'z', MODIFIER_ACCEL, u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo"}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, 'v', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"}, + {0, 'v', MODIFIER_SHIFT | MODIFIER_ALT | MODIFIER_ACCEL, nullptr, u"cmd_paste", nullptr, nullptr, nullptr}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'z', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'a', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_beginLine"}, + {0, 'b', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charPrevious"}, + {0, 'd', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharForward"}, + {0, 'e', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_endLine"}, + {0, 'f', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charNext"}, + {0, 'h', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharBackward"}, + {0, 'k', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine"}, + {0, 'u', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine"}, + {0, 'w', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward"}, + }; + // clang-format on + + TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eInput), expectedMap); + + ShortcutKeys::Shutdown(); // Destroy the singleton instance. +} + +TEST(ShortcutKeyDefinitions, HTMLTextAreaElement) +{ + // clang-format off + const nsTArray expectedMap{ + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_NONE, u"cmd_moveLeft", nullptr, u"cmd_moveLeft", u"cmd_moveLeft", u"cmd_moveLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_NONE, u"cmd_moveRight", nullptr, u"cmd_moveRight", u"cmd_moveRight", u"cmd_moveRight"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT, u"cmd_selectLeft", nullptr, u"cmd_selectLeft", u"cmd_selectLeft", u"cmd_selectLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT, u"cmd_selectRight", nullptr, u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectRight"}, + {NS_VK_LEFT, 0, MODIFIER_CONTROL, u"cmd_moveLeft2", nullptr, nullptr, u"cmd_wordPrevious", u"cmd_wordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2", nullptr, nullptr, u"cmd_wordNext", u"cmd_wordNext"}, + {NS_VK_LEFT, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_beginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_endLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_NONE, u"cmd_moveUp", nullptr, u"cmd_moveUp", u"cmd_moveUp", u"cmd_moveUp"}, + {NS_VK_DOWN, 0, MODIFIER_NONE, u"cmd_moveDown", nullptr, u"cmd_moveDown", u"cmd_moveDown", u"cmd_moveDown"}, + {NS_VK_UP, 0, MODIFIER_SHIFT, u"cmd_selectUp", nullptr, u"cmd_selectUp", u"cmd_selectUp", u"cmd_selectUp"}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectDown", nullptr, u"cmd_selectDown", u"cmd_selectDown", u"cmd_selectDown"}, + {NS_VK_UP, 0, MODIFIER_CONTROL, u"cmd_moveUp2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_CONTROL, u"cmd_moveDown2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_UP, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveTop", nullptr}, + {NS_VK_DOWN, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2", nullptr, nullptr, u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, nullptr, u"cmd_selectWordNext", u"cmd_selectWordNext"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBeginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectEndLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectTop", nullptr}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_PAGE_UP, 0, MODIFIER_NONE, u"cmd_movePageUp", nullptr, nullptr, u"cmd_movePageUp", u"cmd_movePageUp"}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_NONE, u"cmd_movePageDown", nullptr, nullptr, u"cmd_movePageDown", u"cmd_movePageDown"}, + {NS_VK_PAGE_UP, 0, MODIFIER_SHIFT, u"cmd_selectPageUp", nullptr, nullptr, u"cmd_selectPageUp", u"cmd_selectPageUp"}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectPageDown", nullptr, nullptr, u"cmd_selectPageDown", u"cmd_selectPageDown"}, + {NS_VK_PAGE_UP, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveTop", nullptr}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_PAGE_UP, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectTop", nullptr}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_NONE, u"cmd_beginLine", nullptr, nullptr, u"cmd_beginLine", u"cmd_beginLine"}, + {NS_VK_END, 0, MODIFIER_NONE, u"cmd_endLine", nullptr, nullptr, u"cmd_endLine", u"cmd_endLine"}, + {NS_VK_HOME, 0, MODIFIER_SHIFT, u"cmd_selectBeginLine", nullptr, nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine"}, + {NS_VK_END, 0, MODIFIER_SHIFT, u"cmd_selectEndLine", nullptr, nullptr, u"cmd_selectEndLine", u"cmd_selectEndLine"}, + {NS_VK_HOME, 0, MODIFIER_CONTROL, u"cmd_moveTop", nullptr, nullptr, u"cmd_moveTop", u"cmd_moveTop"}, + {NS_VK_END, 0, MODIFIER_CONTROL, u"cmd_moveBottom", nullptr, nullptr, u"cmd_moveBottom", u"cmd_moveBottom"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop", nullptr, nullptr, u"cmd_selectTop", u"cmd_selectTop"}, + {NS_VK_END, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, nullptr, u"cmd_selectBottom", u"cmd_selectBottom"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_INSERT, 0, MODIFIER_SHIFT, u"cmd_paste", nullptr, nullptr, nullptr, u"cmd_paste"}, + {NS_VK_INSERT, 0, MODIFIER_CONTROL, u"cmd_copy", nullptr, nullptr, nullptr, u"cmd_copy"}, + {NS_VK_DELETE, 0, MODIFIER_SHIFT, u"cmd_cutOrDelete", nullptr, nullptr, nullptr, u"cmd_cutOrDelete"}, + {NS_VK_DELETE, 0, MODIFIER_CONTROL, u"cmd_deleteWordForward", nullptr, nullptr, u"cmd_deleteWordForward", u"cmd_copyOrDelete"}, + {NS_VK_DELETE, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine", nullptr}, + {NS_VK_BACK, 0, MODIFIER_CONTROL, u"cmd_deleteWordBackward", nullptr, nullptr, u"cmd_deleteWordBackward", u"cmd_deleteWordBackward"}, + {NS_VK_BACK, 0, MODIFIER_ALT, u"cmd_undo", nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_BACK, 0, MODIFIER_SHIFT | MODIFIER_ALT, u"cmd_redo", nullptr, nullptr, nullptr, nullptr}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, 'a', MODIFIER_ACCEL, u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", nullptr}, + {0, 'a', MODIFIER_ALT, nullptr, nullptr, nullptr, nullptr, u"cmd_selectAll"}, + {0, 'c', MODIFIER_ACCEL, u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy"}, + {0, 'x', MODIFIER_ACCEL, u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut"}, + {0, 'v', MODIFIER_ACCEL, u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"}, + {0, 'y', MODIFIER_ACCEL, u"cmd_redo", nullptr, u"cmd_redo", nullptr, u"cmd_redo"}, + {0, 'z', MODIFIER_ACCEL, u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo"}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, 'v', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"}, + {0, 'v', MODIFIER_SHIFT | MODIFIER_ALT | MODIFIER_ACCEL, nullptr, u"cmd_paste", nullptr, nullptr, nullptr}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'z', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'a', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_beginLine"}, + {0, 'b', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charPrevious"}, + {0, 'd', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharForward"}, + {0, 'e', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_endLine"}, + {0, 'f', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charNext"}, + {0, 'h', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharBackward"}, + {0, 'k', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine"}, + {0, 'n', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_lineNext"}, + {0, 'p', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_linePrevious"}, + {0, 'u', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine"}, + {0, 'w', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward"}, + }; + // clang-format on + + TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eTextArea), + expectedMap); + + ShortcutKeys::Shutdown(); // Destroy the singleton instance. +} + +TEST(ShortcutKeyDefinitions, Browser) +{ + // clang-format off + const nsTArray expectedMap{ + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_NONE, u"cmd_moveLeft", u"cmd_moveLeft", u"cmd_moveLeft", u"cmd_moveLeft", u"cmd_moveLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_NONE, u"cmd_moveRight", u"cmd_moveRight", u"cmd_moveRight", u"cmd_moveRight", u"cmd_moveRight"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT, u"cmd_selectLeft", u"cmd_selectLeft", u"cmd_selectLeft", u"cmd_selectCharPrevious", u"cmd_selectLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT, u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectCharNext", u"cmd_selectRight"}, + {NS_VK_LEFT, 0, MODIFIER_CONTROL, u"cmd_moveLeft2", nullptr, u"cmd_moveLeft2", u"cmd_wordPrevious", u"cmd_wordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2", nullptr, u"cmd_moveRight2", u"cmd_wordNext", u"cmd_wordNext"}, + {NS_VK_LEFT, 0, MODIFIER_ALT, nullptr, u"cmd_moveLeft2", nullptr, u"cmd_beginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_ALT, nullptr, u"cmd_moveRight2", nullptr, u"cmd_endLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_NONE, u"cmd_moveUp", u"cmd_moveUp", u"cmd_moveUp", u"cmd_moveUp", u"cmd_moveUp"}, + {NS_VK_DOWN, 0, MODIFIER_NONE, u"cmd_moveDown", u"cmd_moveDown", u"cmd_moveDown", u"cmd_moveDown", u"cmd_moveDown"}, + {NS_VK_UP, 0, MODIFIER_SHIFT, u"cmd_selectUp", u"cmd_selectUp", u"cmd_selectUp", u"cmd_selectLinePrevious", u"cmd_selectUp"}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectDown", u"cmd_selectDown", u"cmd_selectDown", u"cmd_selectLineNext", u"cmd_selectDown"}, + {NS_VK_UP, 0, MODIFIER_CONTROL, u"cmd_moveUp2", nullptr, u"cmd_moveUp2", nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_CONTROL, u"cmd_moveDown2", nullptr, u"cmd_moveDown2", nullptr, nullptr}, + {NS_VK_UP, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveTop", nullptr}, + {NS_VK_DOWN, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveBottom", nullptr}, + {NS_VK_UP, 0, MODIFIER_META, nullptr, u"cmd_moveUp2", nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_META, nullptr, u"cmd_moveDown2", nullptr, nullptr, nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2", nullptr, u"cmd_selectLeft2", u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, u"cmd_selectRight2", u"cmd_selectWordNext", u"cmd_selectWordNext"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, u"cmd_selectLeft2", nullptr, u"cmd_selectBeginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, u"cmd_selectRight2", nullptr, u"cmd_selectEndLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2", nullptr, u"cmd_selectUp2", nullptr, u"cmd_selectWordPrevious"}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2", nullptr, u"cmd_selectDown2", nullptr, u"cmd_selectWordNext"}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, u"cmd_selectUp2", nullptr, u"cmd_selectTop", nullptr}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, u"cmd_selectDown2", nullptr, u"cmd_selectBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_PAGE_UP, 0, MODIFIER_NONE, u"cmd_movePageUp", u"cmd_scrollPageUp", u"cmd_movePageUp", u"cmd_movePageUp", u"cmd_movePageUp"}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_NONE, u"cmd_movePageDown", u"cmd_scrollPageDown", u"cmd_movePageDown", u"cmd_movePageDown", u"cmd_movePageDown"}, + {NS_VK_PAGE_UP, 0, MODIFIER_SHIFT, u"cmd_selectPageUp", nullptr, u"cmd_selectPageUp", u"cmd_selectPageUp", u"cmd_selectPageUp"}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectPageDown", nullptr, u"cmd_selectPageDown", u"cmd_selectPageDown", u"cmd_selectPageDown"}, + {NS_VK_PAGE_UP, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveTop", nullptr}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_PAGE_UP, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectTop", nullptr}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_NONE, u"cmd_beginLine", u"cmd_scrollTop", u"cmd_beginLine", u"cmd_beginLine", u"cmd_beginLine"}, + {NS_VK_END, 0, MODIFIER_NONE, u"cmd_endLine", u"cmd_scrollBottom", u"cmd_endLine", u"cmd_endLine", u"cmd_endLine"}, + {NS_VK_HOME, 0, MODIFIER_SHIFT, u"cmd_selectBeginLine", nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine", u"cmd_selectBeginLine"}, + {NS_VK_END, 0, MODIFIER_SHIFT, u"cmd_selectEndLine", nullptr, u"cmd_selectEndLine", u"cmd_selectEndLine", u"cmd_selectEndLine"}, + {NS_VK_HOME, 0, MODIFIER_CONTROL, u"cmd_moveTop", nullptr, u"cmd_moveTop", u"cmd_moveTop", u"cmd_moveTop"}, + {NS_VK_END, 0, MODIFIER_CONTROL, u"cmd_moveBottom", nullptr, u"cmd_moveBottom", u"cmd_moveBottom", u"cmd_moveBottom"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop", nullptr, u"cmd_selectTop", u"cmd_selectTop", u"cmd_selectTop"}, + {NS_VK_END, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, u"cmd_selectBottom", u"cmd_selectBottom", u"cmd_selectBottom"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_INSERT, 0, MODIFIER_CONTROL, u"cmd_copy", nullptr, u"cmd_copy", nullptr, u"cmd_copy"}, + {NS_VK_DELETE, 0, MODIFIER_SHIFT, u"cmd_cut", nullptr, u"cmd_cut", nullptr, u"cmd_cut"}, + {NS_VK_DELETE, 0, MODIFIER_CONTROL, u"cmd_deleteWordForward", nullptr, u"cmd_copy", u"cmd_deleteWordForward", u"cmd_copy"}, + {NS_VK_DELETE, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine", nullptr}, + {NS_VK_BACK, 0, MODIFIER_CONTROL, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward", nullptr}, + {NS_VK_BACK, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, ' ', MODIFIER_NONE, u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown"}, + {0, ' ', MODIFIER_SHIFT, u"cmd_scrollPageUp", u"cmd_scrollPageUp", u"cmd_scrollPageUp", u"cmd_scrollPageUp", u"cmd_scrollPageUp"}, + {0, 'a', MODIFIER_ACCEL, u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll"}, + {0, 'a', MODIFIER_ALT, nullptr, nullptr, nullptr, nullptr, u"cmd_selectAll"}, + {0, 'c', MODIFIER_ACCEL, u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy"}, + {0, 'x', MODIFIER_ACCEL, u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut"}, + {0, 'v', MODIFIER_ACCEL, u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"}, + {0, 'y', MODIFIER_ACCEL, u"cmd_redo", nullptr, nullptr, nullptr, nullptr}, + {0, 'z', MODIFIER_ACCEL, u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo"}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, 'v', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting"}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, 'v', MODIFIER_SHIFT | MODIFIER_ALT | MODIFIER_ACCEL, nullptr, u"cmd_pasteNoFormatting", nullptr, nullptr, nullptr}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'z', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"}, + }; + // clang-format on + + TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eBrowser), + expectedMap); + + ShortcutKeys::Shutdown(); // Destroy the singleton instance. +} + +TEST(ShortcutKeyDefinitions, HTMLEditor) +{ + // clang-format off + const nsTArray expectedMap{ + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_NONE, u"cmd_moveLeft", nullptr, u"cmd_moveLeft", u"cmd_moveLeft", u"cmd_moveLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_NONE, u"cmd_moveRight", nullptr, u"cmd_moveRight", u"cmd_moveRight", u"cmd_moveRight"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT, u"cmd_selectLeft", nullptr, u"cmd_selectLeft", u"cmd_selectLeft", u"cmd_selectLeft"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT, u"cmd_selectRight", nullptr, u"cmd_selectRight", u"cmd_selectRight", u"cmd_selectRight"}, + {NS_VK_LEFT, 0, MODIFIER_CONTROL, u"cmd_moveLeft2", nullptr, nullptr, u"cmd_wordPrevious", u"cmd_wordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_CONTROL, u"cmd_moveRight2", nullptr, nullptr, u"cmd_wordNext", u"cmd_wordNext"}, + {NS_VK_LEFT, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_beginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_endLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_NONE, u"cmd_moveUp", nullptr, u"cmd_moveUp", u"cmd_moveUp", u"cmd_moveUp"}, + {NS_VK_DOWN, 0, MODIFIER_NONE, u"cmd_moveDown", nullptr, u"cmd_moveDown", u"cmd_moveDown", u"cmd_moveDown"}, + {NS_VK_UP, 0, MODIFIER_SHIFT, u"cmd_selectUp", nullptr, u"cmd_selectUp", u"cmd_selectUp", u"cmd_selectUp"}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectDown", nullptr, u"cmd_selectDown", u"cmd_selectDown", u"cmd_selectDown"}, + {NS_VK_UP, 0, MODIFIER_CONTROL, u"cmd_moveUp2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_CONTROL, u"cmd_moveDown2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_UP, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveTop", nullptr}, + {NS_VK_DOWN, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectLeft2", nullptr, nullptr, u"cmd_selectWordPrevious", u"cmd_selectWordPrevious"}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectRight2", nullptr, nullptr, u"cmd_selectWordNext", u"cmd_selectWordNext"}, + {NS_VK_LEFT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBeginLine", nullptr}, + {NS_VK_RIGHT, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectEndLine", nullptr}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectUp2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectDown2", nullptr, nullptr, nullptr, nullptr}, + {NS_VK_UP, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectTop", nullptr}, + {NS_VK_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_PAGE_UP, 0, MODIFIER_NONE, u"cmd_movePageUp", nullptr, nullptr, u"cmd_movePageUp", u"cmd_movePageUp"}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_NONE, u"cmd_movePageDown", nullptr, nullptr, u"cmd_movePageDown", u"cmd_movePageDown"}, + {NS_VK_PAGE_UP, 0, MODIFIER_SHIFT, u"cmd_selectPageUp", nullptr, nullptr, u"cmd_selectPageUp", u"cmd_selectPageUp"}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT, u"cmd_selectPageDown", nullptr, nullptr, u"cmd_selectPageDown", u"cmd_selectPageDown"}, + {NS_VK_PAGE_UP, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveTop", nullptr}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_moveBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_PAGE_UP, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectTop", nullptr}, + {NS_VK_PAGE_DOWN, 0, MODIFIER_SHIFT | MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_selectBottom", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_NONE, u"cmd_beginLine", nullptr, nullptr, u"cmd_beginLine", u"cmd_beginLine"}, + {NS_VK_END, 0, MODIFIER_NONE, u"cmd_endLine", nullptr, nullptr, u"cmd_endLine", u"cmd_endLine"}, + {NS_VK_HOME, 0, MODIFIER_SHIFT, u"cmd_selectBeginLine", nullptr, nullptr, u"cmd_selectBeginLine", u"cmd_selectBeginLine"}, + {NS_VK_END, 0, MODIFIER_SHIFT, u"cmd_selectEndLine", nullptr, nullptr, u"cmd_selectEndLine", u"cmd_selectEndLine"}, + {NS_VK_HOME, 0, MODIFIER_CONTROL, u"cmd_moveTop", nullptr, nullptr, u"cmd_moveTop", u"cmd_moveTop"}, + {NS_VK_END, 0, MODIFIER_CONTROL, u"cmd_moveBottom", nullptr, nullptr, u"cmd_moveBottom", u"cmd_moveBottom"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_HOME, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectTop", nullptr, nullptr, u"cmd_selectTop", u"cmd_selectTop"}, + {NS_VK_END, 0, MODIFIER_SHIFT | MODIFIER_CONTROL, u"cmd_selectBottom", nullptr, nullptr, u"cmd_selectBottom", u"cmd_selectBottom"}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_INSERT, 0, MODIFIER_SHIFT, u"cmd_paste", nullptr, nullptr, nullptr, u"cmd_paste"}, + {NS_VK_INSERT, 0, MODIFIER_CONTROL, u"cmd_copy", nullptr, nullptr, nullptr, u"cmd_copy"}, + {NS_VK_DELETE, 0, MODIFIER_SHIFT, u"cmd_cutOrDelete", nullptr, nullptr, nullptr, u"cmd_cutOrDelete"}, + {NS_VK_DELETE, 0, MODIFIER_CONTROL, u"cmd_deleteWordForward", nullptr, nullptr, u"cmd_deleteWordForward", u"cmd_copyOrDelete"}, + {NS_VK_DELETE, 0, MODIFIER_ALT, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine", nullptr}, + {NS_VK_BACK, 0, MODIFIER_CONTROL, u"cmd_deleteWordBackward", nullptr, nullptr, u"cmd_deleteWordBackward", u"cmd_deleteWordBackward"}, + {NS_VK_BACK, 0, MODIFIER_ALT, u"cmd_undo", nullptr, nullptr, u"cmd_deleteToBeginningOfLine", nullptr}, + + // KeyCode Modifiers Windows macOS Linux Android Emacs + {NS_VK_BACK, 0, MODIFIER_SHIFT | MODIFIER_ALT, u"cmd_redo", nullptr, nullptr, nullptr, nullptr}, + + // charCode Modifiers, Windows macOS Linux Android Emacs + {0, ' ', MODIFIER_NONE, u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown", u"cmd_scrollPageDown"}, + {0, ' ', MODIFIER_SHIFT, u"cmd_scrollPageUp", u"cmd_scrollPageUp", u"cmd_scrollPageUp", u"cmd_scrollPageUp", u"cmd_scrollPageUp"}, + {0, 'a', MODIFIER_ACCEL, u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", u"cmd_selectAll", nullptr}, + {0, 'a', MODIFIER_ALT, nullptr, nullptr, nullptr, nullptr, u"cmd_selectAll"}, + {0, 'c', MODIFIER_ACCEL, u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy", u"cmd_copy"}, + {0, 'x', MODIFIER_ACCEL, u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut", u"cmd_cut"}, + {0, 'v', MODIFIER_ACCEL, u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste", u"cmd_paste"}, + {0, 'y', MODIFIER_ACCEL, u"cmd_redo", nullptr, u"cmd_redo", nullptr, u"cmd_redo"}, + {0, 'z', MODIFIER_ACCEL, u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo", u"cmd_undo"}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'v', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting", u"cmd_pasteNoFormatting"}, + {0, 'z', MODIFIER_SHIFT | MODIFIER_ACCEL, u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo", u"cmd_redo"}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'v', MODIFIER_SHIFT | MODIFIER_ACCEL | MODIFIER_ALT, nullptr, u"cmd_pasteNoFormatting", nullptr, nullptr, nullptr}, + + // charCode Modifiers Windows macOS Linux Android Emacs + {0, 'a', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_beginLine"}, + {0, 'b', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charPrevious"}, + {0, 'd', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharForward"}, + {0, 'e', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_endLine"}, + {0, 'f', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_charNext"}, + {0, 'h', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteCharBackward"}, + {0, 'k', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToEndOfLine"}, + {0, 'n', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_lineNext"}, + {0, 'p', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_linePrevious"}, + {0, 'u', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteToBeginningOfLine"}, + {0, 'w', MODIFIER_CONTROL, nullptr, nullptr, nullptr, nullptr, u"cmd_deleteWordBackward"}, + }; + // clang-format on + + TestAllKeyCodes(ShortcutKeys::GetHandlers(HandlerType::eEditor), expectedMap); + + ShortcutKeys::Shutdown(); // Destroy the singleton instance. +} + +#undef MODIFIER_ACCEL +#undef GetCommandForPlatform + +} // namespace mozilla diff --git a/dom/events/test/gtest/moz.build b/dom/events/test/gtest/moz.build new file mode 100644 index 0000000000..d5c0ac6a9e --- /dev/null +++ b/dom/events/test/gtest/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +with Files("**"): + BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling") + +UNIFIED_SOURCES += [ + "TestShortcutKeyDefinitions.cpp", +] + +LOCAL_INCLUDES += ["/dom/events"] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul-gtest" diff --git a/dom/events/test/mochitest.toml b/dom/events/test/mochitest.toml new file mode 100644 index 0000000000..b6b9e58368 --- /dev/null +++ b/dom/events/test/mochitest.toml @@ -0,0 +1,523 @@ +[DEFAULT] +# Skip migration work in BG__migrateUI for browser_startup.js since it increases +# the occurrence of the leak reported in bug 1398563 with test_bug1327798.html. +# Run the font-loader eagerly to minimize the risk that font list finalization +# may disrupt the events received or result in a timeout. +tags = "condprof" +prefs = [ + "browser.migration.version=9999999", + "gfx.font_loader.delay=0", + "ui.dragThresholdX=4", # Bug 1873142 + "ui.dragThresholdY=4", # Bug 1873142 +] +support-files = [ + "bug226361_iframe.xhtml", + "bug299673.js", + "bug322588-popup.html", + "bug426082.html", + "bug545268.html", + "bug574663.html", + "bug607464.html", + "bug656379-1.html", + "bug418986-3.js", + "error_event_worker.js", + "empty.js", + "event_leak_utils.js", + "window_bug493251.html", + "window_bug659071.html", + "window_wheel_default_action.html", + "!/gfx/layers/apz/test/mochitest/apz_test_utils.js", +] + +["test_accel_virtual_modifier.html"] + +["test_accesskey.html"] + +["test_addEventListenerExtraArg.html"] + +["test_all_synthetic_events.html"] +skip-if = [ + "http3", + "http2", +] + +["test_auxclick_autoscroll_off.html"] + +["test_bug226361.xhtml"] + +["test_bug238987.html"] + +["test_bug288392.html"] + +["test_bug299673-1.html"] + +["test_bug299673-2.html"] + +["test_bug322588.html"] + +["test_bug328885.html"] + +["test_bug336682_1.html"] +support-files = ["test_bug336682.js"] + +["test_bug367781.html"] + +["test_bug379120.html"] + +["test_bug402089.html"] + +["test_bug405632.html"] + +["test_bug409604.html"] +skip-if = ["os == 'android'"] # android: TIMED_OUT + +["test_bug412567.html"] + +["test_bug418986-3.html"] + +["test_bug422132.html"] + +["test_bug426082.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug427537.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug428988.html"] + +["test_bug432698.html"] + +["test_bug443985.html"] +skip-if = ["verify"] + +["test_bug447736.html"] + +["test_bug448602.html"] + +["test_bug450876.html"] + +["test_bug456273.html"] + +["test_bug457672.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug489671.html"] + +["test_bug493251.html"] + +["test_bug508479.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM # drag event fails + +["test_bug517851.html"] + +["test_bug534833.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug545268.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug547996-1.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug547996-2.xhtml"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug556493.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug563329.html"] +skip-if = ["true"] # Disabled due to timeouts. + +["test_bug574663.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug591815.html"] + +["test_bug593959.html"] + +["test_bug603008.html"] +skip-if = ["os == 'android'"] + +["test_bug605242.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug607464.html"] +skip-if = [ + "os == 'android'", + "e10s", #CRASH_DUMP, RANDOM, bug 1400586 +] + +["test_bug613634.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug615597.html"] +skip-if = ["os == 'android'"] # failed + +["test_bug624127.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug635465.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug641477.html"] + +["test_bug648573.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug650493.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug656379-1.html"] +skip-if = ["os == 'android'"] + +["test_bug656379-2.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug656954.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug659071.html"] +skip-if = [ + "os == 'android'", # fail + "http3", + "http2", +] + +["test_bug659350.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug662678.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug667612.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug667919-1.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug684208.html"] + +["test_bug687787.html"] + +["test_bug689564.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug698929.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_bug704423.html"] + +["test_bug741666.html"] +skip-if = ["os == 'android'"] # fail + +["test_bug812744.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug822898.html"] + +["test_bug855741.html"] + +["test_bug864040.html"] + +["test_bug924087.html"] + +["test_bug930374-content.html"] + +["test_bug944011.html"] + +["test_bug944847.html"] + +["test_bug946632.html"] +skip-if = ["os == 'android'"] # fail + +["test_bug967796.html"] + +["test_bug985988.html"] + +["test_bug998809.html"] + +["test_bug1003432.html"] +support-files = ["test_bug1003432.js"] + +["test_bug1013412.html"] + +["test_bug1017086_enable.html"] +support-files = ["bug1017086_inner.html"] + +["test_bug1037990.html"] + +["test_bug1079236.html"] + +["test_bug1127588.html"] + +["test_bug1145910.html"] + +["test_bug1150308.html"] + +["test_bug1248459.html"] + +["test_bug1264380.html"] +skip-if = ["os == 'android'"] # some clipboard types and drag aren't supported + +["test_bug1298970.html"] + +["test_bug1304044.html"] + +["test_bug1305458.html"] + +["test_bug1327798.html"] +skip-if = ["headless"] + +["test_bug1332699.html"] + +["test_bug1339758.html"] + +["test_bug1369072.html"] +support-files = ["window_bug1369072.html"] +skip-if = ["os == 'android'"] + +["test_bug1429572.html"] +support-files = ["window_bug1429572.html"] +skip-if = ["os == 'android'"] # failed + +["test_bug1446834.html"] +support-files = ["file_bug1446834.html"] + +["test_bug1447993.html"] +support-files = ["window_bug1447993.html"] +skip-if = ["os == 'android'"] + +["test_bug1484371.html"] +support-files = ["file_bug1484371.html"] + +["test_bug1534562.html"] +skip-if = ["os == 'android'"] # Bug 1312791 + +["test_bug1539497.html"] + +["test_bug1581192.html"] + +["test_bug1635018.html"] + +["test_bug1637259.html"] +disabled = "Enable this when the taskcluster Windows machine upgrades to RS5+" +run-if = ["os == 'win'"] # Only Windows supports pen input synthesis +support-files = ["!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"] + +["test_bug1673434.html"] + +["test_bug1681800.html"] + +["test_bug1686716.html"] + +["test_bug1692052.html"] +support-files = ["file_bug1692052.html"] + +["test_bug1692277.html"] +disabled = "Enable this when the taskcluster Windows machine upgrades to RS5+" +run-if = ["os == 'win'"] # Only Windows supports pen input synthesis +support-files = [ + "!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js", + "!/dom/base/test/Ahem.ttf", +] + +["test_bug1709832.html"] +support-files = ["!/dom/base/test/Ahem.ttf"] + +["test_bug1710509.html"] +disabled = "Enable this when the taskcluster Windows machine upgrades to RS5+" +run-if = ["os == 'win'"] # Only Windows supports pen input synthesis +support-files = ["!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"] + +["test_bug1728171.html"] +run-if = ["os == 'win'"] # Only Windows 1809+ supports pen input synthesis +support-files = ["!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"] + +["test_click_on_reframed_generated_text.html"] + +["test_click_on_restyled_element.html"] + +["test_clickevent_on_input.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_coalesce_mousewheel.html"] +skip-if = ["os == 'android'"] # fail + +["test_coalesce_touchmove.html"] +support-files = [ + "file_coalesce_touchmove_ipc.html", + "file_coalesce_touchmove_browserchild.html", + "file_coalesce_touchmove_browserchild2.html", +] +skip-if = ["debug"] #In order to be able to test touchmoves, the test needs to synthesize touchstart in a way which asserts + +["test_continuous_wheel_events.html"] +skip-if = [ + "verify && debug && (os == 'linux' || os == 'win')", + "os == 'android'", # wheel event isn't supported +] + +["test_dblclick_explicit_original_target.html"] + +["test_deltaMode_lines_always_enabled.html"] + +["test_deviceSensor.html"] + +["test_disabled_events.html"] + +["test_dnd_with_modifiers.html"] + +["test_dom_activate_event.html"] + +["test_dom_keyboard_event.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_dom_mouse_event.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_dom_storage_event.html"] + +["test_dom_wheel_event.html"] +skip-if = ["os == 'android'"] # wheel scroll isn't supported + +["test_drag_coords.html"] +skip-if = ["os == 'android'"] # Need calculate screen coordinates. + +["test_drag_image_file.html"] +skip-if = [ + "xorigin", # Bug 1802904 +] +support-files = ["green.png"] + +["test_draggableprop.html"] + +["test_dragstart.html"] + +["test_error_events.html"] +skip-if = ["os == 'android'"] #TIMED_OUT + +["test_eventTimeStamp.html"] + +["test_event_handler_cc.html"] + +["test_event_screenXY_in_cross_origin_iframe.html"] +support-files = [ + "file_event_screenXY.html", + "!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js", +] +skip-if = ["os == 'android'"] # fail + +["test_event_screenXY_with_zoom.html"] +skip-if = ["os == 'android'"] # Android doesn't have full zoom. + +["test_eventctors.html"] +skip-if = ["os == 'android'"] #CRASH_DUMP, RANDOM + +["test_eventctors_sensors.html"] + +["test_eventhandler_scoping.html"] + +["test_focus_abspos.html"] + +["test_focus_blur_on_click_in_cross_origin_iframe.html"] +support-files = ["file_focus_blur_on_click_in_cross_origin_iframe.html"] +skip-if = ["os == 'android'"] # Bug 1701546 + +["test_focus_blur_on_click_in_deep_cross_origin_iframe.html"] +support-files = [ + "file_focus_blur_on_click_in_deep_cross_origin_iframe_inner.html", + "file_focus_blur_on_click_in_deep_cross_origin_iframe_middle.html", +] +skip-if = [ + "os == 'android'", # Bug 1701546 + "condprof && os == 'win'", # 1773806 +] + +["test_hover_mouseleave.html"] + +["test_legacy_event.html"] + +["test_legacy_touch_api.html"] + +["test_marquee_events.html"] + +["test_messageEvent.html"] + +["test_messageEvent_init.html"] + +["test_mouse_capture_iframe.html"] +support-files = ["file_empty.html"] +skip-if = [ + "os == 'android'", # timeout + "http3", + "http2", +] + +["test_mouse_enterleave_iframe.html"] +support-files = ["file_mouse_enterleave.html"] +skip-if = [ + "!debug", # Bug 1781668 + "os == 'android'", # timeout + "display == 'wayland' && os_version == '22.04'", # Bug 1857022 + "http3", + "http2", +] + +["test_mouse_over_at_removing_down_target.html"] + +["test_moving_and_expanding_selection_per_page.html"] +support-files = ["window_empty_document.html"] + +["test_moz_mouse_pixel_scroll_event.html"] + +["test_offsetxy.html"] + +["test_onerror_handler_args.html"] + +["test_passive_listeners.html"] + +["test_scroll_per_page.html"] +support-files = ["window_empty_document.html"] +skip-if = ["os == 'android'"] # fail + +["test_selection_after_right_click.html"] + +["test_slotted_mouse_event.html"] +skip-if = ["os == 'android'"] # timeout + +["test_slotted_text_click.html"] + +["test_submitevent_on_form.html"] + +["test_text_event_in_content.html"] + +["test_unbound_before_in_active_chain.html"] + +["test_use_conflated_keypress_event_model_on_newer_Office_Online_Server.html"] + +["test_use_split_keypress_event_model_on_old_Confluence.html"] +skip-if = ["!debug"] # The mode change event is available only on debug build + +["test_use_split_keypress_event_model_on_old_Office_Online_Server.html"] +skip-if = ["!debug"] # The mode change event is available only on debug build + +["test_wheel_default_action.html"] +skip-if = [ + "os == 'linux'", + "os == 'android'", +] + +["test_wheel_zoom_on_form_controls.html"] +skip-if = [ + "verify", + "os == 'android'", # wheel isn't supported +] diff --git a/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_1.html b/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_1.html new file mode 100644 index 0000000000..55c4e3cad5 --- /dev/null +++ b/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_1.html @@ -0,0 +1,63 @@ + + + + Pointer Events properties tests + + + + + + + + + +

Pointer Events tests

+
+
+
+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + diff --git a/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_2.html b/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_2.html new file mode 100644 index 0000000000..a533429acb --- /dev/null +++ b/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_2.html @@ -0,0 +1,64 @@ + + + + Pointer Events properties tests + + + + + + + + + +

Pointer Events tests

+
+
+
+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + diff --git a/dom/events/test/pointerevents/bug968148_inner.html b/dom/events/test/pointerevents/bug968148_inner.html new file mode 100644 index 0000000000..464e2e5c38 --- /dev/null +++ b/dom/events/test/pointerevents/bug968148_inner.html @@ -0,0 +1,316 @@ + + + + + Test for Bug 968148 + + + + + +Mozilla Bug 968148 +

+ +
+
+
+
 

 
+
 

 
+

+
+
diff --git a/dom/events/test/pointerevents/bug968148_inner2.html b/dom/events/test/pointerevents/bug968148_inner2.html
new file mode 100644
index 0000000000..ffad5297bc
--- /dev/null
+++ b/dom/events/test/pointerevents/bug968148_inner2.html
@@ -0,0 +1,315 @@
+
+
+
+
+  Test for Bug 968148
+  
+  
+  
+
+
+Mozilla Bug 968148
+

+ +
+
+
+
 

 
+
 

 
+

+
+
diff --git a/dom/events/test/pointerevents/bug_1420589_iframe1.html b/dom/events/test/pointerevents/bug_1420589_iframe1.html
new file mode 100644
index 0000000000..b18d808b84
--- /dev/null
+++ b/dom/events/test/pointerevents/bug_1420589_iframe1.html
@@ -0,0 +1,17 @@
+
+	
+
diff --git a/dom/events/test/pointerevents/bug_1420589_iframe2.html b/dom/events/test/pointerevents/bug_1420589_iframe2.html
new file mode 100644
index 0000000000..75aea1d187
--- /dev/null
+++ b/dom/events/test/pointerevents/bug_1420589_iframe2.html
@@ -0,0 +1,17 @@
+
+	
+
diff --git a/dom/events/test/pointerevents/chrome.toml b/dom/events/test/pointerevents/chrome.toml
new file mode 100644
index 0000000000..36e54e824a
--- /dev/null
+++ b/dom/events/test/pointerevents/chrome.toml
@@ -0,0 +1,3 @@
+[DEFAULT]
+
+["test_bug1697769.xhtml"]
diff --git a/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe.html b/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe.html
new file mode 100644
index 0000000000..88690748e5
--- /dev/null
+++ b/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe.html
@@ -0,0 +1,62 @@
+
+
+
+
+Bug 1671849
+
+
+
+
+
+
+
+Mozilla Bug 1671849
+
+ + +
+
+
+ + diff --git a/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_pointerlock.html b/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_pointerlock.html new file mode 100644 index 0000000000..12174da197 --- /dev/null +++ b/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_pointerlock.html @@ -0,0 +1,111 @@ + + + + +Bug 1671849 + + + + + + + +Mozilla Bug 1671849 +
+ + +
+
+
+ + diff --git a/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_touch.html b/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_touch.html new file mode 100644 index 0000000000..f34605349f --- /dev/null +++ b/dom/events/test/pointerevents/file_pointercapture_xorigin_iframe_touch.html @@ -0,0 +1,69 @@ + + + + +Bug 1671849 - Touch + + + + + + + + + +Mozilla Bug 1671849 +
+ + +
+
+
+ + diff --git a/dom/events/test/pointerevents/file_test_trigger_fullscreen.html b/dom/events/test/pointerevents/file_test_trigger_fullscreen.html new file mode 100644 index 0000000000..2d6549ede7 --- /dev/null +++ b/dom/events/test/pointerevents/file_test_trigger_fullscreen.html @@ -0,0 +1 @@ +
diff --git a/dom/events/test/pointerevents/iframe.html b/dom/events/test/pointerevents/iframe.html new file mode 100644 index 0000000000..0e3eac19b9 --- /dev/null +++ b/dom/events/test/pointerevents/iframe.html @@ -0,0 +1,7 @@ + + + + +
+ + diff --git a/dom/events/test/pointerevents/mochitest.toml b/dom/events/test/pointerevents/mochitest.toml new file mode 100644 index 0000000000..340704f94e --- /dev/null +++ b/dom/events/test/pointerevents/mochitest.toml @@ -0,0 +1,250 @@ +[DEFAULT] +prefs = [ + "gfx.font_loader.delay=0", + "dom.w3c_pointer_events.getcoalescedevents_only_in_securecontext=false" +] + +support-files = [ + "iframe.html", + "mochitest_support_external.js", + "mochitest_support_internal.js", + "wpt/pointerevent_styles.css", + "wpt/pointerevent_support.js", + "pointerevent_utils.js", + "!/gfx/layers/apz/test/mochitest/apz_test_utils.js", +] + +["test_bug968148.html"] +support-files = [ + "bug968148_inner.html", + "bug968148_inner2.html", +] + +["test_bug1285128.html"] + +["test_bug1293174_implicit_pointer_capture_for_touch_1.html"] +support-files = ["bug1293174_implicit_pointer_capture_for_touch_1.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1293174_implicit_pointer_capture_for_touch_2.html"] +support-files = ["bug1293174_implicit_pointer_capture_for_touch_2.html"] +skip-if = [ + "http3", + "http2", +] + +["test_bug1303704.html"] + +["test_bug1315862.html"] + +["test_bug1323158.html"] + +["test_bug1403055.html"] + +["test_bug1420589_1.html"] +support-files = [ + "bug_1420589_iframe1.html", + "bug_1420589_iframe2.html", +] + +["test_bug1420589_2.html"] +support-files = ["bug_1420589_iframe1.html"] + +["test_bug1420589_3.html"] +support-files = ["bug_1420589_iframe1.html"] + +["test_bug1725416.html"] +skip-if = ["os == 'android'"] # Bug 1312791 +support-files = ["!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"] + +["test_getCoalescedEvents.html"] +skip-if = [ + "os == 'android'", # Bug 1312791 + "display == 'wayland' && os_version == '22.04'", # Bug 1856971 + "verify && os == 'win'", # Bug 1659744 +] + +["test_getCoalescedEvents_touch.html"] +skip-if = [ + "os == 'android'", # Bug 1312791 + "verify && os == 'win'", # Bug 1659744 + "win11_2009", # Bug 1781388 +] +support-files = ["!/gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js"] + +["test_multiple_touches.html"] + +["test_pointercapture_remove_iframe.html"] + +["test_pointercapture_xorigin_iframe.html"] +support-files = [ + "file_pointercapture_xorigin_iframe.html", + "file_pointercapture_xorigin_iframe_pointerlock.html", + "file_pointercapture_xorigin_iframe_touch.html", +] +skip-if = [ + "display == 'wayland' && os_version == '22.04'", # Bug 1856971 +] + +["test_pointermove_drag_scrollbar.html"] +skip-if = ["os == 'android'"] # scrollbar not showed on mobile + +["test_remove_frame_when_got_pointer_capture.html"] + +["test_synthesized_touch.html"] + +["test_trigger_fullscreen_by_pointer_events.html"] +support-files = ["file_test_trigger_fullscreen.html"] + +["test_wpt_pointerevent_attributes_hoverable_pointers-manual.html"] +support-files = [ + "wpt/pointerevent_attributes_hoverable_pointers-manual.html", + "wpt/resources/pointerevent_attributes_hoverable_pointers-iframe.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_attributes_nohover_pointers-manual.html"] +support-files = [ + "wpt/pointerevent_attributes_nohover_pointers-manual.html", + "wpt/resources/pointerevent_attributes_hoverable_pointers-iframe.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_boundary_events_in_capturing-manual.html"] +support-files = ["wpt/pointerevent_boundary_events_in_capturing-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_change-touch-action-onpointerdown_touch-manual.html"] +support-files = ["wpt/pointerevent_change-touch-action-onpointerdown_touch-manual.html"] +disabled = "disabled" + +["test_wpt_pointerevent_constructor.html"] +support-files = ["wpt/pointerevent_constructor.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_drag_interaction-manual.html"] +support-files = ["wpt/html/pointerevent_drag_interaction-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_movementxy-manual.html"] +support-files = [ + "wpt/pointerlock/pointerevent_movementxy-manual.html", + "wpt/pointerlock/resources/pointerevent_movementxy-iframe.html", +] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_multiple_primary_pointers_boundary_events-manual.html"] +support-files = ["wpt/pointerevent_multiple_primary_pointers_boundary_events-manual.html"] +disabled = "should be investigated" + +["test_wpt_pointerevent_pointerId_scope-manual.html"] +support-files = ["wpt/resources/pointerevent_pointerId_scope-iframe.html"] +disabled = "should be investigated" + +["test_wpt_pointerevent_pointercancel_touch-manual.html"] +support-files = ["wpt/pointerevent_pointercancel_touch-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_pointerleave_after_pointercancel_touch-manual.html"] +support-files = ["wpt/pointerevent_pointerleave_after_pointercancel_touch-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_pointerleave_pen-manual.html"] +support-files = ["wpt/pointerevent_pointerleave_pen-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_pointerout_after_pointercancel_touch-manual.html"] +support-files = ["wpt/pointerevent_pointerout_after_pointercancel_touch-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_pointerout_pen-manual.html"] +support-files = ["wpt/pointerevent_pointerout_pen-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_releasepointercapture_events_to_original_target-manual.html"] +support-files = ["wpt/pointerevent_releasepointercapture_events_to_original_target-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_releasepointercapture_onpointercancel_touch-manual.html"] +support-files = ["wpt/pointerevent_releasepointercapture_onpointercancel_touch-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_pointerevent_sequence_at_implicit_release_on_drag-manual.html"] +support-files = ["wpt/pointerevent_sequence_at_implicit_release_on_drag-manual.html"] +skip-if = [ + "http3", + "http2", +] + +["test_wpt_touch_action.html"] +skip-if = [ + "os == 'android'", # Bug 1312791 + "os == 'linux' && headless", # Bug 1722906 +] +support-files = [ + "../../../../gfx/layers/apz/test/mochitest/apz_test_utils.js", + "../../../../gfx/layers/apz/test/mochitest/apz_test_native_event_utils.js", + "touch_action_helpers.js", + "wpt/pointerevent_touch-action-auto-css_touch-manual.html", + "wpt/pointerevent_touch-action-button-test_touch-manual.html", + "wpt/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html", + "wpt/pointerevent_touch-action-inherit_child-none_touch-manual.html", + "wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html", + "wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html", + "wpt/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html", + "wpt/pointerevent_touch-action-inherit_parent-none_touch-manual.html", + "wpt/pointerevent_touch-action-none-css_touch-manual.html", + "wpt/pointerevent_touch-action-pan-x-css_touch-manual.html", + "wpt/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html", + "wpt/pointerevent_touch-action-pan-x-pan-y_touch-manual.html", + "wpt/pointerevent_touch-action-pan-y-css_touch-manual.html", + "wpt/pointerevent_touch-action-span-test_touch-manual.html", + "wpt/pointerevent_touch-action-svg-test_touch-manual.html", + "wpt/pointerevent_touch-action-table-test_touch-manual.html", + "wpt/pointerevent_touch-action-pan-down-css_touch-manual.html", + "wpt/pointerevent_touch-action-pan-left-css_touch-manual.html", + "wpt/pointerevent_touch-action-pan-right-css_touch-manual.html", + "wpt/pointerevent_touch-action-pan-up-css_touch-manual.html", +] diff --git a/dom/events/test/pointerevents/mochitest_support_external.js b/dom/events/test/pointerevents/mochitest_support_external.js new file mode 100644 index 0000000000..7f22166fdd --- /dev/null +++ b/dom/events/test/pointerevents/mochitest_support_external.js @@ -0,0 +1,270 @@ +// This file supports translating W3C tests +// to tests on auto MochiTest system with minimum changes. +// Author: Maksim Lebedev + +// Function allows to prepare our tests after load document +addEventListener( + "load", + function (event) { + console.log("OnLoad external document"); + prepareTest(); + }, + false +); + +// Function allows to initialize prerequisites before testing +function prepareTest() { + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestCompleteLog(); + startTest(); +} + +function setImplicitPointerCapture(capture, callback) { + console.log("SET dom.w3c_pointer_events.implicit_capture as " + capture); + SpecialPowers.pushPrefEnv( + { + set: [["dom.w3c_pointer_events.implicit_capture", capture]], + }, + callback + ); +} + +var utils = SpecialPowers.Ci.nsIDOMWindowUtils; + +// Mouse Event Helper Object +var MouseEventHelper = (function () { + return { + MOUSE_ID: utils.DEFAULT_MOUSE_POINTER_ID, + PEN_ID: utils.DEFAULT_PEN_POINTER_ID, + // State + // TODO: Separate this to support mouse and pen simultaneously. + BUTTONS_STATE: utils.MOUSE_BUTTONS_NO_BUTTON, + + // Button + BUTTON_NONE: -1, // Used by test framework only. (replaced before sending) + BUTTON_LEFT: utils.MOUSE_BUTTON_LEFT_BUTTON, + BUTTON_MIDDLE: utils.MOUSE_BUTTON_MIDDLE_BUTTON, + BUTTON_RIGHT: utils.MOUSE_BUTTON_RIGHT_BUTTON, + + // Buttons + BUTTONS_NONE: utils.MOUSE_BUTTONS_NO_BUTTON, + BUTTONS_LEFT: utils.MOUSE_BUTTONS_LEFT_BUTTON, + BUTTONS_MIDDLE: utils.MOUSE_BUTTONS_MIDDLE_BUTTON, + BUTTONS_RIGHT: utils.MOUSE_BUTTONS_RIGHT_BUTTON, + BUTTONS_4TH: utils.MOUSE_BUTTONS_4TH_BUTTON, + BUTTONS_5TH: utils.MOUSE_BUTTONS_5TH_BUTTON, + + // Utils + computeButtonsMaskFromButton(aButton) { + // Since the range of button values is 0 ~ 2 (see nsIDOMWindowUtils.idl), + // we can use an array to find out the desired mask. + var mask = [ + this.BUTTONS_NONE, // -1 (MouseEventHelper.BUTTON_NONE) + this.BUTTONS_LEFT, // 0 + this.BUTTONS_MIDDLE, // 1 + this.BUTTONS_RIGHT, // 2 + ][aButton + 1]; + + ok(mask !== undefined, "Unrecognized button value caught!"); + return mask; + }, + + checkExitState() { + ok(!this.BUTTONS_STATE, "Mismatched mousedown/mouseup caught."); + }, + }; +})(); + +function createMouseEvent(aEventType, aParams) { + var eventObj = { type: aEventType }; + + // Default to mouse. + eventObj.inputSource = + aParams && "inputSource" in aParams + ? aParams.inputSource + : MouseEvent.MOZ_SOURCE_MOUSE; + // Compute pointerId + eventObj.id = + eventObj.inputSource === MouseEvent.MOZ_SOURCE_MOUSE + ? MouseEventHelper.MOUSE_ID + : MouseEventHelper.PEN_ID; + // Check or generate a |button| value. + var isButtonEvent = aEventType === "mouseup" || aEventType === "mousedown"; + + // Set |button| to the default value first. + eventObj.button = isButtonEvent + ? MouseEventHelper.BUTTON_LEFT + : MouseEventHelper.BUTTON_NONE; + + // |button| is passed, use and check it. + if (aParams && "button" in aParams) { + var hasButtonValue = aParams.button !== MouseEventHelper.BUTTON_NONE; + ok( + !isButtonEvent || hasButtonValue, + "Inappropriate |button| value caught." + ); + eventObj.button = aParams.button; + } + + // Generate a |buttons| value and update buttons state + var buttonsMask = MouseEventHelper.computeButtonsMaskFromButton( + eventObj.button + ); + switch (aEventType) { + case "mousedown": + MouseEventHelper.BUTTONS_STATE |= buttonsMask; // Set button flag. + break; + case "mouseup": + MouseEventHelper.BUTTONS_STATE &= ~buttonsMask; // Clear button flag. + break; + } + eventObj.buttons = MouseEventHelper.BUTTONS_STATE; + + // Replace the button value for mousemove events. + // Since in widget level design, even when no button is pressed at all, the + // value of WidgetMouseEvent.button is still 0, which is the same value as + // the one for mouse left button. + if (aEventType === "mousemove") { + eventObj.button = MouseEventHelper.BUTTON_LEFT; + } + return eventObj; +} + +// Helper function to send MouseEvent with different parameters +function sendMouseEvent(int_win, elemId, mouseEventType, params) { + var elem = int_win.document.getElementById(elemId); + if (elem) { + var rect = elem.getBoundingClientRect(); + var eventObj = createMouseEvent(mouseEventType, params); + + // Default to the center of the target element but we can still send to a + // position outside of the target element. + var offsetX = + params && "offsetX" in params ? params.offsetX : rect.width / 2; + var offsetY = + params && "offsetY" in params ? params.offsetY : rect.height / 2; + + console.log(elemId, eventObj); + synthesizeMouse(elem, offsetX, offsetY, eventObj, int_win); + } else { + is(!!elem, true, "Document should have element with id: " + elemId); + } +} + +// Helper function to send MouseEvent with position +function sendMouseEventAtPoint(aWindow, aLeft, aTop, aMouseEventType, aParams) { + var eventObj = createMouseEvent(aMouseEventType, aParams); + console.log(eventObj); + synthesizeMouseAtPoint(aLeft, aTop, eventObj, aWindow); +} + +// Touch Event Helper Object +var TouchEventHelper = { + // State + TOUCH_ID: utils.DEFAULT_TOUCH_POINTER_ID, + TOUCH_STATE: false, + + // Utils + checkExitState() { + ok(!this.TOUCH_STATE, "Mismatched touchstart/touchend caught."); + }, +}; + +// Helper function to send TouchEvent with different parameters +// TODO: Support multiple touch points to test more features such as +// PointerEvent.isPrimary and pinch-zoom. +function sendTouchEvent(int_win, elemId, touchEventType, params) { + var elem = int_win.document.getElementById(elemId); + if (elem) { + var rect = elem.getBoundingClientRect(); + var eventObj = { + type: touchEventType, + id: TouchEventHelper.TOUCH_ID, + }; + + // Update touch state + switch (touchEventType) { + case "touchstart": + TouchEventHelper.TOUCH_STATE = true; // Set touch flag. + break; + case "touchend": + case "touchcancel": + TouchEventHelper.TOUCH_STATE = false; // Clear touch flag. + break; + } + + // Default to the center of the target element but we can still send to a + // position outside of the target element. + var offsetX = + params && "offsetX" in params ? params.offsetX : rect.width / 2; + var offsetY = + params && "offsetY" in params ? params.offsetY : rect.height / 2; + + console.log(elemId, eventObj); + synthesizeTouch(elem, offsetX, offsetY, eventObj, int_win); + } else { + is(!!elem, true, "Document should have element with id: " + elemId); + } +} + +// Helper function to trigger drag and drop. +async function doDragAndDrop(int_win, srcElemId, destElemId, params = {}) { + params.srcElement = int_win.document.getElementById(srcElemId); + params.destElement = int_win.document.getElementById(destElemId); + params.srcWindow = int_win; + params.destWindow = int_win; + params.id = MouseEventHelper.MOUSE_ID; + // This is basically for android which has a larger drag threshold. + params.stepY = params.stepY || 25; + await synthesizePlainDragAndDrop(params); +} + +// Helper function to run Point Event test in a new tab. +function runTestInNewWindow(aFile) { + var testURL = + location.href.substring(0, location.href.lastIndexOf("/") + 1) + aFile; + var testWindow = window.open(testURL, "_blank"); + var testDone = false; + + // We start testing when receiving load event. Inject the mochitest helper js + // to the test case after DOM elements are constructed and before the load + // event is fired. + testWindow.addEventListener( + "DOMContentLoaded", + function () { + var e = testWindow.document.createElement("script"); + e.type = "text/javascript"; + e.src = + "../".repeat(aFile.split("/").length - 1) + + "mochitest_support_internal.js"; + testWindow.document.getElementsByTagName("head")[0].appendChild(e); + }, + { once: true } + ); + + window.addEventListener("message", function (aEvent) { + switch (aEvent.data.type) { + case "START": + // Update constants + MouseEventHelper.MOUSE_ID = aEvent.data.message.mouseId; + MouseEventHelper.PEN_ID = aEvent.data.message.penId; + TouchEventHelper.TOUCH_ID = aEvent.data.message.touchId; + + executeTest(testWindow); + break; + case "RESULT": + // Should not perform checking after SimpleTest.finish(). + if (!testDone) { + ok(aEvent.data.result, aEvent.data.message); + } + break; + case "FIN": + testDone = true; + MouseEventHelper.checkExitState(); + TouchEventHelper.checkExitState(); + testWindow.close(); + SimpleTest.finish(); + break; + } + }); +} diff --git a/dom/events/test/pointerevents/mochitest_support_internal.js b/dom/events/test/pointerevents/mochitest_support_internal.js new file mode 100644 index 0000000000..d46dd14f32 --- /dev/null +++ b/dom/events/test/pointerevents/mochitest_support_internal.js @@ -0,0 +1,125 @@ +// This file supports translating W3C tests +// to tests on auto MochiTest system with minimum changes. +// Author: Maksim Lebedev + +const PARENT_ORIGIN = "http://mochi.test:8888/"; + +// Since web platform tests don't check pointerId, we have to use some heuristic +// to test them. and thus pointerIds are send to mochitest_support_external.js +// before we start sending synthesized widget events. Here, we avoid using +// default values used in Gecko to insure everything works as expected. +const POINTER_MOUSE_ID = 7; +const POINTER_PEN_ID = 8; +const POINTER_TOUCH_ID = 9; // Extend for multiple touch points if needed. + +// Setup environment. +addListeners(document.getElementById("target0")); +addListeners(document.getElementById("target1")); + +// Setup communication between mochitest_support_external.js. +// Function allows to initialize prerequisites before testing +// and adds some callbacks to support mochitest system. +function resultCallback(aTestObj) { + var message = aTestObj.name + " ("; + message += "Get: " + JSON.stringify(aTestObj.status) + ", "; + message += "Expect: " + JSON.stringify(aTestObj.PASS) + ")"; + window.opener.postMessage( + { + type: "RESULT", + message, + result: aTestObj.status === aTestObj.PASS, + }, + PARENT_ORIGIN + ); +} + +add_result_callback(resultCallback); +add_completion_callback(() => { + window.opener.postMessage({ type: "FIN" }, PARENT_ORIGIN); +}); + +window.addEventListener("load", () => { + // Start testing. + var startMessage = { + type: "START", + message: { + mouseId: POINTER_MOUSE_ID, + penId: POINTER_PEN_ID, + touchId: POINTER_TOUCH_ID, + }, + }; + window.opener.postMessage(startMessage, PARENT_ORIGIN); +}); + +function addListeners(elem) { + if (!elem) { + return; + } + var All_Events = [ + "pointerdown", + "pointerup", + "pointercancel", + "pointermove", + "pointerover", + "pointerout", + "pointerenter", + "pointerleave", + "gotpointercapture", + "lostpointercapture", + ]; + All_Events.forEach(function (name) { + elem.addEventListener(name, function (event) { + console.log("(" + event.type + ")-(" + event.pointerType + ")"); + + // Perform checks only for trusted events. + if (!event.isTrusted) { + return; + } + + // Compute the desired event.pointerId from event.pointerType. + var pointerId = { + mouse: POINTER_MOUSE_ID, + pen: POINTER_PEN_ID, + touch: POINTER_TOUCH_ID, + }[event.pointerType]; + + // Compare the pointerId. + resultCallback({ + name: "Mismatched event.pointerId recieved.", + status: event.pointerId, + PASS: pointerId, + }); + }); + }); +} + +// mock the touchScrollInTarget to make the test work. +function touchScrollInTarget() { + return Promise.resolve(); +} + +// mock test_driver to make the test work. +function Actions() {} +Actions.prototype = { + addPointer() { + return this; + }, + pointerMove() { + return this; + }, + pointerDown() { + return this; + }, + pause() { + return this; + }, + pointerUp() { + return this; + }, + send() { + return Promise.resolve(); + }, +}; +const test_driver = { + Actions, +}; diff --git a/dom/events/test/pointerevents/pointerevent_utils.js b/dom/events/test/pointerevents/pointerevent_utils.js new file mode 100644 index 0000000000..ac5eaf61a1 --- /dev/null +++ b/dom/events/test/pointerevents/pointerevent_utils.js @@ -0,0 +1,60 @@ +// Get test filename for page being run in popup so errors are more useful +var testName = location.pathname.split("/").pop(); + +// Wrap test functions and pass to parent window +window.ok = function (a, msg) { + opener.ok(a, testName + ": " + msg); +}; + +window.is = function (a, b, msg) { + opener.is(a, b, testName + ": " + msg); +}; + +window.isnot = function (a, b, msg) { + opener.isnot(a, b, testName + ": " + msg); +}; + +window.todo = function (a, msg) { + opener.todo(a, testName + ": " + msg); +}; + +window.todo_is = function (a, b, msg) { + opener.todo_is(a, b, testName + ": " + msg); +}; + +window.todo_isnot = function (a, b, msg) { + opener.todo_isnot(a, b, testName + ": " + msg); +}; + +window.info = function (msg) { + opener.info(testName + ": " + msg); +}; + +// Override bits of SimpleTest so test files work stand-alone +var SimpleTest = SimpleTest || {}; + +SimpleTest.waitForExplicitFinish = function () { + dump("[POINTEREVENT] Starting " + testName + "\n"); +}; + +SimpleTest.finish = function () { + dump("[POINTEREVENT] Finishing " + testName + "\n"); + opener.nextTest(); +}; + +// Utility functions +function waitForEvent(aTarget, aEvent, aCallback) { + return new Promise(aResolve => { + aTarget.addEventListener( + aEvent, + e => { + ok(true, `got ${e.type} event on ${e.target.id}`); + if (aCallback) { + aCallback(e); + } + aResolve(); + }, + { once: true } + ); + }); +} diff --git a/dom/events/test/pointerevents/readme.md b/dom/events/test/pointerevents/readme.md new file mode 100644 index 0000000000..0cc0190979 --- /dev/null +++ b/dom/events/test/pointerevents/readme.md @@ -0,0 +1,9 @@ +Directory for Pointer Events Tests + +Latest Editor's Draft: https://w3c.github.io/pointerevents/ + +Latest W3C Technical Report: http://www.w3.org/TR/pointerevents/ + +Discussion forum for tests: http://lists.w3.org/Archives/Public/public-test-infra/ + +Test Assertion table: https://www.w3.org/wiki/PointerEvents/TestAssertions diff --git a/dom/events/test/pointerevents/test_bug1285128.html b/dom/events/test/pointerevents/test_bug1285128.html new file mode 100644 index 0000000000..534e265047 --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1285128.html @@ -0,0 +1,51 @@ + + + + + + Test for Bug 1285128 + + + + + +Mozilla Bug 1285128 +

+
+
+ + + diff --git a/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_1.html b/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_1.html new file mode 100644 index 0000000000..a02432f3b3 --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_1.html @@ -0,0 +1,30 @@ + + + + + Test for Bug 1293174 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_2.html b/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_2.html new file mode 100644 index 0000000000..2e5aaccccc --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_2.html @@ -0,0 +1,30 @@ + + + + + Test for Bug 1293174 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_bug1303704.html b/dom/events/test/pointerevents/test_bug1303704.html new file mode 100644 index 0000000000..ed8842997c --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1303704.html @@ -0,0 +1,135 @@ + + + + + + Test for Bug 1303704 + + + + + + + +Mozilla Bug 1303704 +

+Link 1 +
+
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+scroll
+
+
+ + + diff --git a/dom/events/test/pointerevents/test_bug1315862.html b/dom/events/test/pointerevents/test_bug1315862.html new file mode 100644 index 0000000000..92d61a518f --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1315862.html @@ -0,0 +1,66 @@ + + + + + + Test for Bug 1315862 + + + + + +

+ This is a test to check if pointer events are dispatched in the system group +

+ + + diff --git a/dom/events/test/pointerevents/test_bug1323158.html b/dom/events/test/pointerevents/test_bug1323158.html new file mode 100644 index 0000000000..96fd2de12e --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1323158.html @@ -0,0 +1,91 @@ + + + + + + This is a test to check if target and relatedTarget of mouse events are the same as pointer events + + + + + +

+ + + diff --git a/dom/events/test/pointerevents/test_bug1403055.html b/dom/events/test/pointerevents/test_bug1403055.html new file mode 100644 index 0000000000..8327fd147d --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1403055.html @@ -0,0 +1,90 @@ + + + + + + Test for Bug 1403055 + + + + + +Mozilla Bug 1403055 +

+
+
+
+ + + diff --git a/dom/events/test/pointerevents/test_bug1420589_1.html b/dom/events/test/pointerevents/test_bug1420589_1.html new file mode 100644 index 0000000000..8ecea7a28b --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1420589_1.html @@ -0,0 +1,105 @@ + + + + + + Test for Bug 1420589 + + + + + +Mozilla Bug 1420589 +

+ + + + + diff --git a/dom/events/test/pointerevents/test_bug1420589_2.html b/dom/events/test/pointerevents/test_bug1420589_2.html new file mode 100644 index 0000000000..2bfac2cdfc --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1420589_2.html @@ -0,0 +1,122 @@ + + + + + + Test for Bug 1420589 + + + + + +Mozilla Bug 1420589 +

+
+ + + + diff --git a/dom/events/test/pointerevents/test_bug1420589_3.html b/dom/events/test/pointerevents/test_bug1420589_3.html new file mode 100644 index 0000000000..9942591f64 --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1420589_3.html @@ -0,0 +1,115 @@ + + + + + + Test for Bug 1420589 + + + + + +Mozilla Bug 1420589 +

+
+ + + + diff --git a/dom/events/test/pointerevents/test_bug1697769.xhtml b/dom/events/test/pointerevents/test_bug1697769.xhtml new file mode 100644 index 0000000000..09efdb9826 --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1697769.xhtml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + +Mozilla Bug 1697769 +

+

+
+
+
+
diff --git a/dom/events/test/pointerevents/test_bug1725416.html b/dom/events/test/pointerevents/test_bug1725416.html new file mode 100644 index 0000000000..3cc4a6316f --- /dev/null +++ b/dom/events/test/pointerevents/test_bug1725416.html @@ -0,0 +1,37 @@ + + +Bug 1725416 + + + + + + + + +
+ + diff --git a/dom/events/test/pointerevents/test_bug968148.html b/dom/events/test/pointerevents/test_bug968148.html new file mode 100644 index 0000000000..e62d819934 --- /dev/null +++ b/dom/events/test/pointerevents/test_bug968148.html @@ -0,0 +1,46 @@ + + + + + Test for Bug 968148 + + + + + + + + diff --git a/dom/events/test/pointerevents/test_getCoalescedEvents.html b/dom/events/test/pointerevents/test_getCoalescedEvents.html new file mode 100644 index 0000000000..69eeac6919 --- /dev/null +++ b/dom/events/test/pointerevents/test_getCoalescedEvents.html @@ -0,0 +1,88 @@ + + + + + + Test for Bug 1303957 + + + + + +Mozilla Bug 1303957 +

+
+ + + diff --git a/dom/events/test/pointerevents/test_getCoalescedEvents_touch.html b/dom/events/test/pointerevents/test_getCoalescedEvents_touch.html new file mode 100644 index 0000000000..0df34efb30 --- /dev/null +++ b/dom/events/test/pointerevents/test_getCoalescedEvents_touch.html @@ -0,0 +1,111 @@ + + + + + + Test for Bug 1511231 + + + + + + +Mozilla Bug 1511231 +

+
+ + + diff --git a/dom/events/test/pointerevents/test_multiple_touches.html b/dom/events/test/pointerevents/test_multiple_touches.html new file mode 100644 index 0000000000..15202c3636 --- /dev/null +++ b/dom/events/test/pointerevents/test_multiple_touches.html @@ -0,0 +1,196 @@ + + + + + Test for Multiple Touches + + + + + +

+
+
+ + + diff --git a/dom/events/test/pointerevents/test_pointercapture_remove_iframe.html b/dom/events/test/pointerevents/test_pointercapture_remove_iframe.html new file mode 100644 index 0000000000..fca3a440bf --- /dev/null +++ b/dom/events/test/pointerevents/test_pointercapture_remove_iframe.html @@ -0,0 +1,80 @@ + + + + +Bug 1686037 + + + + + + +Mozilla Bug 1686037 +
+ + +
+
+
+ + diff --git a/dom/events/test/pointerevents/test_pointercapture_xorigin_iframe.html b/dom/events/test/pointerevents/test_pointercapture_xorigin_iframe.html new file mode 100644 index 0000000000..2bfb0e8ac1 --- /dev/null +++ b/dom/events/test/pointerevents/test_pointercapture_xorigin_iframe.html @@ -0,0 +1,55 @@ + + + +Test for pointer capture + + + + + +Test for pointer capture +
+
+
+
+ + diff --git a/dom/events/test/pointerevents/test_pointermove_drag_scrollbar.html b/dom/events/test/pointerevents/test_pointermove_drag_scrollbar.html new file mode 100644 index 0000000000..27ef2829ef --- /dev/null +++ b/dom/events/test/pointerevents/test_pointermove_drag_scrollbar.html @@ -0,0 +1,77 @@ + + + + + +Test for Bug 1509710 + + + + + + +Mozilla Bug 1509710 +

+
+
+
+ + + diff --git a/dom/events/test/pointerevents/test_remove_frame_when_got_pointer_capture.html b/dom/events/test/pointerevents/test_remove_frame_when_got_pointer_capture.html new file mode 100644 index 0000000000..790f2cdd55 --- /dev/null +++ b/dom/events/test/pointerevents/test_remove_frame_when_got_pointer_capture.html @@ -0,0 +1,166 @@ + + + + + Test for triggering popup by pointer events + + + + + +

+

+ + + diff --git a/dom/events/test/pointerevents/test_synthesized_touch.html b/dom/events/test/pointerevents/test_synthesized_touch.html new file mode 100644 index 0000000000..8a79303e74 --- /dev/null +++ b/dom/events/test/pointerevents/test_synthesized_touch.html @@ -0,0 +1,47 @@ + + +Test synthesized touch input + + + + + + +
+ + diff --git a/dom/events/test/pointerevents/test_trigger_fullscreen_by_pointer_events.html b/dom/events/test/pointerevents/test_trigger_fullscreen_by_pointer_events.html new file mode 100644 index 0000000000..abdf92831a --- /dev/null +++ b/dom/events/test/pointerevents/test_trigger_fullscreen_by_pointer_events.html @@ -0,0 +1,54 @@ + + + + + Test for triggering Fullscreen by pointer events + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_attributes_hoverable_pointers-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_attributes_hoverable_pointers-manual.html new file mode 100644 index 0000000000..557ee80c4f --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_attributes_hoverable_pointers-manual.html @@ -0,0 +1,53 @@ + + + + + Test pointerevent attributes for hoverable pointers + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_attributes_nohover_pointers-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_attributes_nohover_pointers-manual.html new file mode 100644 index 0000000000..f9fde4f92f --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_attributes_nohover_pointers-manual.html @@ -0,0 +1,26 @@ + + + + + Test pointerevent attributes for non-hoverable pointers + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_boundary_events_in_capturing-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_boundary_events_in_capturing-manual.html new file mode 100644 index 0000000000..24aeb6d9a6 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_boundary_events_in_capturing-manual.html @@ -0,0 +1,46 @@ + + + + + W3C pointerevent_boundary_events_in_capturing-manual.html in Mochitest form + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_change-touch-action-onpointerdown_touch-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_change-touch-action-onpointerdown_touch-manual.html new file mode 100644 index 0000000000..f95b16c850 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_change-touch-action-onpointerdown_touch-manual.html @@ -0,0 +1,39 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_constructor.html b/dom/events/test/pointerevents/test_wpt_pointerevent_constructor.html new file mode 100644 index 0000000000..058e32a967 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_constructor.html @@ -0,0 +1,26 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_drag_interaction-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_drag_interaction-manual.html new file mode 100644 index 0000000000..a05ee9557a --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_drag_interaction-manual.html @@ -0,0 +1,38 @@ + + + + + + Test for Bug 1669673 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_movementxy-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_movementxy-manual.html new file mode 100644 index 0000000000..3059f868b7 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_movementxy-manual.html @@ -0,0 +1,53 @@ + + + + + + Test for Bug 1399740 + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_multiple_primary_pointers_boundary_events-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_multiple_primary_pointers_boundary_events-manual.html new file mode 100644 index 0000000000..825e23857f --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_multiple_primary_pointers_boundary_events-manual.html @@ -0,0 +1,31 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_pointerId_scope-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerId_scope-manual.html new file mode 100644 index 0000000000..f52bf7fc20 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerId_scope-manual.html @@ -0,0 +1,27 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_pointercancel_touch-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_pointercancel_touch-manual.html new file mode 100644 index 0000000000..0adba4f756 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_pointercancel_touch-manual.html @@ -0,0 +1,30 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_after_pointercancel_touch-manual.html new file mode 100644 index 0000000000..53c897bcd0 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_after_pointercancel_touch-manual.html @@ -0,0 +1,30 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_pen-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_pen-manual.html new file mode 100644 index 0000000000..e4904780f6 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerleave_pen-manual.html @@ -0,0 +1,28 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_after_pointercancel_touch-manual.html new file mode 100644 index 0000000000..53cf765fb6 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_after_pointercancel_touch-manual.html @@ -0,0 +1,30 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_pen-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_pen-manual.html new file mode 100644 index 0000000000..6b41f6492b --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_pointerout_pen-manual.html @@ -0,0 +1,28 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_events_to_original_target-manual.html new file mode 100644 index 0000000000..049c41467f --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -0,0 +1,49 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_onpointercancel_touch-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_onpointercancel_touch-manual.html new file mode 100644 index 0000000000..eb39b0bee3 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_releasepointercapture_onpointercancel_touch-manual.html @@ -0,0 +1,30 @@ + + + + + + Test for Bug 1000870 + + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_pointerevent_sequence_at_implicit_release_on_drag-manual.html b/dom/events/test/pointerevents/test_wpt_pointerevent_sequence_at_implicit_release_on_drag-manual.html new file mode 100644 index 0000000000..40a6be2e71 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_pointerevent_sequence_at_implicit_release_on_drag-manual.html @@ -0,0 +1,27 @@ + + + + + W3C pointerevent_sequence_at_implicit_release_on_drag-manual.html in Mochitest form + + + + + + + + + diff --git a/dom/events/test/pointerevents/test_wpt_touch_action.html b/dom/events/test/pointerevents/test_wpt_touch_action.html new file mode 100644 index 0000000000..f2edbfb061 --- /dev/null +++ b/dom/events/test/pointerevents/test_wpt_touch_action.html @@ -0,0 +1,98 @@ + + + + + W3C pointerevents/*touch-action*.html tests in Mochitest form + + + + + + + + + diff --git a/dom/events/test/pointerevents/touch_action_helpers.js b/dom/events/test/pointerevents/touch_action_helpers.js new file mode 100644 index 0000000000..c46cf369a4 --- /dev/null +++ b/dom/events/test/pointerevents/touch_action_helpers.js @@ -0,0 +1,243 @@ +// Some common helpers + +function promiseTimeout(delay) { + return new Promise(resolve => { + setTimeout(resolve, delay); + }); +} + +function promiseTouchStart(element) { + return new Promise(resolve => { + element.addEventListener("touchstart", resolve, { + passive: true, + once: true, + }); + }); +} + +async function touchScrollRight(aSelector = "#target0", aX = 20, aY = 20) { + const target = document.querySelector(aSelector); + const touchStartPromise = promiseTouchStart(document.body); + const touchEndPromise = promiseTouchEnd(document.body); + dump("Synthesizing horizontal drag\n"); + await promiseNativePointerDrag(target, "touch", aX + 40, aY, -40, 0); + await touchStartPromise; + dump("Got touchstart from the horizontal drag\n"); + await touchEndPromise; + dump("Got touchend from the horizontal drag\n"); +} + +async function touchScrollDown(aSelector = "#target0", aX = 20, aY = 20) { + const target = document.querySelector(aSelector); + const touchStartPromise = promiseTouchStart(document.body); + const touchEndPromise = promiseTouchEnd(document.body); + dump("Synthesizing vertical drag\n"); + await promiseNativePointerDrag(target, "touch", aX, aY + 40, 0, -40); + await touchStartPromise; + dump("Got touchstart from the vertical drag\n"); + await touchEndPromise; + dump("Got touchend from the vertical drag\n"); +} + +async function tapCompleteAndWaitTestDone() { + let testDone = new Promise(resolve => { + add_completion_callback(resolve); + }); + + var button = document.getElementById("btnComplete"); + button.click(); + await testDone; +} + +function promiseResetScrollLeft(aSelector = "#target0") { + var target = document.querySelector(aSelector); + return new Promise(resolve => { + target.addEventListener("scroll", function onScroll() { + if (target.scrollLeft == 0) { + target.removeEventListener("scroll", onScroll); + resolve(); + } + }); + }); +} + +// The main body functions to simulate the input events required for the named test + +async function pointerevent_touch_action_auto_css_touch_manual() { + let testDone = new Promise(resolve => { + add_completion_callback(resolve); + }); + + await touchScrollRight(); + await promiseApzFlushedRepaints(); + await touchScrollDown(); + await testDone; +} + +async function pointerevent_touch_action_button_test_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + await touchScrollRight(); + let resetScrollLeftPromise = promiseResetScrollLeft(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + // Wait for resetting target0's scrollLeft to avoid the reset break the + // following scroll behaviors. + await resetScrollLeftPromise; + await touchScrollDown("#target0 > button"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > button"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_inherit_child_auto_child_none_touch_manual() { + await touchScrollDown("#target0 > div div"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > div div"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_inherit_child_none_touch_manual() { + await touchScrollDown("#target0 > div"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > div"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_inherit_child_pan_x_child_pan_x_touch_manual() { + await touchScrollDown("#target0 > div div"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > div div"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_inherit_child_pan_x_child_pan_y_touch_manual() { + await touchScrollDown("#target0 > div div"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > div div"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_inherit_highest_parent_none_touch_manual() { + let testDone = new Promise(resolve => { + add_completion_callback(resolve); + }); + + await touchScrollDown("#target0 > div"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > div"); + await testDone; +} + +async function pointerevent_touch_action_inherit_parent_none_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await touchScrollRight(); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_none_css_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await touchScrollRight(); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_pan_x_css_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await touchScrollRight(); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_pan_x_pan_y_pan_y_touch_manual() { + await touchScrollDown("#target0 > div div"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0 > div div"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_pan_x_pan_y_touch_manual() { + let testDone = new Promise(resolve => { + add_completion_callback(resolve); + }); + + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await touchScrollRight(); + await testDone; +} + +async function pointerevent_touch_action_pan_y_css_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await touchScrollRight(); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_span_test_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + await touchScrollRight(); + let resetScrollLeftPromise = promiseResetScrollLeft(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + // Wait for resetting target0's scrollLeft to avoid the reset break the + // following scroll behaviors. + await resetScrollLeftPromise; + await touchScrollDown("#testspan"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#testspan"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_svg_test_touch_manual() { + await touchScrollDown(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + await touchScrollRight(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + await touchScrollDown("#target0", 250, 250); + await promiseApzFlushedRepaints(); + await touchScrollRight("#target0", 250, 250); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +async function pointerevent_touch_action_table_test_touch_manual() { + await touchScrollDown("#row1"); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + await touchScrollRight("#row1"); + let resetScrollLeftPromise = promiseResetScrollLeft(); + await promiseApzFlushedRepaints(); + await promiseTimeout(2 * scrollReturnInterval); + // Wait for resetting target0's scrollLeft to avoid the reset break the + // following scroll behaviors. + await resetScrollLeftPromise; + await touchScrollDown("#cell3"); + await promiseApzFlushedRepaints(); + await touchScrollRight("#cell3"); + await promiseApzFlushedRepaints(); + await tapCompleteAndWaitTestDone(); +} + +// This the stuff that runs the appropriate body function above + +// eslint-disable-next-line no-eval +var test = eval(_ACTIVE_TEST_NAME.replace(/-/g, "_")); +waitUntilApzStable().then(test).then(subtestDone, subtestFailed); diff --git a/dom/events/test/pointerevents/wpt/compat/pointerevent_touch-action_two-finger_interaction-manual.html b/dom/events/test/pointerevents/wpt/compat/pointerevent_touch-action_two-finger_interaction-manual.html new file mode 100644 index 0000000000..3537e0e1e9 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/compat/pointerevent_touch-action_two-finger_interaction-manual.html @@ -0,0 +1,102 @@ + + + + Pointer Event: touch-action test for two-finger interaction + + + + + + + + + + + + +

Pointer Event: touch-action test for two-finger interaction

+

+

+ Tests that a two-finger pan gesture is cancelled in 'touch-action: pan-x pan-y' but is allowed in 'touch-action: pinch-zoom' +

+
    +
  1. Touch on Black with two fingers and drag both fingers down at same speed.
  2. +
  3. Tap on Done.
  4. +
  5. Touch on Grey with two fingers and drag both fingers down at same speed.
  6. +
  7. Tap on Done.
  8. +
+
+ +
+
+ + diff --git a/dom/events/test/pointerevents/wpt/html/pointerevent_drag_interaction-manual.html b/dom/events/test/pointerevents/wpt/html/pointerevent_drag_interaction-manual.html new file mode 100644 index 0000000000..1a80d239b8 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/html/pointerevent_drag_interaction-manual.html @@ -0,0 +1,103 @@ + + + Pointer Events interaction with drag and drop + + + + + + + + + +

Pointer Events interaction with drag and drop

+

+

+ Test Description: This test checks that the pointercancel (and if needed lostpointercapture) is dispatched when drag starts. +
    +
  1. Press down on the black square.
  2. +
  3. Move your pointer to purple square and release.
  4. +
  5. Repeat the first two steps.
  6. +
  7. Repeat the first two steps once again.
  8. +
  9. Repeat the first two steps once again.
  10. +
+ Test passes if the proper behavior of the events is observed. +

+
+
+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/idlharness.html b/dom/events/test/pointerevents/wpt/idlharness.html new file mode 100644 index 0000000000..a4ba4c35f5 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/idlharness.html @@ -0,0 +1,104 @@ + + +idlharness test + + + + + + + +
+dictionary PointerEventInit : MouseEventInit {
+    long      pointerId = 0;
+    double    width = 1;
+    double    height = 1;
+    float     pressure = 0;
+    float     tangentialPressure = 0;
+    long      tiltX = 0;
+    long      tiltY = 0;
+    long      twist = 0;
+    DOMString pointerType = "";
+    boolean   isPrimary = false;
+};
+
+[Constructor(DOMString type, optional PointerEventInit eventInitDict)]
+interface PointerEvent : MouseEvent {
+    readonly attribute long      pointerId;
+    readonly attribute double    width;
+    readonly attribute double    height;
+    readonly attribute float     pressure;
+    readonly attribute float     tangentialPressure;
+    readonly attribute long      tiltX;
+    readonly attribute long      tiltY;
+    readonly attribute long      twist;
+    readonly attribute DOMString pointerType;
+    readonly attribute boolean   isPrimary;
+};
+
+partial interface Element {
+    void    setPointerCapture(long pointerId);
+    void    releasePointerCapture(long pointerId);
+    boolean hasPointerCapture(long pointerId);
+};
+
+partial interface GlobalEventHandlers {
+    attribute EventHandler ongotpointercapture;
+    attribute EventHandler onlostpointercapture;
+    attribute EventHandler onpointerdown;
+    attribute EventHandler onpointermove;
+    attribute EventHandler onpointerup;
+    attribute EventHandler onpointercancel;
+    attribute EventHandler onpointerover;
+    attribute EventHandler onpointerout;
+    attribute EventHandler onpointerenter;
+    attribute EventHandler onpointerleave;
+};
+
+partial interface Navigator {
+    readonly attribute long maxTouchPoints;
+};
+
+ diff --git a/dom/events/test/pointerevents/wpt/pointerevent_attributes_hoverable_pointers-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_attributes_hoverable_pointers-manual.html new file mode 100644 index 0000000000..0922ae7448 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_attributes_hoverable_pointers-manual.html @@ -0,0 +1,143 @@ + + + + Pointer Events properties tests + + + + + + + + + +

Pointer Events hoverable pointer attributes test

+

+

+ Test Description: This test checks the properties of hoverable pointer events. If you are using hoverable pen don't leave the range of digitizer while doing the instructions. +
    +
  1. Move your pointer over the black square and click on it.
  2. +
  3. Then move it off the black square so that it disappears.
  4. +
  5. When red square appears move your pointer over the red square and click on it.
  6. +
  7. Then move it off the red square.
  8. +
+ + Test passes if the proper behavior of the events is observed. +

+
+ +
+
+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_attributes_nohover_pointers-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_attributes_nohover_pointers-manual.html new file mode 100644 index 0000000000..0fd7904ef0 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_attributes_nohover_pointers-manual.html @@ -0,0 +1,126 @@ + + + + Pointer Events properties tests + + + + + + + + + +

Pointer Events no-hover pointer attributes test

+

+

+ Test Description: This test checks the properties of pointer events that do not support hover. +
    +
  1. Tap the black square.
  2. +
  3. Then move it off the black square so that it disappears.
  4. +
  5. When the red square appears tap on that as well.
  6. +
+ + Test passes if the proper behavior of the events is observed. +

+
+ +
+
+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_boundary_events_in_capturing-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_boundary_events_in_capturing-manual.html new file mode 100644 index 0000000000..0de4d55ed1 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_boundary_events_in_capturing-manual.html @@ -0,0 +1,97 @@ + + + + Pointer Events boundary events in capturing tests + + + + + + + + + +

Pointer Events boundary events in capturing

+

+

+ Test Description: This test checks the boundary events of pointer events while the capturing changes. If you are using hoverable pen don't leave the range of digitizer while doing the instructions. +
    +
  1. Move your pointer over the black square
  2. +
  3. Press down the pointer (i.e. press left button with mouse or touch the screen with finger or pen).
  4. +
  5. Drag the pointer within the black square.
  6. +
  7. Release the pointer.
  8. +
+ + Test passes if the proper behavior of the events is observed. +

+
+
+
Do not hover over or touch this element.
+
+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_change-touch-action-onpointerdown_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_change-touch-action-onpointerdown_touch-manual.html new file mode 100644 index 0000000000..04d56cb7a5 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_change-touch-action-onpointerdown_touch-manual.html @@ -0,0 +1,135 @@ + + + + Change touch-action on pointerdown + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Press and hold your touch. Try to scroll text in any direction. + Then release your touch and try to scroll again. Expected: no panning. +

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ +

touch-action: auto to none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_constructor.html b/dom/events/test/pointerevents/wpt/pointerevent_constructor.html new file mode 100644 index 0000000000..b2a779d1f7 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_constructor.html @@ -0,0 +1,106 @@ + + + + PointerEvent: Constructor test + + + + + + + + +

PointerEvent: Dispatch custom event

+

Test Description: This test checks if PointerEvent constructor works properly using synthetic pointerover and pointerout events. For valid results, this test must be run without generating real (trusted) pointerover or pointerout events on the black rectangle below.

+
+ +
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_multiple_primary_pointers_boundary_events-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_multiple_primary_pointers_boundary_events-manual.html new file mode 100644 index 0000000000..eb758c7073 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_multiple_primary_pointers_boundary_events-manual.html @@ -0,0 +1,145 @@ + + + + Pointer Event: Boundary compatibility events for multiple primary pointers + + + + + + + + + + + +

Pointer Event: Boundary compatibility events for multiple primary pointers

+

+ When more than one primary pointers are active, each will have an independent sequence of pointer boundary events but the compatibilty mouse boundary events have their own sequence. +

+ Instruction: +
    +
  1. Move the mouse directly into Target0 (without going through Target1), and then leave the mouse there unmoved.
  2. +
  3. Tap directly on Target1 with a finger or a stylus, and then lift the finger/stylus off the screen/digitizer without crossing Target1 boundary.
  4. +
  5. Move the mouse into Target0 (if not there already) and move inside it.
  6. +
  7. Click Done (without passing over Target1).
  8. +
+
+ Done +
+
+ Target0 +
+
+ Target1 +
+
+

The following pointer types were detected: .

+

The following events were logged: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_pointerId_scope-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_pointerId_scope-manual.html new file mode 100644 index 0000000000..3640cb6f6b --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_pointerId_scope-manual.html @@ -0,0 +1,82 @@ + + + + + Pointer Events pointerdown tests + + + + + + + + + +

Pointer Events pointerdown tests

+ Complete the following actions: +
    +
  1. Start with your pointing device outside of black box, then move it into black box. If using touch just press in black box and don't release. +
  2. Move your pointing device into purple box (without leaving the digitizer range if you are using hover supported pen or without releasing touch if using touch). Then move it out of the purple box. +
+
+
+ +
+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_pointercancel_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_pointercancel_touch-manual.html new file mode 100644 index 0000000000..70a65eeb5c --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_pointercancel_touch-manual.html @@ -0,0 +1,77 @@ + + + + PointerCancel - touch + + + + + + + + +

pointercancel test

+

Warning: this test works properly only for devices that have touchscreen

+

+ Test Description: This test checks if pointercancel event triggers. +

Start touch over the black rectangle and then move your finger to scroll the page.

+

+

+

+ +

Pointer Events pointercancel Tests

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_pointerleave_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_pointerleave_after_pointercancel_touch-manual.html new file mode 100644 index 0000000000..56be26549f --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_pointerleave_after_pointercancel_touch-manual.html @@ -0,0 +1,66 @@ + + + + pointerleave after pointercancel + + + + + + + + +

pointerleave after pointercancel

+

Test Description: This test checks if pointerleave event triggers after pointercancel. Start touch on the black rectangle and move your touch to scroll in any direction.

+

Note: this test is for touch devices only

+
+ +

Pointer Events pointerleave tests

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_pointerleave_pen-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_pointerleave_pen-manual.html new file mode 100644 index 0000000000..38a2f69792 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_pointerleave_pen-manual.html @@ -0,0 +1,58 @@ + + + + Pointer Event: Dispatch pointerleave (pen). + + + + + + + + + + + + +

Pointer Event: Dispatch pointerleave (pen)

+

+ Test Description: + When a pointing device that supports hover (pen stylus) leaves the range of the digitizer while over an element, the pointerleave event must be dispatched. +

+
+
+ Use a pen to hover over then lift up away from this element. +
+
+

Test complete: Scroll to Summary to view Pass/Fail Results.

+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_pointerout_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_pointerout_after_pointercancel_touch-manual.html new file mode 100644 index 0000000000..1888591a7c --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_pointerout_after_pointercancel_touch-manual.html @@ -0,0 +1,67 @@ + + + + pointerout + + + + + + + + +

pointerout

+

Test Description: This test checks if pointerout event triggers after pointercancel. Start touch on the black rectangle and move your touch to scroll in any direction.

+

Note: this test is for touch devices only

+
+ +

Pointer Events pointerout tests

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_pointerout_pen-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_pointerout_pen-manual.html new file mode 100644 index 0000000000..3973948c16 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_pointerout_pen-manual.html @@ -0,0 +1,57 @@ + + + + pointerout + + + + + + + + +

pointerout

+

Test Description: This test checks if pointerout event triggers for pen. Place your pen over the black rectangle and then pull the pen out of the digitizer's detectable range.

+

Note: this test is for devices that support hover - for pen only

+
+ +

Pointer Events pointerout tests

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_events_to_original_target-manual.html new file mode 100644 index 0000000000..3386fafb5a --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_events_to_original_target-manual.html @@ -0,0 +1,137 @@ + + + + Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms + + + + + + + + + + + +

+
+

Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms

+

+ Test Description: + Use your pointer and press down in the black box. Then move around in the box and release your pointer. + After invoking the releasePointerCapture method on an element, subsequent events for the specified + pointer must follow normal hit testing mechanisms for determining the event target. +

+
+
+
+
+

Test complete: Scroll to Summary to view Pass/Fail Results.

+

The following pointer types were detected: .

+

Refresh the page to run the tests again with a different pointer type.

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_onpointercancel_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_onpointercancel_touch-manual.html new file mode 100644 index 0000000000..105e3b5a97 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_releasepointercapture_onpointercancel_touch-manual.html @@ -0,0 +1,71 @@ + + + + Release capture on pointercancel + + + + + + + +

Pointer Events Capture Test - release capture on pointercancel

+

+ Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions: +
    +
  1. Touch black rectangle and do not release your touch +
  2. Move your touch to scroll the page. "lostpointercapture" should be logged inside of the black rectangle immediately after "pointercancel" +
+

+ Test passes if the proper behavior of the events is observed. +
+ + +

Pointer Events Capture Test

+
+

Test complete: Scroll to Summary to view Pass/Fail Results.

+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_click-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_click-manual.html new file mode 100644 index 0000000000..274f9a435b --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_click-manual.html @@ -0,0 +1,83 @@ + + + + Pointer Event: Event sequence at implicit release on click + + + + + + + + + + + +

Pointer Event: Event sequence at implicit release on click

+

+

+ When a captured pointer is implicitly released after a click, the boundary events should follow the lostpointercapture event. +

+
    +
  1. Click or tap on Black.
  2. +
  3. Click or tap on Green.
  4. +
+
+
+
+

The following pointer types were detected: .

+

The following events were logged: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_drag-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_drag-manual.html new file mode 100644 index 0000000000..7b8e39b94d --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_sequence_at_implicit_release_on_drag-manual.html @@ -0,0 +1,84 @@ + + + + Pointer Event: Event sequence at implicit release on drag + + + + + + + + + + + +

Pointer Event: Event sequence at implicit release on drag

+

+

+ When a captured pointer is implicitly released after a drag, the boundary events should follow the lostpointercapture event. +

+
    +
  1. Drag quickly down starting on Black.
  2. +
  3. Click or tap on Green.
  4. +
+
+
+
+

The following pointer types were detected: .

+

The following events were logged: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_styles.css b/dom/events/test/pointerevents/wpt/pointerevent_styles.css new file mode 100644 index 0000000000..1ee3b0b396 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_styles.css @@ -0,0 +1,112 @@ +#innerFrame { +position: absolute; +top: 300px; +left: 200px; +height: 100px; +width: 100px; +} + +.spacer { +height: 100px; +} + +#square1 { +top: 330px; +left: 150px; +background: black; +} + +#square2 { +top: 50px; +left: 30px; +visibility: hidden; +background: red; +} + +.square { +height: 20px; +width: 20px; +position: absolute; +padding: 0px; +} + +#target0 { +background: black; +color: white; +white-space: nowrap; +overflow-y: auto; +overflow-x: auto; +} + +#target1 { +background: purple; +color: white; +white-space: nowrap; +overflow-y: auto; +overflow-x: auto; +} + +#scrollTarget { + background: darkblue; +} + +.touchActionNone { +touch-action: none; +} + +#innerframe { +width: 90%; +margin: 10px; +margin-left: 10%; +height: 200px; +} + +.scroller { +width: 700px; +height: 430px; +margin: 20px; +overflow: auto; +background: black; +} + +.scroller > div { +height: 1000px; +width: 1000px; +color: white; +} + +.scroller > div div { +height: 100%; +width: 100%; +color: white; +} + +div { +margin: 0em; +padding: 2em; +} + +#complete-notice { +background: #afa; +border: 1px solid #0a0; +display: none; +} + +#pointertype-log { +font-weight: bold; +} + +#event-log { +font-weight: bold; +} + +#listener { +background: orange; +border: 1px solid orange; +position: absolute; +top: -100px; +} + +body.scrollable { +min-height: 5000px; +} diff --git a/dom/events/test/pointerevents/wpt/pointerevent_support.js b/dom/events/test/pointerevents/wpt/pointerevent_support.js new file mode 100644 index 0000000000..cd3c799f73 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_support.js @@ -0,0 +1,333 @@ +var All_Pointer_Events = [ + "pointerdown", + "pointerup", + "pointercancel", + "pointermove", + "pointerover", + "pointerout", + "pointerenter", + "pointerleave", + "gotpointercapture", + "lostpointercapture", +]; + +// Check for conformance to PointerEvent interface +// TA: 1.1, 1.2, 1.6, 1.7, 1.8, 1.9, 1.10, 1.11, 1.12, 1.13 +function check_PointerEvent(event, testNamePrefix) { + if (testNamePrefix === undefined) { + testNamePrefix = ""; + } + + // Use expectedPointerType if set otherwise just use the incoming event pointerType in the test name. + var pointerTestName = + testNamePrefix + + " " + + (expectedPointerType == null ? event.pointerType : expectedPointerType) + + " " + + event.type; + + if (expectedPointerType != null) { + test(function () { + assert_equals( + event.pointerType, + expectedPointerType, + "pointerType should be the one specified in the test page." + ); + }, pointerTestName + " event pointerType is correct."); + } + + test(function () { + assert_true( + event instanceof event.target.ownerDocument.defaultView.PointerEvent, + "event is a PointerEvent event" + ); + }, pointerTestName + " event is a PointerEvent event"); + + // Check attributes for conformance to WebIDL: + // * attribute exists + // * has proper type + // * if the attribute is "readonly", it cannot be changed + // TA: 1.1, 1.2 + var idl_type_check = { + long(v) { + return typeof v === "number" && Math.round(v) === v; + }, + float(v) { + return typeof v === "number"; + }, + string(v) { + return typeof v === "string"; + }, + boolean(v) { + return typeof v === "boolean"; + }, + }; + [ + ["readonly", "long", "pointerId"], + ["readonly", "float", "width"], + ["readonly", "float", "height"], + ["readonly", "float", "pressure"], + ["readonly", "long", "tiltX"], + ["readonly", "long", "tiltY"], + ["readonly", "string", "pointerType"], + ["readonly", "boolean", "isPrimary"], + ["readonly", "long", "detail", 0], + ].forEach(function (attr) { + var readonly = attr[0]; + var type = attr[1]; + var name = attr[2]; + var value = attr[3]; + + // existence check + test(function () { + assert_true( + name in event, + name + " attribute in " + event.type + " event" + ); + }, pointerTestName + "." + name + " attribute exists"); + + // readonly check + if (readonly === "readonly") { + test(function () { + assert_readonly( + event.type, + name, + event.type + "." + name + " cannot be changed" + ); + }, pointerTestName + "." + name + " is readonly"); + } + + // type check + test(function () { + assert_true( + idl_type_check[type](event[name]), + name + " attribute of type " + type + ); + }, pointerTestName + + "." + + name + + " IDL type " + + type + + " (JS type was " + + typeof event[name] + + ")"); + + // value check if defined + if (value != undefined) { + test(function () { + assert_equals(event[name], value, name + " attribute value"); + }, pointerTestName + "." + name + " value is " + value + "."); + } + }); + + // Check the pressure value + // TA: 1.6, 1.7, 1.8 + test(function () { + // TA: 1.6 + assert_greater_than_equal( + event.pressure, + 0, + "pressure is greater than or equal to 0" + ); + assert_less_than_equal( + event.pressure, + 1, + "pressure is less than or equal to 1" + ); + + if (event.type === "pointerup") { + assert_equals(event.pressure, 0, "pressure is 0 during pointerup"); + } + + // TA: 1.7, 1.8 + if (event.pointerType === "mouse") { + if (event.buttons === 0) { + assert_equals( + event.pressure, + 0, + "pressure is 0 for mouse with no buttons pressed" + ); + } else { + assert_equals( + event.pressure, + 0.5, + "pressure is 0.5 for mouse with a button pressed" + ); + } + } + }, pointerTestName + ".pressure value is valid"); + + // Check mouse-specific properties + if (event.pointerType === "mouse") { + // TA: 1.9, 1.10, 1.13 + test(function () { + assert_equals(event.width, 1, "width of mouse should be 1"); + assert_equals(event.height, 1, "height of mouse should be 1"); + assert_equals(event.tiltX, 0, event.type + ".tiltX is 0 for mouse"); + assert_equals(event.tiltY, 0, event.type + ".tiltY is 0 for mouse"); + assert_true(event.isPrimary, event.type + ".isPrimary is true for mouse"); + }, pointerTestName + " properties for pointerType = mouse"); + // Check properties for pointers other than mouse + } +} + +function showPointerTypes() { + var complete_notice = document.getElementById("complete-notice"); + var pointertype_log = document.getElementById("pointertype-log"); + var pointertypes = Object.keys(detected_pointertypes); + pointertype_log.innerHTML = pointertypes.length + ? pointertypes.join(",") + : "(none)"; + complete_notice.style.display = "block"; +} + +function showLoggedEvents() { + var event_log_elem = document.getElementById("event-log"); + event_log_elem.innerHTML = event_log.length ? event_log.join(", ") : "(none)"; + + var complete_notice = document.getElementById("complete-notice"); + complete_notice.style.display = "block"; +} + +function log(msg, el) { + if (++count > 10) { + count = 0; + el.innerHTML = " "; + } + el.innerHTML = msg + "; " + el.innerHTML; +} + +function failOnScroll() { + assert_true(false, "scroll received while shouldn't"); +} + +function updateDescriptionNextStep() { + document.getElementById("desc").innerHTML = + "Test Description: Try to scroll text RIGHT."; +} + +function updateDescriptionComplete() { + document.getElementById("desc").innerHTML = "Test Description: Test complete"; +} + +function updateDescriptionSecondStepTouchActionElement( + target, + scrollReturnInterval +) { + window.setTimeout(function () { + objectScroller(target, "up", 0); + }, scrollReturnInterval); + document.getElementById("desc").innerHTML = + "Test Description: Try to scroll element RIGHT moving your outside of the red border"; +} + +function updateDescriptionThirdStepTouchActionElement( + target, + scrollReturnInterval, + callback = null +) { + window.setTimeout(function () { + objectScroller(target, "left", 0); + if (callback) { + callback(); + } + }, scrollReturnInterval); + document.getElementById("desc").innerHTML = + "Test Description: Try to scroll element DOWN then RIGHT starting your touch inside of the element. Then tap complete button"; +} + +function updateDescriptionFourthStepTouchActionElement( + target, + scrollReturnInterval +) { + document.getElementById("desc").innerHTML = + "Test Description: Try to scroll element RIGHT starting your touch inside of the element"; +} + +function objectScroller(target, direction, value) { + if (direction == "up") { + target.scrollTop = 0; + } else if (direction == "left") { + target.scrollLeft = 0; + } +} + +function sPointerCapture(e) { + try { + target0.setPointerCapture(e.pointerId); + } catch (ex) {} +} + +function rPointerCapture(e) { + try { + captureButton.value = "Set Capture"; + target0.releasePointerCapture(e.pointerId); + } catch (ex) {} +} + +var globalPointerEventTest = null; +var expectedPointerType = null; +const ALL_POINTERS = ["mouse", "touch", "pen"]; +const HOVERABLE_POINTERS = ["mouse", "pen"]; +const NOHOVER_POINTERS = ["touch"]; + +function MultiPointerTypeTest(testName, types) { + this.testName = testName; + this.types = types; + this.currentTypeIndex = 0; + this.currentTest = null; + this.createNextTest(); +} + +MultiPointerTypeTest.prototype.skip = function () { + var prevTest = this.currentTest; + this.createNextTest(); + prevTest.timeout(); +}; + +MultiPointerTypeTest.prototype.done = function () { + var prevTest = this.currentTest; + this.createNextTest(); + if (prevTest != null) { + prevTest.done(); + } +}; + +MultiPointerTypeTest.prototype.step = function (stepFunction) { + this.currentTest.step(stepFunction); +}; + +MultiPointerTypeTest.prototype.createNextTest = function () { + if (this.currentTypeIndex < this.types.length) { + var pointerTypeDescription = document.getElementById( + "pointerTypeDescription" + ); + document.getElementById("pointerTypeDescription").innerHTML = + "Follow the test instructions with " + + this.types[this.currentTypeIndex] + + ". If you don't have the device skip it."; + this.currentTest = async_test( + this.types[this.currentTypeIndex] + " " + this.testName + ); + expectedPointerType = this.types[this.currentTypeIndex]; + this.currentTypeIndex++; + } else { + document.getElementById("pointerTypeDescription").innerHTML = ""; + } + resetTestState(); +}; + +function setup_pointerevent_test(testName, supportedPointerTypes) { + return (globalPointerEventTest = new MultiPointerTypeTest( + testName, + supportedPointerTypes + )); +} + +function checkPointerEventType(event) { + assert_equals( + event.pointerType, + expectedPointerType, + "pointerType should be the same as the requested device." + ); +} diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-auto-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-auto-css_touch-manual.html new file mode 100644 index 0000000000..f5e9d12c35 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-auto-css_touch-manual.html @@ -0,0 +1,129 @@ + + + + touch-action: auto + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll text DOWN. Wait for description update. Expected: pan enabled

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ +

touch-action: auto

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-button-test_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-button-test_touch-manual.html new file mode 100644 index 0000000000..c7c5d9a440 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-button-test_touch-manual.html @@ -0,0 +1,110 @@ + + + + Button touch-action test + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll black element DOWN moving your touch outside of the red border. Wait for description update.

+

Note: this test is for touch only

+
+ +
+
+ + + +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-illegal.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-illegal.html new file mode 100644 index 0000000000..5fe6179840 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-illegal.html @@ -0,0 +1,67 @@ + + + + touch-action: illegal + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Test will automatically check behaviour of following combinations: 'pan-x none', 'pan-y none', 'auto none'

+
+
+
+ +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html new file mode 100644 index 0000000000..dcea283750 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html @@ -0,0 +1,117 @@ + + + + touch-action: parent > child: auto > child: none + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT inside blue rectangle. Tap Complete button under the rectangle when done. Expected: no panning.

+

Note: this test is for touch-devices only

+
+
+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+
+ + +

behaviour: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-none_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-none_touch-manual.html new file mode 100644 index 0000000000..16e42954e5 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-none_touch-manual.html @@ -0,0 +1,112 @@ + + + + touch-action: child: none + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT inside blue rectangle. Tap Complete button under the rectangle when done. Expected: no panning

+

Note: this test is for touch-devices only

+
+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+ + +

behaviour: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html new file mode 100644 index 0000000000..c75d067e44 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html @@ -0,0 +1,112 @@ + + + + touch-action: parent > child: pan-x > child: pan-x + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT inside blue rectangle. Tap Complete button under the rectangle when done. Expected: only pans in x direction.

+

Note: this test is for touch-devices only

+
+
+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+
+ + +

behaviour: pan-x

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html new file mode 100644 index 0000000000..d420cc56c7 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html @@ -0,0 +1,117 @@ + + + + touch-action: parent > child: pan-x > child: pan-y + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT inside blue rectangle. Tap Complete button under the rectangle when done. Expected: no panning/zooming/etc.

+

Note: this test is for touch-devices only

+
+
+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+
+ + +

behaviour: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html new file mode 100644 index 0000000000..d87d2b3a34 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html @@ -0,0 +1,133 @@ + + + + touch-action: parent: none + two embedded children + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll text DOWN inside blue rectangle. Wait for description update. Expected: pan enabled

+

Note: this test is for touch-devices only

+
+
+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+
+ +

behaviour: auto

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_parent-none_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_parent-none_touch-manual.html new file mode 100644 index 0000000000..5e674a14da --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-inherit_parent-none_touch-manual.html @@ -0,0 +1,112 @@ + + + + touch-action: inherit from parent: none + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT inside blue rectangle. Tap Complete button under the rectangle when done. Expected: no panning

+

Note: this test is for touch-devices only

+
+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+ + +

behaviour: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-keyboard-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-keyboard-manual.html new file mode 100644 index 0000000000..3fef3f646f --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-keyboard-manual.html @@ -0,0 +1,124 @@ + + + + touch-action: keyboard + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Press DOWN ARROW key. Wait for description update. Expected: pan enabled

+

Note: this test is for keyboard only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ +

touch-action: none

+
+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-mouse-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-mouse-manual.html new file mode 100644 index 0000000000..fcc8584515 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-mouse-manual.html @@ -0,0 +1,130 @@ + + + + touch-action: mouse + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll text down using mouse (use mouse wheel or click on the scrollbar). Wait for description update.

+

Note: this test is for mouse only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-none-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-none-css_touch-manual.html new file mode 100644 index 0000000000..dec694f3ec --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-none-css_touch-manual.html @@ -0,0 +1,111 @@ + + + + touch-action: none + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: no panning/zooming/etc.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-down-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-down-css_touch-manual.html new file mode 100644 index 0000000000..16e1cb2fab --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-down-css_touch-manual.html @@ -0,0 +1,114 @@ + + + + touch-action: pan-down + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element UP (drag down), then RIGHT (drag left), then DOWN (drag up). Tap Complete button under the rectangle when done. Expected: only pans in down direction.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: pan-down

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-left-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-left-css_touch-manual.html new file mode 100644 index 0000000000..53fd2de138 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-left-css_touch-manual.html @@ -0,0 +1,114 @@ + + + + touch-action: pan-left + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN (drag up), then RIGHT (drag left), then LEFT (drag right). Tap Complete button under the rectangle when done. Expected: only pans in left direction.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: pan-left

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-right-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-right-css_touch-manual.html new file mode 100644 index 0000000000..53bbac65ec --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-right-css_touch-manual.html @@ -0,0 +1,114 @@ + + + + touch-action: pan-right + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN (drag up), then LEFT (drag right), then RIGHT (drag left). Tap Complete button under the rectangle when done. Expected: only pans in right direction.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: pan-right

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-up-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-up-css_touch-manual.html new file mode 100644 index 0000000000..0902700d2d --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-up-css_touch-manual.html @@ -0,0 +1,114 @@ + + + + touch-action: pan-up + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN (drag up), then RIGHT (drag left), then UP (drag down). Tap Complete button under the rectangle when done. Expected: only pans in up direction.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: pan-up

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-css_touch-manual.html new file mode 100644 index 0000000000..e757baec6b --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-css_touch-manual.html @@ -0,0 +1,106 @@ + + + + touch-action: pan-x + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: only pans in x direction.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: pan-x

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html new file mode 100644 index 0000000000..e2a4386b27 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html @@ -0,0 +1,111 @@ + + + + touch-action: parent > child: pan-x pan-y > child: pan-y + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT inside blue rectangle. Tap Complete button under the rectangle when done. Expected: only pans in y direction.

+

Note: this test is for touch-devices only

+
+
+
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+
+
+ + +

behaviour: pan-y

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y_touch-manual.html new file mode 100644 index 0000000000..0c900ff740 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-x-pan-y_touch-manual.html @@ -0,0 +1,126 @@ + + + + touch-action: pan-x pan-y + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll text DOWN. Wait for description update. Expected: pan enabled

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ +

touch-action: pan-x pan-y

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-y-css_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-y-css_touch-manual.html new file mode 100644 index 0000000000..4ad39ecc83 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-pan-y-css_touch-manual.html @@ -0,0 +1,106 @@ + + + + touch-action: pan-y + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: only pans in y direction.

+

Note: this test is for touch-devices only

+
+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem + nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. + Ut wisis enim ad minim veniam, quis nostrud exerci tution ullamcorper suscipit + lobortis nisl ut aliquip ex ea commodo consequat. +

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+

Lorem ipsum dolor sit amet...

+
+ + +

touch-action: pan-y

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-span-test_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-span-test_touch-manual.html new file mode 100644 index 0000000000..61f0e8d329 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-span-test_touch-manual.html @@ -0,0 +1,114 @@ + + + + Span touch-action test + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll black element DOWN moving your touch outside of the red border. Wait for description update.

+

Note: this test is for touch only

+
+ + Test span + +
+ + + +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + \ No newline at end of file diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-svg-test_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-svg-test_touch-manual.html new file mode 100644 index 0000000000..e9dc9d78ee --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-svg-test_touch-manual.html @@ -0,0 +1,122 @@ + + + + SVG test + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll black element DOWN moving your touch outside of the red border. Wait for description update.

+

Note: this test is for touch only

+
+ + + Sorry, your browser does not support inline SVG. + +
+
+ + +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-table-test_touch-manual.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-table-test_touch-manual.html new file mode 100644 index 0000000000..17d5a29575 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-table-test_touch-manual.html @@ -0,0 +1,145 @@ + + + + Table touch-action test + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Try to scroll element DOWN starting your touch over the 1st Row. Wait for description update.

+

Note: this test is for touch only

+
+ + + + + +
The caption, first row element, and cell 3 have touch-action: none.
Header 1 Cell 1 Cell 2
Header 2 Cell 3 Cell 4
Header 3 Cell 5 Cell 6
+
+
+ + + +

touch-action: none

+
+

The following pointer types were detected: .

+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerevent_touch-action-verification.html b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-verification.html new file mode 100644 index 0000000000..7800f2c9da --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerevent_touch-action-verification.html @@ -0,0 +1,91 @@ + + + + touch-action: basic verification + + + + + + + + + +

Pointer Events touch-action attribute support

+

Test Description: Test will automatically check parsing behaviour of various touch-action combinations.

+ +

touch-action: basic verification

+
+

The following pointer types were detected: .

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/dom/events/test/pointerevents/wpt/pointerlock/pointerevent_movementxy-manual.html b/dom/events/test/pointerevents/wpt/pointerlock/pointerevent_movementxy-manual.html new file mode 100644 index 0000000000..5b0edd3c61 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerlock/pointerevent_movementxy-manual.html @@ -0,0 +1,99 @@ + + + + Pointer Events properties tests + + + + + + + + + + +

Pointer Events movementX/Y attribute test

+

+

+ Test Description: This test checks the properties of pointer events that do not support hover. +
    +
  1. Press down on the black square.
  2. +
  3. Move your pointer slowly along a straight line to the red square.
  4. +
  5. Release the pointer when you are over the red square.
  6. +
+ + Test passes if the proper behavior of the events is observed. +

+
+
+
+ +
+
+ + + diff --git a/dom/events/test/pointerevents/wpt/pointerlock/resources/pointerevent_movementxy-iframe.html b/dom/events/test/pointerevents/wpt/pointerlock/resources/pointerevent_movementxy-iframe.html new file mode 100644 index 0000000000..627af3b61c --- /dev/null +++ b/dom/events/test/pointerevents/wpt/pointerlock/resources/pointerevent_movementxy-iframe.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/dom/events/test/pointerevents/wpt/resources/pointerevent_attributes_hoverable_pointers-iframe.html b/dom/events/test/pointerevents/wpt/resources/pointerevent_attributes_hoverable_pointers-iframe.html new file mode 100644 index 0000000000..5e55868282 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/resources/pointerevent_attributes_hoverable_pointers-iframe.html @@ -0,0 +1,10 @@ + + + + + + + +
+ + diff --git a/dom/events/test/pointerevents/wpt/resources/pointerevent_pointerId_scope-iframe.html b/dom/events/test/pointerevents/wpt/resources/pointerevent_pointerId_scope-iframe.html new file mode 100644 index 0000000000..ab33560b35 --- /dev/null +++ b/dom/events/test/pointerevents/wpt/resources/pointerevent_pointerId_scope-iframe.html @@ -0,0 +1,35 @@ + + + + + Pointer Events pointerdown tests + + + + + +
+
+ + diff --git a/dom/events/test/test_DataTransferItemList.html b/dom/events/test/test_DataTransferItemList.html new file mode 100644 index 0000000000..1d093c8cf7 --- /dev/null +++ b/dom/events/test/test_DataTransferItemList.html @@ -0,0 +1,233 @@ + + + Tests for the DataTransferItemList object + + + + + +

+ +
+ drag over here +
+ + + + + diff --git a/dom/events/test/test_accel_virtual_modifier.html b/dom/events/test/test_accel_virtual_modifier.html new file mode 100644 index 0000000000..6d98053fa2 --- /dev/null +++ b/dom/events/test/test_accel_virtual_modifier.html @@ -0,0 +1,90 @@ + + + + Test for DOM "Accel" virtual modifier + + + + +

+ +
+
+
+ + diff --git a/dom/events/test/test_accesskey.html b/dom/events/test/test_accesskey.html new file mode 100644 index 0000000000..cdfff54a28 --- /dev/null +++ b/dom/events/test/test_accesskey.html @@ -0,0 +1,160 @@ + + + + +Test for Accesskey + + + + + +

+ + +
+Checkbox 2
+Checkbox 3
+ +
+
+
+
+ +
+Legend 1 +
+
+
+
+ +
+Legend 2 +
+
+
+ + + + + + + + + diff --git a/dom/events/test/test_addEventListenerExtraArg.html b/dom/events/test/test_addEventListenerExtraArg.html new file mode 100644 index 0000000000..58b18545de --- /dev/null +++ b/dom/events/test/test_addEventListenerExtraArg.html @@ -0,0 +1,31 @@ + + + + + + Test for Bug 828554 + + + + + +Mozilla Bug 828554 +

+ +
+
+ + diff --git a/dom/events/test/test_all_synthetic_events.html b/dom/events/test/test_all_synthetic_events.html new file mode 100644 index 0000000000..d8de1a9148 --- /dev/null +++ b/dom/events/test/test_all_synthetic_events.html @@ -0,0 +1,488 @@ + + + + Test all synthetic events + + + + + +

+ +
+
+
+ + diff --git a/dom/events/test/test_auxclick_autoscroll_off.html b/dom/events/test/test_auxclick_autoscroll_off.html new file mode 100644 index 0000000000..5dd7b95920 --- /dev/null +++ b/dom/events/test/test_auxclick_autoscroll_off.html @@ -0,0 +1,31 @@ + + +Test auxclick works when general.autoScroll is off + + + + + + + + diff --git a/dom/events/test/test_bug1003432.html b/dom/events/test/test_bug1003432.html new file mode 100644 index 0000000000..d74aefb886 --- /dev/null +++ b/dom/events/test/test_bug1003432.html @@ -0,0 +1,45 @@ + + + + + Test for Bug 1003432 + + + + +Mozilla Bug 1003432 +

+ +
+
+
+ + diff --git a/dom/events/test/test_bug1003432.js b/dom/events/test/test_bug1003432.js new file mode 100644 index 0000000000..2f92ebf8da --- /dev/null +++ b/dom/events/test/test_bug1003432.js @@ -0,0 +1,31 @@ +addEventListener( + "foobar", + function (evt) { + postMessage({ + type: evt.type, + bubbles: evt.bubbles, + cancelable: evt.cancelable, + detail: evt.detail, + }); + }, + true +); + +addEventListener( + "message", + function (evt) { + // Test the constructor of CustomEvent + var e = new CustomEvent("foobar", { + bubbles: true, + cancelable: true, + detail: "test", + }); + dispatchEvent(e); + + // Test initCustomEvent + e = new CustomEvent("foobar"); + e.initCustomEvent("foobar", true, true, "test"); + dispatchEvent(e); + }, + true +); diff --git a/dom/events/test/test_bug1013412.html b/dom/events/test/test_bug1013412.html new file mode 100644 index 0000000000..03730b09b4 --- /dev/null +++ b/dom/events/test/test_bug1013412.html @@ -0,0 +1,116 @@ + + + + + Test for Bug 1013412 and 1168182 + + + + + + + +Mozilla Bug 1013412 +Mozilla Bug 1168182 +

+
+

Scrolling the page should be async and scrolling over the dark circle should scroll the page and avoid rotating the white ball.

+
+
+
+
+
+
+
+
+
+ + + diff --git a/dom/events/test/test_bug1017086_enable.html b/dom/events/test/test_bug1017086_enable.html new file mode 100644 index 0000000000..e7e6097c63 --- /dev/null +++ b/dom/events/test/test_bug1017086_enable.html @@ -0,0 +1,35 @@ + + + + + + Test for Bug 1017086 + + + + + + + + + diff --git a/dom/events/test/test_bug1037990.html b/dom/events/test/test_bug1037990.html new file mode 100644 index 0000000000..c148debcf7 --- /dev/null +++ b/dom/events/test/test_bug1037990.html @@ -0,0 +1,61 @@ + + + + + + Test for Bug 1037990 + + + + +Mozilla Bug 1037990 +

+ +
+
+ + + diff --git a/dom/events/test/test_bug1079236.html b/dom/events/test/test_bug1079236.html new file mode 100644 index 0000000000..4c89101574 --- /dev/null +++ b/dom/events/test/test_bug1079236.html @@ -0,0 +1,66 @@ + + + + + + Test for Bug 1079236 + + + + + + +Mozilla Bug 1079236 +

+
+ +
+
+
+ + diff --git a/dom/events/test/test_bug1127588.html b/dom/events/test/test_bug1127588.html new file mode 100644 index 0000000000..ca80328790 --- /dev/null +++ b/dom/events/test/test_bug1127588.html @@ -0,0 +1,62 @@ + + + + + + + + +Mozilla Bug 1127588 +

+