summaryrefslogtreecommitdiffstats
path: root/dom/events/test
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/events/test
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/events/test')
-rw-r--r--dom/events/test/bug1017086_inner.html41
-rw-r--r--dom/events/test/bug1096146_embedded.html16
-rw-r--r--dom/events/test/bug226361_iframe.xhtml47
-rw-r--r--dom/events/test/bug299673.js105
-rw-r--r--dom/events/test/bug322588-popup.html1
-rw-r--r--dom/events/test/bug415498-doc1.html15
-rw-r--r--dom/events/test/bug415498-doc2.html15
-rw-r--r--dom/events/test/bug418986-3.js69
-rw-r--r--dom/events/test/bug426082.html165
-rw-r--r--dom/events/test/bug591249_iframe.xul33
-rw-r--r--dom/events/test/bug602962.xul8
-rw-r--r--dom/events/test/bug656379-1.html185
-rw-r--r--dom/events/test/bug989198_embedded.html20
-rw-r--r--dom/events/test/bug989198_helper.js192
-rw-r--r--dom/events/test/chrome.ini28
-rw-r--r--dom/events/test/empty.js0
-rw-r--r--dom/events/test/error_event_worker.js15
-rw-r--r--dom/events/test/file_bug679494.html8
-rw-r--r--dom/events/test/marionette/head.js142
-rw-r--r--dom/events/test/marionette/manifest.ini4
-rw-r--r--dom/events/test/marionette/test_sensor_orientation.js53
-rw-r--r--dom/events/test/mochitest.ini186
-rw-r--r--dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_1.html64
-rw-r--r--dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_2.html65
-rw-r--r--dom/events/test/pointerevents/mochitest.ini152
-rw-r--r--dom/events/test/pointerevents/mochitest_support_external.js123
-rw-r--r--dom/events/test/pointerevents/mochitest_support_internal.js31
-rw-r--r--dom/events/test/pointerevents/pointerevent_attributes_mouse-manual.html113
-rw-r--r--dom/events/test/pointerevents/pointerevent_capture_mouse-manual.html135
-rw-r--r--dom/events/test/pointerevents/pointerevent_capture_suppressing_mouse-manual.html186
-rw-r--r--dom/events/test/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html138
-rw-r--r--dom/events/test/pointerevents/pointerevent_constructor.html101
-rw-r--r--dom/events/test/pointerevents/pointerevent_element_haspointercapture-manual.html123
-rw-r--r--dom/events/test/pointerevents/pointerevent_element_haspointercapture_release_pending_capture-manual.html76
-rw-r--r--dom/events/test/pointerevents/pointerevent_gotpointercapture_before_first_pointerevent-manual.html100
-rw-r--r--dom/events/test/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html81
-rw-r--r--dom/events/test/pointerevents/pointerevent_lostpointercapture_is_first-manual.html118
-rw-r--r--dom/events/test/pointerevents/pointerevent_multiple_primary_pointers_boundary_events-manual.html148
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerId_scope-manual.html85
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointercancel_touch-manual.html80
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerdown-manual.html60
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerenter-manual.html53
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html91
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerenter_nohover-manual.html77
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html67
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_after_pointerup_nohover-manual.html68
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_descendant_over-manual.html64
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_descendants-manual.html55
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html80
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_mouse-manual.html56
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_pen-manual.html59
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerleave_touch-manual.html54
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointermove-manual.html45
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointermove-on-chorded-mouse-button.html77
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html73
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointermove_pointertype-manual.html67
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerout-manual.html47
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html68
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerout_after_pointerup_nohover-manual.html68
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerout_pen-manual.html58
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerout_received_once-manual.html59
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerover-manual.html53
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointertype_mouse-manual.html66
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointertype_pen-manual.html64
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointertype_touch-manual.html65
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerup-manual.html45
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html66
-rw-r--r--dom/events/test/pointerevents/pointerevent_pointerup_pointertype-manual.html67
-rw-r--r--dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html119
-rw-r--r--dom/events/test/pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html79
-rw-r--r--dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html74
-rw-r--r--dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html82
-rw-r--r--dom/events/test/pointerevents/pointerevent_releasepointercapture_release_right_after_capture-manual.html64
-rw-r--r--dom/events/test/pointerevents/pointerevent_setpointercapture_disconnected-manual.html58
-rw-r--r--dom/events/test/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-manual.html61
-rw-r--r--dom/events/test/pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html68
-rw-r--r--dom/events/test/pointerevents/pointerevent_setpointercapture_override_pending_capture_element-manual.html66
-rw-r--r--dom/events/test/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html103
-rw-r--r--dom/events/test/pointerevents/pointerevent_setpointercapture_to_same_element_twice-manual.html65
-rw-r--r--dom/events/test/pointerevents/pointerevent_styles.css93
-rw-r--r--dom/events/test/pointerevents/pointerevent_support.js185
-rw-r--r--dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_click.html104
-rw-r--r--dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html117
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html129
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-button-test_touch-manual.html109
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-illegal.html67
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html117
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html112
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html112
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html117
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html133
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html112
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-keyboard-manual.html124
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-mouse-manual.html130
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-none-css_touch-manual.html111
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html106
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html111
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html126
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-pan-y-css_touch-manual.html106
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-span-test_touch-manual.html113
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html122
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-table-test_touch-manual.html141
-rw-r--r--dom/events/test/pointerevents/pointerevent_touch-action-verification.html101
-rw-r--r--dom/events/test/pointerevents/readme.md5
-rw-r--r--dom/events/test/pointerevents/resources/pointerevent_pointerId_scope-iframe.html37
-rw-r--r--dom/events/test/pointerevents/test_bug1285128.html48
-rw-r--r--dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_1.html30
-rw-r--r--dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_2.html30
-rw-r--r--dom/events/test/pointerevents/test_empty_file.html7
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_attributes_mouse-manual.html33
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_capture_mouse-manual.html32
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html33
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_change-touch-action-onpointerdown_touch-manual.html39
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_constructor.html26
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_element_haspointercapture-manual.html32
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_element_haspointercapture_release_pending_capture-manual.html30
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_gotpointercapture_before_first_pointerevent-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_lostpointercapture_for_disconnected_node-manual.html31
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_lostpointercapture_is_first-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_multiple_primary_pointers_boundary_events-manual.html31
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerId_scope-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointercancel_touch-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerdown-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerenter-manual.html26
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerenter_does_not_bubble-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerenter_nohover-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointercancel_touch-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointerup_nohover-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_descendant_over-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_descendants-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_does_not_bubble-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_mouse-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_pen-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerleave_touch-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointermove-manual.html26
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointermove-on-chorded-mouse-button.html37
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointermove_pointertype-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerout-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointercancel_touch-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointerup_nohover-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerout_pen-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerout_received_once-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerover-manual.html26
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointertype_mouse-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointertype_pen-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointertype_touch-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerup-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_pointerup_pointertype-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_releasepointercapture_invalid_pointerid-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointercancel_touch-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointerup_mouse-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_releasepointercapture_release_right_after_capture-manual.html30
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_disconnected-manual.html27
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_inactive_button_mouse-manual.html28
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_invalid_pointerid-manual.html26
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_override_pending_capture_element-manual.html31
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html29
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_setpointercapture_to_same_element_twice-manual.html31
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_click.html31
-rw-r--r--dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_drag_mouse.html33
-rw-r--r--dom/events/test/pointerevents/test_touch_action.html99
-rw-r--r--dom/events/test/pointerevents/touch_action_helpers.js206
-rw-r--r--dom/events/test/test_DataTransferItemList.html232
-rw-r--r--dom/events/test/test_accel_virtual_modifier.html90
-rw-r--r--dom/events/test/test_addEventListenerExtraArg.html31
-rw-r--r--dom/events/test/test_all_synthetic_events.html515
-rw-r--r--dom/events/test/test_bug1003432.html45
-rw-r--r--dom/events/test/test_bug1003432.js23
-rw-r--r--dom/events/test/test_bug1013412.html110
-rw-r--r--dom/events/test/test_bug1017086_disable.html41
-rw-r--r--dom/events/test/test_bug1017086_enable.html43
-rw-r--r--dom/events/test/test_bug1037990.html61
-rw-r--r--dom/events/test/test_bug1079236.html60
-rw-r--r--dom/events/test/test_bug1096146.html187
-rw-r--r--dom/events/test/test_bug1128787-1.html54
-rw-r--r--dom/events/test/test_bug1128787-2.html55
-rw-r--r--dom/events/test/test_bug1128787-3.html54
-rw-r--r--dom/events/test/test_bug1145910.html48
-rw-r--r--dom/events/test/test_bug1150308.html41
-rw-r--r--dom/events/test/test_bug1248459.html58
-rw-r--r--dom/events/test/test_bug1264380.html54
-rw-r--r--dom/events/test/test_bug1298970.html33
-rw-r--r--dom/events/test/test_bug226361.xhtml82
-rw-r--r--dom/events/test/test_bug238987.html282
-rw-r--r--dom/events/test/test_bug288392.html97
-rw-r--r--dom/events/test/test_bug299673-1.html61
-rw-r--r--dom/events/test/test_bug299673-2.html60
-rw-r--r--dom/events/test/test_bug322588.html62
-rw-r--r--dom/events/test/test_bug328885.html134
-rw-r--r--dom/events/test/test_bug336682.js94
-rw-r--r--dom/events/test/test_bug336682_1.html68
-rw-r--r--dom/events/test/test_bug336682_2.xul71
-rw-r--r--dom/events/test/test_bug367781.html53
-rw-r--r--dom/events/test/test_bug368835.html101
-rw-r--r--dom/events/test/test_bug379120.html58
-rw-r--r--dom/events/test/test_bug391568.xhtml77
-rw-r--r--dom/events/test/test_bug402089.html67
-rw-r--r--dom/events/test/test_bug405632.html34
-rw-r--r--dom/events/test/test_bug409604.html382
-rw-r--r--dom/events/test/test_bug412567.html47
-rw-r--r--dom/events/test/test_bug415498.xul106
-rw-r--r--dom/events/test/test_bug418986-3.html25
-rw-r--r--dom/events/test/test_bug418986-3.xul27
-rw-r--r--dom/events/test/test_bug422132.html124
-rw-r--r--dom/events/test/test_bug426082.html30
-rw-r--r--dom/events/test/test_bug427537.html61
-rw-r--r--dom/events/test/test_bug428988.html44
-rw-r--r--dom/events/test/test_bug432698.html223
-rw-r--r--dom/events/test/test_bug443985.html76
-rw-r--r--dom/events/test/test_bug447736.html47
-rw-r--r--dom/events/test/test_bug448602.html220
-rw-r--r--dom/events/test/test_bug450876.html41
-rw-r--r--dom/events/test/test_bug456273.html41
-rw-r--r--dom/events/test/test_bug457672.html55
-rw-r--r--dom/events/test/test_bug489671.html55
-rw-r--r--dom/events/test/test_bug493251.html194
-rw-r--r--dom/events/test/test_bug502818.html54
-rw-r--r--dom/events/test/test_bug508479.html103
-rw-r--r--dom/events/test/test_bug517851.html112
-rw-r--r--dom/events/test/test_bug524674.xul147
-rw-r--r--dom/events/test/test_bug534833.html157
-rw-r--r--dom/events/test/test_bug545268.html141
-rw-r--r--dom/events/test/test_bug547996-1.html87
-rw-r--r--dom/events/test/test_bug547996-2.xhtml125
-rw-r--r--dom/events/test/test_bug556493.html74
-rw-r--r--dom/events/test/test_bug563329.html82
-rw-r--r--dom/events/test/test_bug574663.html170
-rw-r--r--dom/events/test/test_bug586961.xul46
-rw-r--r--dom/events/test/test_bug591249.xul75
-rw-r--r--dom/events/test/test_bug591815.html68
-rw-r--r--dom/events/test/test_bug593959.html60
-rw-r--r--dom/events/test/test_bug602962.xul88
-rw-r--r--dom/events/test/test_bug603008.html556
-rw-r--r--dom/events/test/test_bug605242.html58
-rw-r--r--dom/events/test/test_bug607464.html87
-rw-r--r--dom/events/test/test_bug613634.html90
-rw-r--r--dom/events/test/test_bug615597.html39
-rw-r--r--dom/events/test/test_bug617528.xul95
-rw-r--r--dom/events/test/test_bug624127.html35
-rw-r--r--dom/events/test/test_bug635465.html90
-rw-r--r--dom/events/test/test_bug641477.html37
-rw-r--r--dom/events/test/test_bug648573.html109
-rw-r--r--dom/events/test/test_bug650493.html215
-rw-r--r--dom/events/test/test_bug656379-1.html30
-rw-r--r--dom/events/test/test_bug656379-2.html83
-rw-r--r--dom/events/test/test_bug656954.html42
-rw-r--r--dom/events/test/test_bug659071.html39
-rw-r--r--dom/events/test/test_bug659350.html111
-rw-r--r--dom/events/test/test_bug662678.html153
-rw-r--r--dom/events/test/test_bug667612.html39
-rw-r--r--dom/events/test/test_bug667919-1.html41
-rw-r--r--dom/events/test/test_bug679494.xul36
-rw-r--r--dom/events/test/test_bug684208.html80
-rw-r--r--dom/events/test/test_bug687787.html617
-rw-r--r--dom/events/test/test_bug689564.html65
-rw-r--r--dom/events/test/test_bug698929.html47
-rw-r--r--dom/events/test/test_bug704423.html40
-rw-r--r--dom/events/test/test_bug741666.html176
-rw-r--r--dom/events/test/test_bug742376.html74
-rw-r--r--dom/events/test/test_bug812744.html38
-rw-r--r--dom/events/test/test_bug822898.html350
-rw-r--r--dom/events/test/test_bug855741.html90
-rw-r--r--dom/events/test/test_bug864040.html87
-rw-r--r--dom/events/test/test_bug924087.html45
-rw-r--r--dom/events/test/test_bug930374-chrome.html58
-rw-r--r--dom/events/test/test_bug930374-content.html72
-rw-r--r--dom/events/test/test_bug944011.html52
-rw-r--r--dom/events/test/test_bug944847.html42
-rw-r--r--dom/events/test/test_bug946632.html161
-rw-r--r--dom/events/test/test_bug967796.html235
-rw-r--r--dom/events/test/test_bug985988.html76
-rw-r--r--dom/events/test/test_bug998809.html35
-rw-r--r--dom/events/test/test_clickevent_on_input.html111
-rw-r--r--dom/events/test/test_continuous_wheel_events.html3248
-rw-r--r--dom/events/test/test_dblclick_explicit_original_target.html33
-rw-r--r--dom/events/test/test_dom_activate_event.html89
-rw-r--r--dom/events/test/test_dom_before_after_keyboard_event.html136
-rw-r--r--dom/events/test/test_dom_before_after_keyboard_event_remote.html195
-rw-r--r--dom/events/test/test_dom_keyboard_event.html306
-rw-r--r--dom/events/test/test_dom_mouse_event.html143
-rw-r--r--dom/events/test/test_dom_storage_event.html62
-rw-r--r--dom/events/test/test_dom_wheel_event.html811
-rw-r--r--dom/events/test/test_draggableprop.html89
-rw-r--r--dom/events/test/test_dragstart.html585
-rw-r--r--dom/events/test/test_error_events.html72
-rw-r--r--dom/events/test/test_eventTimeStamp.html121
-rw-r--r--dom/events/test/test_eventctors.html953
-rw-r--r--dom/events/test/test_eventctors.xul49
-rw-r--r--dom/events/test/test_eventhandler_scoping.html17
-rw-r--r--dom/events/test/test_focus_disabled.html125
-rw-r--r--dom/events/test/test_legacy_event.html304
-rw-r--r--dom/events/test/test_messageEvent.html79
-rw-r--r--dom/events/test/test_messageEvent_init.html25
-rw-r--r--dom/events/test/test_moz_mouse_pixel_scroll_event.html1363
-rw-r--r--dom/events/test/test_offsetxy.html98
-rw-r--r--dom/events/test/test_onerror_handler_args.html36
-rw-r--r--dom/events/test/test_passive_listeners.html118
-rw-r--r--dom/events/test/test_paste_image.html196
-rw-r--r--dom/events/test/test_wheel_default_action.html39
-rw-r--r--dom/events/test/window_bug493251.html13
-rw-r--r--dom/events/test/window_bug617528.xul9
-rw-r--r--dom/events/test/window_bug659071.html69
-rw-r--r--dom/events/test/window_wheel_default_action.html1848
306 files changed, 33068 insertions, 0 deletions
diff --git a/dom/events/test/bug1017086_inner.html b/dom/events/test/bug1017086_inner.html
new file mode 100644
index 000000000..7ef0f6d86
--- /dev/null
+++ b/dom/events/test/bug1017086_inner.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1017086</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /** Test for Bug 1017086 **/
+ var testelem = undefined;
+ var pointer_events = ["onpointerover", "onpointerenter",
+ "onpointermove",
+ "onpointerdown", "onpointerup",
+ "onpointerout", "onpointerleave",
+ "onpointercancel"];
+ function check(expected_value, event_name, container, container_name) {
+ var text = event_name + " in " + container_name + " should be " + expected_value;
+ parent.is(event_name in container, expected_value, text);
+ }
+ function runTest() {
+ testelem = document.getElementById("test");
+ is(!!testelem, true, "Document should have element with id 'test'");
+ parent.turnOnOffPointerEvents( function() {
+ parent.part_of_checks(pointer_events, check, window, document, testelem);
+ });
+ }
+ </script>
+</head>
+<body onload="runTest();">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1017086">Mozilla Bug 1017086</a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+</body>
+</html>
diff --git a/dom/events/test/bug1096146_embedded.html b/dom/events/test/bug1096146_embedded.html
new file mode 100644
index 000000000..b1c1dd406
--- /dev/null
+++ b/dom/events/test/bug1096146_embedded.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Embedded iframe</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="">
+ <p id="display"></p>
+ <h1>Top</h1>
+ <input id="input" style="display: block;">
+ <pre id="test">
+ <div id="content" style="height: 2000px;"></div>
+ <h1>Bottom</h1>
+</body>
+</html>
diff --git a/dom/events/test/bug226361_iframe.xhtml b/dom/events/test/bug226361_iframe.xhtml
new file mode 100644
index 000000000..df38a8bcb
--- /dev/null
+++ b/dom/events/test/bug226361_iframe.xhtml
@@ -0,0 +1,47 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=226361
+-->
+<head>
+ <title>Test for Bug 226361</title>
+</head>
+<body id="body">
+<p id="display">
+
+<a id="a1" tabindex="3" href="http://home.mozilla.org">This is the 1st
+
+link but the 3rd tabindex</a><br />
+
+<br />
+
+ <a id="a2" tabindex="4" href="http://home.mozilla.org">This is the 2nd
+
+link but the 4th tabindex</a><br />
+
+<br />
+
+ <a id="a3" tabindex="1" href="http://home.mozilla.org">This is the 3rd
+
+link but the 1st tabindex</a><br />
+
+<br />
+
+ <a id="a4" tabindex="5" href="http://home.mozilla.org">This is the 4th
+
+link but the 5th tabindex</a><br />
+
+<br />
+
+ <a id="a5" tabindex="2" href="http://home.mozilla.org">This is the 5th
+
+link but the 2nd tabindex</a>
+
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/bug299673.js b/dom/events/test/bug299673.js
new file mode 100644
index 000000000..f426ffda3
--- /dev/null
+++ b/dom/events/test/bug299673.js
@@ -0,0 +1,105 @@
+var popup;
+
+function OpenWindow()
+{
+log({},">>> OpenWindow");
+ popup = window.open("","Test");
+
+ var output = "<html>";
+
+ output+="<body>";
+ output+="<form>"
+ output+="<input id='popupText1' type='text' onfocus='opener.log(event)' onblur='opener.log(event)'>";
+ output+="</form>"
+ output+="</body>";
+ output+="</html>";
+
+ popup.document.open();
+ popup.document.write(output);
+ popup.document.close();
+
+ popup.document.onclick=function (event) { log(event,"popup-doc") };
+ popup.document.onfocus=function (event) { log(event,"popup-doc") };
+ popup.document.onblur=function (event) { log(event,"popup-doc") };
+ popup.document.onchange=function (event) { log(event,"popup-doc") };
+
+ var e = popup.document.getElementById('popupText1');
+ popup.focus();
+ e.focus();
+ is(popup.document.activeElement, e, "input element in popup should be focused");
+log({},"<<< OpenWindow");
+}
+
+var result;
+
+function log(event,message) {
+ if (event&&event.eventPhase==3) return;
+ e = event.currentTarget||event.target||event.srcElement;
+ var id = e?(e.id?e.id:e.name?e.name:e.value?e.value:''):'';
+ if (id) id = '(' + id + ')';
+ result +=
+ (e?(e.tagName?e.tagName:''):' ')+id+': '+
+ (event.type?event.type:'')+' '+
+ (message?message:'') + '\n';
+}
+
+document.onclick=function (event) { log(event,"top-doc") };
+document.onfocus=function (event) { log(event,"top-doc") };
+document.onblur=function (event) { log(event,"top-doc") };
+document.onchange=function (event) { log(event,"top-doc") };
+
+function doTest1_rest2(expectedEventLog,focusAfterCloseId) {
+ try {
+ is(document.activeElement, document.getElementById(focusAfterCloseId), "wrong element is focused after popup was closed");
+ is(result, expectedEventLog, "unexpected events");
+ SimpleTest.finish();
+ } catch(e) {
+ if (popup)
+ popup.close();
+ throw e;
+ }
+}
+function doTest1_rest1(expectedEventLog,focusAfterCloseId) {
+ try {
+ synthesizeKey("V", {}, popup);
+ synthesizeKey("A", {}, popup);
+ synthesizeKey("L", {}, popup);
+ is(popup.document.getElementById('popupText1').value, "VAL", "input element in popup did not accept input");
+
+ var p = popup;
+ popup = null;
+ p.close();
+
+ SimpleTest.waitForFocus(function () { doTest1_rest2(expectedEventLog,focusAfterCloseId); }, window);
+ } catch(e) {
+ if (popup)
+ popup.close();
+ throw e;
+ }
+}
+
+function doTest1(expectedEventLog,focusAfterCloseId) {
+ try {
+ var select1 = document.getElementById('Select1');
+ select1.focus();
+ is(document.activeElement, select1, "select element should be focused");
+ synthesizeKey("VK_DOWN",{});
+ synthesizeKey("VK_TAB", {});
+ SimpleTest.waitForFocus(function () { doTest1_rest1(expectedEventLog,focusAfterCloseId); }, popup);
+
+ } catch(e) {
+ if (popup)
+ popup.close();
+ throw e;
+ }
+}
+
+function setPrefAndDoTest(expectedEventLog,focusAfterCloseId,prefValue) {
+ var select1 = document.getElementById('Select1');
+ select1.blur();
+ result = "";
+ log({},"Test with browser.link.open_newwindow = "+prefValue);
+ SpecialPowers.pushPrefEnv({"set": [['browser.link.open_newwindow', prefValue]]}, function() {
+ doTest1(expectedEventLog,focusAfterCloseId);
+ });
+}
diff --git a/dom/events/test/bug322588-popup.html b/dom/events/test/bug322588-popup.html
new file mode 100644
index 000000000..767eb9db9
--- /dev/null
+++ b/dom/events/test/bug322588-popup.html
@@ -0,0 +1 @@
+<html><head></head><body onblur="window.close()"><a id="target">a id=target</a></body></html>
diff --git a/dom/events/test/bug415498-doc1.html b/dom/events/test/bug415498-doc1.html
new file mode 100644
index 000000000..91c04832a
--- /dev/null
+++ b/dom/events/test/bug415498-doc1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script type="text/javascript">
+function init() {
+ // This will throw a HierarchyRequestError exception
+ var doc = document.implementation.createDocument(null, 'DOC', null);
+ doc.documentElement.appendChild(doc);
+}
+window.addEventListener("load", init, false);
+</script>
+</head>
+<body>
+ Testcase for bug 415498. This page should show an exception in Error Console on load
+</body>
diff --git a/dom/events/test/bug415498-doc2.html b/dom/events/test/bug415498-doc2.html
new file mode 100644
index 000000000..e556a4e4c
--- /dev/null
+++ b/dom/events/test/bug415498-doc2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script type="text/javascript">
+function init() {
+ // This will throw a HierarchyRequestError exception
+ var doc = document.implementation.createDocument(null, 'DOC', null);
+ doc.documentElement.appendChild(doc);
+}
+onload = init;
+</script>
+</head>
+<body>
+ Testcase for bug 415498. This page should show an exception in Error Console on load
+</body>
diff --git a/dom/events/test/bug418986-3.js b/dom/events/test/bug418986-3.js
new file mode 100644
index 000000000..6bd2a6e69
--- /dev/null
+++ b/dom/events/test/bug418986-3.js
@@ -0,0 +1,69 @@
+SimpleTest.waitForExplicitFinish();
+
+// The main testing function.
+var test = function (isContent) {
+ // Each definition is [eventType, prefSetting]
+ // Where we are setting the "privacy.resistFingerprinting" pref.
+ let eventDefs = [["mousedown", true],
+ ["mouseup", true],
+ ["mousedown", false],
+ ["mouseup", false]];
+
+ let testCounter = 0;
+
+ // Declare ahead of time.
+ let setup;
+
+ // This function is called when the event handler fires.
+ let handleEvent = function (event, prefVal) {
+ let resisting = prefVal && isContent;
+ if (resisting) {
+ is(event.screenX, event.clientX, "event.screenX and event.clientX should be the same");
+ is(event.screenY, event.clientY, "event.screenY and event.clientY should be the same");
+ } else {
+ // We can't be sure about X coordinates not being equal, but we can test Y.
+ isnot(event.screenY, event.clientY, "event.screenY !== event.clientY");
+ }
+ ++testCounter;
+ if (testCounter < eventDefs.length) {
+ nextTest();
+ } else {
+ SimpleTest.finish();
+ }
+ };
+
+ // In this function, we set up the nth div and event handler,
+ // and then synthesize a mouse event in the div, to test
+ // whether the resulting events resist fingerprinting by
+ // suppressing absolute screen coordinates.
+ nextTest = function () {
+ let [eventType, prefVal] = eventDefs[testCounter];
+ SpecialPowers.pushPrefEnv({set:[["privacy.resistFingerprinting", prefVal]]},
+ function () {
+ // The following code creates a new div for each event in eventDefs,
+ // attaches a listener to listen for the event, and then generates
+ // a fake event at the center of the div.
+ let div = document.createElement("div");
+ div.style.width = "10px";
+ div.style.height = "10px";
+ div.style.backgroundColor = "red";
+ // Name the div after the event we're listening for.
+ div.id = eventType;
+ document.getElementById("body").appendChild(div);
+ // Seems we can't add an event listener in chrome unless we run
+ // it in a later task.
+ window.setTimeout(function() {
+ div.addEventListener(eventType, event => handleEvent(event, prefVal), false);
+ // For some reason, the following synthesizeMouseAtCenter call only seems to run if we
+ // wrap it in a window.setTimeout(..., 0).
+ window.setTimeout(function () {
+ synthesizeMouseAtCenter(div, {type : eventType});
+ }, 0);
+ }, 0);
+ });
+ };
+
+ // Now run by starting with the 0th event.
+ nextTest();
+
+};
diff --git a/dom/events/test/bug426082.html b/dom/events/test/bug426082.html
new file mode 100644
index 000000000..8eaaa7391
--- /dev/null
+++ b/dom/events/test/bug426082.html
@@ -0,0 +1,165 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=426082
+-->
+<head>
+ <title>Test for Bug 426082</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ canvas {
+ display: none;
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426082">Mozilla Bug 426082</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<p><input type="button" value="Button" id="button"></p>
+<p><label for="button" id="label">Label</label></p>
+<p id="outside">Something under the label</p>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+/** Test for Bug 426082 **/
+
+var normalButtonCanvas, pressedButtonCanvas, normalFocusedButtonCanvas,
+ pressedFocusedButtonCanvas, currentSnapshot, button, label, outside;
+
+function runTests() {
+ button = $("button");
+ label = $("label");
+ outside = $("outside");
+ SimpleTest.executeSoon(executeTests);
+}
+
+SimpleTest.waitForFocus(runTests);
+
+function isRectContainedInRectFromRegion(rect, region) {
+ return Array.some(region, function (r) {
+ return rect.left >= r.left &&
+ rect.top >= r.top &&
+ rect.right <= r.right &&
+ rect.bottom <= r.bottom;
+ });
+}
+
+function paintListener(e) {
+ if (isRectContainedInRectFromRegion(buttonRect(), SpecialPowers.wrap(e).clientRects)) {
+ gNeedsPaint = false;
+ currentSnapshot = takeSnapshot();
+ }
+}
+
+var gNeedsPaint = false;
+function executeTests() {
+ var testYielder = tests();
+ function execNext() {
+ try {
+ if (!gNeedsPaint) {
+ testYielder.next();
+ button.getBoundingClientRect(); // Flush.
+ gNeedsPaint = true;
+ }
+ SimpleTest.executeSoon(execNext);
+ } catch (e) {}
+ }
+ execNext();
+}
+
+function tests() {
+ window.addEventListener("MozAfterPaint", paintListener, false);
+ normalButtonCanvas = takeSnapshot();
+ // Press the button.
+ sendMouseEvent("mousemove", button);
+ sendMouseEvent("mousedown", button);
+ yield undefined;
+ pressedFocusedButtonCanvas = takeSnapshot();
+ compareSnapshots_(normalButtonCanvas, pressedFocusedButtonCanvas, false, "Pressed focused buttons should look different from normal buttons.");
+ // Release.
+ sendMouseEvent("mouseup", button);
+ yield undefined;
+ // make sure the button is focused as this doesn't happen on click on Mac
+ button.focus();
+ normalFocusedButtonCanvas = takeSnapshot();
+ compareSnapshots_(normalFocusedButtonCanvas, pressedFocusedButtonCanvas, false, "Pressed focused buttons should look different from normal focused buttons.");
+ // Unfocus the button.
+ sendMouseEvent("mousedown", outside);
+ sendMouseEvent("mouseup", outside);
+ yield undefined;
+
+ // Press the label.
+ sendMouseEvent("mousemove", label);
+ sendMouseEvent("mousedown", label);
+ yield undefined;
+ compareSnapshots_(normalButtonCanvas, currentSnapshot, false, "Pressing the label should have pressed the button.");
+ pressedButtonCanvas = takeSnapshot();
+ // Move the mouse down from the label.
+ sendMouseEvent("mousemove", outside);
+ yield undefined;
+ compareSnapshots_(normalButtonCanvas, currentSnapshot, true, "Moving the mouse down from the label should have unpressed the button.");
+ // ... and up again.
+ sendMouseEvent("mousemove", label);
+ yield undefined;
+ compareSnapshots_(pressedButtonCanvas, currentSnapshot, true, "Moving the mouse back on top of the label should have pressed the button.");
+ // Release.
+ sendMouseEvent("mouseup", label);
+ yield undefined;
+ var focusOnMouse = (navigator.platform.indexOf("Mac") != 0);
+ compareSnapshots_(focusOnMouse ? normalFocusedButtonCanvas : normalButtonCanvas,
+ currentSnapshot, true, "Releasing the mouse over the label should have unpressed" +
+ (focusOnMouse ? " (and focused)" : "") + " the button.");
+ // Press the label and remove it.
+ sendMouseEvent("mousemove", label);
+ sendMouseEvent("mousedown", label);
+ yield undefined;
+ label.parentNode.removeChild(label);
+ yield undefined;
+ compareSnapshots_(normalButtonCanvas, currentSnapshot, true, "Removing the label should have unpressed the button.");
+ sendMouseEvent("mouseup", label);
+ window.removeEventListener("MozAfterPaint", paintListener, false);
+ window.opener.finishTests();
+ }
+
+function sendMouseEvent(t, elem) {
+ var r = elem.getBoundingClientRect();
+ synthesizeMouse(elem, r.width / 2, r.height / 2, {type: t});
+}
+
+function compareSnapshots_(c1, c2, shouldBeIdentical, msg) {
+ var [correct, c1url, c2url] = compareSnapshots(c1, c2, shouldBeIdentical);
+ if (correct) {
+ if (shouldBeIdentical) {
+ window.opener.ok(true, msg + " - expected " + c1url);
+ } else {
+ window.opener.ok(true, msg + " - got " + c1url + " and " + c2url);
+ }
+ } else {
+ if (shouldBeIdentical) {
+ window.opener.ok(false, msg + " - expected " + c1url + " but got " + c2url);
+ } else {
+ window.opener.ok(false, msg + " - expected something other than " + c1url);
+ }
+ }
+}
+
+function takeSnapshot() {
+ var r = buttonRect();
+ adjustedRect = { left: r.left - 2, top: r.top - 2,
+ width: r.width + 4, height: r.height + 4 };
+ return SpecialPowers.snapshotRect(window, adjustedRect);
+}
+
+function buttonRect() {
+ return button.getBoundingClientRect();
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/bug591249_iframe.xul b/dom/events/test/bug591249_iframe.xul
new file mode 100644
index 000000000..7c7d7642b
--- /dev/null
+++ b/dom/events/test/bug591249_iframe.xul
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=591249
+-->
+<window title="Mozilla Bug 591249"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <html:style type="text/css">
+ #drop-target {
+ width: 50px;
+ height: 50px;
+ border: 4px dotted black;
+ }
+ #drop-target {
+ background-color: red;
+ }
+ #drop-target:-moz-drag-over {
+ background-color: yellow;
+ }
+ </html:style>
+
+ <html:body>
+ <html:h1 id="iframetext">Iframe for Bug 591249</html:h1>
+
+ <html:div id="drop-target"
+ ondrop="return false;"
+ ondragenter="return false;"
+ ondragover="return false;">
+ </html:div>
+ </html:body>
+</window>
diff --git a/dom/events/test/bug602962.xul b/dom/events/test/bug602962.xul
new file mode 100644
index 000000000..0d54b7ad5
--- /dev/null
+++ b/dom/events/test/bug602962.xul
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window onload="window.opener.doTest()" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <scrollbox id="page-scrollbox" style="border: 1px solid red; background-color: black;overflow: auto" flex="1">
+ <box id="page-box" style="border: 1px solid green;"/>
+ </scrollbox>
+</window>
diff --git a/dom/events/test/bug656379-1.html b/dom/events/test/bug656379-1.html
new file mode 100644
index 000000000..d7a04e3bf
--- /dev/null
+++ b/dom/events/test/bug656379-1.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=656379
+-->
+<head>
+ <title>Test for Bug 656379</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ canvas {
+ display: none;
+ }
+ input[type=button] {
+ -moz-appearance: none;
+ padding: 0;
+ border: none;
+ color: black;
+ background: white;
+ }
+ input[type=button]::-moz-focus-inner { border: none; }
+
+ /* Make sure that normal, focused, hover+active, focused+hover+active
+ buttons all have different styles so that the test keeps moving along. */
+ input[type=button]:hover:active {
+ background: red;
+ }
+ input[type=button]:focus {
+ background: green;
+ }
+ input[type=button]:focus:hover:active {
+ background: purple;
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=656379">Mozilla Bug 656379</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+
+var normalButtonCanvas, pressedButtonCanvas, normalFocusedButtonCanvas,
+ pressedFocusedButtonCanvas, currentSnapshot, button, label, outside;
+
+function runTests() {
+ button = $("button");
+ label = $("label");
+ outside = $("outside");
+ SimpleTest.executeSoon(executeTests);
+}
+
+SimpleTest.waitForFocus(runTests);
+
+function isRectContainedInRectFromRegion(rect, region) {
+ return Array.some(region, function (r) {
+ return rect.left >= r.left &&
+ rect.top >= r.top &&
+ rect.right <= r.right &&
+ rect.bottom <= r.bottom;
+ });
+}
+
+function paintListener(e) {
+ if (isRectContainedInRectFromRegion(buttonRect(), SpecialPowers.wrap(e).clientRects)) {
+ gNeedsPaint = false;
+ currentSnapshot = takeSnapshot();
+ }
+}
+
+var gNeedsPaint = false;
+function executeTests() {
+ var testYielder = tests();
+ function execNext() {
+ try {
+ if (!gNeedsPaint) {
+ testYielder.next();
+ button.getBoundingClientRect(); // Flush.
+ gNeedsPaint = true;
+ }
+ SimpleTest.executeSoon(execNext);
+ } catch (e) {}
+ }
+ execNext();
+}
+
+function tests() {
+ window.addEventListener("MozAfterPaint", paintListener, false);
+ normalButtonCanvas = takeSnapshot();
+ // Press the button.
+ sendMouseEvent("mousemove", button);
+ sendMouseEvent("mousedown", button);
+ yield undefined;
+ pressedFocusedButtonCanvas = takeSnapshot();
+ compareSnapshots_(normalButtonCanvas, pressedFocusedButtonCanvas, false, "Pressed focused buttons should look different from normal buttons.");
+ // Release.
+ sendMouseEvent("mouseup", button);
+ yield undefined;
+ // make sure the button is focused as this doesn't happen on click on Mac
+ button.focus();
+ normalFocusedButtonCanvas = takeSnapshot();
+ compareSnapshots_(normalFocusedButtonCanvas, pressedFocusedButtonCanvas, false, "Pressed focused buttons should look different from normal focused buttons.");
+ // Unfocus the button.
+ sendMouseEvent("mousedown", outside);
+ sendMouseEvent("mouseup", outside);
+ yield undefined;
+
+ // Press the label.
+ sendMouseEvent("mousemove", label);
+ sendMouseEvent("mousedown", label);
+ yield undefined;
+ compareSnapshots_(normalButtonCanvas, currentSnapshot, false, "Pressing the label should have pressed the button.");
+ pressedButtonCanvas = takeSnapshot();
+ // Move the mouse down from the label.
+ sendMouseEvent("mousemove", outside);
+ yield undefined;
+ compareSnapshots_(normalButtonCanvas, currentSnapshot, true, "Moving the mouse down from the label should have unpressed the button.");
+ // ... and up again.
+ sendMouseEvent("mousemove", label);
+ yield undefined;
+ compareSnapshots_(pressedButtonCanvas, currentSnapshot, true, "Moving the mouse back on top of the label should have pressed the button.");
+ // Release.
+ sendMouseEvent("mouseup", label);
+ yield undefined;
+ var focusOnMouse = (navigator.platform.indexOf("Mac") != 0);
+ compareSnapshots_(focusOnMouse ? normalFocusedButtonCanvas : normalButtonCanvas,
+ currentSnapshot, true, "Releasing the mouse over the label should have unpressed" +
+ (focusOnMouse ? " (and focused)" : "") + " the button.");
+ // Press the label and remove it.
+ sendMouseEvent("mousemove", label);
+ sendMouseEvent("mousedown", label);
+ yield undefined;
+ label.parentNode.removeChild(label);
+ yield undefined;
+ compareSnapshots_(normalButtonCanvas, currentSnapshot, true, "Removing the label should have unpressed the button.");
+ sendMouseEvent("mouseup", label);
+ window.removeEventListener("MozAfterPaint", paintListener, false);
+ window.opener.finishTests();
+ }
+
+function sendMouseEvent(t, elem) {
+ var r = elem.getBoundingClientRect();
+ synthesizeMouse(elem, r.width / 2, r.height / 2, {type: t});
+}
+
+function compareSnapshots_(c1, c2, shouldBeIdentical, msg) {
+ var [correct, c1url, c2url] = compareSnapshots(c1, c2, shouldBeIdentical);
+ if (correct) {
+ if (shouldBeIdentical) {
+ window.opener.ok(true, msg + " - expected " + c1url);
+ } else {
+ window.opener.ok(true, msg + " - got " + c1url + " and " + c2url);
+ }
+ } else {
+ if (shouldBeIdentical) {
+ window.opener.ok(false, msg + " - expected " + c1url + " but got " + c2url);
+ } else {
+ window.opener.ok(false, msg + " - expected something other than " + c1url);
+ }
+ }
+}
+
+function takeSnapshot(canvas) {
+ var r = buttonRect();
+ adjustedRect = { left: r.left - 2, top: r.top - 2,
+ width: r.width + 4, height: r.height + 4 };
+ return SpecialPowers.snapshotRect(window, adjustedRect);
+}
+
+function buttonRect() {
+ return button.getBoundingClientRect();
+}
+</script>
+</pre>
+<p><input type="button" value="Button" id="button"></p>
+<p><label for="button" id="label">Label</label></p>
+<p id="outside">Something under the label</p>
+
+</body>
+</html>
diff --git a/dom/events/test/bug989198_embedded.html b/dom/events/test/bug989198_embedded.html
new file mode 100644
index 000000000..cee7683cf
--- /dev/null
+++ b/dom/events/test/bug989198_embedded.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Embedded iframe</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="getFocus();">
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <input id="input" style="display: block;">
+ <pre id="test">
+ <script type="application/javascript">
+ function getFocus() {
+ input = document.getElementById("input");
+ input.focus();
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/events/test/bug989198_helper.js b/dom/events/test/bug989198_helper.js
new file mode 100644
index 000000000..2d74831e9
--- /dev/null
+++ b/dom/events/test/bug989198_helper.js
@@ -0,0 +1,192 @@
+/*
+ * Helper functions for testing BeforeAfterKeyboardEvent.
+ */
+
+const kUnknownEvent = 0x000;
+const kKeyDownEvent = 0x001;
+const kKeyUpEvent = 0x002;
+const kBeforeEvent = 0x010;
+const kAfterEvent = 0x020;
+const kParent = 0x100;
+const kChild = 0x200;
+
+var gCurrentTest;
+
+function frameScript()
+{
+ function handler(e) {
+ var results = sendSyncMessage("forwardevent", { type: e.type });
+ if (results[0]) {
+ e.preventDefault();
+ }
+ }
+ addEventListener('keydown', handler);
+ addEventListener('keyup', handler);
+ addEventListener('mozbrowserbeforekeydown', handler);
+ addEventListener('mozbrowserbeforekeyup', handler);
+ addEventListener('mozbrowserafterkeydown', handler);
+ addEventListener('mozbrowserafterkeyup', handler);
+}
+
+function prepareTest(useRemote)
+{
+ if (useRemote) {
+ setupHandlers(window, embedderHandler);
+ } else {
+ setupHandlers(window, embedderHandlerWithCheck);
+ }
+
+ var iframe = document.createElement("iframe");
+ iframe.id = "embedded";
+ iframe.src = "bug989198_embedded.html";
+ iframe.setAttribute("remote", useRemote ? "true" : "false");
+ SpecialPowers.wrap(iframe).mozbrowser = true;
+
+ iframe.addEventListener("mozbrowserloadend", function onloadend() {
+ iframe.removeEventListener("mozbrowserloadend", onloadend);
+ iframe.focus();
+ var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
+ mm.addMessageListener("forwardevent", function(msg) {
+ return embeddedHandler(msg.json);
+ });
+ mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
+ runTests();
+ return;
+ });
+
+ document.body.appendChild(iframe);
+}
+
+function setupHandlers(element, handler)
+{
+ element.addEventListener('keydown', handler);
+ element.addEventListener('keyup', handler);
+ element.addEventListener('mozbrowserbeforekeydown', handler);
+ element.addEventListener('mozbrowserbeforekeyup', handler);
+ element.addEventListener('mozbrowserafterkeydown', handler);
+ element.addEventListener('mozbrowserafterkeyup', handler);
+}
+
+function teardownHandlers(element, handler)
+{
+ element.removeEventListener('keydown', handler);
+ element.removeEventListener('keyup', handler);
+ element.removeEventListener('mozbrowserbeforekeydown', handler);
+ element.removeEventListener('mozbrowserbeforekeyup', handler);
+ element.removeEventListener('mozbrowserafterkeydown', handler);
+ element.removeEventListener('mozbrowserafterkeyup', handler);
+}
+
+function convertNameToCode(name)
+{
+ switch (name) {
+ case "mozbrowserbeforekeydown":
+ return kBeforeEvent | kKeyDownEvent;
+ case "mozbrowserafterkeydown":
+ return kAfterEvent | kKeyDownEvent;
+ case "mozbrowserbeforekeyup":
+ return kBeforeEvent | kKeyUpEvent;
+ case "mozbrowserafterkeyup":
+ return kAfterEvent | kKeyUpEvent;
+ case "keydown":
+ return kKeyDownEvent;
+ case "keyup":
+ return kKeyUpEvent;
+ default:
+ return kUnknownEvent;
+ }
+}
+
+function classifyEvents(test)
+{
+ // Categorize resultEvents into KEYDOWN group and KEYUP group.
+ for (var i = 0; i < gCurrentTest.resultEvents.length ; i++) {
+ var code = test.resultEvents[i];
+ if ((code & 0xF) == 0x1) { // KEYDOWN
+ test.classifiedEvents[0].push(code);
+ } else if ((code & 0xF) == 0x2) { // KEYUP
+ test.classifiedEvents[1].push(code);
+ } else {
+ ok(false, "Invalid code for events");
+ }
+ }
+}
+
+function verifyResults(test)
+{
+ for (var i = 0; i < gCurrentTest.expectedEvents.length; i++) {
+ is(test.classifiedEvents[i].length,
+ test.expectedEvents[i].length,
+ test.description + ": Wrong number of events");
+
+ for (var j = 0; j < gCurrentTest.classifiedEvents[i].length; j++) {
+ var item = test.classifiedEvents[i][j];
+ is(item, test.expectedEvents[i][j],
+ test.description + ": Wrong order of events");
+ }
+ }
+}
+
+function embeddedHandler(e)
+{
+ return handler(e, kChild);
+}
+
+function embedderHandler(e, callback)
+{
+ handler(e, kParent, callback);
+}
+
+function handler(e, highBit, callback)
+{
+ var code = convertNameToCode(e.type);
+ var newCode = highBit | code;
+ gCurrentTest.resultEvents.push(newCode);
+
+ if (callback) {
+ callback(code);
+ }
+
+ if (highBit == kChild) {
+ // return and let frameScript to handle
+ return newCode == gCurrentTest.doPreventDefaultAt;
+ }
+
+ if (newCode == gCurrentTest.doPreventDefaultAt) {
+ e.preventDefault();
+ }
+}
+
+function embedderHandlerWithCheck(e)
+{
+ // Verify value of attribute embeddedCancelled
+ embedderHandler(e, function checkEmbeddedCancelled(code){
+ switch (code) {
+ case kBeforeEvent | kKeyDownEvent:
+ case kBeforeEvent | kKeyUpEvent:
+ is(e.embeddedCancelled, null,
+ gCurrentTest.description + ": embeddedCancelled should be null");
+ break;
+ case kAfterEvent | kKeyDownEvent:
+ if ((gCurrentTest.doPreventDefaultAt & 0xFF) == kKeyDownEvent) {
+ is(e.embeddedCancelled, true,
+ gCurrentTest.description + ": embeddedCancelled should be true");
+ } else {
+ is(e.embeddedCancelled, false,
+ gCurrentTest.description + ": embeddedCancelled should be false");
+ }
+ break;
+ case kAfterEvent | kKeyUpEvent:
+ if ((gCurrentTest.doPreventDefaultAt & 0xFF) == kKeyUpEvent) {
+ is(e.embeddedCancelled, true,
+ gCurrentTest.description + ": embeddedCancelled should be true");
+ } else {
+ is(e.embeddedCancelled, false,
+ gCurrentTest.description + ": embeddedCancelled should be false");
+ }
+ break;
+ default:
+ break;
+ }
+ });
+}
diff --git a/dom/events/test/chrome.ini b/dom/events/test/chrome.ini
new file mode 100644
index 000000000..111100a75
--- /dev/null
+++ b/dom/events/test/chrome.ini
@@ -0,0 +1,28 @@
+[DEFAULT]
+skip-if = os == 'android'
+support-files =
+ bug415498-doc1.html
+ bug415498-doc2.html
+ bug418986-3.js
+ bug591249_iframe.xul
+ bug602962.xul
+ file_bug679494.html
+ window_bug617528.xul
+ test_bug336682.js
+
+[test_bug336682_2.xul]
+[test_bug368835.html]
+[test_bug415498.xul]
+[test_bug418986-3.xul]
+[test_bug524674.xul]
+[test_bug586961.xul]
+[test_bug591249.xul]
+[test_bug602962.xul]
+[test_bug617528.xul]
+[test_bug679494.xul]
+[test_bug930374-chrome.html]
+[test_bug1128787-1.html]
+[test_bug1128787-2.html]
+[test_bug1128787-3.html]
+[test_eventctors.xul]
+[test_DataTransferItemList.html]
diff --git a/dom/events/test/empty.js b/dom/events/test/empty.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/dom/events/test/empty.js
diff --git a/dom/events/test/error_event_worker.js b/dom/events/test/error_event_worker.js
new file mode 100644
index 000000000..9f6e0e4bd
--- /dev/null
+++ b/dom/events/test/error_event_worker.js
@@ -0,0 +1,15 @@
+ 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: message, filename: filename, lineno: lineno,
+ type: "callback" }
+ postMessage(obj);
+ return false;
+}
+throw new Error("workerhello");
diff --git a/dom/events/test/file_bug679494.html b/dom/events/test/file_bug679494.html
new file mode 100644
index 000000000..a2e47916c
--- /dev/null
+++ b/dom/events/test/file_bug679494.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+ <title>Test for Bug 679494</title>
+</head>
+<body>
+ There and back again.
+</body>
+</html>
diff --git a/dom/events/test/marionette/head.js b/dom/events/test/marionette/head.js
new file mode 100644
index 000000000..c2357f898
--- /dev/null
+++ b/dom/events/test/marionette/head.js
@@ -0,0 +1,142 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const {Cc: Cc, Ci: Ci, Cr: Cr, Cu: Cu} = SpecialPowers;
+
+var Promise = Cu.import("resource://gre/modules/Promise.jsm").Promise;
+
+var _pendingEmulatorCmdCount = 0;
+
+/**
+ * Send emulator command with safe guard.
+ *
+ * We should only call |finish()| after all emulator command transactions
+ * end, so here comes with the pending counter. Resolve when the emulator
+ * gives positive response, and reject otherwise.
+ *
+ * Fulfill params:
+ * result -- an array of emulator response lines.
+ * Reject params:
+ * result -- an array of emulator response lines.
+ *
+ * @return A deferred promise.
+ */
+function runEmulatorCmdSafe(aCommand) {
+ let deferred = Promise.defer();
+
+ ++_pendingEmulatorCmdCount;
+ runEmulatorCmd(aCommand, function(aResult) {
+ --_pendingEmulatorCmdCount;
+
+ ok(true, "Emulator response: " + JSON.stringify(aResult));
+ if (Array.isArray(aResult) &&
+ aResult[aResult.length - 1] === "OK") {
+ deferred.resolve(aResult);
+ } else {
+ deferred.reject(aResult);
+ }
+ });
+
+ return deferred.promise;
+}
+
+/**
+ * Get emulator sensor values of a named sensor.
+ *
+ * Fulfill params:
+ * result -- an array of emulator sensor values.
+ * Reject params: (none)
+ *
+ * @param aSensorName
+ * A string name of the sensor. Availables are: "acceleration"
+ * "magnetic-field", "orientation", "temperature", "proximity".
+ *
+ * @return A deferred promise.
+ */
+function getEmulatorSensorValues(aSensorName) {
+ return runEmulatorCmdSafe("sensor get " + aSensorName)
+ .then(function(aResult) {
+ // aResult = ["orientation = 0:0:0", "OK"]
+ return aResult[0].split(" ")[2].split(":").map(function(aElement) {
+ return parseInt(aElement, 10);
+ });
+ });
+}
+
+/**
+ * Convenient alias function for getting orientation sensor values.
+ */
+function getEmulatorOrientationValues() {
+ return getEmulatorSensorValues("orientation");
+}
+
+/**
+ * Set emulator orientation sensor values.
+ *
+ * Fulfill params: (none)
+ * Reject params: (none)
+ *
+ * @param aAzimuth
+ * @param aPitch
+ * @param aRoll
+ *
+ * @return A deferred promise.
+ */
+function setEmulatorOrientationValues(aAzimuth, aPitch, aRoll) {
+ let cmd = "sensor set orientation " + aAzimuth + ":" + aPitch + ":" + aRoll;
+ return runEmulatorCmdSafe(cmd);
+}
+
+/**
+ * Wait for a named window event.
+ *
+ * Resolve if that named event occurs. Never reject.
+ *
+ * Forfill params: the DOMEvent passed.
+ *
+ * @param aEventName
+ * A string event name.
+ *
+ * @return A deferred promise.
+ */
+function waitForWindowEvent(aEventName) {
+ let deferred = Promise.defer();
+
+ window.addEventListener(aEventName, function onevent(aEvent) {
+ window.removeEventListener(aEventName, onevent);
+
+ ok(true, "Window event '" + aEventName + "' got.");
+ deferred.resolve(aEvent);
+ });
+
+ return deferred.promise;
+}
+
+/**
+ * Wait for pending emulator transactions and call |finish()|.
+ */
+function cleanUp() {
+ // Use ok here so that we have at least one test run.
+ ok(true, ":: CLEANING UP ::");
+
+ waitFor(finish, function() {
+ return _pendingEmulatorCmdCount === 0;
+ });
+}
+
+/**
+ * Basic test routine helper.
+ *
+ * This helper does nothing but clean-ups.
+ *
+ * @param aTestCaseMain
+ * A function that takes no parameter.
+ */
+function startTestBase(aTestCaseMain) {
+ Promise.resolve()
+ .then(aTestCaseMain)
+ .then(cleanUp, function() {
+ ok(false, 'promise rejects during test.');
+ cleanUp();
+ });
+}
diff --git a/dom/events/test/marionette/manifest.ini b/dom/events/test/marionette/manifest.ini
new file mode 100644
index 000000000..b0ec98d99
--- /dev/null
+++ b/dom/events/test/marionette/manifest.ini
@@ -0,0 +1,4 @@
+[DEFAULT]
+run-if = buildapp == 'b2g'
+
+[test_sensor_orientation.js]
diff --git a/dom/events/test/marionette/test_sensor_orientation.js b/dom/events/test/marionette/test_sensor_orientation.js
new file mode 100644
index 000000000..70df0ccd3
--- /dev/null
+++ b/dom/events/test/marionette/test_sensor_orientation.js
@@ -0,0 +1,53 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 120000;
+MARIONETTE_HEAD_JS = 'head.js';
+
+function doTest(aAzimuth, aPitch, aRoll) {
+ log("Testing [azimuth, pitch, roll] = " + Array.slice(arguments));
+
+ return setEmulatorOrientationValues(aAzimuth, aPitch, aRoll)
+ .then(() => waitForWindowEvent("deviceorientation"))
+ .then(function(aEvent) {
+ is(aEvent.alpha, aAzimuth, "azimuth");
+ is(aEvent.beta, aPitch, "pitch");
+ is(aEvent.gamma, aRoll, "roll");
+ });
+}
+
+function testAllPermutations() {
+ const angles = [-180, -90, 0, 90, 180];
+ let promise = Promise.resolve();
+ for (let i = 0; i < angles.length; i++) {
+ for (let j = 0; j < angles.length; j++) {
+ for (let k = 0; k < angles.length; k++) {
+ promise =
+ promise.then(doTest.bind(null, angles[i], angles[j], angles[k]));
+ }
+ }
+ }
+ return promise;
+}
+
+startTestBase(function() {
+ let origValues;
+
+ return Promise.resolve()
+
+ // Retrieve original status.
+ .then(() => getEmulatorOrientationValues())
+ .then(function(aValues) {
+ origValues = aValues;
+ is(typeof origValues, "object", "typeof origValues");
+ is(origValues.length, 3, "origValues.length");
+ })
+
+ // Test original status
+ .then(() => doTest.apply(null, origValues))
+
+ .then(testAllPermutations)
+
+ // Restore original status.
+ .then(() => setEmulatorOrientationValues.apply(null, origValues));
+});
diff --git a/dom/events/test/mochitest.ini b/dom/events/test/mochitest.ini
new file mode 100644
index 000000000..e100e60a1
--- /dev/null
+++ b/dom/events/test/mochitest.ini
@@ -0,0 +1,186 @@
+[DEFAULT]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+support-files =
+ bug226361_iframe.xhtml
+ bug299673.js
+ bug322588-popup.html
+ bug426082.html
+ bug656379-1.html
+ bug418986-3.js
+ error_event_worker.js
+ empty.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_addEventListenerExtraArg.html]
+[test_all_synthetic_events.html]
+[test_bug226361.xhtml]
+[test_bug238987.html]
+[test_bug288392.html]
+[test_bug299673-1.html]
+[test_bug1037990.html]
+[test_bug299673-2.html]
+[test_bug322588.html]
+[test_bug328885.html]
+[test_bug336682_1.html]
+support-files = test_bug336682.js
+[test_bug367781.html]
+[test_bug368835.html]
+[test_bug379120.html]
+[test_bug391568.xhtml]
+[test_bug402089.html]
+[test_bug405632.html]
+[test_bug409604.html]
+skip-if = toolkit == 'android' #TIMED_OUT
+[test_bug412567.html]
+[test_bug418986-3.html]
+[test_bug422132.html]
+[test_bug426082.html]
+[test_bug427537.html]
+[test_bug428988.html]
+[test_bug432698.html]
+[test_bug443985.html]
+[test_bug447736.html]
+[test_bug448602.html]
+[test_bug450876.html]
+[test_bug456273.html]
+[test_bug457672.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug489671.html]
+[test_bug493251.html]
+[test_bug502818.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug508479.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM # drag event fails
+[test_bug517851.html]
+[test_bug534833.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug545268.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug547996-1.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug547996-2.xhtml]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug556493.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug563329.html]
+skip-if = true # Disabled due to timeouts.
+[test_bug574663.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug591815.html]
+[test_bug593959.html]
+[test_bug603008.html]
+skip-if = toolkit == 'android'
+[test_bug605242.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug607464.html]
+skip-if = toolkit == 'android' || (e10s && os == 'win') || (e10s && os == "mac") #CRASH_DUMP, RANDOM, bug 1252273
+[test_bug613634.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug615597.html]
+[test_bug624127.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug635465.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug641477.html]
+[test_bug648573.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug650493.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug656379-1.html]
+skip-if = toolkit == 'android'
+[test_bug656379-2.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug656954.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug659071.html]
+[test_bug659350.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug662678.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug667612.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug667919-1.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug684208.html]
+[test_bug689564.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug698929.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_bug704423.html]
+[test_bug741666.html]
+[test_bug742376.html]
+[test_bug812744.html]
+[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 = (e10s && os == "mac") # bug 1252273
+[test_bug967796.html]
+skip-if = e10s # bug 1251659
+[test_bug985988.html]
+[test_bug998809.html]
+[test_bug1003432.html]
+support-files = test_bug1003432.js
+[test_bug1013412.html]
+[test_bug1017086_disable.html]
+support-files = bug1017086_inner.html
+[test_bug1017086_enable.html]
+support-files = bug1017086_inner.html
+[test_bug1079236.html]
+[test_bug1096146.html]
+support-files =
+ bug1096146_embedded.html
+[test_bug1145910.html]
+[test_bug1150308.html]
+[test_bug1248459.html]
+[test_bug1264380.html]
+run-if = (e10s && os != "win") # Bug 1270043, crash at windows platforms; Bug1264380 comment 20, nsDragService::InvokeDragSessionImpl behaves differently among platform implementations in non-e10s mode which prevents us to check the validity of nsIDragService::getCurrentSession() consistently via synthesize mouse clicks in non-e10s mode.
+[test_clickevent_on_input.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_continuous_wheel_events.html]
+[test_dblclick_explicit_original_target.html]
+[test_dom_activate_event.html]
+[test_dom_before_after_keyboard_event.html]
+support-files =
+ bug989198_embedded.html
+ bug989198_helper.js
+[test_dom_before_after_keyboard_event_remote.html]
+support-files =
+ bug989198_embedded.html
+ bug989198_helper.js
+skip-if = e10s
+[test_dom_keyboard_event.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_dom_mouse_event.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_dom_storage_event.html]
+[test_dom_wheel_event.html]
+[test_draggableprop.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_dragstart.html]
+[test_error_events.html]
+skip-if = toolkit == 'android' #TIMED_OUT
+[test_eventctors.html]
+skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
+[test_eventhandler_scoping.html]
+[test_eventTimeStamp.html]
+[test_focus_disabled.html]
+[test_legacy_event.html]
+[test_messageEvent.html]
+[test_messageEvent_init.html]
+[test_moz_mouse_pixel_scroll_event.html]
+[test_offsetxy.html]
+[test_onerror_handler_args.html]
+[test_passive_listeners.html]
+[test_paste_image.html]
+[test_wheel_default_action.html]
+[test_bug687787.html]
+[test_bug1298970.html]
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 000000000..cd5c2b36e
--- /dev/null
+++ b/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_1.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Events properties tests</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("implicit pointer capture for touch");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ let target0 = window.document.getElementById("target0");
+ let target1 = window.document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ detected_pointertypes[event.pointerType] = true;
+ assert_true(true, "target0 receives pointerdown");
+ });
+
+ on_event(target0, "pointermove", function (event) {
+ assert_true(true, "target0 receives pointermove");
+ assert_true(target0.hasPointerCapture(event.pointerId), "target0.hasPointerCapture should be true");
+ });
+
+ on_event(target0, "gotpointercapture", function (event) {
+ assert_true(true, "target0 should receive gotpointercapture");
+ });
+
+ on_event(target0, "lostpointercapture", function (event) {
+ assert_true(true, "target0 should receive lostpointercapture");
+ });
+
+ on_event(target1, "pointermove", function (event) {
+ assert_true(false, "target1 should not receive pointermove");
+ });
+
+ on_event(target0, "pointerup", function (event) {
+ assert_true(true, "target0 receives pointerup");
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events tests</h1>
+ <div id="target0" style="width: 200px; height: 200px; background: green" touch-action:none></div>
+ <div id="target1" style="width: 200px; height: 200px; background: green" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
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 000000000..e84faacf6
--- /dev/null
+++ b/dom/events/test/pointerevents/bug1293174_implicit_pointer_capture_for_touch_2.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Events properties tests</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("implicit pointer capture for touch");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ let target0 = window.document.getElementById("target0");
+ let target1 = window.document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ detected_pointertypes[event.pointerType] = true;
+ assert_true(true, "target0 receives pointerdown");
+ });
+
+ on_event(target0, "pointermove", function (event) {
+ assert_true(true, "target0 receives pointermove");
+ assert_false(target0.hasPointerCapture(event.pointerId), "target0.hasPointerCapture should be false");
+ });
+
+ on_event(target0, "gotpointercapture", function (event) {
+ assert_unreached("target0 should not receive gotpointercapture");
+ });
+
+ on_event(target0, "lostpointercapture", function (event) {
+ assert_unreached("target0 should not receive lostpointercapture");
+ });
+
+ on_event(target1, "pointermove", function (event) {
+ assert_true(true, "target1 receives pointermove");
+ assert_false(target1.hasPointerCapture(), "target1.hasPointerCapture should be false");
+ });
+
+ on_event(target0, "pointerup", function (event) {
+ assert_true(true, "target0 receives pointerup");
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events tests</h1>
+ <div id="target0" style="width: 200px; height: 200px; background: green" touch-action:none></div>
+ <div id="target1" style="width: 200px; height: 200px; background: green" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/mochitest.ini b/dom/events/test/pointerevents/mochitest.ini
new file mode 100644
index 000000000..58eae12fe
--- /dev/null
+++ b/dom/events/test/pointerevents/mochitest.ini
@@ -0,0 +1,152 @@
+[DEFAULT]
+skip-if = os == 'android' # Bug 1312791
+support-files =
+ mochitest_support_external.js
+ mochitest_support_internal.js
+ pointerevent_styles.css
+ pointerevent_support.js
+
+[test_pointerevent_attributes_mouse-manual.html]
+ support-files = pointerevent_attributes_mouse-manual.html
+[test_pointerevent_capture_mouse-manual.html]
+ support-files = pointerevent_capture_mouse-manual.html
+[test_pointerevent_capture_suppressing_mouse-manual.html]
+ support-files = pointerevent_capture_suppressing_mouse-manual.html
+[test_pointerevent_change-touch-action-onpointerdown_touch-manual.html]
+ support-files = pointerevent_change-touch-action-onpointerdown_touch-manual.html
+ disabled = disabled
+[test_pointerevent_constructor.html]
+ support-files = pointerevent_constructor.html
+[test_pointerevent_element_haspointercapture-manual.html]
+ support-files = pointerevent_element_haspointercapture-manual.html
+[test_pointerevent_element_haspointercapture_release_pending_capture-manual.html]
+ support-files = pointerevent_element_haspointercapture_release_pending_capture-manual.html
+[test_pointerevent_gotpointercapture_before_first_pointerevent-manual.html]
+ support-files = pointerevent_gotpointercapture_before_first_pointerevent-manual.html
+[test_pointerevent_lostpointercapture_for_disconnected_node-manual.html]
+ support-files = pointerevent_lostpointercapture_for_disconnected_node-manual.html
+[test_pointerevent_lostpointercapture_is_first-manual.html]
+ support-files = pointerevent_lostpointercapture_is_first-manual.html
+[test_pointerevent_multiple_primary_pointers_boundary_events-manual.html]
+ support-files = pointerevent_multiple_primary_pointers_boundary_events-manual.html
+ disabled = should be investigated
+[test_pointerevent_pointercancel_touch-manual.html]
+ support-files = pointerevent_pointercancel_touch-manual.html
+[test_pointerevent_pointerdown-manual.html]
+ support-files = pointerevent_pointerdown-manual.html
+[test_pointerevent_pointerenter_does_not_bubble-manual.html]
+ support-files = pointerevent_pointerenter_does_not_bubble-manual.html
+[test_pointerevent_pointerenter_nohover-manual.html]
+ support-files = pointerevent_pointerenter_nohover-manual.html
+[test_pointerevent_pointerId_scope-manual.html]
+ support-files =
+ test_pointerevent_pointerId_scope-manual.html
+ ./resources/pointerevent_pointerId_scope-iframe.html
+ disabled = should be investigated
+[test_pointerevent_pointerenter-manual.html]
+ support-files = pointerevent_pointerenter-manual.html
+[test_pointerevent_pointerleave_after_pointercancel_touch-manual.html]
+ support-files = pointerevent_pointerleave_after_pointercancel_touch-manual.html
+[test_pointerevent_pointerleave_after_pointerup_nohover-manual.html]
+ support-files = pointerevent_pointerleave_after_pointerup_nohover-manual.html
+[test_pointerevent_pointerleave_descendant_over-manual.html]
+ support-files = pointerevent_pointerleave_descendant_over-manual.html
+[test_pointerevent_pointerleave_descendants-manual.html]
+ support-files = pointerevent_pointerleave_descendants-manual.html
+[test_pointerevent_pointerleave_does_not_bubble-manual.html]
+ support-files = pointerevent_pointerleave_does_not_bubble-manual.html
+[test_pointerevent_pointerleave_mouse-manual.html]
+ support-files = pointerevent_pointerleave_mouse-manual.html
+[test_pointerevent_pointerleave_pen-manual.html]
+ support-files = pointerevent_pointerleave_pen-manual.html
+[test_pointerevent_pointerleave_touch-manual.html]
+ support-files = pointerevent_pointerleave_touch-manual.html
+[test_pointerevent_pointermove-manual.html]
+ support-files = pointerevent_pointermove-manual.html
+[test_pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html]
+ support-files = pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html
+[test_pointerevent_pointermove-on-chorded-mouse-button.html]
+ support-files = pointerevent_pointermove-on-chorded-mouse-button.html
+[test_pointerevent_pointermove_pointertype-manual.html]
+ support-files = pointerevent_pointermove_pointertype-manual.html
+[test_pointerevent_pointerout-manual.html]
+ support-files = pointerevent_pointerout-manual.html
+[test_pointerevent_pointerout_after_pointercancel_touch-manual.html]
+ support-files = pointerevent_pointerout_after_pointercancel_touch-manual.html
+[test_pointerevent_pointerout_after_pointerup_nohover-manual.html]
+ support-files = pointerevent_pointerout_after_pointerup_nohover-manual.html
+[test_pointerevent_pointerout_pen-manual.html]
+ support-files = pointerevent_pointerout_pen-manual.html
+[test_pointerevent_pointerout_received_once-manual.html]
+ support-files = pointerevent_pointerout_received_once-manual.html
+[test_pointerevent_pointerover-manual.html]
+ support-files = pointerevent_pointerover-manual.html
+[test_pointerevent_pointertype_mouse-manual.html]
+ support-files = pointerevent_pointertype_mouse-manual.html
+[test_pointerevent_pointertype_pen-manual.html]
+ support-files = pointerevent_pointertype_pen-manual.html
+[test_pointerevent_pointertype_touch-manual.html]
+ support-files = pointerevent_pointertype_touch-manual.html
+[test_pointerevent_pointerup-manual.html]
+ support-files = pointerevent_pointerup-manual.html
+[test_pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html]
+ support-files = pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html
+[test_pointerevent_pointerup_pointertype-manual.html]
+ support-files = pointerevent_pointerup_pointertype-manual.html
+[test_pointerevent_releasepointercapture_events_to_original_target-manual.html]
+ support-files = pointerevent_releasepointercapture_events_to_original_target-manual.html
+[test_pointerevent_releasepointercapture_invalid_pointerid-manual.html]
+ support-files = pointerevent_releasepointercapture_invalid_pointerid-manual.html
+[test_pointerevent_releasepointercapture_onpointercancel_touch-manual.html]
+ support-files = pointerevent_releasepointercapture_onpointercancel_touch-manual.html
+[test_pointerevent_releasepointercapture_onpointerup_mouse-manual.html]
+ support-files = pointerevent_releasepointercapture_onpointerup_mouse-manual.html
+[test_pointerevent_releasepointercapture_release_right_after_capture-manual.html]
+ support-files = pointerevent_releasepointercapture_release_right_after_capture-manual.html
+[test_pointerevent_setpointercapture_disconnected-manual.html]
+ support-files = pointerevent_setpointercapture_disconnected-manual.html
+[test_pointerevent_setpointercapture_inactive_button_mouse-manual.html]
+ support-files = pointerevent_setpointercapture_inactive_button_mouse-manual.html
+ disabled = should be investigated
+[test_pointerevent_setpointercapture_invalid_pointerid-manual.html]
+ support-files = pointerevent_setpointercapture_invalid_pointerid-manual.html
+[test_pointerevent_setpointercapture_override_pending_capture_element-manual.html]
+ support-files = pointerevent_setpointercapture_override_pending_capture_element-manual.html
+[test_pointerevent_setpointercapture_relatedtarget-manual.html]
+ support-files = pointerevent_setpointercapture_relatedtarget-manual.html
+[test_pointerevent_setpointercapture_to_same_element_twice-manual.html]
+ support-files = pointerevent_setpointercapture_to_same_element_twice-manual.html
+[test_pointerevent_suppress_compat_events_on_click.html]
+ support-files = pointerevent_suppress_compat_events_on_click.html
+ disabled = should be investigated
+[test_pointerevent_suppress_compat_events_on_drag_mouse.html]
+ support-files = pointerevent_suppress_compat_events_on_drag_mouse.html
+ disabled = should be investigated
+[test_touch_action.html]
+ 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
+ pointerevent_touch-action-auto-css_touch-manual.html
+ pointerevent_touch-action-button-test_touch-manual.html
+ pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html
+ pointerevent_touch-action-inherit_child-none_touch-manual.html
+ pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html
+ pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html
+ pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html
+ pointerevent_touch-action-inherit_parent-none_touch-manual.html
+ pointerevent_touch-action-none-css_touch-manual.html
+ pointerevent_touch-action-pan-x-css_touch-manual.html
+ pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html
+ pointerevent_touch-action-pan-x-pan-y_touch-manual.html
+ pointerevent_touch-action-pan-y-css_touch-manual.html
+ pointerevent_touch-action-span-test_touch-manual.html
+ pointerevent_touch-action-svg-test_touch-manual.html
+ pointerevent_touch-action-table-test_touch-manual.html
+[test_bug1285128.html]
+[test_bug1293174_implicit_pointer_capture_for_touch_1.html]
+ support-files = bug1293174_implicit_pointer_capture_for_touch_1.html
+[test_bug1293174_implicit_pointer_capture_for_touch_2.html]
+ support-files = bug1293174_implicit_pointer_capture_for_touch_2.html
+[test_empty_file.html]
+ disabled = disabled # Bug 1150091 - Issue with support-files
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 000000000..01c340728
--- /dev/null
+++ b/dom/events/test/pointerevents/mochitest_support_external.js
@@ -0,0 +1,123 @@
+// This file supports translating W3C tests
+// to tests on auto MochiTest system with minimum changes.
+// Author: Maksim Lebedev <alessarik@gmail.com>
+
+// 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();
+ turnOnPointerEvents(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);
+}
+
+function turnOnPointerEvents(callback) {
+ console.log("SET dom.w3c_pointer_events.enabled as TRUE");
+ console.log("SET layout.css.touch_action.enabled as TRUE");
+ SpecialPowers.pushPrefEnv({
+ "set": [
+ ["dom.w3c_pointer_events.enabled", true],
+ ["layout.css.touch_action.enabled", true]
+ ]
+ }, callback);
+}
+
+// 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 = {type: mouseEventType};
+ if(params && "button" in params)
+ eventObj.button = params.button;
+ if(params && "inputSource" in params)
+ eventObj.inputSource = params.inputSource;
+ if(params && "buttons" in params)
+ eventObj.buttons = params.buttons;
+
+ // 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 TouchEvent with different parameters
+function sendTouchEvent(int_win, elemId, touchEventType, params) {
+ var elem = int_win.document.getElementById(elemId);
+ if(!!elem) {
+ var rect = elem.getBoundingClientRect();
+ var eventObj = {type: touchEventType};
+
+ // 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 run Point Event test in a new tab.
+function runTestInNewWindow(aFile) {
+ var w = window.open('', "_blank");
+ w.is = function(a, b, msg) { return is(a, b, aFile + " | " + msg); };
+ w.ok = function(cond, name, diag) { return ok(cond, aFile + " | " + name, diag); };
+ w.location = location.href.substring(0, location.href.lastIndexOf('/') + 1) + aFile;
+
+ w.testContext = {
+ result_callback: (aTestObj) => {
+ if(aTestObj["status"] != aTestObj["PASS"]) {
+ console.log(aTestObj["status"] + " = " + aTestObj["PASS"] + ". " + aTestObj["name"]);
+ }
+ is(aTestObj["status"], aTestObj["PASS"], aTestObj["name"]);
+ },
+
+ completion_callback: () => {
+ if (!!w.testContext.executionPromise) {
+ // We need to wait tests done and execute finished then we can close the window
+ w.testContext.executionPromise.then(() => {
+ w.close();
+ SimpleTest.finish();
+ });
+ } else {
+ // execute may synchronous trigger tests done. In that case executionPromise
+ // is not yet assigned
+ w.close();
+ SimpleTest.finish();
+ }
+ },
+
+ execute: (aWindow) => {
+ turnOnPointerEvents(() => {
+ w.testContext.executionPromise = new Promise((aResolve, aReject) => {
+ executeTest(aWindow);
+ aResolve();
+ });
+ });
+ }
+ };
+ return w;
+}
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 000000000..f8161362c
--- /dev/null
+++ b/dom/events/test/pointerevents/mochitest_support_internal.js
@@ -0,0 +1,31 @@
+// This file supports translating W3C tests
+// to tests on auto MochiTest system with minimum changes.
+// Author: Maksim Lebedev <alessarik@gmail.com>
+
+// Function allows to prepare our tests after load document
+addEventListener("load", function(event) {
+ console.log("OnLoad internal document");
+ addListeners(document.getElementById("target0"));
+ addListeners(document.getElementById("target1"));
+ preExecute();
+}, false);
+
+// Function allows to initialize prerequisites before testing
+// and adds some callbacks to support mochitest system.
+function preExecute() {
+ add_result_callback(testContext.result_callback);
+ add_completion_callback(testContext.completion_callback);
+ testContext.execute(window);
+}
+
+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+')');
+ }, false);
+ });
+}
diff --git a/dom/events/test/pointerevents/pointerevent_attributes_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_attributes_mouse-manual.html
new file mode 100644
index 000000000..a54e79911
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_attributes_mouse-manual.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Events properties tests</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ var detected_eventTypes = {};
+ var test_pointerEvent = async_test("pointerevent attributes");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var square1 = document.getElementById("square1");
+ var rectSquare1 = square1.getBoundingClientRect();
+ var pointerover_event;
+
+ var eventList = ['pointerenter', 'pointerover', 'pointermove', 'pointerdown', 'pointerup', 'pointerout', 'pointerleave'];
+ eventList.forEach(function(eventName) {
+ on_event(square1, eventName, function (event) {
+ if (detected_eventTypes[event.type])
+ return;
+ detected_pointertypes[event.pointerType] = true;
+ test(function () {
+ assert_equals(event.pointerType, 'mouse', 'pointerType should be mouse');
+ }, event.type + ".pointerType attribute is correct.");
+
+ // Test button and buttons
+ if (event.type == 'pointerdown') {
+ test(function() {
+ assert_true(event.button == 0, "If left mouse button is pressed button attribute is 0")
+ }, event.type + "'s button attribute is 0 when left mouse button is pressed.");
+ test(function() {
+ assert_true(event.buttons == 1, "If left mouse button is pressed buttons attribute is 1")
+ }, event.type + "'s buttons attribute is 1 when left mouse button is pressed.");
+ } else if (event.type == 'pointerup') {
+ test(function() {
+ assert_true(event.button == 0, "If left mouse button is just released button attribute is 0")
+ }, event.type + "'s button attribute is 0 when left mouse button is just released.");
+ test(function() {
+ assert_true(event.buttons == 0, "If left mouse button is just released buttons attribute is 0")
+ }, event.type + "'s buttons attribute is 0 when left mouse button is just released.");
+ } else {
+ test(function() {
+ assert_true(event.button == -1, "If mouse buttons are released button attribute is -1")
+ }, event.type + "'s button is -1 when mouse buttons are released.");
+ test(function() {
+ assert_true(event.buttons == 0, "If mouse buttons are released buttons attribute is 0")
+ }, event.type + "'s buttons is 0 when mouse buttons are released.");
+ }
+
+ // Test clientX and clientY
+ if (event.type != 'pointerout' && event.type != 'pointerleave' ) {
+ test(function () {
+ assert_true(event.clientX >= rectSquare1.left && event.clientX < rectSquare1.right, "ClientX should be in the boundaries of the black box");
+ }, event.type + ".clientX attribute is correct.");
+ test(function () {
+ assert_true(event.clientY >= rectSquare1.top && event.clientY < rectSquare1.bottom, "ClientY should be in the boundaries of the black box");
+ }, event.type + ".clientY attribute is correct.");
+ } else {
+ test(function () {
+ assert_true(event.clientX < rectSquare1.left || event.clientX > rectSquare1.right - 1 || event.clientY < rectSquare1.top || event.clientY > rectSquare1.bottom - 1, "ClientX/Y should be out of the boundaries of the black box");
+ }, event.type + "'s ClientX and ClientY attributes are correct.");
+ }
+
+ // Test isPrimary
+ test(function () {
+ assert_equals(event.isPrimary, true, "isPrimary should be true");
+ }, event.type + ".isPrimary attribute is correct.");
+
+ // Test width and height
+ test(function () {
+ assert_equals(event.width, 1, "width of mouse should be 1");
+ }, event.type + ".width attribute is correct.");
+ test(function () {
+ assert_equals(event.height, 1, "height of mouse should be 1");
+ }, event.type + ".height attribute is correct.");
+
+ check_PointerEvent(event);
+ detected_eventTypes[event.type] = true;
+ if (Object.keys(detected_eventTypes).length == eventList.length)
+ test_pointerEvent.done();
+ });
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events pointerdown tests</h1>
+ <!--
+ <h4>
+ Test Description: This test checks the properties of mouse pointer events. Move your mouse over the black square and click on it. Then move it off the black square.
+ </h4>
+ -->
+ Test passes if the proper behavior of the events is observed.
+ <div id="square1" class="square"></div>
+ <div class="spacer"></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
+
diff --git a/dom/events/test/pointerevents/pointerevent_capture_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_capture_mouse-manual.html
new file mode 100644
index 000000000..63e8af777
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_capture_mouse-manual.html
@@ -0,0 +1,135 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Set/Release capture</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body>
+ <!--
+ <h1>Pointer Events capture test</h1>
+ <h4>
+ Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions:
+ <ol>
+ <li> Move your mouse over the black rectangle. pointermove event should be logged in the black rectangle</li>
+ <li> Move your mouse over the purple rectangle. pointerover event should be logged in the purple rectangle</li>
+ <li> Press and hold left mouse button over "Set Capture" button. "gotpointercapture" should be logged in the black rectangle</li>
+ <li> Move your mouse anywhere. pointermove should be logged in the black rectangle</li>
+ <li> Move your mouse over the purple rectangle. Nothig should happen</li>
+ <li> Move your mouse over the black rectangle. pointermove should be logged in the black rectangle</li>
+ <li> Release left mouse button. "lostpointercapture" should be logged in the black rectangle</li>
+ </ol>
+ </h4>
+ Test passes if the proper behaviour of the events is observed.
+ -->
+ <div id="target0"></div>
+ <br>
+ <div id="target1"></div>
+ <br>
+ <input type="button" id="btnCapture" value="Set Capture">
+ <script type='text/javascript'>
+ var isPointerCapture = false;
+ var pointermoveNoCaptureGot0 = false;
+ var pointermoveCaptureGot0 = false;
+ var pointermoveNoCaptureGot1 = false;
+ var ownEventForTheCapturedTargetGot = false;
+ var count=0;
+
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var target0 = document.getElementById('target0');
+ var target1 = document.getElementById('target1');
+ var captureButton = document.getElementById('btnCapture');
+
+ var test_gotpointercapture = async_test("gotpointercapture event received");
+ var test_lostpointercapture = async_test("lostpointercapture event received");
+
+ window.onload = function() {
+ on_event(captureButton, 'pointerdown', function(e) {
+ if(isPointerCapture == false) {
+ isPointerCapture = true;
+ sPointerCapture(e);
+ }
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ test_gotpointercapture.done();
+ log("gotpointercapture", target0);
+ });
+
+ on_event(target0, 'lostpointercapture', function(e) {
+ test_lostpointercapture.done();
+ isPointerCapture = false;
+ log("lostpointercapture", target0);
+ });
+
+ run();
+ }
+
+ function run() {
+ var test_pointermove0 = async_test("pointerover event for black rectangle received")
+ var test_pointermove1 = async_test("pointerover event for purple rectangle received")
+
+ on_event(target0, "pointermove", function (event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ if(!pointermoveNoCaptureGot0) {
+ test_pointermove0.done();
+ log("pointermove", document.getElementById('target0'));
+ pointermoveNoCaptureGot0 = true;
+ }
+ if(isPointerCapture) {
+ if(!pointermoveCaptureGot0) {
+ test(function() {
+ assert_true(event.relatedTarget==null, "relatedTarget is null when the capture is set")
+ }, "relatedTarget is null when the capture is set. relatedTarget is " + event.relatedTarget);
+ test(function() {
+ assert_true((event.clientX < target0.getBoundingClientRect().left)||
+ (event.clientX > target0.getBoundingClientRect().right)||
+ (event.clientY < target0.getBoundingClientRect().top)||
+ (event.clientY > target0.getBoundingClientRect().bottom),
+ "pointermove received for captured element while out of it")
+ }, "pointermove received for captured element while out of it");
+ log("pointermove", document.getElementById('target0'));
+ pointermoveCaptureGot0 = true;
+ }
+ if((event.clientX > target0.getBoundingClientRect().left)&&
+ (event.clientX < target0.getBoundingClientRect().right)&&
+ (event.clientY > target0.getBoundingClientRect().top)&&
+ (event.clientY < target0.getBoundingClientRect().bottom)&&
+ !ownEventForTheCapturedTargetGot) {
+ test(function() {
+ assert_true(true, "pointermove received for captured element while inside of it");
+ }, "pointermove received for captured element while inside of it");
+ log("pointermove", document.getElementById('target0'));
+ ownEventForTheCapturedTargetGot = true;
+ }
+ }
+ });
+
+ on_event(target1, "pointermove", function (event) {
+ if(isPointerCapture == true) {
+ test(function() {
+ assert_unreached("pointermove shouldn't trigger for this target when capture is enabled");
+ }, "pointermove shouldn't trigger for the purple rectangle while the black rectangle has capture");
+ }
+ if(!pointermoveNoCaptureGot1) {
+ test_pointermove1.done();
+ log("pointermove", document.getElementById('target1'));
+ pointermoveNoCaptureGot1 = true;
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_capture_suppressing_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_capture_suppressing_mouse-manual.html
new file mode 100644
index 000000000..6b891b846
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_capture_suppressing_mouse-manual.html
@@ -0,0 +1,186 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Set/Release capture</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body>
+ <!--
+ <h1>Pointer Events capture test</h1>
+ <h4>
+ Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions:
+ <ol>
+ <li> Put your mouse over the black rectangle. pointerover and pointerenter should be logged inside of it.</li>
+ <li> Move your mouse out of the black rectangle. pointerout and pointerleave should be logged inside of it</li>
+ <li> Put your mouse over the purple rectangle. pointerover and pointerenter should be logged inside of it.</li>
+ <li> Move your mouse out of the purple rectangle. pointerout and pointerleave should be logged inside of it</li>
+ <li> Press and hold left mouse button over "Set Capture" button. "gotpointercapture" should be logged in the black rectangle</li>
+ <li> Put your mouse over the purple rectangle and then move it out. Nothing should happen</li>
+ <li> Put your mouse over the black rectangle. pointerover and pointerenter should be logged inside of it.</li>
+ <li> Move your mouse out of the black rectangle. pointerout and pointerleave should be logged inside of it</li>
+ <li> Release left mouse button. "lostpointercapture" should be logged in the black rectangle</li>
+ </ol>
+ </h4>
+ Test passes if the proper behaviour of the events is observed.
+ -->
+ <div id="target0"></div>
+ <br>
+ <div id="target1"></div>
+ <br>
+ <input type="button" id="btnCapture" value="Set Capture">
+ <script type='text/javascript'>
+ var isPointerCapture = false;
+ var isRelatedTargetValueTested = false;
+ var isTargetAuthenticityTested = false;
+ var count = 0;
+
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var target0 = document.getElementById('target0');
+ var target1 = document.getElementById('target1');
+ var captureButton = document.getElementById('btnCapture');
+
+ var test_gotpointercapture = async_test("gotpointercapture event received");
+ var test_lostpointercapture = async_test("lostpointercapture event received");
+
+ var test_pointerover_no_capture = async_test("pointerover event without capture received");
+ var test_pointerover_capture = async_test("pointerover event with capture received");
+
+ var test_pointerout_no_capture = async_test("pointerout event without capture received");
+ var test_pointerout_capture = async_test("pointerout event with capture received");
+
+ var test_pointerenter_no_capture = async_test("pointerenter event without capture received");
+ var test_pointerenter_capture = async_test("pointerenter event with capture received");
+
+ var test_pointerleave_no_capture = async_test("pointerleave event without capture received");
+ var test_pointerleave_capture = async_test("pointerleave event with capture received");
+
+ window.onload = function() {
+ on_event(captureButton, 'pointerdown', function(e) {
+ if(isPointerCapture == false) {
+ sPointerCapture(e);
+ isPointerCapture = true;
+ }
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ test_gotpointercapture.done();
+ log("gotpointercapture", target0);
+ });
+
+ on_event(target0, 'lostpointercapture', function(e) {
+ isPointerCapture = false;
+ test_lostpointercapture.done();
+ log("lostpointercapture", target0);
+ });
+
+ run();
+ }
+
+ function run() {
+ on_event(target0, "pointerover", function (event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ log("pointerover", target0);
+ if(isPointerCapture) {
+ test_pointerover_capture.done();
+ if (!isRelatedTargetValueTested) {
+ test(function() {
+ assert_true(event.relatedTarget==null, "relatedTarget is null when the capture is set")
+ }, "relatedTarget is null when the capture is set. relatedTarget is " + event.relatedTarget);
+ isRelatedTargetValueTested = true;
+ }
+ var hitTest = document.elementFromPoint(event.clientX, event.clientY);
+ if(event.target !== hitTest && !isTargetAuthenticityTested) {
+ test(function () {
+ assert_unreached("pointerover for this target shouldn't trigger events on capture target");
+ }, "pointerover should only trigger over the black rectangle");
+ isTargetAuthenticityTested = true;
+ }
+ }
+ else {
+ test_pointerover_no_capture.done();
+ }
+ });
+
+ on_event(target0, "pointerout", function (event) {
+ log("pointerout", target0);
+ if(isPointerCapture) {
+ test_pointerout_capture.done();
+ }
+ else {
+ test_pointerout_no_capture.done();
+ }
+ });
+
+ on_event(target0, "pointerenter", function (event) {
+ log("pointerenter", target0);
+ if(isPointerCapture) {
+ test_pointerenter_capture.done();
+ }
+ else {
+ test_pointerenter_no_capture.done();
+ }
+ });
+
+ on_event(target0, "pointerleave", function (event) {
+ log("pointerleave", target0);
+ if(isPointerCapture) {
+ test_pointerleave_capture.done();
+ }
+ else {
+ test_pointerleave_no_capture.done();
+ }
+ });
+
+ // fail if capture is set but event is received for the non-captured target
+ on_event(target1, "pointerover", function (event) {
+ log("pointerover", target1);
+ if(isPointerCapture == true) {
+ test(function() {
+ assert_unreached("pointerover shouldn't trigger for this target when capture is enabled");
+ }, "pointerover shouldn't trigger for the purple rectangle while the black rectangle has capture");
+ }
+ });
+
+ on_event(target1, "pointerout", function (event) {
+ log("pointerout", target1);
+ if(isPointerCapture == true) {
+ test(function() {
+ assert_unreached("pointerout shouldn't trigger for this target when capture is enabled");
+ }, "pointerout shouldn't trigger for the purple rectangle while the black rectangle has capture");
+ }
+ });
+
+ on_event(target1, "pointerenter", function (event) {
+ log("pointerenter", target1);
+ if(isPointerCapture == true) {
+ test(function() {
+ assert_unreached("pointerenter shouldn't trigger for this target when capture is enabled");
+ }, "pointerenter shouldn't trigger for the purple rectangle while the black rectangle has capture");
+ }
+ });
+
+ on_event(target1, "pointerleave", function (event) {
+ log("pointerleave", target1);
+ if(isPointerCapture == true) {
+ test(function() {
+ assert_unreached("pointerleave shouldn't trigger for this target when capture is enabled");
+ }, "pointerleave shouldn't trigger for the purple rectangle while the black rectangle has capture");
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html b/dom/events/test/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html
new file mode 100644
index 000000000..b5f522f8b
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_change-touch-action-onpointerdown_touch-manual.html
@@ -0,0 +1,138 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Change touch-action on pointerdown</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ <style>
+ #target0 {
+ background: black;
+ width: 700px;
+ height: 430px;
+ color: white;
+ overflow-y: auto;
+ overflow-x: auto;
+ white-space: nowrap;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <!--
+ <h4>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.
+ </h4>
+ <p>Note: this test is for touch-devices only</p>
+ -->
+ <div id="target0" style="touch-action: auto;">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var styleIsChanged = false;
+ var scrollIsReceived = false;
+ var firstTouchCompleted = false;
+ var countToPass = 50;
+ var xScr0, yScr0, xScr1, yScr1;
+
+ setup({ explicit_done: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, 'scroll', function(event) {
+ if(!scrollIsReceived && firstTouchCompleted) {
+ test(function() {
+ failOnScroll();
+ }, "scroll was received while shouldn't");
+ scrollIsReceived = true;
+ }
+ done();
+ });
+
+ on_event(target0, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ if(!styleIsChanged) {
+ var before = document.getElementById('target0').style.touchAction;
+
+ document.getElementById('target0').style.touchAction = 'none';
+
+ var after = document.getElementById('target0').style.touchAction;
+
+ test(function() {
+ assert_true(before != after, "touch-action was changed");
+ }, "touch-action was changed");
+
+ styleIsChanged = true;
+ }
+ });
+
+ on_event(target0, 'pointerup', function(event) {
+ firstTouchCompleted = true;
+ });
+ }
+ </script>
+ <h1>touch-action: auto to none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_constructor.html b/dom/events/test/pointerevents/pointerevent_constructor.html
new file mode 100644
index 000000000..9ef04cccb
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_constructor.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<html>
+ <head>
+ <title>PointerEvent: Constructor test</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>PointerEvent: Dispatch custom event</h1>
+ <h4>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.</h4>
+ <div id="target0"></div>
+ <script>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ async_test(function() {
+ var target0 = document.getElementById("target0");
+ // set values for non-default constructor
+ var testBubbles = true;
+ var testCancelable = true;
+ var testPointerId = 42;
+ var testPointerType = 'pen';
+ var testClientX = 300;
+ var testClientY = 500;
+ var testWidth = 3;
+ var testHeight = 5;
+ var testTiltX = -45;
+ var testTiltY = 30;
+ var testPressure = 0.4;
+ var testIsPrimary = true;
+
+ on_event(target0, "pointerover", this.step_func(function(event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ generate_tests(assert_equals, [
+ ["custom bubbles", event.bubbles, testBubbles],
+ ["custom cancelable", event.cancelable, testCancelable],
+ ["custom pointerId", event.pointerId, testPointerId],
+ ["custom pointerType", event.pointerType, testPointerType],
+ ["custom width", event.width, testWidth],
+ ["custom height", event.height, testHeight],
+ ["custom clientX", event.clientX, testClientX],
+ ["custom clientY", event.clientY, testClientY],
+ ["custom tiltX", event.tiltX, testTiltX],
+ ["custom tiltY", event.tiltY, testTiltY],
+ ["custom isPrimary", event.isPrimary, testIsPrimary]
+ ]);
+ test(function() {
+ assert_approx_equals(event.pressure, testPressure, 0.00000001, "custom pressure: ");
+ }, "custom pressure: ");
+ }));
+
+ on_event(target0, "pointerout", this.step_func(function(event) {
+ generate_tests(assert_equals, [
+ ["default pointerId", event.pointerId, 0],
+ ["default pointerType", event.pointerType, ""],
+ ["default width", event.width, 1],
+ ["default height", event.height, 1],
+ ["default tiltX", event.tiltX, 0],
+ ["default tiltY", event.tiltY, 0],
+ ["default pressure", event.pressure, 0],
+ ["default isPrimary", event.isPrimary, false]
+ ]);
+ }));
+
+ on_event(window, "load", this.step_func_done(function() {
+ assert_not_equals(window.PointerEvent, undefined);
+
+ var pointerEventCustom = new PointerEvent("pointerover",
+ {bubbles: testBubbles,
+ cancelable: testCancelable,
+ pointerId: testPointerId,
+ pointerType: testPointerType,
+ width: testWidth,
+ height: testHeight,
+ clientX: testClientX,
+ clientY: testClientY,
+ tiltX: testTiltX,
+ tiltY: testTiltY,
+ pressure: testPressure,
+ isPrimary: testIsPrimary
+ });
+ // A PointerEvent created with a PointerEvent constructor must have all its attributes set to the corresponding values provided to the constructor.
+ // For attributes where values are not provided to the constructor, the corresponding default values must be used.
+ // TA: 12.1
+ target0.dispatchEvent(pointerEventCustom);
+ var pointerEventDefault = new PointerEvent("pointerout");
+ target0.dispatchEvent(pointerEventDefault);
+ }, "PointerEvent constructor"));
+ })
+ </script>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_element_haspointercapture-manual.html b/dom/events/test/pointerevents/pointerevent_element_haspointercapture-manual.html
new file mode 100644
index 000000000..1826467fe
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_element_haspointercapture-manual.html
@@ -0,0 +1,123 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Element.hasPointerCapture test</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+ var test_pointerEvent = async_test("hasPointerCapture");
+ var listening_events = [
+ "pointerover",
+ "pointerenter",
+ "pointerout",
+ "pointerleave",
+ "pointermove",
+ "gotpointercapture"
+ ];
+ var set_capture_to_target0 = false;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var target1 = document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (e) {
+ detected_pointertypes[e.pointerType] = true;
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), false,
+ "before target0.setPointerCapture, target0.hasPointerCapture should be false");
+ });
+ target1.setPointerCapture(e.pointerId);
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), false,
+ "after target1.setPointerCapture, target0.hasPointerCapture should be false");
+ assert_equals(target1.hasPointerCapture(e.pointerId), true,
+ "after target1.setPointerCapture, target1.hasPointerCapture should be true");
+ });
+ target0.setPointerCapture(e.pointerId);
+ set_capture_to_target0 = true;
+ // hasPointerCapture will return true immediately after a call to setPointerCapture
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), true,
+ "after target0.setPointerCapture, target0.hasPointerCapture should be true");
+ });
+ // hasPointerCapture will return false immediately after a call to releasePointerCapture
+ target0.releasePointerCapture(e.pointerId);
+ set_capture_to_target0 = false;
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), false,
+ "after target0.releasePointerCapture, target0.hasPointerCapture should be false");
+ assert_equals(target1.hasPointerCapture(e.pointerId), false,
+ "after target0.releasePointerCapture, target1.hasPointerCapture should be false");
+ });
+ target0.setPointerCapture(e.pointerId);
+ set_capture_to_target0 = true;
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), true,
+ "after target0.setPointerCapture, target0.hasPointerCapture should be true");
+ });
+ });
+
+ for (var i = 0; i < listening_events.length; i++) {
+ on_event(target0, listening_events[i], function (e) {
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), set_capture_to_target0,
+ "Received " + e.type + " target0.hasPointerCapture should be " + set_capture_to_target0);
+ });
+ });
+ }
+
+ on_event(target0, "pointerup", function (e) {
+ // Immediately after firing the pointerup or pointercancel events, a user agent must run the steps
+ // as if the releasePointerCapture() method has been called
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), true,
+ "pointerup target0.hasPointerCapture should be true");
+ });
+ set_capture_to_target0 = false;
+ });
+
+ on_event(target0, "lostpointercapture", function (e) {
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), false,
+ "pointerup target0.hasPointerCapture should be false");
+ });
+ });
+
+ on_event(target1, "pointerup", function (e) {
+ test_pointerEvent.step(function () {
+ assert_equals(target1.hasPointerCapture(e.pointerId), false,
+ "pointerup target1.hasPointerCapture should be false");
+ });
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Element.hasPointerCapture test</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if Element.hasPointerCapture returns value correctly
+ <ol>
+ <li> Press black rectangle and do not release
+ <li> Move your pointer to purple rectangle
+ <li> Release the pointer
+ <li> Click purple rectangle
+ </ol>
+ </h4>
+ <p>
+ -->
+ <div id="target0" touch-action:none></div>
+ <div id="target1" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_element_haspointercapture_release_pending_capture-manual.html b/dom/events/test/pointerevents/pointerevent_element_haspointercapture_release_pending_capture-manual.html
new file mode 100644
index 000000000..a0f25c131
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_element_haspointercapture_release_pending_capture-manual.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Element.hasPointerCapture test after the pending pointer capture element releases pointer capture</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+ var test_pointerEvent = async_test("hasPointerCapture test after the pending pointer capture element releases pointer capture");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var target1 = document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (e) {
+ detected_pointertypes[e.pointerType] = true;
+ target0.setPointerCapture(e.pointerId);
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), true, "After target0.setPointerCapture, target0.hasPointerCapture should return true");
+ });
+ });
+
+ on_event(target0, "gotpointercapture", function (e) {
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), true, "After target0 received gotpointercapture, target0.hasPointerCapture should return true");
+ });
+ target1.setPointerCapture(e.pointerId);
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), false, "After target1.setPointerCapture, target0.hasPointerCapture should return false");
+ assert_equals(target1.hasPointerCapture(e.pointerId), true, "After target1.setPointerCapture, target1.hasPointerCapture should return true");
+ });
+ target1.releasePointerCapture(e.pointerId);
+ test_pointerEvent.step(function () {
+ assert_equals(target0.hasPointerCapture(e.pointerId), false, "After target1.releasePointerCapture, target0.hasPointerCapture should be false");
+ assert_equals(target1.hasPointerCapture(e.pointerId), false, "After target1.releasePointerCapture, target1.hasPointerCapture should be false");
+ });
+ });
+
+ on_event(target1, "gotpointercapture", function (e) {
+ test_pointerEvent.step(function () {
+ assert_true(false, "target1 should never receive gotpointercapture in this test");
+ });
+ });
+
+ on_event(target0, "lostpointercapture", function (e) {
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Element.hasPointerCapture test after the pending pointer capture element releases pointer capture</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if Element.hasPointerCapture returns value correctly after the pending pointer capture element releases pointer capture
+ <ol>
+ <li> Press black rectangle and do not release
+ <li> Move your pointer to purple rectangle
+ <li> Release the pointer
+ </ol>
+ </h4>
+ -->
+ <p>
+ <div id="target0" touch-action:none></div>
+ <div id="target1" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_gotpointercapture_before_first_pointerevent-manual.html b/dom/events/test/pointerevents/pointerevent_gotpointercapture_before_first_pointerevent-manual.html
new file mode 100644
index 000000000..0589ff2b3
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_gotpointercapture_before_first_pointerevent-manual.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: gotpiontercapture is fired first and asynchronously.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <meta name="assert" content="After setting capture, the gotpointercapture dispatched to the capturing element before any other event is fired." />
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("gotpointercapture event"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var target0;
+ var listener;
+ var pointerdown_event;
+ var detected_pointerEvents = new Array();
+ var eventRcvd = false;
+ var isWaiting = false;
+
+
+ function run() {
+ target0 = document.getElementById("target0");
+ target0.style["touchAction"] = "none";
+ listener = document.getElementById("listener");
+
+ // listen to all events
+ for (var i = 0; i < All_Pointer_Events.length; i++) {
+ on_event(listener, All_Pointer_Events[i], function (event) {
+ if (event.type == "gotpointercapture") {
+ check_PointerEvent(event);
+
+ // TA: 10.2
+ assert_true(isWaiting, "gotpointercapture must be fired asynchronously");
+ isWaiting = false;
+
+ // if any events have been received with same pointerId before gotpointercapture, then fail
+ var eventsRcvd_str = "";
+ if (eventRcvd) {
+ eventsRcvd_str = "Events received before gotpointercapture: ";
+ for (var i = 0; i < detected_pointerEvents.length; i++) {
+ eventsRcvd_str += detected_pointerEvents[i] + ", ";
+ }
+ }
+ test_pointerEvent.step(function () {
+ assert_false(eventRcvd, "no other events should be received before gotpointercapture." + eventsRcvd_str);
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointerID is same for pointerdown and gotpointercapture");
+ });
+ }
+ else {
+ if (pointerdown_event.pointerId === event.pointerId) {
+ assert_false(isWaiting, event.type + " must be fired after gotpointercapture");
+ detected_pointerEvents.push(event.type);
+ eventRcvd = true;
+ test_pointerEvent.done(); // complete test
+ }
+ }
+ });
+ }
+
+ // set pointer capture
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointerdown_event = event;
+ listener.setPointerCapture(event.pointerId);
+ isWaiting = true;
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch gotpointercapture event</h1>
+ <!--
+ <h4>Test Description:
+ After pointer capture is set for a pointer, and prior to dispatching the first event for the pointer, the gotpointercapture
+ event must be dispatched to the element that is receiving the pointer capture. The gotpointercapture event must be dispatched asynchronously.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Use the mouse, touch or pen to tap/click this box.
+ </div>
+ <div id="listener">Do not hover over or touch this element. </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html b/dom/events/test/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html
new file mode 100644
index 000000000..d103804dc
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_lostpointercapture_for_disconnected_node-manual.html
@@ -0,0 +1,81 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Lostpointercapture fires on document when target is removed</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body>
+ <!--
+ <h1>Pointer Events - lostpointercapture when capturing element is removed</h1>
+ <h4>
+ Test Description:
+ This test checks if lostpointercapture is fired at the document when the capturing node is removed from the document.
+ Complete the following actions:
+ <ol>
+ <li>Press and hold left mouse button over "Set Capture" button. "gotpointercapture" should be logged inside of the black rectangle.
+ <li>"lostpointercapture" should be logged inside of the black rectangle after a short delay.
+ </ol>
+ </h4>
+ -->
+ <div id="target0"></div>
+ <div id="target1" style="background:black; color:white"></div>
+ <br>
+ <input type="button" id="btnCapture" value="Set Capture">
+ <script type='text/javascript'>
+ var isDisconnected = false;
+ var count = 0;
+
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var target0 = document.getElementById('target0');
+ var target1 = document.getElementById('target1');
+ var captureButton = document.getElementById('btnCapture');
+
+ var test_lostpointercapture = async_test("lostpointercapture event received");
+
+ window.onload = function() {
+ on_event(captureButton, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ sPointerCapture(event);
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ log("gotpointercapture", target1);
+ setTimeout(function() {
+ isDisconnected = true;
+ target0.parentNode.removeChild(target0);
+ }, 250);
+ });
+
+ on_event(target0, 'lostpointercapture', function(e) {
+ log("lostpointercapture on element", target1);
+ test(function() {
+ // TA: 11.3
+ assert_unreached("lostpointercapture must be fired on the document, not the capturing element");
+ }, "lostpointercapture must not be dispatched on the disconnected node");
+ });
+
+ on_event(document, 'lostpointercapture', function(e) {
+ log("lostpointercapture on document", target1);
+ test(function() {
+ // TA: 11.3
+ assert_true(isDisconnected, "lostpointercapture must be fired on the document");
+
+ }, "lostpointercapture is dispatched on the document");
+ test_lostpointercapture.done();
+ });
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_lostpointercapture_is_first-manual.html b/dom/events/test/pointerevents/pointerevent_lostpointercapture_is_first-manual.html
new file mode 100644
index 000000000..16a000cbe
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_lostpointercapture_is_first-manual.html
@@ -0,0 +1,118 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Lostpointercapture triggers first and asynchronously</title>
+ <meta name="assert" content="TA5.2.10: A user agent must fire a pointer event named lostpointercapture after pointer capture is released for a pointer. This event must be fired prior to any subsequent events for the pointer after capture was released. This event is fired at the element from which pointer capture was removed;">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events capture test - lostpointercapture order</h1>
+ <!--
+ <h4>
+ Test Description:
+ This test checks if lostpointercapture is handled asynchronously and prior to all subsequent events.
+ Complete the following actions:
+ <ol>
+ <li>Press and hold left mouse button over "Set Capture" button. "gotpointercapture" should be logged inside of the black rectangle
+ <li>"lostpointercapture" should be logged inside of the black rectangle after pointerup
+ </ol>
+ </h4>
+ Test passes if lostpointercapture is dispatched after releasing the mouse button and before any additional pointer events.
+ -->
+ <div id="target0" style="background:black; color:white"></div>
+ <br>
+ <input type="button" id="btnCapture" value="Set Capture">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var detected_pointerEvents = new Array();
+ var pointerdown_event = null;
+
+ var test_pointerEvent = async_test("lostpointercapture is dispatched prior to subsequent events"); // set up test harness
+
+ var isPointerCapture = false;
+ var count=0;
+
+ var testStarted = false;
+ var eventRcvd = false;
+ var isAsync = false;
+
+ add_completion_callback(showPointerTypes);
+
+ var target0 = document.getElementById('target0');
+ var captureButton = document.getElementById('btnCapture');
+
+ function run() {
+ on_event(captureButton, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointerdown_event = event;
+ if(isPointerCapture == false) {
+ isPointerCapture = true;
+ captureButton.value = 'Release Capture';
+ sPointerCapture(event);
+ }
+ });
+
+ // TA5.1.3.1: Process Pending Pointer Capture
+ // Whenever a user agent is to fire a Pointer Event that is not gotpointercapture or lostpointercapture,
+ // it must first run the steps of processing pending pointer capture
+ //
+ // TA5.2.12: The lostpointercapture event
+ // After pointer capture is released for a pointer, and prior to any subsequent events for the pointer,
+ // the lostpointercapture event must be dispatched to the element from which pointer capture was removed.
+ // listen to all events
+ for (var i = 0; i < All_Pointer_Events.length; i++) {
+ on_event(target0, All_Pointer_Events[i], function (event) {
+ // if the event was gotpointercapture, just log it and return
+ if (event.type == "gotpointercapture") {
+ testStarted = true;
+ rPointerCapture(event);
+ isAsync = true;
+ log("gotpointercapture", target0);
+ return;
+ }
+ else if (event.type == "lostpointercapture") {
+ log("lostpointercapture", target0);
+ captureButton.value = 'Set Capture';
+ isPointerCapture = false;
+
+ // TA: 11.2
+ test_pointerEvent.step(function () {
+ assert_true(isAsync, "lostpointercapture must be fired asynchronously");
+ });
+
+ // if any events except pointerup have been received with same pointerId before lostpointercapture, then fail
+ var eventsRcvd_str = "";
+ if (eventRcvd) {
+ eventsRcvd_str = "Events received before lostpointercapture: ";
+ for (var i = 0; i < detected_pointerEvents.length; i++) {
+ eventsRcvd_str += detected_pointerEvents[i] + ", ";
+ }
+ }
+ test_pointerEvent.step(function () {
+ assert_false(eventRcvd, "no other events should be received before lostpointercapture." + eventsRcvd_str);
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointerID is same for pointerdown and lostpointercapture");
+ });
+ test_pointerEvent.done(); // complete test
+ }
+ else {
+ if (testStarted && pointerdown_event != null && pointerdown_event.pointerId === event.pointerId && event.type != "pointerup") {
+ detected_pointerEvents.push(event.type);
+ eventRcvd = true;
+ }
+ }
+ });
+ }
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_multiple_primary_pointers_boundary_events-manual.html b/dom/events/test/pointerevents/pointerevent_multiple_primary_pointers_boundary_events-manual.html
new file mode 100644
index 000000000..296d9d49f
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_multiple_primary_pointers_boundary_events-manual.html
@@ -0,0 +1,148 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Boundary compatibility events for multiple primary pointers</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Google" href="http://www.google.com "/>
+ <meta name="assert" content="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."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var test_pointerEvent = async_test("Multi-pointer boundary compat events");
+ add_completion_callback(end_of_test);
+
+ var detected_pointertypes = {};
+ var event_log = [];
+
+ // These two ids help us detect two different pointing devices.
+ var first_entry_pointer_id = -1;
+ var second_entry_pointer_id = -1;
+
+ // Current node for each pointer id
+ var current_node_for_id = {};
+
+ function end_of_test() {
+ showLoggedEvents();
+ showPointerTypes();
+ }
+
+ function end_of_interaction() {
+ test(function () {
+ assert_equals(event_log.join(", "),
+ "mouseover@target0, mouseenter@target0, mouseout@target0, mouseleave@target0, " +
+ "mouseover@target1, mouseenter@target1, mouseout@target1, mouseleave@target1, " +
+ "mouseover@target0, mouseenter@target0, mouseout@target0, mouseleave@target0"
+ );
+ }, "Event log");
+
+ test_pointerEvent.done(); // complete test
+ }
+
+ function log_event(label) {
+ event_log.push(label);
+ }
+
+ function run() {
+ on_event(document.getElementById("done"), "click", end_of_interaction);
+
+ var target_list = ["target0", "target1"];
+ var pointer_event_list = ["pointerenter", "pointerleave", "pointerover", "pointerout", "pointerdown"];
+ var mouse_event_list = ["mouseenter", "mouseleave", "mouseover", "mouseout"];
+
+ target_list.forEach(function(targetId) {
+ var target = document.getElementById(targetId);
+
+ pointer_event_list.forEach(function(eventName) {
+ on_event(target, eventName, function (event) {
+ var label = event.type + "@" + targetId;
+
+ detected_pointertypes[event.pointerType] = true;
+
+ if (!event.isPrimary) {
+ test(function () {
+ assert_unreached("Non-primary pointer " + label);
+ }, "Non-primary pointer " + label);
+ }
+
+ if (event.type === "pointerenter") {
+ var pointer_id = event.pointerId;
+ if (current_node_for_id[pointer_id] !== undefined) {
+ test(function () {
+ assert_unreached("Double entry " + label);
+ }, "Double entry " + label);
+ }
+ current_node_for_id[pointer_id] = event.target;
+
+ // Test that two different pointing devices are used
+ if (first_entry_pointer_id === -1) {
+ first_entry_pointer_id = pointer_id;
+ } else if (second_entry_pointer_id === -1) {
+ second_entry_pointer_id = pointer_id;
+ test(function () {
+ assert_true(first_entry_pointer_id !== second_entry_pointer_id);
+ }, "Different pointing devices");
+ }
+ } else if (event.type === "pointerleave") {
+ var pointer_id = event.pointerId;
+ if (current_node_for_id[pointer_id] !== event.target) {
+ test(function () {
+ assert_unreached("Double exit " + label);
+ }, "Double exit " + label);
+ }
+ current_node_for_id[pointer_id] = undefined;
+ }
+ });
+ });
+
+ mouse_event_list.forEach(function(eventName) {
+ on_event(target, eventName, function (event) {
+ log_event(event.type + "@" + targetId);
+ });
+ });
+ });
+ }
+ </script>
+ <style>
+ #target0, #target1 {
+ margin: 20px;
+ }
+
+ #done {
+ margin: 20px;
+ border: 2px solid black;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Boundary compatibility events for multiple primary pointers</h1>
+ <!--
+ <h4>
+ 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.
+ </h4>
+ Instruction:
+ <ol>
+ <li>Move the mouse directly into Target0 (without going through Target1), and then leave the mouse there unmoved.</li>
+ <li>Tap directly on Target1 with a finger or a stylus, and then lift the finger/stylus off the screen/digitizer without crossing Target1 boundary.</li>
+ <li>Move the mouse into Target0 (if not there already) and move inside it.</li>
+ <li>Click Done (without passing over Target1).</li>
+ </ol>
+ -->
+ <div id="done">
+ Done
+ </div>
+ <div id="target0">
+ Target0
+ </div>
+ <div id="target1">
+ Target1
+ </div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>The following events were logged: <span id="event-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerId_scope-manual.html b/dom/events/test/pointerevents/pointerevent_pointerId_scope-manual.html
new file mode 100644
index 000000000..98bbb879d
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerId_scope-manual.html
@@ -0,0 +1,85 @@
+<!doctype html>
+<html>
+ <!--
+Test cases for Pointer Events v1 spec
+This document references Test Assertions (abbrev TA below) written by Cathy Chan
+http://www.w3.org/wiki/PointerEvents/TestAssertions
+-->
+ <head>
+ <title>Pointer Events pointerdown tests</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerId of an active pointer is the same across iframes");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var pointerover_pointerId = null;
+ var pointerover_pointerType = null;
+
+ var eventList = ['pointerenter', 'pointerover', 'pointermove', 'pointerout', 'pointerleave'];
+ var receivedEvents = {};
+ var receivedEventsInnerFrame = {};
+
+
+ function checkPointerId(event, inner) {
+ detected_pointertypes[event.pointerType] = true;
+ var eventName = (inner ? "inner frame " : "" ) + event.type;
+ test_pointerEvent.step(function() {
+ assert_equals(event.pointerId, pointerover_pointerId, "PointerId of " + eventName + " is not correct");
+ assert_equals(event.pointerType, pointerover_pointerType, "PointerType of " + eventName + " is not correct");
+ }, eventName + ".pointerId were the same as first pointerover");
+ }
+
+ on_event(window, "message", function(event) {
+ var pe_event = JSON.parse(event.data);
+ receivedEventsInnerFrame[pe_event.type] = 1;
+ checkPointerId(pe_event, true);
+ if (Object.keys(receivedEvents).length == eventList.length && Object.keys(receivedEventsInnerFrame).length == eventList.length)
+ test_pointerEvent.done();
+ });
+
+ eventList.forEach(function(eventName) {
+ on_event(target0, eventName, function (event) {
+ if (pointerover_pointerId === null && event.type == 'pointerover') {
+ pointerover_pointerId = event.pointerId;
+ pointerover_pointerType = event.pointerType;
+ } else {
+ checkPointerId(event, false);
+ }
+ receivedEvents[event.type] = 1;
+ });
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events pointerdown tests</h1>
+ Complete the following actions:
+ <!--
+ <ol>
+ <li>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.
+ <li>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.
+ </ol>
+ -->
+ <div id="target0" class="touchActionNone">
+ </div>
+ <iframe src="resources/pointerevent_pointerId_scope-iframe.html" id="innerframe"></iframe>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointercancel_touch-manual.html b/dom/events/test/pointerevents/pointerevent_pointercancel_touch-manual.html
new file mode 100644
index 000000000..00f4495dc
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointercancel_touch-manual.html
@@ -0,0 +1,80 @@
+<!doctype html>
+<html>
+ <head>
+ <title>PointerCancel - touch</title>
+ <meta name="viewport" content="width=device-width">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body class="scrollable" onload="run()">
+ <h1>pointercancel test</h1>
+ <!--
+ <h3>Warning: this test works properly only for devices that have touchscreen</h3>
+ <h4>
+ Test Description: This test checks if pointercancel event triggers.
+ <p>Start touch over the black rectangle and then move your finger to scroll the page.</p>
+ </h4>
+ <p>
+ -->
+ <div id="target0" style="background: black"></div>
+ <script>
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointercancel event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var pointerdown_event = null;
+ var pointercancel_event = null;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, "pointercancel", function (event) {
+ pointercancel_event = event;
+ test_pointerEvent.step(function () {
+ assert_not_equals(pointerdown_event, null, "pointerdown was received: ");
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointerId should be the same for pointerdown and pointercancel");
+ assert_equals(event.pointerType, pointerdown_event.pointerType, "pointerType should be the same for pointerdown and pointercancel");
+ assert_equals(event.isPrimary, pointerdown_event.isPrimary, "isPrimary should be the same for pointerdown and pointercancel");
+ check_PointerEvent(event);
+ });
+ });
+
+ on_event(target0, "pointerout", function (event) {
+ test_pointerEvent.step(function () {
+ assert_not_equals(pointercancel_event, null, "pointercancel was received before pointerout: ");
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointerId should be the same for pointerout and pointercancel");
+ assert_equals(event.pointerType, pointerdown_event.pointerType, "pointerType should be the same for pointerout and pointercancel");
+ assert_equals(event.isPrimary, pointerdown_event.isPrimary, "isPrimary should be the same for pointerout and pointercancel");
+ });
+ });
+
+ on_event(target0, "pointerleave", function (event) {
+ test_pointerEvent.step(function () {
+ assert_not_equals(pointercancel_event, null, "pointercancel was received before pointerleave: ");
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointerId should be the same for pointerleave and pointercancel");
+ assert_equals(event.pointerType, pointerdown_event.pointerType, "pointerType should be the same for pointerleave and pointercancel");
+ assert_equals(event.isPrimary, pointerdown_event.isPrimary, "isPrimary should be the same for pointerleave and pointercancel");
+ });
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ <h1>Pointer Events pointercancel Tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerdown-manual.html b/dom/events/test/pointerevents/pointerevent_pointerdown-manual.html
new file mode 100644
index 000000000..eb80e68a3
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerdown-manual.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<html>
+ <!--
+Test cases for Pointer Events v1 spec
+This document references Test Assertions (abbrev TA below) written by Cathy Chan
+http://www.w3.org/wiki/PointerEvents/TestAssertions
+-->
+ <head>
+ <title>Pointer Events pointerdown tests</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script>
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerdown event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var pointerover_event;
+
+ on_event(target0, "pointerover", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointerover_event = event;
+ check_PointerEvent(event);
+ });
+
+ on_event(target0, "pointerdown", function (event) {
+ check_PointerEvent(event);
+
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, pointerover_event.pointerType, "pointerType is same for pointerover and pointerdown");
+ assert_equals(event.isPrimary, pointerover_event.isPrimary, "isPrimary is same for pointerover and pointerdown");
+ });
+
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events pointerdown tests</h1>
+ <div id="target0">
+ Start with your pointing device outside of this box, then click here.
+ </div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerenter-manual.html b/dom/events/test/pointerevents/pointerevent_pointerenter-manual.html
new file mode 100644
index 000000000..d03741769
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerenter-manual.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Dispatch pointerenter. </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="When a pointing device is moved into the hit test boundaries of an element or one of its descendants, the pointerenter event must be dispatched."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerenter event"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerenter", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.type, "pointerenter", "pointer event received: " + event.type);
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointerenter</h1>
+ <h4>
+ Test Description:
+ When a pointing device is moved into the hit test boundaries of an element or one of its descendants, the pointerenter event must be dispatched.
+ </h4>
+ <div id="target0">
+ Use the mouse or pen to move over this box.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html b/dom/events/test/pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html
new file mode 100644
index 000000000..38289201e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerenter_does_not_bubble-manual.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: The pointerenter event does not bubble </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="The pointerenter event must not bubble up to parent elements."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerEnter event does not bubble"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var pointerenter_event = null;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var parent0 = document.getElementById("parent0");
+
+ on_event(target0, "pointerenter", function (event) {
+ pointerenter_event = event;
+
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.type, "pointerenter", "pointer event received: " + event.type);
+ assert_false(event.bubbles, "pointerenter event.bubbles should be false: " + event.bubbles);
+ });
+ });
+ on_event(target0, "pointerout", function (event) {
+ test_pointerEvent.step(function () {
+ assert_not_equals(pointerenter_event, null, "pointerout event was never received: ");
+ });
+ test_pointerEvent.done(); // complete test
+ });
+
+ // parent
+ on_event(parent0, "pointerenter", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_pointerEvent.step(function () {
+ assert_equals(event.target.id, "parent0", "Recieved " + event.type + " in parent for " + event.target.id);
+ });
+ });
+ }
+
+ </script>
+ <style>
+ #target0 {
+ background: purple;
+ border: 1px solid orange;
+ width:50px;
+ height:50px;
+ }
+ #parent0 {
+ background: black;
+ border: 1px solid orange;
+ width:100px;
+ height:100px;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1> Pointer Event: pointerenter does not bubble</h1>
+ <!--
+ <h4>
+ Test Description:
+ The pointerenter event must not bubble up to parent elements.
+ </h4>
+ <div id="instructions">
+ Use the mouse or pen to hover over then out of the purple box nested in the black box. Or with touch, tap on the purple box.
+ </div>
+ -->
+ <div id="parent0">
+ <div id="target0"></div>
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerenter_nohover-manual.html b/dom/events/test/pointerevents/pointerevent_pointerenter_nohover-manual.html
new file mode 100644
index 000000000..9b8d38ca5
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerenter_nohover-manual.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Dispatch pointerenter. (nohover)</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="When a pointing device that does not support hover is moved into the hit test boundaries of an element
+or one of its descendants as a result of a pointerdown event, the pointerenter event must be dispatched. "/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerenter event"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var test_pointerEnter;
+ var f_pointerenter_rcvd = false;
+ var pointerenter_event;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerdown", function (event) {
+ if(event.pointerType == 'touch') {
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.type, "pointerdown", "pointer event received: " + event.type);
+ assert_true(f_pointerenter_rcvd, "pointerenter event should have been received before pointerdown");
+ assert_equals(event.pointerType, pointerenter_event.pointerType, "pointerType is same for pointerenter and pointerdown");
+ assert_equals(event.isPrimary, pointerenter_event.isPrimary, "isPrimary is same for pointerenter and pointerdown");
+ });
+ test_pointerEvent.done(); // complete test
+ }
+ });
+
+ on_event(target0, "pointerenter", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ if(event.pointerType == 'touch') {
+ pointerenter_event = event;
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.type, "pointerenter", "pointer event received: " + event.type);
+ });
+ f_pointerenter_rcvd = true;
+ }
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointerenter (nohover)</h1>
+ <!--
+ <h4>
+ Test Description:
+ When a pointing device that does not support hover is moved into the hit test boundaries of an element or one of its
+ descendants as a result of a pointerdown event, the pointerenter event must be dispatched.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Tap here.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html
new file mode 100644
index 000000000..b04698d3d
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_after_pointercancel_touch-manual.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerleave after pointercancel</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body class="scrollable" onload="run()">
+ <h2>pointerleave after pointercancel</h2>
+ <h4>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. </h4>
+ <p>Note: this test is for touch devices only</p>
+ <div id="target0"></div>
+ <script>
+ var test_pointerleave = async_test("pointerleave event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var eventTested = false;
+ var pointercancel_event = null;
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointercancel", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointercancel_event = event;
+ });
+
+ // After firing the pointercancel event the pointerleave event must be dispatched.
+ // TA: 4.3.1
+ on_event(target0, "pointerleave", function (event) {
+ if(event.pointerType == 'touch') {
+ if(pointercancel_event != null) {
+ if(eventTested == false) {
+ test_pointerleave.step(function() {
+ assert_equals(event.pointerType, pointercancel_event.pointerType, "pointerType is same for pointercancel and pointerleave");
+ assert_equals(event.isPrimary, pointercancel_event.isPrimary, "isPrimary is same for pointercancel and pointerleave");
+ });
+ eventTested = true;
+ test_pointerleave.done();
+ }
+ }
+ else {
+ test_pointerleave.step(function() {
+ assert_unreached("pointerleave received before pointercancel");
+ }, "pointerleave received before pointercancel");
+ }
+ }
+ });
+ }
+
+ </script>
+ <h1>Pointer Events pointerleave tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_after_pointerup_nohover-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_after_pointerup_nohover-manual.html
new file mode 100644
index 000000000..b0c74f23b
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_after_pointerup_nohover-manual.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerleave after pointerup</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h2>pointerleave after pointerup</h2>
+ <h4>Test Description: This test checks if pointerleave event triggers for devices that don't support hover. Tap the black rectangle. </h4>
+ <p>Note: this test is only for devices that do not support hover.</p>
+ <div id="target0"></div>
+ <script>
+ var test_pointerleave = async_test("pointerleave event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var eventTested = false;
+ var isPointerupReceived = false;
+ var pointerup_event = null;
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerup", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointerup_event = event;
+ });
+
+ // For input devices that do not support hover, a pointerleave event must follow the pointerup event.
+ // TA: 3.6
+ on_event(target0, "pointerleave", function (event) {
+ if(event.pointerType == 'touch') {
+ if(pointerup_event != null) {
+ if(eventTested == false) {
+ eventTested = true;
+ test_pointerleave.step(function() {
+ assert_equals(event.pointerType, pointerup_event.pointerType, "pointerType is same for pointerup and pointerleave");
+ assert_equals(event.isPrimary, pointerup_event.isPrimary, "isPrimary is same for pointerup and pointerleave");
+ });
+ test_pointerleave.done();
+ }
+ }
+ else {
+ test_pointerleave.step(function() {
+ assert_unreached("pointerleave received before pointerup");
+ }, "pointerleave received before pointerup");
+ }
+ }
+ });
+ }
+
+ </script>
+ <h1>Pointer Events pointerleave tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_descendant_over-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_descendant_over-manual.html
new file mode 100644
index 000000000..61bf12224
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_descendant_over-manual.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerleave + descendant</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>pointerleave</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if pointerleave event works properly.
+ <ol>
+ <li>Put your mouse over the black rectangle
+ <li>Then move it into the purple rectangle
+ <li>Click on the purple rectangle to complete the test
+ </ol>
+ Note: when you entered the black rectangle once don't leave it before the end of the test to get proper results.
+ </h4>
+ <p>
+ -->
+ <div id="target0" style="background:black">
+ <div id="target1" style="background:purple"></div>
+ </div>
+ <script>
+ var eventTested = false;
+ var pointerleaveReceived = false;
+ var detected_pointertypes = {};
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // The pointerleave event must not be dispatched when the pointer enters a child element without leaving the hit test boundaries of the parent. (as distinct from pointerout)
+ // TA: 9.2
+ on_event(target1, "pointerdown", function(event) {
+ detected_pointertypes[event.pointerType] = true;
+
+ test(function() {
+ assert_true(!pointerleaveReceived, "pointerleave shouldn't be received on descendant's pointerover")
+ }, "pointerleave shouldn't be received on descendant's pointerover");
+ });
+
+ on_event(target0, "pointerleave", function (event) {
+ if (eventTested == false) {
+ pointerleaveReceived = true;
+ eventTested = true;
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerleave tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_descendants-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_descendants-manual.html
new file mode 100644
index 000000000..40542f2a2
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_descendants-manual.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointerleave + descendant</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>pointerleave</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if pointerleave event works properly.
+ <p>Put your mouse over the black rectangle and then move it out through purple rectangle boundaries.</p>
+ </h4>
+ <p>
+ -->
+ <div id="target0" style="background:black; height: 47px;">
+ <div style="background:purple; height: 35px; width: 90%; position: absolute"></div>
+ </div>
+ <script>
+ var eventTested = false;
+ var detected_pointertypes = {};
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var test_pointerleave = async_test("pointerleave event received");
+
+ on_event(target0, "pointerover", function(event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ });
+
+ // When a pointing device is moved off of the hit test boundaries of an element and all of its descendants, the pointerleave event must be dispatched.
+ // TA: 9.1
+ on_event(target0, "pointerleave", function (event) {
+ if (eventTested == false) {
+ test_pointerleave.done();
+ eventTested = true;
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerleave tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html
new file mode 100644
index 000000000..662a714a9
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_does_not_bubble-manual.html
@@ -0,0 +1,80 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: The pointerleave event does not bubble </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="The pointerleave event must not bubble up to parent elements."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerLeave event does not bubble"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var parent0 = document.getElementById("parent0");
+
+ on_event(target0, "pointerleave", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.type, "pointerleave", "pointer event received: " + event.type);
+ assert_false(event.bubbles, "pointerleave event.bubbles should be false: " + event.bubbles);
+ });
+ });
+
+ on_event(parent0, "pointerleave", function (event) {
+ test_pointerEvent.step(function () {
+ assert_equals(event.target.id, "parent0", "Recieved " + event.type + " in parent for " + event.target.id);
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ <style>
+ #target0 {
+ background: purple;
+ border: 1px solid orange;
+ width:50px;
+ height:50px;
+ }
+ #parent0 {
+ background: black;
+ border: 1px solid orange;
+ width:100px;
+ height:100px;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1> Pointer Event: pointerleave does not bubble</h1>
+ <!--
+ <h4>
+ Test Description:
+ The pointerleave event must not bubble up to parent elements.
+ </h4>
+ <div id="instructions">
+ Use the mouse or pen to hover over then out of the purple box nested in the black box. Or with touch, tap on the purple box.
+ </div>
+ -->
+ <div id="parent0">
+ <div id="target0"></div>
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_mouse-manual.html
new file mode 100644
index 000000000..042f7a8cd
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_mouse-manual.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Dispatch pointerleave (mouse). </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="When a pointing device that has continuous position (such as a mouse) leaves the hit test boundaries of an element, the pointerleave event must be dispatched."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerleave event"); // set up test harness;
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerleave", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, "mouse", "Test should be run using a mouse as input.");
+ assert_equals(event.type, "pointerleave", "The " + event.type + " event was received.");
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointerleave (mouse)</h1>
+ <!--
+ <h4>
+ Test Description:
+ When a pointing device that has continuous position (such as a mouse) leaves the hit test boundaries of an element, the pointerleave event must be dispatched.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Use a mouse to move over then out of this element
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_pen-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_pen-manual.html
new file mode 100644
index 000000000..b5ff230e8
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_pen-manual.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Dispatch pointerleave (pen). </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="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."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerleave event"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerleave", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, "pen", "Test should be run using a pen as input");
+ assert_equals(event.type, "pointerleave", "The " + event.type + " event was received");
+ assert_true((event.clientX > target0.getBoundingClientRect().left)&&
+ (event.clientX < target0.getBoundingClientRect().right)&&
+ (event.clientY > target0.getBoundingClientRect().top)&&
+ (event.clientY < target0.getBoundingClientRect().bottom),
+ "pointerleave should be received inside of target bounds");
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointerleave (pen)</h1>
+ <h4>
+ 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.
+ </h4>
+ <br />
+ <div id="target0">
+ Use a pen to hover over then lift up away from this element.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerleave_touch-manual.html b/dom/events/test/pointerevents/pointerevent_pointerleave_touch-manual.html
new file mode 100644
index 000000000..1dc35c709
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerleave_touch-manual.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Dispatch pointerleave (touch). </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="When a pointing device that does not support hover (such as a finger) leaves the hit test boundaries as a result of a pointerup event, the pointerleave event must be dispatched. "/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerleave event");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerleave", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, "touch", "Test should be run using touch input");
+ assert_equals(event.type, "pointerleave", "The " + event.type + " event received");
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointerleave (touch)</h1>
+ <h4>
+ Test Description:
+ When a pointing device that does not support hover (such as a finger) leaves the hit test boundaries as a result of a pointerup event, the pointerleave event must be dispatched.
+ </h4>
+ <br />
+ <div id="target0">
+ Use touch to tap on this box.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointermove-manual.html b/dom/events/test/pointerevents/pointerevent_pointermove-manual.html
new file mode 100644
index 000000000..2d55cfead
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointermove-manual.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointermove</title>
+ <meta name="viewport" content="width=device-width">
+ <meta name="assert" content="When a pointer changes coordinates, the pointermove event must be dispatched."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h2>PointerMove</h2>
+ <h4>Test Description: This test checks if pointermove event triggers. Move your mouse over the black rectangle or slide it if you are using touchscreen.</h4>
+ <div id="target0" style="background:black"></div>
+ <script>
+ var eventTested = false;
+ var detected_pointertypes = {};
+ var test_pointermove = async_test("pointermove event received");
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // When a pointer changes coordinates, the pointermove event must be dispatched.
+ // TA: 5.3
+ on_event(target0, "pointermove", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ if (eventTested == false) {
+ test_pointermove.done();
+ eventTested = true;
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events pointermove Tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointermove-on-chorded-mouse-button.html b/dom/events/test/pointerevents/pointerevent_pointermove-on-chorded-mouse-button.html
new file mode 100644
index 000000000..7db3dcddd
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointermove-on-chorded-mouse-button.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointermove on button state changes</title>
+ <meta name="viewport" content="width=device-width">
+ <meta name="assert" content="When a pointer changes button state and does not produce a different event, the pointermove event must be dispatched."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h2>PointerMove</h2>
+ <h4>Test Description: This test checks if pointermove event are triggered by button state changes
+ <ol>
+ <li>Put your mouse over the black rectangle</li>
+ <li>Press a button and hold it</li>
+ <li>Press a second button</li>
+ <li>Release the second button</li>
+ <li>Release the first button to complete the test</li>
+ </ol>
+ </h4>
+ <div id="target0" style="background:black"></div>
+ <script>
+ var eventTested = false;
+ var detected_pointertypes = {};
+ var test_pointermove = async_test("pointermove events received for button state changes");
+ add_completion_callback(showPointerTypes);
+
+ var step = 0;
+ var firstButton = 0;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // When a pointer changes button state and the circumstances produce no other pointer event, the pointermove event must be dispatched.
+ // 5.2.6
+
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_pointermove.step(function() {assert_true(step === 0, "There must not be more than one pointer down event.");});
+ if (step == 0) {
+ step = 1;
+ firstButton = event.buttons;
+ }
+ });
+ on_event(target0, "pointermove", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+
+ if (step == 1 && event.button != -1) { // second button pressed
+ test_pointermove.step(function() {assert_true(event.buttons !== firstButton, "The pointermove event must be triggered by pressing a second button.");});
+ test_pointermove.step(function() {assert_true((event.buttons & firstButton) != 0, "The first button must still be reported pressed.");});
+ step = 2;
+ } else if (step == 2 && event.button != -1) { // second button released
+ test_pointermove.step(function() {assert_true(event.buttons === firstButton, "The pointermove event must be triggered by releasing the second button.");});
+ step = 3;
+ }
+ });
+ on_event(target0, "pointerup", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_pointermove.step(function() {assert_true(step === 3, "The pointerup event must be triggered after pressing and releasing the second button.");});
+ test_pointermove.step(function() {assert_true(event.buttons === 0, "The pointerup event must be triggered by releasing the last pressed button.");});
+ test_pointermove.done();
+ eventTested = true;
+ });
+ }
+ </script>
+ <h1>Pointer Events pointermove on button state changes Tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html b/dom/events/test/pointerevents/pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html
new file mode 100644
index 000000000..04c4c93ed
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: pointermove has same isPrimary as last pointerdown with the same pointerId</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="The isPrimary attribute of a pointermove event must have the same value as the isPrimary attribute of the last pointerdown event with the same pointerId attribute."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointermove has same isPrimary as last pointerdown"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var pointermove_event = null;
+ var pointerdown_event = null;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointermove", function (event) {
+ if (pointerdown_event != null) {
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointermove.pointerId should be the same as pointerdown.pointerId.");
+ assert_equals(event.isPrimary, pointerdown_event.isPrimary, "pointermove.isPrimary should be the same as pointerdown.isPrimary.");
+ });
+ pointermove_event = event;
+ }
+ });
+
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, "pointerup", function (event) {
+ test_pointerEvent.step(function () {
+ assert_not_equals(pointermove_event, null, "pointermove event was never received: ");
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <!--
+ <h1>Pointer Event: pointermove has the same isPrimary as last pointerdown with the same pointerId</h1>
+ <h4>Test Description:
+ The isPrimary attribute of a pointermove event must have the same value as the isPrimary attribute of the last pointerdown event with the same pointerId attribute.
+ </h4>
+ <div id="instructions">
+ Press and hold a mouse button, touch contact or pen contact on this element. Move around inside the element while maintaining contact/button down. Only use one device per test run.
+ <p>Lift off of the element to complete the test.</p>
+ </div>
+ -->
+ <div id="target0" style="touch-action: none;">
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointermove_pointertype-manual.html b/dom/events/test/pointerevents/pointerevent_pointermove_pointertype-manual.html
new file mode 100644
index 000000000..5db76ac1e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointermove_pointertype-manual.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerType conservation</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <!--
+ <h1>pointerType conservation</h1>
+ <h4>Test Description: This test checks if pointerType attribute defined properly.</h4>
+ <div id="instructions">
+ Press and move a mouse button, touch contact or pen contact on the black rectangle. Only use one device per test run.
+ </div>
+ <p>Note: This test may be run with different pointer devices, however only one device should be used per test run.
+ <p>
+ -->
+ <div id="target0"></div>
+ <script>
+ var eventTested = false;
+ var pointerTypeGot = false;
+ var pointerdown_event;
+ var detected_pointertypes = {};
+
+ setup({ explicit_done: true });
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerover", function(event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ });
+
+ // The pointerType attribute of a pointermove event must have the same value as the pointerType attribute of the last pointerdown event with the same pointerId attribute.
+ // TA: 5.1
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ pointerTypeGot = true;
+ });
+
+ on_event(target0, "pointermove", function (event) {
+ if(pointerTypeGot == true) {
+ if(!eventTested) {
+ test(function() {
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointer IDs are equal: ");
+ assert_equals(event.pointerType, pointerdown_event.pointerType, "pointerType of pointermove event matches pointerdown event: ");
+ }, "pointerType is dispatched properly");
+ }
+ done();
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerType conservation tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerout-manual.html b/dom/events/test/pointerevents/pointerevent_pointerout-manual.html
new file mode 100644
index 000000000..eb8a820ea
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerout-manual.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerout</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h2>pointerout</h2>
+ <h4>Test Description: This test checks if pointerout event triggers. Put your mouse over the black rectangle and then move it out of the rectangle boundaries. If you are using touchscreen tap the black rectangle. </h4>
+ <div id="target0" style="background: black"></div>
+ <script>
+ var test_pointerEvent = async_test("pointerout event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var eventTested = false;
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerout", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ if (eventTested == false) {
+ eventTested = true;
+ check_PointerEvent(event);
+ test_pointerEvent.done();
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerout tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html
new file mode 100644
index 000000000..63cdcb057
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerout_after_pointercancel_touch-manual.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerout</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body class="scrollable" onload="run()">
+ <h2>pointerout</h2>
+ <h4>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. </h4>
+ <p>Note: this test is for touch devices only</p>
+ <div id="target0"></div>
+ <script>
+ var test_pointerout = async_test("pointerout event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var eventTested = false;
+ var pointercancel_event = null;
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointercancel", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointercancel_event = event;
+ });
+
+ // After firing the pointercancel event the pointerout event must be dispatched.
+ // TA: 4.3
+ on_event(target0, "pointerout", function (event) {
+ if(event.pointerType == 'touch') {
+ if(pointercancel_event != null) {
+ if (eventTested == false) {
+ test_pointerout.step(function() {
+ assert_equals(event.pointerType, pointercancel_event.pointerType, "pointerType is same for pointercancel and pointerout");
+ assert_equals(event.isPrimary, pointercancel_event.isPrimary, "isPrimary is same for pointercancel and pointerout");
+ });
+ eventTested = true;
+ test_pointerout.done();
+ }
+ }
+ else {
+ test_pointerout.step(function() {
+ assert_true(false,
+ "pointercancel received before pointerout");
+ }, "pointercancel received before pointerout");
+ }
+ }
+ });
+ }
+
+ </script>
+ <h1>Pointer Events pointerout tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerout_after_pointerup_nohover-manual.html b/dom/events/test/pointerevents/pointerevent_pointerout_after_pointerup_nohover-manual.html
new file mode 100644
index 000000000..025023d33
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerout_after_pointerup_nohover-manual.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerout</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h2>pointerout</h2>
+ <h4>Test Description: This test checks if pointerout event triggers for devices that don't support hover. Tap the black rectangle. </h4>
+ <p>Note: this test is only for devices that do not support hover.</p>
+ <div id="target0"></div>
+ <script>
+ var test_pointerout = async_test("pointerout event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var eventTested = false;
+ var pointerup_event = null;
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerup", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ pointerup_event = event;
+ });
+
+ // For input devices that do not support hover, a pointerout event must follow the pointerup event.
+ // TA: 3.6
+ on_event(target0, "pointerout", function (event) {
+ if(event.pointerType == 'touch') {
+ if(pointerup_event != null) {
+ if(eventTested == false) {
+ test_pointerout.step(function() {
+ assert_equals(event.pointerType, pointerup_event.pointerType, "pointerType is same for pointerup and pointerout");
+ assert_equals(event.isPrimary, pointerup_event.isPrimary, "isPrimary is same for pointerup and pointerout");
+ });
+ eventTested = true;
+ test_pointerout.done();
+ }
+ }
+ else {
+ test_pointerout.step(function() {
+ assert_true(false,
+ "pointerup received before pointerout");
+ }, "pointerup received before pointerout");
+ }
+ }
+ });
+ }
+
+ </script>
+ <h1>Pointer Events pointerout tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_pointerout_pen-manual.html b/dom/events/test/pointerevents/pointerevent_pointerout_pen-manual.html
new file mode 100644
index 000000000..ba58b5503
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerout_pen-manual.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerout</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h2>pointerout</h2>
+ <h4>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. </h4>
+ <p>Note: this test is for devices that support hover - for pen only</p>
+ <div id="target0"></div>
+ <script>
+ var test_pointerout = async_test("pointerout event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var eventTested = false;
+ var isPointerupReceived = false;
+ var detected_pointertypes = {};
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // When a pen stylus leaves the hover range detectable by the digitizer the pointerout event must be dispatched.
+ // TA: 7.2
+ on_event(target0, "pointerout", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ if(event.pointerType == 'pen') {
+ if (eventTested == false) {
+ eventTested = true;
+ test_pointerout.done();
+ }
+ }
+ else {
+ test_pointerout.step(function() {
+ assert_true(false,
+ "you have to use pen for this test");
+ }, "you have to use pen for this test");
+ }
+ });
+ }
+
+ </script>
+ <h1>Pointer Events pointerout tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerout_received_once-manual.html b/dom/events/test/pointerevents/pointerevent_pointerout_received_once-manual.html
new file mode 100644
index 000000000..44191fd47
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerout_received_once-manual.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerout received just once</title>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <meta name="viewport" content="width=device-width">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>pointerout received just once</h1>
+ <h4>
+ Test Description: This test checks if pointerout event dispatched properly.
+ <ol>
+ <li>Put your mouse over the black rectangle.
+ <li>Move your mouse out of the black rectangle
+ </ol>
+ </h4>
+ <p>
+ <div id="target0" style="background:black"></div>
+ <script>
+ var pointeroutCounter = 0;
+ var detected_pointertypes = {};
+
+ setup({ explicit_done: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // When a mouse passes through dispatches one event
+ // TA: 7.4
+ on_event(target0, "pointerover", function (event) {
+ pointeroutCounter = 0;
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, "pointerout", function (event) {
+ pointeroutCounter++;
+
+ setTimeout(function() {
+ test(function() {
+ assert_true(pointeroutCounter == 1, "pointerout received just once")
+ }, "pointerout received just once");
+ done();
+ }, 5000);
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerout received once test</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerover-manual.html b/dom/events/test/pointerevents/pointerevent_pointerover-manual.html
new file mode 100644
index 000000000..450ed1a03
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerover-manual.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Dispatch pointerover. </title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="When a pointing device is moved into the hit test boundaries of an element, the pointerover event must be dispatched. "/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerover is dispatched"); // set up test harness;
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerover", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_pointerEvent.step(function () {
+ check_PointerEvent(event);
+ assert_equals(event.type, "pointerover", "Pointer Event received");
+ });
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointerover.</h1>
+ <h4>Test Description:
+ When a pointing device is moved into the hit test boundaries of an element, the pointerover event must be dispatched.
+ </h4>
+ <br />
+ <div id="target0">
+ Use mouse, touch or pen to hover or contact this element..
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointertype_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_pointertype_mouse-manual.html
new file mode 100644
index 000000000..50bd056e3
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointertype_mouse-manual.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: If a pointer event is initiated by a mouse device, then the pointerType must be "mouse"</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="If a pointer event is initiated by a mouse device, then the pointerType must be 'mouse'."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointer event have pointerType as mouse"); // set up test harness
+ var eventTested = false;
+
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function eventHandler(event) {
+ detected_pointertypes[event.pointerType] = true;
+ if(!eventTested && event.type == "pointerover") {
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, "mouse", "Verify event.pointerType is 'mouse'.");
+ });
+ eventTested = true;
+ }
+ if (event.type == "pointerup") {
+ test_pointerEvent.done(); // complete test
+ }
+ }
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // listen for all events.
+ for (var i = 0; i < All_Pointer_Events.length; i++) {
+ on_event(target0, All_Pointer_Events[i], eventHandler);
+ }
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointer events with pointerType equal to "mouse"</h1>
+ <!--
+ <h4>Test Description:
+ If a pointer event is initiated by a mouse device, then the pointerType must be 'mouse'.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Using the mouse, click this element.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointertype_pen-manual.html b/dom/events/test/pointerevents/pointerevent_pointertype_pen-manual.html
new file mode 100644
index 000000000..cd018c50e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointertype_pen-manual.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: If a pointer event is initiated by a pen device, then the pointerType must be "pen"</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="If a pointer event is initiated by a pen device, then the pointerType must be 'pen'."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointer event has pointerType as pen"); // set up test harness
+ var eventTested = false;
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function eventHandler(event) {
+ detected_pointertypes[event.pointerType] = true;
+ if(!eventTested) {
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, "pen", "Verify event.pointerType is 'pen'.");
+ });
+ eventTested = true;
+ }
+ if (event.type == "pointerup") {
+ test_pointerEvent.done(); // complete test
+ }
+ }
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ // listen for all events.
+ for (var i = 0; i < All_Pointer_Events.length; i++) {
+ on_event(target0, All_Pointer_Events[i], eventHandler);
+ }
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointer events with pointerType equal to "pen"</h1>
+ <!--
+ <h4>Test Description:
+ If a pointer event is initiated by a pen device, then the pointerType must be 'pen'.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Using pen, tap here.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointertype_touch-manual.html b/dom/events/test/pointerevents/pointerevent_pointertype_touch-manual.html
new file mode 100644
index 000000000..d8034573f
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointertype_touch-manual.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: If a pointer event is initiated by a touch device, then the pointerType must be "touch"</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="If a pointer event is initiated by a touch device, then the pointerType must be 'touch'."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointer event has pointerType as touch"); // set up test harness
+ var eventTested = false;
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function eventHandler(event) {
+ detected_pointertypes[event.pointerType] = true;
+ if(!eventTested) {
+ check_PointerEvent(event);
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerType, "touch", "Verify event.pointerType is 'touch'.");
+ });
+ eventTested = true;
+ }
+ if (event.type == "pointerup") {
+ test_pointerEvent.done(); // complete test
+ }
+ }
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ // listen for all events.
+ for (var i = 0; i < All_Pointer_Events.length; i++) {
+ on_event(target0, All_Pointer_Events[i], eventHandler);
+ }
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Dispatch pointer events with pointerType equal to "touch"</h1>
+ <!--
+ <h4>Test Description:
+ If a pointer event is initiated by a touch device, then the pointerType must be 'touch'.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Using touch, tap here.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerup-manual.html b/dom/events/test/pointerevents/pointerevent_pointerup-manual.html
new file mode 100644
index 000000000..893a5bd2e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerup-manual.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerup</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>pointerup</h1>
+ <h4>Test Description: This test checks if pointerup event triggers. Press mouse left button and release it over the black rectangle or tap it if you are using a touchscreen.</h4>
+ <div id="target0" style="background:black"></div>
+ <script>
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerup event received");
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerup", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_pointerEvent.step(function () {
+ check_PointerEvent(event);
+ assert_equals(event.type, "pointerup", "Pointer Event received.");
+ });
+ test_pointerEvent.done();
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerup tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html b/dom/events/test/pointerevents/pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html
new file mode 100644
index 000000000..a339b5ffd
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: pointerup has same isPrimary as last pointerdown with the same pointerId</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="The isPrimary attribute of a pointerup event must have the same value as the isPrimary attribute of the last pointerdown event with the same pointerId attribute."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointerup has same isPrimary as last pointerdown"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var pointerup_event = null;
+ var pointerdown_event = null;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerup", function (event) {
+ if (pointerdown_event != null) {
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointerup.pointerId should be the same as pointerdown.pointerId.");
+ assert_equals(event.isPrimary, pointerdown_event.isPrimary, "pointerup.isPrimary should be the same as pointerdown.isPrimary.");
+ });
+ pointerup_event = event;
+ test_pointerEvent.done(); // complete test
+ }
+ });
+
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ detected_pointertypes[event.pointerType] = true;
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: pointerup has the same isPrimary as last pointerdown with the same pointerId</h1>
+ <!--
+ <h4>Test Description:
+ The isPrimary attribute of a pointerup event must have the same value as the isPrimary attribute of the last pointerdown event with the same pointerId attribute.
+ </h4>
+ <div id="instructions">
+ Press and release a mouse button, touch contact or pen contact on this element. Only use one device per test run.
+ </div>
+ -->
+ <div id="target0" style="touch-action: none;">
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_pointerup_pointertype-manual.html b/dom/events/test/pointerevents/pointerevent_pointerup_pointertype-manual.html
new file mode 100644
index 000000000..95dc56451
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_pointerup_pointertype-manual.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+ <head>
+ <title>pointerType conservation</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>pointerType conservation</h1>
+ <!--
+ <h4>Test Description: This test checks if pointerType attribute defined properly.</h4>
+ <div id="instructions">
+ Press and release a mouse button, touch contact or pen contact on the black rectangle. Only use one device per test run.
+ </div>
+ <p>Note: This test may be run with different pointer devices, however only one device should be used per test run.
+ <p>
+ -->
+ <div id="target0"></div>
+ <script>
+ var eventTested = false;
+ var pointerTypeGot = false;
+ var pointerdown_event;
+ var detected_pointertypes = {};
+
+ setup({ explicit_done: true });
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerover", function(event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ });
+
+ // The pointerType attribute of a pointerup event must have the same value as the pointerType attribute of the last pointerdown event with the same pointerId attribute.
+ // TA: 3.1
+ on_event(target0, "pointerdown", function (event) {
+ pointerdown_event = event;
+ pointerTypeGot = true;
+ });
+
+ on_event(target0, "pointerup", function (event) {
+ if(pointerTypeGot == true) {
+ if(!eventTested) {
+ test(function() {
+ assert_equals(event.pointerId, pointerdown_event.pointerId, "pointer IDs are equal: ");
+ assert_equals(event.pointerType, pointerdown_event.pointerType, "pointerType of pointerup event matches pointerdown event: ");
+ }, "pointerType is dispatched properly");
+ }
+ done();
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events pointerType conservation tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html
new file mode 100644
index 000000000..f4d5573ed
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_events_to_original_target-manual.html
@@ -0,0 +1,119 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <meta name="assert" content="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"/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("lostpointercapture: subsequent events to target."); // set up test harness
+ var suppressedEventsFail = false;
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var captured_event;
+ var f_gotPointerCapture = false;
+ var f_lostPointerCapture = false;
+
+ function listenerEventHandler(event) {
+ detected_pointertypes[event.pointerType] = true;
+ if (event.type == "gotpointercapture") {
+ f_gotPointerCapture = true;
+ check_PointerEvent(event);
+ }
+ else if (event.type == "lostpointercapture") {
+ f_lostPointerCapture = true;
+ f_gotPointerCapture = false;
+ check_PointerEvent(event);
+ }
+ else if(event.type == "pointerover" || event.type == "pointerenter" || event.type == "pointerout" || event.type == "pointerleave") {
+ if(!suppressedEventsFail) {
+ test(function() {
+ assert_true(false, "Suppressed events were received");
+ }, "Suppressed events were received");
+ suppressedEventsFail = true;
+ }
+ }
+ else if (event.pointerId == captured_event.pointerId) {
+ if (f_gotPointerCapture && event.type == "pointermove") {
+ // on first event received for capture, release capture
+ listener.releasePointerCapture(event.pointerId);
+ }
+ else {
+ // if any other events are received after releaseCapture, then the test fails
+ test_pointerEvent.step(function () {
+ assert_true(false, event.target.id + "-" + event.type + " should be handled by target element handler");
+ });
+ }
+ }
+ }
+
+ function targetEventHandler(event) {
+ if (f_gotPointerCapture) {
+ if(event.type != "pointerout" && event.type != "pointerleave") {
+ test_pointerEvent.step(function () {
+ assert_true(false, "The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". ");
+ });
+ }
+ }
+
+ if (event.type == "pointerdown") {
+ // pointerdown event received will be used to capture events.
+ listener.setPointerCapture(event.pointerId);
+ captured_event = event;
+ }
+
+ if (f_lostPointerCapture) {
+ test_pointerEvent.step(function () {
+ assert_equals(event.pointerId, captured_event.pointerId, "pointerID is same for event captured and after release");
+ });
+ if (event.type == "pointerup") {
+ test_pointerEvent.done(); // complete test
+ }
+ }
+ }
+
+ function run() {
+ var listener = document.getElementById("listener");
+ var target0 = document.getElementById("target0");
+ target0.style["touchAction"] = "none";
+
+ // target0 and listener - handle all events
+ for (var i = 0; i < All_Pointer_Events.length; i++) {
+ on_event(target0, All_Pointer_Events[i], targetEventHandler);
+ on_event(listener, All_Pointer_Events[i], listenerEventHandler);
+ }
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <div id="listener"></div>
+ <h1>Pointer Event: releasePointerCapture() - subsequent events follow normal hitting testing mechanisms</h1>
+ <!--
+ <h4>
+ Test Description:
+ 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
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Use mouse, touch or pen to contact here and move around.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html
new file mode 100644
index 000000000..e92f2d38a
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_invalid_pointerid-manual.html
@@ -0,0 +1,79 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: releasePointerCapture DOMException - InvalidPointerId</title>
+ <meta name="assert" content="releasePointerCapture DOMException - InvalidPointerId"/>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/"/>
+ <link rel="help" href="http://www.w3.org/wiki/PointerEvents/TestAssertions">
+ <meta name="assert" content="When the releasePointerCapture method is invoked, if the provided pointerId value does not match any of the active pointers, a DOMException with the name InvalidPointerId must be thrown."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("releasePointerCapture: DOMException InvalidPointerId"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var invalid_pointerId = 314159265358973923;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ target0.style["touchAction"] = "none";
+ var listener = document.getElementById("listener");
+
+ // try to release pointer capture with an invalid id
+ on_event(listener, "pointermove", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+
+ try {
+ listener.releasePointerCapture(invalid_pointerId);
+
+ test_pointerEvent.step(function () {
+ assert_true(false, "DOMException not thrown. Expected: InvalidPointerId should have been thrown");
+ });
+ } catch (e) {
+ test_pointerEvent.step(function () {
+ assert_true(e.name == "InvalidPointerId", "DOMException should be InvalidPointerId");
+ });
+ }
+ test_pointerEvent.done(); // complete test
+ });
+
+ // set pointer capture
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ listener.setPointerCapture(event.pointerId);
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <div id="listener"></div>
+ <h1> Pointer Event: releasePointerCapture() DOMException - InvalidPointerId</h1>
+ <!--
+ <h4>
+ Test Description:
+ Upon invocation of the releasePointerCapture method, if the provided pointerId value does not match any of the
+ active pointers, a DOMException with the name InvalidPointerId must be thrown.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Use the mouse, touch or pen to move over or contact this box.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html
new file mode 100644
index 000000000..9c6c680ed
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointercancel_touch-manual.html
@@ -0,0 +1,74 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Release capture on pointercancel</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body class="scrollable">
+ <h1>Pointer Events Capture Test - release capture on pointercancel</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions:
+ <ol>
+ <li> Touch black rectangle and do not release your touch
+ <li> Move your touch to scroll the page. "lostpointercapture" should be logged inside of the black rectangle immediately after "pointercancel"
+ </ol>
+ </h4>
+ Test passes if the proper behavior of the events is observed.
+ -->
+ <div id="target0" style="background:black; color:white"></div>
+
+ <script type='text/javascript'>
+ var pointercancelGot = false;
+ var count=0;
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("pointer capture is released on pointercancel");
+
+ var target0 = document.getElementById('target0');
+
+ add_completion_callback(showPointerTypes);
+
+ window.onload = function() {
+ on_event(target0, 'pointerdown', function(e) {
+ detected_pointertypes[e.pointerType] = true;
+ test_pointerEvent.step(function () {
+ assert_equals(e.pointerType, "touch", "Test should be run using a touch as input");
+ });
+ isPointerCapture = true;
+ sPointerCapture(e);
+ pointercancelGot = false;
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ log("gotpointercapture", document.getElementById('target0'));
+ });
+
+ // If the setPointerCapture method has been invoked on the pointer specified by pointerId, and the releasePointerCapture method has not been invoked, a lostpointercapture event must be dispatched to the element on which the setPointerCapture method was invoked. Furthermore, subsequent events for the specified pointer must follow normal hit testing mechanisms for determining the event target.
+ // TA: 4.4
+ on_event(target0, 'lostpointercapture', function(e) {
+ log("lostpointercapture", document.getElementById('target0'));
+ test_pointerEvent.step(function () {
+ assert_true(pointercancelGot, "pointercancel was received before lostpointercapture");
+ });
+ test_pointerEvent.done();
+ });
+
+ on_event(target0, 'pointercancel', function(e) {
+ log("pointercancel", target0);
+ pointercancelGot = true;
+ });
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html
new file mode 100644
index 000000000..7ba33d9be
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_onpointerup_mouse-manual.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Release capture on pointerup</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body>
+ <h1>Pointer Events Capture Test - release capture on pointerup</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions:
+ <ol>
+ <li> Press and hold left mouse button over "Set Capture" button
+ <li> Release left mouse button anywhere over the document. "lostpointercapture" should be logged inside of the black rectangle immediately after "pointerup"
+ </ol>
+ </h4>
+ Test passes if the proper behavior of the events is observed.
+ -->
+ <div id="target0" style="background:black; color:white"></div>
+ <br>
+ <input type="button" id="btnCapture" value="Set Capture">
+ <script type='text/javascript'>
+ var isPointerCapture = false;
+ var pointerupGot = false;
+ var count=0;
+
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var target0 = document.getElementById('target0');
+ var captureButton = document.getElementById('btnCapture');
+
+ setup({ explicit_done: true });
+
+ window.onload = function() {
+ on_event(captureButton, 'pointerdown', function(e) {
+ detected_pointertypes[e.pointerType] = true;
+ if(isPointerCapture == false) {
+ isPointerCapture = true;
+ sPointerCapture(e);
+ pointerupGot = false;
+ }
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ log("gotpointercapture", document.getElementById('target0'));
+ });
+
+ // If the setPointerCapture method has been invoked on the pointer specified by pointerId,
+ // and the releasePointerCapture method has not been invoked,a lostpointercapture event must be
+ // dispatched to the element on which the setPointerCapture method was invoked. Furthermore,
+ // subsequent events for the specified pointer must follow normal hit testing mechanisms for
+ // determining the event target.
+ // TA: 3.7
+ on_event(target0, 'lostpointercapture', function(e) {
+ test(function() {
+ assert_true(pointerupGot, "pointerup was received before lostpointercapture")
+ }, "pointerup was received before lostpointercapture");
+ log("lostpointercapture", document.getElementById('target0'));
+ isPointerCapture = false;
+ done();
+ });
+
+ on_event(target0, 'pointerup', function(e) {
+ log("pointerup", target0);
+ pointerupGot = true;
+ });
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_releasepointercapture_release_right_after_capture-manual.html b/dom/events/test/pointerevents/pointerevent_releasepointercapture_release_right_after_capture-manual.html
new file mode 100644
index 000000000..d5aabddfa
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_releasepointercapture_release_right_after_capture-manual.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Release pointer capture right after setpointercapture</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+ var test_setPointerCapture = async_test("Release pointer capture right after setpointercapture");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var target1 = document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ target0.setPointerCapture(event.pointerId);
+ target0.releasePointerCapture(event.pointerId);
+ assert_equals(target0.hasPointerCapture(e.pointerId), false, "After target0.releasePointerCapture, target0.hasPointerCapture should be false");
+ });
+
+ on_event(target0, "gotpointercapture", function (event) {
+ test_setPointerCapture.step(function () {
+ assert_true(false, "target0 shouldn't receive gotpointercapture");
+ });
+ });
+
+ on_event(target0, "lostpointercapture", function (event) {
+ test_setPointerCapture.step(function () {
+ assert_true(false, "target0 shouldn't receive lostpointercapture");
+ });
+ });
+
+ on_event(target0, "pointerup", function (event) {
+ test_setPointerCapture.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Release pointer capture right after setpointercapture</h1>
+ <!--
+ <h4>Test Description:
+ When calling releasePointer right after setPointerCapture method is invoked, the pending pointer capture should be cleared and no element should receive gotpointercapture and lostpointercapture events
+ <ol>
+ <li>Press and hold left mouse button over black box
+ <li>Move mouse and release mouse button
+ </ol>
+ </h4>
+ -->
+ <br>
+ <div id="target0" touch-action:none></div>
+ <div id="target1" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_setpointercapture_disconnected-manual.html b/dom/events/test/pointerevents/pointerevent_setpointercapture_disconnected-manual.html
new file mode 100644
index 000000000..00875693e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_setpointercapture_disconnected-manual.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<html>
+ <head>
+ <title>setPointerCapture() throws on disconnected node</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+ var test_setPointerCapture = async_test("setPointerCapture: DOMException InvalidStateError");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var target1 = document.getElementById("target1");
+
+ target1.parentNode.removeChild(target1);
+
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ try {
+ target1.setPointerCapture(event.pointerId);
+
+ test_setPointerCapture.step(function() {
+ assert_unreached("DOMException: InvalidStateError should have been thrown.");
+ });
+ } catch (e) {
+ // TA: 13.4
+ test_setPointerCapture.step(function() {
+ assert_equals(e.name, "InvalidStateError", "DOMException should be InvalidStateError");
+ });
+ }
+ test_setPointerCapture.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: DOMException InvalidStateError</h1>
+ <!--
+ <h4>Test Description:
+ When the setPointerCapture method is invoked, if the target node does not participate in its ownerDocument's tree, a DOMException with the name InvalidStateError must be thrown.
+ </h4>
+ <br>
+ -->
+ <div id="target0">
+ Use the mouse, touch or pen to contact this box.
+ </div>
+ <div id="target1"></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-manual.html b/dom/events/test/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-manual.html
new file mode 100644
index 000000000..72504bc3b
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_setpointercapture_inactive_button_mouse-manual.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<html>
+ <head>
+ <title>setPointerCapture + inactive button state</title>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <meta name="viewport" content="width=device-width">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body onload="run()">
+ <h1>setPointerCapture</h1>
+ <!--
+ <h4>
+ Test Description: This test checks if setPointerCapture works properly.
+ <ol>
+ <li>Put your mouse over the black rectangle
+ <li>Move you mouse out to complete the test
+ </ol>
+ </h4>
+ <p>
+ -->
+ <div id="target0" style="background:black; color:white;"></div>
+ <script>
+ var detected_pointertypes = {};
+
+ var captureGot = false;
+
+ setup({ explicit_done: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ on_event(target0, "pointerover", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ target0.setPointerCapture(event.pointerId);
+ });
+
+ // When the setPointerCapture method is invoked, if the specified pointer is not in active button state, then the method must have no effect on subsequent pointer events.
+ // TA: 13.2
+ on_event(target0, "pointerout", function (event) {
+ test(function() {
+ assert_false(captureGot, "pointer capture is not set while button state is inactive")
+ }, "pointer capture is not set while button state is inactive");
+ done();
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ captureGot = true;
+ });
+ }
+ </script>
+ <h1>Pointer Events setPointerCapture Tests</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html b/dom/events/test/pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html
new file mode 100644
index 000000000..711afc615
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_setpointercapture_invalid_pointerid-manual.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: gotPiontercapture is fired first.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/wiki/PointerEvents/TestAssertions">
+ <meta name="assert" content="When the setPointerCapture method is invoked, if the provided pointerId value does not match any of the active pointers, a DOMException with the name InvalidPointerId must be thrown." />
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <!-- /resources/testharness.js -->
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <!-- Additional helper script for common checks across event types -->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ var test_pointerEvent = async_test("setPointerCapture: DOMException InvalidPointerId"); // set up test harness
+ // showPointerTypes is defined in pointerevent_support.js
+ // Requirements: the callback function will reference the test_pointerEvent object and
+ // will fail unless the async_test is created with the var name "test_pointerEvent".
+ add_completion_callback(showPointerTypes);
+
+ var INVALID_POINTERID = -39548;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ target0.style["touchAction"] = "none";
+ var listener = document.getElementById("complete-notice");
+
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+
+ try {
+ listener.setPointerCapture(INVALID_POINTERID);
+
+ test_pointerEvent.step(function () {
+ assert_true(false, "DOMException: InvalidPointerId should have been thrown.");
+ });
+ } catch (e) {
+ test_pointerEvent.step(function () {
+ assert_equals(e.name, "InvalidPointerId", "DOMException should be InvalidPointerId");
+ });
+ }
+ test_pointerEvent.done(); // complete test
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: DOMException InvalidPointerId</h1>
+ <!--
+ <h4>Test Description:
+ When the setPointerCapture method is invoked, if the provided pointerId value does not match any of the active pointers, a DOMException with the name InvalidPointerId must be thrown.
+ </h4>
+ <br />
+ -->
+ <div id="target0">
+ Use the mouse, touch or pen to contact this box.
+ </div>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_setpointercapture_override_pending_capture_element-manual.html b/dom/events/test/pointerevents/pointerevent_setpointercapture_override_pending_capture_element-manual.html
new file mode 100644
index 000000000..e4bf4ddea
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_setpointercapture_override_pending_capture_element-manual.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Test overriding the pending pointer capture element</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+ var test_setPointerCapture = async_test("setPointerCapture: override the pending pointer capture element");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var target1 = document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ target0.setPointerCapture(event.pointerId);
+ test_setPointerCapture.step(function () {
+ assert_equals(target0.hasPointerCapture(event.pointerId), true, "Set capture to target0, target0.hasPointerCapture should be true");
+ });
+ target1.setPointerCapture(event.pointerId);
+ test_setPointerCapture.step(function () {
+ assert_equals(target0.hasPointerCapture(event.pointerId), false, "Set capture to target1, target0.hasPointerCapture should be false");
+ assert_equals(target1.hasPointerCapture(event.pointerId), true, "Set capture to target1, target1.hasPointerCapture should be true");
+ });
+ });
+
+ on_event(target0, "gotpointercapture", function (event) {
+ assert_true(false, "target0 shouldn't receive gotpointercapture");
+ });
+
+ on_event(target1, "gotpointercapture", function (event) {
+ assert_true(true, "target1 should receive gotpointercapture");
+ });
+
+ on_event(target1, "pointerup", function (event) {
+ test_setPointerCapture.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Test overriding the pending pointer capture element</h1>
+ <!--
+ <h4>Test Description:
+ After an element setPointerCapture, if another element also setPointerCapture and override it, the old pending pointer capture element shouldn't receive any gotpointercapture or lostpointercapture event
+ <ol>
+ <li>Press and hold left mouse button over black box
+ <li>Move mouse and release mouse button
+ </ol>
+ </h4>
+ -->
+ <br>
+ <div id="target0" touch-action:none></div>
+ <div id="target1" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html b/dom/events/test/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html
new file mode 100644
index 000000000..ede53af5d
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_setpointercapture_relatedtarget-manual.html
@@ -0,0 +1,103 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Set/Release capture + relatedTarget</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ </head>
+ <body>
+ <!--
+ <h1>Pointer Events Capture Test - capture and relatedTarget</h1>
+ <h4>
+ Test Description: This test checks if setCapture/releaseCapture functions works properly. Complete the following actions:
+ <ol>
+ <li> Put your mouse over the lower rectangle. pointerover should be received for the purple rectangle
+ <li> Press and hold left mouse button over "Set Capture" button
+ <li> Put your mouse over the upper rectangle. pointerover should be received for the black rectangle
+ <li> Release left mouse button to complete the test.
+ </ol>
+ </h4>
+ Test passes if the proper behavior of the events is observed.
+ -->
+ <div id="target0" style="background:black; color:white"></div>
+ <br>
+ <div id="target1" style="background:purple; color:white"></div>
+ <br>
+ <input type="button" id="btnCapture" value="Set Capture">
+ <script type='text/javascript'>
+ var isPointerCapture = false;
+ var isPointeroverGot = false;
+ var count=0;
+
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var target0 = document.getElementById('target0');
+ var target1 = document.getElementById('target1');
+ var captureButton = document.getElementById('btnCapture');
+
+ setup({ explicit_done: true });
+
+ window.onload = function() {
+ on_event(captureButton, 'pointerdown', function(e) {
+ if(isPointerCapture == false) {
+ isPointerCapture = true;
+ sPointerCapture(e);
+ }
+ else {
+ isPointerCapture = false;
+ rPointerCapture(e);
+ }
+ });
+
+ on_event(target0, 'gotpointercapture', function(e) {
+ log("gotpointercapture", document.getElementById('target0'));
+ });
+
+ on_event(target0, 'lostpointercapture', function(e) {
+ log("lostpointercapture", document.getElementById('target0'));
+ isPointerCapture = false;
+ });
+
+ run();
+ }
+
+ function run() {
+ // After invoking the setPointerCapture method on an element, subsequent pointer events for the specified pointer must be targeted at that element.
+ // Additionally, the relatedTarget property of all such pointer events must be set to null.
+ // TA: 13.3
+ on_event(target0, "pointerover", function (event) {
+ log("pointerover", document.getElementById('target0'));
+ if(isPointerCapture && isPointeroverGot) {
+ test(function() {
+ assert_true(event.relatedTarget==null, "relatedTarget is null when the capture is set")
+ }, "relatedTarget is null when the capture is set. relatedTarget is " + event.relatedTarget);
+ done();
+ }
+ });
+
+ on_event(target1, "pointerover", function (event) {
+ detected_pointertypes[ event.pointerType ] = true;
+ if(!isPointeroverGot) {
+ test(function() {
+ assert_true(isPointerCapture==false, "pointerover shouldn't trigger for this target when capture is enabled");
+ }, "pointerover shouldn't trigger for the purple rectangle while the black rectangle has capture");
+ isPointeroverGot = true;
+ log("pointerover", document.getElementById('target1'));
+ }
+ });
+ }
+ </script>
+ <h1>Pointer Events Capture Test</h1>
+ <div id="complete-notice">
+ <p>Test complete: Scroll to Summary to view Pass/Fail Results.</p>
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>Refresh the page to run the tests again with a different pointer type.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_setpointercapture_to_same_element_twice-manual.html b/dom/events/test/pointerevents/pointerevent_setpointercapture_to_same_element_twice-manual.html
new file mode 100644
index 000000000..248c54818
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_setpointercapture_to_same_element_twice-manual.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+ <head>
+ <title>setPointerCapture() to the element which already captured the pointer</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script src="pointerevent_support.js"></script>
+ <script src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+ var test_setPointerCapture = async_test("setPointerCapture: set to the element which already captured the pointer");
+ var got_pointer_capture = false;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var target1 = document.getElementById("target1");
+
+ on_event(target0, "pointerdown", function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ target0.setPointerCapture(event.pointerId);
+ });
+
+ on_event(target0, "gotpointercapture", function (event) {
+ test_setPointerCapture.step(function () {
+ assert_equals(got_pointer_capture, false, "Target0 should receive gotpointercapture at the first time it captured the pointer");
+ assert_equals(target0.hasPointerCapture(event.pointerId), true, "Target 0 received gotpointercapture, target0.hasPointerCapture should be true");
+ });
+ got_pointer_capture = true;
+
+ target0.setPointerCapture(event.pointerId);
+ test_setPointerCapture.step(function () {
+ assert_equals(target0.hasPointerCapture(event.pointerId), true, "Set capture to target0, target0.hasPointerCapture should be true");
+ assert_equals(target1.hasPointerCapture(event.pointerId), false, "Set capture to target0, target1.hasPointerCapture should be false");
+ });
+ });
+
+ on_event(target0, "pointerup", function (event) {
+ test_setPointerCapture.done();
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: setPointerCapture to the element which already captured the pointer</h1>
+ <!--
+ <h4>Test Description:
+ When the setPointerCapture method is invoked, if the target element had already captured the pointer, it should not trigger any gotpointercapture or lostpointercapture event
+ <ol>
+ <li>Press and hold left mouse button over black box
+ <li>Move mouse and release mouse button
+ </ol>
+ </h4>
+ -->
+ <br>
+ <div id="target0" touch-action:none></div>
+ <div id="target1" touch-action:none></div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_styles.css b/dom/events/test/pointerevents/pointerevent_styles.css
new file mode 100644
index 000000000..d2acf940d
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_styles.css
@@ -0,0 +1,93 @@
+.spacer {
+height: 100px;
+}
+
+#square1 {
+background: black;
+top: 150px;
+left: 100px;
+}
+
+.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;
+}
+
+.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/pointerevent_support.js b/dom/events/test/pointerevents/pointerevent_support.js
new file mode 100644
index 000000000..4067d53dd
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_support.js
@@ -0,0 +1,185 @@
+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) {
+ var pointerTestName = event.pointerType + ' ' + event.type;
+ test(function () {
+ assert_true(event instanceof 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": function (v) { return typeof v === "number" && Math.round(v) === v; },
+ "float": function (v) { return typeof v === "number"; },
+ "string": function (v) { return typeof v === "string"; },
+ "boolean": function (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");
+
+
+ // 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.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) {
+ window.setTimeout(function() {
+ objectScroller(target, 'left', 0);}
+ , 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(e) {
+ }
+}
+
+function rPointerCapture(e) {
+ try {
+ captureButton.value = 'Set Capture';
+ target0.releasePointerCapture(e.pointerId);
+ }
+ catch(e) {
+ }
+}
diff --git a/dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_click.html b/dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_click.html
new file mode 100644
index 000000000..89508ee92
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_click.html
@@ -0,0 +1,104 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Suppress compatibility mouse events on click</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Google" href="http://www.google.com "/>
+ <meta name="assert" content="When a pointerdown is canceled, a click/tap shouldn't fire any compatibility mouse events."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var test_pointerEvent = async_test("Suppress compat mouse events on click");
+ add_completion_callback(end_of_test);
+
+ var detected_pointertypes = {};
+ var event_log = [];
+
+ function end_of_test() {
+ showLoggedEvents();
+ showPointerTypes();
+ }
+
+ function end_of_interaction() {
+ test(function () {
+ assert_equals(event_log.join(", "),
+ "mousedown@target1, mouseup@target1");
+ }, "Event log");
+
+ test_pointerEvent.done(); // complete test
+ }
+
+ function run() {
+ on_event(document.getElementById("done"), "click", end_of_interaction);
+
+ var target_list = ["target0", "target1"];
+ var pointer_event_list = ["pointerdown"];
+ var mouse_event_list = ["mousedown", "mouseup"];
+
+ target_list.forEach(function(targetId) {
+ var target = document.getElementById(targetId);
+
+ pointer_event_list.forEach(function(eventName) {
+ on_event(target, eventName, function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ var label = event.type + "@" + targetId;
+
+ test(function () {
+ assert_true(event.isPrimary);
+ }, "primary pointer " + label);
+
+ if (label === "pointerdown@target0")
+ event.preventDefault();
+ });
+ });
+
+ mouse_event_list.forEach(function(eventName) {
+ on_event(target, eventName, function (event) {
+ event_log.push(event.type + "@" + targetId);
+ });
+ });
+ });
+ }
+ </script>
+ <style>
+ #target0, #target1 {
+ margin: 20px;
+ }
+
+ #done {
+ margin: 20px;
+ border: 2px solid black;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Suppress compatibility mouse events on click</h1>
+ <h4>
+ When a pointerdown is canceled, a click/tap shouldn't fire any compatibility mouse events.
+ </h4>
+ <!--
+ <ol>
+ <li> Click or tap on Target0.</li>
+ <li> Click or tap on Target1.</li>
+ <li> Click Done.</li>
+ </ol>
+ -->
+ <div id="target0">
+ Target0
+ </div>
+ <div id="target1">
+ Target1
+ </div>
+ <div id="done">
+ Done
+ </div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>The following events were logged: <span id="event-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html b/dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html
new file mode 100644
index 000000000..337d6ac5f
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_suppress_compat_events_on_drag_mouse.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Pointer Event: Suppress compatibility mouse events on drag</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
+ <link rel="author" title="Google" href="http://www.google.com "/>
+ <meta name="assert" content="When a pointerdown is canceled, a mouse drag shouldn't fire any compatibility mouse events."/>
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <!--script src="/resources/testharnessreport.js"></script-->
+ <script type="text/javascript" src="pointerevent_support.js"></script>
+ <script type="text/javascript" src="mochitest_support_internal.js"></script>
+ <script type="text/javascript">
+ var test_pointerEvent = async_test("Suppress compat mouse events on drag");
+ add_completion_callback(end_of_test);
+
+ var detected_pointertypes = {};
+ var event_log = [];
+
+ function end_of_test() {
+ showLoggedEvents();
+ showPointerTypes();
+ }
+
+ var include_next_mousemove = false;
+
+ // Limits logging/testing of mousemove.
+ function drop_event(event_type) {
+ return (event_type == "mousemove" && !include_next_mousemove);
+ }
+
+ function end_of_interaction() {
+ test(function () {
+ assert_equals(event_log.join(", "),
+ "mousedown@target1, mousemove@target1, mouseup@target1");
+ }, "Event log");
+
+ test_pointerEvent.done(); // complete test
+ }
+
+ function run() {
+ on_event(document.getElementById("done"), "click", end_of_interaction);
+
+ var target_list = ["target0", "target1"];
+ var pointer_event_list = ["pointerdown"];
+ var mouse_event_list = ["mousedown", "mouseup", "mousemove"];
+
+ target_list.forEach(function(targetId) {
+ var target = document.getElementById(targetId);
+
+ pointer_event_list.forEach(function(eventName) {
+ on_event(target, eventName, function (event) {
+ detected_pointertypes[event.pointerType] = true;
+ var label = event.type + "@" + targetId;
+
+ test(function () {
+ assert_true(event.isPrimary);
+ }, "primary pointer " + label);
+
+ if (label === "pointerdown@target0")
+ event.preventDefault();
+ });
+ });
+
+ mouse_event_list.forEach(function(eventName) {
+ on_event(target, eventName, function (event) {
+ if (drop_event(event.type))
+ return;
+
+ event_log.push(event.type + "@" + targetId);
+
+ include_next_mousemove = (event.type == "mousedown");
+ });
+ });
+ });
+ }
+ </script>
+ <style>
+ #target0, #target1 {
+ margin: 20px;
+ touch-action: none;
+ }
+
+ #done {
+ margin: 20px;
+ border: 2px solid black;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Event: Suppress compatibility mouse events on drag</h1>
+ <!--
+ <h4>
+ When a pointerdown is canceled, a mouse drag shouldn't fire any compatibility mouse events.
+ </h4>
+ <ol>
+ <li> Drag mouse within Target0 &amp; release.</li>
+ <li> Drag mouse within Target1 &amp; release.</li>
+ <li> Click Done.</li>
+ </ol>
+ -->
+ <div id="target0">
+ Target0
+ </div>
+ <div id="target1">
+ Target1
+ </div>
+ <div id="done">
+ Done
+ </div>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ <p>The following events were logged: <span id="event-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html
new file mode 100644
index 000000000..f5e9d12c3
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-auto-css_touch-manual.html
@@ -0,0 +1,129 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: auto</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: auto;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll text DOWN. Wait for description update. Expected: pan enabled</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(target0, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(event.pointerType, "touch", "wrong pointer type was detected: ");
+ });
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction.step(function () {
+ yScrollIsReceived = true;
+ assert_true(true, "y-scroll received.");
+ });
+ updateDescriptionNextStep();
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction.done();
+ updateDescriptionComplete();
+ }
+ });
+ }
+ </script>
+ <h1>touch-action: auto</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-button-test_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-button-test_touch-manual.html
new file mode 100644
index 000000000..8268f2ff7
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-button-test_touch-manual.html
@@ -0,0 +1,109 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Button touch-action test</title>
+ <meta name="assert" content="TA15.11 -The touch-action CSS property applies to button elements.">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ height: 150px;
+ width: 200px;
+ overflow-y: auto;
+ background: black;
+ padding: 100px;
+ position: relative;
+ }
+ button {
+ touch-action: none;
+ width: 350px;
+ height: 350px;
+ border: 2px solid red;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h2>Pointer Events touch-action attribute support</h2>
+ <h4 id="desc">Test Description: Try to scroll black element DOWN moving your touch outside of the red border. Wait for description update.</h4>
+ <p>Note: this test is for touch only</p>
+ <div id="target0">
+ <button id="testButton">Test Button</button>
+ </div>
+ <br>
+ <input type="button" id="btnComplete" value="Complete test">
+
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+ var scrollReturnInterval = 1000;
+ var isFirstPart = true;
+ setup({ explicit_timeout: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ //TA 15.11
+ var test_touchaction_div = async_test("touch-action attribute test out of element");
+ var test_touchaction_button = async_test("touch-action attribute test in element");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(btnComplete, 'click', function(event) {
+ test_touchaction_button.step(function() {
+ assert_equals(target0.scrollLeft, 0, "button scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "button scroll y offset should be 0 in the end of the test");
+ assert_true(xScrollIsReceived && yScrollIsReceived, "target0 x and y scroll offsets should be greater than 0 after first two interactions (outside red border) respectively");
+ });
+ test_touchaction_button.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(btnComplete, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ if(isFirstPart) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction_div.step(function () {
+ yScrollIsReceived = true;
+ });
+ updateDescriptionSecondStepTouchActionElement(target0, scrollReturnInterval);
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction_div.done();
+ updateDescriptionThirdStepTouchActionElement(target0, scrollReturnInterval);
+ setTimeout(function() {
+ isFirstPart = false;
+ }, 2 * scrollReturnInterval); // avoid immediate triggering while scroll is still being performed
+ }
+ }
+ else {
+ test_touchaction_button.step(failOnScroll, "scroll received while shouldn't");
+ }
+ });
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-illegal.html b/dom/events/test/pointerevents/pointerevent_touch-action-illegal.html
new file mode 100644
index 000000000..5fe617984
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-illegal.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: illegal</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 50px;
+ touch-action: pan-x none;
+ }
+ #target1 {
+ width: 700px;
+ height: 50px;
+ background: black;
+ margin-top: 5px;
+ touch-action: pan-y none;
+ }
+ #target2 {
+ width: 700px;
+ height: 50px;
+ background: black;
+ margin-top: 5px;
+ touch-action: auto none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Test will automatically check behaviour of following combinations: 'pan-x none', 'pan-y none', 'auto none'</h4>
+ <div id="target0"></div>
+ <div id="target1"></div>
+ <div id="target2"></div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ setup({ explicit_done: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById('target0');
+ var target1 = document.getElementById('target1');
+ var target2 = document.getElementById('target2');
+
+ test(function() {
+ assert_true(getComputedStyle(target0).touchAction == 'auto', "'pan-x none' is corrected properly");
+ }, "'pan-x none' is corrected properly");
+ test(function() {
+ assert_true(getComputedStyle(target1).touchAction == 'auto', "'pan-y none' is corrected properly");
+ }, "'pan-y none' is corrected properly");
+ test(function() {
+ assert_true(getComputedStyle(target2).touchAction == 'auto', "'auto none' is corrected properly");
+ }, "'auto none' is corrected properly");
+ done();
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html
new file mode 100644
index 000000000..364c9c11f
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-auto-child-none_touch-manual.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: parent > child: auto > child: none</title>
+ <meta name="assert" content="TA15.5 - when a user touches an element, the effect of that touch is determined by the value of the touch-action property and the default touch behaviors on the element and its ancestors. Scrollable-Parent, Child: `auto`, Grand-Child: `none`">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ .scroller > div {
+ touch-action: auto;
+ }
+ .scroller > div div {
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: no panning.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div class="scroller" id="target0">
+ <div>
+ <div>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if touch-action attribute works properly for embedded divs
+ // Scrollable-Parent, Child: `auto`, Grand-Child: `none`
+ // TA: 15.5
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ test_touchaction.step(failOnScroll, "scroll received while touch-action is none");
+ });
+ }
+ </script>
+ <h1>behaviour: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html
new file mode 100644
index 000000000..786819b85
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-none_touch-manual.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: child: none</title>
+ <meta name="assert" content="TA15.9 - when a user touches an element, the effect of that touch is determined by the value of the touch-action property and the default touch behaviors on the element and its ancestors. Scrollable-Parent, Child: `none`">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ .scroller > div {
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: no panning</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div class="scroller" id="target0">
+ <div>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if touch-action attribute works properly for embedded divs
+ //
+ // TA: 15.9
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ test_touchaction.step(failOnScroll, "scroll received while touch-action is none");
+ });
+ }
+ </script>
+ <h1>behaviour: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html
new file mode 100644
index 000000000..09a97e3cb
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: parent > child: pan-x > child: pan-x</title>
+ <meta name="assert" content="TA15.6 - when a user touches an element, the effect of that touch is determined by the value of the touch-action property and the default touch behaviors on the element and its ancestors. Scrollable-Parent, Child: `pan-x`, Grand-Child: `pan-x`">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ .scroller > div {
+ touch-action: pan-x;
+ }
+ .scroller > div div {
+ touch-action: pan-x;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: only pans in x direction.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div class="scroller" id="target0">
+ <div>
+ <div>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var test_touchaction = async_test("touch-action attribute test");
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if touch-action attribute works properly for embedded divs
+ //
+ // TA: 15.6
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_not_equals(target0.scrollLeft, 0, "scroll x offset should not be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+ }
+ </script>
+ <h1>behaviour: pan-x</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html
new file mode 100644
index 000000000..527e55374
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: parent > child: pan-x > child: pan-y</title>
+ <meta name="assert" content="TA15.13 - Touch action inherits child 'pan-x' -> child 'pan-y' test">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ .scroller > div {
+ touch-action: pan-x;
+ }
+ .scroller > div div {
+ touch-action: pan-y;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: no panning/zooming/etc.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div class="scroller" id="target0">
+ <div>
+ <div>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if touch-action attribute works properly for embedded divs
+ // Scrollable-Parent, Child: `pan-x`, Grand-Child: `pan-y`
+ // TA: 15.13
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ test_touchaction.step(failOnScroll, "scroll received while touch-action is none");
+ });
+ }
+ </script>
+ <h1>behaviour: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html
new file mode 100644
index 000000000..b13013c43
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_highest-parent-none_touch-manual.html
@@ -0,0 +1,133 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: parent: none + two embedded children</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #divParent {
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll text DOWN. Wait for description update. Expected: pan enabled</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div id="divParent">
+ <div class="scroller" id="target0">
+ <div>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ </div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+
+ add_completion_callback(showPointerTypes);
+ add_completion_callback(enableScrolling);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(target0, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ // Check if touch-action attribute works properly for embedded divs
+ //
+ // TA: 15.
+ on_event(target0, 'scroll', function(event) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ yScrollIsReceived = true;
+ updateDescriptionNextStep();
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction.done();
+ updateDescriptionComplete();
+ }
+ });
+ }
+
+ function enableScrolling() {
+ document.getElementById('divParent').setAttribute('style', 'touch-action: auto');
+ }
+ </script>
+ <h1>behaviour: auto</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html
new file mode 100644
index 000000000..163ef9b8e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-inherit_parent-none_touch-manual.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: inherit from parent: none</title>
+ <meta name="assert" content="TA15.8 - when a user touches an element, the effect of that touch is determined by the value of the touch-action property and the default touch behaviors on the element and its ancestors. Scrollable-Parent: `none` Child: `auto`">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ .scroller {
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: no panning</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div class="scroller" id="target0">
+ <div>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if touch-action attribute works properly for embedded divs
+ //
+ // TA: 15.8
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ test_touchaction.step(failOnScroll, "scroll received while touch-action is none");
+ });
+ }
+ </script>
+ <h1>behaviour: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-keyboard-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-keyboard-manual.html
new file mode 100644
index 000000000..3fef3f646
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-keyboard-manual.html
@@ -0,0 +1,124 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: keyboard</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Press DOWN ARROW key. Wait for description update. Expected: pan enabled</h4>
+ <p>Note: this test is for keyboard only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <script type='text/javascript'>
+
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ target0.focus();
+
+ on_event(target0, 'scroll', function(event) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction.step(function () {
+ yScrollIsReceived = true;
+ assert_true(true, "y-scroll received.");
+ });
+ updateDescriptionNextStepKeyboard();
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction.done();
+ updateDescriptionComplete();
+ }
+ });
+ }
+
+ function updateDescriptionNextStepKeyboard() {
+ document.getElementById('desc').innerHTML = "Test Description: press RIGHT ARROW key.";
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-mouse-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-mouse-manual.html
new file mode 100644
index 000000000..fcc858451
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-mouse-manual.html
@@ -0,0 +1,130 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: mouse</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll text down using mouse (use mouse wheel or click on the scrollbar). Wait for description update.</h4>
+ <p>Note: this test is for mouse only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(target0, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction.step(function () {
+ yScrollIsReceived = true;
+ assert_true(true, "y-scroll received.");
+ });
+ updateDescriptionNextStepMouse();
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction.done();
+ updateDescriptionComplete();
+ }
+ });
+ }
+
+ function updateDescriptionNextStepMouse() {
+ document.getElementById('desc').innerHTML = "Test Description: Try to scroll text right using mouse (use mouse wheel or click on the scrollbar).";
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-none-css_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-none-css_touch-manual.html
new file mode 100644
index 000000000..dec694f3e
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-none-css_touch-manual.html
@@ -0,0 +1,111 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: none</title>
+ <meta name="assert" content="TA15.2 - With `touch-action: none` on a swiped or click/dragged element, `pointerdown+(optional pointermove)+pointerup` must be dispatched.">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: no panning/zooming/etc.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var test_touchaction = async_test("touch-action attribute test");
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if "touch-action: none" attribute works properly
+ //TA: 15.2
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ test_touchaction.step(failOnScroll, "scroll received while touch-action is none");
+ });
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html
new file mode 100644
index 000000000..e757baec6
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html
@@ -0,0 +1,106 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: pan-x</title>
+ <meta name="assert" content="TA15.3 - With `touch-action: pan-x` on a swiped or click/dragged element, only panning on the x-axis should be possible.">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: pan-x;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: only pans in x direction.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var test_touchaction = async_test("touch-action attribute test");
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if "touch-action: pan-x" attribute works properly
+ //TA: 15.3
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_not_equals(target0.scrollLeft, 0, "scroll x offset should not be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+ }
+ </script>
+ <h1>touch-action: pan-x</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html
new file mode 100644
index 000000000..e89b8b742
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual.html
@@ -0,0 +1,111 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: parent > child: pan-x pan-y > child: pan-y</title>
+ <meta name="assert" content="TA15.17 - Touch action 'pan-x pan-y' 'pan-y' test">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ .scroller > div {
+ touch-action: pan-x pan-y;
+ }
+ .scroller > div div {
+ touch-action: pan-y;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: only pans in y direction.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div class="scroller" id="target0">
+ <div>
+ <div>
+ 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.
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ </div>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ add_completion_callback(showPointerTypes);
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if touch-action attribute works properly for embedded divs
+ //
+ // TA: 15.17
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_not_equals(target0.scrollTop, 0, "scroll y offset should not be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+ }
+ </script>
+ <h1>behaviour: pan-y</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html
new file mode 100644
index 000000000..0c900ff74
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-pan-x-pan-y_touch-manual.html
@@ -0,0 +1,126 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: pan-x pan-y</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: pan-x pan-y;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll text DOWN. Wait for description update. Expected: pan enabled</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+
+ var test_touchaction = async_test("touch-action attribute test");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(target0, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction.step(function () {
+ yScrollIsReceived = true;
+ assert_true(true, "y-scroll received.");
+ });
+ updateDescriptionNextStep();
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction.done();
+ updateDescriptionComplete();
+ }
+ });
+ }
+ </script>
+ <h1>touch-action: pan-x pan-y</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-pan-y-css_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-pan-y-css_touch-manual.html
new file mode 100644
index 000000000..4ad39ecc8
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-pan-y-css_touch-manual.html
@@ -0,0 +1,106 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: pan-y</title>
+ <meta name="assert" content="TA15.4 - With `touch-action: pan-y` on a swiped or click/dragged element, only panning in the y-axis should be possible.">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 430px;
+ touch-action: pan-y;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h1>Pointer Events touch-action attribute support</h1>
+ <h4 id="desc">Test Description: Try to scroll element DOWN then RIGHT. Tap Complete button under the rectangle when done. Expected: only pans in y direction.</h4>
+ <p>Note: this test is for touch-devices only</p>
+ <div id="target0">
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>
+ 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.
+ </p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ <p>Lorem ipsum dolor sit amet...</p>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var test_touchaction = async_test("touch-action attribute test");
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ // Check if "touch-action: pan-y" attribute works properly
+ //TA: 15.4
+ on_event(btnComplete, 'click', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ test_touchaction.step(function() {
+ assert_equals(target0.scrollLeft, 0, "scroll x offset should be 0 in the end of the test");
+ assert_not_equals(target0.scrollTop, 0, "scroll y offset should not be 0 in the end of the test");
+ });
+ test_touchaction.done();
+ updateDescriptionComplete();
+ });
+ }
+ </script>
+ <h1>touch-action: pan-y</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-span-test_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-span-test_touch-manual.html
new file mode 100644
index 000000000..41635e0bf
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-span-test_touch-manual.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Span touch-action test</title>
+ <meta name="assert" content="TA15.18 - The touch-action CSS property applies to all elements except non-replaced inline elements."
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ height: 150px;
+ width: 200px;
+ overflow-y: auto;
+ background: black;
+ padding: 100px;
+ position: relative;
+ }
+ #testspan {
+ touch-action: none;
+ font-size: 72pt;
+ padding: 0px 0px 180px 0px;
+ border: 2px solid red;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h2>Pointer Events touch-action attribute support</h2>
+ <h4 id="desc">Test Description: Try to scroll black element DOWN moving your touch outside of the red border. Wait for description update.</h4>
+ <p>Note: this test is for touch only</p>
+ <div id="target0">
+ <span id="testspan">
+ Test span
+ </span>
+ </div>
+ <input type="button" id="btnComplete" value="Complete test">
+
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var failScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+ var scrollReturnInterval = 500;
+ var isFirstPart = true;
+ setup({ explicit_timeout: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ //TA 15.18
+ var test_touchaction_div = async_test("touch-action attribute test out of element");
+ var test_touchaction_span = async_test("touch-action attribute test in element");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(btnComplete, 'click', function(event) {
+ test_touchaction_span.step(function() {
+ assert_not_equals(target0.scrollLeft, 0, "span scroll x offset should not be 0 in the end of the test");
+ assert_not_equals(target0.scrollTop, 0, "span scroll y offset should not be 0 in the end of the test");
+ assert_true(!isFirstPart, "target0 x and y scroll offsets should be greater than 0 after first two interactions (outside red border) respectively");
+ });
+ test_touchaction_span.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(btnComplete, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ if(isFirstPart) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction_div.step(function () {
+ yScrollIsReceived = true;
+ });
+ updateDescriptionSecondStepTouchActionElement(target0, scrollReturnInterval);
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction_div.done();
+ updateDescriptionThirdStepTouchActionElement(target0, scrollReturnInterval);
+ setTimeout(function() {
+ isFirstPart = false;
+ xScr0 = target0.scrollLeft;
+ xScr0 = target0.scrollLeft;
+ xScrollIsReceived = false;
+ yScrollIsReceived = false;
+ }, 2 * scrollReturnInterval); // avoid immediate triggering while scroll is still being performed
+ }
+ }
+ });
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html
new file mode 100644
index 000000000..422a72e19
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-svg-test_touch-manual.html
@@ -0,0 +1,122 @@
+<!doctype html>
+<html>
+ <head>
+ <title>SVG test</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ height: 350px;
+ width: 300px;
+ overflow-y: auto;
+ background: black;
+ padding: 100px;
+ position: relative;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h2>Pointer Events touch-action attribute support</h2>
+ <h4 id="desc">Test Description: Try to scroll black element DOWN moving your touch outside of the red border. Wait for description update.</h4>
+ <p>Note: this test is for touch only</p>
+ <div id="target0">
+ <svg id="testSvg" width="555" height="555" style="touch-action: none; border: 4px double red;">
+ <circle cx="305" cy="305" r="250" stroke="green" stroke-width="4" fill="yellow" />
+ Sorry, your browser does not support inline SVG.
+ </svg>
+ </div>
+ <br>
+ <input type="button" id="btnComplete" value="Complete test">
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+ var scrollReturnInterval = 1000;
+ var isFirstPart = true;
+ setup({ explicit_timeout: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ var test_touchaction_div = async_test("touch-action attribute test out of SVG");
+ var test_touchaction_svg = async_test("touch-action attribute test in SVG");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(btnComplete, 'click', function(event) {
+ test_touchaction_svg.step(function() {
+ assert_equals(target0.scrollLeft, 0, "SVG scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "SVG scroll y offset should be 0 in the end of the test");
+ });
+ test_touchaction_svg.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(btnComplete, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ if(isFirstPart) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction_div.step(function () {
+ yScrollIsReceived = true;
+ assert_true(true, "y-scroll received.");
+ });
+ updateDescriptionSecondStepSVG();
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction_div.done();
+ updateDescriptionThirdStepSVG();
+ setTimeout(function() {
+ isFirstPart = false;
+ }, 2 * scrollReturnInterval);
+ }
+ }
+ });
+ }
+
+ function updateDescriptionSecondStepSVG() {
+ window.setTimeout(function() {
+ objectScroller(target0, 'up', 0);}
+ , scrollReturnInterval);
+ document.getElementById('desc').innerHTML = "Test Description: Try to scroll element RIGHT moving your touch outside of the red border";
+ }
+
+ function updateDescriptionThirdStepSVG() {
+ window.setTimeout(function() {
+ objectScroller(target0, 'left', 0);}
+ , scrollReturnInterval);
+ document.getElementById('desc').innerHTML = "Test Description: Try to scroll element DOWN then RIGHT starting your touch inside of the circle. Tap Complete button under the rectangle when done";
+ }
+
+ function objectScroller(target, direction, value) {
+ if (direction == 'up') {
+ target.scrollTop = 0;
+ } else if (direction == 'left') {
+ target.scrollLeft = 0;
+ }
+ }
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-table-test_touch-manual.html b/dom/events/test/pointerevents/pointerevent_touch-action-table-test_touch-manual.html
new file mode 100644
index 000000000..fcc3a3e7c
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-table-test_touch-manual.html
@@ -0,0 +1,141 @@
+<!doctype html>
+<html>
+ <head>
+ <title>Table touch-action test</title>
+ <meta name="assert" content="TA15.19 The touch-action CSS property applies to all elements except table rows, row groups, table columns, and column groups.">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ height: 150px;
+ width: 200px;
+ overflow-y: auto;
+ background: black;
+ padding: 100px;
+ position: relative;
+ }
+ #testtable{
+ color: white;
+ width: 350px;
+ padding: 0px 0px 200px 0px;
+ border: 2px solid green;
+ }
+ .testtd, .testth {
+ border: 2px solid green;
+ height: 80px;
+ }
+ #row1 {
+ touch-action: none;
+ }
+ #cell3 {
+ touch-action: none;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h2>Pointer Events touch-action attribute support</h2>
+ <h4 id="desc">Test Description: Try to scroll element DOWN starting your touch over the 1st Row. Wait for description update.</h4>
+ <p>Note: this test is for touch only</p>
+ <div id="target0">
+ <table id="testtable">
+ <caption>The caption, first row element, and cell 3 have touch-action: none.</caption>
+ <tr id="row1"><th class="testth">Header 1 <td class="testtd">Cell 1 <td class="testtd">Cell 2</tr>
+ <tr id="row2"><th class="testth">Header 2 <td id="cell3" class="testtd">Cell 3 <td class="testtd">Cell 4</tr>
+ <tr id="row3"> <th class="testth">Header 3 <td class="testtd">Cell 5 <td class="testtd"> Cell 6</tr>
+ </table>
+ </div>
+ <br>
+ <input type="button" id="btnComplete" value="Complete test">
+
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+ var xScrollIsReceived = false;
+ var yScrollIsReceived = false;
+ var xScr0, yScr0, xScr1, yScr1;
+ var scrollReturnInterval = 1000;
+ var isFirstPart = true;
+ setup({ explicit_timeout: true });
+ add_completion_callback(showPointerTypes);
+
+ function run() {
+ var target0 = document.getElementById("target0");
+ var btnComplete = document.getElementById("btnComplete");
+
+ //TA 15.19
+ var test_touchaction_cell = async_test("touch-action attribute test on the cell");
+ var test_touchaction_row = async_test("touch-action attribute test on the row");
+
+ xScr0 = target0.scrollLeft;
+ yScr0 = target0.scrollTop;
+
+ on_event(btnComplete, 'click', function(event) {
+ test_touchaction_cell.step(function() {
+ assert_equals(target0.scrollLeft, 0, "table scroll x offset should be 0 in the end of the test");
+ assert_equals(target0.scrollTop, 0, "table scroll y offset should be 0 in the end of the test");
+ assert_true(xScrollIsReceived && yScrollIsReceived, "target0 x and y scroll offsets should be greater than 0 after first two interactions (outside red border) respectively");
+ });
+ test_touchaction_cell.done();
+ updateDescriptionComplete();
+ });
+
+ on_event(btnComplete, 'pointerdown', function(event) {
+ detected_pointertypes[event.pointerType] = true;
+ });
+
+ on_event(target0, 'scroll', function(event) {
+ if(isFirstPart) {
+ xScr1 = target0.scrollLeft;
+ yScr1 = target0.scrollTop;
+
+ if(xScr1 != xScr0) {
+ xScrollIsReceived = true;
+ }
+
+ if(yScr1 != yScr0) {
+ test_touchaction_row.step(function () {
+ yScrollIsReceived = true;
+ });
+ updateDescriptionSecondStepTable(target0, scrollReturnInterval);
+ }
+
+ if(xScrollIsReceived && yScrollIsReceived) {
+ test_touchaction_row.done();
+ updateDescriptionThirdStepTable(target0, scrollReturnInterval);
+ setTimeout(function() {
+ isFirstPart = false;
+ }, 2 * scrollReturnInterval); // avoid immediate triggering while scroll is still being performed
+ }
+ }
+ else {
+ test_touchaction_cell.step(failOnScroll, "scroll received while shouldn't");
+ }
+ });
+ }
+
+ function updateDescriptionSecondStepTable(target, scrollReturnInterval, element) {
+ window.setTimeout(function() {
+ objectScroller(target, 'up', 0);
+ }
+ , scrollReturnInterval);
+ document.getElementById('desc').innerHTML = "Test Description: Try to scroll element RIGHT staring your touch over the Row 1";
+ }
+
+ function updateDescriptionThirdStepTable(target, scrollReturnInterval) {
+ window.setTimeout(function() {
+ objectScroller(target, 'left', 0);
+ }
+ , scrollReturnInterval);
+ document.getElementById('desc').innerHTML = "Test Description: Try to scroll element DOWN then RIGHT starting your touch inside of the Cell 3";
+ }
+
+ </script>
+ <h1>touch-action: none</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/pointerevent_touch-action-verification.html b/dom/events/test/pointerevents/pointerevent_touch-action-verification.html
new file mode 100644
index 000000000..2e694229a
--- /dev/null
+++ b/dom/events/test/pointerevents/pointerevent_touch-action-verification.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<html>
+ <head>
+ <title>touch-action: basic verification</title>
+ <meta name="assert" content="TA15.20 - The touch-action CSS property determines whether touch input MAY trigger default behavior supplied by the user agent.
+ auto: The user agent MAY determine any permitted touch behaviors, such as panning and zooming manipulations of the viewport, for touches that begin on the element.
+ none: Touches that begin on the element MUST NOT trigger default touch behaviors.
+ pan-x: The user agent MAY consider touches that begin on the element only for the purposes of horizontally scrolling the element's nearest ancestor with horizontally scrollable content.
+ pan-y: The user agent MAY consider touches that begin on the element only for the purposes of vertically scrolling the element's nearest ancestor with vertically scrollable content.
+ manipulation: The user agent MAY consider touches that begin on the element only for the purposes of scrolling and continuous zooming. Any additional behaviors supported by auto are out of scope for this specification.">
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="pointerevent_support.js"></script>
+ <style>
+ #target0 {
+ width: 700px;
+ height: 20px;
+ touch-action: auto;
+ }
+ #target1 {
+ width: 700px;
+ height: 20px;
+ touch-action: none;
+ background: black;
+ margin-top: 5px;
+ touch-action: pan-x;
+ }
+ #target2 {
+ width: 700px;
+ height: 20px;
+ touch-action: none;
+ background: black;
+ margin-top: 5px;
+ touch-action: pan-y;
+ }
+ #target3 {
+ width: 700px;
+ height: 20px;
+ touch-action: none;
+ background: black;
+ margin-top: 5px;
+ touch-action: none;
+ }
+ #target4 {
+ width: 700px;
+ height: 20px;
+ touch-action: none;
+ background: black;
+ margin-top: 5px;
+ touch-action: manipulation;
+ }
+ </style>
+ </head>
+ <body onload="run()">
+ <h2>Pointer Events touch-action attribute support</h2>
+ <h4 id="desc">Test Description: Test will automatically check behaviour of following values: 'auto', 'pan-x', 'pan-y', ' none', 'manipulation'</h4>
+ <div id="target0"></div>
+ <div id="target1"></div>
+ <div id="target2"></div>
+ <div id="target3"></div>
+ <div id="target4"></div>
+ <script type='text/javascript'>
+ var detected_pointertypes = {};
+
+ setup({ explicit_done: true });
+
+ function run() {
+ var target0 = document.getElementById('target0');
+ var target1 = document.getElementById('target1');
+ var target2 = document.getElementById('target2');
+ var target3 = document.getElementById('target3');
+ var target4 = document.getElementById('target4');
+
+ //TA 15.20
+ test(function() {
+ assert_true(getComputedStyle(target0).touchAction == 'auto', "'auto' is set properly");
+ }, "'auto' is set properly");
+ test(function() {
+ assert_true(getComputedStyle(target1).touchAction == 'pan-x', "'pan-x' is corrected properly");
+ }, "'pan-x' is corrected properly");
+ test(function() {
+ assert_true(getComputedStyle(target2).touchAction == 'pan-y', "'pan-y' is set properly");
+ }, "'pan-y' is set properly");
+ test(function() {
+ assert_true(getComputedStyle(target3).touchAction == 'none', "'none' is set properly");
+ }, "'none' is set properly");
+ test(function() {
+ assert_true(getComputedStyle(target4).touchAction == 'manipulation', "'manipulation' is set properly");
+ }, "'manipulation' is set properly");
+ done();
+ }
+ </script>
+ <h1>touch-action: basic verification</h1>
+ <div id="complete-notice">
+ <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+ </div>
+ <div id="log"></div>
+ </body>
+</html> \ No newline at end of file
diff --git a/dom/events/test/pointerevents/readme.md b/dom/events/test/pointerevents/readme.md
new file mode 100644
index 000000000..f0d4fc73e
--- /dev/null
+++ b/dom/events/test/pointerevents/readme.md
@@ -0,0 +1,5 @@
+Directory for Pointer Events Tests
+
+All tests were got from official repository:
+
+https://github.com/w3c/web-platform-tests/tree/master/pointerevents
diff --git a/dom/events/test/pointerevents/resources/pointerevent_pointerId_scope-iframe.html b/dom/events/test/pointerevents/resources/pointerevent_pointerId_scope-iframe.html
new file mode 100644
index 000000000..ad1a57fb4
--- /dev/null
+++ b/dom/events/test/pointerevents/resources/pointerevent_pointerId_scope-iframe.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+ <!--
+Test cases for Pointer Events v1 spec
+This document references Test Assertions (abbrev TA below) written by Cathy Chan
+http://www.w3.org/wiki/PointerEvents/TestAssertions
+-->
+ <head>
+ <title>Pointer Events pointerdown tests</title>
+ <meta name="viewport" content="width=device-width">
+ <link rel="stylesheet" type="text/css" href="../pointerevent_styles.css">
+ <script>
+ function run() {
+ var target1 = document.getElementById("target1");
+ var pointerover_event;
+ var ponterId = null;
+
+ var eventList = ['pointerenter', 'pointerover', 'pointermove', 'pointerout', 'pointerleave'];
+
+ eventList.forEach(function(eventName) {
+ target1.addEventListener(eventName, function (event) {
+ var pass_data = {
+ 'pointerId' : event.pointerId,
+ 'type' : event.type,
+ 'pointerType' : event.pointerType
+ };
+ top.postMessage(JSON.stringify(pass_data), "*");
+ });
+ });
+ }
+ </script>
+ </head>
+ <body onload="run()">
+ <div id="target1" class="touchActionNone">
+ </div>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_bug1285128.html b/dom/events/test/pointerevents/test_bug1285128.html
new file mode 100644
index 000000000..f7f1eb698
--- /dev/null
+++ b/dom/events/test/pointerevents/test_bug1285128.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1285128
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1285128</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1285128">Mozilla Bug 1285128</a>
+<p id="display"></p>
+<div id="target0" style="width: 200px; height: 200px; background: green"></div>
+<script type="text/javascript">
+
+/** Test for Bug 1285128 **/
+SimpleTest.waitForExplicitFinish();
+
+function runTests() {
+ let target0 = window.document.getElementById("target0");
+ let pointerEventsList = ["pointerover", "pointerenter", "pointerdown",
+ "pointerup", "pointerleave", "pointerout"];
+ let receivedPointerEvents = false;
+ pointerEventsList.forEach((elem, index, arr) => {
+ target0.addEventListener(elem, (event) => {
+ ok(false, "receiving event " + event.type);
+ receivedPointerEvents = true;
+ }, false);
+ });
+
+ target0.addEventListener("mouseenter", () => {
+ ok(!receivedPointerEvents, "synthesized mousemove should not trigger any pointer events");
+ SimpleTest.finish();
+ });
+
+ synthesizeMouseAtCenter(target0, { type: "mousemove",
+ inputSource: SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE,
+ isWidgetEventSynthesized: true });
+}
+
+SpecialPowers.pushPrefEnv({"set": [["dom.w3c_pointer_events.enabled", true]]}, runTests);
+
+</script>
+</body>
+</html>
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 000000000..bf5fd5d5e
--- /dev/null
+++ b/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1293174</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ setImplicitPointerCapture(true, loadSubFrame);
+ }
+ function loadSubFrame() {
+ runTestInNewWindow("bug1293174_implicit_pointer_capture_for_touch_1.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ sendTouchEvent(int_win, "target1", "touchmove");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
+
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 000000000..f1a1cc314
--- /dev/null
+++ b/dom/events/test/pointerevents/test_bug1293174_implicit_pointer_capture_for_touch_2.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1293174</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ setImplicitPointerCapture(false, loadSubFrame);
+ }
+ function loadSubFrame() {
+ runTestInNewWindow("bug1293174_implicit_pointer_capture_for_touch_2.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ sendTouchEvent(int_win, "target1", "touchmove");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
+
diff --git a/dom/events/test/pointerevents/test_empty_file.html b/dom/events/test/pointerevents/test_empty_file.html
new file mode 100644
index 000000000..56f2cd085
--- /dev/null
+++ b/dom/events/test/pointerevents/test_empty_file.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+This file should exist until bug 1150091 will be fixed.
+[manifestparser] Adding support-files under tests overwrites DEFAULT instead of appending.
+-->
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_attributes_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_attributes_mouse-manual.html
new file mode 100644
index 000000000..1cda30c35
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_attributes_mouse-manual.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_attributes_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "square1", "mousemove", {button:-1});
+ sendMouseEvent(int_win, "square1", "mousedown", {button:0});
+ sendMouseEvent(int_win, "square1", "mouseup", {button:0});
+ sendMouseEvent(int_win, "square1", "mousemove", {button:-1});
+ sendMouseEvent(int_win, "square1", "mousemove", {button:-1,
+ offsetX: -1,
+ offsetY: -1});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
+
diff --git a/dom/events/test/pointerevents/test_pointerevent_capture_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_capture_mouse-manual.html
new file mode 100644
index 000000000..d2e0c52bf
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_capture_mouse-manual.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_capture_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "btnCapture", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "btnCapture", "mousedown", {button:1});
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "target1", "mouseup");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html
new file mode 100644
index 000000000..dc3903592
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_capture_suppressing_mouse-manual.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_capture_suppressing_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "btnCapture", "mousedown", {button:1});
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "target1", "mouseup");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_change-touch-action-onpointerdown_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_change-touch-action-onpointerdown_touch-manual.html
new file mode 100644
index 000000000..44d4f2a1b
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_change-touch-action-onpointerdown_touch-manual.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_change-touch-action-onpointerdown_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ const WM_VSCROLL = 0x0115;
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ sendTouchEvent(int_win, "target0", "touchend");
+
+ // NOTE: This testcase is about that modifying touch-action during a
+ // pointerdown callback "should not" affect the gesture detection of the
+ // touch session started by the pointerdown. That is, a scroll should
+ // still fired by gesture detection, instead of launching by our own.
+ var utils = _getDOMWindowUtils(int_win);
+ var target0 = int_win.document.getElementById("target0");
+ utils.sendNativeMouseScrollEvent(target0.getBoundingClientRect().left + 5,
+ target0.getBoundingClientRect().top + 5,
+ WM_VSCROLL, 10, 10, 0, 0, 0, target0);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_constructor.html b/dom/events/test/pointerevents/test_pointerevent_constructor.html
new file mode 100644
index 000000000..785169fb5
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_constructor.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_constructor.html");
+ }
+ function executeTest(int_win) {
+ // Function should be, but can be empty
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_element_haspointercapture-manual.html b/dom/events/test/pointerevents/test_pointerevent_element_haspointercapture-manual.html
new file mode 100644
index 000000000..215e93b57
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_element_haspointercapture-manual.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_element_haspointercapture-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target1", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target1", "mouseup", {button:0});
+ sendMouseEvent(int_win, "target1", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target1", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_element_haspointercapture_release_pending_capture-manual.html b/dom/events/test/pointerevents/test_pointerevent_element_haspointercapture_release_pending_capture-manual.html
new file mode 100644
index 000000000..1ec769bc7
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_element_haspointercapture_release_pending_capture-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_element_haspointercapture_release_pending_capture-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target1", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target1", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_gotpointercapture_before_first_pointerevent-manual.html b/dom/events/test/pointerevents/test_pointerevent_gotpointercapture_before_first_pointerevent-manual.html
new file mode 100644
index 000000000..875e18429
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_gotpointercapture_before_first_pointerevent-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_gotpointercapture_before_first_pointerevent-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_lostpointercapture_for_disconnected_node-manual.html b/dom/events/test/pointerevents/test_pointerevent_lostpointercapture_for_disconnected_node-manual.html
new file mode 100644
index 000000000..b381de108
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_lostpointercapture_for_disconnected_node-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.requestFlakyTimeout("Official test uses timeout");
+ function startTest() {
+ runTestInNewWindow("pointerevent_lostpointercapture_for_disconnected_node-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "btnCapture", "mousedown");
+ sendMouseEvent(int_win, "btnCapture", "mousemove");
+ setTimeout(function() {
+ sendMouseEvent(int_win, "target1", "mousemove");
+ }, 500);
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_lostpointercapture_is_first-manual.html b/dom/events/test/pointerevents/test_pointerevent_lostpointercapture_is_first-manual.html
new file mode 100644
index 000000000..43071b67f
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_lostpointercapture_is_first-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_lostpointercapture_is_first-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "btnCapture", "mousedown", {button:0});
+ sendMouseEvent(int_win, "btnCapture", "mouseup", {button:0});
+ sendMouseEvent(int_win, "btnCapture", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_multiple_primary_pointers_boundary_events-manual.html b/dom/events/test/pointerevents/test_pointerevent_multiple_primary_pointers_boundary_events-manual.html
new file mode 100644
index 000000000..d3c2f8962
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_multiple_primary_pointers_boundary_events-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_multiple_primary_pointers_boundary_events-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendTouchEvent(int_win, "target1", "touchstart");
+ sendTouchEvent(int_win, "target1", "touchend");
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "done", "mousedown", {button:0});
+ sendMouseEvent(int_win, "done", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerId_scope-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerId_scope-manual.html
new file mode 100644
index 000000000..d78246dca
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerId_scope-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerId_scope-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointercancel_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointercancel_touch-manual.html
new file mode 100644
index 000000000..de2839350
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointercancel_touch-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointercancel_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchcancel");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerdown-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerdown-manual.html
new file mode 100644
index 000000000..f6febcfd4
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerdown-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerdown-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "log", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousedown", {button:1});
+ sendMouseEvent(int_win, "target0", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerenter-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerenter-manual.html
new file mode 100644
index 000000000..9c2247198
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerenter-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerenter-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerenter_does_not_bubble-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerenter_does_not_bubble-manual.html
new file mode 100644
index 000000000..5e13dd212
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerenter_does_not_bubble-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerenter_does_not_bubble-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "log", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerenter_nohover-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerenter_nohover-manual.html
new file mode 100644
index 000000000..b92db3d52
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerenter_nohover-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerenter_nohover-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "log", "mousemove");
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointercancel_touch-manual.html
new file mode 100644
index 000000000..89419e29b
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointercancel_touch-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_after_pointercancel_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchcancel");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointerup_nohover-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointerup_nohover-manual.html
new file mode 100644
index 000000000..1cde764c4
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_after_pointerup_nohover-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_after_pointerup_nohover-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_descendant_over-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_descendant_over-manual.html
new file mode 100644
index 000000000..49c769f40
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_descendant_over-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_descendant_over-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target1", "mousedown");
+ sendMouseEvent(int_win, "target1", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_descendants-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_descendants-manual.html
new file mode 100644
index 000000000..6893b4aca
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_descendants-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_descendants-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "log", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_does_not_bubble-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_does_not_bubble-manual.html
new file mode 100644
index 000000000..e7b96d218
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_does_not_bubble-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_does_not_bubble-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_mouse-manual.html
new file mode 100644
index 000000000..d15f2c72a
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_mouse-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "log", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_pen-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_pen-manual.html
new file mode 100644
index 000000000..52f8d6618
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_pen-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_pen-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ sendMouseEvent(int_win, "target0", "mouseup", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ sendMouseEvent(int_win, "target0", "mousecancel", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerleave_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerleave_touch-manual.html
new file mode 100644
index 000000000..78ad0190a
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerleave_touch-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerleave_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointermove-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointermove-manual.html
new file mode 100644
index 000000000..218da5124
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointermove-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointermove-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointermove-on-chorded-mouse-button.html b/dom/events/test/pointerevents/test_pointerevent_pointermove-on-chorded-mouse-button.html
new file mode 100644
index 000000000..6e90b4230
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointermove-on-chorded-mouse-button.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointermove-on-chorded-mouse-button.html");
+ }
+
+ function executeTest(int_win) {
+ var utils = _getDOMWindowUtils(int_win);
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0, buttons:utils.MOUSE_BUTTONS_NO_BUTTON});
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0, buttons:utils.MOUSE_BUTTONS_LEFT_BUTTON});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0, buttons:utils.MOUSE_BUTTONS_LEFT_BUTTON});
+ sendMouseEvent(int_win, "target0", "mousedown", {button:1, buttons:utils.MOUSE_BUTTONS_LEFT_BUTTON |
+ utils.MOUSE_BUTTONS_MIDDLE_BUTTON});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:1, buttons:utils.MOUSE_BUTTONS_LEFT_BUTTON |
+ utils.MOUSE_BUTTONS_MIDDLE_BUTTON});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:1, buttons:utils.MOUSE_BUTTONS_LEFT_BUTTON});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:1, buttons:utils.MOUSE_BUTTONS_LEFT_BUTTON});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0, buttons:utils.MOUSE_BUTTONS_NO_BUTTON});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html
new file mode 100644
index 000000000..a0f3cee07
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointermove_isprimary_same_as_pointerdown-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target0", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointermove_pointertype-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointermove_pointertype-manual.html
new file mode 100644
index 000000000..7b2d13980
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointermove_pointertype-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointermove_pointertype-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ sendMouseEvent(int_win, "target0", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerout-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerout-manual.html
new file mode 100644
index 000000000..31c6dad5f
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerout-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerout-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointercancel_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointercancel_touch-manual.html
new file mode 100644
index 000000000..c861caf26
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointercancel_touch-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerout_after_pointercancel_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchcancel");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointerup_nohover-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointerup_nohover-manual.html
new file mode 100644
index 000000000..c3bfd29d5
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerout_after_pointerup_nohover-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerout_after_pointerup_nohover-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerout_pen-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerout_pen-manual.html
new file mode 100644
index 000000000..11f48b104
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerout_pen-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerout_pen-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ sendMouseEvent(int_win, "target0", "mouseup", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ sendMouseEvent(int_win, "target0", "mousecancel", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerout_received_once-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerout_received_once-manual.html
new file mode 100644
index 000000000..b895244bb
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerout_received_once-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerout_received_once-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerover-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerover-manual.html
new file mode 100644
index 000000000..80ae99c48
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerover-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerover-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointertype_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointertype_mouse-manual.html
new file mode 100644
index 000000000..aec2e8486
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointertype_mouse-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointertype_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointertype_pen-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointertype_pen-manual.html
new file mode 100644
index 000000000..1469de68c
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointertype_pen-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointertype_pen-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ sendMouseEvent(int_win, "target0", "mouseup", {inputSource:MouseEvent.MOZ_SOURCE_PEN});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointertype_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointertype_touch-manual.html
new file mode 100644
index 000000000..18a99f490
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointertype_touch-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointertype_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerup-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerup-manual.html
new file mode 100644
index 000000000..5417ad5cd
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerup-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerup-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ sendMouseEvent(int_win, "target0", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html
new file mode 100644
index 000000000..fc1fb6981
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerup_isprimary_same_as_pointerdown-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_pointerup_pointertype-manual.html b/dom/events/test/pointerevents/test_pointerevent_pointerup_pointertype-manual.html
new file mode 100644
index 000000000..b6f07dd50
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_pointerup_pointertype-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_pointerup_pointertype-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ sendMouseEvent(int_win, "target0", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html
new file mode 100644
index 000000000..cbf91df74
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_events_to_original_target-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_releasepointercapture_events_to_original_target-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ sendTouchEvent(int_win, "target0", "touchend");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_invalid_pointerid-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_invalid_pointerid-manual.html
new file mode 100644
index 000000000..55f347358
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_invalid_pointerid-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_releasepointercapture_invalid_pointerid-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchmove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointercancel_touch-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointercancel_touch-manual.html
new file mode 100644
index 000000000..6b63c307c
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointercancel_touch-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_releasepointercapture_onpointercancel_touch-manual.html");
+ }
+ function executeTest(int_win) {
+ sendTouchEvent(int_win, "target0", "touchstart");
+ sendTouchEvent(int_win, "target0", "touchcancel");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointerup_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointerup_mouse-manual.html
new file mode 100644
index 000000000..8d5bec3c3
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_onpointerup_mouse-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_releasepointercapture_onpointerup_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "btnCapture", "mousedown");
+ sendMouseEvent(int_win, "btnCapture", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_release_right_after_capture-manual.html b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_release_right_after_capture-manual.html
new file mode 100644
index 000000000..3f55c1afe
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_releasepointercapture_release_right_after_capture-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_releasepointercapture_release_right_after_capture-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_disconnected-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_disconnected-manual.html
new file mode 100644
index 000000000..ffbfc6009
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_disconnected-manual.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_setpointercapture_disconnected-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ sendMouseEvent(int_win, "target0", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_inactive_button_mouse-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_inactive_button_mouse-manual.html
new file mode 100644
index 000000000..e587e6e68
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_inactive_button_mouse-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_setpointercapture_inactive_button_mouse-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_invalid_pointerid-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_invalid_pointerid-manual.html
new file mode 100644
index 000000000..61171196a
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_invalid_pointerid-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_setpointercapture_invalid_pointerid-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_override_pending_capture_element-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_override_pending_capture_element-manual.html
new file mode 100644
index 000000000..5a3adede6
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_override_pending_capture_element-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_setpointercapture_override_pending_capture_element-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html
new file mode 100644
index 000000000..0883d616b
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_relatedtarget-manual.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_setpointercapture_relatedtarget-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "btnCapture", "mousedown");
+ sendMouseEvent(int_win, "target1", "mousemove");
+ sendMouseEvent(int_win, "target1", "mouseup");
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_setpointercapture_to_same_element_twice-manual.html b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_to_same_element_twice-manual.html
new file mode 100644
index 000000000..e4af7dd56
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_setpointercapture_to_same_element_twice-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_setpointercapture_to_same_element_twice-manual.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousemove");
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_click.html b/dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_click.html
new file mode 100644
index 000000000..c09135449
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_click.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_suppress_compat_events_on_click.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ sendMouseEvent(int_win, "target1", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target1", "mouseup", {button:0});
+ sendMouseEvent(int_win, "done", "mousedown", {button:0});
+ sendMouseEvent(int_win, "done", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_drag_mouse.html b/dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_drag_mouse.html
new file mode 100644
index 000000000..d379134cd
--- /dev/null
+++ b/dom/events/test/pointerevents/test_pointerevent_suppress_compat_events_on_drag_mouse.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1000870
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1000870</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="mochitest_support_external.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ SimpleTest.waitForExplicitFinish();
+ function startTest() {
+ runTestInNewWindow("pointerevent_suppress_compat_events_on_drag_mouse.html");
+ }
+ function executeTest(int_win) {
+ sendMouseEvent(int_win, "target0", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target0", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target0", "mouseup", {button:0});
+ sendMouseEvent(int_win, "target1", "mousedown", {button:0});
+ sendMouseEvent(int_win, "target1", "mousemove", {button:0});
+ sendMouseEvent(int_win, "target1", "mouseup", {button:0});
+ sendMouseEvent(int_win, "done", "mousedown", {button:0});
+ sendMouseEvent(int_win, "done", "mouseup", {button:0});
+ }
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/dom/events/test/pointerevents/test_touch_action.html b/dom/events/test/pointerevents/test_touch_action.html
new file mode 100644
index 000000000..31d115f82
--- /dev/null
+++ b/dom/events/test/pointerevents/test_touch_action.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>W3C pointerevents/*touch-action*.html tests in Mochitest form</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="apz_test_utils.js"></script>
+ <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+var apz_touch_action_prefs = [
+ // Obviously we need touch-action support enabled for testing touch-action.
+ ["layout.css.touch_action.enabled", true],
+ // Dropping the touch slop to 0 makes the tests easier to write because
+ // we can just do a one-pixel drag to get over the pan threshold rather
+ // than having to hard-code some larger value.
+ ["apz.touch_start_tolerance", "0.0"],
+ // The touchstart from the drag can turn into a long-tap if the touch-move
+ // events get held up. Try to prevent that by making long-taps require
+ // a 10 second hold. Note that we also cannot enable chaos mode on this
+ // test for this reason, since chaos mode can cause the long-press timer
+ // to fire sooner than the pref dictates.
+ ["ui.click_hold_context_menus.delay", 10000],
+ // The subtests in this test do touch-drags to pan the page, but we don't
+ // want those pans to turn into fling animations, so we increase the
+ // fling-stop threshold velocity to absurdly high.
+ ["apz.fling_stopped_threshold", "10000"],
+ // The helper_div_pan's div gets a displayport on scroll, but if the
+ // test takes too long the displayport can expire before the new scroll
+ // position is synced back to the main thread. So we disable displayport
+ // expiry for these tests.
+ ["apz.displayport_expiry_ms", 0],
+];
+
+function apzScriptInjector(name) {
+ return function(childWin) {
+ childWin._ACTIVE_TEST_NAME = name;
+ injectScript('/tests/SimpleTest/paint_listener.js', childWin)()
+ .then(injectScript('apz_test_utils.js', childWin))
+ .then(injectScript('apz_test_native_event_utils.js', childWin))
+ .then(injectScript('touch_action_helpers.js', childWin));
+ };
+}
+
+// Each of these test names is turned into an entry in the |subtests| array
+// below.
+var testnames = [
+ 'pointerevent_touch-action-auto-css_touch-manual',
+ 'pointerevent_touch-action-button-test_touch-manual',
+ // this one runs as a web-platform-test since it's not a manual test
+ // 'pointerevent_touch-action-illegal',
+ 'pointerevent_touch-action-inherit_child-auto-child-none_touch-manual',
+ 'pointerevent_touch-action-inherit_child-none_touch-manual',
+ 'pointerevent_touch-action-inherit_child-pan-x-child-pan-x_touch-manual',
+ 'pointerevent_touch-action-inherit_child-pan-x-child-pan-y_touch-manual',
+ 'pointerevent_touch-action-inherit_highest-parent-none_touch-manual',
+ 'pointerevent_touch-action-inherit_parent-none_touch-manual',
+ // the keyboard-manual and mouse-manual tests require simulating keyboard/
+ // mouse input, rather than touch, so we're not going to do that here.
+ //'pointerevent_touch-action-keyboard-manual',
+ //'pointerevent_touch-action-mouse-manual',
+ 'pointerevent_touch-action-none-css_touch-manual',
+ 'pointerevent_touch-action-pan-x-css_touch-manual',
+ 'pointerevent_touch-action-pan-x-pan-y-pan-y_touch-manual',
+ 'pointerevent_touch-action-pan-x-pan-y_touch-manual',
+ 'pointerevent_touch-action-pan-y-css_touch-manual',
+ 'pointerevent_touch-action-span-test_touch-manual',
+ 'pointerevent_touch-action-svg-test_touch-manual',
+ 'pointerevent_touch-action-table-test_touch-manual',
+ // this one runs as a web-platform-test since it's not a manual test
+ //'pointerevent_touch-action-verification',
+];
+
+// Each entry in |subtests| is loaded in a new window. When loaded, it runs
+// the function returned by apzScriptInjector, which injects some helper JS
+// files into the vanilla unmodified W3C testcase, and simulates the necessary
+// user input to run the test.
+var subtests = [];
+for (var name of testnames) {
+ subtests.push({
+ 'file': name + '.html',
+ 'prefs': apz_touch_action_prefs,
+ 'onload': apzScriptInjector(name),
+ });
+}
+
+if (isApzEnabled()) {
+ SimpleTest.waitForExplicitFinish();
+ window.onload = function() {
+ runSubtestsSeriallyInFreshWindows(subtests)
+ .then(SimpleTest.finish);
+ };
+}
+
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
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 000000000..91f628827
--- /dev/null
+++ b/dom/events/test/pointerevents/touch_action_helpers.js
@@ -0,0 +1,206 @@
+// Some common helpers
+
+function touchActionSetup(testDriver) {
+ add_completion_callback(subtestDone);
+ document.body.addEventListener('touchend', testDriver, { passive: true });
+}
+
+function touchScrollRight(aSelector = '#target0', aX = 20, aY = 20) {
+ var target = document.querySelector(aSelector);
+ return ok(synthesizeNativeTouchDrag(target, aX + 40, aY, -40, 0), "Synthesized horizontal drag");
+}
+
+function touchScrollDown(aSelector = '#target0', aX = 20, aY = 20) {
+ var target = document.querySelector(aSelector);
+ return ok(synthesizeNativeTouchDrag(target, aX, aY + 40, 0, -40), "Synthesized vertical drag");
+}
+
+function tapComplete() {
+ var button = document.getElementById('btnComplete');
+ return button.click();
+}
+
+// The main body functions to simulate the input events required for the named test
+
+function* pointerevent_touch_action_auto_css_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollDown();
+}
+
+function* pointerevent_touch_action_button_test_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollDown('#target0 > button');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > button');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_auto_child_none_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_none_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#target0 > div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_pan_x_child_pan_x_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_child_pan_x_child_pan_y_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_inherit_highest_parent_none_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#target0 > div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > div');
+}
+
+function* pointerevent_touch_action_inherit_parent_none_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_none_css_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_pan_x_css_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_pan_x_pan_y_pan_y_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0 > div div');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_pan_x_pan_y_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight();
+}
+
+function* pointerevent_touch_action_pan_y_css_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_span_test_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollDown('#testspan');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#testspan');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_svg_test_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollRight();
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollDown('#target0', 250, 250);
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#target0', 250, 250);
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+function* pointerevent_touch_action_table_test_touch_manual(testDriver) {
+ touchActionSetup(testDriver);
+
+ yield touchScrollDown('#row1');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollRight('#row1');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield setTimeout(testDriver, 2 * scrollReturnInterval);
+ yield touchScrollDown('#cell3');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield touchScrollRight('#cell3');
+ yield waitForApzFlushedRepaints(testDriver);
+ yield tapComplete();
+}
+
+// This the stuff that runs the appropriate body function above
+
+var test = eval(_ACTIVE_TEST_NAME.replace(/-/g, '_'));
+waitUntilApzStable().then(runContinuation(test));
diff --git a/dom/events/test/test_DataTransferItemList.html b/dom/events/test/test_DataTransferItemList.html
new file mode 100644
index 000000000..a267a183e
--- /dev/null
+++ b/dom/events/test/test_DataTransferItemList.html
@@ -0,0 +1,232 @@
+<html>
+<head>
+ <title>Tests for the DatTransferItemList object</title>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+<body style="height: 300px; overflow: auto;">
+<p id="display"> </p>
+<img id="image" draggable="true" src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82">
+<div id="over" "style="width: 100px; height: 100px; border: 2px black dashed;">
+ drag over here
+</div>
+
+<script>
+ function spin() {
+ // Defer to the event loop twice to wait for any events to be flushed out.
+ return new Promise(function(a) {
+ SimpleTest.executeSoon(function() {
+ SimpleTest.executeSoon(a)
+ });
+ });
+ }
+
+ add_task(function* () {
+ yield spin();
+ var draggable = document.getElementById('image');
+ var over = document.getElementById('over');
+
+ var dragstartFired = 0;
+ draggable.addEventListener('dragstart', onDragStart);
+ function onDragStart(e) {
+ draggable.removeEventListener('dragstart', onDragStart);
+
+ var dt = e.dataTransfer;
+ dragstartFired++;
+
+ ok(true, "dragStart event fired");
+ var dtList = e.dataTransfer.items;
+ ok(dtList instanceof DataTransferItemList,
+ "DataTransfer.items returns a DataTransferItemList");
+
+ for (var i = 0; i < dtList.length; i++) {
+ var item = dtList[i];
+ ok(item instanceof DataTransferItem,
+ "operator[] returns DataTransferItem objects");
+ if (item.kind == "file") {
+ var file = item.getAsFile();
+ ok(file instanceof File, "getAsFile() returns File objects");
+ }
+ }
+
+ dtList.clear();
+ is(dtList.length, 0, "after .clear() DataTransferItemList should be empty");
+
+ dtList.add("this is some text", "text/plain");
+ dtList.add("<a href='www.mozilla.org'>this is a link</a>", "text/html");
+ dtList.add("http://www.mozilla.org", "text/uri-list");
+ dtList.add("this is custom-data", "custom-data");
+
+
+ var file = new File(['<a id="a"><b id="b">hey!</b></a>'], "myfile.html",
+ {type: "text/html"});
+
+ dtList.add(file);
+
+ checkTypes(["text/plain", "text/html", "text/uri-list", "custom-data", "text/html"],
+ dtList, "DataTransferItemList.add test");
+
+ var files = e.dataTransfer.files;
+ is(files.length, 1, "DataTransfer.files should contain the one file we added earlier");
+ is(files[0], file, "It should be the same file as the file we originally created");
+ is(file, e.dataTransfer.mozGetDataAt("text/html", 1),
+ "It should be stored in index 1 for mozGetDataAt");
+
+ var file2 = new File(['<a id="c"><b id="d">yo!</b></a>'], "myotherfile.html",
+ {type: "text/html"});
+ dtList.add(file2);
+
+ todo(files.length == 2, "This test has chrome privileges, so the FileList objects aren't updated live");
+ files = e.dataTransfer.files;
+ is(files.length, 2, "The files property should have been updated in place");
+ is(files[1], file2, "It should be the same file as the file we originally created");
+ is(file2, e.dataTransfer.mozGetDataAt("text/html", 2),
+ "It should be stored in index 2 for mozGetDataAt");
+
+ var oldLength = dtList.length;
+ var randomString = "foo!";
+ e.dataTransfer.mozSetDataAt("random/string", randomString, 3);
+ is(oldLength, dtList.length,
+ "Adding a non-file entry to a non-zero index should not add an item to the items list");
+
+ var file3 = new File(['<a id="e"><b id="f">heya!</b></a>'], "yetanotherfile.html",
+ {type: "text/html"});
+ e.dataTransfer.mozSetDataAt("random/string", file3, 3);
+ is(oldLength + 1, dtList.length,
+ "Replacing the entry with a file should add it to the list!");
+ is(dtList[oldLength].getAsFile(), file3, "It should be stored in the last index as a file");
+ is(dtList[oldLength].type, "text/html", "It should have the correct type");
+ is(dtList[oldLength].kind, "file", "It should have the correct kind");
+
+ todo(files.length == 3, "This test has chrome privileges, so the FileList objects aren't updated live");
+ files = e.dataTransfer.files;
+ is(files[files.length - 1], file3, "It should also be in the files list");
+
+ oldLength = dtList.length;
+ var nonstring = {};
+ e.dataTransfer.mozSetDataAt("jsobject", nonstring, 0);
+ is(oldLength + 1, dtList.length,
+ "Adding a non-string object using the mozAPIs to index 0 should add an item to the dataTransfer");
+ is(dtList[oldLength].type, "jsobject", "It should have the correct type");
+ is(dtList[oldLength].kind, "other", "It should have the correct kind");
+
+ // Clear the event's data and get it set up so we can read it later!
+ dtList.clear();
+
+ dtList.add(file);
+ dtList.add("this is some text", "text/plain");
+ is(e.dataTransfer.mozGetDataAt("text/html", 1), file);
+ }
+
+ var getAsStringCalled = 0;
+ var dragenterFired = 0;
+ over.addEventListener('dragenter', onDragEnter);
+ function onDragEnter(e) {
+ over.removeEventListener('dragenter', onDragEnter);
+
+ var dt = e.dataTransfer;
+ dragenterFired++;
+
+ readOnly(e);
+ }
+
+ var dropFired = 0;
+ over.addEventListener('drop', onDrop);
+ function onDrop(e) {
+ over.removeEventListener('drop', onDrop);
+
+ var dt = e.dataTransfer;
+ dropFired++;
+ e.preventDefault();
+
+ readOnly(e);
+ }
+
+
+ function readOnly(e) {
+ var dtList = e.dataTransfer.items;
+ var num = dtList.length;
+
+ // .clear() should have no effect
+ dtList.clear();
+ is(dtList.length, num,
+ ".clear() should have no effect on the object during a readOnly event");
+
+ // .remove(i) should throw InvalidStateError
+ for (var i = 0; i < dtList.length; i++) {
+ expectError(function() { dtList.remove(i); },
+ "InvalidStateError", ".remove(" + i + ") during a readOnly event");
+ }
+
+ // .add() should return null and have no effect
+ var data = [["This is a plain string", "text/plain"],
+ ["This is <em>HTML!</em>", "text/html"],
+ ["http://www.mozilla.org/", "text/uri-list"],
+ ["this is some custom data", "custom-data"]];
+
+ for (var i = 0; i < data.length; i++) {
+ is(dtList.add(data[i][0], data[i][1]), null,
+ ".add() should return null during a readOnly event");
+
+ is(dtList.length, num, ".add() should have no effect during a readOnly event");
+ }
+
+ // .add() with a file should return null and have no effect
+ var file = new File(['<a id="a"><b id="b">hey!</b></a>'], "myfile.html",
+ {type: "text/html"});
+ is(dtList.add(file), null, ".add() with a file should return null during a readOnly event");
+ is(dtList.length, num, ".add() should have no effect during a readOnly event");
+
+ // We should be able to access the files
+ is(e.dataTransfer.files.length, 1, "Should be able to access files");
+ ok(e.dataTransfer.files[0], "File should be the same file!");
+ is(e.dataTransfer.items.length, 2, "Should be able to see there are 2 items");
+
+ is(e.dataTransfer.items[0].kind, "file", "First item should be a file");
+ is(e.dataTransfer.items[1].kind, "string", "Second item should be a string");
+
+ is(e.dataTransfer.items[0].type, "text/html", "first item should be text/html");
+ is(e.dataTransfer.items[1].type, "text/plain", "second item should be text/plain");
+
+ ok(e.dataTransfer.items[0].getAsFile(), "Should be able to get file");
+ e.dataTransfer.items[1].getAsString(function(s) {
+ getAsStringCalled++;
+ is(s, "this is some text", "Should provide the correct string");
+ });
+ }
+
+ synthesizeDrop(draggable, over, null, null);
+
+ // Wait for the getAsString callbacks to complete
+ yield spin();
+ is(getAsStringCalled, 2, "getAsString should be called twice");
+
+ // Sanity-check to make sure that the events were actually run
+ is(dragstartFired, 1, "dragstart fired");
+ is(dragenterFired, 1, "dragenter fired");
+ is(dropFired, 1, "drop fired");
+ });
+
+ function expectError(fn, eid, testid) {
+ var error = "";
+ try {
+ fn();
+ } catch (ex) {
+ error = ex.name;
+ }
+ is(error, eid, testid + " causes exception " + eid);
+ }
+
+ function checkTypes(aExpectedList, aDtList, aTestid) {
+ is(aDtList.length, aExpectedList.length, aTestid + " length test");
+ for (var i = 0; i < aExpectedList.length; i++) {
+ is(aDtList[i].type, aExpectedList[i], aTestid + " type " + i);
+ }
+ }
+</script>
+
+</body>
+</html>
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 000000000..5e320b61f
--- /dev/null
+++ b/dom/events/test/test_accel_virtual_modifier.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for DOM "Accel" virtual modifier</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+var kAccel = "Accel";
+var kAccelKeyCode = SpecialPowers.getIntPref("ui.key.accelKey");
+
+var mouseEvent = new MouseEvent("mousedown", {});
+is(mouseEvent.getModifierState(kAccel), false,
+ "MouseEvent.getModifierState(\"" + kAccel + "\") should be false");
+mouseEvent = new MouseEvent("wheel", { accelKey: true});
+is(mouseEvent.getModifierState(kAccel), false,
+ "MouseEvent.getModifierState(\"" + kAccel + "\") should be false due to not supporting accelKey attribute");
+mouseEvent = new MouseEvent("mousedown", { ctrlKey: true });
+is(mouseEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_CONTROL,
+ "MouseEvent.getModifierState(\"" + kAccel + "\") should be true if ctrlKey is an accel modifier");
+mouseEvent = new MouseEvent("mousedown", { altKey: true });
+is(mouseEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_ALT,
+ "MouseEvent.getModifierState(\"" + kAccel + "\") should be true if altKey is an accel modifier");
+mouseEvent = new MouseEvent("mousedown", { metaKey: true });
+is(mouseEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_META,
+ "MouseEvent.getModifierState(\"" + kAccel + "\") should be true if metaKey is an accel modifier");
+mouseEvent = new MouseEvent("mousedown", { ctrlKey: true, altKey: true, metaKey: true });
+is(mouseEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_CONTROL ||
+ kAccelKeyCode == KeyboardEvent.DOM_VK_ALT ||
+ kAccelKeyCode == KeyboardEvent.DOM_VK_META,
+ "MouseEvent.getModifierState(\"" + kAccel + "\") should be true if one of ctrlKey, altKey or metaKey is an accel modifier");
+
+var wheelEvent = new WheelEvent("wheel", {});
+is(wheelEvent.getModifierState(kAccel), false,
+ "WheelEvent.getModifierState(\"" + kAccel + "\") should be false");
+wheelEvent = new WheelEvent("wheel", { accelKey: true});
+is(wheelEvent.getModifierState(kAccel), false,
+ "WheelEvent.getModifierState(\"" + kAccel + "\") should be false due to not supporting accelKey attribute");
+wheelEvent = new WheelEvent("wheel", { ctrlKey: true });
+is(wheelEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_CONTROL,
+ "WheelEvent.getModifierState(\"" + kAccel + "\") should be true if ctrlKey is an accel modifier");
+wheelEvent = new WheelEvent("wheel", { altKey: true });
+is(wheelEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_ALT,
+ "WheelEvent.getModifierState(\"" + kAccel + "\") should be true if altKey is an accel modifier");
+wheelEvent = new WheelEvent("wheel", { metaKey: true });
+is(wheelEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_META,
+ "WheelEvent.getModifierState(\"" + kAccel + "\") should be true if metaKey is an accel modifier");
+wheelEvent = new WheelEvent("wheel", { ctrlKey: true, altKey: true, metaKey: true });
+is(wheelEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_CONTROL ||
+ kAccelKeyCode == KeyboardEvent.DOM_VK_ALT ||
+ kAccelKeyCode == KeyboardEvent.DOM_VK_META,
+ "WheelEvent.getModifierState(\"" + kAccel + "\") should be true if one of ctrlKey, altKey or metaKey is an accel modifier");
+
+var keyboardEvent = new KeyboardEvent("keydown", {});
+is(keyboardEvent.getModifierState(kAccel), false,
+ "KeyboardEvent.getModifierState(\"" + kAccel + "\") should be false");
+keyboardEvent = new KeyboardEvent("keydown", { accelKey: true});
+is(keyboardEvent.getModifierState(kAccel), false,
+ "KeyboardEvent.getModifierState(\"" + kAccel + "\") should be false due to not supporting accelKey attribute");
+keyboardEvent = new KeyboardEvent("keydown", { ctrlKey: true });
+is(keyboardEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_CONTROL,
+ "KeyboardEvent.getModifierState(\"" + kAccel + "\") should be true if ctrlKey is an accel modifier");
+keyboardEvent = new KeyboardEvent("keydown", { altKey: true });
+is(keyboardEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_ALT,
+ "KeyboardEvent.getModifierState(\"" + kAccel + "\") should be true if altKey is an accel modifier");
+keyboardEvent = new KeyboardEvent("keydown", { metaKey: true });
+is(keyboardEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_META,
+ "KeyboardEvent.getModifierState(\"" + kAccel + "\") should be true if metaKey is an accel modifier");
+keyboardEvent = new KeyboardEvent("keydown", { ctrlKey: true, altKey: true, metaKey: true });
+is(keyboardEvent.getModifierState(kAccel), kAccelKeyCode == KeyboardEvent.DOM_VK_CONTROL ||
+ kAccelKeyCode == KeyboardEvent.DOM_VK_ALT ||
+ kAccelKeyCode == KeyboardEvent.DOM_VK_META,
+ "KeyboardEvent.getModifierState(\"" + kAccel + "\") should be true if one of ctrlKey, altKey or metaKey is an accel modifier");
+
+// "Accel" virtual modifier must be supported with getModifierState(). So, any legacy init*Event()'s
+// modifiers list argument shouldn't accept "Accel".
+ok(typeof(KeyboardEvent.initKeyboardEvent) != "function",
+ "If we would support KeyboardEvent.initKeyboardEvent, we should test its modifier list argument doesn't accept \"" + kAccel + "\"");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_addEventListenerExtraArg.html b/dom/events/test/test_addEventListenerExtraArg.html
new file mode 100644
index 000000000..e343f3c6d
--- /dev/null
+++ b/dom/events/test/test_addEventListenerExtraArg.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=828554
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 828554</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 828554 **/
+ SimpleTest.waitForExplicitFinish();
+ window.addEventListener("message", function() {
+ ok(true, "We got called");
+ SimpleTest.finish();
+ }, false, undefined);
+ window.postMessage("Hey there", "*");
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=828554">Mozilla Bug 828554</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
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 000000000..90dbe95ee
--- /dev/null
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -0,0 +1,515 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Test all synthetic events</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/**
+ * kEventConstructors is a helper and database of all events.
+ * The sort order of the definition is by A to Z (ignore the Event postfix).
+ *
+ * XXX: should we move this into EventUtils.js?
+ *
+ * create: function or null. If this is null, it's impossible to create untrusted event for it.
+ * Otherwise, create(aName, aProps) returns an instance of the event initialized with aProps.
+ * aName specifies the event's type name. See each create() code for the detail of aProps.
+ */
+const kEventConstructors = {
+ Event: { create: function (aName, aProps) {
+ return new Event(aName, aProps);
+ },
+ },
+ AnimationEvent: { create: function (aName, aProps) {
+ return new AnimationEvent(aName, aProps);
+ },
+ },
+ AnimationPlaybackEvent: { create: function (aName, aProps) {
+ return new AnimationPlaybackEvent(aName, aProps);
+ },
+ },
+ AudioProcessingEvent: { create: null, // Cannot create untrusted event from JS.
+ },
+ BeforeAfterKeyboardEvent: { create: function (aName, aProps) {
+ return new BeforeAfterKeyboardEvent(aName, aProps);
+ },
+ },
+ BeforeUnloadEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("beforeunloadevent");
+ e.initEvent(aName, aProps.bubbles, aProps.cancelable);
+ return e;
+ },
+ },
+ BlobEvent: { create: function (aName, aProps) {
+ return new BlobEvent(aName, aProps);
+ },
+ },
+ CallEvent: { create: function (aName, aProps) {
+ return new CallEvent(aName, aProps);
+ },
+ },
+ CallGroupErrorEvent: { create: function (aName, aProps) {
+ return new CallGroupErrorEvent(aName, aProps);
+ },
+ },
+ CFStateChangeEvent: { create: function (aName, aProps) {
+ return new CFStateChangeEvent(aName, aProps);
+ },
+ },
+ CloseEvent: { create: function (aName, aProps) {
+ return new CloseEvent(aName, aProps);
+ },
+ },
+ ClipboardEvent: { create: function (aName, aProps) {
+ return new ClipboardEvent(aName, aProps);
+ },
+ },
+ CommandEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("commandevent");
+ e.initCommandEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.command);
+ return e;
+ },
+ },
+ CompositionEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("compositionevent");
+ e.initCompositionEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.data, aProps.locale);
+ return e;
+ },
+ },
+ CustomEvent: { create: function (aName, aProps) {
+ return new CustomEvent(aName, aProps);
+ },
+ },
+ DataErrorEvent: { create: function (aName, aProps) {
+ return new DataErrorEvent(aName, aProps);
+ },
+ },
+ DataContainerEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("datacontainerevent");
+ e.initEvent(aName, aProps.bubbles, aProps.cancelable);
+ return e;
+ },
+ },
+ DeviceLightEvent: { create: function (aName, aProps) {
+ return new DeviceLightEvent(aName, aProps);
+ },
+ },
+ DeviceMotionEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("devicemotionevent");
+ e.initDeviceMotionEvent(aName, aProps.bubbles, aProps.cancelable, aProps.acceleration,
+ aProps.accelerationIncludingGravity, aProps.rotationRate,
+ aProps.interval || 0.0);
+ return e;
+ },
+ },
+ DeviceOrientationEvent: { create: function (aName, aProps) {
+ return new DeviceOrientationEvent(aName, aProps);
+ },
+ },
+ DeviceProximityEvent: { create: function (aName, aProps) {
+ return new DeviceProximityEvent(aName, aProps);
+ },
+ },
+ DownloadEvent: { create: function (aName, aProps) {
+ return new DownloadEvent(aName, aProps);
+ },
+ },
+ DragEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("dragevent");
+ e.initDragEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.detail,
+ aProps.screenX, aProps.screenY,
+ aProps.clientX, aProps.clientY,
+ aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey,
+ aProps.button, aProps.relatedTarget, aProps.dataTransfer);
+ return e;
+ },
+ },
+ ErrorEvent: { create: function (aName, aProps) {
+ return new ErrorEvent(aName, aProps);
+ },
+ },
+ FlyWebFetchEvent: { create: null, // Cannot create untrusted event from JS.
+ },
+ FlyWebWebSocketEvent: { create: null, // Cannot create untrusted event from JS.
+ },
+ FocusEvent: { create: function (aName, aProps) {
+ return new FocusEvent(aName, aProps);
+ },
+ },
+ FontFaceSetLoadEvent: { create: function (aName, aProps) {
+ return new FontFaceSetLoadEvent(aName, aProps);
+ },
+ },
+ GamepadEvent: { create: function (aName, aProps) {
+ return new GamepadEvent(aName, aProps);
+ },
+ },
+ GamepadAxisMoveEvent: { create: function (aName, aProps) {
+ return new GamepadAxisMoveEvent(aName, aProps);
+ },
+ },
+ GamepadButtonEvent: { create: function (aName, aProps) {
+ return new GamepadButtonEvent(aName, aProps);
+ },
+ },
+ HashChangeEvent: { create: function (aName, aProps) {
+ return new HashChangeEvent(aName, aProps);
+ },
+ },
+ IDBVersionChangeEvent: { create: function (aName, aProps) {
+ return new IDBVersionChangeEvent(aName, aProps);
+ },
+ },
+ ImageCaptureErrorEvent: { create: function (aName, aProps) {
+ return new ImageCaptureErrorEvent(aName, aProps);
+ },
+ },
+ InputEvent: { create: function (aName, aProps) {
+ return new InputEvent(aName, aProps);
+ },
+ },
+ KeyEvent: { create: function (aName, aProps) {
+ return new KeyboardEvent(aName, aProps);
+ },
+ },
+ KeyboardEvent: { create: function (aName, aProps) {
+ return new KeyboardEvent(aName, aProps);
+ },
+ },
+ MediaEncryptedEvent: { create: function (aName, aProps) {
+ return new MediaEncryptedEvent(aName, aProps);
+ },
+ },
+ MediaKeyMessageEvent: { create: function (aName, aProps) {
+ return new MediaKeyMessageEvent(aName, {
+ messageType: "license-request",
+ message: new ArrayBuffer(0)
+ });
+ },
+ },
+ MediaStreamEvent: { create: function (aName, aProps) {
+ return new MediaStreamEvent(aName, aProps);
+ },
+ },
+ MediaStreamTrackEvent: {
+ // Difficult to test required arguments.
+ },
+ MessageEvent: { create: function (aName, aProps) {
+ var e = new MessageEvent("messageevent", { bubbles: aProps.bubbles,
+ cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin,
+ lastEventId: aProps.lastEventId, source: aProps.source });
+ return e;
+ },
+ },
+ MouseEvent: { create: function (aName, aProps) {
+ return new MouseEvent(aName, aProps);
+ },
+ },
+ MouseScrollEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("mousescrollevents");
+ e.initMouseScrollEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.detail,
+ aProps.screenX, aProps.screenY,
+ aProps.clientX, aProps.clientY,
+ aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey,
+ aProps.button, aProps.relatedTarget, aProps.axis);
+ return e;
+ },
+ },
+ MozApplicationEvent: { create: function (aName, aProps) {
+ return new MozApplicationEvent(aName, aProps);
+ },
+ },
+ MozClirModeEvent: { create: function (aName, aProps) {
+ return new MozClirModeEvent(aName, aProps);
+ },
+ },
+ MozContactChangeEvent: { create: function (aName, aProps) {
+ return new MozContactChangeEvent(aName, aProps);
+ },
+ },
+ MozEmergencyCbModeEvent: { create: function (aName, aProps) {
+ return new MozEmergencyCbModeEvent(aName, aProps);
+ },
+ },
+ MozMessageDeletedEvent: { create: function (aName, aProps) {
+ return new MozMessageDeletedEvent(aName, aProps);
+ },
+ },
+ MozMmsEvent: { create: function (aName, aProps) {
+ return new MozMmsEvent(aName, aProps);
+ },
+ },
+ MozOtaStatusEvent: { create: function (aName, aProps) {
+ return new MozOtaStatusEvent(aName, aProps);
+ },
+ },
+ MozSettingsEvent: { create: function (aName, aProps) {
+ return new MozSettingsEvent(aName, aProps);
+ },
+ },
+ MozSettingsTransactionEvent: { create: function (aName, aProps) {
+ return new MozSettingsTransactionEvent(aName, aProps);
+ },
+ },
+ MozSmsEvent: { create: function (aName, aProps) {
+ return new MozSmsEvent(aName, aProps);
+ },
+ },
+ MozStkCommandEvent: { create: function (aName, aProps) {
+ return new MozStkCommandEvent(aName, aProps);
+ },
+ },
+ MozWifiConnectionInfoEvent: { create: function (aName, aProps) {
+ return new MozWifiConnectionInfoEvent(aName, aProps);
+ },
+ },
+ MozWifiStatusChangeEvent: { create: function (aName, aProps) {
+ return new MozWifiStatusChangeEvent(aName, aProps);
+ },
+ },
+ MozWifiStationInfoEvent: { create: function (aName, aProps) {
+ return new MozWifiStationInfoEvent(aName, aProps);
+ },
+ },
+ MutationEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("mutationevent");
+ e.initMutationEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.relatedNode, aProps.prevValue, aProps.newValue,
+ aProps.attrName, aProps.attrChange);
+ return e;
+ },
+ },
+ NotifyPaintEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("notifypaintevent");
+ e.initEvent(aName, aProps.bubbles, aProps.cancelable);
+ return e;
+ },
+ },
+ OfflineAudioCompletionEvent: { create: null, // Cannot create untrusted event from JS.
+ },
+ PageTransitionEvent: { create: function (aName, aProps) {
+ return new PageTransitionEvent(aName, aProps);
+ },
+ },
+ PointerEvent: { create: function (aName, aProps) {
+ return new PointerEvent(aName, aProps);
+ },
+ },
+ PopStateEvent: { create: function (aName, aProps) {
+ return new PopStateEvent(aName, aProps);
+ },
+ },
+ PopupBlockedEvent: { create: function (aName, aProps) {
+ return new PopupBlockedEvent(aName, aProps);
+ },
+ },
+ ProgressEvent: { create: function (aName, aProps) {
+ return new ProgressEvent(aName, aProps);
+ },
+ },
+ RecordErrorEvent: { create: function (aName, aProps) {
+ return new RecordErrorEvent(aName, aProps);
+ },
+ },
+ RTCDataChannelEvent: { create: function (aName, aProps) {
+ return new RTCDataChannelEvent(aName, aProps);
+ },
+ },
+ RTCDTMFToneChangeEvent: { create: function (aName, aProps) {
+ return new RTCDTMFToneChangeEvent(aName, aProps);
+ },
+ },
+ RTCPeerConnectionIceEvent: { create: function (aName, aProps) {
+ return new RTCPeerConnectionIceEvent(aName, aProps);
+ },
+ },
+ RTCTrackEvent: {
+ // Difficult to test required arguments.
+ },
+ ScrollAreaEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("scrollareaevent");
+ e.initScrollAreaEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.details,
+ aProps.x || 0.0, aProps.y || 0.0,
+ aProps.width || 0.0, aProps.height || 0.0);
+ return e;
+ },
+ },
+ ServiceWorkerMessageEvent: { create: function (aName, aProps) {
+ var e = new ServiceWorkerMessageEvent("serviceworkermessageevent", { bubbles: aProps.bubbles,
+ cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin,
+ lastEventId: aProps.lastEventId, source: aProps.source });
+ return e;
+ },
+ },
+ SimpleGestureEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("simplegestureevent");
+ e.initSimpleGestureEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.detail,
+ aProps.screenX, aProps.screenY,
+ aProps.clientX, aProps.clientY,
+ aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey,
+ aProps.button, aProps.relatedTarget,
+ aProps.allowedDirections, aProps.direction, aProps.delta || 0.0,
+ aProps.clickCount);
+ return e;
+ },
+ },
+ SpeechRecognitionError: { create: function (aName, aProps) {
+ return new SpeechRecognitionError(aName, aProps);
+ },
+ },
+ SpeechRecognitionEvent: { create: function (aName, aProps) {
+ return new SpeechRecognitionEvent(aName, aProps);
+ },
+ },
+ SpeechSynthesisErrorEvent: { create: function (aName, aProps) {
+ aProps.error = "synthesis-unavailable";
+ aProps.utterance = new SpeechSynthesisUtterance("Hello World");
+ return new SpeechSynthesisErrorEvent(aName, aProps);
+ },
+ },
+ SpeechSynthesisEvent: { create: function (aName, aProps) {
+ aProps.utterance = new SpeechSynthesisUtterance("Hello World");
+ return new SpeechSynthesisEvent(aName, aProps);
+ },
+ },
+ StorageEvent: { create: function (aName, aProps) {
+ return new StorageEvent(aName, aProps);
+ },
+ },
+ StyleRuleChangeEvent: { create: function (aName, aProps) {
+ return new StyleRuleChangeEvent(aName, aProps);
+ },
+ chromeOnly: true,
+ },
+ StyleSheetApplicableStateChangeEvent: { create: function (aName, aProps) {
+ return new StyleSheetApplicableStateChangeEvent(aName, aProps);
+ },
+ chromeOnly: true,
+ },
+ StyleSheetChangeEvent: { create: function (aName, aProps) {
+ return new StyleSheetChangeEvent(aName, aProps);
+ },
+ chromeOnly: true,
+ },
+ SVGZoomEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("svgzoomevent");
+ e.initUIEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.detail);
+ return e;
+ },
+ },
+ TCPSocketErrorEvent: { create: function(aName, aProps) {
+ return new TCPSocketErrorEvent(aName, aProps);
+ },
+ },
+ TCPSocketEvent: { create: function(aName, aProps) {
+ return new TCPSocketEvent(aName, aProps);
+ },
+ },
+ TCPServerSocketEvent: { create: function(aName, aProps) {
+ return new TCPServerSocketEvent(aName, aProps);
+ },
+ },
+ TimeEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("timeevent");
+ e.initTimeEvent(aName, aProps.view, aProps.detail);
+ return e;
+ },
+ },
+ TouchEvent: { create: function (aName, aProps) {
+ var e = document.createEvent("touchevent");
+ e.initTouchEvent(aName, aProps.bubbles, aProps.cancelable,
+ aProps.view, aProps.detail,
+ aProps.ctrlKey, aProps.altKey, aProps.shiftKey, aProps.metaKey,
+ aProps.touches, aProps.targetTouches, aProps.changedTouches);
+ return e;
+ },
+ },
+ TrackEvent: { create: function (aName, aProps) {
+ return new TrackEvent(aName, aProps);
+ },
+ },
+ TransitionEvent: { create: function (aName, aProps) {
+ return new TransitionEvent(aName, aProps);
+ },
+ },
+ UIEvent: { create: function (aName, aProps) {
+ return new UIEvent(aName, aProps);
+ },
+ },
+ UserProximityEvent: { create: function (aName, aProps) {
+ return new UserProximityEvent(aName, aProps);
+ },
+ },
+ USSDReceivedEvent: { create: function (aName, aProps) {
+ return new USSDReceivedEvent(aName, aProps);
+ },
+ },
+ WheelEvent: { create: function (aName, aProps) {
+ return new WheelEvent(aName, aProps);
+ },
+ },
+ WebGLContextEvent: { create: function (aName, aProps) {
+ return new WebGLContextEvent(aName, aProps);
+ },
+ },
+};
+
+for (var name of Object.keys(kEventConstructors)) {
+ if (!kEventConstructors[name].chromeOnly) {
+ continue;
+ }
+ if (window[name]) {
+ ok(false, name + " should be chrome only.");
+ }
+ window[name] = SpecialPowers.unwrap(SpecialPowers.wrap(window)[name]);
+}
+
+var props = Object.getOwnPropertyNames(window);
+for (var i = 0; i < props.length; i++) {
+ // Assume that event object must be named as "FooBarEvent".
+ if (!props[i].match(/^([A-Z][a-zA-Z]+)?Event$/)) {
+ continue;
+ }
+ if (!kEventConstructors[props[i]]) {
+ ok(false, "Unknown event found: " + props[i]);
+ continue;
+ }
+ if (!kEventConstructors[props[i]].create) {
+ todo(false, "Cannot create untrusted event of " + props[i]);
+ continue;
+ }
+ ok(true, "Creating " + props[i] + "...");
+ var event = kEventConstructors[props[i]].create("foo", {});
+ if (!event) {
+ ok(false, "Failed to create untrusted event: " + props[i]);
+ continue;
+ }
+ if (typeof(event.getModifierState) == "function") {
+ const kModifiers = [ "Shift", "Control", "Alt", "AltGr", "Meta", "CapsLock", "ScrollLock", "NumLock", "OS", "Fn", "FnLock", "Symbol", "SymbolLock" ];
+ for (var j = 0; j < kModifiers.length; j++) {
+ ok(true, "Calling " + props[i] + ".getModifierState(" + kModifiers[j] + ")...");
+ var modifierState = event.getModifierState(kModifiers[j]);
+ ok(true, props[i] + ".getModifierState(" + kModifiers[j] + ") = " + modifierState);
+ }
+ }
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1003432.html b/dom/events/test/test_bug1003432.html
new file mode 100644
index 000000000..7ffd3f7c4
--- /dev/null
+++ b/dom/events/test/test_bug1003432.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1003432
+-->
+<head>
+ <title>Test for Bug 1003432</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1003432">Mozilla Bug 1003432</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1003432 **/
+// Test CustomEvent on worker
+SimpleTest.waitForExplicitFinish();
+var worker = new Worker("test_bug1003432.js");
+ok(worker, "Should have worker!");
+
+var count = 0;
+worker.onmessage = function(evt) {
+ is(evt.data.type, "foobar", "Should get 'foobar' event!");
+ is(evt.data.detail, "test", "Detail should be 'test'.");
+ ok(evt.data.bubbles, "Event should bubble!");
+ ok(evt.data.cancelable, "Event should be cancelable.");
+
+ // wait for test results of constructor and initCustomEvent
+ if (++count == 2) {
+ worker.terminate();
+ SimpleTest.finish();
+ }
+};
+
+worker.postMessage("");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1003432.js b/dom/events/test/test_bug1003432.js
new file mode 100644
index 000000000..1ace8fefd
--- /dev/null
+++ b/dom/events/test/test_bug1003432.js
@@ -0,0 +1,23 @@
+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 000000000..b63eb615e
--- /dev/null
+++ b/dom/events/test/test_bug1013412.html
@@ -0,0 +1,110 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1013412
+-->
+<head>
+ <title>Test for Bug 1013412</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ #content {
+ height: 800px;
+ overflow: scroll;
+ }
+
+ #scroller {
+ height: 2000px;
+ background: repeating-linear-gradient(#EEE, #EEE 100px, #DDD 100px, #DDD 200px);
+ }
+
+ #scrollbox {
+ margin-top: 200px;
+ width: 500px;
+ height: 500px;
+ border-radius: 250px;
+ box-shadow: inset 0 0 0 60px #555;
+ background: #777;
+ }
+
+ #circle {
+ position: relative;
+ left: 240px;
+ top: 20px;
+ border: 10px solid white;
+ border-radius: 10px;
+ width: 0px;
+ height: 0px;
+ transform-origin: 10px 230px;
+ will-change: transform;
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1013412">Mozilla Bug 1013412</a>
+<p id="display"></p>
+<div id="content">
+ <p>Scrolling the page should be async, but scrolling over the dark circle should not scroll the page and instead rotate the white ball.</p>
+ <div id="scroller">
+ <div id="scrollbox">
+ <div id="circle"></div>
+ </div>
+ </div>
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7">
+
+/** Test for Bug 1013412 **/
+
+var rotation = 0;
+var rotationAdjusted = false;
+
+var incrementForMode = function (mode) {
+ switch (mode) {
+ case WheelEvent.DOM_DELTA_PIXEL: return 1;
+ case WheelEvent.DOM_DELTA_LINE: return 15;
+ case WheelEvent.DOM_DELTA_PAGE: return 400;
+ }
+ return 0;
+};
+
+document.getElementById("scrollbox").addEventListener("wheel", function (e) {
+ rotation += e.deltaY * incrementForMode(e.deltaMode) * 0.2;
+ document.getElementById("circle").style.transform = "rotate(" + rotation + "deg)";
+ rotationAdjusted = true;
+ e.preventDefault();
+});
+
+var iteration = 0;
+function runTest() {
+ var content = document.getElementById('content');
+ if (iteration < 300) { // enough iterations that we would scroll to the bottom of 'content'
+ iteration++;
+ synthesizeWheel(content, 100, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ setTimeout(runTest, 0);
+ return;
+ }
+ var scrollbox = document.getElementById('scrollbox');
+ is(content.scrollTop < content.scrollTopMax, true, "We should not have scrolled to the bottom of the scrollframe");
+ is(rotationAdjusted, true, "The rotation should have been adjusted");
+ SimpleTest.finish();
+}
+
+function startTest() {
+ // If we allow smooth scrolling the "smooth" scrolling may cause the page to
+ // glide past the scrollbox (which is supposed to stop the scrolling) and so
+ // we might end up at the bottom of the page.
+ SpecialPowers.pushPrefEnv({"set": [["general.smoothScroll", false]]}, runTest);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(startTest, window);
+
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug1017086_disable.html b/dom/events/test/test_bug1017086_disable.html
new file mode 100644
index 000000000..f13d2aff3
--- /dev/null
+++ b/dom/events/test/test_bug1017086_disable.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1017086</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ /** Test for Bug 1017086 **/
+ var pointer_events_enabled = false;
+ function prepareTest() {
+ SimpleTest.waitForExplicitFinish();
+ turnOnOffPointerEvents(startTest);
+ }
+ function turnOnOffPointerEvents(callback) {
+ SpecialPowers.pushPrefEnv({
+ "set": [
+ ["dom.w3c_pointer_events.enabled", pointer_events_enabled]
+ ]
+ }, callback);
+ }
+ function startTest() {
+ var iframe = document.getElementById("testFrame");
+ iframe.src = "bug1017086_inner.html";
+ }
+ function part_of_checks(pointer_events, check, window, document, testelem) {
+ for(item in pointer_events) { check(false, pointer_events[item], window, "window"); }
+ for(item in pointer_events) { check(false, pointer_events[item], document, "document"); }
+ for(item in pointer_events) { check(false, pointer_events[item], testelem, "element"); }
+ SimpleTest.finish();
+ }
+ </script>
+ </head>
+ <body onload="prepareTest()">
+ <iframe id="testFrame" height="700" width="700"></iframe>
+ </body>
+</html>
diff --git a/dom/events/test/test_bug1017086_enable.html b/dom/events/test/test_bug1017086_enable.html
new file mode 100644
index 000000000..7930757a6
--- /dev/null
+++ b/dom/events/test/test_bug1017086_enable.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
+-->
+ <head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1017086</title>
+ <meta name="author" content="Maksim Lebedev" />
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+ /** Test for Bug 1017086 **/
+ var pointer_events_enabled = true;
+ function prepareTest() {
+ SimpleTest.waitForExplicitFinish();
+ turnOnOffPointerEvents(startTest);
+ }
+ function turnOnOffPointerEvents(callback) {
+ SpecialPowers.pushPrefEnv({
+ "set": [
+ ["dom.w3c_pointer_events.enabled", pointer_events_enabled]
+ ]
+ }, callback);
+ }
+ function startTest() {
+ var iframe = document.getElementById("testFrame");
+ iframe.src = "bug1017086_inner.html";
+ }
+ function part_of_checks(pointer_events, check, window, document, testelem) {
+ for(item in pointer_events) { check(true, pointer_events[item], window, "window"); }
+ /** TODO
+ for(item in pointer_events) { check(false, pointer_events[item], document, "document"); }
+ **/
+ for(item in pointer_events) { check(true, pointer_events[item], testelem, "element"); }
+ SimpleTest.finish();
+ }
+ </script>
+ </head>
+ <body onload="prepareTest()">
+ <iframe id="testFrame" height="700" width="700"></iframe>
+ </body>
+</html>
diff --git a/dom/events/test/test_bug1037990.html b/dom/events/test/test_bug1037990.html
new file mode 100644
index 000000000..025c8744b
--- /dev/null
+++ b/dom/events/test/test_bug1037990.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1037990
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1037990</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037990">Mozilla Bug 1037990</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+
+ /** Test for Bug 1037990 **/
+
+ var pre, node, detachedAccess, attachedAcess;
+
+ node = document.createElement('a');
+ node.href = 'http://example.org';
+ node.accessKey = 'e';
+ detachedAccess = node.accessKeyLabel;
+ info('[window.document] detached: ' + detachedAccess);
+ document.body.appendChild(node);
+ attachedAcess = node.accessKeyLabel;
+ info('[window.document] attached: ' + attachedAcess);
+ is(detachedAccess, attachedAcess, "Both values are same for the window.document");
+
+ var parser=new DOMParser();
+ var xmlDoc=parser.parseFromString("<root></root>","text/xml");
+ var nn = xmlDoc.createElementNS('http://www.w3.org/1999/xhtml','a');
+ nn.setAttribute('accesskey','t')
+ detachedAccess = nn.accessKeyLabel;
+ info('[xmlDoc] detached: ' + detachedAccess);
+ var root = xmlDoc.getElementsByTagName('root')[0];
+ root.appendChild(nn);
+ attachedAcess = nn.accessKeyLabel;
+ info('[xmlDoc] attached: ' + attachedAcess);
+ is(detachedAccess, attachedAcess, "Both values are same for the xmlDoc");
+
+ var myDoc = new Document();
+ var newnode = myDoc.createElementNS('http://www.w3.org/1999/xhtml','a');
+ newnode.href = 'http://example.org';
+ newnode.accessKey = 'f';
+ detachedAccess = newnode.accessKeyLabel;
+ info('[new document] detached: ' + detachedAccess);
+ myDoc.appendChild(newnode);
+ attachedAcess = newnode.accessKeyLabel;
+ info('[new document] attached: ' + attachedAcess);
+ is(detachedAccess, attachedAcess, "Both values are same for the new Document()");
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1079236.html b/dom/events/test/test_bug1079236.html
new file mode 100644
index 000000000..7957823e6
--- /dev/null
+++ b/dom/events/test/test_bug1079236.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1079236
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1079236</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1079236 **/
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+
+function runTests() {
+ var c = document.getElementById("content");
+ var sr = c.createShadowRoot();
+ sr.innerHTML = "<input type='file'" + ">";
+ var file = sr.firstChild;
+ is(file.type, "file");
+ file.offsetLeft; // Flush layout because dispatching mouse events.
+ document.body.onmousemove = function(e) {
+ is(e.target, c, "Event target should be the element in non-Shadow DOM");
+ if (e.originalTarget == file) {
+ is(e.originalTarget, file,
+ "type='file' implementation doesn't seem to have native anonymous content");
+ } else {
+ var wrapped = SpecialPowers.wrap(e.originalTarget);
+ isnot(wrapped, file, "Shouldn't have the same event.target and event.originalTarget");
+ }
+
+ ok(!("composedTarget" in e), "Events shouldn't have composedTarget in non-chrome context!");
+ e = SpecialPowers.wrap(e);
+ var composedTarget = SpecialPowers.unwrap(e.composedTarget);
+ ok(composedTarget, file, "composedTarget should be the file object.");
+
+ SimpleTest.finish();
+ }
+
+ var r = file.getBoundingClientRect();
+ synthesizeMouse(file, r.width / 6, r.height / 2, { type: "mousemove"} );
+ document.body.onmousemove = null;
+}
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1079236">Mozilla Bug 1079236</a>
+<p id="display"></p>
+<div id="content">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1096146.html b/dom/events/test/test_bug1096146.html
new file mode 100644
index 000000000..85b7a35f0
--- /dev/null
+++ b/dom/events/test/test_bug1096146.html
@@ -0,0 +1,187 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1096146
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1096146</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="runTests();">
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=1096146">Mozilla Bug 1096146</a>
+<div id="content" style="display: none;">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+const kKeydownEvent = 0x1;
+const kScrollEvent = 0x2;
+
+var gCurrentTest = 0;
+var gNumEvents = 0;
+var kTests = [
+ {
+ description: "no preventDefault at 'mozbrowserbeforekeydown'",
+ expectedEvents: kKeydownEvent | kScrollEvent,
+ resultEvents: 0x0,
+ doPreventDefault: false
+ },
+ {
+ description: "do preventDefault at 'mozbrowserbeforekeydown'",
+ expectedEvents: 0x0,
+ resultEvents: 0x0,
+ doPreventDefault: true
+ }
+]
+
+function frameScript()
+{
+ function handler(e) {
+ sendSyncMessage("forwardevent", { type: e.type });
+ }
+ addEventListener('keydown', handler);
+ addEventListener('scroll', handler);
+}
+
+
+function waitAndVerifyResult(count) {
+ if (gNumEvents >= 3 || count > 10) {
+ is(kTests[gCurrentTest].resultEvents,
+ kTests[gCurrentTest].expectedEvents,
+ "verify result");
+ runTests();
+ } else {
+ SimpleTest.requestFlakyTimeout("We must delay to wait for scroll/keydown events.");
+ setTimeout(() => waitAndVerifyResult(count + 1), 100);
+ }
+}
+
+function testDefaultAction()
+{
+ synthesizeKey('VK_END', {}, document.getElementById("embedded").contentWindow);
+ waitAndVerifyResult(0);
+}
+
+function prepareTest()
+{
+ gNumEvents = 0;
+
+ var handler;
+ if (kTests[gCurrentTest].doPreventDefault) {
+ handler = preventDefaultHandler;
+ } else {
+ handler = noPreventDefaultHandler;
+ }
+ window.addEventListener("mozbrowserbeforekeydown", handler);
+
+ var iframe = document.createElement("iframe");
+ iframe.id = "embedded";
+ iframe.src = "bug1096146_embedded.html";
+ iframe.setAttribute("remote", "false");
+ SpecialPowers.wrap(iframe).mozbrowser = true;
+
+ iframe.addEventListener("mozbrowserloadend", function onloadend() {
+ iframe.removeEventListener("mozbrowserloadend", onloadend);
+ iframe.focus();
+ var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
+ mm.addMessageListener("forwardevent", function(msg) {
+ var value = 0;
+ switch(msg.json.type) {
+ case "scroll":
+ ++gNumEvents;
+ value = kScrollEvent;
+ break;
+ case "keydown":
+ ++gNumEvents;
+ value = kKeydownEvent;
+ break;
+ default:
+ ok(false, "unexpected event");
+ }
+
+ kTests[gCurrentTest].resultEvents =
+ kTests[gCurrentTest].resultEvents | value;
+ });
+ mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false);
+ runTests();
+ return;
+ });
+
+ document.body.appendChild(iframe);
+}
+
+function preventDefaultHandler(evt)
+{
+ ok(true, "receive " + evt.type + " and do preventDefault.");
+ ++gNumEvents;
+ evt.preventDefault();
+}
+
+function noPreventDefaultHandler(evt)
+{
+ ok(true, "receive " + evt.type + ".");
+ ++gNumEvents;
+}
+
+function teardownHandler()
+{
+ var handler;
+ if (kTests[gCurrentTest].doPreventDefault) {
+ handler = preventDefaultHandler;
+ } else {
+ handler = noPreventDefaultHandler;
+ }
+ window.removeEventListener("mozbrowserbeforekeydown", handler);
+ document.body.removeChild(document.getElementById("embedded"));
+
+ runTests();
+}
+
+var tests = [
+ function addPermissions() {
+ SpecialPowers.pushPermissions(
+ [{ type: "before-after-keyboard-event", allow: true, context: document },
+ { type: "browser", allow: true, context: document }],
+ runTests);
+ },
+ function addPreferences() {
+ SpecialPowers.pushPrefEnv(
+ { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
+ ["dom.mozBrowserFramesEnabled", true],
+ ["dom.ipc.tabs.disabled", false],
+ ["network.disable.ipc.security", true]] },
+ runTests);
+ },
+
+ prepareTest,
+ testDefaultAction,
+ teardownHandler,
+
+ function() {
+ gCurrentTest++;
+ runTests();
+ },
+ prepareTest,
+ testDefaultAction,
+ teardownHandler
+];
+
+function runTests()
+{
+ if (!tests.length) {
+ SimpleTest.finish();
+ return;
+ }
+
+ var test = tests.shift();
+ test();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1128787-1.html b/dom/events/test/test_bug1128787-1.html
new file mode 100644
index 000000000..947bace38
--- /dev/null
+++ b/dom/events/test/test_bug1128787-1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1128787
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1128787</title>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1128787 **/
+ SimpleTest.waitForExplicitFinish();
+
+ window.onload = function (aEvent) {
+ var blurEventFired = false;
+ var input = document.getElementsByTagName("input")[0];
+ input.addEventListener("blur", function (aEvent) {
+ input.removeEventListener("blur", arguments.callee);
+ ok(true, "input element gets blur event correctly");
+
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+ is(utils.IMEStatus, utils.IME_STATUS_ENABLED, "IME should be enabled");
+
+ SimpleTest.executeSoon(function () {
+ document.designMode = "off";
+
+ // XXX Should be fixed.
+ todo_is(utils.IMEStatus, utils.IME_STATUS_DISABLED, "IME should be disabled");
+
+ SimpleTest.finish();
+ });
+ });
+ document.designMode = "on";
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1128787">Mozilla Bug 1128787</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<input type="button"/>
+<script>
+var input = document.getElementsByTagName("input")[0];
+input.focus();
+</script>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1128787-2.html b/dom/events/test/test_bug1128787-2.html
new file mode 100644
index 000000000..3e2a6cada
--- /dev/null
+++ b/dom/events/test/test_bug1128787-2.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1128787
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1128787</title>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1128787 **/
+ SimpleTest.waitForExplicitFinish();
+
+ window.onload = function (aEvent) {
+ var blurEventFired = false;
+ var input = document.getElementsByTagName("input")[0];
+ input.addEventListener("blur", function (aEvent) {
+ input.removeEventListener("blur", arguments.callee);
+ ok(true, "input element gets blur event correctly");
+
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+ is(utils.IMEStatus, utils.IME_STATUS_ENABLED, "IME should be enabled");
+
+ SimpleTest.executeSoon(function () {
+ document.designMode = "off";
+
+ // XXX Should be fixed.
+ todo_is(utils.IMEStatus, utils.IME_STATUS_DISABLED, "IME should be disabled");
+
+ SimpleTest.finish();
+ });
+ });
+ document.designMode = "on";
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1128787">Mozilla Bug 1128787</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<p contenteditable="true"></p>
+<input type="button"/>
+<script>
+var input = document.getElementsByTagName("input")[0];
+input.focus();
+</script>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1128787-3.html b/dom/events/test/test_bug1128787-3.html
new file mode 100644
index 000000000..a7b86cdb6
--- /dev/null
+++ b/dom/events/test/test_bug1128787-3.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1128787
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1128787</title>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1128787 **/
+ SimpleTest.waitForExplicitFinish();
+
+ window.onload = function (aEvent) {
+ var blurEventFired = false;
+ var input = document.getElementsByTagName("input")[0];
+ input.addEventListener("blur", function (aEvent) {
+ input.removeEventListener("blur", arguments.callee);
+ ok(true, "input element gets blur event correctly");
+
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+ is(utils.IMEStatus, utils.IME_STATUS_ENABLED, "IME should be enabled");
+
+ is(document.designMode, "on",
+ "designMode should be \"on\" when blur event caused by enabling designMode is fired");
+ document.designMode = "off";
+ is(document.designMode, "off",
+ "designMode should become \"off\" even if it's reset by the blur event handler caused by enabling designMode");
+
+ todo_is(utils.IMEStatus, utils.IME_STATUS_DISABLED, "IME should be disabled");
+ SimpleTest.finish();
+ });
+ document.designMode = "on";
+ }
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1128787">Mozilla Bug 1128787</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<input type="button"/>
+<script>
+var input = document.getElementsByTagName("input")[0];
+input.focus();
+</script>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1145910.html b/dom/events/test/test_bug1145910.html
new file mode 100644
index 000000000..b87104eb5
--- /dev/null
+++ b/dom/events/test/test_bug1145910.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1145910
+-->
+<head>
+ <title>Test for Bug 1145910</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<style>
+div:active {
+ color: rgb(0, 255, 0);
+}
+</style>
+<div id="host">Foo</div>
+<script type="application/javascript">
+
+/** Test for Bug 1145910 **/
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ var host = document.getElementById("host");
+ var shadow = host.createShadowRoot();
+ shadow.innerHTML = '<style>div:active { color: rgb(0, 255, 0); }</style><div id="inner">Bar</div>';
+ var inner = shadow.getElementById("inner");
+
+ is(window.getComputedStyle(host).color, "rgb(0, 0, 0)", "The host should not be active");
+ is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
+
+ synthesizeMouseAtCenter(host, { type: "mousedown" });
+
+ is(window.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
+ is(window.getComputedStyle(host).color, "rgb(0, 255, 0)", "Host should be active when the inner div is made active.");
+
+ synthesizeMouseAtCenter(host, { type: "mouseup" });
+
+ is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
+ is(window.getComputedStyle(host).color, "rgb(0, 0, 0)", "Host should no longer be active.");
+
+ SimpleTest.finish();
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1150308.html b/dom/events/test/test_bug1150308.html
new file mode 100644
index 000000000..c90e1055c
--- /dev/null
+++ b/dom/events/test/test_bug1150308.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1150308
+-->
+<head>
+ <title>Test for Bug 1150308</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<div id="host"><span id="distributeme">Foo</span></div>
+<script type="application/javascript">
+
+/** Test for Bug 1150308 **/
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ var host = document.getElementById("host");
+ var shadow = host.createShadowRoot();
+ shadow.innerHTML = '<style>.bar:active { color: rgb(0, 255, 0); }</style><div class="bar" id="inner"><content></content></div>';
+ var inner = shadow.getElementById("inner");
+ var distributed = document.getElementById("distributeme");
+
+ is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "The div inside the shadow root should not be active.");
+
+ synthesizeMouseAtCenter(distributed, { type: "mousedown" });
+
+ is(window.getComputedStyle(inner).color, "rgb(0, 255, 0)", "Div inside shadow root should be active.");
+
+ synthesizeMouseAtCenter(distributed, { type: "mouseup" });
+
+ is(window.getComputedStyle(inner).color, "rgb(0, 0, 0)", "Div inside shadow root should no longer be active.");
+
+ SimpleTest.finish();
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1248459.html b/dom/events/test/test_bug1248459.html
new file mode 100644
index 000000000..4eefa8e12
--- /dev/null
+++ b/dom/events/test/test_bug1248459.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1248459
+-->
+<head>
+ <title>Test for Bug 1248459</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<input id="input" value="foo">
+<div id="div">bar</div>
+<script type="application/javascript">
+
+/** Test for Bug 1248459 **/
+/**
+ * The bug occurs when a piece of text outside of the editor's root element is
+ * somehow selected when the editor is focused. In the bug's case, it's the
+ * placeholder anonymous div that's selected. In this test's case, it's a
+ * document div that's selected.
+ */
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ var div = document.getElementById("div");
+ var input = document.getElementById("input");
+
+ input.appendChild(div);
+ input.focus();
+
+ var editor = SpecialPowers.wrap(input).editor;
+ var sel = editor.selection;
+
+ sel.selectAllChildren(editor.rootElement);
+ var result = synthesizeQuerySelectedText();
+
+ ok(result.succeeded, "Query selected text should succeed");
+ is(result.offset, 0, "Selected text should be at offset 0");
+ is(result.text, "foo", "Selected text should match");
+
+ var range = document.createRange();
+ range.selectNode(div);
+
+ sel.removeAllRanges();
+ sel.addRange(range);
+
+ result = synthesizeQuerySelectedText();
+
+ ok(!result.succeeded, "Query out-of-bounds selection should fail");
+
+ SimpleTest.finish();
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1264380.html b/dom/events/test/test_bug1264380.html
new file mode 100644
index 000000000..76b9fb46b
--- /dev/null
+++ b/dom/events/test/test_bug1264380.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+ <title>Test the dragstart event on the anchor in side shadow DOM</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+SpecialPowers.pushPrefEnv({"set": [
+ ["dom.webcomponents.enabled", true]
+]});
+
+function runTests()
+{
+ let dragService = SpecialPowers.Cc["@mozilla.org/widget/dragservice;1"].
+ getService(SpecialPowers.Ci.nsIDragService);
+
+ let shadow = document.querySelector('#outter').createShadowRoot();
+ let target = document.createElement('a');
+ let linkText = document.createTextNode("Drag me if you can!");
+ target.appendChild(linkText);
+ target.href = "http://www.mozilla.org/";
+ shadow.appendChild(target);
+
+ let dataTransfer;
+ let trapDrag = function(event) {
+ ok(true, "Got dragstart event");
+ dataTransfer = event.dataTransfer;
+ ok(dataTransfer, "DataTransfer object is available.");
+ is(dataTransfer.mozItemCount, 1, "initial link item count");
+ is(dataTransfer.getData("text/uri-list"), "http://www.mozilla.org/", "link text/uri-list");
+ is(dataTransfer.getData("text/plain"), "http://www.mozilla.org/", "link text/plain");
+ }
+
+ ok(!dragService.getCurrentSession(), "There shouldn't be a drag session!");
+ window.addEventListener("dragstart", trapDrag, true);
+ synthesizeMouse(target, 2, 2, { type: "mousedown" });
+ synthesizeMouse(target, 11, 11, { type: "mousemove" });
+ synthesizeMouse(target, 20, 20, { type: "mousemove" });
+ window.removeEventListener("dragstart", trapDrag, true);
+ ok(dragService.getCurrentSession(), "Drag session is available.");
+ dragService.endDragSession(false);
+ ok(!dragService.getCurrentSession(), "There shouldn't be a drag session anymore!");
+ SimpleTest.finish();
+}
+
+</script>
+
+<body onload="window.setTimeout(runTests, 0);">
+<div id="outter"/>
+</body>
+</html>
diff --git a/dom/events/test/test_bug1298970.html b/dom/events/test/test_bug1298970.html
new file mode 100644
index 000000000..6b00aabff
--- /dev/null
+++ b/dom/events/test/test_bug1298970.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1298970
+-->
+<head>
+ <title>Test for Bug 1298970</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1298970">Mozilla Bug 1298970</a>
+<p id="display"></p>
+<div id="inner"></div>
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 1298970 **/
+var target = document.getElementById("inner");
+var event = new Event("test", { bubbles: true, cancelable: true });
+
+is(event.cancelBubble, false, "Event.cancelBubble should be false by default");
+
+target.addEventListener("test", (e) => {
+ e.stopPropagation();
+ is(e.cancelBubble, true, "Event.cancelBubble should be true after stopPropagation");
+}, true);
+
+target.dispatchEvent(event);
+
+</script>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug226361.xhtml b/dom/events/test/test_bug226361.xhtml
new file mode 100644
index 000000000..5095bb193
--- /dev/null
+++ b/dom/events/test/test_bug226361.xhtml
@@ -0,0 +1,82 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=226361
+-->
+<head>
+ <title>Test for Bug 226361</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body id="body1">
+<p id="display">
+
+ <a id="b1" tabindex="1" href="http://home.mozilla.org">start</a><br />
+<br />
+
+<iframe id="iframe" tabindex="2" src="bug226361_iframe.xhtml"></iframe>
+
+ <a id="b2" tabindex="3" href="http://home.mozilla.org">end</a>
+
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+<![CDATA[
+
+/** Test for Bug 226361 **/
+
+// accessibility.tabfocus must be set to value 7 before running test also
+// on a mac.
+function setTabFocus() {
+ SpecialPowers.pushPrefEnv({ set: [[ "accessibility.tabfocus", 7 ]] }, doTest);
+}
+
+// =================================
+
+var doc = document;
+function tab_to(id) {
+ var wu = SpecialPowers.DOMWindowUtils;
+ wu.sendKeyEvent('keypress', 9, 0, 0);
+ is(doc.activeElement.id, id, "element with id=" + id + " should have focus");
+}
+
+function tab_iframe() {
+ doc = document;
+ tab_to('iframe');
+
+ // inside iframe
+ doc = document.getElementById('iframe').contentDocument
+ tab_to('a3');tab_to('a5');tab_to('a1');tab_to('a2');tab_to('a4');
+}
+
+
+function doTest() {
+ window.getSelection().removeAllRanges();
+ document.getElementById('body1').focus();
+ is(document.activeElement.id, document.body.id, "body element should be focused");
+
+ doc = document;
+ tab_to('b1');
+
+ tab_iframe();
+
+ doc=document
+ document.getElementById('iframe').focus()
+ tab_to('b2');
+ // Change tabindex so the next TAB goes back to the IFRAME
+ document.getElementById('iframe').setAttribute('tabindex','4');
+
+ tab_iframe();
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(setTabFocus);
+
+]]>
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug238987.html b/dom/events/test/test_bug238987.html
new file mode 100644
index 000000000..814b0596b
--- /dev/null
+++ b/dom/events/test/test_bug238987.html
@@ -0,0 +1,282 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=238987
+-->
+<head>
+ <title>Test for Bug 238987</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=238987">Mozilla Bug 238987</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+ /** Test for Bug 238987 **/
+
+ var shouldStop = false;
+ var modifier = 0;
+ var expectedResult = "i1,i2,i3,i4,i5,i6,i7,i8,number,i9,i10,i11,i12";
+ var forwardFocusArray = expectedResult.split(",");
+ var backwardFocusArray = expectedResult.split(",");
+ var forwardBlurArray = expectedResult.split(",");
+ var backwardBlurArray = expectedResult.split(",");
+ // Adding 3 for "begin", "end", "begin" and one for the <a> in the Mochitest template,
+ var expectedWindowFocusCount = forwardFocusArray.length + backwardFocusArray.length + 4;
+ // but the last blur event goes to i1, not "begin".
+ var expectedWindowBlurCount = forwardFocusArray.length + backwardFocusArray.length + 3;
+
+ function handleFocus(e) {
+ if (e.target.id == "begin") {
+ // if the modifier is set, the test is coming back from the end.
+ if (modifier) {
+ shouldStop = true;
+ }
+ } else if (e.target.id == "end") {
+ modifier = Components.interfaces.nsIDOMEvent.SHIFT_MASK;
+ } else if (modifier) {
+ var expected = backwardFocusArray.pop();
+ ok(expected == e.target.id,
+ "(focus) Backward tabbing, expected [" +
+ expected + "], got [" + e.target.id + "]");
+ } else {
+ var expected = forwardFocusArray.shift();
+ is(e.target, document.activeElement, "Wrong activeElement!");
+ ok(expected == e.target.id,
+ "(focus) Forward tabbing, expected [" +
+ expected + "], got [" + e.target.id + "]");
+ }
+ }
+
+ function handleWindowFocus(e) {
+ --expectedWindowFocusCount;
+ var s = "target " + e.target;
+ if ("id" in e.target) {
+ s = s + ", id=\"" + e.target.id + "\"";
+ }
+ ok(e.eventPhase == Components.interfaces.nsIDOMEvent.CAPTURING_PHASE,
+ "|window| should not have got a focus event, " + s);
+ }
+
+ function handleBlur(e) {
+ if (e.target.id == "begin" || e.target.id == "end") {
+ return;
+ } else if (modifier) {
+ var expected = backwardBlurArray.pop();
+ ok(expected == e.target.id,
+ "(blur) backward tabbing, expected [" +
+ expected + "], got [" + e.target.id + "]");
+ } else {
+ var expected = forwardBlurArray.shift();
+ ok(expected == e.target.id,
+ "(blur) forward tabbing, expected [" +
+ expected + "], got [" + e.target.id + "]");
+ }
+ }
+
+ function handleWindowBlur(e) {
+ --expectedWindowBlurCount;
+ var s = "target " + e.target;
+ if ("id" in e.target) {
+ s = s + ", id=\"" + e.target.id + "\"";
+ }
+ ok(e.eventPhase == Components.interfaces.nsIDOMEvent.CAPTURING_PHASE,
+ "|window| should not have got a blur event, " + s);
+ }
+
+ function tab() {
+ var utils = SpecialPowers.DOMWindowUtils;
+ // Send tab key events.
+ var key = Components.interfaces.nsIDOMKeyEvent.DOM_VK_TAB;
+ utils.sendKeyEvent("keydown", key, 0, modifier);
+ utils.sendKeyEvent("keypress", key, 0, modifier);
+ utils.sendKeyEvent("keyup", key, 0, modifier);
+ if (shouldStop) {
+ // Did focus handling succeed
+ is(forwardFocusArray.length, 0,
+ "Not all forward tabbing focus tests were run, " +
+ forwardFocusArray.toString());
+ is(backwardFocusArray.length, 0,
+ "Not all backward tabbing focus tests were run, " +
+ backwardFocusArray.toString());
+ is(expectedWindowFocusCount, 0,
+ "|window| didn't get the right amount of focus events");
+
+ // and blur.
+ is(forwardBlurArray.length, 0,
+ "Not all forward tabbing blur tests were run, " +
+ forwardBlurArray.toString());
+ is(backwardBlurArray.length, 0,
+ "Not all backward tabbing blur tests were run, " +
+ backwardBlurArray.toString());
+ is(expectedWindowBlurCount, 0,
+ "|window| didn't get the right amount of blur events");
+
+ // Cleanup
+ window.removeEventListener("focus", handleWindowFocus, true);
+ window.removeEventListener("focus", handleWindowFocus, false);
+ window.removeEventListener("blur", handleWindowBlur, true);
+ window.removeEventListener("blur", handleWindowBlur, false);
+ var elements = document.getElementsByTagName("*");
+ for (var i = 0; i < elements.length; ++i) {
+ if (elements[i].hasAttribute("id")) {
+ elements[i].removeEventListener("focus", handleFocus, false);
+ elements[i].removeEventListener("blur", handleBlur, false);
+ }
+ }
+
+ SimpleTest.finish();
+ } else {
+ setTimeout(tab, 0);
+ }
+ }
+
+ function start() {
+ window.focus();
+ window.addEventListener("focus", handleWindowFocus, true);
+ window.addEventListener("focus", handleWindowFocus, false);
+ window.addEventListener("blur", handleWindowBlur, true);
+ window.addEventListener("blur", handleWindowBlur, false);
+ var elements = document.getElementsByTagName("*");
+ for (var i = 0; i < elements.length; ++i) {
+ if (elements[i].hasAttribute("id")) {
+ elements[i].addEventListener("focus", handleFocus, false);
+ elements[i].addEventListener("blur", handleBlur, false);
+ }
+ if (elements[i].getAttribute("tabindex") == "1") {
+ elements[i].setAttribute("tabindex", "-1");
+ }
+ }
+ tab();
+ }
+
+ // accessibility.tabfocus must be set to value 7 before running test also
+ // on a mac.
+ function doTest() {
+ SpecialPowers.pushPrefEnv({"set": [["accessibility.tabfocus", 7]]}, start);
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(doTest);
+
+</script>
+</pre>
+ <h4 tabindex="0" id="begin">Test:</h4>
+ <table>
+ <tbody>
+ <tr>
+ <td>type="text"</td><td><input type="text" id="i1" value=""></td>
+ </tr>
+ <tr>
+ <td>type="button"</td><td><input type="button" id="i2" value="type='button'"></td>
+ </tr>
+ <tr>
+ <td>type="checkbox"</td><td><input type="checkbox" id="i3" ></td>
+ </tr>
+ <tr>
+ <td>type="radio" checked</td><td><input type="radio" id="i4" name="radio" checked>
+ <input type="radio" id="i4b" name="radio"></td>
+ </tr>
+ <tr>
+ <td>type="radio"</td><td><input type="radio" id="i5" name="radio2">
+ <input type="radio" id="i6" name="radio2"></td>
+ </tr>
+ <tr>
+ <td>type="password"</td><td><input type="password" id="i7"></td>
+ </tr>
+ <tr>
+ <td>type="file"</td><td><input type="file" id="i8"></td>
+ </tr>
+ <tr>
+ <td>type="number"</td><td><input type="number" id="number"></td>
+ </tr>
+ <tr>
+ <td>button</td><td><button id="i9">button</button></td>
+ </tr>
+ <tr>
+ <td>select</td><td><select id="i10"><option>select</option></select></td>
+ </tr>
+ <tr>
+ <td>a</td><td><a href="#radio" id="i11">a link</a></td>
+ </tr>
+ <tr>
+ <td>tabindex="0"</td><td><span tabindex="0" id="i12">span</span></td>
+ </tr>
+
+ <tr>
+ <td><h3>Form elements with tabindex="-1"</h3></td>
+ </tr>
+ <tr>
+ <td>type="text"</td><td><input type="text" tabindex="-1" value=""></td>
+ </tr>
+ <tr>
+ <td>type="button"</td><td><input type="button" tabindex="-1" value="type='button'"></td>
+ </tr>
+ <tr>
+ <td>type="checkbox"</td><td><input type="checkbox" tabindex="-1"></td>
+ </tr>
+ <tr>
+ <td>type="radio" checked</td><td><input type="radio" tabindex="-1" name="radio3" checked>
+ <input type="radio" tabindex="-1" name="radio3"></td>
+ </tr>
+ <tr>
+ <td>type="radio"</td><td><input type="radio" tabindex="-1" name="radio4">
+ <input type="radio" tabindex="-1" name="radio4"></td>
+ </tr>
+ <tr>
+ <td>type="password"</td><td><input type="password" tabindex="-1"></td>
+ </tr>
+ <tr>
+ <td>type="file"</td><td><input type="file" tabindex="-1"></td>
+ </tr>
+ <tr>
+ <td>button</td><td><button tabindex="-1">button</button></td>
+ </tr>
+ <tr>
+ <td>select</td><td><select tabindex="-1"><option>select</option></select></td>
+ </tr>
+
+ <tr>
+ <td><h3>Form elements with .setAttribute("tabindex", "-1")</h3></td>
+ </tr>
+ <tr>
+ <td>type="text"</td><td><input type="text" tabindex="1" value=""></td>
+ </tr>
+ <tr>
+ <td>type="button"</td><td><input type="button" tabindex="1" value="type='button'"></td>
+ </tr>
+ <tr>
+ <td>type="checkbox"</td><td><input type="checkbox" tabindex="1"></td>
+ </tr>
+ <tr>
+ <td>type="radio" checked</td><td><input type="radio" tabindex="1" name="radio5" checked>
+ <input type="radio" tabindex="1" name="radio5"></td>
+ </tr>
+ <tr>
+ <td>type="radio"</td><td><input type="radio" tabindex="1" name="radio6">
+ <input type="radio" tabindex="1" name="radio6"></td>
+ </tr>
+ <tr>
+ <td>type="password"</td><td><input type="password" tabindex="1"></td>
+ </tr>
+ <tr>
+ <td>type="file"</td><td><input type="file" tabindex="1"></td>
+ </tr>
+ <tr>
+ <td>button</td><td><button tabindex="1">button</button></td>
+ </tr>
+ <tr>
+ <td>select</td><td><select tabindex="1"><option>select</option></select></td>
+ </tr>
+
+ </tbody>
+ </table>
+ <h4 tabindex="0" id="end">done.</h4>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug288392.html b/dom/events/test/test_bug288392.html
new file mode 100644
index 000000000..bec2cca4c
--- /dev/null
+++ b/dom/events/test/test_bug288392.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=288392
+-->
+<head>
+ <title>Test for Bug 288392</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=288392">Mozilla Bug 288392</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<div id="mutationTarget">
+</div>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 288392 **/
+var subtreeModifiedCount;
+
+function subtreeModified(e)
+{
+ ++subtreeModifiedCount;
+}
+
+function doTest() {
+ var targetNode = document.getElementById("mutationTarget");
+ targetNode.addEventListener("DOMSubtreeModified", subtreeModified, false);
+
+ subtreeModifiedCount = 0;
+ var temp = document.createElement("DIV");
+ targetNode.appendChild(temp);
+ is(subtreeModifiedCount, 1,
+ "Appending a child node should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ temp.setAttribute("foo", "bar");
+ is(subtreeModifiedCount, 1,
+ "Setting an attribute should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ targetNode.removeChild(temp);
+ is(subtreeModifiedCount, 1,
+ "Removing a child node should have dispatched a DOMSubtreeModified event");
+
+ // Testing events in a subtree, which is not in the document.
+ var subtree = document.createElement("div");
+ var s = "<e1 attr1='value1'>Something1</e1><e2 attr2='value2'>Something2</e2>";
+ subtree.innerHTML = s;
+ subtree.addEventListener("DOMSubtreeModified", subtreeModified, false);
+
+ subtreeModifiedCount = 0;
+ subtree.firstChild.firstChild.data = "foo";
+ is(subtreeModifiedCount, 1,
+ "Editing character data should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ subtree.firstChild.removeChild(subtree.firstChild.firstChild);
+ is(subtreeModifiedCount, 1,
+ "Removing a child node should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ subtree.firstChild.setAttribute("foo", "bar");
+ is(subtreeModifiedCount, 1,
+ "Setting an attribute should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ subtree.textContent = "foobar";
+ is(subtreeModifiedCount, 1,
+ "Setting .textContent should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ subtree.innerHTML = s;
+ is(subtreeModifiedCount, 1,
+ "Setting .innerHTML should have dispatched a DOMSubtreeModified event");
+
+ subtreeModifiedCount = 0;
+ subtree.removeEventListener("DOMSubtreeModified", subtreeModified, false);
+ subtree.appendChild(document.createTextNode(""));
+ subtree.addEventListener("DOMSubtreeModified", subtreeModified, false);
+ subtree.normalize();
+ is(subtreeModifiedCount, 1,
+ "Calling normalize() should have dispatched a DOMSubtreeModified event");
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+addLoadEvent(SimpleTest.finish);
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug299673-1.html b/dom/events/test/test_bug299673-1.html
new file mode 100644
index 000000000..f3c6fb276
--- /dev/null
+++ b/dom/events/test/test_bug299673-1.html
@@ -0,0 +1,61 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=299673
+-->
+<head>
+ <title>Test #1 for Bug 299673</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body id="Body">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=299673">Mozilla Bug 299673</a>
+<p id="display">
+
+ <SELECT id="Select1" onchange="log(event); OpenWindow()" onfocus="log(event); " onblur="log(event)">
+ <OPTION selected>option1</OPTION>
+ <OPTION>option2</OPTION>
+ <OPTION>option3</OPTION>
+ </SELECT>
+
+ <INPUT id="Text1" type="text" onfocus="log(event)" onblur="log(event)">
+ <INPUT id="Text2" type="text" onfocus="log(event)" onblur="log(event)">
+
+</p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+
+<script src="bug299673.js"></script>
+
+<script class="testbody" type="text/javascript">
+
+/** Test #1 for Bug 299673 **/
+function doTest(expectedEventLog) {
+ var eventLogForNewWindow = '\
+ : Test with browser.link.open_newwindow = 2\n\
+: focus top-doc\n\
+SELECT(Select1): focus \n\
+SELECT(Select1): change \n\
+ : >>> OpenWindow\n\
+: blur top-doc\n\
+: focus popup-doc\n\
+INPUT(popupText1): focus \n\
+ : <<< OpenWindow\n\
+SELECT(Select1): blur \n\
+INPUT(popupText1): blur \n\
+: blur popup-doc\n\
+: focus top-doc\n\
+'
+
+ setPrefAndDoTest(eventLogForNewWindow,'Body',2); // 2 = open new window as window
+}
+
+todo(false, "Please write a test for bug 299673 that actually works, see bug 553417");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug299673-2.html b/dom/events/test/test_bug299673-2.html
new file mode 100644
index 000000000..f393d6609
--- /dev/null
+++ b/dom/events/test/test_bug299673-2.html
@@ -0,0 +1,60 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=299673
+-->
+<head>
+ <title>Test #2 for Bug 299673</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body id="Body">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=299673">Mozilla Bug 299673</a>
+<p id="display">
+
+ <SELECT id="Select1" onchange="log(event); OpenWindow()" onfocus="log(event); " onblur="log(event)">
+ <OPTION selected>option1</OPTION>
+ <OPTION>option2</OPTION>
+ <OPTION>option3</OPTION>
+ </SELECT>
+
+ <INPUT id="Text1" type="text" onfocus="log(event)" onblur="log(event)">
+ <INPUT id="Text2" type="text" onfocus="log(event)" onblur="log(event)">
+
+</p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+
+<script src="bug299673.js"></script>
+
+<script class="testbody" type="text/javascript">
+
+/** Test #2 for Bug 299673 **/
+function doTest(expectedEventLog) {
+ var eventLogForNewTab = '\
+ : Test with browser.link.open_newwindow = 3\n\
+: focus top-doc\n\
+SELECT(Select1): focus \n\
+SELECT(Select1): change \n\
+ : >>> OpenWindow\n\
+: blur top-doc\n\
+: focus popup-doc\n\
+INPUT(popupText1): focus \n\
+ : <<< OpenWindow\n\
+SELECT(Select1): blur \n\
+INPUT(popupText1): blur \n\
+: blur popup-doc\n\
+: focus top-doc\n\
+'
+ setPrefAndDoTest(eventLogForNewTab,'Body',3); // 3 = open new window as tab
+}
+
+todo(false, "Please write a test for bug 299673 that actually works, see bug 553417");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug322588.html b/dom/events/test/test_bug322588.html
new file mode 100644
index 000000000..1c931c006
--- /dev/null
+++ b/dom/events/test/test_bug322588.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=322588
+-->
+<head>
+ <title>Test for Bug 322588 - onBlur window close no longer works</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=322588">Mozilla Bug 322588 - onBlur window close no longer works</a>
+<p id="display">
+<a id="link" href="javascript:pop350d('bug322588-popup.html#target')">Openwindow</a><br>
+The opened window should not directly close when clicking on the Openwindow link
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 322588 **/
+
+var result = "";
+
+var w;
+function pop350d(url) {
+ w = window.open();
+ w.addEventListener("unload", function () { result += " unload";}, false);
+ w.addEventListener("load", function () { result += " load"; setTimeout(done, 1000);}, false);
+ w.addEventListener("blur", function () { result += " blur";}, false);
+ w.location = url;
+}
+
+function doTest() {
+ try {
+ sendMouseEvent({type:'click'}, 'link');
+ } catch(e) {
+ if (w)
+ w.close();
+ throw e;
+ }
+}
+
+function done() {
+ is(result," unload load","unexpected events"); // The first unload is for about:blank
+ if (w)
+ w.close();
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+addLoadEvent(doTest);
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug328885.html b/dom/events/test/test_bug328885.html
new file mode 100644
index 000000000..5af2d5611
--- /dev/null
+++ b/dom/events/test/test_bug328885.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=328885
+-->
+<head>
+ <title>Test for Bug 328885</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=328885">Mozilla Bug 328885</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<input type="text" id="inputelement"
+ style="position: absolute; left: 0px; top: 0px;">
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 328885 **/
+
+ var inputelement = null;
+ var mutationCount = 0;
+
+ function mutationListener(evt) {
+ ++mutationCount;
+ }
+
+ function clickTest() {
+ inputelement.addEventListener("DOMSubtreeModified", mutationListener, false);
+ inputelement.addEventListener("DOMNodeInserted", mutationListener, false);
+ inputelement.addEventListener("DOMNodeRemoved", mutationListener, false);
+ inputelement.addEventListener("DOMNodeRemovedFromDocument", mutationListener, false);
+ inputelement.addEventListener("DOMNodeInsertedIntoDocument", mutationListener, false);
+ inputelement.addEventListener("DOMAttrModified", mutationListener, false);
+ inputelement.addEventListener("DOMCharacterDataModified", mutationListener, false);
+
+ inputelement.addEventListener('click',
+ function(event) {
+ var evt = SpecialPowers.wrap(event);
+ ok(SpecialPowers.unwrap(evt.originalTarget) instanceof HTMLDivElement,
+ "(1) Wrong originalTarget!");
+ is(SpecialPowers.unwrap(evt.originalTarget.parentNode), inputelement,
+ "(2) Wront parent node!");
+ ok(mutationCount == 0, "(3) No mutations should have happened! [" + mutationCount + "]");
+ evt.originalTarget.textContent = "foo";
+ ok(mutationCount == 0, "(4) Mutation listener shouldn't have been called! [" + mutationCount + "]");
+ evt.originalTarget.innerHTML = "foo2";
+ ok(mutationCount == 0, "(5) Mutation listener shouldn't have been called! [" + mutationCount + "]");
+ evt.originalTarget.lastChild.data = "bar";
+ ok(mutationCount == 0, "(6) Mutation listener shouldn't have been called! [" + mutationCount + "]");
+
+ var r = SpecialPowers.wrap(document.createRange());
+ r.selectNodeContents(evt.originalTarget);
+ r.deleteContents();
+ ok(mutationCount == 0, "(7) Mutation listener shouldn't have been called! [" + mutationCount + "]");
+
+ evt.originalTarget.textContent = "foo";
+ ok(mutationCount == 0, "(8) Mutation listener shouldn't have been called! [" + mutationCount + "]");
+ r = SpecialPowers.wrap(document.createRange());
+ r.selectNodeContents(evt.originalTarget);
+ r.extractContents();
+ ok(mutationCount == 0, "(9) Mutation listener shouldn't have been called! [" + mutationCount + "]");
+
+ evt.originalTarget.setAttribute("foo", "bar");
+ ok(mutationCount == 0, "(10) Mutation listener shouldn't have been called! ["+ mutationCount + "]");
+
+ // Same tests with non-native-anononymous element.
+ // mutationCount should be increased by 2 each time, since there is
+ // first a mutation specific event and then DOMSubtreeModified.
+ inputelement.textContent = "foo";
+ ok(mutationCount == 2, "(11) Mutation listener should have been called! [" + mutationCount + "]");
+ inputelement.lastChild.data = "bar";
+ ok(mutationCount == 4, "(12) Mutation listener should have been called! [" + mutationCount + "]");
+
+ r = document.createRange();
+ r.selectNodeContents(inputelement);
+ r.deleteContents();
+ ok(mutationCount == 6, "(13) Mutation listener should have been called! [" + mutationCount + "]");
+
+ inputelement.textContent = "foo";
+ ok(mutationCount == 8, "(14) Mutation listener should have been called! [" + mutationCount + "]");
+ r = document.createRange();
+ r.selectNodeContents(inputelement);
+ r.extractContents();
+ ok(mutationCount == 10, "(15) Mutation listener should have been called! [" + mutationCount + "]");
+
+ inputelement.setAttribute("foo", "bar");
+ ok(mutationCount == 12, "(16) Mutation listener should have been called! ["+ mutationCount + "]");
+
+ // Then try some mixed mutations. The mutation handler of non-native-a
+ inputelement.addEventListener("DOMAttrModified",
+ function (evt2) {
+ evt.originalTarget.setAttribute("foo", "bar" + mutationCount);
+ ok(evt.originalTarget.getAttribute("foo") == "bar" + mutationCount,
+ "(17) Couldn't update the attribute?!?");
+ }
+ , false);
+ inputelement.setAttribute("foo", "");
+ ok(mutationCount == 14, "(18) Mutation listener should have been called! ["+ mutationCount + "]");
+
+ inputelement.textContent = "foo";
+ ok(mutationCount == 16, "(19) Mutation listener should have been called! ["+ mutationCount + "]");
+ inputelement.addEventListener("DOMCharacterDataModified",
+ function (evt2) {
+ evt.originalTarget.textContent = "bar" + mutationCount;
+ }, false);
+ // This one deletes and inserts a new node, then DOMSubtreeModified.
+ inputelement.textContent = "bar";
+ ok(mutationCount == 19, "(20) Mutation listener should have been called! ["+ mutationCount + "]");
+ }
+ ,false);
+ synthesizeMouseAtCenter(inputelement, {}, window);
+ SimpleTest.finish();
+ }
+
+ function doTest() {
+ inputelement = document.getElementById('inputelement');
+ inputelement.focus();
+ setTimeout(clickTest, 100);
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.requestFlakyTimeout("untriaged");
+ addLoadEvent(doTest);
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug336682.js b/dom/events/test/test_bug336682.js
new file mode 100644
index 000000000..7f4ecfdf7
--- /dev/null
+++ b/dom/events/test/test_bug336682.js
@@ -0,0 +1,94 @@
+/*
+ * Helper functions for online/offline events tests.
+ *
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+var gState = 0;
+/**
+ * After all the on/offline handlers run,
+ * gState is expected to be equal to MAX_STATE.
+ */
+var MAX_STATE;
+
+function trace(text) {
+ var t = text.replace(/&/g, "&" + "amp;").replace(/</g, "&" + "lt;") + "<br>";
+ //document.getElementById("display").innerHTML += t;
+}
+
+// window.ononline and window.onclick shouldn't work
+// Right now, <body ononline=...> sets window.ononline (bug 380618)
+// When these start passing, be sure to uncomment the code inside if(0) below.
+todo(typeof window.ononline == "undefined",
+ "window.ononline should be undefined at this point");
+todo(typeof window.onoffline == "undefined",
+ "window.onoffline should be undefined at this point");
+
+if (0) {
+ window.ononline = function() {
+ ok(false, "window.ononline shouldn't be called");
+ }
+ window.onoffline = function() {
+ ok(false, "window.onclick shouldn't be called");
+ }
+}
+
+/**
+ * Returns a handler function for an online/offline event. The returned handler
+ * ensures the passed event object has expected properties and that the handler
+ * is called at the right moment (according to the gState variable).
+ * @param nameTemplate The string identifying the hanlder. '%1' in that
+ * string will be replaced with the event name.
+ * @param eventName 'online' or 'offline'
+ * @param expectedStates an array listing the possible values of gState at the
+ * moment the handler is called. The handler increases
+ * gState by one before checking if it's listed in
+ * expectedStates.
+ */
+function makeHandler(nameTemplate, eventName, expectedStates) {
+ return function(e) {
+ var name = nameTemplate.replace(/%1/, eventName);
+ ++gState;
+ trace(name + ": gState=" + gState);
+ ok(expectedStates.indexOf(gState) != -1,
+ "handlers called in the right order: " + name + " is called, " +
+ "gState=" + gState + ", expectedStates=" + expectedStates);
+ ok(e.constructor == Event, "event should be an Event");
+ ok(e.type == eventName, "event type should be " + eventName);
+ ok(e.bubbles, "event should bubble");
+ ok(!e.cancelable, "event should not be cancelable");
+ ok(e.target == (document instanceof HTMLDocument
+ ? document.body : document.documentElement),
+ "the event target should be the body element");
+ }
+}
+
+function doTest() {
+ var iosvc = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
+ .getService(SpecialPowers.Ci.nsIIOService2);
+ iosvc.manageOfflineStatus = false;
+ iosvc.offline = false;
+ ok(navigator.onLine, "navigator.onLine should be true, since we've just " +
+ "set nsIIOService.offline to false");
+
+ gState = 0;
+
+ trace("setting iosvc.offline = true");
+ iosvc.offline = true;
+ trace("done setting iosvc.offline = true");
+ ok(!navigator.onLine,
+ "navigator.onLine should be false when iosvc.offline == true");
+ ok(gState == window.MAX_STATE,
+ "offline event: all registered handlers should have been invoked, " +
+ "actual: " + gState);
+
+ gState = 0;
+ trace("setting iosvc.offline = false");
+ iosvc.offline = false;
+ trace("done setting iosvc.offline = false");
+ ok(navigator.onLine,
+ "navigator.onLine should be true when iosvc.offline == false");
+ ok(gState == window.MAX_STATE,
+ "online event: all registered handlers should have been invoked, " +
+ "actual: " + gState);
+}
diff --git a/dom/events/test/test_bug336682_1.html b/dom/events/test/test_bug336682_1.html
new file mode 100644
index 000000000..da80c1649
--- /dev/null
+++ b/dom/events/test/test_bug336682_1.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Bug 336682: online/offline events tests.
+
+Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/licenses/publicdomain/
+-->
+<head>
+ <title>Test for Bug 336682 (online/offline events)</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body ononline="trace('<body ononline=...>');
+ bodyOnonline(this, event)"
+ onoffline="trace('<body onoffline=...>'); bodyOnoffline(this, event)"
+ >
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=336682">Mozilla Bug 336682</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<script type="text/javascript" src="test_bug336682.js"></script>
+
+<script class="testbody" type="text/javascript">
+
+function makeBodyHandler(eventName) {
+ return function (aThis, aEvent) {
+ var handler = makeHandler("<body on%1='...'>", eventName, [3,4]);
+ handler(aEvent);
+ }
+}
+addLoadEvent(function() {
+ /** @see test_bug336682.js */
+ MAX_STATE = 4;
+
+ for (var event of ["online", "offline"]) {
+ document.body.addEventListener(
+ event,
+ makeHandler("document.body.addEventListener('%1', ..., false)",
+ event, [1]),
+ false);
+
+ document.addEventListener(
+ event,
+ makeHandler("document.addEventListener('%1', ..., false)",
+ event, [2]),
+ false);
+
+ window["bodyOn" + event] = makeBodyHandler(event);
+
+ window.addEventListener(
+ event,
+ makeHandler("window.addEventListener('%1', ..., false)",
+ event, [3,4]),
+ false);
+ }
+
+ doTest();
+ SimpleTest.finish();
+});
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug336682_2.xul b/dom/events/test/test_bug336682_2.xul
new file mode 100644
index 000000000..303348c2e
--- /dev/null
+++ b/dom/events/test/test_bug336682_2.xul
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+Bug 336682: online/offline events tests.
+
+Any copyright is dedicated to the Public Domain.
+http://creativecommons.org/licenses/publicdomain/
+-->
+<window title="Mozilla Bug 336682"
+ onoffline="trace('lt;body onoffline=...'); windowOnoffline(this, event)"
+ ononline="trace('lt;body ononline=...'); windowOnonline(this, event)"
+
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=336682">
+Mozilla Bug 336682 (online/offline events)</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+</body>
+
+<script type="text/javascript" src="test_bug336682.js"/>
+<script class="testbody" type="text/javascript">
+<![CDATA[
+addLoadEvent(function() {
+ /** @see test_bug336682.js */
+ MAX_STATE = 4;
+
+ function makeWindowHandler(eventName) {
+ return function (aThis, aEvent) {
+ var handler = makeHandler("<body on%1='...'>", eventName, [3,4]);
+ handler(aEvent);
+ }
+ }
+
+ for (var event of ["online", "offline"]) {
+ document.documentElement.addEventListener(
+ event,
+ makeHandler("document.body.addEventListener('%1', ..., false)",
+ event, [1]),
+ false);
+
+ document.addEventListener(
+ event,
+ makeHandler("document.addEventListener('%1', ..., false)",
+ event, [2]),
+ false);
+
+ window["windowOn" + event] = makeWindowHandler(event);
+
+ window.addEventListener(
+ event,
+ makeHandler("window.addEventListener('%1', ..., false)",
+ event, [3,4]),
+ false);
+ }
+
+ doTest();
+ SimpleTest.finish();
+});
+
+SimpleTest.waitForExplicitFinish();
+]]>
+</script>
+
+</window>
diff --git a/dom/events/test/test_bug367781.html b/dom/events/test/test_bug367781.html
new file mode 100644
index 000000000..06fa130c8
--- /dev/null
+++ b/dom/events/test/test_bug367781.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=367781
+-->
+<head>
+ <title>Test for Bug 367781</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=367781">Mozilla Bug 367781</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug **/
+var eventCounter = 0;
+
+function handler(e) {
+ if (e.type == "DOMNodeInserted") {
+ ++eventCounter;
+ }
+}
+
+function doTest() {
+ var i1 = document.getElementById('i1');
+ var i2 = document.getElementById('i2');
+ var pre = i1.contentDocument.getElementsByTagName("pre")[0];
+ pre.addEventListener("DOMNodeInserted", handler, false);
+ pre.textContent = pre.textContent + pre.textContent;
+ ok(eventCounter == 1, "DOMNodeInserted should have been dispatched");
+
+ pre.parentNode.removeChild(pre);
+ i2.contentDocument.adoptNode(pre);
+ i2.contentDocument.body.appendChild(pre);
+ ok(eventCounter == 2, "DOMNodeInserted should have been dispatched in the new document");
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+addLoadEvent(SimpleTest.finish);
+
+</script>
+</pre>
+<iframe id="i1" src="data:text/html,&lt;html&gt;&lt;body&gt;&lt;pre&gt;Foobar&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;"></iframe>
+<iframe id="i2" src="data:text/html,&lt;html&gt;&lt;body&gt;&lt;/body&gt;&lt;/html&gt;"></iframe>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug368835.html b/dom/events/test/test_bug368835.html
new file mode 100644
index 000000000..14581ee34
--- /dev/null
+++ b/dom/events/test/test_bug368835.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=368835
+-->
+ <head>
+ <title>Test for Bug 368835</title>
+
+ <link rel="stylesheet" type="text/css" href="http://mochi.test:8888/tests/SimpleTest/test.css" />
+
+ <script type="text/javascript" src="http://mochi.test:8888/tests/SimpleTest/SimpleTest.js"></script>
+ </head>
+
+ <body>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=368835">
+ Mozilla Bug 368835
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ <script class="testbody" type="text/javascript">
+ function dataContainerEventHandler(aEvent)
+ {
+ var value = "";
+ var isPassed = true;
+ try {
+ value = aEvent.getData("data1");
+ isPassed = true;
+ } catch (e) {
+ isPassed = false;
+ }
+
+ ok(isPassed, "getData shouldn't fail.");
+ ok(value == "data1", "Wrong value of data.");
+
+ is(aEvent.getData("document"), document);
+ is(aEvent.getData("window"), window);
+ is(aEvent.getData("event"), aEvent);
+ is(aEvent.getData("null"), null);
+ is(aEvent.getData("1"), 1);
+ is(aEvent.getData("1.1"), 1.1);
+ is(aEvent.getData("true"), true);
+
+ try {
+ aEvent.setData("data3", "data3");
+ isPassed = false;
+ } catch (e) {
+ isPassed = true;
+ }
+
+ ok(isPassed, "setData should fail during event dispatching.");
+ }
+
+ function doTest()
+ {
+ var isPassed;
+ var event = null;
+
+ try {
+ event = document.createEvent("datacontainerevents");
+ isPassed = true;
+ } catch (e) {
+ isPassed = false;
+ }
+
+ ok(isPassed, "Document should know about 'datacontainerevents' event class.");
+ ok(("setData" in event), "nsIDOMDataContainerEvent isn't available.");
+
+ event.initEvent("dataContainerEvent", true, true);
+
+ try {
+ event.setData("data1", "data1");
+ event.setData("document", document);
+ event.setData("window", window);
+ event.setData("event", event);
+ event.setData("null", null);
+ event.setData("1", 1);
+ event.setData("1.1", 1.1);
+ event.setData("true", true);
+ isPassed = true;
+ } catch (e) {
+ isPassed = false;
+ }
+
+ ok(isPassed, "setData shouldn't fail when event is initialized.");
+
+ document.body.addEventListener("dataContainerEvent",
+ dataContainerEventHandler, true);
+ document.body.dispatchEvent(event);
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(doTest);
+ </script>
+ </pre>
+ </body>
+</html>
+
diff --git a/dom/events/test/test_bug379120.html b/dom/events/test/test_bug379120.html
new file mode 100644
index 000000000..9a7925743
--- /dev/null
+++ b/dom/events/test/test_bug379120.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=379120
+-->
+<head>
+ <title>Test for Bug 379120</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=379120">Mozilla Bug 379120</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 379120 **/
+
+ var originalString = "<test></test>";
+
+ // Parse the content into an XMLDocument
+ var parser = new DOMParser();
+ var originalDoc = parser.parseFromString(originalString, "text/xml");
+
+ var stylesheetText =
+ "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' " +
+ "version='1.0' xmlns='http://www.w3.org/1999/xhtml'> " +
+
+ "<xsl:output method='xml' version='1.0' encoding='UTF-8' " +
+ "doctype-system='http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd' " +
+ "doctype-public='-//W3C//DTD XHTML 1.0 Transitional//EN' /> " +
+
+ "<xsl:template match='/'>" +
+ "<div onload='var i = 1'/>" +
+ "<xsl:apply-templates />" +
+ "</xsl:template>" +
+ "</xsl:stylesheet>";
+ var stylesheet = parser.parseFromString(stylesheetText, "text/xml");
+
+ var processor = new XSLTProcessor();
+
+ var targetDocument;
+ processor.importStylesheet (stylesheet);
+ var transformedDocument = processor.transformToDocument (originalDoc);
+ is(transformedDocument.documentElement.getAttribute("onload"),
+ "var i = 1");
+ ok(transformedDocument.documentElement.onload === null,
+ "Shouldn't have onload handler",
+ "got " + repr(transformedDocument.documentElement.onload) +
+ ", expected null");;
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug391568.xhtml b/dom/events/test/test_bug391568.xhtml
new file mode 100644
index 000000000..0a35072be
--- /dev/null
+++ b/dom/events/test/test_bug391568.xhtml
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xbl="http://www.mozilla.org/xbl">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=391568
+-->
+<head>
+ <title>Test for Bug 391568</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ <script>
+ var constructorFired = 0;
+ </script>
+ <xbl:bindings>
+ <xbl:binding id="test">
+ <xbl:content><span>
+ (anonumous content)
+ <span><xbl:children/></span>
+ (anonumous content)</span>
+ </xbl:content>
+
+ <xbl:implementation>
+ <xbl:constructor>
+ var win = XPCNativeWrapper.unwrap(window);
+ ++win.constructorFired;
+ document.getAnonymousNodes(this)[0].addEventListener(
+ "DOMCharacterDataModified",
+ function(evt) {
+ ++win.characterdatamodified;
+ },
+ true);
+ </xbl:constructor>
+ </xbl:implementation>
+ </xbl:binding>
+ </xbl:bindings>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=391568">Mozilla Bug 391568</a>
+<p id="display"></p>
+<div id="content">
+ <span style="-moz-binding: url(#test);"><span id="real1">(real content)</span></span>
+ <span style="-moz-binding: url(#test);"><span id="real2">(real content)</span></span>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+
+/** Test for Bug 391568 **/
+
+var characterdatamodified = 0;
+
+document.getElementById('real1').addEventListener(
+ "DOMCharacterDataModified",
+ function(evt) {},
+ true);
+
+function testListeners() {
+ if (constructorFired < 2) {
+ setTimeout(testListeners, 0);
+ return;
+ }
+ document.getElementById('real1').firstChild.data = "(real content 2)";
+ ok(characterdatamodified == 1,
+ "There is a DOMCharacterDataModified listener in anonymous content which didn't get called (1)!");
+ document.getElementById('real2').firstChild.data = "(real content 2)";
+ ok(characterdatamodified == 2,
+ "There is a DOMCharacterDataModified listener in anonymous content which didn't get called (2)!");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(testListeners);
+]]>
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug402089.html b/dom/events/test/test_bug402089.html
new file mode 100644
index 000000000..58ba423dd
--- /dev/null
+++ b/dom/events/test/test_bug402089.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=402089
+-->
+<head>
+ <title>Test for Bug 402089</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<!-- setTimeout so that the test starts after paint suppression ends -->
+<body onload="setTimeout(doTest,0);">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=402089">Mozilla Bug 402089</a>
+<p id="display"></p>
+<div id="content">
+ <pre id="result1"></pre>
+ <pre id="result2"></pre>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 402089 **/
+
+var cachedEvent = null;
+
+function testCachedEvent() {
+ testEvent('result2');
+ ok((document.getElementById('result1').textContent ==
+ document.getElementById('result2').textContent),
+ "Event coordinates should be the same after dispatching.");
+ SimpleTest.finish();
+}
+
+function testEvent(res) {
+ var s = cachedEvent.type + "\n";
+ s += "clientX: " + cachedEvent.clientX + ", clientY: " + cachedEvent.clientY + "\n";
+ s += "screenX: " + cachedEvent.screenX + ", screenY: " + cachedEvent.screenY + "\n";
+ s += "layerX: " + cachedEvent.layerX + ", layerY: " + cachedEvent.layerY + "\n";
+ s += "pageX: " + cachedEvent.pageX + ", pageY: " + cachedEvent.pageY + "\n";
+ document.getElementById(res).textContent += s;
+}
+
+function clickHandler(e) {
+ cachedEvent = e;
+ testEvent('result1');
+ e.stopPropagation();
+ e.preventDefault();
+ window.removeEventListener("click", clickHandler, true);
+ setTimeout(testCachedEvent, 10);
+}
+
+function doTest() {
+ window.addEventListener("click", clickHandler, true);
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+ utils.sendMouseEvent("mousedown", 1, 1, 0, 1, 0);
+ utils.sendMouseEvent("mouseup", 1, 1, 0, 1, 0);
+
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug405632.html b/dom/events/test/test_bug405632.html
new file mode 100644
index 000000000..96465225e
--- /dev/null
+++ b/dom/events/test/test_bug405632.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=405632
+-->
+<head>
+ <title>Test for Bug 405632</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=405632">Mozilla Bug 405632</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 405632 **/
+
+ var me = document.createEvent("mouseevent");
+ me.initMouseEvent("foo", false, false, window, 0, 100, 100, 100, 100,
+ false, false, false, false, 0, null);
+ ok(me.clientX == me.pageX,
+ "mouseEvent.clientX should be the same as mouseEvent.pageX when event is initialized manually");
+ ok(me.clientY == me.pageY,
+ "mouseEvent.clientY should be the same as mouseEvent.pageY when event is initialized manually");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug409604.html b/dom/events/test/test_bug409604.html
new file mode 100644
index 000000000..ec714ab64
--- /dev/null
+++ b/dom/events/test/test_bug409604.html
@@ -0,0 +1,382 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=409604
+-->
+<head>
+ <title>Test for Bug 409604</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body id="body">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409604">Mozilla Bug 409604</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+ /** Test for Bug 409604 **/
+
+ var modifier = SpecialPowers.Ci.nsIDOMEvent.ALT_MASK |
+ SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK;
+ var expectedFocus = "a,c,d,e,f,g,h,i,j,k,l,m,n,p,x,y";
+ // XXX the "map" test is causing trouble, see bug 433089
+ var focusArray = expectedFocus.split(",");
+ var unfocusableElementId = "invalid";
+ var unfocusableTags = [
+ {tag: "abbr", content: "text", attribs: {title: "something"}},
+ {tag: "acronym", content: "text", attribs: {title: "something"}},
+ {tag: "address", content: "text"},
+ {tag: "b", content: "text"},
+ {tag: "bdo", content: "text"},
+ {tag: "big", content: "text"},
+ {tag: "blockquote", content: "text"},
+ {tag: "caption", content: "text", parent: "table", where: "first"},
+ {tag: "cite", content: "text"},
+ {tag: "code", content: "text"},
+ {tag: "dd", content: "text", parent: "dl"},
+ {tag: "del", content: "text"},
+ {tag: "dfn", content: "text", attribs: {title: "something"}},
+ {tag: "div", content: "text"},
+ {tag: "dl", content: "<dd>text</dd>", parent: "dl"},
+ {tag: "dt", content: "text", parent: "dl"},
+ {tag: "em", content: "text"},
+ {tag: "fieldset", content: "text"},
+ {tag: "form", content: "text", attribs: {action: "any.html"}},
+ {tag: "h1", content: "text"},
+ {tag: "h2", content: "text"},
+ {tag: "h3", content: "text"},
+ {tag: "h4", content: "text"},
+ {tag: "h5", content: "text"},
+ {tag: "h6", content: "text"},
+ {tag: "hr"},
+ {tag: "i", content: "text"},
+ {tag: "img", attribs: {src: "any.png", alt: "image"}},
+ {tag: "ins", content: "text"},
+ {tag: "kbd", content: "text"},
+ {tag: "li", content: "text", parent: "ol"},
+ {tag: "li", content: "text", parent: "ul"},
+ {tag: "noscript", content: "text"},
+ {tag: "ol", content: "<li>text</li>"},
+ {tag: "optgroup", content: "<option>text</option>", attribs: {label: "some label"}, parent: "select"},
+ {tag: "option", content: "text", parent: "select"},
+ {tag: "p", content: "text"},
+ {tag: "pre", content: "text"},
+ {tag: "q", content: "text"},
+ {tag: "samp", content: "text"},
+ {tag: "small", content: "text"},
+ {tag: "span", content: "text"},
+ {tag: "strong", content: "text"},
+ {tag: "sub", content: "text"},
+ {tag: "sup", content: "text"},
+ {tag: "tt", content: "text"},
+ {tag: "ul", content: "<li>text</li>"},
+ {tag: "var", content: "text"}
+ ];
+ var invalidElements = [
+ "body",
+ "col",
+ "colgroup",
+// XXX the "map" test is causing trouble, see bug 433089
+// "map",
+ "table",
+ "tbody",
+ "td",
+ "tfoot",
+ "th",
+ "thead",
+ "tr"
+ ];
+
+ function handleFocus(e) {
+ ok("accessKey" in e, "(focus) accesskey property not found on element");
+ var expected = focusArray.shift();
+ // "k" and "n" are a special cases because the element receiving the focus
+ // is not the element which has the accesskey.
+ if (expected == "k" || expected == "n") {
+ ok(e.value == "test for label", "(focus) unexpected element: " + e.value +
+ " expected: " + "test for label");
+ // "l" is a special case because the element receiving the focus is not
+ // the element which has the accesskey.
+ } else if (expected == "l") {
+ ok(e.value == "test for legend", "(focus) unexpected element: " + e.value +
+ " expected: " + "test for legend");
+ } else {
+ ok(expected == e.accessKey, "(focus) unexpected element: " + e.accessKey +
+ " expected: " + expected);
+ }
+ }
+
+ function handleClick(e) {
+ ok("accessKey" in e, "(click) accesskey property not found on element");
+ }
+
+ function handleInvalid(e) {
+ ok("accessKey" in e, "(invalid) accesskey property not found on element");
+ ok(false, "(invalid) accesskey should not have any effect on this element: " +
+ e.localName);
+ }
+
+ function pressAccessKey(key) {
+ var utils = SpecialPowers.DOMWindowUtils;
+ utils.sendKeyEvent("keydown", key, key, modifier);
+ utils.sendKeyEvent("keypress", key, key, modifier);
+ utils.sendKeyEvent("keyup", key, key, modifier);
+ }
+
+ function testFocusableElements() {
+ for (var code = "a".charCodeAt(0); code <= "y".charCodeAt(0); ++ code) {
+ // XXX the "map" test is causing trouble, see bug 433089
+ if (code == "b".charCodeAt(0))
+ continue;
+ pressAccessKey(code);
+ }
+ ok(focusArray.length == 0, "(focus) unhandled elements remaining: " + focusArray.join(","));
+ }
+
+ function createUnfocusableElement(elem, accesskey) {
+ ok("tag" in elem, "invalid object passed to createUnfocusableElement: " + elem.toString());
+ var e = document.createElement(elem.tag);
+ if ("content" in elem) {
+ e.innerHTML = elem.content;
+ }
+ if ("attribs" in elem) {
+ for (var attr in elem.attribs) {
+ e.setAttribute(attr, elem.attribs[attr]);
+ }
+ }
+ e.setAttribute("accesskey", accesskey);
+ e.setAttribute("onclick", "handleClick(event.target); event.preventDefault();");
+ e.setAttribute("onfocus", "handleInvalid(event.target);");
+ var parent = null;
+ var elementToInsert = null;
+ if ("parent" in elem) {
+ parent = document.getElementById(elem.parent);
+ elementToInsert = e;
+ } else {
+ parent = document.getElementById("tbody");
+ elementToInsert = document.createElement("tr");
+ var td = document.createElement("td");
+ td.textContent = elem.tag;
+ elementToInsert.appendChild(td);
+ td = document.createElement("td");
+ td.appendChild(e);
+ elementToInsert.appendChild(td);
+ }
+ ok(parent != null, "parent element not specified for element: " + elem.tag);
+ ok(elementToInsert != null, "elementToInsert not specified for element: " + elem.tag);
+ elementToInsert.setAttribute("id", unfocusableElementId);
+ if ("where" in elem) {
+ if (elem.where == "first") {
+ parent.insertBefore(elementToInsert, parent.firstChild);
+ } else {
+ ok(false, "invalid where value specified for element: " + elem.tag);
+ }
+ } else {
+ parent.appendChild(elementToInsert);
+ }
+ }
+
+ function destroyUnfocusableElement() {
+ var el = document.getElementById(unfocusableElementId);
+ ok(el != null, "unfocusable element not found");
+ el.parentNode.removeChild(el);
+ ok(document.getElementById(unfocusableElementId) == null, "unfocusable element not properly removed");
+ }
+
+ function testUnfocusableElements() {
+ var i, e;
+ for (i = 0; i < unfocusableTags.length; ++ i) {
+ createUnfocusableElement(unfocusableTags[i], "z");
+ pressAccessKey("z".charCodeAt(0));
+ destroyUnfocusableElement();
+ }
+ for (i = 0; i < invalidElements.length; ++ i) {
+ e = document.getElementById(invalidElements[i]);
+ ok(e != null, "element with ID " + invalidElements[i] + " not found");
+ e.setAttribute("accesskey", "z");
+ e.setAttribute("onclick", "handleClick(event.target); event.preventDefault();");
+ e.setAttribute("onfocus", "handleInvalid(event.target);");
+ pressAccessKey("z".charCodeAt(0));
+ e.removeAttribute("accesskey");
+ e.removeAttribute("onclick");
+ e.removeAttribute("onfocus");
+ }
+ }
+
+ function start() {
+ testFocusableElements();
+ testUnfocusableElements();
+ SimpleTest.finish();
+ }
+
+ function doTest() {
+ SpecialPowers.pushPrefEnv({"set": [["ui.key.contentAccess", 5]]}, start);
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(doTest);
+
+</script>
+</pre>
+ <table id="table">
+ <thead id="thead">
+ <tr id="tr"><th id="th">Test header</th><th></th></tr>
+ </thead>
+ <tfoot id="tfoot">
+ <tr><td id="td">Test footer</td><td></td></tr>
+ </tfoot>
+ <tbody id="tbody">
+ <colgroup id="colgroup">
+ <col id="col"></col>
+ <col></col>
+ </colgroup>
+ <tr>
+ <td>a</td><td><a href="#" onclick="handleClick(event.target); return false;" accesskey="a" onfocus="handleFocus(event.target);">test link"</a></td>
+ </tr>
+<!-- the "map" test is causing trouble, see bug 433089
+ <tr>
+ <td>area</td><td><img src="about:logo" width="300" height="236" usemap="#map">
+ <map id="map" name="map"><area shape="rect" coords="0,0,82,126" href="#"
+ onclick="handleClick(event.target); return false;" accesskey="b"></map>
+ </td>
+ </tr>
+-->
+ <tr>
+ <td>button</td><td><button onclick="handleClick(event.target);" accesskey="c" onfocus="handleFocus(event.target);">test button"</button></td>
+ </tr>
+ <tr>
+ <td>input type="text"</td><td><input type="text" value="" onclick="handleClick(event.target);" onfocus="handleFocus(event.target);" accesskey="d"></td>
+ </tr>
+ <tr>
+ <td>input type="button"</td><td><input type="button" value="type='button'" onclick="handleClick(event.target);" onfocus="handleFocus(event.target);" accesskey="e"></td>
+ </tr>
+ <tr>
+ <td>input type="checkbox"</td><td><input type="checkbox" onclick="handleClick(event.target);" onfocus="handleFocus(event.target)" accesskey="f"></td>
+ </tr>
+ <tr>
+ <td>input type="radio"</td><td><input type="radio" name="radio" onclick="handleClick(event.target);" onfocus="handleFocus(event.target);" accesskey="g"></td>
+ </tr>
+ <tr>
+ <td>input type="password"</td><td><input type="password" onclick="handleClick(event.target);" onfocus="handleFocus(event.target);" accesskey="h"></td>
+ </tr>
+ <tr>
+ <td>input type="submit"</td><td><input type="submit" value="type='submit'" onclick="handleClick(event.target); return false;"
+ onfocus="handleFocus(event.target);" accesskey="i"></td>
+ </tr>
+ <tr>
+ <td>input type="reset"</td><td><input type="submit" value="type='reset'" onclick="handleClick(event.target);"
+ onfocus="handleFocus(event.target);" accesskey="j"></td>
+ </tr>
+ <tr>
+ <td>label</td><td><label accesskey="k" onclick="handleClick(event.target);" onfocus="handleInvalid(event.target);">test label
+ <input type="text" value="test for label" onfocus="handleFocus(event.target);" onclick="handleClick(event.target);"></label></td>
+ </tr>
+ <tr>
+ <td>legend</td><td><fieldset><legend accesskey="l">test legend</legend>
+ <input type="text" value="test for legend" onfocus="handleFocus(event.target);" onclick="handleClick(event.target);" ></fieldset></td>
+ </tr>
+ <tr>
+ <td>textarea</td><td><textarea onfocus="handleFocus(event.target);" onclick="handleClick(event.target);" accesskey="m">test text</textarea></td>
+ </tr>
+ <tr>
+ <td>label (label invisible)</td><td><label for="txt1" accesskey="n" style="display:none"
+ onclick="handleClick(event.target);" onfocus="handleInvalid(event.target);">test label</label>
+ <input type="text" id="txt1" value="test for label" onclick="handleClick(event.target);" onfocus="handleFocus(event.target);"></td>
+ </tr>
+ <tr>
+ <td>label (control invisible)</td><td><label for="txt2" accesskey="o"
+ onclick="handleClick(event.target);" onfocus="handleInvalid(event.target);">test label</label>
+ <input type="text" id="txt2" value="test for label" onclick="handleClick(event.target);"
+ onfocus="handleInvalid(event.target);" style="display:none"></td>
+ </tr>
+ <tr>
+ <td>select</td>
+ <td>
+ <select onclick="handleClick(event.target);" onfocus="handleFocus(event.target)" accesskey="p"><option>option</option></select>
+ </td>
+ </tr>
+ <tr>
+ <td>object</td>
+ <td>
+ <object onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="q">an object</object>
+ </td>
+ </tr>
+ <tr>
+ <td>a without href</td>
+ <td>
+ <a onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="r">an object</object>
+ </td>
+ </tr>
+ <tr>
+ <td>disabled button</td>
+ <td>
+ <button disabled="" onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="s">disabled</button>
+ </td>
+ </tr>
+ <tr>
+ <td>disabled input</td>
+ <td>
+ <input disabled="" onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="t"></input>
+ </td>
+ </tr>
+ <tr>
+ <td>hidden input</td>
+ <td>
+ <input type="hidden" onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="u">disabled</input>
+ </td>
+ </tr>
+ <tr>
+ <td>disabled select</td>
+ <td>
+ <select disabled onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="v">
+ <option>disabled</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>disabled textarea</td>
+ <td>
+ <textarea disabled onclick="handleClick(event.target);" onfocus="handleInvalid(event.target)" accesskey="w">disabled</textarea>
+ </td>
+ </tr>
+ <tr>
+ <td>scrollable div(focusable)</td>
+ <td>
+ <div onclick="handleClick(event.target);" onfocus="handleFocus(event.target)" accesskey="x" style="height: 50px; overflow: auto;">
+ The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy
+
+ dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the
+
+ lazy dog. The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy
+
+ dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the
+
+ lazy dog. The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy
+
+ dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the
+
+ lazy dog. The quick brown fox jumps over the lazy dog.
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td>contenteditable div(focusable)</td>
+ <td>
+ <div onclick="handleClick(event.target);" onfocus="handleFocus(event.target)" accesskey="y" contenteditable="true">
+ Test text.....
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <dl id="dl"></dl>
+ <ul id="ul"></ul>
+ <ol id="ol"></ol>
+ <select id="select"></select>
+</body>
+</html>
diff --git a/dom/events/test/test_bug412567.html b/dom/events/test/test_bug412567.html
new file mode 100644
index 000000000..08352366b
--- /dev/null
+++ b/dom/events/test/test_bug412567.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=412567
+-->
+<head>
+ <title>Test for Bug 412567</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body onload="testRedispatching(event);">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=412567">Mozilla Bug 412567</a>
+<p id="display"></p>
+<div id="content" style="display: none" onload="redispatchinHandler(event)">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 412567 **/
+
+var loadEvent = null;
+
+function redispatchinHandler(evt) {
+ is(evt.type, "load", "Wrong event type!");
+ ok(!evt.isTrusted, "Event should not be trusted!");
+ SimpleTest.finish();
+}
+
+function redispatch() {
+ ok(loadEvent.isTrusted, "Event should be trusted before redispatching!");
+ document.getElementById('content').dispatchEvent(loadEvent);
+}
+
+function testRedispatching(evt) {
+ is(evt.type, "load", "Wrong event type!");
+ ok(evt.isTrusted, "Event should be trusted!");
+ loadEvent = evt;
+ setTimeout(redispatch, 0);
+}
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug415498.xul b/dom/events/test/test_bug415498.xul
new file mode 100644
index 000000000..009431cb1
--- /dev/null
+++ b/dom/events/test/test_bug415498.xul
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=415498
+-->
+<window title="Mozilla Bug 415498"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ onload="init()">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/chrome-harness.js"></script>
+<body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=415498">Mozilla Bug 415498</a>
+
+ <p id="display"></p>
+
+ <pre id="test">
+ <script class="testbody" type="application/javascript"><![CDATA[
+
+ /** Test for Bug 415498 **/
+ if (Cc === undefined) {
+ var Cc = Components.classes;
+ var Ci = Components.interfaces;
+ }
+ var Cr = Components.results;
+
+ SimpleTest.waitForExplicitFinish();
+
+ var gTestsIterator;
+ var gConsole;
+ var gConsoleListener;
+ var gMessages = [];
+
+ function init() {
+ gTestsIterator = testsIterator();
+
+ gConsole = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+
+ gConsoleListener = {
+ observe: function(aObject) {
+ gMessages.push(aObject);
+ }
+ };
+ gConsole.registerListener(gConsoleListener);
+
+ nextTest();
+ }
+
+ function nextTest() {
+ try {
+ gTestsIterator.next();
+ } catch (err) {
+ ok(err instanceof StopIteration,
+ "Some other exception was thrown than what we expected!");
+
+ if (gConsole && gConsoleListener) {
+ gConsole.unregisterListener(gConsoleListener);
+ }
+ SimpleTest.finish();
+ }
+ }
+
+ function testsIterator() {
+
+ var browser = $("browser");
+ browser.addEventListener("load", function() {
+ setTimeout(nextTest, 0)
+ }, false);
+
+ // 1) This document uses addEventListener to register a method throwing an exception
+ var chromeDir = getRootDirectory(window.location.href);
+ browser.loadURI(chromeDir + "bug415498-doc1.html");
+ yield undefined;
+
+ ok(verifyErrorReceived("HierarchyRequestError"),
+ "Error message not reported in event listener callback!");
+ gMessages = [];
+
+ // 2) This document sets window.onload to register a method throwing an exception
+ var chromeDir = getRootDirectory(window.location.href);
+ browser.loadURI(chromeDir + "bug415498-doc2.html");
+ yield undefined;
+
+ ok(verifyErrorReceived("HierarchyRequestError"),
+ "Error message not reported in window.onload!");
+ }
+
+ function verifyErrorReceived(errorString) {
+ for (var i = 0; i < gMessages.length; i++) {
+ if (gMessages[i].message.indexOf(errorString) != -1)
+ return true;
+ }
+ return false;
+ }
+ ]]></script>
+ </pre>
+</body>
+
+<browser id="browser" type="content" flex="1" src="about:blank"/>
+
+</window>
diff --git a/dom/events/test/test_bug418986-3.html b/dom/events/test/test_bug418986-3.html
new file mode 100644
index 000000000..a92b1e0f5
--- /dev/null
+++ b/dom/events/test/test_bug418986-3.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=418986
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test 3/3 for Bug 418986 - Resist fingerprinting by preventing exposure of screen and system info</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body id="body">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418986">Bug 418986</a>
+<p id="display"></p>
+<pre id="test"></pre>
+<script type="application/javascript;version=1.7" src="bug418986-3.js"></script>
+<script type="application/javascript;version=1.7">
+ // This test produces fake mouse events and checks that the screenX and screenY
+ // properties of the received event objects provide client window coordinates.
+ // Run the test once the window has loaded.
+ window.onload = () => test(true);
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug418986-3.xul b/dom/events/test/test_bug418986-3.xul
new file mode 100644
index 000000000..574cda0ce
--- /dev/null
+++ b/dom/events/test/test_bug418986-3.xul
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+Bug 418986
+-->
+<window title="Mozilla Bug 418986"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+<body id="body" xmlns="http://www.w3.org/1999/xhtml">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418986">
+Mozilla Bug 418986</a>
+</body>
+
+<script type="application/javascript;version=1.7" src="bug418986-3.js"></script>
+<script type="application/javascript;version=1.7"><![CDATA[
+ // This test produces fake mouse events and checks that the screenX and screenY
+ // properties of the received event objects provide client window coordinates.
+ // Run the test once the window has loaded.
+ test(false);
+]]></script>
+
+</window>
diff --git a/dom/events/test/test_bug422132.html b/dom/events/test/test_bug422132.html
new file mode 100644
index 000000000..bceeb79e8
--- /dev/null
+++ b/dom/events/test/test_bug422132.html
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=422132
+-->
+<head>
+ <title>Test for Bug 422132</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422132">Mozilla Bug 422132</a>
+<p id="display"></p>
+<div id="target" style="font-size: 0; width: 200px; height: 200px; overflow: auto;">
+ <div style="width: 1000px; height: 1000px;"></div>
+</div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 422132 **/
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ SpecialPowers.pushPrefEnv({
+ "set":[["general.smoothScroll", false],
+ ["mousewheel.min_line_scroll_amount", 1],
+ ["mousewheel.system_scroll_override_on_root_content.enabled", false],
+ ["mousewheel.transaction.timeout", 100000]]}, runTests)}, window);
+
+function runTests()
+{
+ var target = document.getElementById("target");
+
+ var scrollLeft = target.scrollLeft;
+ var scrollTop = target.scrollTop;
+
+ var tests = [
+ {
+ prepare: function() {
+ scrollLeft = target.scrollLeft;
+ scrollTop = target.scrollTop;
+ },
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.5,
+ deltaY: 0.5,
+ lineOrPageDeltaX: 0,
+ lineOrPageDeltaY: 0
+ },
+ }, {
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.5,
+ deltaY: 0.5,
+ lineOrPageDeltaX: 0,
+ lineOrPageDeltaY: 0
+ },
+ check: function() {
+ is(target.scrollLeft - scrollLeft, 1,
+ "not scrolled to right by 0.5px delta value with pending 0.5px delta");
+ is(target.scrollTop - scrollTop, 1,
+ "not scrolled to bottom by 0.5px delta value with pending 0.5px delta");
+ },
+ }, {
+ prepare: function() {
+ scrollLeft = target.scrollLeft;
+ scrollTop = target.scrollTop;
+ },
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5,
+ deltaY: 0.5,
+ lineOrPageDeltaX: 0,
+ lineOrPageDeltaY: 0
+ },
+ }, {
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5,
+ deltaY: 0.5,
+ lineOrPageDeltaX: 1,
+ lineOrPageDeltaY: 1
+ },
+ check: function() {
+ is(target.scrollLeft - scrollLeft, 1,
+ "not scrolled to right by 0.5 line delta value with pending 0.5 line delta");
+ is(target.scrollTop - scrollTop, 1,
+ "not scrolled to bottom by 0.5 line delta value with pending 0.5 line delta");
+ }
+ }
+ ];
+
+ var nextTest = function() {
+ var test = tests.shift();
+ if (test.prepare) {
+ test.prepare();
+ }
+
+ sendWheelAndPaint(target, 10, 10, test.event, function() {
+ if (test.check) {
+ test.check();
+ }
+ if (tests.length == 0) {
+ SimpleTest.finish();
+ return;
+ }
+
+ setTimeout(nextTest, 0);
+ });
+ }
+
+ nextTest();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug426082.html b/dom/events/test/test_bug426082.html
new file mode 100644
index 000000000..d07559413
--- /dev/null
+++ b/dom/events/test/test_bug426082.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=426082
+-->
+<head>
+ <title>Test for Bug 426082</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+/** Test for Bug 426082 **/
+SimpleTest.waitForExplicitFinish();
+var subwindow = window.open("./bug426082.html", "bug426082", "width=800,height=1000");
+
+function finishTests() {
+ subwindow.close();
+ SimpleTest.finish();
+}
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug427537.html b/dom/events/test/test_bug427537.html
new file mode 100644
index 000000000..060581f2f
--- /dev/null
+++ b/dom/events/test/test_bug427537.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=427537
+-->
+<head>
+ <title>Test for Bug 427537</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=427537">Mozilla Bug 427537</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 427537 **/
+
+var e = document.createEvent("CustomEvent");
+ok(e, "Should have custom event!");
+
+// Test initCustomEvent and also cycle collection handling by
+// passing reference to the event as 'detail' parameter.
+e.initCustomEvent("foobar", true, true, e);
+
+var didCallListener = false;
+document.addEventListener("foobar",
+ function(evt) {
+ didCallListener = true;
+ is(evt.type, "foobar", "Should get 'foobar' event!");
+ is(evt.detail, evt, ".detail should point to the event itself.");
+ ok(e.bubbles, "Event should bubble!");
+ ok(e.cancelable, "Event should be cancelable.");
+ }, true);
+
+document.dispatchEvent(e);
+ok(didCallListener, "Should have called listener!");
+
+e = document.createEvent("CustomEvent");
+e.initEvent("foo", true, true);
+is(e.detail, null, "Default detail should be null.");
+
+e = document.createEvent("CustomEvent");
+e.initCustomEvent("foobar", true, true, 1);
+is(e.detail, 1, "Detail should be 1.");
+
+e = document.createEvent("CustomEvent");
+e.initCustomEvent("foobar", true, true, "test");
+is(e.detail, "test", "Detail should be 'test'.");
+
+e = document.createEvent("CustomEvent");
+e.initCustomEvent("foobar", true, true, true);
+is(e.detail, true, "Detail should be true.");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug428988.html b/dom/events/test/test_bug428988.html
new file mode 100644
index 000000000..97a0069fd
--- /dev/null
+++ b/dom/events/test/test_bug428988.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=428988
+-->
+<head>
+ <title>Test for Bug 428988</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428988">Mozilla Bug 428988</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 428988 **/
+
+function listenerForClick(evt) {
+ is(Math.round(evt.mozPressure*100), 56, "Wrong .mozPressure");
+}
+
+function doTest() {
+ var target = document.getElementById("testTarget");
+ target.addEventListener("click", listenerForClick, true);
+ var me = document.createEvent("MouseEvent");
+ me.initNSMouseEvent("click", true, true, window, 0, 0, 0, 0, 0,
+ false, false, false, false, 0, null, 0.56, 0);
+ target.dispatchEvent(me);
+ target.removeEventListener("click", listenerForClick, true);
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+<span id="testTarget" style="border: 1px solid black;">testTarget</span>
+</body>
+</html>
diff --git a/dom/events/test/test_bug432698.html b/dom/events/test/test_bug432698.html
new file mode 100644
index 000000000..335890b0a
--- /dev/null
+++ b/dom/events/test/test_bug432698.html
@@ -0,0 +1,223 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=432698
+-->
+<head>
+ <title>Test for Bug 432698</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=432698">Mozilla Bug 432698</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 432698 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+var outer;
+var middle;
+var inner;
+var outside;
+var container;
+var file;
+var iframe;
+var checkRelatedTarget = false;
+var expectedRelatedEnter = null;
+var expectedRelatedLeave = null;
+var mouseentercount = 0;
+var mouseleavecount = 0;
+var mouseovercount = 0;
+var mouseoutcount = 0;
+
+function sendMouseEvent(t, elem) {
+ var r = elem.getBoundingClientRect();
+ synthesizeMouse(elem, r.width / 2, r.height / 2, {type: t});
+}
+
+var expectedMouseEnterTargets = [];
+var expectedMouseLeaveTargets = [];
+
+function runTests() {
+ outer = document.getElementById("outertest");
+ middle = document.getElementById("middletest");
+ inner = document.getElementById("innertest");
+ outside = document.getElementById("outside");
+ container = document.getElementById("container");
+ file = document.getElementById("file");
+ iframe = document.getElementById("iframe");
+
+ // Make sure ESM thinks mouse is outside the test elements.
+ sendMouseEvent("mousemove", outside);
+
+ mouseentercount = 0;
+ mouseleavecount = 0;
+ mouseovercount = 0;
+ mouseoutcount = 0;
+ checkRelatedTarget = true;
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = inner;
+ expectedMouseEnterTargets = ["outertest", "middletest", "innertest"];
+ sendMouseEvent("mousemove", inner);
+ is(mouseentercount, 3, "Unexpected mouseenter event count!");
+ is(mouseovercount, 1, "Unexpected mouseover event count!");
+ is(mouseoutcount, 0, "Unexpected mouseout event count!");
+ is(mouseleavecount, 0, "Unexpected mouseleave event count!");
+ expectedRelatedEnter = inner;
+ expectedRelatedLeave = outside;
+ expectedMouseLeaveTargets = ["innertest", "middletest", "outertest"];
+ sendMouseEvent("mousemove", outside);
+ is(mouseentercount, 3, "Unexpected mouseenter event count!");
+ is(mouseovercount, 1, "Unexpected mouseover event count!");
+ is(mouseoutcount, 1, "Unexpected mouseout event count!");
+ is(mouseleavecount, 3, "Unexpected mouseleave event count!");
+
+ // Event handling over native anonymous content.
+ var r = file.getBoundingClientRect();
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = file;
+ synthesizeMouse(file, r.width / 6, r.height / 2, {type: "mousemove"});
+ is(mouseentercount, 4, "Unexpected mouseenter event count!");
+ is(mouseovercount, 2, "Unexpected mouseover event count!");
+ is(mouseoutcount, 1, "Unexpected mouseout event count!");
+ is(mouseleavecount, 3, "Unexpected mouseleave event count!");
+
+ // Moving mouse over type="file" shouldn't cause mouseover/out/enter/leave events
+ synthesizeMouse(file, r.width - (r.width / 6), r.height / 2, {type: "mousemove"});
+ is(mouseentercount, 4, "Unexpected mouseenter event count!");
+ is(mouseovercount, 2, "Unexpected mouseover event count!");
+ is(mouseoutcount, 1, "Unexpected mouseout event count!");
+ is(mouseleavecount, 3, "Unexpected mouseleave event count!");
+
+ expectedRelatedEnter = file;
+ expectedRelatedLeave = outside;
+ sendMouseEvent("mousemove", outside);
+ is(mouseentercount, 4, "Unexpected mouseenter event count!");
+ is(mouseovercount, 2, "Unexpected mouseover event count!");
+ is(mouseoutcount, 2, "Unexpected mouseout event count!");
+ is(mouseleavecount, 4, "Unexpected mouseleave event count!");
+
+ // Initialize iframe
+ iframe.contentDocument.documentElement.style.overflow = "hidden";
+ iframe.contentDocument.body.style.margin = "0px";
+ iframe.contentDocument.body.style.width = "100%";
+ iframe.contentDocument.body.style.height = "100%";
+ iframe.contentDocument.body.innerHTML =
+ "<div style='width: 100%; height: 50%; border: 1px solid black;'></div>" +
+ "<div style='width: 100%; height: 50%; border: 1px solid black;'></div>";
+ iframe.contentDocument.body.offsetLeft; // flush
+
+ iframe.contentDocument.body.firstChild.onmouseenter = menter;
+ iframe.contentDocument.body.firstChild.onmouseleave = mleave;
+ iframe.contentDocument.body.lastChild.onmouseenter = menter;
+ iframe.contentDocument.body.lastChild.onmouseleave = mleave;
+ r = iframe.getBoundingClientRect();
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = iframe;
+ // Move mouse inside the iframe.
+ synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "mousemove"},
+ iframe.contentWindow);
+ synthesizeMouse(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "mousemove"},
+ iframe.contentWindow);
+ is(mouseentercount, 7, "Unexpected mouseenter event count!");
+ expectedRelatedEnter = iframe;
+ expectedRelatedLeave = outside;
+ sendMouseEvent("mousemove", outside);
+ is(mouseleavecount, 7, "Unexpected mouseleave event count!");
+
+ checkRelatedTarget = false;
+
+ iframe.contentDocument.body.firstChild.onmouseenter = null;
+ iframe.contentDocument.body.firstChild.onmouseleave = null;
+ iframe.contentDocument.body.lastChild.onmouseenter = null;
+ iframe.contentDocument.body.lastChild.onmouseleave = null;
+
+ container.onmouseenter = null;
+ container.onmouseleave = null;
+ container.onmouseout = null;
+ container.onmouseover = null;
+
+ var children = container.getElementsByTagName('*');
+ for (var i=0;i<children.length;i++) {
+ children[i].onmouseenter = null;
+ children[i].onmouseleave = null;
+ children[i].onmouseout = null;
+ children[i].onmouseover = null;
+ }
+
+ SimpleTest.finish();
+}
+
+function menter(evt) {
+ ++mouseentercount;
+ evt.stopPropagation();
+ if (expectedMouseEnterTargets.length) {
+ var t = expectedMouseEnterTargets.shift();
+ is(evt.target.id, t, "Wrong event target!");
+ }
+ is(evt.bubbles, false, evt.type + " should not bubble!");
+ is(evt.cancelable, false, evt.type + " is not cancelable!");
+ is(evt.target, evt.currentTarget, "Wrong event target!");
+ ok(!evt.relatedTarget || evt.target.ownerDocument == evt.relatedTarget.ownerDocument,
+ "Leaking nodes to another document?");
+ if (checkRelatedTarget && evt.target.ownerDocument == document) {
+ is(evt.relatedTarget, expectedRelatedEnter, "Wrong related target (mouseenter)");
+ }
+}
+
+function mleave(evt) {
+ ++mouseleavecount;
+ evt.stopPropagation();
+ if (expectedMouseLeaveTargets.length) {
+ var t = expectedMouseLeaveTargets.shift();
+ is(evt.target.id, t, "Wrong event target!");
+ }
+ is(evt.bubbles, false, evt.type + " should not bubble!");
+ is(evt.cancelable, false, evt.type + " is not cancelable!");
+ is(evt.target, evt.currentTarget, "Wrong event target!");
+ ok(!evt.relatedTarget || evt.target.ownerDocument == evt.relatedTarget.ownerDocument,
+ "Leaking nodes to another document?");
+ if (checkRelatedTarget && evt.target.ownerDocument == document) {
+ is(evt.relatedTarget, expectedRelatedLeave, "Wrong related target (mouseleave)");
+ }
+}
+
+function mover(evt) {
+ ++mouseovercount;
+ evt.stopPropagation();
+}
+
+function mout(evt) {
+ ++mouseoutcount;
+ evt.stopPropagation();
+}
+
+</script>
+</pre>
+<div id="container" onmouseenter="menter(event)" onmouseleave="mleave(event)"
+ onmouseout="mout(event)" onmouseover="mover(event)">
+ <div id="outside" onmouseout="event.stopPropagation()" onmouseover="event.stopPropagation()">foo</div>
+ <div id="outertest" onmouseenter="menter(event)" onmouseleave="mleave(event)"
+ onmouseout="mout(event)" onmouseover="mover(event)">
+ <div id="middletest" onmouseenter="menter(event)" onmouseleave="mleave(event)"
+ onmouseout="mout(event)" onmouseover="mover(event)">
+ <div id="innertest" onmouseenter="menter(event)" onmouseleave="mleave(event)"
+ onmouseout="mout(event)" onmouseover="mover(event)">foo</div>
+ </div>
+ </div>
+ <input type="file" id="file"
+ onmouseenter="menter(event)" onmouseleave="mleave(event)"
+ onmouseout="mout(event)" onmouseover="mover(event)">
+ <br>
+ <iframe id="iframe" width="50px" height="50px"
+ onmouseenter="menter(event)" onmouseleave="mleave(event)"
+ onmouseout="mout(event)" onmouseover="mover(event)"></iframe>
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug443985.html b/dom/events/test/test_bug443985.html
new file mode 100644
index 000000000..0ed4138be
--- /dev/null
+++ b/dom/events/test/test_bug443985.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=443985
+-->
+<head>
+ <title>Test for Bug 443985</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=443985">Mozilla Bug 443985</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 443985 **/
+
+
+function listenerForNoScroll(evt) {
+ is(evt.clientX, evt.pageX, "Wrong .pageX");
+ is(evt.clientY, evt.pageY, "Wrong .pageY");
+ is(evt.screenX, 0, "Wrong .screenX");
+ is(evt.screenY, 0, "Wrong .screenY");
+ is(evt.clientX, 10, "Wrong .clientX");
+ is(evt.clientY, 10, "Wrong .clientY");
+}
+
+function listenerForScroll(evt) {
+ isnot(evt.clientX, evt.pageX, "Wrong .pageX");
+ isnot(evt.clientY, evt.pageY, "Wrong .pageY");
+ ok(evt.pageX > 3000, "Wrong .pageX");
+ ok(evt.pageY > 3000, "Wrong .pageY");
+ is(evt.screenX, 0, "Wrong .screenX");
+ is(evt.screenY, 0, "Wrong .screenY");
+ is(evt.clientX, 10, "Wrong .clientX");
+ is(evt.clientY, 10, "Wrong .clientY");
+}
+
+function doTest() {
+ window.scrollTo(0, 0);
+ var target = document.getElementById("testTarget");
+ target.addEventListener("click", listenerForNoScroll, true);
+ var me = document.createEvent("MouseEvent");
+ me.initMouseEvent("click", true, true, window, 0, 0, 0, 10, 10,
+ false, false, false, false, 0, null);
+ target.dispatchEvent(me);
+ target.removeEventListener("click", listenerForNoScroll, true);
+
+ target.scrollIntoView(true);
+ target.addEventListener("click", listenerForScroll, true);
+ me = document.createEvent("MouseEvent");
+ me.initMouseEvent("click", true, true, window, 0, 0, 0, 10, 10,
+ false, false, false, false, 0, null);
+ target.dispatchEvent(me);
+ target.addEventListener("click", listenerForNoScroll, true);
+
+ document.getElementsByTagName("a")[0].scrollIntoView(true);
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+<div style="min-height: 4000px; min-width: 4000px;"></div>
+<div style="min-width: 4000px; text-align: right;">
+ <span id="testTarget" style="border: 1px solid black;">testTarget</span>
+</div>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug447736.html b/dom/events/test/test_bug447736.html
new file mode 100644
index 000000000..fc696d5e9
--- /dev/null
+++ b/dom/events/test/test_bug447736.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=447736
+-->
+<head>
+ <title>Test for Bug 447736</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=447736">Mozilla Bug 447736</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<div id="secondTarget"></div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 447736 **/
+
+var loadEvent = null;
+window.addEventListener("load",
+ function (evt) {
+ is(evt.target, window.document, "Wrong target!");
+ is(evt.originalTarget, window.document, "Wrong originalTarget!");
+ ok(evt.isTrusted, "Event should be trusted!");
+ loadEvent = evt;
+ setTimeout("st.dispatchEvent(loadEvent)", 0);
+ }, true);
+
+var st = document.getElementById("secondTarget");
+st.addEventListener("load",
+ function (evt) {
+ is(evt.target, st, "Wrong target! (2)");
+ is(evt.originalTarget, st, "Wrong originalTarget! (2)");
+ ok(!evt.isTrusted, "Event shouldn't be trusted anymore!");
+ SimpleTest.finish();
+ }, true);
+
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug448602.html b/dom/events/test/test_bug448602.html
new file mode 100644
index 000000000..0d2d8b580
--- /dev/null
+++ b/dom/events/test/test_bug448602.html
@@ -0,0 +1,220 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=448602
+-->
+<head>
+ <title>Test for Bug 448602</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448602">Mozilla Bug 448602</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 448602 **/
+
+var els, root, l2, l3;
+
+function runTests() {
+ els = SpecialPowers.Cc["@mozilla.org/eventlistenerservice;1"]
+ .getService(SpecialPowers.Ci.nsIEventListenerService);
+
+ // Event listener info tests
+ root = document.getElementById("testroot");
+ var infos = els.getListenerInfoFor(root, {});
+ is(infos.length, 0, "Element shouldn't have listeners (1)");
+
+ var listenerSource = 'alert(event);';
+ root.setAttribute("onclick", listenerSource);
+ infos = els.getListenerInfoFor(root, {});
+ is(infos.length, 1, "Element should have listeners (1)");
+ is(infos[0].toSource(), 'function onclick(event) {\n' + listenerSource + '\n}',
+ "Unexpected serialization (1)");
+ is(infos[0].type, "click", "Wrong type (1)");
+ is(infos[0].capturing, false, "Wrong phase (1)");
+ is(infos[0].allowsUntrusted, true, "Should allow untrusted events (1)");
+ is(SpecialPowers.unwrap(infos[0].listenerObject), root.onclick,
+ "Should have the right listener object (1)");
+
+ root.removeAttribute("onclick");
+ root.setAttribute("onclick", "...invalid script...");
+ SimpleTest.expectUncaughtException(true);
+ infos = els.getListenerInfoFor(root, {});
+ SimpleTest.expectUncaughtException(false);
+ is(infos.length, 1);
+ is(infos[0].listenerObject, null);
+
+ root.removeAttribute("onclick");
+ infos = els.getListenerInfoFor(root, {});
+ is(infos.length, 0, "Element shouldn't have listeners (2)");
+
+ var l = function (e) { alert(e); };
+ root.addEventListener("foo", l, true, true);
+ root.addEventListener("foo", l, false, false);
+ infos = els.getListenerInfoFor(root, {});
+ is(infos.length, 2, "Element should have listeners (2)");
+ is(infos[0].toSource(), "(function (e) { alert(e); })",
+ "Unexpected serialization (2)");
+ is(infos[0].type, "foo", "Wrong type (2)");
+ is(infos[0].capturing, true, "Wrong phase (2)");
+ is(infos[0].allowsUntrusted, true, "Should allow untrusted events (2)");
+ is(SpecialPowers.unwrap(infos[0].listenerObject), l,
+ "Should have the right listener object (2)");
+ is(infos[1].toSource(), "(function (e) { alert(e); })",
+ "Unexpected serialization (3)");
+ is(infos[1].type, "foo", "Wrong type (3)");
+ is(infos[1].capturing, false, "Wrong phase (3)");
+ is(infos[1].allowsUntrusted, false, "Shouldn't allow untrusted events (1)");
+ is(SpecialPowers.unwrap(infos[1].listenerObject), l,
+ "Should have the right listener object (3)");
+
+ root.removeEventListener("foo", l, true);
+ root.removeEventListener("foo", l, false);
+ infos = els.getListenerInfoFor(root, {});
+ is(infos.length, 0, "Element shouldn't have listeners (3)");
+
+ root.onclick = l;
+ infos = els.getListenerInfoFor(root, {});
+ is(infos.length, 1, "Element should have listeners (3)");
+ is(infos[0].toSource(), '(function (e) { alert(e); })',
+ "Unexpected serialization (4)");
+ is(infos[0].type, "click", "Wrong type (4)");
+ is(infos[0].capturing, false, "Wrong phase (4)");
+ is(infos[0].allowsUntrusted, true, "Should allow untrusted events (3)");
+ is(SpecialPowers.unwrap(infos[0].listenerObject), l,
+ "Should have the right listener object (4)");
+
+ // Event target chain tests
+ l2 = document.getElementById("testlevel2");
+ l3 = document.getElementById("testlevel3");
+ var textnode = l3.firstChild;
+ var chain = els.getEventTargetChainFor(textnode, true, {});
+ ok(chain.length > 3, "Too short event target chain.");
+ ok(SpecialPowers.compare(chain[0], textnode), "Wrong chain item (1)");
+ ok(SpecialPowers.compare(chain[1], l3), "Wrong chain item (2)");
+ ok(SpecialPowers.compare(chain[2], l2), "Wrong chain item (3)");
+ ok(SpecialPowers.compare(chain[3], root), "Wrong chain item (4)");
+
+ var hasDocumentInChain = false;
+ var hasWindowInChain = false;
+ for (var i = 0; i < chain.length; ++i) {
+ if (SpecialPowers.compare(chain[i], document)) {
+ hasDocumentInChain = true;
+ } else if (SpecialPowers.compare(chain[i], window)) {
+ hasWindowInChain = true;
+ }
+ }
+
+ ok(hasDocumentInChain, "Should have document in event target chain!");
+ ok(hasWindowInChain, "Should have window in event target chain!");
+
+ try {
+ els.getListenerInfoFor(null, {});
+ ok(false, "Should have thrown an exception.");
+ } catch (ex) {
+ ok(true, "We should be still running.");
+ }
+ setTimeout(testAllListener, 0);
+}
+
+function dispatchTrusted(t, o) {
+ SpecialPowers.dispatchEvent(window, t, new Event("testevent", o));
+}
+
+function testAllListener() {
+ els = SpecialPowers.wrap(els);
+ var results = [];
+ var expectedResults =
+ [ { target: "testlevel3", phase: 3, trusted: false },
+ { target: "testlevel3", phase: 3, trusted: false },
+ { target: "testlevel3", phase: 3, trusted: true },
+ { target: "testlevel3", phase: 3, trusted: true },
+ { target: "testlevel3", phase: 3, trusted: true }
+ ];
+
+ function allListener(e) {
+ results.push({
+ target: e.target.id,
+ phase: e.eventPhase,
+ trusted: e.isTrusted
+ });
+ e.stopPropagation();
+ }
+ function allListenerTrustedOnly(e) {
+ results.push({
+ target: e.target.id,
+ phase: e.eventPhase,
+ trusted: e.isTrusted
+ });
+ e.stopPropagation();
+ }
+
+ els.addListenerForAllEvents(root, allListener, false, true);
+ var infos = els.getListenerInfoFor(root);
+ var nullTypes = 0;
+ for (var i = 0; i < infos.length; ++i) {
+ if (infos[i].type == null) {
+ ++nullTypes;
+ }
+ }
+ is(nullTypes, 1, "Should have one all-event-listener!");
+
+ els.addListenerForAllEvents(root, allListener, false, true, true);
+ els.addListenerForAllEvents(root, allListenerTrustedOnly, false, false, true);
+ l3.dispatchEvent(new Event("testevent", { bubbles: true, composed: true }));
+ dispatchTrusted(l3, { bubbles: true, composed: true });
+ els.removeListenerForAllEvents(root, allListener, false);
+ els.removeListenerForAllEvents(root, allListener, false, true);
+ els.removeListenerForAllEvents(root, allListenerTrustedOnly, false, true);
+ // make sure removeListenerForAllEvents works.
+ l3.dispatchEvent(new Event("testevent", { bubbles: true, composed : true }));
+ dispatchTrusted(l3, { bubbles: true, composed: true });
+
+ // Test the order of event listeners.
+ var clickListenerCalled = false;
+ var allListenerCalled = false;
+ function clickListener() {
+ clickListenerCalled = true;
+ ok(allListenerCalled, "Should have called '*' listener before normal listener!");
+ }
+ function allListener2() {
+ allListenerCalled = true;
+ notok(clickListenerCalled, "Shouldn't have called click listener before '*' listener!");
+ }
+ root.onclick = null; // Remove the listener added in earlier tests.
+ root.addEventListener("click", clickListener);
+ els.addListenerForAllEvents(root, allListener2, false, true);
+ l3.dispatchEvent(new MouseEvent("click", { bubbles: true }));
+ root.removeEventListener("click", clickListener);
+ els.removeListenerForAllEvents(root, allListener2, false);
+ ok(allListenerCalled, "Should have called '*' listener");
+ ok(clickListenerCalled, "Should have called click listener");
+
+ is(results.length, expectedResults.length, "count");
+ for (var i = 0; i < expectedResults.length; ++i) {
+ for (var p in expectedResults[i]) {
+ is(results[i][p], expectedResults[i][p], p);
+ }
+ }
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(runTests);
+</script>
+</pre>
+<div id="testroot">
+ <div id="testlevel2">
+ <div id="testlevel3">
+ Test
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug450876.html b/dom/events/test/test_bug450876.html
new file mode 100644
index 000000000..79efeda28
--- /dev/null
+++ b/dom/events/test/test_bug450876.html
@@ -0,0 +1,41 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=450876
+-->
+<head>
+ <title>Test for Bug 450876 - Crash [@ nsEventStateManager::GetNextTabbableMapArea] with img usemap and tabindex</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450876">Mozilla Bug 450876</a>
+<p id="display"><a href="#" id="a">link to focus from</a><img usemap="#a" tabindex="1"></p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 450876 **/
+
+function doTest() {
+ is(document.activeElement, document.body, "body element should be focused");
+ document.getElementById('a').focus();
+ is(document.activeElement, document.getElementById('a'), "link should have focus");
+ is(document.hasFocus(), true, "document should be focused");
+ SpecialPowers.DOMWindowUtils.sendKeyEvent('keypress', 9, 0, 0);
+ is(document.activeElement, document.getElementById('a'), "body element should be focused");
+ is(document.hasFocus(), false, "document should not be focused");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug456273.html b/dom/events/test/test_bug456273.html
new file mode 100644
index 000000000..ac7bd2bce
--- /dev/null
+++ b/dom/events/test/test_bug456273.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=456273
+-->
+<head>
+ <title>Test for Bug 456273</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=456273">Mozilla Bug 456273</a>
+<p id="display">PASS if Firefox does not crash.</p>
+<div id="content" style="display: none">
+
+</div>
+
+<div id="edit456273" contenteditable="true">text</div>
+
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 456273 **/
+
+function doTest() {
+ var ev = document.createEvent('KeyboardEvent');
+ ev.initKeyEvent("keypress", true, true, null, true, false,
+ false, false, 0, "z".charCodeAt(0));
+ SpecialPowers.dispatchEvent(window, document.getElementById('edit456273'), ev);
+
+ ok(true, "PASS");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug457672.html b/dom/events/test/test_bug457672.html
new file mode 100644
index 000000000..b3dc5bcb3
--- /dev/null
+++ b/dom/events/test/test_bug457672.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=457672
+-->
+<head>
+ <title>Test for Bug 457672</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=457672">Mozilla Bug 457672</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 457672 **/
+
+var windowBlurCount = 0;
+
+function listener(evt) {
+ if (evt.type == "focus") {
+ is(windowBlurCount, 1,
+ "Window should have got blur event when opening a new tab!");
+ document.getElementsByTagName("a")[0].focus();
+ SimpleTest.finish();
+ } else if (evt.type == "blur") {
+ ++windowBlurCount;
+ }
+ document.getElementById('log').textContent += evt.target + ":" + evt.type + "\n";
+}
+
+function startTest() {
+ SpecialPowers.pushPrefEnv({"set": [["browser.link.open_newwindow", 3]]}, function() {
+ document.getElementsByTagName("a")[0].focus();
+ // Note, focus/blur don't bubble
+ window.addEventListener("focus", listener, false);
+ window.addEventListener("blur", listener, false);
+ var subwin = window.open("about:blank", "", "");
+ subwin.addEventListener("focus", function(e) { subwin.close(); }, false);
+ });
+}
+
+addLoadEvent(startTest);
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+<pre id="log">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug489671.html b/dom/events/test/test_bug489671.html
new file mode 100644
index 000000000..4def80cba
--- /dev/null
+++ b/dom/events/test/test_bug489671.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=489671
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 489671</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=489671"
+ >Mozilla Bug 489671</a>
+<p id="display" onclick="queueNextTest(); throw 'Got click 1';"></p>
+<script>
+// override window.onerror so it won't see our exceptions
+window.onerror = function() {}
+
+var testNum = 0;
+function doTest() {
+ switch(testNum++) {
+ case 0:
+ var event = document.createEvent("MouseEvents");
+ event.initMouseEvent("click", true, true, document.defaultView,
+ 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ $("display").dispatchEvent(event);
+ break;
+ case 1:
+ var script = document.createElement("script");
+ script.textContent = "queueNextTest(); throw 'Got click 2'";
+ document.body.appendChild(script);
+ break;
+ case 2:
+ window.setTimeout("queueNextTest(); throw 'Got click 3'", 0);
+ break;
+ case 3:
+ SimpleTest.endMonitorConsole();
+ return;
+ }
+}
+function queueNextTest() { SimpleTest.executeSoon(doTest); }
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.monitorConsole(SimpleTest.finish, [
+ { errorMessage: "uncaught exception: Got click 1" },
+ { errorMessage: "uncaught exception: Got click 2" },
+ { errorMessage: "uncaught exception: Got click 3" }
+]);
+
+doTest();
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_bug493251.html b/dom/events/test/test_bug493251.html
new file mode 100644
index 000000000..d23045dee
--- /dev/null
+++ b/dom/events/test/test_bug493251.html
@@ -0,0 +1,194 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=493251
+-->
+<head>
+ <title>Test for Bug 493251</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=493251">Mozilla Bug 493251</a>
+<p id="display">
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 493251 **/
+
+ var win;
+
+ var mouseDown = 0;
+ var mouseUp = 0;
+ var mouseClick = 0;
+
+ var keyDown = 0;
+ var keyPress = 0;
+ var keyUp = 0;
+
+ function suppressEventHandling(aSuppress) {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ ok(true, "suppressEventHandling: aSuppress=" + aSuppress);
+ utils.suppressEventHandling(aSuppress);
+ }
+
+ function dispatchKeyEvent(type) {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ ok(true, "Dipatching key event: type=" + type);
+ utils.sendKeyEvent(type,
+ SpecialPowers.Ci.nsIDOMKeyEvent.DOM_VK_A,
+ 0, 0);
+ }
+
+ function dispatchMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers) {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ ok(true, "Dipatching mouse event: aType=" + aType + ", aX=" + aX + ", aY" +
+ aY + ", aButton=" + aButton + ", aClickCount=" + aClickCount +
+ ", aModifiers=" + aModifiers);
+ utils.sendMouseEvent(aType, aX, aY, aButton, aClickCount, aModifiers);
+ }
+
+ function dumpEvent(aEvent) {
+ var detail = "target=" + aEvent.target + ", originalTarget=" +
+ aEvent.originalTarget + ", defaultPrevented=" +
+ aEvent.defaultPrevented + ", isTrusted=" + aEvent.isTrusted;
+ switch (aEvent.type) {
+ case "keydown":
+ case "keypress":
+ case "keyup":
+ detail += ", charCode=0x" + aEvent.charCode.toString(16) +
+ ", keyCode=0x" + aEvent.keyCode.toString(16) +
+ ", altKey=" + (aEvent.altKey ? "PRESSED" : "no") +
+ ", ctrlKey=" + (aEvent.ctrlKey ? "PRESSED" : "no") +
+ ", shiftKey=" + (aEvent.shiftKey ? "PRESSED" : "no") +
+ ", metaKey=" + (aEvent.metaKey ? "PRESSED" : "no");
+ break;
+ case "mousedown":
+ case "mouseup":
+ case "click":
+ detail += ", screenX=" + aEvent.screenX + ", screenY=" + aEvent.screenY +
+ ", clientX=" + aEvent.clientX + ", clientY=" + aEvent.clientY +
+ ", altKey=" + (aEvent.altKey ? "PRESSED" : "no") +
+ ", ctrlKey=" + (aEvent.ctrlKey ? "PRESSED" : "no") +
+ ", shiftKey=" + (aEvent.shiftKey ? "PRESSED" : "no") +
+ ", metaKey=" + (aEvent.metaKey ? "PRESSED" : "no") +
+ ", button=" + aEvent.button +
+ ", relatedTarget=" + aEvent.relatedTarget;
+ break;
+ }
+ ok(true, aEvent.type + " event is handled: " + detail);
+
+ var fm = SpecialPowers.Cc["@mozilla.org/focus-manager;1"].
+ getService(SpecialPowers.Ci.nsIFocusManager);
+ ok(true, "focused element is \"" + fm.focusedElement +
+ "\" and focused window is \"" + fm.focusedWindow +
+ "\" (the testing window is \"" + win + "\"");
+ }
+
+ function doTest() {
+ win.document.getElementsByTagName("input")[0].focus();
+ win.addEventListener("keydown",
+ function(e) { dumpEvent(e); ++keyDown; }, true);
+ win.addEventListener("keypress",
+ function(e) { dumpEvent(e); ++keyPress; }, true);
+ win.addEventListener("keyup",
+ function(e) { dumpEvent(e); ++keyUp; }, true);
+ win.addEventListener("mousedown",
+ function(e) { dumpEvent(e); ++mouseDown; }, true);
+ win.addEventListener("mouseup",
+ function(e) { dumpEvent(e); ++mouseUp; }, true);
+ win.addEventListener("click",
+ function(e) { dumpEvent(e); ++mouseClick; }, true);
+
+ ok(true, "doTest #1...");
+ dispatchKeyEvent("keydown");
+ dispatchKeyEvent("keypress");
+ dispatchKeyEvent("keyup");
+ is(keyDown, 1, "Wrong number events (1)");
+ is(keyPress, 1, "Wrong number events (2)");
+ is(keyUp, 1, "Wrong number events (3)");
+
+ ok(true, "doTest #2...");
+ suppressEventHandling(true);
+ dispatchKeyEvent("keydown");
+ dispatchKeyEvent("keypress");
+ dispatchKeyEvent("keyup");
+ is(keyDown, 1, "Wrong number events (4)");
+ is(keyPress, 1, "Wrong number events (5)");
+ is(keyUp, 1, "Wrong number events (6)");
+ suppressEventHandling(false);
+ is(keyDown, 1, "Wrong number events (7)");
+ is(keyPress, 1, "Wrong number events (8)");
+ is(keyUp, 1, "Wrong number events (9)");
+
+ setTimeout(continueTest1, 0);
+ }
+
+ function continueTest1() {
+ ok(true, "continueTest1...");
+ dispatchKeyEvent("keydown");
+ suppressEventHandling(true);
+ dispatchKeyEvent("keypress");
+ dispatchKeyEvent("keyup");
+ is(keyDown, 2, "Wrong number events (10)");
+ is(keyPress, 1, "Wrong number events (11)");
+ is(keyUp, 1, "Wrong number events (12)");
+ suppressEventHandling(false);
+ setTimeout(continueTest2, 0);
+ }
+
+ function continueTest2() {
+ ok(true, "continueTest2 #1...");
+ is(keyDown, 2, "Wrong number events (13)");
+ is(keyPress, 2, "Wrong number events (14)");
+ is(keyUp, 2, "Wrong number events (15)");
+
+ dispatchMouseEvent("mousedown", 5, 5, 0, 1, 0);
+ dispatchMouseEvent("mouseup", 5, 5, 0, 1, 0);
+ is(mouseDown, 1, "Wrong number events (16)");
+ is(mouseUp, 1, "Wrong number events (17)");
+ is(mouseClick, 1, "Wrong number events (18)");
+
+ ok(true, "continueTest2 #2...");
+ suppressEventHandling(true);
+ dispatchMouseEvent("mousedown", 5, 5, 0, 1, 0);
+ dispatchMouseEvent("mouseup", 5, 5, 0, 1, 0);
+ suppressEventHandling(false);
+ is(mouseDown, 1, "Wrong number events (19)");
+ is(mouseUp, 1, "Wrong number events (20)");
+ is(mouseClick, 1, "Wrong number events (21)");
+
+ setTimeout(continueTest3, 0);
+ }
+
+ function continueTest3() {
+ ok(true, "continueTest3...");
+ dispatchMouseEvent("mousedown", 5, 5, 0, 1, 0);
+ suppressEventHandling(true);
+ dispatchMouseEvent("mouseup", 5, 5, 0, 1, 0);
+ suppressEventHandling(false);
+ setTimeout(continueTest4, 1000);
+ }
+
+ function continueTest4() {
+ ok(true, "continueTest4...");
+ is(mouseDown, 2, "Wrong number events (19)");
+ is(mouseUp, 2, "Wrong number events (20)");
+ is(mouseClick, 2, "Wrong number events (21)");
+ win.close();
+ SimpleTest.finish();
+ }
+
+
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.requestFlakyTimeout("untriaged");
+ win = window.open("window_bug493251.html", "_blank" , "width=500,height=500");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug502818.html b/dom/events/test/test_bug502818.html
new file mode 100644
index 000000000..699b312f3
--- /dev/null
+++ b/dom/events/test/test_bug502818.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=502818
+-->
+<head>
+ <title>Test for Bug 502818</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=502818">Mozilla Bug 502818</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 502818 **/
+
+ var count = 0;
+
+ function listener(evt) {
+ ++count;
+ is(evt.foo, 'bar', "Event.prototype should be accessible from " + evt.type);
+ }
+
+ Event.prototype.foo = 'bar';
+ window.addEventListener('DOMMouseScroll', listener, false);
+ window.addEventListener('MozMousePixelScroll', listener, false);
+ window.addEventListener('foobar', listener, false);
+
+ var e = document.createEvent("mousescrollevents");
+ e.initMouseScrollEvent("DOMMouseScroll", true, true, window,
+ 0, 0, 0, 0, 0, false, false, false, false,
+ 0, null, 1);
+ window.dispatchEvent(e);
+
+ e.initMouseScrollEvent("MozMousePixelScroll", true, true, window,
+ 0, 0, 0, 0, 0, false, false, false, false,
+ 0, null, 1);
+ window.dispatchEvent(e);
+
+ e.initMouseScrollEvent("foobar", true, true, window,
+ 0, 0, 0, 0, 0, false, false, false, false,
+ 0, null, 1);
+ window.dispatchEvent(e);
+
+ is(count, 3, "Wrong number tests run!");
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug508479.html b/dom/events/test/test_bug508479.html
new file mode 100644
index 000000000..9cf9e22b8
--- /dev/null
+++ b/dom/events/test/test_bug508479.html
@@ -0,0 +1,103 @@
+<html>
+<head>
+ <title>Tests for the dragstart event</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<script>
+
+var gGotHandlingDrop = false;
+var gGotNotHandlingDrop = false;
+
+SimpleTest.waitForExplicitFinish();
+
+function fireEvent(target, event) {
+ SpecialPowers.DOMWindowUtils.dispatchDOMEventViaPresShell(target, event, true);
+}
+
+function fireDrop(element, shouldAllowDrop, shouldAllowOnlyChromeDrop) {
+ var ds = SpecialPowers.Cc["@mozilla.org/widget/dragservice;1"].
+ getService(SpecialPowers.Ci.nsIDragService);
+
+ var dataTransfer;
+ var trapDrag = function(event) {
+ dataTransfer = event.dataTransfer;
+ dataTransfer.setData("text/plain", "Hello");;
+ dataTransfer.dropEffect = "move";
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ // need to use real mouse action
+ window.addEventListener("dragstart", trapDrag, true);
+ synthesizeMouse(element, 2, 2, { type: "mousedown" });
+ synthesizeMouse(element, 11, 11, { type: "mousemove" });
+ synthesizeMouse(element, 20, 20, { type: "mousemove" });
+ window.removeEventListener("dragstart", trapDrag, true);
+ synthesizeMouse(element, 20, 20, { type: "mouseup" });
+
+ ds.startDragSession();
+
+ var event = document.createEvent("DragEvent");
+ event.initDragEvent("dragover", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
+ fireEvent(element, event);
+
+ is(ds.getCurrentSession().canDrop, shouldAllowDrop, "Unexpected .canDrop");
+ is(ds.getCurrentSession().onlyChromeDrop, shouldAllowOnlyChromeDrop,
+ "Unexpected .onlyChromeDrop");
+
+ event = document.createEvent("DragEvent");
+ event.initDragEvent("drop", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null, dataTransfer);
+ fireEvent(element, event);
+
+ ds.endDragSession(false);
+ ok(!ds.getCurrentSession(), "There shouldn't be a drag session anymore!");
+}
+
+var chromeGotEvent = false;
+function chromeListener(e) {
+ chromeGotEvent = true;
+}
+
+function runTests()
+{
+ var targetHandling = document.getElementById("handling_target");
+ fireDrop(targetHandling, true, false);
+
+ is(gGotHandlingDrop, true, "Got drop on accepting element (1)");
+ is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (1)");
+
+ // reset
+ gGotHandlingDrop = false;
+ gGotNotHandlingDrop = false;
+
+ SpecialPowers.addChromeEventListener("drop", chromeListener, true, false);
+ var targetNotHandling = document.getElementById("nothandling_target");
+ fireDrop(targetNotHandling, true, true);
+ SpecialPowers.removeChromeEventListener("drop", chromeListener, true);
+ ok(chromeGotEvent, "Chrome should have got drop event!");
+ is(gGotHandlingDrop, false, "Didn't get drop on accepting element (2)");
+ is(gGotNotHandlingDrop, false, "Didn't get drop on unaccepting element (2)");
+
+ SimpleTest.finish();
+}
+
+</script>
+
+<body onload="window.setTimeout(runTests, 0);">
+
+<img style="width: 100px; height: 100px;"
+ src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
+ id="handling_target"
+ ondragenter="event.preventDefault()"
+ ondragover="event.preventDefault()"
+ ondrop="gGotHandlingDrop = true;">
+
+<img style="width: 100px; height: 100px;"
+ src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
+ id="nothandling_target"
+ ondrop="gGotNotHandlingDrop = true;">
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug517851.html b/dom/events/test/test_bug517851.html
new file mode 100644
index 000000000..895c867a1
--- /dev/null
+++ b/dom/events/test/test_bug517851.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=517851
+-->
+<head>
+ <title>Test for Bug 517851</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=517851">Mozilla Bug 517851</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe id="subframe"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 517851 **/
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(function() {
+window.handledCount = 0;
+window.testReturnValue = false;
+var target = document.createElement("div");
+var target2 = $("subframe").contentDocument.body;
+target.setAttribute("onerror", "++window.handledCount; return window.testReturnValue;");
+target.setAttribute("onmouseover", "++window.handledCount; return window.testReturnValue;");
+target.setAttribute("onbeforeunload", "++window.handledCount; return window.testReturnValue;");
+target2.setAttribute("onbeforeunload", "++window.parent.handledCount; return window.parent.testReturnValue;");
+target.setAttribute("onmousemove", "++window.handledCount; return window.testReturnValue;");
+
+var e = document.createEvent("Event");
+e.initEvent("error", true, true);
+window.testReturnValue = false;
+is(target.dispatchEvent(e), !window.testReturnValue,
+ "error event should have reverse return value handling!");
+is(handledCount, 1, "Wrong event count!");
+window.testReturnValue = true;
+is(target.dispatchEvent(e), !window.testReturnValue,
+ "error event should have reverse return value handling (2)!");
+is(handledCount, 2, "Wrong event count!");
+
+e = document.createEvent("MouseEvent");
+e.initEvent("mouseover", true, true);
+window.testReturnValue = false;
+is(target.dispatchEvent(e), !window.testReturnValue,
+ "mouseover event should have reverse return value handling!");
+is(handledCount, 3, "Wrong event count!");
+window.testReturnValue = true;
+is(target.dispatchEvent(e), !window.testReturnValue,
+ "mouseover event should have reverse return value handling (2)!");
+is(handledCount, 4, "Wrong event count!");
+
+e = document.createEvent("BeforeUnloadEvent");
+e.initEvent("beforeunload", true, true);
+window.testReturnValue = true;
+is(target.dispatchEvent(e), true,
+ "beforeunload event on random element should not be prevented!");
+is(handledCount, 4, "Wrong event count; handler should not have run!");
+is(target2.dispatchEvent(e), false,
+ "beforeunload event should be prevented!");
+is(handledCount, 5, "Wrong event count!");
+window.testReturnValue = false;
+is(target.dispatchEvent(e), false,
+ "beforeunload event on random element should be prevented because the event was already cancelled!");
+is(handledCount, 5, "Wrong event count; handler should not have run! (2)");
+
+e = document.createEvent("BeforeUnloadEvent");
+e.initEvent("beforeunload", true, true);
+window.testReturnValue = false;
+is(target.dispatchEvent(e), true,
+ "beforeunload event on random element should not be prevented (2)!");
+is(handledCount, 5, "Wrong event count; handler should not have run! (2)");
+
+is(target2.dispatchEvent(e), false,
+ "beforeunload event should be prevented (2)!");
+is(handledCount, 6, "Wrong event count!");
+
+// Create normal event for beforeunload.
+e = document.createEvent("Event");
+e.initEvent("beforeunload", true, true);
+window.testReturnValue = true;
+is(target.dispatchEvent(e), true,
+ "beforeunload event shouldn't be prevented (3)!");
+is(handledCount, 6, "Wrong event count: handler should not have run(3)!");
+is(target2.dispatchEvent(e), true,
+ "beforeunload event shouldn't be prevented (3)!");
+is(handledCount, 7, "Wrong event count!");
+
+e = document.createEvent("MouseEvent");
+e.initEvent("mousemove", true, true);
+window.testReturnValue = true;
+is(target.dispatchEvent(e), window.testReturnValue,
+ "mousemove event shouldn't have reverse return value handling!");
+is(handledCount, 8, "Wrong event count!");
+window.testReturnValue = false;
+is(target.dispatchEvent(e), window.testReturnValue,
+ "mousemove event shouldn't have reverse return value handling (2)!");
+is(handledCount, 9, "Wrong event count!");
+
+// Now unhook the beforeunload handler in the subframe, so we don't prompt to
+// unload.
+target2.onbeforeunload = null;
+
+SimpleTest.finish();
+});
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug524674.xul b/dom/events/test/test_bug524674.xul
new file mode 100644
index 000000000..463d9269b
--- /dev/null
+++ b/dom/events/test/test_bug524674.xul
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=524674
+-->
+<window title="Mozilla Bug 524674"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=524674"
+ target="_blank">Mozilla Bug 524674</a>
+ </body>
+
+ <!-- test code goes here -->
+ <script type="application/javascript">
+ <![CDATA[
+ /** Test for Bug 524674 **/
+
+ var els = Components.classes["@mozilla.org/eventlistenerservice;1"]
+ .getService(Components.interfaces.nsIEventListenerService);
+
+ const Ci = Components.interfaces;
+
+ function dummyListener() {}
+
+ var runningTest = null;
+ var d = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+ var xhr = new XMLHttpRequest();
+
+ // Test also double removals and such.
+ var tests = [
+ function() {
+ els.addListenerChangeListener(changeListener);
+ d.addEventListener("foo", dummyListener);
+ d.addEventListener("foo", dummyListener);
+ xhr.addEventListener("foo", dummyListener);
+ tests[0] = [{target: d, listeners: ["onfoo"]},
+ {target: xhr, listeners: ["onfoo"]}];
+ },
+ function() {
+ d.addEventListener("bar", dummyListener);
+ d.addEventListener("baz", dummyListener);
+ xhr.addEventListener("bar", dummyListener);
+ xhr.addEventListener("baz", dummyListener);
+ tests[0] = [{target: d, listeners: ["onbaz", "onbar"]},
+ {target: xhr, listeners: ["onbaz", "onbar"]}];
+ },
+ function() {
+ d.onclick = dummyListener;
+ d.onclick = dummyListener;
+ xhr.onload = dummyListener;
+ tests[0] = [{target: d, listeners: ["onclick"]},
+ {target: xhr, listeners: ["onload"]}];
+ },
+ function() {
+ d.onclick = function() {};
+ tests[0] = [{target: d, listeners: ["onclick"]}];
+ },
+ function() {
+ d.removeEventListener("foo", dummyListener);
+ d.removeEventListener("foo", dummyListener);
+ xhr.removeEventListener("foo", dummyListener);
+ tests[0] = [{target: d, listeners: ["onfoo"]},
+ {target: xhr, listeners: ["onfoo"]}];
+ },
+ function() {
+ d.removeEventListener("bar", dummyListener);
+ d.removeEventListener("baz", dummyListener);
+ xhr.removeEventListener("bar", dummyListener);
+ xhr.removeEventListener("baz", dummyListener);
+ tests[0] = [{target: d, listeners: ["onbar", "onbaz"]},
+ {target: xhr, listeners: ["onbar", "onbaz"]}];
+ },
+ function() {
+ d.onclick = null;
+ d.onclick = null;
+ xhr.onload = null;
+ tests[0] = [{target: d, listeners: ["onclick"]},
+ {target: xhr, listeners: ["onload"]}];
+ },
+ function() {
+ els.removeListenerChangeListener(changeListener);
+ // Check that once we've removed the change listener, it isn't called anymore.
+ d.addEventListener("foo", dummyListener);
+ xhr.addEventListener("foo", dummyListener);
+ SimpleTest.executeSoon(function() {
+ SimpleTest.finish();
+ });
+ }
+ ];
+
+ SimpleTest.executeSoon(tests[0]);
+
+ function changeListener(array) {
+ if (typeof tests[0] == "function") {
+ return;
+ }
+ var expectedEventChanges = tests[0];
+ var eventChanges = array.enumerate();
+ var i = 0;
+ while (eventChanges.hasMoreElements() && i < expectedEventChanges.length) {
+ var current;
+ try {
+ current = eventChanges.getNext().QueryInterface(Ci.nsIEventListenerChange);
+ var expected = expectedEventChanges[i];
+
+ if (current.target == expected.target) {
+ // expected.target.listeners should be a subset of
+ // current.changedListenerNames if all expected listener changes were
+ // sent. We may get random other event listener changes here too, not
+ // just the one from the test.
+ is(current.target, expected.target, current.target + " = " + expected.target);
+
+ var eNames = current.changedListenerNames.enumerate();
+ var listeners = [];
+ while (eNames.hasMoreElements()) {
+ var listenerName = eNames.getNext().QueryInterface(Ci.nsIAtom).toString();
+ listeners.push(listenerName);
+ }
+ var matchAll = expected.listeners.every(function(val)
+ { return listeners.indexOf(val) >= 0; });
+ if (!matchAll)
+ return;
+ ++i;
+ }
+ } catch(ex) {
+ continue;
+ }
+ }
+ if (expectedEventChanges.length != i) {
+ return;
+ }
+
+ is(expectedEventChanges.length, i, "Should have got notification for all the changes.");
+ tests.shift();
+
+ ok(tests.length);
+ SimpleTest.executeSoon(tests[0]);
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ ]]>
+ </script>
+</window>
diff --git a/dom/events/test/test_bug534833.html b/dom/events/test/test_bug534833.html
new file mode 100644
index 000000000..9d9a2eb1d
--- /dev/null
+++ b/dom/events/test/test_bug534833.html
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=534833
+-->
+<head>
+ <title>Test for Bug 534833</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534833">Mozilla Bug 534833</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 534833 **/
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(runTests);
+
+var input1GotClick = 0;
+var input2GotClick = 0;
+var textarea1GotClick = 0;
+var textarea2GotClick = 0;
+var div1GotClick = 0;
+var div2GotClick = 0;
+
+var tests = [ { element: "text", clickText: true },
+ { element: "text2", clickText: false },
+ { element: "area", clickText: true },
+ { element: "area2", clickText: false },
+ { element: "d", clickText: true },
+ { element: "d", clickText: false },
+ { element: "d2", clickText: true },
+ { element: "d2", clickText: false }
+ ];
+
+function nextTest_() {
+ if (!tests.length) {
+ finishTests();
+ return;
+ }
+
+ var test = tests.shift();
+ var el = document.getElementById(test.element);
+ el.scrollIntoView(true);
+ if (test.clickText) {
+ synthesizeMouse(el, 5, 5, {type : "mousedown" });
+ synthesizeMouse(el, 5, 5, {type : "mouseup" });
+ } else {
+ synthesizeMouse(el, el.getBoundingClientRect().width - 5, 5, {type : "mousedown" });
+ synthesizeMouse(el, el.getBoundingClientRect().width - 5, 5, {type : "mouseup" });
+ }
+ nextTest();
+}
+
+function nextTest() {
+ var el = document.getElementById("initialfocus");
+
+ el.addEventListener("focus", function() {
+ el.removeEventListener("focus", arguments.callee, false);
+ setTimeout(nextTest_, 0);
+ }, false);
+ el.focus();
+}
+
+function runTests() {
+ var t = document.getElementById("text");
+ var t2 = document.getElementById("text2");
+ var a = document.getElementById("area");
+ var a2 = document.getElementById("area2");
+ var d = document.getElementById("d");
+ var d2 = document.getElementById("d2");
+
+ // input 1
+ t.onfocus = function(e) {
+ t.value = "";
+ }
+ t.onclick = function(e) {
+ ++input1GotClick;
+ }
+
+ // input 2
+ t2.onfocus = function(e) {
+ t2.value = "";
+ }
+ t2.onclick = function(e) {
+ ++input2GotClick;
+ }
+
+ // textarea 1
+ a.onfocus = function(e) {
+ a.value = "";
+ }
+ a.onclick = function(e) {
+ ++textarea1GotClick;
+ }
+
+ // textarea 2
+ a2.onfocus = function(e) {
+ a2.value = "";
+ }
+ a2.onclick = function(e) {
+ ++textarea2GotClick;
+ }
+
+ // div 1
+ var c = 0;
+ d.onmousedown = function(e) {
+ d.textContent = (++c) + " / click before or after |";
+ }
+ d.onclick = function(e) {
+ ++div1GotClick;
+ }
+
+ // div 2
+ var c2 = 0;
+ d2.onmousedown = function(e) {
+ d2.firstChild.data = (++c2) + " / click before or after |";
+ }
+ d2.onclick = function(e) {
+ ++div2GotClick;
+ }
+ nextTest();
+}
+
+function finishTests() {
+ is(input1GotClick, 1, "input element should have got a click!");
+ is(input2GotClick, 1, "input element should have got a click! (2)");
+ is(textarea1GotClick, 1, "textarea element should have got a click!");
+ is(textarea2GotClick, 1, "textarea element should have got a click! (2)");
+ is(div1GotClick, 2, "div element's content text was replaced, it should have got 2 click!");
+ is(div2GotClick, 2, "div element's content text was modified, it should have got 2 clicks!");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<input type="text" id="initialfocus"><br>
+<input type="text" id="text" value="click before |" style="width: 95%;"><br>
+<input type="text" id="text2" value="click after |" style="width: 95%;">
+<br>
+<textarea id="area" rows="2" style="width: 95%;">
+ click before
+ |
+</textarea><br>
+<textarea id="area2" rows="2" style="width: 95%;">
+ click after |
+</textarea>
+<div id="d" style="border: 1px solid black;">click before or after |</div>
+<div id="d2" style="border: 1px solid black;">click before or after |</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug545268.html b/dom/events/test/test_bug545268.html
new file mode 100644
index 000000000..c2ad64780
--- /dev/null
+++ b/dom/events/test/test_bug545268.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=545268
+-->
+<head>
+ <title>Test for Bug 545268</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=545268">Mozilla Bug 545268</a>
+<p id="display">
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 545268
+ Like the test for bug 493251, but we test that suppressing events in
+ a parent window stops the events from reaching the child window. */
+
+ var win;
+ var subwin;
+
+ var mouseDown = 0;
+ var mouseUp = 0;
+ var mouseClick = 0;
+
+ var keyDown = 0;
+ var keyPress = 0;
+ var keyUp = 0;
+
+ function dispatchKeyEvent(type) {
+ var utils = SpecialPowers.getDOMWindowUtils(subwin);
+ utils.sendKeyEvent(type,
+ SpecialPowers.Ci.nsIDOMKeyEvent.DOM_VK_A,
+ 0, 0);
+ }
+
+ function doTest() {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ var f = win.document.getElementById("f");
+ subwin = f.contentWindow;
+ subwin.document.getElementsByTagName("input")[0].focus();
+ subwin.addEventListener("keydown", function(e) { ++keyDown; }, true);
+ subwin.addEventListener("keypress", function(e) { ++keyPress; }, true);
+ subwin.addEventListener("keyup", function(e) { ++keyUp; }, true);
+ subwin.addEventListener("mousedown", function(e) { ++mouseDown; }, true);
+ subwin.addEventListener("mouseup", function(e) { ++mouseUp; }, true);
+ subwin.addEventListener("click", function(e) { ++mouseClick; }, true);
+
+ dispatchKeyEvent("keydown");
+ dispatchKeyEvent("keypress");
+ dispatchKeyEvent("keyup");
+ is(keyDown, 1, "Wrong number events (1)");
+ is(keyPress, 1, "Wrong number events (2)");
+ is(keyUp, 1, "Wrong number events (3)");
+
+ // Test that suppressing events on the parent window prevents key
+ // events in the subdocument window
+ utils.suppressEventHandling(true);
+ dispatchKeyEvent("keydown");
+ dispatchKeyEvent("keypress");
+ dispatchKeyEvent("keyup");
+ is(keyDown, 1, "Wrong number events (4)");
+ is(keyPress, 1, "Wrong number events (5)");
+ is(keyUp, 1, "Wrong number events (6)");
+ utils.suppressEventHandling(false);
+ is(keyDown, 1, "Wrong number events (7)");
+ is(keyPress, 1, "Wrong number events (8)");
+ is(keyUp, 1, "Wrong number events (9)");
+
+ setTimeout(continueTest1, 0);
+ }
+
+ function continueTest1() {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ dispatchKeyEvent("keydown");
+ utils.suppressEventHandling(true);
+ dispatchKeyEvent("keypress");
+ dispatchKeyEvent("keyup");
+ is(keyDown, 2, "Wrong number events (10)");
+ is(keyPress, 1, "Wrong number events (11)");
+ is(keyUp, 1, "Wrong number events (12)");
+ utils.suppressEventHandling(false);
+ setTimeout(continueTest2, 0);
+ }
+
+ function continueTest2() {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ is(keyDown, 2, "Wrong number events (13)");
+ is(keyPress, 2, "Wrong number events (14)");
+ is(keyUp, 2, "Wrong number events (15)");
+
+ utils.sendMouseEvent("mousedown", 5, 5, 0, 1, 0);
+ utils.sendMouseEvent("mouseup", 5, 5, 0, 1, 0);
+ is(mouseDown, 1, "Wrong number events (16)");
+ is(mouseUp, 1, "Wrong number events (17)");
+ is(mouseClick, 1, "Wrong number events (18)");
+
+ utils.suppressEventHandling(true);
+ utils.sendMouseEvent("mousedown", 5, 5, 0, 1, 0);
+ utils.sendMouseEvent("mouseup", 5, 5, 0, 1, 0);
+ utils.suppressEventHandling(false);
+ is(mouseDown, 1, "Wrong number events (19)");
+ is(mouseUp, 1, "Wrong number events (20)");
+ is(mouseClick, 1, "Wrong number events (21)");
+
+ setTimeout(continueTest3, 0);
+ }
+
+ function continueTest3() {
+ var utils = SpecialPowers.getDOMWindowUtils(win);
+ utils.sendMouseEvent("mousedown", 5, 5, 0, 1, 0);
+ utils.suppressEventHandling(true);
+ utils.sendMouseEvent("mouseup", 5, 5, 0, 1, 0);
+ utils.suppressEventHandling(false);
+ setTimeout(continueTest4, 1000);
+ }
+
+ function continueTest4() {
+ is(mouseDown, 2, "Wrong number events (19)");
+ is(mouseUp, 2, "Wrong number events (20)");
+ is(mouseClick, 2, "Wrong number events (21)");
+ win.close();
+ SimpleTest.finish();
+ }
+
+
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.requestFlakyTimeout("untriaged");
+ win = window.open("data:text/html,<iframe id='f' style='position:absolute; border:none; width:100%; height:100%; left:0; top:0' src='data:text/html,&lt;input&gt;'>", "" , "");
+ win.onload = doTest;
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug547996-1.html b/dom/events/test/test_bug547996-1.html
new file mode 100644
index 000000000..11944ec5d
--- /dev/null
+++ b/dom/events/test/test_bug547996-1.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=547996
+-->
+<head>
+ <title>Test for Bug 547996</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=547996">Mozilla Bug 547996</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 547996 **/
+/* mouseEvent.mozInputSource attribute */
+
+function prepareListener(eventName, expectedValue) {
+ return function(event) {
+ is(event.mozInputSource, expectedValue, "Correct .mozInputSource value in " + eventName);
+ };
+}
+
+const INPUT_SOURCE_UNKNOWN = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN;
+const INPUT_SOURCE_KEYBOARD = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_KEYBOARD;
+
+function doTest() {
+ var eventNames = [
+ "mousedown",
+ "mouseup",
+ "click",
+ "dblclick",
+ "contextmenu",
+ "DOMMouseScroll",
+ "dragdrop",
+ "dragstart",
+ "dragend",
+ "dragenter",
+ "dragleave",
+ "dragover"
+ ];
+
+ var target = document.getElementById("testTarget");
+
+ for (var i in eventNames) {
+ for(var value = INPUT_SOURCE_UNKNOWN; value <= INPUT_SOURCE_KEYBOARD; value++) {
+ var eventName = eventNames[i];
+ var listener = prepareListener(eventName, value);
+
+ target.addEventListener(eventName, listener, false);
+
+ var newEvent = document.createEvent("MouseEvent");
+ newEvent.initNSMouseEvent(eventName, true, true, window, 0, 0, 0, 0, 0,
+ false, false, false, false, 0, null, 0, value);
+ target.dispatchEvent(newEvent);
+ target.removeEventListener(eventName, listener, false);
+ }
+
+ // Events created by script that do not initialize the mozInputSource
+ // value should have the value MOZ_SOURCE_UNKNOWN
+ var listener = prepareListener(eventName, INPUT_SOURCE_UNKNOWN);
+ target.addEventListener(eventName, listener, false);
+
+ var newEvent = document.createEvent("MouseEvent");
+ newEvent.initMouseEvent(eventName, true, true, window, 0, 0, 0, 0, 0,
+ false, false, false, false, 0, null);
+ target.dispatchEvent(newEvent);
+ target.removeEventListener(eventName, listener, false);
+
+ }
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+<span id="testTarget" style="border: 1px solid black;">testTarget</span>
+</body>
+</html>
diff --git a/dom/events/test/test_bug547996-2.xhtml b/dom/events/test/test_bug547996-2.xhtml
new file mode 100644
index 000000000..52ee9a06e
--- /dev/null
+++ b/dom/events/test/test_bug547996-2.xhtml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=547996
+-->
+<head>
+ <title>Test for Bug 547996</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=547996">Mozilla Bug 547996</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+<script type="application/javascript"><![CDATA[
+
+/** Test for Bug 547996 **/
+/* mouseEvent.mozInputSource attribute */
+
+var expectedInputSource = null;
+
+function check(event) {
+ is(event.mozInputSource, expectedInputSource, ".mozInputSource");
+}
+
+function doTest() {
+ setup();
+
+ expectedInputSource = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_KEYBOARD;
+ testKeyboard();
+
+ expectedInputSource = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE;
+ testMouse();
+
+ expectedInputSource = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_UNKNOWN;
+ testScriptedClicks();
+
+ cleanup();
+ SimpleTest.finish();
+}
+
+function testKeyboard() {
+
+ $("inputTarget").focus();
+ synthesizeKey("VK_SPACE", {});
+ synthesizeKey("VK_RETURN", {});
+
+ $("buttonTarget").focus();
+ synthesizeKey("VK_SPACE", {});
+ synthesizeKey("VK_RETURN", {});
+
+ //XUL buttons do not generate click on ENTER or SPACE,
+ //they do only on accessKey
+
+ $("anchorTarget").focus();
+ synthesizeKey("VK_RETURN", {});
+
+ synthesizeKey("VK_TAB", {});
+ synthesizeKey("VK_SPACE", {});
+ synthesizeKey("VK_RIGHT", {});
+
+ $("checkboxTarget").focus();
+ synthesizeKey("VK_SPACE", {});
+
+ var accessKeyDetails = (navigator.platform.indexOf("Mac") >= 0) ?
+ { ctrlKey : true } : { altKey : true, shiftKey: true };
+
+ synthesizeKey("o", accessKeyDetails);
+ synthesizeKey("t", accessKeyDetails);
+}
+
+function testMouse() {
+ synthesizeMouse($("inputTarget"), 0, 0, {});
+ synthesizeMouse($("buttonTarget"), 0, 0, {});
+ synthesizeMouse($("xulButtonTarget"), 0, 0, {});
+ synthesizeMouse($("anchorTarget"), 0, 0, {});
+ synthesizeMouse($("radioTarget1"), 0, 0, {});
+ synthesizeMouse($("radioTarget2"), 0, 0, {});
+ synthesizeMouse($("checkboxTarget"), 0, 0, {});
+}
+
+function testScriptedClicks() {
+ $("inputTarget").click();
+ $("buttonTarget").click();
+ $("xulButtonTarget").click();
+}
+
+function setup() {
+ $("inputTarget").addEventListener("click", check, false);
+ $("buttonTarget").addEventListener("click", check, false);
+ $("anchorTarget").addEventListener("click", check, false);
+ $("xulButtonTarget").addEventListener("click", check, false);
+ $("radioTarget1").addEventListener("click", check, false);
+ $("radioTarget2").addEventListener("click", check, false);
+ $("checkboxTarget").addEventListener("click", check, false);
+
+}
+
+function cleanup() {
+ $("inputTarget").removeEventListener("click", check, false);
+ $("buttonTarget").removeEventListener("click", check, false);
+ $("xulButtonTarget").removeEventListener("click", check, false);
+ $("anchorTarget").removeEventListener("click", check, false);
+ $("radioTarget1").removeEventListener("click", check, false);
+ $("radioTarget2").removeEventListener("click", check, false);
+ $("checkboxTarget").removeEventListener("click", check, false);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(doTest, window);
+
+]]></script>
+</pre>
+<input type="checkbox" id="checkboxTarget">Checkbox target</input>
+<input id="inputTarget" type="button" value="HTML Input" accesskey="o"/>
+<button id="buttonTarget">HTML Button</button>
+<xul:button id="xulButtonTarget" accesskey="t">XUL Button</xul:button>
+<a href="#" id="anchorTarget">Anchor</a>
+<input type="radio" id="radioTarget1" name="group">Radio Target 1</input>
+<input type="radio" id="radioTarget2" name="group">Radio Target 2</input>
+</body>
+</html>
diff --git a/dom/events/test/test_bug556493.html b/dom/events/test/test_bug556493.html
new file mode 100644
index 000000000..3a86ada65
--- /dev/null
+++ b/dom/events/test/test_bug556493.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=556493
+-->
+<head>
+ <title>Test for Bug 556493</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ div {
+ border: 1px solid;
+ }
+ </style>
+</head>
+<body onload="setTimeout(runTest, 0)">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=556493">Mozilla Bug 556493</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 556493 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var downCount = 0;
+var upCount = 0;
+var clickCount = 0;
+function runTest() {
+ var d0 = document.getElementById("d0");
+ var d1 = document.getElementById("d1");
+ var d2 = document.getElementById("d2");
+
+ d0.onmousedown = function(e) { ++downCount; };
+ d0.onmouseup = function(e) { ++upCount; }
+ d0.onclick = function(e) { ++clickCount; }
+
+ synthesizeMouse(d1, 3, 3, { type: "mousedown"});
+ synthesizeMouse(d1, 3, 3, { type: "mouseup"});
+
+ is(downCount, 1, "Wrong mousedown event count!");
+ is(upCount, 1, "Wrong mouseup event count!");
+ is(clickCount, 1, "Wrong click event count!");
+
+ synthesizeMouse(d1, 3, 3, { type: "mousedown"});
+ synthesizeMouse(d1, 30, 3, { type: "mouseup"});
+
+ is(downCount, 2, "Wrong mousedown event count!");
+ is(upCount, 2, "Wrong mouseup event count!");
+ is(clickCount, 2, "Wrong click event count!");
+
+ synthesizeMouse(d1, 3, 3, { type: "mousedown"});
+ synthesizeMouse(d2, 3, 3, { type: "mouseup"});
+
+ is(downCount, 3, "Wrong mousedown event count!");
+ is(upCount, 3, "Wrong mouseup event count!");
+ is(clickCount, 2, "Wrong click event count!");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<div id="d0">
+Test divs --
+<div id="d1">t</div><div id="d2">t</div>
+--
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug563329.html b/dom/events/test/test_bug563329.html
new file mode 100644
index 000000000..847c5b2a8
--- /dev/null
+++ b/dom/events/test/test_bug563329.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=563329
+-->
+<head>
+ <title>Test for Bug 563329</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=563329">Mozilla Bug 563329</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7">
+
+/** Test for Bug 563329 **/
+/* ui.click_hold_context_menus preference */
+
+var target = null;
+var tests = getTests();
+var currentTest = null;
+
+function getTests() {
+ let tests = [
+ { "func": function() { setTimeout(doCheckContextMenu, 100)}, "message": "Context menu should has fired"},
+ { "func": function() { setTimeout(doCheckDuration, 100)}, "message": "Context menu should has fired with delay"},
+ { "func": function() { setTimeout(finishTest, 100)}, "message": "" }
+ ];
+
+ let i = 0;
+ while (i < tests.length)
+ yield tests[i++];
+}
+
+function doTest() {
+ target = document.getElementById("testTarget");
+
+ document.documentElement.addEventListener("contextmenu", function() {
+ SimpleTest.ok(true, currentTest.message);
+ synthesizeMouse(target, 0, 0, {type: "mouseup"});
+ SimpleTest.executeSoon(function() {
+ currentTest = tests.next();
+ currentTest.func();
+ });
+ }, false);
+
+ SimpleTest.executeSoon(function() {
+ currentTest = tests.next();
+ currentTest.func();
+ });
+}
+
+function doCheckContextMenu() {
+ synthesizeMouse(target, 0, 0, {type: "mousedown"});
+}
+
+function doCheckDuration() {
+ var duration = 50;
+
+ // Change click hold delay
+ SpecialPowers.pushPrefEnv({"set":[["ui.click_hold_context_menus.delay", duration]]}, function() { synthesizeMouse(target, 0, 0, {type: "mousedown"}); });
+}
+
+function finishTest() {
+ synthesizeKey("VK_ESCAPE", {}, window);
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ SpecialPowers.pushPrefEnv({"set":[["ui.click_hold_context_menus", true]]}, doTest);
+});
+</script>
+</pre>
+<span id="testTarget" style="border: 1px solid black;">testTarget</span>
+</body>
+</html>
diff --git a/dom/events/test/test_bug574663.html b/dom/events/test/test_bug574663.html
new file mode 100644
index 000000000..23c572590
--- /dev/null
+++ b/dom/events/test/test_bug574663.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=574663
+-->
+<head>
+ <title>Test for Bug 574663</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=574663">Mozilla Bug 574663</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7">
+
+/** Test for Bug 574663 **/
+
+// SimpleTest's paint_listener does not work on other windows, so we inline
+// a smaller version here.
+function waitForPaint(win, utils, callback) {
+ win.document.documentElement.getBoundingClientRect();
+ if (!utils.isMozAfterPaintPending) {
+ callback();
+ return;
+ }
+
+ var onpaint = function() {
+ if (!utils.isMozAfterPaintPending) {
+ win.removeEventListener("MozAfterPaint", onpaint);
+ callback();
+ return;
+ }
+ if (utils.isTestControllingRefreshes) {
+ utils.advanceTimeAndRefresh(0);
+ }
+ }
+ win.addEventListener("MozAfterPaint", onpaint);
+ if (utils.isTestControllingRefreshes) {
+ utils.advanceTimeAndRefresh(0);
+ }
+}
+
+function forceScrollAndWait(scrollbox, callback) {
+ let win = scrollbox.ownerDocument.defaultView;
+ let utils = SpecialPowers.getDOMWindowUtils(win);
+
+ utils.advanceTimeAndRefresh(1000);
+
+ let postApzFlush = function() {
+ SpecialPowers.Services.obs.removeObserver(postApzFlush, "apz-repaints-flushed", false);
+ waitForPaint(win, utils, callback);
+ }
+ SpecialPowers.Services.obs.addObserver(postApzFlush, "apz-repaints-flushed", false);
+ if (!utils.flushApzRepaints()) {
+ postApzFlush();
+ }
+}
+
+function sendTouchpadScrollMotion(scrollbox, direction, ctrl, momentum, callback) {
+ var win = scrollbox.ownerDocument.defaultView;
+ let event = {
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaY: direction * 3,
+ lineOrPageDeltaY: direction,
+ ctrlKey: ctrl,
+ isMomentum: momentum
+ };
+
+ let kExtraEvents = 5;
+
+ var received = 0;
+ var onwheel = function() {
+ if (++received == 1 + kExtraEvents) {
+ // We have captured all the outstanding wheel events. Wait for the
+ // animation to add itself to the refresh driver.
+ scrollbox.removeEventListener("wheel", onwheel);
+ setTimeout(function() {
+ forceScrollAndWait(scrollbox, callback);
+ }, 0);
+ }
+ };
+ scrollbox.addEventListener("wheel", onwheel);
+
+ synthesizeWheel(scrollbox, 10, 10, event, win);
+ // then 5 additional pixel scrolls
+ event.lineOrPageDeltaY = 0;
+ for (let i = 1; i <= kExtraEvents; ++i) {
+ synthesizeWheel(scrollbox, 10, 10, event, win);
+ }
+}
+
+function runTest() {
+ var win = open('data:text/html,<!DOCTYPE html>\n' +
+ '<div id="scrollbox" style="height: 100px; overflow: auto;">' +
+ ' <div style="height: 1000px;"></div>' +
+ '</div>', '_blank', 'width=300,height=300');
+ SimpleTest.waitForFocus(function () {
+ var scrollbox = win.document.getElementById("scrollbox");
+ let winUtils = SpecialPowers.getDOMWindowUtils(win);
+ let outstandingTests = [
+ [false, false],
+ [false, true],
+ [true, false],
+ [true, true],
+ ];
+
+ // grab the refresh driver, since we want to make sure
+ // async scrolls happen in deterministic time
+ winUtils.advanceTimeAndRefresh(1000);
+
+ function nextTest() {
+ let [ctrlKey, isMomentum] = outstandingTests.shift();
+ let scrollTopBefore = scrollbox.scrollTop;
+ let zoomFactorBefore = winUtils.fullZoom;
+
+ let check = function() {
+ if (!ctrlKey) {
+ let postfix = isMomentum ? ", even after releasing the touchpad" : "";
+ // Normal scroll: scroll
+ is(winUtils.fullZoom, zoomFactorBefore, "Normal scrolling shouldn't change zoom" + postfix);
+ isnot(scrollbox.scrollTop, scrollTopBefore, "Normal scrolling should scroll" + postfix);
+ } else {
+ if (!isMomentum) {
+ isnot(winUtils.fullZoom, zoomFactorBefore, "Ctrl-scrolling should zoom while the user is touching the touchpad");
+ is(scrollbox.scrollTop, scrollTopBefore, "Ctrl-scrolling shouldn't scroll while the user is touching the touchpad");
+ } else {
+ is(winUtils.fullZoom, zoomFactorBefore, "Momentum scrolling shouldn't zoom, even when pressing Ctrl");
+ isnot(scrollbox.scrollTop, scrollTopBefore, "Momentum scrolling should scroll, even when pressing Ctrl");
+ }
+ }
+
+ if (!outstandingTests.length) {
+ winUtils.restoreNormalRefresh();
+ win.close();
+ SimpleTest.finish();
+ return;
+ }
+
+ // Revert the effect for the next test.
+ sendTouchpadScrollMotion(scrollbox, -1, ctrlKey, isMomentum, function() {
+ setTimeout(nextTest, 0);
+ });
+ }
+
+ sendTouchpadScrollMotion(scrollbox, 1, ctrlKey, isMomentum, check);
+ }
+ nextTest();
+ }, win);
+}
+
+window.onload = function() {
+ SpecialPowers.pushPrefEnv({
+ "set":[["general.smoothScroll", false],
+ ["mousewheel.acceleration.start", -1],
+ ["mousewheel.system_scroll_override_on_root_content.enabled", false],
+ ["mousewheel.with_control.action", 3]]}, runTest);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug586961.xul b/dom/events/test/test_bug586961.xul
new file mode 100644
index 000000000..43ad5fb9b
--- /dev/null
+++ b/dom/events/test/test_bug586961.xul
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=586961
+-->
+<window title="Mozilla Bug 586961"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+<body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=586961">Mozilla Bug 586961</a>
+
+ <p id="display"></p>
+<div id="content" style="display: none">
+</div>
+</body>
+
+<box onclick="clicked(event)">
+ <label id="controllabel" control="controlbutton" accesskey="k" value="Click here" />
+ <button id="controlbutton" label="Button" />
+</box>
+
+<script class="testbody" type="application/javascript;version=1.7"><![CDATA[
+
+/** Test for Bug 586961 **/
+
+function clicked(event) {
+ is(event.target.id, "controlbutton", "Accesskey was directed to controlled element.");
+ SimpleTest.finish();
+}
+
+function test() {
+ var accessKeyDetails = (navigator.platform.indexOf("Mac") >= 0) ?
+ { altKey : true, ctrlKey : true } :
+ { altKey : true, shiftKey: true };
+ synthesizeKey("k", accessKeyDetails);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(test, window);
+
+]]></script>
+
+</window>
diff --git a/dom/events/test/test_bug591249.xul b/dom/events/test/test_bug591249.xul
new file mode 100644
index 000000000..d57c02e66
--- /dev/null
+++ b/dom/events/test/test_bug591249.xul
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=591249
+-->
+<window title="Mozilla Bug 591249" onload="RunTest()"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=591249">Mozilla Bug 591249</a>
+ <img id="image"
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"
+ ondragstart="event.preventDefault();"/>
+ <iframe id="iframe" src="chrome://mochitests/content/chrome/dom/events/test/bug591249_iframe.xul" style="height: 300px; width: 100%;"></iframe>
+</body>
+
+<script class="testbody" type="application/javascript;version=1.8"><![CDATA[
+/** Test for Bug 591249 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function completeTest(aBox) {
+ ok(window.getComputedStyle(aBox).backgroundColor == "rgb(255, 0, 0)", "The -moz-drag-over style should be removed.");
+ SimpleTest.finish();
+}
+
+function fireEvent(target, event) {
+ var win = target.ownerDocument.defaultView;
+ var utils =
+ win.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
+ getInterface(Components.interfaces.nsIDOMWindowUtils);
+ utils.dispatchDOMEventViaPresShell(target, event, true);
+}
+
+function RunTest() {
+ var image = document.getElementById("image");
+ var iframe = document.getElementById("iframe");
+ var iBox = iframe.contentDocument.getElementById("drop-target");
+ var insideBoxX = iBox.offsetWidth + 10;
+ var insideBoxY = iBox.offsetHeight + 10;
+
+ var dataTransfer;
+ var trapDrag = function(event) {
+ dataTransfer = event.dataTransfer;
+ dataTransfer.setData("text/plain", "Hello");
+ dataTransfer.dropEffect = "move";
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ // need to use real mouse action to get the dataTransfer
+ window.addEventListener("dragstart", trapDrag, true);
+ synthesizeMouse(image, 2, 2, { type: "mousedown" });
+ synthesizeMouse(image, 11, 11, { type: "mousemove" });
+ synthesizeMouse(image, 20, 20, { type: "mousemove" });
+ window.removeEventListener("dragstart", trapDrag, true);
+ synthesizeMouse(image, 20, 20, { type: "mouseup" });
+
+ var event = document.createEvent("DragEvent");
+ event.initDragEvent("dragover", true, true, iBox.ownerDocument.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, iBox, dataTransfer);
+ fireEvent(iBox, event);
+ synthesizeMouse(image, 3, 3, { type: "mousedown" });
+ synthesizeMouse(image, 23, 23, { type: "mousemove" });
+ synthesizeMouse(iBox, insideBoxX, insideBoxY, { type: "mousemove" });
+ ok(window.getComputedStyle(iBox).backgroundColor == "rgb(255, 255, 0)", "The -moz-drag-over style should be applied.");
+ synthesizeMouse(iBox, insideBoxX, insideBoxY, { type: "mouseup" });
+ window.setTimeout(function () { completeTest(iBox); }, 40);
+}
+]]></script>
+
+</window>
diff --git a/dom/events/test/test_bug591815.html b/dom/events/test/test_bug591815.html
new file mode 100644
index 000000000..f7e5c5050
--- /dev/null
+++ b/dom/events/test/test_bug591815.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=591815
+-->
+<head>
+ <title>Test for Bug 591815</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="setTimeout(runTest, 0)">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=591815">Mozilla Bug 591815</a>
+<p id="display"></p>
+<div id="content">
+ <div id="wrapper">
+ <!-- 20x20 of red -->
+ <img id="image" ondragstart="fail();"
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC"/>
+ </div>
+</div>
+<pre id="test">
+
+<script type="application/javascript">
+
+/** Test for Bug 591815 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function fail() {
+ ok(false, "drag started but should not have");
+}
+
+function runTest() {
+ var image = document.getElementById("image");
+ var wrapper = document.getElementById("wrapper");
+ var preventDefault = function(event) {
+ event.preventDefault();
+ };
+ wrapper.addEventListener('mousedown', preventDefault, false);
+
+ synthesizeMouse(image, 3, 3, { type: "mousedown"});
+ synthesizeMouse(image, 53, 53, { type: "mousemove"});
+ synthesizeMouse(image, 53, 53, { type: "mouseup"});
+
+ wrapper.removeEventListener('mousedown', preventDefault, false);
+
+ var relocateElementAndPreventDefault = function(event) {
+ document.body.appendChild(wrapper);
+ event.preventDefault();
+ }
+ wrapper.addEventListener('mousedown', relocateElementAndPreventDefault, false);
+
+ synthesizeMouse(image, 3, 3, { type: "mousedown"});
+ synthesizeMouse(image, 53, 53, { type: "mousemove"});
+ synthesizeMouse(image, 53, 53, { type: "mouseup"});
+
+ wrapper.removeEventListener('mousedown', relocateElementAndPreventDefault, false);
+
+ ok(true, "passed the test");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug593959.html b/dom/events/test/test_bug593959.html
new file mode 100644
index 000000000..933616744
--- /dev/null
+++ b/dom/events/test/test_bug593959.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=593959
+-->
+<head>
+ <title>Test for Bug 593959</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ body:active {
+ background: red;
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=593959">Mozilla Bug 593959</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 593959 **/
+
+ function doTest() {
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+ var e = document.createEvent("MouseEvent");
+ e.initEvent("mousedown", false, false, window, 0, 1, 1, 1, 1,
+ false, false, false, false, 0, null);
+ utils.dispatchDOMEventViaPresShell(document.body, e, true);
+
+ is(document.querySelector("body:active"), document.body, "body should be active!")
+
+ var ifrwindow = document.getElementById("ifr").contentWindow;
+
+ var utils2 = SpecialPowers.getDOMWindowUtils(ifrwindow);
+
+ var e2 = ifrwindow.document.createEvent("MouseEvent");
+ e2.initEvent("mouseup", false, false, ifrwindow, 0, 1, 1, 1, 1,
+ false, false, false, false, 0, null);
+ utils2.dispatchDOMEventViaPresShell(ifrwindow.document.body, e2, true);
+
+ isnot(document.querySelector("body:active"), document.body, "body shouldn't be active!")
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(doTest);
+
+
+
+</script>
+</pre>
+<iframe id="ifr"></iframe>
+</body>
+</html>
diff --git a/dom/events/test/test_bug602962.xul b/dom/events/test/test_bug602962.xul
new file mode 100644
index 000000000..cc500d132
--- /dev/null
+++ b/dom/events/test/test_bug602962.xul
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=602962
+-->
+<window title="Mozilla Bug 602962" onload="openWindow()"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602962">Mozilla Bug 602962</a>
+ <p id="display"></p>
+<div id="content" style="display: none">
+</div>
+</body>
+
+<script class="testbody" type="application/javascript;version=1.8"><![CDATA[
+/** Test for Bug 602962 **/
+var scrollbox, sbo, content;
+var scrollX = 0, scrollY = 0;
+
+var oldWidth = 0, oldHeight = 0;
+var win = null;
+
+function openWindow() {
+ win = window.open("chrome://mochitests/content/chrome/dom/events/test/bug602962.xul", "_blank", "width=600,height=600");
+}
+
+function doTest() {
+ scrollbox = win.document.getElementById("page-scrollbox");
+ sbo = scrollbox.boxObject;
+ content = win.document.getElementById("page-box");
+ content.style.width = 400 + "px";
+
+ win.addEventListener("resize", function() {
+ win.removeEventListener("resize", arguments.callee, false);
+
+ setTimeout(function(){
+ sbo.scrollBy(200, 0);
+ resize();
+ },0);
+ }, false);
+
+ oldWidth = win.outerWidth;
+ oldHeight = win.outerHeight;
+ win.resizeTo(200, 400);
+}
+
+function resize() {
+ scrollX = sbo.positionX;
+ scrollY = sbo.positionY;
+
+ win.addEventListener("resize", function() {
+ content.style.width = (oldWidth + 400) + "px";
+ win.removeEventListener("resize", arguments.callee, true);
+
+ setTimeout(function() {
+ finish();
+ }, 0);
+ }, true);
+
+ win.resizeTo(oldWidth, oldHeight);
+}
+
+function finish() {
+ if (win.outerWidth != oldWidth ||
+ win.outerHeight != oldHeight) {
+ // We should eventually get back to the original size.
+ setTimeout(finish, 0);
+ return;
+ }
+ sbo.scrollBy(scrollX, scrollY);
+
+ is(sbo.positionX, 200, "Scroll X should have been restored to the value before the resize");
+ is(sbo.positionY, 0, "Scroll Y should have been restored to the value before the resize");
+
+ is(win.outerWidth, oldWidth, "Width should be resized");
+ is(win.outerHeight, oldHeight, "Height should be resized");
+ win.close();
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+]]></script>
+
+</window>
diff --git a/dom/events/test/test_bug603008.html b/dom/events/test/test_bug603008.html
new file mode 100644
index 000000000..786f68412
--- /dev/null
+++ b/dom/events/test/test_bug603008.html
@@ -0,0 +1,556 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=508906
+-->
+<head>
+ <title>Test for Bug 603008</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=508906">Mozilla Bug 603008</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.8">
+
+/** Test for Bug 306008 - Touch* Events **/
+
+let tests = [], testTarget, parent;
+
+let touch = {
+ id: 0,
+ point: {x: 0, y: 0},
+ radius: {x: 0, y: 0},
+ rotation: 0,
+ force: 0.5,
+ target: null
+}
+
+function nextTest() {
+ if (tests.length)
+ SimpleTest.executeSoon(tests.shift());
+}
+
+function random() {
+ return Math.floor(Math.random() * 100);
+}
+
+function checkEvent(aFakeEvent) {
+ return function(aEvent) {
+ is(aFakeEvent.ctrlKey, aEvent.ctrlKey, "Correct ctrlKey");
+ is(aFakeEvent.altKey, aEvent.altKey, "Correct altKey");
+ is(aFakeEvent.shiftKey, aEvent.shiftKey, "Correct shiftKey");
+ is(aFakeEvent.metaKey, aEvent.metaKey, "Correct metaKey");
+ checkTouches(aFakeEvent.touches, aEvent.touches);
+ checkTouches(aFakeEvent.targetTouches, aEvent.targetTouches);
+ checkTouches(aFakeEvent.changedTouches, aEvent.changedTouches);
+ }
+}
+
+function checkTouches(aTouches1, aTouches2) {
+ is(aTouches1.length, aTouches2.length, "Correct touches length");
+ for (var i = 0; i < aTouches1.length; i++) {
+ checkTouch(aTouches1[i], aTouches2[i]);
+ }
+}
+
+function checkTouch(aFakeTouch, aTouch) {
+ is(aFakeTouch.identifier, aTouch.identifier, "Touch has correct identifier");
+ is(aFakeTouch.target, aTouch.target, "Touch has correct target");
+ is(aFakeTouch.page.x, aTouch.pageX, "Touch has correct pageX");
+ is(aFakeTouch.page.y, aTouch.pageY, "Touch has correct pageY");
+ is(aFakeTouch.page.x + Math.round(window.mozInnerScreenX), aTouch.screenX, "Touch has correct screenX");
+ is(aFakeTouch.page.y + Math.round(window.mozInnerScreenY), aTouch.screenY, "Touch has correct screenY");
+ is(aFakeTouch.page.x, aTouch.clientX, "Touch has correct clientX");
+ is(aFakeTouch.page.y, aTouch.clientY, "Touch has correct clientY");
+ is(aFakeTouch.radius.x, aTouch.radiusX, "Touch has correct radiusX");
+ is(aFakeTouch.radius.y, aTouch.radiusY, "Touch has correct radiusY");
+ is(aFakeTouch.rotationAngle, aTouch.rotationAngle, "Touch has correct rotationAngle");
+ is(aFakeTouch.force, aTouch.force, "Touch has correct force");
+}
+
+function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) {
+ var ids = [], xs=[], ys=[], rxs = [], rys = [],
+ rotations = [], forces = [];
+
+ for (var touchType of ["touches", "changedTouches", "targetTouches"]) {
+ for (var i = 0; i < aEvent[touchType].length; i++) {
+ if (ids.indexOf(aEvent[touchType][i].identifier) == -1) {
+ ids.push(aEvent[touchType][i].identifier);
+ xs.push(aEvent[touchType][i].page.x);
+ ys.push(aEvent[touchType][i].page.y);
+ rxs.push(aEvent[touchType][i].radius.x);
+ rys.push(aEvent[touchType][i].radius.y);
+ rotations.push(aEvent[touchType][i].rotationAngle);
+ forces.push(aEvent[touchType][i].force);
+ }
+ }
+ }
+ return windowUtils.sendTouchEvent(aType,
+ ids, xs, ys, rxs, rys,
+ rotations, forces,
+ ids.length, aModifiers, 0);
+}
+
+function touchEvent(aOptions) {
+ if (!aOptions) {
+ aOptions = {};
+ }
+ this.ctrlKey = aOptions.ctrlKey || false;
+ this.altKey = aOptions.altKey || false;
+ this.shiftKey = aOptions.shiftKey || false;
+ this.metaKey = aOptions.metaKey || false;
+ this.touches = aOptions.touches || [];
+ this.targetTouches = aOptions.targetTouches || [];
+ this.changedTouches = aOptions.changedTouches || [];
+}
+
+function testtouch(aOptions) {
+ if (!aOptions)
+ aOptions = {};
+ this.identifier = aOptions.identifier || 0;
+ this.target = aOptions.target || 0;
+ this.page = aOptions.page || {x: 0, y: 0};
+ this.radius = aOptions.radius || {x: 0, y: 0};
+ this.rotationAngle = aOptions.rotationAngle || 0;
+ this.force = aOptions.force || 1;
+}
+
+function testSingleTouch(name) {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction = checkEvent(event);
+ window.addEventListener("touchstart", checkFunction, false);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction, false);
+
+ // test touchmove event fires correctly
+ event.touches[0].page.x -= 1;
+ event.targetTouches[0].page.x -= 1;
+ event.changedTouches[0].page.x -= 1;
+ checkFunction = checkEvent(event);
+ window.addEventListener("touchmove", checkFunction, false);
+ sendTouchEvent(cwu, "touchmove", event, 0);
+ window.removeEventListener("touchmove", checkFunction, false);
+
+ // test touchend event fires correctly
+ event.touches = [];
+ event.targetTouches = [];
+ checkFunction = checkEvent(event);
+ window.addEventListener("touchend", checkFunction, false);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ window.removeEventListener("touchend", checkFunction, false);
+
+ nextTest();
+}
+
+function testSingleTouch2(name) {
+ // firing a touchstart that includes only one touch will evict any touches in the queue with touchend messages
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ identifier: 0,
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target
+ });
+ let event1 = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+ let touch2 = new testtouch({
+ identifier: 1,
+ page: {x: Math.round(bcr2.left + bcr2.width/2),
+ y: Math.round(bcr2.top + bcr2.height/2)},
+ target: target2
+ });
+ let event2 = new touchEvent({
+ touches: [touch2],
+ targetTouches: [touch2],
+ changedTouches: [touch2]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction1 = checkEvent(event1);
+ window.addEventListener("touchstart", checkFunction1, false);
+ sendTouchEvent(cwu, "touchstart", event1, 0);
+ window.removeEventListener("touchstart", checkFunction1, false);
+
+ event1.touches = [];
+ event1.targetTouches = [];
+ checkFunction1 = checkEvent(event1);
+ var checkFunction2 = checkEvent(event2);
+
+ window.addEventListener("touchend", checkFunction1, false);
+ window.addEventListener("touchstart", checkFunction2, false);
+ sendTouchEvent(cwu, "touchstart", event2, 0);
+ window.removeEventListener("touchend", checkFunction1, false);
+ window.removeEventListener("touchstart", checkFunction2, false);
+
+ sendTouchEvent(cwu, "touchstart", event1, 0);
+
+ nextTest();
+}
+
+
+function testMultiTouch(name) {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target1 = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target1.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ identifier: 0,
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target1
+ });
+ let touch2 = new testtouch({
+ identifier: 1,
+ page: {x: Math.round(bcr2.left + bcr2.width/2),
+ y: Math.round(bcr2.top + bcr2.height/2)},
+ target: target2
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction = checkEvent(event);
+ window.addEventListener("touchstart", checkFunction, false);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction, false);
+
+ event.touches.push(touch2);
+ event.targetTouches = [touch2];
+ event.changedTouches = [touch2];
+ window.addEventListener("touchstart", checkFunction, false);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction, false);
+
+ // test moving one touch point
+ event.touches[0].page.x -= 1;
+ event.targetTouches = [event.touches[0]];
+ event.changedTouches = [event.touches[0]];
+ window.addEventListener("touchmove", checkFunction, false);
+ sendTouchEvent(cwu, "touchmove", event, 0);
+ window.removeEventListener("touchmove", checkFunction, false);
+
+ // test moving both touch points -- two touchmove events should fire, one on each target
+ event.touches[0].page.x -= 1;
+ event.touches[1].page.x -= 1;
+ event.targetTouches = event.touches;
+ event.changedTouches = event.touches;
+ var touchMoveEvents = 0;
+ var checkFunction2 = function(aEvent) {
+ is(event.ctrlKey, aEvent.ctrlKey, "Correct ctrlKey");
+ is(event.altKey, aEvent.altKey, "Correct altKey");
+ is(event.shiftKey, aEvent.shiftKey, "Correct shiftKey");
+ is(event.metaKey, aEvent.metaKey, "Correct metaKey");
+ checkTouches(event.touches, aEvent.touches);
+ checkTouches(event.changedTouches, aEvent.changedTouches);
+ if (aEvent.targetTouches[0].target == target1) {
+ checkTouches([event.touches[0]], aEvent.targetTouches);
+ } else if (aEvent.targetTouches[0].target == target2) {
+ checkTouches([event.touches[1]], aEvent.targetTouches);
+ } else
+ ok(false, "Event target is incorrect: " + event.targetTouches[0].target.nodeName + "#" + event.targetTouches[0].target.id);
+ touchMoveEvents++;
+ };
+ window.addEventListener("touchmove", checkFunction2, false);
+ sendTouchEvent(cwu, "touchmove", event, 0);
+ ok(touchMoveEvents, 2, "Correct number of touchmove events fired");
+ window.removeEventListener("touchmove", checkFunction2, false);
+
+ // test removing just one finger
+ var expected = new touchEvent({
+ touches: [touch2],
+ targetTouches: [],
+ changedTouches: [touch1]
+ });
+ checkFunction = checkEvent(expected);
+
+ event.touches = [];
+ event.targetTouches = [];
+ event.changedTouches = [touch1];
+
+ // test removing the other finger
+ window.addEventListener("touchend", checkFunction, false);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ window.removeEventListener("touchend", checkFunction, false);
+
+ event.touches = [];
+ event.targetTouches = [];
+ event.changedTouches = [touch2];
+ checkFunction = checkEvent(event);
+ window.addEventListener("touchend", checkFunction, false);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ window.removeEventListener("touchend", checkFunction, false);
+
+ nextTest();
+}
+
+function testTouchChanged() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target1 = document.getElementById("testTarget");
+ let bcr = target1.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ identifier: 0,
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target1
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ var checkFunction = checkEvent(event);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+
+ var moveEvents = 0;
+ function onMove(aEvent) {
+ moveEvents++;
+ }
+
+ window.addEventListener("touchmove", onMove, false);
+
+ // the first touchmove should always fire an event
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // changing nothing should not fire a touchmove event
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test moving x
+ event.touches[0].page.x -= 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test moving y
+ event.touches[0].page.y -= 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing y radius
+ event.touches[0].radius.y += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing x radius
+ event.touches[0].radius.x += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing rotationAngle
+ event.touches[0].rotationAngle += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // test changing force
+ event.touches[0].force += 1;
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ // changing nothing again
+ sendTouchEvent(cwu, "touchmove", event, 0);
+
+ is(moveEvents, 7, "Six move events fired");
+
+ window.removeEventListener("touchmove", onMove, false);
+ sendTouchEvent(cwu, "touchend", event, 0);
+ nextTest();
+}
+
+function testPreventDefault() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let target2 = document.getElementById("testTarget2");
+ let bcr = target.getBoundingClientRect();
+ let bcr2 = target2.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: bcr.left + bcr.width/2,
+ y: bcr.top + bcr.height/2},
+ target: target
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ let preventFunction = function(aEvent) {
+ aEvent.preventDefault();
+ }
+
+ let tests = [
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: true, doPrevent: true },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: true, doPrevent: true },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false, doPrevent: true },
+ { name: "touchend", prevent: false }],
+ [{ name: "touchstart", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchmove", prevent: false },
+ { name: "touchend", prevent: true, doPrevent: true }]
+ ];
+
+ var dotest = function(aTest) {
+ if (aTest.doPrevent) {
+ target.addEventListener(aTest.name, preventFunction, false);
+ }
+
+ if (aTest.name == "touchmove") {
+ touch1.page.x++;
+ event.touches[0] = touch1;
+ }
+
+ is(sendTouchEvent(cwu, aTest.name, event, 0), aTest.prevent, "Got correct status");
+
+ if (aTest.doPrevent)
+ target.removeEventListener(aTest.name, preventFunction, false);
+ }
+
+ for (var i = 0; i < tests.length; i++) {
+ for (var j = 0; j < tests[i].length; j++) {
+ dotest(tests[i][j]);
+ }
+ }
+
+ nextTest();
+}
+
+function testRemovingElement() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let bcr = document.getElementById("testTarget").getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: bcr.left + bcr.width/2,
+ y: bcr.top + bcr.height/2},
+ });
+ let e = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ var touchEvents = 0;
+ var removeTarget = function(aEvent) {
+ aEvent.target.parentNode.removeChild(aEvent.target);
+ };
+
+ var checkTarget = function(aEvent) {
+ is(aEvent.target, target, "Event has correct target");
+ touchEvents++;
+ };
+
+ target.addEventListener("touchstart", removeTarget, false);
+ target.addEventListener("touchmove", checkTarget, false);
+ target.addEventListener("touchend", checkTarget, false);
+
+ sendTouchEvent(cwu, "touchstart", e, 0);
+
+ e.touches[0].page.x++;
+ sendTouchEvent(cwu, "touchmove", e, 0);
+ sendTouchEvent(cwu, "touchend", e, 0);
+
+ target.removeEventListener("touchstart", removeTarget, false);
+ target.removeEventListener("touchmove", checkTarget, false);
+ target.removeEventListener("touchend", checkTarget, false);
+
+ is(touchEvents, 2, "Check target was called twice");
+
+ nextTest();
+}
+
+function testNAC() {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget3");
+ let bcr = target.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target
+ });
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkFunction = checkEvent(event);
+ window.addEventListener("touchstart", checkFunction, false);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+ window.removeEventListener("touchstart", checkFunction, false);
+
+ sendTouchEvent(cwu, "touchend", event, 0);
+
+ nextTest();
+}
+
+function doTest() {
+ tests.push(testSingleTouch);
+ tests.push(testSingleTouch2);
+ tests.push(testMultiTouch);
+ tests.push(testPreventDefault);
+ tests.push(testTouchChanged);
+ tests.push(testRemovingElement);
+ tests.push(testNAC);
+
+ tests.push(function() {
+ SimpleTest.finish();
+ });
+
+ nextTest();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+<div id="parent">
+ <span id="testTarget" style="padding: 5px; border: 1px solid black;">testTarget</span>
+ <span id="testTarget2" style="padding: 5px; border: 1px solid blue;">testTarget</span>
+ <input type="text" id="testTarget3">
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug605242.html b/dom/events/test/test_bug605242.html
new file mode 100644
index 000000000..f8f9354d5
--- /dev/null
+++ b/dom/events/test/test_bug605242.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=605242
+-->
+<head>
+ <title>Test for Bug 605242</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="setTimeout('runTest()', 0)">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=605242">Mozilla Bug 605242</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 605242 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var utils = SpecialPowers.getDOMWindowUtils(window);
+function sendMouseDown(el) {
+ var rect = el.getBoundingClientRect();
+ utils.sendMouseEvent('mousedown', rect.left + 5, rect.top + 5, 0, 1, 0);
+}
+
+function sendMouseUp(el) {
+ var rect = el.getBoundingClientRect();
+ utils.sendMouseEvent('mouseup', rect.left + 5, rect.top + 5, 0, 1, 0);
+}
+
+function runTest() {
+ var b = document.getElementById("testbutton");
+ sendMouseDown(b);
+ var l = document.querySelectorAll(":active");
+
+ var contains = false;
+ for (var i = 0; i < l.length; ++i) {
+ if (l[i] == b) {
+ contains = true;
+ }
+ }
+
+ ok(contains, "Wrong active content! \n");
+ sendMouseUp(b);
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<button id="testbutton">A button</button>
+<pre id="log">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug607464.html b/dom/events/test/test_bug607464.html
new file mode 100644
index 000000000..ac8076bfd
--- /dev/null
+++ b/dom/events/test/test_bug607464.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=607464
+-->
+<head>
+ <title>Test for Bug 607464</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=607464">Mozilla Bug 607464</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.7">
+
+/**
+ * Test for Bug 607464:
+ * Pixel scrolling shouldn't scroll smoothly, even if general.smoothScroll is on.
+ **/
+
+function scrollDown150PxWithPixelScrolling(scrollbox) {
+ var win = scrollbox.ownerDocument.defaultView;
+ let event = {
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaY: 30.0,
+ lineOrPageDeltaY: 1
+ };
+ // A pixel scroll with lineOrPageDeltaY.
+ synthesizeWheel(scrollbox, 10, 10, event, win);
+ // then 4 pixel scrolls without lineOrPageDeltaY.
+ event.lineOrPageDeltaY = 0;
+ for (let i = 0; i < 4; ++i) {
+ synthesizeWheel(scrollbox, 10, 10, event, win);
+ }
+
+ // Note: the line scroll shouldn't have any effect because it has
+ // hasPixels = true set on it. We send it to emulate normal
+ // behavior.
+}
+
+function runTest() {
+ var win = open('data:text/html,<!DOCTYPE html>\n' +
+ '<div id="scrollbox" style="height: 100px; overflow: auto;">' +
+ ' <div style="height: 1000px;"></div>' +
+ '</div>', '_blank', 'width=300,height=300');
+ SimpleTest.waitForFocus(function () {
+ var scrollbox = win.document.getElementById("scrollbox");
+ let scrollTopBefore = scrollbox.scrollTop;
+
+ win.addEventListener("scroll", function(e) {
+ is(scrollbox.scrollTop % 30, 0,
+ "Pixel scrolling should happen instantly, not smoothly. The " +
+ "scroll position " + scrollbox.scrollTop + " in this sequence of wheel " +
+ "events should be a multiple of 30.");
+ if (scrollbox.scrollTop == 150) {
+ win.close();
+ SimpleTest.finish();
+ }
+ }, true);
+
+ flushApzRepaints(function() {
+ scrollDown150PxWithPixelScrolling(scrollbox);
+ }, win);
+ }, win);
+}
+
+window.onload = function() {
+ SpecialPowers.pushPrefEnv({
+ "set":[["general.smoothScroll", true],
+ ["mousewheel.acceleration.start", -1],
+ ["mousewheel.system_scroll_override_on_root_content.enabled", false]]}, runTest);
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.testInChaosMode();
+
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug613634.html b/dom/events/test/test_bug613634.html
new file mode 100644
index 000000000..540df5c90
--- /dev/null
+++ b/dom/events/test/test_bug613634.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=613634
+-->
+<head>
+ <title>Test for Bug 613634</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=613634">Mozilla Bug 613634</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 613634 **/
+
+var eventCount = 0;
+function l(e) {
+ if (e.eventPhase != Event.CAPTURING_PHASE) {
+ ++eventCount;
+ } else {
+ ok(false, "Listener shouldn't be called!");
+ }
+}
+
+var d1 = document.createElement("div");
+var d2 = document.createElement("div");
+
+d1.appendChild(d2);
+
+var x = new XMLHttpRequest();
+
+try {
+d1.addEventListener("foo", l);
+document.addEventListener("foo", l);
+window.addEventListener("foo", l);
+x.addEventListener("foo", l);
+} catch(ex) {
+ ok(false, "Shouldn't throw " + ex);
+}
+
+var ev = document.createEvent("Event");
+ev.initEvent("foo", true, true);
+d2.dispatchEvent(ev);
+is(eventCount, 1, "Event listener should have been called!");
+
+ev = document.createEvent("Event");
+ev.initEvent("foo", false, false);
+d2.dispatchEvent(ev);
+is(eventCount, 1, "Event listener shouldn't have been called!");
+
+d1.removeEventListener("foo", l);
+ev = document.createEvent("Event");
+ev.initEvent("foo", true, true);
+d2.dispatchEvent(ev);
+is(eventCount, 1, "Event listener shouldn't have been called!");
+
+
+ev = document.createEvent("Event");
+ev.initEvent("foo", true, true);
+document.body.dispatchEvent(ev);
+is(eventCount, 3, "Event listener should have been called on document and window!");
+
+document.removeEventListener("foo", l);
+window.removeEventListener("foo", l, false);
+ev = document.createEvent("Event");
+ev.initEvent("foo", true, true);
+document.body.dispatchEvent(ev);
+is(eventCount, 3, "Event listener shouldn't have been called on document and window!");
+
+ev = document.createEvent("Event");
+ev.initEvent("foo", true, true);
+x.dispatchEvent(ev);
+is(eventCount, 4, "Event listener should have been called on XMLHttpRequest!");
+
+x.removeEventListener("foo", l);
+ev = document.createEvent("Event");
+ev.initEvent("foo", true, true);
+x.dispatchEvent(ev);
+is(eventCount, 4, "Event listener shouldn't have been called on XMLHttpRequest!");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug615597.html b/dom/events/test/test_bug615597.html
new file mode 100644
index 000000000..4f0eaeecf
--- /dev/null
+++ b/dom/events/test/test_bug615597.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=615597
+-->
+<head>
+ <title>Test for Bug 615597</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=615597">Mozilla Bug 615597</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 615597 **/
+
+window.addEventListener("deviceorientation", function(event) {
+ is(event.alpha, 1.5);
+ is(event.beta, 2.25);
+ is(event.gamma, 3.667);
+ is(event.absolute, true);
+}, true);
+
+var event = DeviceOrientationEvent;
+ok(!!event, "Should have seen DeviceOrientationEvent!");
+
+event = document.createEvent("DeviceOrientationEvent");
+event.initDeviceOrientationEvent('deviceorientation', true, true, 1.5, 2.25, 3.667, true);
+window.dispatchEvent(event);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug617528.xul b/dom/events/test/test_bug617528.xul
new file mode 100644
index 000000000..83038b36b
--- /dev/null
+++ b/dom/events/test/test_bug617528.xul
@@ -0,0 +1,95 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=617528
+-->
+<window title="Mozilla Bug 617528"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=617528"
+ target="_blank">Mozilla Bug 617528</a>
+ </body>
+
+ <script type="application/javascript"><![CDATA[
+ var _window;
+ var browser;
+
+ function start() {
+ _window = window.open("window_bug617528.xul", "_new", "chrome");
+ _window.addEventListener("load", onLoad, false);
+ }
+
+ function onLoad() {
+ _window.removeEventListener("load", onLoad, false);
+
+ browser = _window.document.getElementById("browser");
+ browser.addEventListener("pageshow", onPageShow, false);
+
+ var uri='data:text/html,\
+<html>\
+ <body>\
+ <div oncontextmenu="event.preventDefault()">\
+ <input id="node" type="text" value="Click here"></input>\
+ </div>\
+ </body>\
+</html>';
+ browser.loadURI(uri);
+ }
+
+ function onPageShow() {
+ browser.removeEventListener("pageshow", onPageShow, true);
+ SimpleTest.executeSoon(doTest);
+ }
+
+ function onContextMenu1(event) {
+ is(event.defaultPrevented, true,
+ "expected event.defaultPrevented to be true (1)");
+ is(event.target.localName, "input",
+ "expected event.target.localName to be 'input' (1)");
+ is(event.originalTarget.localName, "div",
+ "expected event.originalTarget.localName to be 'div' (1)");
+ }
+
+ function onContextMenu2(event) {
+ is(event.defaultPrevented, false,
+ "expected event.defaultPrevented to be false (2)");
+ is(event.target.localName, "input",
+ "expected event.target.localName to be 'input' (2)");
+ is(event.originalTarget.localName, "div",
+ "expected event.originalTarget.localName to be 'div' (2)");
+ }
+
+ function doTest() {
+ var win = browser.contentWindow;
+ win.focus();
+ var node = win.document.getElementById("node");
+ var rect = node.getBoundingClientRect();
+ var left = rect.left + rect.width / 2;
+ var top = rect.top + rect.height / 2;
+
+ var wu = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIDOMWindowUtils);
+
+ browser.addEventListener("contextmenu", onContextMenu1, false);
+ wu.sendMouseEvent("contextmenu", left, top, 2, 1, 0);
+ browser.removeEventListener("contextmenu", onContextMenu1, false);
+
+ browser.addEventListener("contextmenu", onContextMenu2, false);
+ var shiftMask = Components.interfaces.nsIDOMEvent.SHIFT_MASK;
+ wu.sendMouseEvent("contextmenu", left, top, 2, 1, shiftMask);
+ browser.removeEventListener("contextmenu", onContextMenu2, false);
+
+ _window.close();
+ SimpleTest.finish();
+ }
+
+ addLoadEvent(start);
+ SimpleTest.waitForExplicitFinish();
+ ]]></script>
+</window>
diff --git a/dom/events/test/test_bug624127.html b/dom/events/test/test_bug624127.html
new file mode 100644
index 000000000..269e1f62d
--- /dev/null
+++ b/dom/events/test/test_bug624127.html
@@ -0,0 +1,35 @@
+<html>
+<head>
+ <title>Test for Bug 624127</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="setTimeout('runTest()', 0)">
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function runTest() {
+ synthesizeMouse($("text"), 2, 2, { type: "mousedown" });
+ synthesizeMouse(frames[0].document.body, 2, 2, { type: "mouseup" }, frames[0]);
+ synthesizeMouse($("text2"), 50, 8, { type: "mousemove" });
+
+ is(window.getSelection().toString(), "", "no selection made");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+
+<p id="text">Normal text</p>
+<iframe src="data:text/plain,text in iframe"></iframe>
+<p id="text2">Normal text</p>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug635465.html b/dom/events/test/test_bug635465.html
new file mode 100644
index 000000000..7bd0db2be
--- /dev/null
+++ b/dom/events/test/test_bug635465.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=635465
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 635465</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style type="text/css">
+ #item {
+ position: relative;
+ }
+ .s-menu-section-submenu {
+ position: absolute;
+ display: none;
+ }
+ .open .s-menu-section-submenu {
+ display: block;
+ }
+</style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=635465">Mozilla Bug 635465</a>
+<div id="display">
+ <div class="item" id="item"
+ onmouseover="showSubmenu(event)" onmouseout="hideSubmenu(event)">
+ <a href="#" id="firsthover">Hover me</a>
+ <div class="s-menu-section-submenu" id="menu">
+ <a href="#" id="secondhover">Now hover me</a>
+ </div>
+ </div>
+</div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+/** Test for Bug 635465 **/
+function showSubmenu(event) {
+ var item = document.getElementById('item');
+
+ var width = item.offsetWidth; // IT WORKS IF YOU REMOVE THIS LINE
+
+ item.className='open';
+}
+
+function hideSubmenu(event) {
+ document.getElementById('item').className='';
+}
+
+SimpleTest.waitForExplicitFinish();
+
+function executeTests() {
+ // First flush out layout of firsthover
+ ok($("firsthover").getBoundingClientRect().height > 0, true,
+ "Should have a nonzero height before hover");
+
+ // Now trigger a mouseover on firsthover
+ synthesizeMouseAtCenter($("firsthover"), { type: "mousemove" });
+
+ ok($("secondhover").getBoundingClientRect().height > 0, true,
+ "Should have a nonzero height for submenu after hover");
+
+ // Now determine where secondhover is hanging out
+ var rect = $("secondhover").getBoundingClientRect();
+ synthesizeMouseAtCenter($("secondhover"), { type: "mousemove" });
+
+ // And another mouseover one pixel to the right of where the center used to be
+ synthesizeMouseAtPoint(rect.left + rect.width/2 + 1,
+ rect.top + rect.height/2,
+ { type: "mousemove" });
+
+ ok($("secondhover").getBoundingClientRect().height > 0, true,
+ "Should have a nonzero height for submenu after second hover");
+
+ // And check computed display of the menu
+ is(getComputedStyle($("menu"), "").display, "block", "Should have block display");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForFocus(executeTests);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug641477.html b/dom/events/test/test_bug641477.html
new file mode 100644
index 000000000..2fdc43a5c
--- /dev/null
+++ b/dom/events/test/test_bug641477.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=641477
+-->
+<head>
+ <title>Test for Bug 641477</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=641477">Mozilla Bug 641477</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 641477 **/
+
+var didThrow = false;
+
+var e = document.createEvent("Event");
+try {
+ is(e.type, "", "Event type should be empty string before initialization");
+ document.dispatchEvent(e);
+} catch(ex) {
+ didThrow = (ex.name == "InvalidStateError" && ex.code == DOMException.INVALID_STATE_ERR);
+}
+
+ok(didThrow, "Should have thrown InvalidStateError!");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug648573.html b/dom/events/test/test_bug648573.html
new file mode 100644
index 000000000..0a4a9e7e3
--- /dev/null
+++ b/dom/events/test/test_bug648573.html
@@ -0,0 +1,109 @@
+<!-- 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/. -->
+
+<!DOCTYPE html>
+<html>
+ <!--
+ https://bugzilla.mozilla.org/show_bug.cgi?id=648573
+ -->
+ <head>
+ <title>Test for Bug 648573</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ </head>
+ <body>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=648573">Mozilla Bug 648573</a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+
+ </div>
+ <pre id="test">
+ <script type="application/javascript">
+
+ /** Test for Bug 648573 **/
+ SimpleTest.waitForExplicitFinish();
+ var utils = SpecialPowers.getDOMWindowUtils(window);
+
+ ok("createTouch" in document, "Should have createTouch function");
+ ok("createTouchList" in document, "Should have createTouchList function");
+ ok(document.createEvent("touchevent"), "Should be able to create TouchEvent objects");
+
+ var t1 = document.createTouch(window, document, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+ is(t1.target, document, "Wrong target");
+ is(t1.identifier, 1, "Wrong identifier");
+ is(t1.pageX, 2, "Wrong pageX");
+ is(t1.pageY, 3, "Wrong pageY");
+ is(t1.screenX, 4, "Wrong screenX");
+ is(t1.screenY, 5, "Wrong screenY");
+ is(t1.clientX, 6, "Wrong clientX");
+ is(t1.clientY, 7, "Wrong clientY");
+ is(t1.radiusX, 8, "Wrong radiusX");
+ is(t1.radiusY, 9, "Wrong radiusY");
+ is(t1.rotationAngle, 10, "Wrong rotationAngle");
+ is(t1.force, 11, "Wrong force");
+
+ var t2 = document.createTouch();
+
+ var l1 = document.createTouchList(t1);
+ is(l1.length, 1, "Wrong length");
+ is(l1.item(0), t1, "Wront item (1)");
+ is(l1[0], t1, "Wront item (2)");
+
+ var l2 = document.createTouchList([t1, t2]);
+ is(l2.length, 2, "Wrong length");
+ is(l2.item(0), t1, "Wront item (3)");
+ is(l2.item(1), t2, "Wront item (4)");
+ is(l2[0], t1, "Wront item (5)");
+ is(l2[1], t2, "Wront item (6)");
+
+ var l3 = document.createTouchList();
+
+ var e = document.createEvent("touchevent");
+ e.initTouchEvent("touchmove", true, true, window, 0, true, true, true, true,
+ l1, l2, l3);
+ is(e.touches, l1, "Wrong list (1)");
+ is(e.targetTouches, l2, "Wrong list (2)");
+ is(e.changedTouches, l3, "Wrong list (3)");
+ ok(e.altKey, "Alt should be true");
+ ok(e.metaKey, "Meta should be true");
+ ok(e.ctrlKey, "Ctrl should be true");
+ ok(e.shiftKey, "Shift should be true");
+
+
+ var events =
+ ["touchstart",
+ "touchend",
+ "touchmove",
+ "touchcancel"];
+
+ function runEventTest(type) {
+ var e = document.createEvent("touchevent");
+ e.initTouchEvent(type, true, true, window, 0, true, true, true, true,
+ l1, l2, l3);
+ var t = document.createElement("div");
+ // Testing target.onFoo;
+ var didCall = false;
+ t["on" + type] = function (evt) {
+ is(evt, e, "Wrong event");
+ evt.target.didCall = true;
+ }
+ t.dispatchEvent(e);
+ ok(t.didCall, "Should have called the listener(1)");
+
+ // Testing <element onFoo="">
+ t = document.createElement("div");
+ t.setAttribute("on" + type, "this.didCall = true;");
+ t.dispatchEvent(e);
+ ok(t.didCall, "Should have called the listener(2)");
+ }
+
+ for (var i = 0; i < events.length; ++i) {
+ runEventTest(events[i]);
+ }
+
+ SimpleTest.finish();
+ </script>
+ </pre>
+ </body>
+</html>
diff --git a/dom/events/test/test_bug650493.html b/dom/events/test/test_bug650493.html
new file mode 100644
index 000000000..60a32d56e
--- /dev/null
+++ b/dom/events/test/test_bug650493.html
@@ -0,0 +1,215 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=650493
+-->
+<head>
+ <title>Test for Bug 650493</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650493">Mozilla Bug 650493</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+function getNodes() {
+ var walker = document.createTreeWalker($('content'), NodeFilter.SHOW_ALL, null);
+ var nodes = [];
+ do {
+ nodes.push(walker.currentNode);
+ } while(walker.nextNode());
+
+ return nodes;
+}
+
+function check() {
+ var current = getNodes();
+ is(nodes.length, current.length, "length after " + testName);
+ nodes.forEach(function(val, index) {
+ ok(current.indexOf(val) > -1, "nodes[" + index + "] (" + val + ") shouldn't exist after " + testName);
+ });
+}
+
+var nodes = getNodes();
+var testName = "empty";
+var mutateCount = 0;
+
+check();
+
+// Set up listeners
+root = $('content');
+root.addEventListener("DOMNodeInserted", function(e) {
+ mutateCount++;
+ is(e.isTrusted, true, "untrusted mutation event");
+ var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null);
+ do {
+ is(nodes.indexOf(w.currentNode), -1, "already have inserted node (" + w.currentNode + ") when " + testName);
+ nodes.push(w.currentNode);
+ } while(w.nextNode());
+}, false);
+root.addEventListener("DOMNodeRemoved", function(e) {
+ mutateCount++;
+ is(e.isTrusted, true, "untrusted mutation event");
+ var w = document.createTreeWalker(e.target, NodeFilter.SHOW_ALL, null);
+ do {
+ var index = nodes.indexOf(w.currentNode);
+ ok(index != -1, "missing removed node (" + w.currentNode + ") when " + testName);
+ nodes.splice(index, 1);
+ } while(w.nextNode());
+}, false);
+
+testName = "text-only innerHTML";
+root.innerHTML = "hello world";
+check();
+
+testName = "innerHTML with <b>";
+root.innerHTML = "<b>bold</b> world";
+check();
+
+testName = "complex innerHTML";
+root.innerHTML = "<b>b<span>old</span></b> <strong>world";
+check();
+
+testName = "replacing using .textContent";
+root.textContent = "i'm just a plain text minding my own business";
+check();
+
+testName = "clearing using .textContent";
+root.textContent = "";
+check();
+
+testName = "inserting using .textContent";
+root.textContent = "i'm new text!!";
+check();
+
+testName = "inserting using .textContent";
+root.textContent = "i'm new text!!";
+check();
+
+testName = "preparing to normalize";
+root.innerHTML = "<u><b>foo</b></u> ";
+var u = root.firstChild;
+is(u.nodeName, "U", "got the right node");
+var b = u.firstChild;
+is(b.nodeName, "B", "got the right node");
+b.insertBefore(document.createTextNode(""), b.firstChild);
+b.insertBefore(document.createTextNode(""), b.firstChild);
+b.appendChild(document.createTextNode(""));
+b.appendChild(document.createTextNode("hello"));
+b.appendChild(document.createTextNode("world"));
+u.appendChild(document.createTextNode("foo"));
+u.appendChild(document.createTextNode(""));
+u.appendChild(document.createTextNode("bar"));
+check();
+
+testName = "normalizing";
+root.normalize();
+check();
+
+testName = "self replace firstChild";
+mutateCount = 0;
+root.replaceChild(root.firstChild, root.firstChild);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "self replace second child";
+mutateCount = 0;
+root.replaceChild(root.firstChild.nextSibling, root.firstChild.nextSibling);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "self replace lastChild";
+mutateCount = 0;
+root.replaceChild(root.lastChild, root.lastChild);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "self insertBefore firstChild";
+mutateCount = 0;
+root.insertBefore(root.firstChild, root.firstChild);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "self insertBefore second child";
+mutateCount = 0;
+root.insertBefore(root.firstChild.nextSibling, root.firstChild.nextSibling);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "self insertBefore lastChild";
+mutateCount = 0;
+root.insertBefore(root.lastChild, root.lastChild);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "appendChild last";
+mutateCount = 0;
+root.appendChild(root.lastChild);
+check();
+is(mutateCount, 2, "should remove and reinsert " + testName);
+
+testName = "prepare script/style";
+script = document.createElement("script");
+script.appendChild(document.createTextNode("void(0);"));
+root.appendChild(script);
+style = document.createElement("style");
+root.appendChild(style);
+check();
+
+testName = "set something in script";
+script.text = "something";
+check();
+
+testName = "set something in style";
+style.innerHTML = "something { dislay: none; }";
+check();
+
+testName = "moving style";
+root.insertBefore(style, root.firstChild);
+check();
+
+testName = "replacing script";
+root.replaceChild(b, script);
+check();
+
+testName = "doc-fragment insert in the middle";
+frag = document.createDocumentFragment();
+frag.addEventListener("DOMNodeRemoved", function(e) {
+ var index = children.indexOf(e.target);
+ ok(index != -1, "unknown child removed from fragment");
+ children.splice(index, 1);
+}, false);
+var children = [];
+children.push(document.createTextNode("foo"));
+children.push(document.createTextNode("bar"));
+children.push(document.createElement("span"));
+children.push(document.createElement("b"));
+children[2].appendChild(document.createElement("i"));
+children.forEach(function(child) { frag.appendChild(child); });
+ok(root.firstChild, "need to have children in order to test inserting before end");
+root.replaceChild(frag, root.firstChild);
+check();
+is(children.length, 0, "should have received DOMNodeRemoved for all frag children when inserting");
+is(frag.childNodes.length, 0, "fragment should be empty when inserting");
+
+testName = "doc-fragment append at the end";
+children.push(document.createTextNode("foo"));
+children.push(document.createTextNode("bar"));
+children.push(document.createElement("span"));
+children.push(document.createElement("b"));
+children[2].appendChild(document.createElement("i"));
+children.forEach(function(child) { frag.appendChild(child); });
+root.appendChild(frag);
+check();
+is(children.length, 0, "should have received DOMNodeRemoved for all frag children when appending");
+is(frag.childNodes.length, 0, "fragment should be empty when appending");
+
+</script>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug656379-1.html b/dom/events/test/test_bug656379-1.html
new file mode 100644
index 000000000..bc92189e2
--- /dev/null
+++ b/dom/events/test/test_bug656379-1.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=656379
+-->
+<head>
+ <title>Test for Bug 656379</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+/** Test for Bug 656379 **/
+SimpleTest.waitForExplicitFinish();
+var subwindow = window.open("./bug656379-1.html", "bug656379", "width=800,height=1000");
+
+function finishTests() {
+ subwindow.close();
+ SimpleTest.finish();
+}
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug656379-2.html b/dom/events/test/test_bug656379-2.html
new file mode 100644
index 000000000..d53abce41
--- /dev/null
+++ b/dom/events/test/test_bug656379-2.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=656379
+-->
+<head>
+ <title>Test for Bug 656379</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ input[type="button"]:hover { color: green; }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=656379">Mozilla Bug 656379</a>
+<p id="display">
+ <label for="button1" id="label1">Label 1</label>
+ <input type="button" id="button1" value="Button 1">
+ <label>
+ <span id="label2">Label 2</span>
+ <input type="button" id="button2" value="Button 2">
+ </label>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+/** Test for Bug 656379 **/
+SimpleTest.waitForExplicitFinish();
+function tests() {
+ synthesizeMouseAtCenter($("label1"), { type: "mousemove" });
+ yield undefined;
+ is($("button1").matches(":hover"), true,
+ "Button 1 should be hovered after mousemove over label1");
+ is($("label1").matches(":hover"), true,
+ "Label 1 should be hovered after mousemove over label1");
+ is($("button2").matches(":hover"), false,
+ "Button 2 should not be hovered after mousemove over label1");
+ is($("label2").matches(":hover"), false,
+ "Label 2 should not be hovered after mousemove over label1");
+ synthesizeMouseAtCenter($("button2"), { type: "mousemove" });
+ yield undefined;
+ is($("button1").matches(":hover"), false,
+ "Button 1 should not be hovered after mousemove over button2");
+ is($("label1").matches(":hover"), false,
+ "Label 1 should not be hovered after mousemove over button2");
+ is($("button2").matches(":hover"), true,
+ "Button 2 should be hovered after mousemove over button2");
+ is($("label2").matches(":hover"), false,
+ "Label 2 should not be hovered after mousemove over label2");
+ synthesizeMouseAtCenter($("label2"), { type: "mousemove" });
+ yield undefined;
+ is($("button1").matches(":hover"), false,
+ "Button 1 should not be hovered after mousemove over label2");
+ is($("label1").matches(":hover"), false,
+ "Label 1 should not be hovered after mousemove over label2");
+ is($("button2").matches(":hover"), true,
+ "Button 2 should be hovered after mousemove over label2");
+ is($("label2").matches(":hover"), true,
+ "Label 2 should be hovered after mousemove over label2");
+ SimpleTest.finish();
+}
+
+function executeTests() {
+ var testYielder = tests();
+ function execNext() {
+ try {
+ testYielder.next();
+ SimpleTest.executeSoon(execNext);
+ } catch(e) {}
+ }
+ execNext();
+}
+
+SimpleTest.waitForFocus(executeTests);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug656954.html b/dom/events/test/test_bug656954.html
new file mode 100644
index 000000000..c4fd29e04
--- /dev/null
+++ b/dom/events/test/test_bug656954.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=656954
+-->
+<head>
+ <title>Test for Bug 656954</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=656954">Mozilla Bug 656954</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 656954 **/
+
+var e = document.createEvent("Event");
+is(e.defaultPrevented, false,
+ "After creating event defaultPrevented should be false");
+e.initEvent("foo", true, true);
+var el = document.createElement("div");
+el.addEventListener("foo",
+ function(evt) {
+ evt.preventDefault();
+ }, false);
+el.dispatchEvent(e);
+is(e.defaultPrevented, true, "preventDefault() should have been called!");
+
+e = document.createEvent("Event");
+e.initEvent("foo", true, false);
+el.dispatchEvent(e);
+is(e.defaultPrevented, false, "preventDefault() should not have any effect!");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug659071.html b/dom/events/test/test_bug659071.html
new file mode 100644
index 000000000..9a40c525c
--- /dev/null
+++ b/dom/events/test/test_bug659071.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=659071
+-->
+<head>
+ <title>Test for Bug 659071</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=659071">Mozilla Bug 659071</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 659071 **/
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+var subWin = window.open("window_bug659071.html", "_blank",
+ "width=500,height=500");
+
+function finish()
+{
+ subWin.close();
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug659350.html b/dom/events/test/test_bug659350.html
new file mode 100644
index 000000000..0d566c0b1
--- /dev/null
+++ b/dom/events/test/test_bug659350.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=659350
+-->
+<head>
+ <title>Test for Bug 659350</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=659350">Mozilla Bug 659350</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 659350 **/
+function testIn(eventName, obj, objName, expected) {
+ is(eventName in obj, expected, "'" + eventName + "' shuld be in " + objName);
+}
+
+var div = document.createElement("div");
+
+// Forwarded events
+testIn("onscroll", window, "window", true);
+testIn("onscroll", document.body, "body", true);
+testIn("onscroll", div, "div", true);
+// Window events
+testIn("onpopstate", window, "window", true);
+testIn("onpopstate", document.body, "body", true);
+testIn("onpopstate", div, "div", false);
+// Non-idl events
+testIn("onopen", window, "window", false);
+testIn("onopen", document.body, "body", false);
+testIn("onopen", div, "div", false);
+
+function f() {}
+function g() {}
+
+// Basic sanity of interaction between the IDL and content attributes
+div.onload = f;
+is(div.onload, f, "Should have 'f' as div's onload");
+div.setAttribute("onload", "");
+isnot(div.onload, f, "Should not longer have 'f' as div's onload");
+is(div.onload.toString(), "function onload(event) {\n\n}",
+ "Should have wrapped empty string in a function");
+div.setAttribute("onload", "foopy();");
+is(div.onload.toString(), "function onload(event) {\nfoopy();\n}",
+ "Should have wrapped call in a function");
+div.removeAttribute("onload");
+is(div.onload, null, "Should have null onload now");
+
+// Test forwarding to window for both events that are window-specific and that
+// exist on all elements
+function testPropagationToWindow(eventName) {
+ is(window["on"+eventName], null, "Shouldn't have " + eventName + " stuff yet");
+ document.body["on"+eventName] = f;
+ is(window["on"+eventName], f,
+ "Setting on"+eventName+" on body should propagate to window");
+ document.createElement("body")["on"+eventName] = g;
+ is(window["on"+eventName], g,
+ "Setting on"+eventName+" on body not in document should propagate to window");
+ document.createElement("frameset")["on"+eventName] = f;
+ is(window["on"+eventName], f,
+ "Setting on"+eventName+" on frameset not in document should propagate to window");
+
+ document.body.setAttribute("on"+eventName, eventName);
+ is(window["on"+eventName].toString(),
+ "function on"+eventName+"(event) {\n"+eventName+"\n}",
+ "Setting on"+eventName+"attribute on body should propagate to window");
+ document.createElement("body").setAttribute("on"+eventName, eventName+"2");
+ is(window["on"+eventName].toString(),
+ "function on"+eventName+"(event) {\n"+eventName+"2\n}",
+ "Setting on"+eventName+"attribute on body outside the document should propagate to window");
+}
+
+testPropagationToWindow("popstate");
+testPropagationToWindow("scroll");
+
+// Test |this| and scoping
+var called;
+div.onscroll = function(event) {
+ is(this, div, "This should be div when invoking event listener");
+ is(event, ev, "Event argument should be the event that was dispatched");
+ called = true;
+}
+var ev = document.createEvent("Events");
+ev.initEvent("scroll", true, true);
+called = false;
+div.dispatchEvent(ev);
+is(called, true, "Event listener set via on* property not called");
+
+div.foopy = "Found me";
+document.foopy = "Didn't find me";
+document.foopy2 = "Found me";
+div.setAttribute("onscroll",
+ "is(this, div, 'This should be div when invoking via attribute');\
+ is(foopy, 'Found me', 'div should be on the scope chain when invoking handler compiled from content attribute');\
+ is(foopy2, 'Found me', 'document should be on the scope chain when invking handler compiled from content attribute');\
+ is(event, ev, 'Event argument should be the event that was dispatched');\
+ called = true;");
+called = false;
+div.dispatchEvent(ev);
+is(called, true, "Event listener set via on* attribute not called");
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug662678.html b/dom/events/test/test_bug662678.html
new file mode 100644
index 000000000..d543f9b96
--- /dev/null
+++ b/dom/events/test/test_bug662678.html
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=662678
+-->
+<head>
+ <title>Test for Bug 662678</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=662678">Mozilla Bug 662678</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 662678 **/
+SimpleTest.waitForExplicitFinish();
+
+var checkMotion = function(event) {
+ window.removeEventListener("devicemotion", checkMotion, true);
+
+ is(event.acceleration.x, 1.5, "acceleration.x");
+ is(event.acceleration.y, 2.5, "acceleration.y");
+ is(event.acceleration.z, 3.5, "acceleration.z");
+ is(event.accelerationIncludingGravity.x, 4.5, "accelerationIncludingGravity.x");
+ is(event.accelerationIncludingGravity.y, 5.5, "accelerationIncludingGravity.y");
+ is(event.accelerationIncludingGravity.z, 6.5, "accelerationIncludingGravity.z");
+ is(event.rotationRate.alpha, 7.5, "rotationRate.alpha");
+ is(event.rotationRate.beta, 8.5, "rotationRate.beta");
+ is(event.rotationRate.gamma, 9.5, "rotationRate.gamma");
+ is(event.interval, 0.5, "interval");
+
+ var e = document.createEvent("DeviceMotionEvent");
+ e.initDeviceMotionEvent('devicemotion', true, true,
+ null, null, null, null);
+ is(e.acceleration.x, null, "acceleration.x");
+ is(e.acceleration.y, null, "acceleration.y");
+ is(e.acceleration.z, null, "acceleration.z");
+ is(e.accelerationIncludingGravity.x, null, "accelerationIncludingGravity.x");
+ is(e.accelerationIncludingGravity.y, null, "accelerationIncludingGravity.y");
+ is(e.accelerationIncludingGravity.z, null, "accelerationIncludingGravity.z");
+ is(e.rotationRate.alpha, null, "rotationRate.alpha");
+ is(e.rotationRate.beta, null, "rotationRate.beta");
+ is(e.rotationRate.gamma, null, "rotationRate.gamma");
+ is(e.interval, null, "interval");
+
+ e.initDeviceMotionEvent('devicemotion', true, true,
+ {}, {}, {}, 0);
+ is(e.acceleration.x, null, "acceleration.x");
+ is(e.acceleration.y, null, "acceleration.y");
+ is(e.acceleration.z, null, "acceleration.z");
+ is(e.accelerationIncludingGravity.x, null, "accelerationIncludingGravity.x");
+ is(e.accelerationIncludingGravity.y, null, "accelerationIncludingGravity.y");
+ is(e.accelerationIncludingGravity.z, null, "accelerationIncludingGravity.z");
+ is(e.rotationRate.alpha, null, "rotationRate.alpha");
+ is(e.rotationRate.beta, null, "rotationRate.beta");
+ is(e.rotationRate.gamma, null, "rotationRate.gamma");
+ is(e.interval, 0, "interval");
+
+ window.addEventListener("devicemotion", checkMotionCtor, true);
+
+ event = new DeviceMotionEvent('devicemotion', {
+ bubbles: true, cancelable: true,
+ acceleration: {x:1.5,y:2.5,z:3.5},
+ accelerationIncludingGravity: {x:4.5,y:5.5,z:6.5},
+ rotationRate: {alpha:7.5,beta:8.5,gamma:9.5},
+ interval: 0.5
+ });
+ window.dispatchEvent(event);
+};
+
+var checkMotionCtor = function(event) {
+ window.removeEventListener("devicemotion", checkMotionCtor, true);
+
+ is(event.acceleration.x, 1.5, "acceleration.x");
+ is(event.acceleration.y, 2.5, "acceleration.y");
+ is(event.acceleration.z, 3.5, "acceleration.z");
+ is(event.accelerationIncludingGravity.x, 4.5, "accelerationIncludingGravity.x");
+ is(event.accelerationIncludingGravity.y, 5.5, "accelerationIncludingGravity.y");
+ is(event.accelerationIncludingGravity.z, 6.5, "accelerationIncludingGravity.z");
+ is(event.rotationRate.alpha, 7.5, "rotationRate.alpha");
+ is(event.rotationRate.beta, 8.5, "rotationRate.beta");
+ is(event.rotationRate.gamma, 9.5, "rotationRate.gamma");
+ is(event.interval, 0.5, "interval");
+
+ var e = new DeviceMotionEvent('devicemotion');
+ is(e.acceleration.x, null, "acceleration.x");
+ is(e.acceleration.y, null, "acceleration.y");
+ is(e.acceleration.z, null, "acceleration.z");
+ is(e.accelerationIncludingGravity.x, null, "accelerationIncludingGravity.x");
+ is(e.accelerationIncludingGravity.y, null, "accelerationIncludingGravity.y");
+ is(e.accelerationIncludingGravity.z, null, "accelerationIncludingGravity.z");
+ is(e.rotationRate.alpha, null, "rotationRate.alpha");
+ is(e.rotationRate.beta, null, "rotationRate.beta");
+ is(e.rotationRate.gamma, null, "rotationRate.gamma");
+ is(e.interval, null, "interval");
+
+ e = new DeviceMotionEvent('devicemotion', {
+ bubbles: true, cancelable: true,
+ acceleration: null, accelerationIncludingGravity: null,
+ rotationRate: null, interval: null
+ });
+ is(e.acceleration.x, null, "acceleration.x");
+ is(e.acceleration.y, null, "acceleration.y");
+ is(e.acceleration.z, null, "acceleration.z");
+ is(e.accelerationIncludingGravity.x, null, "accelerationIncludingGravity.x");
+ is(e.accelerationIncludingGravity.y, null, "accelerationIncludingGravity.y");
+ is(e.accelerationIncludingGravity.z, null, "accelerationIncludingGravity.z");
+ is(e.rotationRate.alpha, null, "rotationRate.alpha");
+ is(e.rotationRate.beta, null, "rotationRate.beta");
+ is(e.rotationRate.gamma, null, "rotationRate.gamma");
+ is(e.interval, null, "interval");
+
+ e = new DeviceMotionEvent('devicemotion', {
+ bubbles: true, cancelable: true,
+ acceleration: {}, accelerationIncludingGravity: {},
+ rotationRate: {}, interval: 0
+ });
+ is(e.acceleration.x, null, "acceleration.x");
+ is(e.acceleration.y, null, "acceleration.y");
+ is(e.acceleration.z, null, "acceleration.z");
+ is(e.accelerationIncludingGravity.x, null, "accelerationIncludingGravity.x");
+ is(e.accelerationIncludingGravity.y, null, "accelerationIncludingGravity.y");
+ is(e.accelerationIncludingGravity.z, null, "accelerationIncludingGravity.z");
+ is(e.rotationRate.alpha, null, "rotationRate.alpha");
+ is(e.rotationRate.beta, null, "rotationRate.beta");
+ is(e.rotationRate.gamma, null, "rotationRate.gamma");
+ is(e.interval, 0, "interval");
+
+ SimpleTest.finish();
+};
+
+window.addEventListener("devicemotion", checkMotion, true);
+
+var event = DeviceMotionEvent;
+ok(!!event, "Should have seen DeviceMotionEvent!");
+
+event = document.createEvent("DeviceMotionEvent");
+event.initDeviceMotionEvent('devicemotion', true, true,
+ {x:1.5,y:2.5,z:3.5},
+ {x:4.5,y:5.5,z:6.5},
+ {alpha:7.5,beta:8.5,gamma:9.5},
+ 0.5);
+window.dispatchEvent(event);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug667612.html b/dom/events/test/test_bug667612.html
new file mode 100644
index 000000000..b5d4fe88b
--- /dev/null
+++ b/dom/events/test/test_bug667612.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=667612
+-->
+<head>
+ <title>Test for Bug 667612</title>
+ <script type="text/javascript" src="/MochiKit/packed.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=667612">Mozilla Bug 667612</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+xhr = new XMLHttpRequest;
+w = new Worker("empty.js");
+window.addEventListener("load", null, false);
+document.addEventListener("load", null, false);
+document.body.addEventListener("load", null, false);
+xhr.addEventListener("load", null, false);
+w.addEventListener("load", null, false);
+window.addEventListener("load", undefined, false);
+document.addEventListener("load", undefined, false);
+document.body.addEventListener("load", undefined, false);
+xhr.addEventListener("load", undefined, false);
+w.addEventListener("load", undefined, false);
+
+ok(true, "didn't throw");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug667919-1.html b/dom/events/test/test_bug667919-1.html
new file mode 100644
index 000000000..56643ae01
--- /dev/null
+++ b/dom/events/test/test_bug667919-1.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=615597
+-->
+<head>
+ <title>Test for Bug 615597</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=615597">Mozilla Bug 615597</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 615597 **/
+
+window.ondeviceorientation = function(event) {
+ is(event.alpha, 1.5);
+ is(event.beta, 2.25);
+ is(event.gamma, 3.667);
+ is(event.absolute, true);
+ SimpleTest.finish();
+};
+
+var event = DeviceOrientationEvent;
+ok(!!event, "Should have seen DeviceOrientationEvent!");
+
+event = document.createEvent("DeviceOrientationEvent");
+event.initDeviceOrientationEvent('deviceorientation', true, true, 1.5, 2.25, 3.667, true);
+window.dispatchEvent(event);
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug679494.xul b/dom/events/test/test_bug679494.xul
new file mode 100644
index 000000000..0239fbb02
--- /dev/null
+++ b/dom/events/test/test_bug679494.xul
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=679494
+-->
+<window title="Mozilla Bug 679494" onload="doTest();"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=679494">Mozilla Bug 679494</a>
+ <p id="display"></p>
+<div id="content" style="display: none">
+ <iframe id="contentframe" src="http://mochi.test:8888/tests/dom/events/test/file_bug679494.html"></iframe>
+</div>
+</body>
+
+<script class="testbody" type="application/javascript;version=1.8"><![CDATA[
+
+/* Test for bug 679494 */
+function doTest() {
+ SimpleTest.waitForExplicitFinish();
+
+ var w = document.getElementById("contentframe").contentWindow;
+ w.addEventListener("message", function(e) {
+ is("test", e.data, "We got the data without a compartment mismatch assertion!");
+ SimpleTest.finish();
+ }, false);
+ w.postMessage("test", "*");
+}
+
+]]></script>
+
+</window>
diff --git a/dom/events/test/test_bug684208.html b/dom/events/test/test_bug684208.html
new file mode 100644
index 000000000..f8aa2f575
--- /dev/null
+++ b/dom/events/test/test_bug684208.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=684208
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 684208</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 684208 **/
+
+ function checkDispatchReturnValue(targetOrUndefined) {
+ var target = targetOrUndefined ? targetOrUndefined : self;
+ function createEvent() {
+ if ("MouseEvent" in this) {
+ return new MouseEvent("click", {cancelable: true});
+ }
+ return new Event("dummy", {cancelable: true});
+ }
+
+ function postSelfMessage(msg) {
+ try {
+ self.postMessage(msg);
+ } catch(ex) {
+ self.postMessage(msg, "*");
+ }
+ }
+
+ function passiveListener(e) {
+ e.target.removeEventListener(e.type, passiveListener);
+ }
+ var event = createEvent();
+ target.addEventListener(event.type, passiveListener);
+ postSelfMessage(target.dispatchEvent(event) == true);
+
+ function cancellingListener(e) {
+ e.target.removeEventListener(e.type, cancellingListener);
+ e.preventDefault();
+ }
+ event = createEvent();
+ target.addEventListener(event.type, cancellingListener);
+ postSelfMessage(target.dispatchEvent(event) == false);
+ }
+
+ function test() {
+ var expectedEvents = 6;
+ function messageHandler(e) {
+ ok(e.data, "All the dispatchEvent calls should pass.");
+ --expectedEvents;
+ if (!expectedEvents) {
+ window.onmessage = null;
+ window.worker.onmessage = null;
+ SimpleTest.finish();
+ }
+ }
+ window.onmessage = messageHandler;
+ checkDispatchReturnValue();
+ checkDispatchReturnValue(document.getElementById("link"));
+ window.worker =
+ new Worker(URL.createObjectURL(new Blob(["(" + checkDispatchReturnValue.toString() + ")();"])));
+ window.worker.onmessage = messageHandler;
+ }
+
+ SimpleTest.waitForExplicitFinish();
+
+ </script>
+</head>
+<body onload="test();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=684208">Mozilla Bug 684208</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<a id="link" href="#foo">foo</a>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug687787.html b/dom/events/test/test_bug687787.html
new file mode 100644
index 000000000..137e2a1eb
--- /dev/null
+++ b/dom/events/test/test_bug687787.html
@@ -0,0 +1,617 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+-->
+<head>
+ <title>Test for Bug 687787</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=687787">Mozilla Bug 687787</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var content = document.getElementById('content');
+var eventStack = [];
+
+function _callback(e){
+ var event = {'type' : e.type, 'target' : e.target, 'relatedTarget' : e.relatedTarget }
+ eventStack.push(event);
+}
+
+function clearEventStack(){
+ eventStack = [];
+}
+
+window.addEventListener("focus", _callback, true);
+window.addEventListener("focusin", _callback, true);
+window.addEventListener("focusout", _callback, true);
+window.addEventListener("blur", _callback, true);
+
+function CompareEventToExpected(e, expected) {
+ if (expected == null || e == null)
+ return false;
+ if (e.type == expected.type && e.target == expected.target && e.relatedTarget == expected.relatedTarget)
+ return true;
+ return false;
+}
+
+function TestEventOrderNormal() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var input3 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ input3.setAttribute('id', 'input3');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+ input3.setAttribute('type', 'text');
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.appendChild(input3);
+ content.style.display = 'block'
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ {'type' : 'focusin',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ {'type' : 'blur',
+ 'target' : input2,
+ 'relatedTarget' : input3},
+ {'type' : 'focusout',
+ 'target' : input2,
+ 'relatedTarget' : input3},
+ {'type' : 'focus',
+ 'target' : input3,
+ 'relatedTarget' : input2},
+ {'type' : 'focusin',
+ 'target' : input3,
+ 'relatedTarget' : input2},
+ ]
+
+ input1.focus();
+ clearEventStack();
+
+ input2.focus();
+ input3.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length ; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestEventOrderNormalFiresAtRightTime() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var input3 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ input3.setAttribute('id', 'input3');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+ input3.setAttribute('type', 'text');
+
+ input1.onblur = function(e)
+ {
+ ok(document.activeElement == document.body, 'input1: not focused when blur fires')
+ }
+
+ input1.addEventListener('focusout', function(e)
+ {
+ ok(document.activeElement == document.body, 'input1: not focused when focusout fires')
+ });
+
+ input2.onfocus = function(e)
+ {
+ ok(document.activeElement == input2, 'input2: focused when focus fires')
+ }
+
+ input2.addEventListener('focusin', function(e)
+ {
+ ok(document.activeElement == input2, 'input2: focused when focusin fires')
+ });
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.style.display = 'block'
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ {'type' : 'focusin',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ ]
+
+ input1.focus();
+ clearEventStack();
+
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length ; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestFocusOutRedirectsFocus() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var input3 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ input3.setAttribute('id', 'input3');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+ input3.setAttribute('type', 'text');
+ input1.addEventListener('focusout', function () {
+ input3.focus();
+ });
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.appendChild(input3);
+ content.style.display = 'block'
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input3,
+ 'relatedTarget' : null},
+ {'type' : 'focusin',
+ 'target' : input3,
+ 'relatedTarget' : null},
+ ]
+
+ input1.focus();
+ clearEventStack();
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestFocusInRedirectsFocus() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var input3 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ input3.setAttribute('id', 'input3');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+ input3.setAttribute('type', 'text');
+ input2.addEventListener('focusin', function () {
+ input3.focus();
+ });
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.appendChild(input3);
+ content.style.display = 'block'
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ {'type' : 'focusin',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ {'type' : 'blur',
+ 'target' : input2,
+ 'relatedTarget' : input3},
+ {'type' : 'focusout',
+ 'target' : input2,
+ 'relatedTarget' : input3},
+ {'type' : 'focus',
+ 'target' : input3,
+ 'relatedTarget' : input2},
+ {'type' : 'focusin',
+ 'target' : input3,
+ 'relatedTarget' : input2},
+ ]
+
+ input1.focus();
+ clearEventStack();
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestBlurRedirectsFocus() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var input3 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ input3.setAttribute('id', 'input3');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+ input3.setAttribute('type', 'text');
+ input1.onblur = function () {
+ input3.focus();
+ }
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.appendChild(input3);
+ content.style.display = 'block'
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input3,
+ 'relatedTarget' : null},
+ {'type' : 'focusin',
+ 'target' : input3,
+ 'relatedTarget' : null},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ ]
+
+ input1.focus();
+ clearEventStack();
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestFocusRedirectsFocus() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var input3 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ input3.setAttribute('id', 'input3');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+ input3.setAttribute('type', 'text');
+ input2.onfocus = function () {
+ input3.focus();
+ }
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.appendChild(input3);
+ content.style.display = 'block'
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input2,
+ 'relatedTarget' : input1},
+ {'type' : 'blur',
+ 'target' : input2,
+ 'relatedTarget' : input3},
+ {'type' : 'focusout',
+ 'target' : input2,
+ 'relatedTarget' : input3},
+ {'type' : 'focus',
+ 'target' : input3,
+ 'relatedTarget' : input2},
+ {'type' : 'focusin',
+ 'target' : input3,
+ 'relatedTarget' : input2},
+ ]
+
+ input1.focus();
+ clearEventStack();
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestEventOrderDifferentDocument() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var iframe1 = document.createElement('iframe');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ iframe1.setAttribute('id', 'iframe1');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+
+ content.appendChild(input1);
+ content.appendChild(iframe1);
+ iframe1.contentDocument.body.appendChild(input2);
+ content.style.display = 'block'
+
+ iframe1.contentDocument.addEventListener("focus", _callback, true);
+ iframe1.contentDocument.addEventListener("focusin", _callback, true);
+ iframe1.contentDocument.addEventListener("focusout", _callback, true);
+ iframe1.contentDocument.addEventListener("blur", _callback, true);
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : null},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : null},
+ {'type' : 'blur',
+ 'target' : document,
+ 'relatedTarget' : null},
+ {'type' : 'blur',
+ 'target' : window,
+ 'relatedTarget' : null},
+ {'type' : 'focus',
+ 'target' : iframe1.contentDocument,
+ 'relatedTarget' : null},
+ {'type' : 'focus',
+ 'target' : input2,
+ 'relatedTarget' : null},
+ {'type' : 'focusin',
+ 'target' : input2,
+ 'relatedTarget' : null},
+ ]
+
+ input1.focus();
+ clearEventStack();
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+
+function TestFocusOutMovesTarget() {
+
+ var input1 = document.createElement('input');
+ var input2 = document.createElement('input');
+ var iframe1 = document.createElement('iframe');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input2.setAttribute('id', 'input2');
+ iframe1.setAttribute('id', 'iframe1');
+ input1.setAttribute('type', 'text');
+ input2.setAttribute('type', 'text');
+
+ input1.addEventListener('focusout', function () {
+ iframe1.contentDocument.body.appendChild(input2);
+ });
+
+ content.appendChild(input1);
+ content.appendChild(input2);
+ content.appendChild(iframe1);
+ content.style.display = 'block'
+
+ iframe1.contentDocument.addEventListener("focus", _callback, true);
+ iframe1.contentDocument.addEventListener("focusin", _callback, true);
+ iframe1.contentDocument.addEventListener("focusout", _callback, true);
+ iframe1.contentDocument.addEventListener("blur", _callback, true);
+
+ expectedEventOrder = [
+ {'type' : 'blur',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focusout',
+ 'target' : input1,
+ 'relatedTarget' : input2},
+ {'type' : 'focus',
+ 'target' : input2,
+ 'relatedTarget' : null},
+ {'type' : 'focusin',
+ 'target' : input2,
+ 'relatedTarget' : null},
+ ]
+
+ input1.focus();
+ clearEventStack();
+ input2.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+function TestBlurWindowAndRefocusInputOnlyFiresFocusInOnInput() {
+
+ var input1 = document.createElement('input');
+ var content = document.getElementById('content');
+
+ input1.setAttribute('id', 'input1');
+ input1.setAttribute('type', 'text');
+
+ content.appendChild(input1);
+
+ expectedEventOrder = [
+ {'type' : 'focus',
+ 'target' : document,
+ 'relatedTarget' : null},
+ {'type' : 'focus',
+ 'target' : window,
+ 'relatedTarget' : null},
+ {'type' : 'focus',
+ 'target' : input1,
+ 'relatedTarget' : null},
+ {'type' : 'focusin',
+ 'target' : input1,
+ 'relatedTarget' : null},
+ ]
+
+ window.blur();
+ clearEventStack();
+ input1.focus();
+
+ for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
+ ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ + 'Expected ('
+ + expectedEventOrder[i].type + ','
+ + (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ + (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ + 'Actual ('
+ + eventStack[i].type + ','
+ + (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ + (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
+ }
+
+ content.innerHTML = '';
+}
+
+TestEventOrderNormal();
+TestEventOrderNormalFiresAtRightTime();
+TestFocusOutRedirectsFocus();
+TestFocusInRedirectsFocus();
+TestBlurRedirectsFocus();
+TestFocusRedirectsFocus();
+TestFocusOutMovesTarget();
+TestEventOrderDifferentDocument();
+TestBlurWindowAndRefocusInputOnlyFiresFocusInOnInput();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug689564.html b/dom/events/test/test_bug689564.html
new file mode 100644
index 000000000..e6b4f3764
--- /dev/null
+++ b/dom/events/test/test_bug689564.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=689564
+-->
+<head>
+ <title>Test for Bug 689564</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=689564">Mozilla Bug 689564</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 689564 **/
+var div = document.createElement("div");
+div.setAttribute("onclick", "div");
+is(window.onclick, null, "div should not forward onclick");
+is(div.onclick.toString(), "function onclick(event) {\ndiv\n}",
+ "div should have an onclick handler");
+
+div.setAttribute("onscroll", "div");
+is(window.onscroll, null, "div should not forward onscroll");
+is(div.onscroll.toString(), "function onscroll(event) {\ndiv\n}",
+ "div should have an onscroll handler");
+
+div.setAttribute("onpopstate", "div");
+is(window.onpopstate, null, "div should not forward onpopstate");
+is("onpopstate" in div, false, "div should not have onpopstate handler");
+
+var body = document.createElement("body");
+body.setAttribute("onclick", "body");
+is(window.onclick, null, "body should not forward onclick");
+is(body.onclick.toString(), "function onclick(event) {\nbody\n}",
+ "body should have an onclick handler");
+body.setAttribute("onscroll", "body");
+is(window.onscroll.toString(), "function onscroll(event) {\nbody\n}",
+ "body should forward onscroll");
+body.setAttribute("onpopstate", "body");
+is(window.onpopstate.toString(), "function onpopstate(event) {\nbody\n}",
+ "body should forward onpopstate");
+
+var frameset = document.createElement("frameset");
+frameset.setAttribute("onclick", "frameset");
+is(window.onclick, null, "frameset should not forward onclick");
+is(frameset.onclick.toString(), "function onclick(event) {\nframeset\n}",
+ "frameset should have an onclick handler");
+frameset.setAttribute("onscroll", "frameset");
+is(window.onscroll.toString(), "function onscroll(event) {\nframeset\n}",
+ "frameset should forward onscroll");
+frameset.setAttribute("onpopstate", "frameset");
+is(window.onpopstate.toString(), "function onpopstate(event) {\nframeset\n}",
+ "frameset should forward onpopstate");
+
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug698929.html b/dom/events/test/test_bug698929.html
new file mode 100644
index 000000000..03c2ff081
--- /dev/null
+++ b/dom/events/test/test_bug698929.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=698929
+-->
+<head>
+ <title>Test for Bug 698929</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=698929">Mozilla Bug 698929</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 698929 **/
+
+ var e = document.createEvent("Event");
+ e.initEvent("foo", true, true);
+ var c = 0;
+ var b = 0;
+ document.addEventListener("foo",
+ function() {
+ ++c;
+ });
+ document.body.addEventListener("foo", function(e) {
+ ++b;
+ e.stopImmediatePropagation();
+ });
+ document.body.addEventListener("foo", function(e) {
+ ++b;
+ });
+ document.body.dispatchEvent(e);
+ document.documentElement.dispatchEvent(e);
+ is(c, 1, "Listener in the document should have been called once.");
+ is(b, 1, "Listener in the body should have been called once.");
+
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug704423.html b/dom/events/test/test_bug704423.html
new file mode 100644
index 000000000..282745477
--- /dev/null
+++ b/dom/events/test/test_bug704423.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=704423
+-->
+<head>
+ <title>Test for Bug 704423</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=704423">Mozilla Bug 704423</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 704423 **/
+
+function doTest()
+{
+ function handler(aEvent) {
+ aEvent.preventDefault();
+ ok(aEvent.defaultPrevented,
+ "mousemove event should be cancelable");
+ }
+ window.addEventListener("mousemove", handler, true);
+ synthesizeMouseAtCenter(document.body, { type: "mousemove" });
+ window.removeEventListener("mousemove", handler, true);
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(doTest);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug741666.html b/dom/events/test/test_bug741666.html
new file mode 100644
index 000000000..41d6c8321
--- /dev/null
+++ b/dom/events/test/test_bug741666.html
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=741666
+-->
+<head>
+ <title>Test for Bug 741666</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=741666">Mozilla Bug 741666</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.8">
+
+/** Test for Bug 306008 - Touch events with a reference held should retain their touch lists **/
+
+let tests = [], testTarget, parent;
+
+let touch = {
+ id: 0,
+ point: {x: 0, y: 0},
+ radius: {x: 0, y: 0},
+ rotation: 0,
+ force: 0.5,
+ target: null
+}
+
+function nextTest() {
+ if (tests.length)
+ SimpleTest.executeSoon(tests.shift());
+}
+
+function checkEvent(aFakeEvent, aTouches) {
+ return function(aEvent, aTrusted) {
+ is(aFakeEvent.ctrlKey, aEvent.ctrlKey, "Correct ctrlKey");
+ is(aFakeEvent.altKey, aEvent.altKey, "Correct altKey");
+ is(aFakeEvent.shiftKey, aEvent.shiftKey, "Correct shiftKey");
+ is(aFakeEvent.metaKey, aEvent.metaKey, "Correct metaKey");
+ is(aEvent.isTrusted, aTrusted, "Event is trusted");
+ checkTouches(aFakeEvent[aTouches], aEvent[aTouches]);
+ }
+}
+
+function checkTouches(aTouches1, aTouches2) {
+ is(aTouches1.length, aTouches2.length, "Correct touches length");
+ for (var i = 0; i < aTouches1.length; i++) {
+ checkTouch(aTouches1[i], aTouches2[i]);
+ }
+}
+
+function checkTouch(aFakeTouch, aTouch) {
+ is(aFakeTouch.identifier, aTouch.identifier, "Touch has correct identifier");
+ is(aFakeTouch.target, aTouch.target, "Touch has correct target");
+ is(aFakeTouch.page.x, aTouch.pageX, "Touch has correct pageX");
+ is(aFakeTouch.page.y, aTouch.pageY, "Touch has correct pageY");
+ is(aFakeTouch.page.x + Math.round(window.mozInnerScreenX), aTouch.screenX, "Touch has correct screenX");
+ is(aFakeTouch.page.y + Math.round(window.mozInnerScreenY), aTouch.screenY, "Touch has correct screenY");
+ is(aFakeTouch.page.x, aTouch.clientX, "Touch has correct clientX");
+ is(aFakeTouch.page.y, aTouch.clientY, "Touch has correct clientY");
+ is(aFakeTouch.radius.x, aTouch.radiusX, "Touch has correct radiusX");
+ is(aFakeTouch.radius.y, aTouch.radiusY, "Touch has correct radiusY");
+ is(aFakeTouch.rotationAngle, aTouch.rotationAngle, "Touch has correct rotationAngle");
+ is(aFakeTouch.force, aTouch.force, "Touch has correct force");
+}
+
+function sendTouchEvent(windowUtils, aType, aEvent, aModifiers) {
+ var ids = [], xs=[], ys=[], rxs = [], rys = [],
+ rotations = [], forces = [];
+
+ for (var touchType of ["touches", "changedTouches", "targetTouches"]) {
+ for (var i = 0; i < aEvent[touchType].length; i++) {
+ if (ids.indexOf(aEvent[touchType][i].identifier) == -1) {
+ ids.push(aEvent[touchType][i].identifier);
+ xs.push(aEvent[touchType][i].page.x);
+ ys.push(aEvent[touchType][i].page.y);
+ rxs.push(aEvent[touchType][i].radius.x);
+ rys.push(aEvent[touchType][i].radius.y);
+ rotations.push(aEvent[touchType][i].rotationAngle);
+ forces.push(aEvent[touchType][i].force);
+ }
+ }
+ }
+ return windowUtils.sendTouchEvent(aType,
+ ids, xs, ys, rxs, rys,
+ rotations, forces,
+ ids.length, aModifiers, 0);
+}
+
+function touchEvent(aOptions) {
+ if (!aOptions) {
+ aOptions = {};
+ }
+ this.ctrlKey = aOptions.ctrlKey || false;
+ this.altKey = aOptions.altKey || false;
+ this.shiftKey = aOptions.shiftKey || false;
+ this.metaKey = aOptions.metaKey || false;
+ this.touches = aOptions.touches || [];
+ this.targetTouches = aOptions.targetTouches || [];
+ this.changedTouches = aOptions.changedTouches || [];
+}
+
+function testtouch(aOptions) {
+ if (!aOptions)
+ aOptions = {};
+ this.identifier = aOptions.identifier || 0;
+ this.target = aOptions.target || 0;
+ this.page = aOptions.page || {x: 0, y: 0};
+ this.radius = aOptions.radius || {x: 0, y: 0};
+ this.rotationAngle = aOptions.rotationAngle || 0;
+ this.force = aOptions.force || 1;
+}
+
+function testPreventDefault(name) {
+ let cwu = SpecialPowers.getDOMWindowUtils(window);
+ let target = document.getElementById("testTarget");
+ let bcr = target.getBoundingClientRect();
+
+ let touch1 = new testtouch({
+ page: {x: Math.round(bcr.left + bcr.width/2),
+ y: Math.round(bcr.top + bcr.height/2)},
+ target: target
+ });
+
+ let event = new touchEvent({
+ touches: [touch1],
+ targetTouches: [touch1],
+ changedTouches: [touch1]
+ });
+
+ // test touchstart event fires correctly
+ var checkTouches = checkEvent(event, "touches");
+ var checkTargetTouches = checkEvent(event, "targetTouches");
+
+ /* This is the heart of the test. Verify that the touch event
+ looks correct both in and outside of a setTimeout */
+ window.addEventListener("touchstart", function(firedEvent) {
+ checkTouches(firedEvent, true);
+ setTimeout(function() {
+ checkTouches(firedEvent, true);
+ checkTargetTouches(firedEvent, true);
+
+ event.touches = [];
+ event.targetTouches = [];
+ sendTouchEvent(cwu, "touchend", event, 0);
+
+ nextTest();
+ }, 0);
+ }, false);
+ sendTouchEvent(cwu, "touchstart", event, 0);
+}
+
+function doTest() {
+ tests.push(testPreventDefault);
+
+ tests.push(function() {
+ SimpleTest.finish();
+ });
+
+ nextTest();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doTest);
+
+</script>
+</pre>
+<div id="parent">
+ <span id="testTarget" style="margin-left: 200px; padding: 5px; border: 1px solid black;">testTarget</span>
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug742376.html b/dom/events/test/test_bug742376.html
new file mode 100644
index 000000000..7672ea014
--- /dev/null
+++ b/dom/events/test/test_bug742376.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=402089
+-->
+<head>
+ <title>Test for Bug 742376</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=742376">Mozilla Bug 742376</a>
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 742376 **/
+
+function hasListeners() {
+
+ var Cc = SpecialPowers.Cc;
+ var Ci = SpecialPowers.Ci;
+ var dss = Cc["@mozilla.org/devicesensors;1"].getService(Ci.nsIDeviceSensors);
+
+ return dss.hasWindowListener(Ci.nsIDeviceSensorData.TYPE_ORIENTATION, window) ||
+ dss.hasWindowListener(Ci.nsIDeviceSensorData.TYPE_ROTATION_VECTOR, window) ||
+ dss.hasWindowListener(Ci.nsIDeviceSensorData.TYPE_GAME_ROTATION_VECTOR, window);
+}
+
+is(hasListeners(), false, "Must not have listeners before tests start");
+
+function dumbListener(event) {}
+function dumbListener2(event) {}
+function dumbListener3(event) {}
+
+window.addEventListener("deviceorientation", dumbListener, false);
+window.addEventListener("random_event_name", function() {}, false);
+window.addEventListener("deviceorientation", dumbListener2, false);
+
+is(hasListeners(), true, "Listeners should have been added");
+
+window.setTimeout(function() {
+
+ window.removeEventListener("deviceorientation", dumbListener, false);
+ is(hasListeners(), true, "Only some listeners should have been removed");
+ window.setTimeout(function() {
+
+ window.removeEventListener("deviceorientation", dumbListener2, false);
+ window.setTimeout(function() {
+ is(hasListeners(), false, "Listeners should have been removed");
+ testEventHandler();
+ }, 0);
+ }, 0);
+}, 0);
+
+function testEventHandler() {
+ window.ondeviceorientation = function() {}
+ window.setTimeout(function() {
+ is(hasListeners(), true, "Handler should have been added");
+ window.ondeviceorientation = null;
+ window.setTimeout(function() {
+ is(hasListeners(), false, "Handler should have been removed");
+ SimpleTest.finish();
+ }, 0);
+ }, 0)
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/events/test/test_bug812744.html b/dom/events/test/test_bug812744.html
new file mode 100644
index 000000000..aac2435f7
--- /dev/null
+++ b/dom/events/test/test_bug812744.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=812744
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 812744</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=812744">Mozilla Bug 812744</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="f"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 812744 **/
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(function() {
+ var f = $("f");
+ var el = f.contentDocument.documentElement;
+ f.onload = function() {
+ el.setAttribute("onmouseleave", "(void 0)");
+ is(el.onmouseleave.toString(), "function onmouseleave(event) {\n(void 0)\n}",
+ "Should have a function here");
+ SimpleTest.finish();
+ };
+ f.src = "http://www.example.com/"
+});
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug822898.html b/dom/events/test/test_bug822898.html
new file mode 100644
index 000000000..2ac0a6572
--- /dev/null
+++ b/dom/events/test/test_bug822898.html
@@ -0,0 +1,350 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=822898
+-->
+<head>
+ <title>Test for Bug 822898</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=822898">Mozilla Bug 822898</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe id="subFrame"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="application/javascript;version=1.8">
+
+/** Test for Bug 822898 - Pointer* Events **/
+
+let tests = [], testTarget, parent, iframeBody, gOnPointerPropHandled;
+
+function nextTest() {
+ if (tests.length)
+ SimpleTest.executeSoon(tests.shift());
+}
+
+function random() {
+ return Math.floor(Math.random() * 100);
+}
+
+function createTestEventValue(name) {
+
+ let detail = random();
+ let screenX = random();
+ let screenY = random();
+ let clientX = random();
+ let clientY = random();
+ let ctrlKey = random() % 2 ? true : false;
+ let altKey = random() % 2 ? true : false;
+ let shiftKey = random() % 2 ? true : false;
+ let metaKey = random() % 2 ? true : false;
+ let button = random();
+ let pointerId = random();
+
+ return function() {
+ let event = new PointerEvent("pointerdown", {
+ bubbles: true, cancelable: true, view: window,
+ detail: detail, screenX: screenX, screenY: screenY, clientX: clientX, clientY: clientY,
+ ctrlKey: ctrlKey, altKey: altKey, shiftKey: shiftKey, metaKey: metaKey,
+ button: button, relatedTarget: null, pointerId: pointerId
+ });
+
+
+ function check(ev) {
+ is(ev.detail, detail, "Correct detail");
+ is(ev.screenX, screenX, "Correct screenX");
+ is(ev.screenY, screenY, "Correct screenY");
+ is(ev.clientX, clientX, "Correct clientX");
+ is(ev.clientY, clientY, "Correct clientY");
+ is(ev.ctrlKey, ctrlKey, "Correct ctrlKey");
+ is(ev.altKey, altKey, "Correct altKey");
+ is(ev.shiftKey, shiftKey, "Correct shiftKey");
+ is(ev.metaKey, metaKey, "Correct metaKey");
+ is(ev.button, button, "Correct buttonArg");
+ is(ev.pointerId, pointerId, "Correct pointerId");
+ }
+
+ for (let target of [document, window, testTarget, parent])
+ target.addEventListener(name, check, false);
+
+ testTarget.dispatchEvent(event);
+
+ for (let target of [document, window, testTarget, parent])
+ target.removeEventListener(name, check, false);
+
+
+ nextTest();
+ }
+}
+
+function getDefaultArgEvent(eventname) {
+ return new PointerEvent(eventname, {
+ bubbles: true, cancelable: true, view: window,
+ detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+ button: 0, relatedTarget: null, pointerId: 0
+ });
+}
+
+function testDefaultArg() {
+ let event = getDefaultArgEvent("pointerdown");
+
+ testTarget.addEventListener("pointerdown", function(ev) {
+ testTarget.removeEventListener("pointerdown", arguments.callee, false);
+ is(ev.pointerId, 0, "Correct default pointerId");
+ }, false);
+ testTarget.dispatchEvent(event);
+
+ nextTest();
+}
+
+function testStopPropagation() {
+ let event = getDefaultArgEvent("pointerdown");
+
+ let unreachableListener = function () {
+ ok(false, "Event should have been stopped");
+ }
+
+ // Capturing phase
+ let captured = false;
+ parent.addEventListener("pointerdown", function() {
+ parent.removeEventListener("pointerdown", arguments.callee, true);
+ captured = true;
+ }, true); // Capturing phase
+
+ // Bubbling phase
+ parent.addEventListener("pointerdown", unreachableListener, false);
+
+ testTarget.addEventListener("pointerdown", function(ev) {
+ testTarget.removeEventListener("pointerdown", arguments.callee, false);
+ is(captured, true, "Event should have been captured");
+ ev.stopPropagation();
+ }, false);
+
+ testTarget.dispatchEvent(event);
+
+ parent.removeEventListener("pointerdown", unreachableListener, false);
+
+ nextTest();
+}
+
+function testPreventDefault() {
+ let event = getDefaultArgEvent("pointerdown");
+
+ parent.addEventListener("pointerdown", function(ev) {
+ parent.removeEventListener("pointerdown", arguments.callee, false);
+ is(ev.defaultPrevented, true, "preventDefault can be called");
+ nextTest();
+ }, false);
+
+ testTarget.addEventListener("pointerdown", function(ev) {
+ testTarget.removeEventListener("pointerdown", arguments.callee, false);
+ ev.preventDefault();
+ }, false);
+
+ testTarget.dispatchEvent(event);
+}
+
+function testBlockPreventDefault() {
+ let event = new PointerEvent("pointerdown", {
+ bubbles: true, cancelable: false, view: window,
+ detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+ button: 0, relatedTarget: null, pointerId: 0, pointerType: "pen"
+ });
+
+ parent.addEventListener("pointerdown", function(ev) {
+ parent.removeEventListener("pointerdown", arguments.callee, false);
+ is(ev.defaultPrevented, false, "aCancelableArg works");
+ nextTest();
+ }, false);
+
+ testTarget.addEventListener("pointerdown", function(ev) {
+ testTarget.removeEventListener("pointerdown", arguments.callee, false);
+ ev.preventDefault();
+ }, false);
+
+ testTarget.dispatchEvent(event);
+}
+
+function testBlockBubbling() {
+ let unreachableListener = function () {
+ ok(false, "aCanBubble doesn't work");
+ }
+
+ let event = new PointerEvent("pointerdown", {
+ bubbles: false, cancelable: true, view: window,
+ detail: 0, screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+ button: 0, relatedTarget: null, pointerId: 0
+ });
+
+ parent.addEventListener("pointerdown", unreachableListener, false);
+ testTarget.dispatchEvent(event);
+ parent.removeEventListener("pointerdown", unreachableListener, false);
+
+ nextTest();
+}
+
+function testOnPointerProperty()
+{
+ iframeBody.onpointerdown = function (e) { gOnPointerPropHandled["pointerdown"] = true; }
+ iframeBody.onpointerup = function (e) { gOnPointerPropHandled["pointerup"] = true; }
+ iframeBody.onpointermove = function (e) { gOnPointerPropHandled["pointermove"] = true; }
+ iframeBody.onpointerout = function (e) { gOnPointerPropHandled["pointerout"] = true; }
+ iframeBody.onpointerover = function (e) { gOnPointerPropHandled["pointerover"] = true; }
+ iframeBody.onpointerenter = function (e) { gOnPointerPropHandled["pointerenter"] = true; }
+ iframeBody.onpointerleave = function (e) { gOnPointerPropHandled["pointerleave"] = true; }
+ iframeBody.onpointercancel = function (e) { gOnPointerPropHandled["pointercancel"] = true; }
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointerdown"));
+ is(gOnPointerPropHandled['pointerdown'], true, "pointerdown property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointerup"));
+ is(gOnPointerPropHandled['pointerup'], true, "pointerup property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointermove"));
+ is(gOnPointerPropHandled['pointermove'], true, "pointermove property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointerout"));
+ is(gOnPointerPropHandled['pointerout'], true, "pointerout property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointerover"));
+ is(gOnPointerPropHandled['pointerover'], true, "pointerover property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointerenter"));
+ is(gOnPointerPropHandled['pointerenter'], true, "pointerenter property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointerleave"));
+ is(gOnPointerPropHandled['pointerleave'], true, "pointerleave property is performed");
+
+ iframeBody.dispatchEvent(getDefaultArgEvent("pointercancel"));
+ is(gOnPointerPropHandled['pointercancel'], true, "pointercancel property is performed");
+
+ nextTest();
+}
+
+function testPointerEventCTORS()
+{
+ // TODO: This should go to test_eventctors.html, when PointerEvents enabled by default
+ var receivedEvent;
+ iframeBody.addEventListener("hello", function(e) { receivedEvent = e; }, true);
+
+ var e;
+ var ex = false;
+
+ try {
+ e = new PointerEvent();
+ } catch(exp) {
+ ex = true;
+ }
+ ok(ex, "PointerEvent: First parameter is required!");
+ ex = false;
+
+ e = new PointerEvent("hello");
+ ok(e.type, "hello", "PointerEvent: Wrong event type!");
+ ok(!e.isTrusted, "PointerEvent: Event shouldn't be trusted!");
+ ok(!e.bubbles, "PointerEvent: Event shouldn't bubble!");
+ ok(!e.cancelable, "PointerEvent: Event shouldn't be cancelable!");
+ iframeBody.dispatchEvent(e);
+ is(receivedEvent, e, "PointerEvent: Wrong event!");
+
+ var PointerEventProps =
+ [ { screenX: 0 },
+ { screenY: 0 },
+ { clientX: 0 },
+ { clientY: 0 },
+ { ctrlKey: false },
+ { shiftKey: false },
+ { altKey: false },
+ { metaKey: false },
+ { button: 0 },
+ { buttons: 0 },
+ { relatedTarget: null },
+ { pointerId: 0 },
+ { pointerType: "" }
+ ];
+
+ var testPointerProps =
+ [
+ { screenX: 1 },
+ { screenY: 2 },
+ { clientX: 3 },
+ { clientY: 4 },
+ { ctrlKey: true },
+ { shiftKey: true },
+ { altKey: true },
+ { metaKey: true },
+ { button: 5 },
+ { buttons: 6 },
+ { relatedTarget: window },
+ { pointerId: 5 },
+ { pointerType: "mouse" }
+ ];
+
+ var defaultPointerEventValues = {};
+ for (var i = 0; i < PointerEventProps.length; ++i) {
+ for (prop in PointerEventProps[i]) {
+ ok(prop in e, "PointerEvent: PointerEvent doesn't have property " + prop + "!");
+ defaultPointerEventValues[prop] = PointerEventProps[i][prop];
+ }
+ }
+
+ while (testPointerProps.length) {
+ var p = testPointerProps.shift();
+ e = new PointerEvent("foo", p);
+ for (var def in defaultPointerEventValues) {
+ if (!(def in p)) {
+ is(e[def], defaultPointerEventValues[def],
+ "PointerEvent: Wrong default value for " + def + "!");
+ } else {
+ is(e[def], p[def], "PointerEvent: Wrong event init value for " + def + "!");
+ }
+ }
+ }
+ nextTest();
+}
+
+function runTests() {
+ testTarget = document.getElementById("testTarget");
+ parent = testTarget.parentNode;
+ gOnPointerPropHandled = new Array;
+ iframeBody = document.getElementById("subFrame").contentWindow.document.body;
+
+ tests.push(createTestEventValue("pointerdown"));
+ tests.push(createTestEventValue("pointermove"));
+ tests.push(createTestEventValue("pointerup"));
+
+ tests.push(testDefaultArg);
+ tests.push(testStopPropagation);
+
+ tests.push(testPreventDefault);
+ tests.push(testBlockPreventDefault);
+
+ tests.push(testBlockBubbling);
+ tests.push(testOnPointerProperty());
+ tests.push(testPointerEventCTORS());
+
+ tests.push(function() {
+ SimpleTest.finish();
+ });
+
+ nextTest();
+}
+
+window.onload = function() {
+ SpecialPowers.pushPrefEnv({"set":[["dom.w3c_pointer_events.enabled", true]]}, runTests);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+<div id="parent">
+ <span id="testTarget" style="border: 1px solid black;">testTarget</span>
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug855741.html b/dom/events/test/test_bug855741.html
new file mode 100644
index 000000000..d7707e220
--- /dev/null
+++ b/dom/events/test/test_bug855741.html
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=855741
+-->
+<head>
+ <title>Test for Bug 855741</title>
+ <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<input type="text" id="testTarget" value="focus">
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 855741 **/
+function testFocusEvent(event) {
+ ok(('relatedTarget' in event), 'FocusEvent.relatedTarget exists');
+
+ if (event.construct_test == true) {
+ ok(event.relatedTarget == $("content"), 'FocusEvent.relatedTarget is ' + $("content").id);
+ }
+}
+
+function testUIEvent(event) {
+ ok((event.detail == 0),
+ 'UIEvent.detail should be 0 in ' + event.target.value + ' event');
+
+ ok((event.defaultView == null),
+ 'UIEvent.defaultView should be null in ' + event.target.value + ' event');
+}
+
+function testEventType(event, type) {
+ ok((event.type == type), 'Event.type match: ' + type);
+}
+
+function eventhandle(event) {
+ testFocusEvent(event);
+ testUIEvent(event);
+ testEventType(event, event.target.value);
+
+ if (event.target.value == 'blur') {
+ event.target.value = 'focus';
+ } else {
+ event.target.value = 'blur';
+ }
+}
+
+//
+// event handler:
+//
+$("testTarget").addEventListener("focus", eventhandle, true);
+$("testTarget").addEventListener("blur", eventhandle, true);
+
+//
+// FocusEvent structure test
+//
+$("testTarget").focus();
+$("testTarget").blur();
+
+//
+// Focus/Blur constructor test
+//
+var focus_event = new FocusEvent("focus",
+ {bubbles: true,
+ cancelable: true,
+ relatedTarget: $("content")});
+focus_event.construct_test = true;
+
+var blur_event = new FocusEvent("blur",
+ {bubbles: true,
+ cancelable: true,
+ relatedTarget: $("content")});
+blur_event.construct_test = true;
+
+// create cycle referece for leak test
+$("content").foo_focus = focus_event;
+$("content").foo_blur = blur_event;
+
+$("testTarget").dispatchEvent(focus_event);
+$("testTarget").dispatchEvent(blur_event);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug864040.html b/dom/events/test/test_bug864040.html
new file mode 100644
index 000000000..774e1e3ca
--- /dev/null
+++ b/dom/events/test/test_bug864040.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=864040
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 864040</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=864040">Mozilla Bug 864040</a>
+<div id="display">
+ <textarea id="ta" rows="5" cols="20" style="-moz-appearance:none"></textarea>
+ <div id="ce" contentEditable="true" style="height: 5em;"></div>
+</div>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+ <script type="application/javascript">
+ /**
+ * Test for Bug 864040
+ *
+ * We use a selection event to set the selection to the end of an editor
+ * containing an ending newline. Then we test to see that the caret is
+ * actually drawn on the newline.
+ */
+
+ function testSelectEndOfText(elem) {
+ var tn = elem.tagName;
+ elem.focus();
+
+ // Enter test string into editor
+ var test_string = 'test\n';
+ sendString(test_string);
+
+ // Get the caret position after what we entered
+ var result = synthesizeQuerySelectedText();
+ ok(result, tn + ': failed to query selection (1)');
+ var refoffset = result.offset;
+
+ // Take a snapshot of where the caret is (on the new line)
+ referenceSnapshot = snapshotWindow(window, true /* withCaret */);
+ ok(referenceSnapshot, tn + ': failed to take snapshot (1)');
+
+ // Set selection to the same spot through a selection event
+ ok(synthesizeSelectionSet(refoffset, 0, false), tn + ': failed to set selection');
+
+ // Make sure new selection is the same
+ result = synthesizeQuerySelectedText();
+ ok(result, tn + ': failed to query selection (2)');
+ is(result.offset, refoffset, tn + ': caret is not at the right position');
+
+ // Take a snapshot of where the new caret is (shoud still be on the new line)
+ testSnapshot = snapshotWindow(window, true /* withCaret */);
+ ok(testSnapshot, tn + ': failed to take snapshot (2)');
+
+ // Compare snapshot (should be the same)
+ result = compareSnapshots(referenceSnapshot, testSnapshot, true /* expected */)
+ ok(result, tn + ': failed to compare snapshots');
+ // result = [correct, s1data, s2data]
+ ok(result[0], tn + ': caret is not on new line');
+ if (!result[0]) {
+ dump('Ref: ' + result[1] + '\n');
+ dump('Res: ' + result[2] + '\n');
+ }
+ }
+
+ function runTests() {
+ // we don't test regular <input> because this test is about multiline support
+ // test textarea
+ testSelectEndOfText(document.getElementById('ta'));
+ // test contentEditable
+ testSelectEndOfText(document.getElementById('ce'));
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+
+ SimpleTest.waitForFocus(runTests);
+ </script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug924087.html b/dom/events/test/test_bug924087.html
new file mode 100644
index 000000000..59fc81f5d
--- /dev/null
+++ b/dom/events/test/test_bug924087.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=924087
+-->
+<head>
+ <title>Test for Bug 924087</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<div contenteditable><a id="editable" href="#">editable link</a></div>
+<a id="noneditable" href="#">non-editable link</a>
+<input>
+<textarea></textarea>
+<pre id="test">
+<script type="application/javascript;version=1.8">
+
+/** Test for Bug 924087 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ var editable = document.querySelector("#editable");
+ var noneditable = document.querySelector("#noneditable");
+ var input = document.querySelector("input");
+ var textarea = document.querySelector("textarea");
+ synthesizeMouseAtCenter(noneditable, {type:"mousedown"});
+ is(document.querySelector(":active:link"), noneditable, "Normal links should become :active");
+ synthesizeMouseAtCenter(noneditable, {type:"mouseup"});
+ synthesizeMouseAtCenter(editable, {type:"mousedown"});
+ is(document.querySelector(":active:link"), null, "Editable links should not become :active");
+ synthesizeMouseAtCenter(editable, {type:"mouseup"});
+ [input, textarea].forEach(textbox => {
+ synthesizeMouseAtCenter(textbox, {type:"mousedown"});
+ is(document.querySelector(textbox.localName + ":active"), textbox, "The textbox should become :active");
+ synthesizeMouseAtCenter(textbox, {type:"mouseup"});
+ });
+ SimpleTest.finish();
+});
+
+</script>
+</pre>
+
+</body>
+</html>
diff --git a/dom/events/test/test_bug930374-chrome.html b/dom/events/test/test_bug930374-chrome.html
new file mode 100644
index 000000000..291a98ca1
--- /dev/null
+++ b/dom/events/test/test_bug930374-chrome.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=930374
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 930374</title>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=930374">Mozilla Bug 930374</a>
+<div id="display">
+ <input id="input-text">
+</div>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+
+ var gKeyPress = null;
+ function onKeyPress(aEvent)
+ {
+ gKeyPress = aEvent;
+ is(aEvent.target, document.getElementById("input-text"), "input element should have focus");
+ ok(!aEvent.defaultPrevented, "keypress event should be consumed before keypress event handler");
+ }
+
+ function runTests()
+ {
+ document.addEventListener("keypress", onKeyPress, false);
+ var input = document.getElementById("input-text");
+ input.focus();
+
+ input.addEventListener("input", function (aEvent) {
+ input.removeEventListener("input", arguments.callee, false);
+ ok(gKeyPress,
+ "Test1: keypress event must be fired before an input event");
+ ok(gKeyPress.defaultPrevented,
+ "Test1: keypress event's defaultPrevented should be true in chrome even if it's consumed by default action handler of editor");
+ setTimeout(function () {
+ ok(gKeyPress.defaultPrevented,
+ "Test2: keypress event's defaultPrevented should be true after event dispatching finished");
+ SimpleTest.finish();
+ }, 0);
+ }, false);
+
+ sendChar("a");
+ }
+
+ SimpleTest.waitForFocus(runTests);
+ </script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug930374-content.html b/dom/events/test/test_bug930374-content.html
new file mode 100644
index 000000000..73654bf04
--- /dev/null
+++ b/dom/events/test/test_bug930374-content.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=930374
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 930374</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=930374">Mozilla Bug 930374</a>
+<div id="display">
+ <input id="input-text">
+</div>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+
+ var gKeyPress = null;
+ function onKeyPress(aEvent)
+ {
+ gKeyPress = aEvent;
+ is(aEvent.target, document.getElementById("input-text"), "input element should have focus");
+ ok(!aEvent.defaultPrevented, "keypress event should be consumed before keypress event handler");
+ }
+
+ function runTests()
+ {
+ document.addEventListener("keypress", onKeyPress, false);
+ var input = document.getElementById("input-text");
+ input.focus();
+
+ input.addEventListener("input", function (aEvent) {
+ input.removeEventListener("input", arguments.callee, false);
+ ok(gKeyPress,
+ "Test1: keypress event must be fired before an input event");
+ ok(!gKeyPress.defaultPrevented,
+ "Test1: keypress event's defaultPrevented should be false even though it's consumed by the default action handler of editor");
+ gKeyPress.preventDefault();
+ ok(gKeyPress.defaultPrevented,
+ "Test1: keypress event's defaultPrevented should become true because of a call of preventDefault()");
+ }, false);
+
+ sendChar("a");
+ gKeyPress = null;
+
+ input.addEventListener("input", function (aEvent) {
+ input.removeEventListener("input", arguments.callee, false);
+ ok(gKeyPress,
+ "Test2: keypress event must be fired before an input event");
+ ok(!gKeyPress.defaultPrevented,
+ "Test2: keypress event's defaultPrevented should be false even though it's consumed by the default action handler of editor");
+ setTimeout(function () {
+ ok(!gKeyPress.defaultPrevented,
+ "Test2: keypress event's defaultPrevented should not become true after event dispatching finished");
+ SimpleTest.finish();
+ }, 0);
+ }, false);
+
+ sendChar("b");
+ }
+
+ SimpleTest.waitForFocus(runTests);
+ </script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug944011.html b/dom/events/test/test_bug944011.html
new file mode 100644
index 000000000..eab74ee32
--- /dev/null
+++ b/dom/events/test/test_bug944011.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=944011
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 944011</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 944011 comment 24 - Event handlers should fire even if the
+ target comes from a non-current inner. **/
+ SimpleTest.waitForExplicitFinish();
+ var gLoadCount = 0;
+ function loaded() {
+ ++gLoadCount;
+ switch(gLoadCount) {
+ case 1:
+ ok(true, "Got first load");
+ oldBody = window[0].document.body;
+ oldBody.onclick = function() {
+ ok(true, "Got onclick");
+ SimpleTest.finish();
+ }
+ $('ifr').setAttribute('src', 'data:text/html,<html><body>Second frame</body></html>');
+ break;
+ case 2:
+ ok(true, "Got second load");
+ oldBody.dispatchEvent(new MouseEvent('click'));
+ break;
+ default:
+ ok(false, "Unexpected load");
+ SimpleTest.finish();
+ }
+ }
+
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=944011">Mozilla Bug 944011</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe id="ifr" onload="loaded();" src="data:text/html,<html><body>foo</body></html>"></iframe>
+ <div name="testTarget"></div>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug944847.html b/dom/events/test/test_bug944847.html
new file mode 100644
index 000000000..105c0d5c9
--- /dev/null
+++ b/dom/events/test/test_bug944847.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=944847
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 944847</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 944847 **/
+
+ var e1 = document.createElement("div");
+ is(e1.onclick, null);
+ e1.setAttribute("onclick", "");
+ isnot(e1.onclick, null);
+
+ var e2 = document.implementation.createHTMLDocument(null, null).createElement("div");
+ is(e2.onclick, null);
+ e2.setAttribute("onclick", "");
+ is(e2.onclick, null);
+
+ var e3 = document.createElement("div");
+ is(e3.onclick, null);
+ e3.setAttribute("onclick", "");
+ e2.ownerDocument.adoptNode(e3);
+ is(e3.onclick, null);
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=944847">Mozilla Bug 944847</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug946632.html b/dom/events/test/test_bug946632.html
new file mode 100644
index 000000000..3ef7b815f
--- /dev/null
+++ b/dom/events/test/test_bug946632.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=946632
+-->
+<head>
+ <title>Test for bug 946632 - propagate mouse-wheel vertical scroll events to container</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ .scrollable {
+ overflow: scroll;
+ height: 200px;
+ width: 200px;
+ }
+ input {
+ font-size: 72px;
+ height: 20px;
+ width: 20px;
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946632">Mozilla Bug 946632</a>
+<p id="display"></p>
+<div id="container" class="scrollable">
+ <input value="value">
+ x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>x<br>
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+</div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ SpecialPowers.pushPrefEnv({
+ "set":[["general.smoothScroll", false],
+ ["mousewheel.system_scroll_override_on_root_content.enabled", false]]
+ }, runTests)
+ }, window);
+
+var input = document.querySelector("input");
+var container = document.querySelector("#container");
+
+function reset()
+{
+ container.scrollTop = 0;
+ container.scrollLeft = 0;
+ input.scrollTop = 0;
+ input.scrollLeft = 0;
+ container.style.display='none';
+ container.getBoundingClientRect();
+}
+
+function prepare(check)
+{
+ container.style.display='';
+ container.getBoundingClientRect();
+ scrollHandler = function(event) {
+ window.removeEventListener("scroll", arguments.callee, true);
+ event.stopPropagation();
+ check(event)
+ setTimeout(nextTest,0);
+ };
+ window.addEventListener("scroll", scrollHandler, true);
+}
+
+var tests = [
+ {
+ check: function(event) {
+ is(event.target, container, "<input> vertical line scroll targets container");
+ ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
+ is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
+ is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
+ is(input.scrollLeft, 0, "<input> horizontal line scroll input.scrollLeft");
+ },
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0,
+ lineOrPageDeltaY: 1,
+ }
+ },
+ {
+ check: function(event) {
+ is(event.target, input, "<input> horizontal line scroll targets <input>");
+ is(input.scrollTop, 0, "<input> horizontal line scroll input.scrollTop");
+ ok(input.scrollLeft > 0, "<input> horizontal line scroll input.scrollLeft");
+ is(container.scrollTop, 0, "<input> horizontal line scroll container.scrollTop");
+ is(container.scrollLeft, 0, "<input> horizontal line scroll container.scrollLeft");
+ },
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0,
+ lineOrPageDeltaX: 1
+ }
+ },
+ {
+ check: function(event) {
+ is(event.target, container, "<input> vertical page scroll targets container");
+ ok(container.scrollTop > 0, "<input> vertical line scroll container.scrollTop");
+ is(container.scrollLeft, 0, "<input> vertical line scroll container.scrollLeft");
+ is(input.scrollTop, 0, "<input> vertical page scroll input.scrollTop");
+ is(input.scrollLeft, 0, "<input> vertical page scroll input.scrollLeft");
+ },
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0,
+ lineOrPageDeltaY: 1
+ }
+ },
+ {
+ check: function(event) {
+ is(event.target, input, "<input> horizontal page scroll targets <input>");
+ is(input.scrollTop, 0, "<input> horizontal page scroll input.scrollTop");
+ ok(input.scrollLeft > 0, "<input> horizontal page scroll input.scrollLeft");
+ is(container.scrollTop, 0, "<input> horizontal page scroll container.scrollTop");
+ is(container.scrollLeft, 0, "<input> horizontal page scroll container.scrollLeft");
+ },
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0,
+ lineOrPageDeltaX: 1
+ }
+ },
+];
+
+var i = 0;
+function nextTest()
+{
+ if (i == tests.length) {
+ SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
+ SimpleTest.finish();
+ return;
+ }
+ var test = tests[i];
+ ++i;
+ reset();
+
+ window.waitForAllPaintsFlushed(function() {
+ prepare(test.check);
+
+ sendWheelAndPaint(input, 5, 5, test.event, function() {
+ // Do nothing - we wait for the scroll event.
+ });
+ });
+}
+
+function runTests()
+{
+ nextTest();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug967796.html b/dom/events/test/test_bug967796.html
new file mode 100644
index 000000000..cf1996a45
--- /dev/null
+++ b/dom/events/test/test_bug967796.html
@@ -0,0 +1,235 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=967796
+-->
+<head>
+ <title>Test for Bug 967796</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=967796">Mozilla Bug 967796</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 967796 **/
+
+SpecialPowers.setBoolPref("dom.w3c_pointer_events.enabled", true); // Enable Pointer Events
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+var outer;
+var middle;
+var inner;
+var outside;
+var container;
+var file;
+var iframe;
+var checkRelatedTarget = false;
+var expectedRelatedEnter = null;
+var expectedRelatedLeave = null;
+var pointerentercount = 0;
+var pointerleavecount = 0;
+var pointerovercount = 0;
+var pointeroutcount = 0;
+
+function sendPointerEvent(t, elem) {
+ var r = elem.getBoundingClientRect();
+ synthesizePointer(elem, r.width / 2, r.height / 2, {type: t});
+}
+
+var expectedPointerEnterTargets = [];
+var expectedPointerLeaveTargets = [];
+
+function runTests() {
+ outer = document.getElementById("outertest");
+ middle = document.getElementById("middletest");
+ inner = document.getElementById("innertest");
+ outside = document.getElementById("outside");
+ container = document.getElementById("container");
+ file = document.getElementById("file");
+ iframe = document.getElementById("iframe");
+
+ // Make sure ESM thinks pointer is outside the test elements.
+ sendPointerEvent("pointermove", outside);
+
+ pointerentercount = 0;
+ pointerleavecount = 0;
+ pointerovercount = 0;
+ pointeroutcount = 0;
+ checkRelatedTarget = true;
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = inner;
+ expectedPointerEnterTargets = ["outertest", "middletest", "innertest"];
+ sendPointerEvent("pointermove", inner);
+ is(pointerentercount, 3, "Unexpected pointerenter event count!");
+ is(pointerovercount, 1, "Unexpected pointerover event count!");
+ is(pointeroutcount, 0, "Unexpected pointerout event count!");
+ is(pointerleavecount, 0, "Unexpected pointerleave event count!");
+ expectedRelatedEnter = inner;
+ expectedRelatedLeave = outside;
+ expectedPointerLeaveTargets = ["innertest", "middletest", "outertest"];
+ sendPointerEvent("pointermove", outside);
+ is(pointerentercount, 3, "Unexpected pointerenter event count!");
+ is(pointerovercount, 1, "Unexpected pointerover event count!");
+ is(pointeroutcount, 1, "Unexpected pointerout event count!");
+ is(pointerleavecount, 3, "Unexpected pointerleave event count!");
+
+ // Event handling over native anonymous content.
+ var r = file.getBoundingClientRect();
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = file;
+ synthesizePointer(file, r.width / 6, r.height / 2, {type: "pointermove"});
+ is(pointerentercount, 4, "Unexpected pointerenter event count!");
+ is(pointerovercount, 2, "Unexpected pointerover event count!");
+ is(pointeroutcount, 1, "Unexpected pointerout event count!");
+ is(pointerleavecount, 3, "Unexpected pointerleave event count!");
+
+ // Moving pointer over type="file" shouldn't cause pointerover/out/enter/leave events
+ synthesizePointer(file, r.width - (r.width / 6), r.height / 2, {type: "pointermove"});
+ is(pointerentercount, 4, "Unexpected pointerenter event count!");
+ is(pointerovercount, 2, "Unexpected pointerover event count!");
+ is(pointeroutcount, 1, "Unexpected pointerout event count!");
+ is(pointerleavecount, 3, "Unexpected pointerleave event count!");
+
+ expectedRelatedEnter = file;
+ expectedRelatedLeave = outside;
+ sendPointerEvent("pointermove", outside);
+ is(pointerentercount, 4, "Unexpected pointerenter event count!");
+ is(pointerovercount, 2, "Unexpected pointerover event count!");
+ is(pointeroutcount, 2, "Unexpected pointerout event count!");
+ is(pointerleavecount, 4, "Unexpected pointerleave event count!");
+
+ // Initialize iframe
+ iframe.contentDocument.documentElement.style.overflow = "hidden";
+ iframe.contentDocument.body.style.margin = "0px";
+ iframe.contentDocument.body.style.width = "100%";
+ iframe.contentDocument.body.style.height = "100%";
+ iframe.contentDocument.body.innerHTML =
+ "<div style='width: 100%; height: 50%; border: 1px solid black;'></div>" +
+ "<div style='width: 100%; height: 50%; border: 1px solid black;'></div>";
+ iframe.contentDocument.body.offsetLeft; // flush
+
+ iframe.contentDocument.body.firstChild.onpointerenter = penter;
+ iframe.contentDocument.body.firstChild.onpointerleave = pleave;
+ iframe.contentDocument.body.lastChild.onpointerenter = penter;
+ iframe.contentDocument.body.lastChild.onpointerleave = pleave;
+ r = iframe.getBoundingClientRect();
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = iframe;
+ // Move pointer inside the iframe.
+ synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointermove"},
+ iframe.contentWindow);
+ synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "pointermove"},
+ iframe.contentWindow);
+ is(pointerentercount, 7, "Unexpected pointerenter event count!");
+ expectedRelatedEnter = iframe;
+ expectedRelatedLeave = outside;
+ sendPointerEvent("pointermove", outside);
+ is(pointerleavecount, 7, "Unexpected pointerleave event count!");
+
+ // pointerdown must produce pointerenter event
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = iframe;
+ // Move pointer inside the iframe.
+ synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
+ iframe.contentWindow);
+ synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height - (r.height / 4), {type: "pointerdown"},
+ iframe.contentWindow);
+ is(pointerentercount, 10, "Unexpected pointerenter event count!");
+
+ // pointerdown + pointermove must produce single pointerenter event
+ expectedRelatedEnter = outside;
+ expectedRelatedLeave = iframe;
+ synthesizePointer(iframe.contentDocument.body, r.width / 2, r.height / 4, {type: "pointerdown"},
+ iframe.contentWindow);
+ synthesizePointer(iframe.contentDocument.body, r.width / 2 + 1, r.height / 4 + 1, {type: "pointermove"},
+ iframe.contentWindow);
+ is(pointerentercount, 11, "Unexpected pointerenter event count!");
+
+ Array.from(document.querySelectorAll('*'))
+ .concat([iframe.contentDocument.body.firstChild, iframe.contentDocument.body.lastChild])
+ .forEach((elt) => {
+ elt.onpointerenter = null;
+ elt.onpointerleave = null;
+ elt.onpointerenter = null;
+ elt.onpointerleave = null;
+ });
+ SpecialPowers.clearUserPref("dom.w3c_pointer_events.enabled"); // Disable Pointer Events
+
+ SimpleTest.finish();
+}
+
+function penter(evt) {
+ ++pointerentercount;
+ evt.stopPropagation();
+ if (expectedPointerEnterTargets.length) {
+ var t = expectedPointerEnterTargets.shift();
+ is(evt.target.id, t, "Wrong event target!");
+ }
+ is(evt.bubbles, false, evt.type + " should not bubble!");
+ is(evt.cancelable, false, evt.type + " is cancelable!");
+ is(evt.target, evt.currentTarget, "Wrong event target!");
+ ok(!evt.relatedTarget || evt.target.ownerDocument == evt.relatedTarget.ownerDocument,
+ "Leaking nodes to another document?");
+ if (checkRelatedTarget && evt.target.ownerDocument == document) {
+ is(evt.relatedTarget, expectedRelatedEnter, "Wrong related target (pointerenter)");
+ }
+}
+
+function pleave(evt) {
+ ++pointerleavecount;
+ evt.stopPropagation();
+ if (expectedPointerLeaveTargets.length) {
+ var t = expectedPointerLeaveTargets.shift();
+ is(evt.target.id, t, "Wrong event target!");
+ }
+ is(evt.bubbles, false, evt.type + " should not bubble!");
+ is(evt.cancelable, false, evt.type + " is cancelable!");
+ is(evt.target, evt.currentTarget, "Wrong event target!");
+ ok(!evt.relatedTarget || evt.target.ownerDocument == evt.relatedTarget.ownerDocument,
+ "Leaking nodes to another document?");
+ if (checkRelatedTarget && evt.target.ownerDocument == document) {
+ is(evt.relatedTarget, expectedRelatedLeave, "Wrong related target (pointerleave)");
+ }
+}
+
+function pover(evt) {
+ ++pointerovercount;
+ evt.stopPropagation();
+}
+
+function pout(evt) {
+ ++pointeroutcount;
+ evt.stopPropagation();
+}
+
+</script>
+</pre>
+<div id="container" onpointerenter="penter(event)" onpointerleave="pleave(event)"
+ onpointerout="pout(event)" onpointerover="pover(event)">
+ <div id="outside" onpointerout="event.stopPropagation()" onpointerover="event.stopPropagation()">foo</div>
+ <div id="outertest" onpointerenter="penter(event)" onpointerleave="pleave(event)"
+ onpointerout="pout(event)" onpointerover="pover(event)">
+ <div id="middletest" onpointerenter="penter(event)" onpointerleave="pleave(event)"
+ onpointerout="pout(event)" onpointerover="pover(event)">
+ <div id="innertest" onpointerenter="penter(event)" onpointerleave="pleave(event)"
+ onpointerout="pout(event)" onpointerover="pover(event)">foo</div>
+ </div>
+ </div>
+ <input type="file" id="file"
+ onpointerenter="penter(event)" onpointerleave="pleave(event)"
+ onpointerout="pout(event)" onpointerover="pover(event)">
+ <br>
+ <iframe id="iframe" width="50px" height="50px"
+ onpointerenter="penter(event)" onpointerleave="pleave(event)"
+ onpointerout="pout(event)" onpointerover="pover(event)"></iframe>
+</div>
+</body>
+</html>
diff --git a/dom/events/test/test_bug985988.html b/dom/events/test/test_bug985988.html
new file mode 100644
index 000000000..1939e52a6
--- /dev/null
+++ b/dom/events/test/test_bug985988.html
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=985988
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 985988</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 985988 **/
+
+ function handler() {
+ return false;
+ }
+
+ function reversedHandler() {
+ return true;
+ }
+
+ function test() {
+ var t = document.getElementById("testtarget");
+
+ t.onclick = handler;
+ var e = new MouseEvent("click", {cancelable: true});
+ t.dispatchEvent(e);
+ ok(e.defaultPrevented, "Should have prevented default handling.");
+
+ t.onclick = reversedHandler;
+ e = new MouseEvent("click", {cancelable: true});
+ t.dispatchEvent(e);
+ ok(!e.defaultPrevented, "Shouldn't have prevented default handling.");
+
+ // mouseover has reversed meaning for handler return value.
+ t.onmouseover = reversedHandler;
+ e = new MouseEvent("mouseover", {cancelable: true});
+ t.dispatchEvent(e);
+ ok(e.defaultPrevented, "Should have prevented default handling.");
+
+ t.onmouseover = handler;
+ e = new MouseEvent("mouseover", {cancelable: true});
+ t.dispatchEvent(e);
+ ok(!e.defaultPrevented, "Shouldn't have prevented default handling.");
+
+ // error has reversed meaning for handler return value.
+ t.onerror = reversedHandler;
+ e = new ErrorEvent("error", {cancelable: true});
+ t.dispatchEvent(e);
+ ok(e.defaultPrevented, "Should have prevented default handling.");
+
+ t.onerror = handler;
+ e = new MouseEvent("error", {cancelable: true});
+ t.dispatchEvent(e);
+ ok(!e.defaultPrevented, "Shouldn't have prevented default handling.");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(test);
+
+ </script>
+</head>
+<body onload="test()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=985988">Mozilla Bug 985988</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<a href="#" id="testtarget">test target</a>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_bug998809.html b/dom/events/test/test_bug998809.html
new file mode 100644
index 000000000..08499d2c7
--- /dev/null
+++ b/dom/events/test/test_bug998809.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=998809
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 998809</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 998809 **/
+ var event1 = document.createEvent("Event");
+ event1.initEvent("a", false, false);
+ event1.initEvent("b", false, false);
+ is(event1.type, "b");
+ var event2 = document.createEvent("Event");
+ event2.initEvent("a", false, false);
+ is(event2.type, "a");
+ event2.initEvent("b", false, false);
+ is(event2.type, "b");
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=998809">Mozilla Bug 998809</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_clickevent_on_input.html b/dom/events/test/test_clickevent_on_input.html
new file mode 100644
index 000000000..07fe6ade6
--- /dev/null
+++ b/dom/events/test/test_clickevent_on_input.html
@@ -0,0 +1,111 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test click event on input</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display">
+<input id="input"
+ style="position: absolute; top: 5px; left: 5px; border: solid 15px blue; width: 100px; height: 20px;"
+ onclick="gClickCount++;">
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+var gClickCount = 0;
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+
+var input = document.getElementById("input");
+
+function runTests()
+{
+ for (var i = 0; i < 3; i++) {
+ doTest(i);
+ }
+
+ // Re-test left clicking when the input element has some text.
+ gClickCount = 0;
+ input.value = "Long text Long text Long text Long text Long text Long text";
+ doTest(0);
+
+ input.style.display = "none";
+ SimpleTest.finish();
+}
+
+function isEnabledMiddleClickPaste()
+{
+ try {
+ return SpecialPowers.getBoolPref("middlemouse.paste");
+ } catch (e) {
+ return false;
+ }
+}
+
+function isEnabledAccessibleCaret()
+{
+ try {
+ return SpecialPowers.getBoolPref("layout.accessiblecaret.enabled");
+ } catch (e) {
+ return false;
+ }
+}
+
+function doTest(aButton)
+{
+ // NOTE #1: Right click causes a context menu to popup, then, the click event
+ // isn't generated.
+ // NOTE #2: If middle click causes text to be pasted, then, the click event
+ // isn't generated.
+ // NOTE #3: If touch caret is enabled, touch caret would ovelap input element,
+ // then, the click event isn't generated.
+ if (aButton != 2 &&
+ (aButton != 1 || !isEnabledMiddleClickPaste()) &&
+ (aButton != 0 || !isEnabledAccessibleCaret())) {
+ gClickCount = 0;
+ // click on border of input
+ synthesizeMouse(input, 5, 5, { button: aButton });
+ is(gClickCount, 1,
+ "click event doesn't fired on input element (button is " +
+ aButton + ")");
+
+ gClickCount = 0;
+ // down on border
+ synthesizeMouse(input, 5, 5, { type: "mousedown", button: aButton });
+ // up on anonymous div of input
+ synthesizeMouse(input, 20, 20, { type: "mouseup", button: aButton });
+ is(gClickCount, 1,
+ "click event doesn't fired on input element (button is " +
+ aButton + ")");
+
+ gClickCount = 0;
+ // down on anonymous div of input
+ synthesizeMouse(input, 20, 20, { type: "mousedown", button: aButton });
+ // up on border
+ synthesizeMouse(input, 5, 5, { type: "mouseup", button: aButton });
+ is(gClickCount, 1,
+ "click event doesn't fired on input element (button is " +
+ aButton + ")");
+ }
+
+ gClickCount = 0;
+ // down on outside of input
+ synthesizeMouse(input, -3, -3, { type: "mousedown", button: aButton });
+ // up on border
+ synthesizeMouse(input, 5, 5, { type: "mouseup", button: aButton });
+ is(gClickCount, 0,
+ "click event is fired on input element unexpectedly (button is " +
+ aButton + ")");
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_continuous_wheel_events.html b/dom/events/test/test_continuous_wheel_events.html
new file mode 100644
index 000000000..fc8c69390
--- /dev/null
+++ b/dom/events/test/test_continuous_wheel_events.html
@@ -0,0 +1,3248 @@
+<!DOCTYPE HTML>
+<html style="font-size: 32px;">
+<head>
+ <title>Test for D3E WheelEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="scrollable" style="font-family:monospace; font-size: 18px; line-height: 1; overflow: auto; width: 200px; height: 200px;">
+ <div id="scrolled" style="font-size: 64px; width: 5000px; height: 5000px;">
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ </div>
+</div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests, window);
+
+var gScrollableElement = document.getElementById("scrollable");
+var gScrolledElement = document.getElementById("scrolled");
+
+var gLineHeight = 0;
+var gHorizontalLine = 0;
+var gPageHeight = 0;
+var gPageWidth = 0;
+
+function sendWheelAndWait(aX, aY, aEvent)
+{
+ sendWheelAndPaint(gScrollableElement, aX, aY, aEvent, continueTest);
+}
+
+function* prepareScrollUnits()
+{
+ var result = -1;
+ function handler(aEvent)
+ {
+ result = aEvent.detail;
+ aEvent.preventDefault();
+ }
+ window.addEventListener("MozMousePixelScroll", handler, true);
+
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gLineHeight = result;
+ ok(gLineHeight > 10 && gLineHeight < 25, "prepareScrollUnits: gLineHeight may be illegal value, got " + gLineHeight);
+
+ result = -1;
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gHorizontalLine = result;
+ ok(gHorizontalLine > 5 && gHorizontalLine < 16, "prepareScrollUnits: gHorizontalLine may be illegal value, got " + gHorizontalLine);
+
+ result = -1;
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gPageHeight = result;
+ // XXX Cannot we know the actual scroll port size?
+ ok(gPageHeight >= 150 && gPageHeight <= 200,
+ "prepareScrollUnits: gPageHeight is strange value, got " + gPageHeight);
+
+ result = -1;
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gPageWidth = result;
+ ok(gPageWidth >= 150 && gPageWidth <= 200,
+ "prepareScrollUnits: gPageWidth is strange value, got " + gPageWidth);
+
+ window.removeEventListener("MozMousePixelScroll", handler, true);
+}
+
+// Tests continuous trusted wheel events. Trusted wheel events should cause
+// legacy mouse scroll events when its lineOrPageDelta value is not zero or
+// accumulated delta values of pixel scroll events of pixel only device
+// become over the line height.
+function* testContinuousTrustedEvents()
+{
+ const kSynthesizedWheelEventTests = [
+ { description: "Simple horizontal wheel event by pixels (16.0 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 16 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by pixels (16.0 - 1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 16 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by pixels (16.0 - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 16 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple vertical wheel event by pixels (16.0 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 16.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 16.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 16 } }
+ },
+ { description: "Simple vertical wheel event by pixels (16.0 - 1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 16.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 16.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 16 } }
+ },
+ { description: "Simple vertical wheel event by pixels (16.0 - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 16.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 16.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 16 } }
+ },
+
+ { description: "Simple z-direction wheel event by pixels (16.0 - 1)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple horizontal wheel event by pixels (-16.0 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -16.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -16 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by pixels (-16.0 - -1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -16.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -16 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by pixels (-16.0 - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -16.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -16 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple vertical wheel event by pixels (-16.0 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -16.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -16.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -16 } }
+ },
+ { description: "Simple vertical wheel event by pixels (-16.0 - -1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -16.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -16.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -16 } }
+ },
+ { description: "Simple vertical wheel event by pixels (-16.0 - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -16.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -16.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -16 } }
+ },
+
+ { description: "Simple z-direction wheel event by pixels (-16.0 - -1)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: -16.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: -16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ // 3 scroll events per line, and legacy line scroll will be fired first.
+ { description: "Horizontal wheel event by pixels (5.3 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Vertical wheel event by pixels (5.3 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Vertical wheel event by pixels (5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Vertical wheel event by pixels (5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+
+ { description: "Horizontal wheel event by pixels (-5.3 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (-5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (-5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Vertical wheel event by pixels (-5.3 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Vertical wheel event by pixels (-5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Vertical wheel event by pixels (-5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+
+ // 3 scroll events per line, and legacy line scroll will be fired last.
+ { description: "Horizontal wheel event by pixels (5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (5.3 - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Vertical wheel event by pixels (5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Vertical wheel event by pixels (5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Vertical wheel event by pixels (5.3 - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+
+ { description: "Horizontal wheel event by pixels (-5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (-5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Horizontal wheel event by pixels (-5.3 - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Vertical wheel event by pixels (-5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Vertical wheel event by pixels (-5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Vertical wheel event by pixels (-5.3 - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+
+ // Oblique scroll.
+ { description: "To bottom-right wheel event by pixels (5.3/5.2 - 1/1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 5.2, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 5.2, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "To bottom-right wheel event by pixels (5.3/5.2 - 0/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 5.2, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 5.2, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "To bottom-right wheel event by pixels (5.3/5.2 - 0/0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 5.2, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 5.2, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+
+ { description: "To bottom-left wheel event by pixels (-5.3/5.3 - -1/1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "To bottom-left wheel event by pixels (-5.3/5.3 - 0/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "To bottom-left wheel event by pixels (-5.3/5.3 - 0/0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+
+ { description: "To top-left wheel event by pixels (-5.2/-5.3 - -1/-1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.2, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.2, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "To top-left wheel event by pixels (-5.2/-5.3 - 0/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.2, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.2, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "To top-left wheel event by pixels (-5.2/-5.3 - 0/0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.2, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.2, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+
+ { description: "To top-right wheel event by pixels (5.3/-5.3 - 1/-1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "To top-right wheel event by pixels (5.3/-5.3 - 0/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+
+ // Pixel scroll only device's test. the lineOrPageDelta values should be computed
+ // by ESM. When changing the direction for each delta value, it should be
+ // reset at that time.
+ { description: "Pixel only device's horizontal wheel event by pixels (5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Pixel only device's horizontal wheel event by pixels (5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Pixel only device's horizontal wheel event by pixels (5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (5.3 - 0) #4",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 1.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (5.3 - 1) #5",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 5 } }
+ },
+
+ { description: "Pixel only device's horizontal wheel event by pixels (-5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Pixel only device's horizontal wheel event by pixels (-5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Pixel only device's horizontal wheel event by pixels (-5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Pixel only device's Vertical wheel event by pixels (-5.3 - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (-5.3 - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (-5.3 - 0) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (-5.3 - 0) #4",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -1.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } }
+ },
+ { description: "Pixel only device's Vertical wheel event by pixels (-5.3 - -1) #5",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -5.3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -5 } }
+ },
+
+ // ESM should reset an accumulated delta value only when the direction of it
+ // is changed but shouldn't reset the other delta.
+ { description: "Pixel only device's bottom-right wheel event by pixels (5.3/4.9 - 0/0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: 4 } }
+ },
+ { description: "Pixel only device's bottom-right wheel event by pixels (5.3/4.9 - 0/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: 4 } }
+ },
+ { description: "Pixel only device's bottom-left wheel event by pixels (-5.3/4.9 - 0/0) #4",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: 4 } }
+ },
+ // the accumulated X should be 0 here, but Y shouldn't be reset.
+ { description: "Pixel only device's bottom-right wheel event by pixels (5.3/4.9 - 0/0) #5",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 5.3, deltaY: 1.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 5.3, deltaY: 1.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 5 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } }
+ },
+
+ { description: "Pixel only device's top-left wheel event by pixels (-5.3/-4.9 - 0/0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: -4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: -4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: -4 } }
+ },
+ { description: "Pixel only device's top-left wheel event by pixels (-5.3/-4.9 - 0/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: -4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: -4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: -4 } }
+ },
+ { description: "Pixel only device's bottom-left wheel event by pixels (-5.3/4.9 - 0/0) #4",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: 4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: 4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: 4 } }
+ },
+ // the accumulated Y should be 0 here, but X shouldn't be reset.
+ { description: "Pixel only device's top-left wheel event by pixels (-5.3/-4.9 - 0/0) #5",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -5.3, deltaY: -4.9, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: true,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -5.3, deltaY: -4.9, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -5 },
+ vertical: { expected: true, preventDefault: false, detail: -4 } }
+ },
+
+ // Simple line scroll tests.
+ { description: "Simple horizontal wheel event by lines (1.0 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gHorizontalLine },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by lines (1.0 - 1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gHorizontalLine },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple horizontal wheel event by lines (-1.0 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -gHorizontalLine },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by lines (-1.0 - -1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -gHorizontalLine },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple vertical wheel event by lines (-1.0 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -gLineHeight } }
+ },
+ { description: "Simple vertical wheel event by lines (-1.0 - -1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -gLineHeight } }
+ },
+
+ { description: "Simple vertical wheel event by lines (1.0 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: gLineHeight } }
+ },
+ { description: "Simple vertical wheel event by lines (1.0 - 1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: gLineHeight } }
+ },
+
+ // high resolution line scroll
+ { description: "High resolution horizontal wheel event by lines (0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by lines (0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by lines (0.333... - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "High resolution horizontal wheel event by lines (-0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -Math.floor(gHorizontalLine / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by lines (-0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -Math.floor(gHorizontalLine / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by lines (-0.333... - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -Math.floor(gHorizontalLine / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "High resolution vertical wheel event by lines (0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by lines (0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by lines (0.333... - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 3) } }
+ },
+
+ { description: "High resolution vertical wheel event by lines (-0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -Math.floor(gLineHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by lines (-0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -Math.floor(gLineHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by lines (-0.333... - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -Math.floor(gLineHeight / 3) } }
+ },
+
+ // Oblique line scroll
+ { description: "Oblique wheel event by lines (-1.0/2.0 - -1/2)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 2.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 2, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0, deltaY: 2.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: true, preventDefault: false, detail: 2 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -gHorizontalLine },
+ vertical: { expected: true, preventDefault: false, detail: gLineHeight * 2 } }
+ },
+
+ { description: "Oblique wheel event by lines (1.0/-2.0 - 1/-2)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: -2.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: -2, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: -2.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: -2 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: false, detail: -gLineHeight * 2 } }
+ },
+
+ { description: "High resolution oblique wheel event by lines (0.5/0.333.../-0.8 - 0/0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 3) } }
+ },
+ { description: "High resolution oblique wheel event by lines (0.5/0.333.../-0.8 - 1/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 3) } }
+ },
+ { description: "High resolution oblique wheel event by lines (0.5/0.333.../-0.8 - 0/1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 3) } }
+ },
+
+ // Simple page scroll tests.
+ { description: "Simple horizontal wheel event by pages (1.0 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gPageWidth },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by pages (1.0 - 1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gPageWidth },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple horizontal wheel event by pages (-1.0 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -gPageWidth },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "Simple horizontal wheel event by pages (-1.0 - -1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -gPageWidth },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "Simple vertical wheel event by pages (-1.0 - -1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -gPageHeight } }
+ },
+ { description: "Simple vertical wheel event by pages (-1.0 - -1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -gPageHeight } }
+ },
+
+ { description: "Simple vertical wheel event by pages (1.0 - 1) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: gPageHeight } }
+ },
+ { description: "Simple vertical wheel event by pages (1.0 - 1) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: gPageHeight } }
+ },
+
+ // high resolution page scroll
+ { description: "High resolution horizontal wheel event by pages (0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by pages (0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by pages (0.333... - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "High resolution horizontal wheel event by pages (-0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -Math.floor(gPageWidth / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by pages (-0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -Math.floor(gPageWidth / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+ { description: "High resolution horizontal wheel event by pages (-0.333... - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0 / 3, deltaY: 0.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -Math.floor(gPageWidth / 3) },
+ vertical: { expected: false, preventDefault: false, detail: 0 } }
+ },
+
+ { description: "High resolution vertical wheel event by pages (0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by pages (0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by pages (0.333... - 1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: 1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight / 3) } }
+ },
+
+ { description: "High resolution vertical wheel event by pages (-0.333... - 0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -Math.floor(gPageHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by pages (-0.333... - 0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -Math.floor(gPageHeight / 3) } }
+ },
+ { description: "High resolution vertical wheel event by pages (-0.333... - -1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.0, deltaY: -1.0 / 3, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -Math.floor(gPageHeight / 3) } }
+ },
+
+ // Oblique page scroll
+ { description: "Oblique wheel event by pages (-1.0/2.0 - -1/2)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 2.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 2, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -1.0, deltaY: 2.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -gPageWidth },
+ vertical: { expected: true, preventDefault: false, detail: gPageHeight * 2 } }
+ },
+
+ { description: "Oblique wheel event by pages (1.0/-2.0 - 1/-2)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: -2.0, deltaZ: 0.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: -2, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: -2.0, deltaZ: 0.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: false, detail: -gPageHeight * 2 } }
+ },
+
+ { description: "High resolution oblique wheel event by pages (0.5/0.333.../-0.8 - 0/0) #1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth / 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight / 3) } }
+ },
+ { description: "High resolution oblique wheel event by pages (0.5/0.333.../-0.8 - 1/0) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth / 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight / 3) } }
+ },
+ { description: "High resolution oblique wheel event by pages (0.5/0.333.../-0.8 - 0/1) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8, isMomentum: false,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.5, deltaY: 1.0 / 3, deltaZ: -0.8
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth / 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight / 3) } }
+ },
+
+ // preventDefault() shouldn't prevent other legacy events.
+ { description: "preventDefault() shouldn't prevent other legacy events (pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 1 },
+ vertical: { expected: true, preventDefault: true, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 16 },
+ vertical: { expected: true, preventDefault: true, detail: 16 } },
+ },
+ { description: "preventDefault() shouldn't prevent other legacy events (line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 1 },
+ vertical: { expected: true, preventDefault: true, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: true, detail: gLineHeight } },
+ },
+ { description: "preventDefault() shouldn't prevent other legacy events (page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: true, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: true, detail: gPageHeight } },
+ },
+
+ // If wheel event is consumed by preventDefault(), legacy events are not necessary.
+ { description: "If wheel event is consumed by preventDefault(), legacy events are not necessary (pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: true,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ },
+ { description: "If wheel event is consumed by preventDefault(), legacy events are not necessary (line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: true,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ },
+ { description: "If wheel event is consumed by preventDefault(), legacy events are not necessary (page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: true,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ },
+
+ // modifier key state tests
+ { description: "modifier key tests (shift, pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 16 },
+ vertical: { expected: true, preventDefault: true, detail: 16 } },
+ },
+ { description: "modifier key tests (shift, line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: true, detail: gLineHeight } },
+ },
+ { description: "modifier key tests (shift, page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: true, detail: gPageHeight } },
+ },
+
+ { description: "modifier key tests (ctrl, pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 16 },
+ vertical: { expected: true, preventDefault: true, detail: 16 } },
+ },
+ { description: "modifier key tests (ctrl, line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: true, detail: gLineHeight } },
+ },
+ { description: "modifier key tests (ctrl, page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: true, detail: gPageHeight } },
+ },
+
+ { description: "modifier key tests (alt, pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: true, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 16 },
+ vertical: { expected: true, preventDefault: true, detail: 16 } },
+ },
+ { description: "modifier key tests (alt, line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: true, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: true, detail: gLineHeight } },
+ },
+ { description: "modifier key tests (alt, page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: true, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: true, detail: gPageHeight } },
+ },
+
+ { description: "modifier key tests (meta, pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: true },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: 16 },
+ vertical: { expected: true, preventDefault: true, detail: 16 } },
+ },
+ { description: "modifier key tests (meta, line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: true },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: true, detail: gLineHeight } },
+ },
+ { description: "modifier key tests (meta, page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: true,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: true, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: true, detail: gPageHeight } },
+ },
+
+ // Momentum scroll should cause legacy events.
+ { description: "Momentum scroll should cause legacy events (pixel, not momentum)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 16 },
+ vertical: { expected: true, preventDefault: false, detail: 16 } },
+ },
+ { description: "Momentum scroll should cause legacy events (pixel, momentum)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0, isMomentum: true,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 16.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 16 },
+ vertical: { expected: true, preventDefault: false, detail: 16 } },
+ },
+ { description: "Momentum scroll should cause legacy events (line, not momentum)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: false, detail: gLineHeight } },
+ },
+ { description: "Momentum scroll should cause legacy events (line, momentum)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: true,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gHorizontalLine },
+ vertical: { expected: true, preventDefault: false, detail: gLineHeight } },
+ },
+ { description: "Momentum scroll should cause legacy events (page, not momentum)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: false,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: false, detail: gPageHeight } },
+ },
+ { description: "Momentum scroll should cause legacy events (page, momentum)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, isMomentum: true,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: gPageWidth },
+ vertical: { expected: true, preventDefault: false, detail: gPageHeight } },
+ },
+
+ // Tests for accumulation delta when delta_multiplier_is customized.
+ { description: "lineOrPageDelta should be recomputed by ESM (pixel) #1",
+ prepare: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 200],
+ ["mousewheel.default.delta_multiplier_y", 300]]},
+ continueTest);
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: gHorizontalLine / 4, deltaY: gLineHeight / 8, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: gHorizontalLine / 4 * 2, deltaY: gLineHeight / 8 * 3, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine / 4 * 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight / 8 * 3) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (pixel) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: gHorizontalLine / 4 + 1, deltaY: gLineHeight / 8 + 1, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: (gHorizontalLine / 4 + 1) * 2, deltaY: (gLineHeight / 8 + 1) * 3, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor((gHorizontalLine / 4 + 1) * 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor((gLineHeight / 8 + 1) * 3) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (pixel) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: gHorizontalLine / 4 + 1, deltaY: gLineHeight / 8 + 1, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: (gHorizontalLine / 4 + 1) * 2, deltaY: (gLineHeight / 8 + 1) * 3, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor((gHorizontalLine / 4 + 1) * 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor((gLineHeight / 8 + 1) * 3) } },
+ finished: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ },
+
+ { description: "lineOrPageDelta should be recomputed by ESM (pixel, negative, shift) #1",
+ prepare: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.with_shift.delta_multiplier_x", 200],
+ ["mousewheel.with_shift.delta_multiplier_y", 300]]},
+ continueTest);
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -gHorizontalLine / 4, deltaY: -gLineHeight / 8, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -gHorizontalLine / 4 * 2, deltaY: -gLineHeight / 8 * 3, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(-gHorizontalLine / 4 * 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.ceil(-gLineHeight / 8 * 3) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (pixel, negative, shift) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -(gHorizontalLine / 4 + 1), deltaY: -(gLineHeight / 8 + 1), deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -(gHorizontalLine / 4 + 1) * 2, deltaY: -(gLineHeight / 8 + 1) * 3, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(-(gHorizontalLine / 4 + 1) * 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.ceil(-(gLineHeight / 8 + 1) * 3) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (pixel, negative, shift) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -(gHorizontalLine / 4 + 1), deltaY: -(gLineHeight / 8 + 1), deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -(gHorizontalLine / 4 + 1) * 2, deltaY: -(gLineHeight / 8 + 1) * 3, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: -1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(-(gHorizontalLine / 4 + 1) * 2) },
+ vertical: { expected: true, preventDefault: false, detail: Math.ceil(-(gLineHeight / 8 + 1) * 3) } },
+ finished: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.with_shift.delta_multiplier_x", 100],
+ ["mousewheel.with_shift.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ },
+
+ { description: "lineOrPageDelta should be recomputed by ESM (line) #1",
+ prepare: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 200],
+ ["mousewheel.default.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.3, deltaY: 0.4, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.6, deltaY: 0.4, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine * 0.6) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight * 0.4) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (line) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.3, deltaY: 0.4, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.6, deltaY: 0.4, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: 1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine * 0.6) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight * 0.4) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (line) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.3, deltaY: 0.4, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.6, deltaY: 0.4, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gHorizontalLine * 0.6) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight * 0.4) } },
+ finished: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ },
+
+ { description: "lineOrPageDelta should be recomputed by ESM (line, negative) #1",
+ prepare: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 200],
+ ["mousewheel.default.delta_multiplier_y", -100]]},
+ continueTest);
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.3, deltaY: -0.4, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -0.6, deltaY: 0.4, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(gHorizontalLine * -0.6) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight * 0.4) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (line, negative) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.3, deltaY: -0.4, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -0.6, deltaY: 0.4, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: -1 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(gHorizontalLine * -0.6) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight * 0.4) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (line, negative) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.3, deltaY: -0.4, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -0.6, deltaY: 0.4, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: 1 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(gHorizontalLine * -0.6) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gLineHeight * 0.4) } },
+ finished: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ },
+
+ { description: "lineOrPageDelta should be recomputed by ESM (page) #1",
+ prepare: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 200]]},
+ continueTest);
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.3, deltaY: 0.4, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.3, deltaY: 0.8, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth * 0.3) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight * 0.8) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (page) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.3, deltaY: 0.4, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.3, deltaY: 0.8, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth * 0.3) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight * 0.8) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (page) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.4, deltaY: 0.4, deltaZ: 0,
+ lineOrPageDeltaX: 3, lineOrPageDeltaY: 5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: 0.4, deltaY: 0.8, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_DOWN } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.floor(gPageWidth * 0.4) },
+ vertical: { expected: true, preventDefault: false, detail: Math.floor(gPageHeight * 0.8) } },
+ finished: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ },
+
+ { description: "lineOrPageDelta should be recomputed by ESM (page, negative) #1",
+ prepare: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 200]]},
+ continueTest);
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.3, deltaY: -0.4, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -0.3, deltaY: -0.8, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: false, preventDefault: false, detail: 0 } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(gPageWidth * -0.3) },
+ vertical: { expected: true, preventDefault: false, detail: Math.ceil(gPageHeight * -0.8) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (page, negative) #2",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.3, deltaY: -0.4, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -0.3, deltaY: -0.8, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: false, preventDefault: false, detail: 0 },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(gPageWidth * -0.3) },
+ vertical: { expected: true, preventDefault: false, detail: Math.ceil(gPageHeight * -0.8) } },
+ },
+ { description: "lineOrPageDelta should be recomputed by ESM (page, negative) #3",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.4, deltaY: -0.4, deltaZ: 0,
+ lineOrPageDeltaX: -3, lineOrPageDeltaY: -5, isNoLineOrPageDelta: false,
+ isCustomizedByPrefs: false,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false },
+ wheel: {
+ expected: true, preventDefault: false,
+ deltaX: -0.4, deltaY: -0.8, deltaZ: 0
+ },
+ DOMMouseScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP },
+ vertical: { expected: true, preventDefault: false, detail: UIEvent.SCROLL_PAGE_UP } },
+ MozMousePixelScroll: {
+ horizontal: { expected: true, preventDefault: false, detail: Math.ceil(gPageWidth * -0.4) },
+ vertical: { expected: true, preventDefault: false, detail: Math.ceil(gPageHeight * -0.8) } },
+ finished: function () {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100]]},
+ continueTest);
+ },
+ },
+ ];
+
+ var currentWheelEventTest;
+ var calledHandlers = { wheel: false,
+ DOMMouseScroll: { horizontal: false, vertical: false },
+ MozMousePixelScroll: { horizontal: false, vertical: false } };
+
+ function wheelEventHandler(aEvent)
+ {
+ var description = "testContinuousTrustedEvents, ";
+ description += currentWheelEventTest.description + ": wheel event ";
+
+ ok(!calledHandlers.wheel,
+ description + "was fired twice or more");
+ calledHandlers.wheel = true;
+
+ is(aEvent.target, gScrolledElement,
+ description + "target was invalid");
+ is(aEvent.deltaMode, currentWheelEventTest.event.deltaMode,
+ description + "deltaMode was invalid");
+ is(aEvent.deltaX, currentWheelEventTest.wheel.deltaX,
+ description + "deltaX was invalid");
+ is(aEvent.deltaY, currentWheelEventTest.wheel.deltaY,
+ description + "deltaY was invalid");
+ is(aEvent.deltaZ, currentWheelEventTest.wheel.deltaZ,
+ description + "deltaZ was invalid");
+ is(aEvent.shiftKey, currentWheelEventTest.event.shiftKey,
+ description + "shiftKey was invalid");
+ is(aEvent.ctrlKey, currentWheelEventTest.event.ctrlKey,
+ description + "ctrlKey was invalid");
+ is(aEvent.altKey, currentWheelEventTest.event.altKey,
+ description + "shiftKey was invalid");
+ is(aEvent.metaKey, currentWheelEventTest.event.metaKey,
+ description + "metaKey was invalid");
+
+ ok(!aEvent.defaultPrevented,
+ description + "defaultPrevented should be false");
+ if (currentWheelEventTest.wheel.preventDefault) {
+ aEvent.preventDefault();
+ ok(aEvent.defaultPrevented,
+ description + "defaultPrevented should be true");
+ }
+ }
+
+ function legacyEventHandler(aEvent)
+ {
+ var description = "testContinuousTrustedEvents, ";
+ description += currentWheelEventTest.description + ": " + aEvent.type + " event ";
+
+ if (aEvent.axis != MouseScrollEvent.HORIZONTAL_AXIS &&
+ aEvent.axis != MouseScrollEvent.VERTICAL_AXIS) {
+ ok(false,
+ description + "had invalid axis (" + aEvent.axis + ")");
+ return;
+ }
+
+ var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS);
+
+ description += isHorizontal ? "(horizontal) " : "(vertical) ";
+
+ var isScrollEvent = (aEvent.type == "DOMMouseScroll");
+ var expectedEvent =
+ isScrollEvent ? currentWheelEventTest.DOMMouseScroll :
+ currentWheelEventTest.MozMousePixelScroll;
+ var expected =
+ isHorizontal ? expectedEvent.horizontal : expectedEvent.vertical;
+
+ if (aEvent.type == "DOMMouseScroll") {
+ if (isHorizontal) {
+ ok(!calledHandlers.DOMMouseScroll.horizontal,
+ description + "was fired twice or more");
+ calledHandlers.DOMMouseScroll.horizontal = true;
+ } else {
+ ok(!calledHandlers.DOMMouseScroll.vertical,
+ description + "was fired twice or more");
+ calledHandlers.DOMMouseScroll.vertical = true;
+ }
+ } else {
+ if (isHorizontal) {
+ ok(!calledHandlers.MozMousePixelScroll.horizontal,
+ description + "was fired twice or more");
+ calledHandlers.MozMousePixelScroll.horizontal = true;
+ } else {
+ ok(!calledHandlers.MozMousePixelScroll.vertical,
+ description + "was fired twice or more");
+ calledHandlers.MozMousePixelScroll.vertical = true;
+ }
+ }
+
+ is(aEvent.target, gScrolledElement,
+ description + "target was invalid");
+ is(aEvent.detail, expected.detail,
+ description + "detail was invalid");
+
+ is(aEvent.shiftKey, currentWheelEventTest.event.shiftKey,
+ description + "shiftKey was invalid");
+ is(aEvent.ctrlKey, currentWheelEventTest.event.ctrlKey,
+ description + "ctrlKey was invalid");
+ is(aEvent.altKey, currentWheelEventTest.event.altKey,
+ description + "shiftKey was invalid");
+ is(aEvent.metaKey, currentWheelEventTest.event.metaKey,
+ description + "metaKey was invalid");
+
+ var expectedDefaultPrevented =
+ isScrollEvent ? false :
+ isHorizontal ? currentWheelEventTest.DOMMouseScroll.horizontal.preventDefault :
+ currentWheelEventTest.DOMMouseScroll.vertical.preventDefault;
+ is(aEvent.defaultPrevented, expectedDefaultPrevented,
+ description + "defaultPrevented should be " + expectedDefaultPrevented);
+
+ if (expected.preventDefault) {
+ aEvent.preventDefault();
+ ok(aEvent.defaultPrevented,
+ description + "defaultPrevented should be true");
+ }
+ }
+
+ window.addEventListener("wheel", wheelEventHandler, true);
+ window.addEventListener("DOMMouseScroll", legacyEventHandler, true);
+ window.addEventListener("MozMousePixelScroll", legacyEventHandler, true);
+
+ for (var i = 0; i < kSynthesizedWheelEventTests.length; i++) {
+ gScrollableElement.scrollTop = gScrollableElement.scrollBottom = 1000;
+
+ currentWheelEventTest = kSynthesizedWheelEventTests[i];
+
+ if (currentWheelEventTest.prepare) {
+ yield currentWheelEventTest.prepare();
+ }
+
+ yield sendWheelAndWait(10, 10, currentWheelEventTest.event);
+
+ if (currentWheelEventTest.finished) {
+ yield currentWheelEventTest.finished();
+ }
+
+ var description = "testContinuousTrustedEvents, " +
+ currentWheelEventTest.description + ": ";
+ is(calledHandlers.wheel, currentWheelEventTest.wheel.expected,
+ description + "wheel event was fired or not fired");
+ is(calledHandlers.DOMMouseScroll.horizontal,
+ currentWheelEventTest.DOMMouseScroll.horizontal.expected,
+ description + "horizontal DOMMouseScroll event was fired or not fired");
+ is(calledHandlers.DOMMouseScroll.vertical,
+ currentWheelEventTest.DOMMouseScroll.vertical.expected,
+ description + "vertical DOMMouseScroll event was fired or not fired");
+ is(calledHandlers.MozMousePixelScroll.horizontal,
+ currentWheelEventTest.MozMousePixelScroll.horizontal.expected,
+ description + "horizontal MozMousePixelScroll event was fired or not fired");
+ is(calledHandlers.MozMousePixelScroll.vertical,
+ currentWheelEventTest.MozMousePixelScroll.vertical.expected,
+ description + "vertical MozMousePixelScroll event was fired or not fired");
+
+ calledHandlers = { wheel: false,
+ DOMMouseScroll: { horizontal: false, vertical: false },
+ MozMousePixelScroll: { horizontal: false, vertical: false } };
+ }
+
+ window.removeEventListener("wheel", wheelEventHandler, true);
+ window.removeEventListener("DOMMouseScroll", legacyEventHandler, true);
+ window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true);
+}
+
+var gTestContinuation = null;
+
+function continueTest()
+{
+ if (!gTestContinuation) {
+ gTestContinuation = testBody();
+ }
+ var ret = gTestContinuation.next();
+ if (ret.done) {
+ SimpleTest.finish();
+ }
+}
+
+function* testBody()
+{
+ yield* prepareScrollUnits();
+ yield* testContinuousTrustedEvents();
+}
+
+function runTests()
+{
+ SpecialPowers.pushPrefEnv({"set": [
+ ["mousewheel.transaction.timeout", 100000],
+ ["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100],
+ ["mousewheel.default.delta_multiplier_z", 100],
+ ["mousewheel.with_alt.delta_multiplier_x", 100],
+ ["mousewheel.with_alt.delta_multiplier_y", 100],
+ ["mousewheel.with_alt.delta_multiplier_z", 100],
+ ["mousewheel.with_control.delta_multiplier_x", 100],
+ ["mousewheel.with_control.delta_multiplier_y", 100],
+ ["mousewheel.with_control.delta_multiplier_z", 100],
+ ["mousewheel.with_meta.delta_multiplier_x", 100],
+ ["mousewheel.with_meta.delta_multiplier_y", 100],
+ ["mousewheel.with_meta.delta_multiplier_z", 100],
+ ["mousewheel.with_shift.delta_multiplier_x", 100],
+ ["mousewheel.with_shift.delta_multiplier_y", 100],
+ ["mousewheel.with_shift.delta_multiplier_z", 100],
+ ["mousewheel.with_win.delta_multiplier_x", 100],
+ ["mousewheel.with_win.delta_multiplier_y", 100],
+ ["mousewheel.with_win.delta_multiplier_z", 100]
+ ]}, continueTest);
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_dblclick_explicit_original_target.html b/dom/events/test/test_dblclick_explicit_original_target.html
new file mode 100644
index 000000000..8aa5f5d4c
--- /dev/null
+++ b/dom/events/test/test_dblclick_explicit_original_target.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test explicit original target of dblclick event</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display">Test explicit original target of dblclick event</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+
+function runTests()
+{
+ synthesizeMouse(document.getElementById("display"), 5, 5, { clickCount: 2 });
+}
+
+window.ondblclick = function(event) {
+ is(event.explicitOriginalTarget.nodeType, Node.TEXT_NODE, "explicitOriginalTarget is a text node");
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_activate_event.html b/dom/events/test/test_dom_activate_event.html
new file mode 100644
index 000000000..22e32d988
--- /dev/null
+++ b/dom/events/test/test_dom_activate_event.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test DOMActivate event</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display">
+<a id="a" href="#dummy">link</a>
+<button id="button">button</button>
+<input id="checkbox" type="checkbox">
+<input id="radio" type="radio">
+<input id="submit" type="submit">
+<input id="ibutton" type="button">
+<input id="reset" type="reset">
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests);
+
+function runIsTrustedTestCausedByTrustedClick(aElement, aNextTest)
+{
+ const kDescription = "runIsTrustedTestCausedByTrustedClick(aElement.id=" + aElement.id + "): ";
+ var DOMActivateFired = false;
+ aElement.addEventListener("DOMActivate", function (aEvent) {
+ DOMActivateFired = true;
+ ok(aEvent.isTrusted, kDescription + "DOMActivate event should be trusted event");
+ aElement.removeEventListener("DOMActivate", arguments.callee);
+ aNextTest();
+ });
+ aElement.addEventListener("click", function (aEvent) {
+ ok(aEvent.isTrusted, kDescription + "click event should be trusted event");
+ aElement.removeEventListener("click", arguments.callee);
+ });
+ synthesizeMouseAtCenter(aElement, {});
+}
+
+function runIsTrustedTestCausedByUntrustedClick(aElement, aNextTest)
+{
+ const kDescription = "runIsTrustedTestCausedByUntrustedClick(aElement.id=" + aElement.id + "): ";
+ var DOMActivateFired = false;
+ aElement.addEventListener("DOMActivate", function (aEvent) {
+ DOMActivateFired = true;
+ ok(aEvent.isTrusted,
+ kDescription + "DOMActivate event should be trusted event even if it's caused by untrusted event");
+ aElement.removeEventListener("DOMActivate", arguments.callee);
+ aNextTest();
+ });
+ aElement.addEventListener("click", function (aEvent) {
+ ok(!aEvent.isTrusted, kDescription + "click event should be untrusted event");
+ aElement.removeEventListener("click", arguments.callee);
+ });
+ var click = new MouseEvent("click", { button: 0 });
+ aElement.dispatchEvent(click);
+}
+
+function runTests()
+{
+ // XXX Don't add indentation here. If you add indentation, the diff will be
+ // complicated when somebody adds new tests.
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("a"), function () {
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("button"), function () {
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("checkbox"), function () {
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("radio"), function () {
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("submit"), function () {
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("ibutton"), function () {
+ runIsTrustedTestCausedByTrustedClick(document.getElementById("reset"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("a"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("button"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("checkbox"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("radio"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("submit"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("ibutton"), function () {
+ runIsTrustedTestCausedByUntrustedClick(document.getElementById("reset"), function () {
+ SimpleTest.finish();
+ });});});});});});});});});});});});});});
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_before_after_keyboard_event.html b/dom/events/test/test_dom_before_after_keyboard_event.html
new file mode 100644
index 000000000..533a7e73a
--- /dev/null
+++ b/dom/events/test/test_dom_before_after_keyboard_event.html
@@ -0,0 +1,136 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Bug 989198</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
+ <script type="text/javascript" src="bug989198_helper.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="runTests();">
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=989198">Mozilla Bug 989198</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+function cleanupTest()
+{
+ teardownHandlers(window, embedderHandler);
+ runTests();
+}
+
+function testEventOrderAndAttr()
+{
+ const kTests = [
+ {
+ description: "Testing the order of the events",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kUnknownEvent
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at \"mozbrowserbeforekeydown\" event",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kParent | kBeforeEvent | kKeyDownEvent
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at \"mozbrowserbeforekeyup\" event",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kParent | kBeforeEvent | kKeyUpEvent
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at \"keydown\" event",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kChild | kKeyDownEvent
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at \"keyup\" event",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kChild | kKeyUpEvent
+ }
+ ];
+
+ for (var k = 0; k < kTests.length; k++ ) {
+ gCurrentTest = kTests[k];
+ synthesizeKey('a', {}, document.getElementById("embedded").contentWindow);
+ classifyEvents(kTests[k]);
+ verifyResults(kTests[k]);
+ }
+
+ runTests();
+}
+
+var tests = [
+ function addPermissions() {
+ SpecialPowers.pushPermissions(
+ [{ type: "before-after-keyboard-event", allow: true, context: document },
+ { type: "browser", allow: true, context: document }],
+ runTests);
+ },
+ function addPreferences() {
+ SpecialPowers.pushPrefEnv(
+ { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
+ ["dom.mozBrowserFramesEnabled", true],
+ ["network.disable.ipc.security", true],
+ ["dom.ipc.tabs.disabled", false]] },
+ runTests);
+ },
+
+ // Tests for in-process iframe, i.e. <iframe mozbrowser>.
+ function () {
+ prepareTest(false);
+ },
+ testEventOrderAndAttr,
+ cleanupTest,
+];
+
+function runTests()
+{
+ if (!tests.length) {
+ SimpleTest.finish();
+ return;
+ }
+
+ var test = tests.shift();
+ test();
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_before_after_keyboard_event_remote.html b/dom/events/test/test_dom_before_after_keyboard_event_remote.html
new file mode 100644
index 000000000..b82b102a9
--- /dev/null
+++ b/dom/events/test/test_dom_before_after_keyboard_event_remote.html
@@ -0,0 +1,195 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Bug 989198</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/NativeKeyCodes.js"></script>
+ <script type="text/javascript" src="bug989198_helper.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="runTests();">
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=989198">Mozilla Bug 989198</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+var testsForEventOrder = [
+ {
+ description: "Testing the order of the events (OOP)",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kUnknownEvent
+ },
+ {
+ description: "Testing the order of the events (OOP), calling " +
+ "preventDefault() at \"mozbrowserbeforekeydown\" event",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kParent | kBeforeEvent | kKeyDownEvent
+ },
+ {
+ description: "Testing the order of the events (OOP), calling " +
+ "preventDefault() at \"mozbrowserbeforekeyup\" event",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kParent | kBeforeEvent | kKeyUpEvent
+ },
+ {
+ description: "Testing the order of the events (OOP), calling " +
+ "preventDefault() at \"keydown\" event in parent process",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kParent | kKeyDownEvent
+ },
+ {
+ description: "Testing the order of the events (OOP), calling " +
+ "preventDefault() at \"keydown\" event in child process",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kChild | kKeyDownEvent
+ },
+ {
+ description: "Testing the order of the events (OOP), calling " +
+ "preventDefault() at \"keyup\" event in parent process",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kParent | kKeyUpEvent
+ },
+ {
+ description: "Testing the order of the events (OOP), calling " +
+ "preventDefault() at \"keyup\" event in child process",
+ expectedEvents: [ [ kParent | kBeforeEvent | kKeyDownEvent,
+ kParent | kKeyDownEvent,
+ kChild | kKeyDownEvent,
+ kParent | kAfterEvent | kKeyDownEvent ],
+ [ kParent | kBeforeEvent | kKeyUpEvent,
+ kParent | kKeyUpEvent,
+ kChild | kKeyUpEvent,
+ kParent | kAfterEvent | kKeyUpEvent ] ],
+ resultEvents: [],
+ classifiedEvents: [ [], [] ],
+ doPreventDefaultAt: kChild | kKeyUpEvent
+ }
+];
+
+function cleanupTest()
+{
+ teardownHandlers(window, embedderHandler);
+ runTests();
+}
+
+function testEventOrder()
+{
+ if (!testsForEventOrder.length) {
+ runTests();
+ return;
+ }
+ gCurrentTest = testsForEventOrder.shift();
+
+ synthesizeKey('a', {}, document.getElementById("embedded").contentWindow);
+ // It take some time to propagate events to a remote iframe.
+
+ waitAndVerifyResult(0);
+}
+
+function waitAndVerifyResult(aCount) {
+ expectedEventLength = gCurrentTest.expectedEvents[0].length +
+ gCurrentTest.expectedEvents[1].length;
+ if (gCurrentTest.resultEvents.length >= expectedEventLength || aCount > 10) {
+ classifyEvents(gCurrentTest);
+ verifyResults(gCurrentTest);
+ testEventOrder();
+ }
+ else {
+ setTimeout(() => waitAndVerifyResult(aCount + 1),
+ 100);
+ }
+}
+
+var tests = [
+ function addPermissions() {
+ SpecialPowers.pushPermissions(
+ [{ type: "before-after-keyboard-event", allow: true, context: document },
+ { type: "browser", allow: true, context: document }],
+ runTests);
+ },
+ function addPreferences() {
+ SpecialPowers.pushPrefEnv(
+ { "set": [["dom.beforeAfterKeyboardEvent.enabled", true],
+ ["dom.mozBrowserFramesEnabled", true],
+ ["network.disable.ipc.security", true],
+ ["dom.ipc.tabs.disabled", false]] },
+ runTests);
+ },
+
+ // Tests for out-of-process iframe, i.el. <iframe mozbrowser remote>
+ function () {
+ prepareTest(true);
+ },
+ testEventOrder,
+ cleanupTest
+];
+
+function runTests()
+{
+ if (!tests.length) {
+ SimpleTest.finish();
+ return;
+ }
+
+ var test = tests.shift();
+ test();
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_keyboard_event.html b/dom/events/test/test_dom_keyboard_event.html
new file mode 100644
index 000000000..e85065904
--- /dev/null
+++ b/dom/events/test/test_dom_keyboard_event.html
@@ -0,0 +1,306 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for DOM KeyboardEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+var gCodeEnabled = SpecialPowers.getBoolPref("dom.keyboardevent.code.enabled");
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests, window);
+
+function testInitializingUntrustedEvent()
+{
+ const kTests = [
+ { createEventArg: "KeyboardEvent",
+ type: "keydown", bubbles: true, cancelable: true, view: null,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+ keyCode: 0x00, charCode: 0x00 },
+
+ { createEventArg: "keyboardevent",
+ type: "keyup", bubbles: false, cancelable: true, view: window,
+ ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
+ keyCode: 0x10, charCode: 0x00 },
+
+ { createEventArg: "Keyboardevent",
+ type: "keypess", bubbles: true, cancelable: false, view: null,
+ ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
+ keyCode: 0x11, charCode: 0x30 },
+
+ { createEventArg: "keyboardEvent",
+ type: "boo", bubbles: false, cancelable: false, view: window,
+ ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
+ keyCode: 0x30, charCode: 0x40 },
+
+ { createEventArg: "KeyBoardEvent",
+ type: "foo", bubbles: true, cancelable: true, view: null,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
+ keyCode: 0x00, charCode: 0x50 },
+
+ { createEventArg: "keyboardevEnt",
+ type: "bar", bubbles: false, cancelable: true, view: window,
+ ctrlKey: true, altKey: true, shiftKey: false, metaKey: false,
+ keyCode: 0x00, charCode: 0x60 },
+
+ { createEventArg: "KeyboaRdevent",
+ type: "keydown", bubbles: true, cancelable: false, view: null,
+ ctrlKey: false, altKey: true, shiftKey: false, metaKey: true,
+ keyCode: 0x30, charCode: 0x00 },
+
+ { createEventArg: "KEYBOARDEVENT",
+ type: "keyup", bubbles: false, cancelable: false, view: window,
+ ctrlKey: true, altKey: false, shiftKey: true, metaKey: false,
+ keyCode: 0x10, charCode: 0x80 },
+
+ { createEventArg: "KeyboardEvent",
+ type: "keypress", bubbles: false, cancelable: false, view: window,
+ ctrlKey: true, altKey: false, shiftKey: true, metaKey: true,
+ keyCode: 0x10, charCode: 0x80 },
+
+ { createEventArg: "KeyboardEvent",
+ type: "foo", bubbles: false, cancelable: false, view: window,
+ ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
+ keyCode: 0x10, charCode: 0x80 },
+ ];
+
+ const kOtherModifierName = [
+ "CapsLock", "NumLock", "ScrollLock", "Symbol", "SymbolLock", "Fn", "FnLock", "OS", "AltGraph"
+ ];
+
+ const kInvalidModifierName = [
+ "shift", "control", "alt", "meta", "capslock", "numlock", "scrolllock",
+ "symbollock", "fn", "os", "altgraph", "Invalid", "Shift Control",
+ "Win", "Scroll"
+ ];
+
+ for (var i = 0; i < kTests.length; i++) {
+ var description = "testInitializingUntrustedEvent, Index: " + i + ", ";
+ const kTest = kTests[i];
+ var e = document.createEvent(kTest.createEventArg);
+ e.initKeyEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
+ kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
+ kTest.keyCode, kTest.charCode);
+ is(e.toString(), "[object KeyboardEvent]",
+ description + 'class string should be "KeyboardEvent"');
+
+ for (var attr in kTest) {
+ if (attr == "createEventArg") {
+ continue;
+ }
+ if (attr == "keyCode") {
+ // If this is keydown, keyup of keypress event, keycod must be correct.
+ if (kTest.type == "keydown" || kTest.type == "keyup" || kTest.type == "keypress") {
+ is(e[attr], kTest[attr], description + attr + " returns wrong value");
+ // Otherwise, should be always zero (why?)
+ } else {
+ is(e[attr], 0, description + attr + " returns non-zero for invalid event");
+ }
+ } else if (attr == "charCode") {
+ // If this is keydown or keyup event, charCode always 0.
+ if (kTest.type == "keydown" || kTest.type == "keyup") {
+ is(e[attr], 0, description + attr + " returns non-zero for keydown or keyup event");
+ // If this is keypress event, charCode must be correct.
+ } else if (kTest.type == "keypress") {
+ is(e[attr], kTest[attr], description + attr + " returns wrong value");
+ // Otherwise, we have a bug.
+ } else {
+ if (e[attr] != kTest[attr]) { // avoid random unexpected pass.
+ todo_is(e[attr], kTest[attr], description + attr + " returns wrong value");
+ }
+ }
+ } else {
+ is(e[attr], kTest[attr], description + attr + " returns wrong value");
+ }
+ }
+ is(e.isTrusted, false, description + "isTrusted returns wrong value");
+
+ // key and code values cannot be initialized with initKeyEvent().
+ is(e.key, "", description + "key must return empty string");
+ if (gCodeEnabled) {
+ is(e.code, "", description + "code must be empty string");
+ }
+
+ // getModifierState() tests
+ is(e.getModifierState("Shift"), kTest.shiftKey,
+ description + "getModifierState(\"Shift\") returns wrong value");
+ is(e.getModifierState("Control"), kTest.ctrlKey,
+ description + "getModifierState(\"Control\") returns wrong value");
+ is(e.getModifierState("Alt"), kTest.altKey,
+ description + "getModifierState(\"Alt\") returns wrong value");
+ is(e.getModifierState("Meta"), kTest.metaKey,
+ description + "getModifierState(\"Meta\") returns wrong value");
+
+ for (var j = 0; j < kOtherModifierName.length; j++) {
+ ok(!e.getModifierState(kOtherModifierName[j]),
+ description + "getModifierState(\"" + kOtherModifierName[j] + "\") returns wrong value");
+ }
+ for (var k = 0; k < kInvalidModifierName.length; k++) {
+ ok(!e.getModifierState(kInvalidModifierName[k]),
+ description + "getModifierState(\"" + kInvalidModifierName[k] + "\") returns wrong value");
+ }
+ }
+}
+
+function testSynthesizedKeyLocation()
+{
+ const kTests = [
+ { key: "a", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_SHIFT", isModifier: true,
+ event: { shiftKey: true, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_LEFT },
+ },
+ { key: "VK_SHIFT", isModifier: true,
+ event: { shiftKey: true, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT },
+ },
+ { key: "VK_CONTROL", isModifier: true,
+ event: { shiftKey: false, ctrlKey: true, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_LEFT },
+ },
+ { key: "VK_CONTROL", isModifier: true,
+ event: { shiftKey: false, ctrlKey: true, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT },
+ },
+/* XXX Alt key activates menubar even if we consume the key events.
+ { key: "VK_ALT", isModifier: true,
+ event: { shiftKey: false, ctrlKey: false, altKey: true, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_LEFT },
+ },
+ { key: "VK_ALT", isModifier: true,
+ event: { shiftKey: false, ctrlKey: false, altKey: true, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT },
+ },
+*/
+ { key: "VK_META", isModifier: true,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: true,
+ location: KeyboardEvent.DOM_KEY_LOCATION_LEFT },
+ },
+ { key: "VK_META", isModifier: true,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: true,
+ location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT },
+ },
+ { key: "VK_DOWN", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_DOWN", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD },
+ },
+ { key: "5", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_NUMPAD5", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD },
+ },
+ { key: "+", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_ADD", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD },
+ },
+ { key: "VK_RETURN", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_RETURN", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD },
+ },
+ { key: "VK_NUM_LOCK", isModifier: true,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_INSERT", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD },
+ },
+ { key: "VK_INSERT", isModifier: false,
+ event: { shiftKey: false, ctrlKey: false, altKey: false, metaKey: false,
+ location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD },
+ },
+ ];
+
+ function getLocationName(aLocation)
+ {
+ switch (aLocation) {
+ case KeyboardEvent.DOM_KEY_LOCATION_STANDARD:
+ return "DOM_KEY_LOCATION_STANDARD";
+ case KeyboardEvent.DOM_KEY_LOCATION_LEFT:
+ return "DOM_KEY_LOCATION_LEFT";
+ case KeyboardEvent.DOM_KEY_LOCATION_RIGHT:
+ return "DOM_KEY_LOCATION_RIGHT";
+ case KeyboardEvent.DOM_KEY_LOCATION_NUMPAD:
+ return "DOM_KEY_LOCATION_NUMPAD";
+ default:
+ return "Invalid value (" + aLocation + ")";
+ }
+ }
+
+ var currentTest, description;
+ var events = { keydown: false, keypress: false, keyup: false };
+
+ function handler(aEvent)
+ {
+ is(aEvent.location, currentTest.event.location,
+ description + "location of " + aEvent.type + " was invalid");
+ events[aEvent.type] = true;
+ if (aEvent.type != "keydown" ||
+ (currentTest.event.isModifier && aEvent.type == "keydown")) {
+ aEvent.preventDefault();
+ }
+ }
+
+ window.addEventListener("keydown", handler, true);
+ window.addEventListener("keypress", handler, true);
+ window.addEventListener("keyup", handler, true);
+
+ for (var i = 0; i < kTests.length; i++) {
+ currentTest = kTests[i];
+ events = { keydown: false, keypress: false, keyup: false };
+ description = "testSynthesizedKeyLocation, " + i + ", key: " +
+ currentTest.key + ", location: " +
+ getLocationName(currentTest.event.location) + ": ";
+ synthesizeKey(currentTest.key, currentTest.event);
+ ok(events.keydown, description + "keydown event wasn't fired");
+ if (currentTest.isModifier) {
+ todo(events.keypress, description + "keypress event was fired for modifier key");
+ } else {
+ ok(events.keypress, description + "keypress event wasn't fired");
+ }
+ ok(events.keyup, description + "keyup event wasn't fired");
+ }
+
+ window.removeEventListener("keydown", handler, true);
+ window.removeEventListener("keypress", handler, true);
+ window.removeEventListener("keyup", handler, true);
+}
+
+function runTests()
+{
+ testInitializingUntrustedEvent();
+ testSynthesizedKeyLocation();
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_mouse_event.html b/dom/events/test/test_dom_mouse_event.html
new file mode 100644
index 000000000..d1433eb35
--- /dev/null
+++ b/dom/events/test/test_dom_mouse_event.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for DOM MouseEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTests, window);
+
+function testInitializingUntrustedEvent()
+{
+ const kTests = [
+ { createEventArg: "MouseEvent",
+ type: "mousedown", bubbles: true, cancelable: true, view: null, detail: 1,
+ screenX: 0, screenY: 0, clientX: 0, clientY: 0,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
+ button: 6, relatedTarget: null },
+
+ { createEventArg: "mouseevent",
+ type: "mouseup", bubbles: false, cancelable: true, view: window, detail: 2,
+ screenX: 0, screenY: 0, clientX: 0, clientY: 400,
+ ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
+ button: 1, relatedTarget: document.getElementById("content") },
+
+ { createEventArg: "Mouseevent",
+ type: "click", bubbles: true, cancelable: false, view: null, detail: -5,
+ screenX: 0, screenY: 0, clientX: 300, clientY: 0,
+ ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
+ button: 2, relatedTarget: document.getElementById("test") },
+
+ { createEventArg: "mouseEvent",
+ type: "dblclick", bubbles: false, cancelable: false, view: window, detail: -1,
+ screenX: 0, screenY: 200, clientX: 0, clientY: 0,
+ ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
+ button: 12, relatedTarget: document.getElementById("content") },
+
+ { createEventArg: "MouseEvents",
+ type: "mouseenter", bubbles: true, cancelable: true, view: null, detail: 111000,
+ screenX: 100, screenY: 0, clientX: 0, clientY: 0,
+ ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
+ button: 2, relatedTarget: document.getElementById("test") },
+
+ { createEventArg: "mouseevents",
+ type: "mouseleave", bubbles: false, cancelable: true, view: window, detail: 500,
+ screenX: 100, screenY: 500, clientX: 0, clientY: 0,
+ ctrlKey: true, altKey: true, shiftKey: false, metaKey: false,
+ button: 8, relatedTarget: document.getElementById("content") },
+
+ { createEventArg: "Mouseevents",
+ type: "mouseover", bubbles: true, cancelable: false, view: null, detail: 3,
+ screenX: 0, screenY: 0, clientX: 200, clientY: 300,
+ ctrlKey: false, altKey: true, shiftKey: false, metaKey: true,
+ button: 7, relatedTarget: document.getElementById("test") },
+
+ { createEventArg: "mouseEvents",
+ type: "mouseout", bubbles: false, cancelable: false, view: window, detail: 5,
+ screenX: -100, screenY: 300, clientX: 600, clientY: -500,
+ ctrlKey: true, altKey: false, shiftKey: true, metaKey: false,
+ button: 8, relatedTarget: document.getElementById("content") },
+
+ { createEventArg: "MouseEvent",
+ type: "mousemove", bubbles: false, cancelable: false, view: window, detail: 30,
+ screenX: 500, screenY: -100, clientX: -8888, clientY: -5000,
+ ctrlKey: true, altKey: false, shiftKey: true, metaKey: true,
+ button: 8, relatedTarget: document.getElementById("test") },
+
+ { createEventArg: "MouseEvent",
+ type: "foo", bubbles: false, cancelable: false, view: window, detail: 100,
+ screenX: 2000, screenY: 6000, clientX: 5000, clientY: 3000,
+ ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
+ button: 8, relatedTarget: document.getElementById("test") },
+ ];
+
+ const kOtherModifierName = [
+ "CapsLock", "NumLock", "ScrollLock", "Symbol", "SymbolLock", "Fn", "FnLock", "OS", "AltGraph"
+ ];
+
+ const kInvalidModifierName = [
+ "shift", "control", "alt", "meta", "capslock", "numlock", "scrolllock",
+ "symbollock", "fn", "os", "altgraph", "Invalid", "Shift Control",
+ "Win", "Scroll"
+ ];
+
+ for (var i = 0; i < kTests.length; i++) {
+ var description = "testInitializingUntrustedEvent, Index: " + i + ", ";
+ const kTest = kTests[i];
+ var e = document.createEvent(kTest.createEventArg);
+ e.initMouseEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
+ kTest.detail, kTest.screenX, kTest.screenY, kTest.clientX, kTest.clientY,
+ kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
+ kTest.button, kTest.relatedTarget);
+
+ for (var attr in kTest) {
+ if (attr == "createEventArg") {
+ continue;
+ }
+ is(e[attr], kTest[attr], description + attr + " returns wrong value");
+ }
+ is(e.isTrusted, false, description + "isTrusted returns wrong value");
+ is(e.buttons, 0, description + "buttons returns wrong value");
+ is(e.movementX, 0, description + "movementX returns wrong value");
+ is(e.movementY, 0, description + "movementY returns wrong value");
+
+ // getModifierState() tests
+ is(e.getModifierState("Shift"), kTest.shiftKey,
+ description + "getModifierState(\"Shift\") returns wrong value");
+ is(e.getModifierState("Control"), kTest.ctrlKey,
+ description + "getModifierState(\"Control\") returns wrong value");
+ is(e.getModifierState("Alt"), kTest.altKey,
+ description + "getModifierState(\"Alt\") returns wrong value");
+ is(e.getModifierState("Meta"), kTest.metaKey,
+ description + "getModifierState(\"Meta\") returns wrong value");
+
+ for (var j = 0; j < kOtherModifierName.length; j++) {
+ ok(!e.getModifierState(kOtherModifierName[j]),
+ description + "getModifierState(\"" + kOtherModifierName[j] + "\") returns wrong value");
+ }
+ for (var k = 0; k < kInvalidModifierName.length; k++) {
+ ok(!e.getModifierState(kInvalidModifierName[k]),
+ description + "getModifierState(\"" + kInvalidModifierName[k] + "\") returns wrong value");
+ }
+ }
+}
+
+function runTests()
+{
+ testInitializingUntrustedEvent();
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_storage_event.html b/dom/events/test/test_dom_storage_event.html
new file mode 100644
index 000000000..4ac967dfe
--- /dev/null
+++ b/dom/events/test/test_dom_storage_event.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for DOM StorageEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+const kTests = [
+ { createEventArg: "StorageEvent",
+ type: "aaa", bubbles: true, cancelable: true,
+ key: null, oldValue: 'a', newValue: 'b', url: 'c', storageArea: null },
+
+ { createEventArg: "storageevent",
+ type: "bbb", bubbles: false, cancelable: true,
+ key: 'key', oldValue: null, newValue: 'b', url: 'c', storageArea: null },
+
+ { createEventArg: "Storageevent",
+ type: "ccc", bubbles: true, cancelable: false,
+ key: 'key', oldValue: 'a', newValue: null, url: 'c', storageArea: null },
+
+ { createEventArg: "storageEvent",
+ type: "ddd", bubbles: false, cancelable: false,
+ key: 'key', oldValue: 'a', newValue: 'b', url: null, storageArea: null },
+
+ { createEventArg: "StorageEvent",
+ type: "eee", bubbles: true, cancelable: true,
+ key: 'key', oldValue: 'a', newValue: 'b', url: 'c', storageArea: null },
+
+ { createEventArg: "storageevent",
+ type: "fff", bubbles: false, cancelable: true,
+ key: null, oldValue: null, newValue: null, url: null, storageArea: null },
+ ];
+
+for (var i = 0; i < kTests.length; i++) {
+ var description = "test, Index: " + i + ", ";
+ const kTest = kTests[i];
+ var e = document.createEvent(kTest.createEventArg);
+ e.initStorageEvent(kTest.type, kTest.bubbles, kTest.cancelable,
+ kTest.key, kTest.oldValue, kTest.newValue, kTest.url,
+ kTest.storageArea);
+
+ for (var attr in kTest) {
+ if (attr == 'createEventArg')
+ continue;
+
+ is(e[attr], kTest[attr], description + attr + " returns wrong value");
+ }
+ is(e.isTrusted, false, description + "isTrusted returns wrong value");
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_dom_wheel_event.html b/dom/events/test/test_dom_wheel_event.html
new file mode 100644
index 000000000..043eaa06c
--- /dev/null
+++ b/dom/events/test/test_dom_wheel_event.html
@@ -0,0 +1,811 @@
+<!DOCTYPE HTML>
+<html style="font-size: 32px;">
+<head>
+ <title>Test for D3E WheelEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="scrollable" style="font-family: monospace; font-size: 16px; line-height: 1; overflow: auto; width: 200px; height: 200px;">
+ <div id="scrolled" style="font-size: 64px; width: 5000px; height: 5000px;">
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ </div>
+</div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTest, window);
+
+var gScrollableElement = document.getElementById("scrollable");
+var gScrolledElement = document.getElementById("scrolled");
+
+var gLineHeight = 0;
+var gHorizontalLine = 0;
+var gPageHeight = 0;
+var gPageWidth = 0;
+
+function sendWheelAndWait(aX, aY, aEvent)
+{
+ sendWheelAndPaint(gScrollableElement, aX, aY, aEvent, continueTest);
+}
+
+function* prepareScrollUnits()
+{
+ var result = -1;
+ function handler(aEvent)
+ {
+ result = aEvent.detail;
+ aEvent.preventDefault();
+ }
+ window.addEventListener("MozMousePixelScroll", handler, true);
+
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gLineHeight = result;
+ ok(gLineHeight > 10 && gLineHeight < 25, "prepareScrollUnits: gLineHeight may be illegal value, got " + gLineHeight);
+
+ result = -1;
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gHorizontalLine = result;
+ ok(gHorizontalLine > 5 && gHorizontalLine < 16, "prepareScrollUnits: gHorizontalLine may be illegal value, got " + gHorizontalLine);
+
+ result = -1;
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gPageHeight = result;
+ // XXX Cannot we know the actual scroll port size?
+ ok(gPageHeight >= 150 && gPageHeight <= 200,
+ "prepareScrollUnits: gPageHeight is strange value, got " + gPageHeight);
+
+ result = -1;
+ yield sendWheelAndWait(10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gPageWidth = result;
+ ok(gPageWidth >= 150 && gPageWidth <= 200,
+ "prepareScrollUnits: gPageWidth is strange value, got " + gPageWidth);
+
+ window.removeEventListener("MozMousePixelScroll", handler, true);
+}
+
+function testMakingUntrustedEvent()
+{
+ const kCreateEventArgs = [
+ "WheelEvent", "wheelevent", "wheelEvent", "Wheelevent"
+ ];
+
+ for (var i = 0; i < kCreateEventArgs.length; i++) {
+ try {
+ // We never support WheelEvent construction with document.createEvent().
+ var event = document.createEvent(kCreateEventArgs[i]);
+ ok(false, "document.createEvent(" + kCreateEventArgs[i] + ") should throw an error");
+ } catch (e) {
+ ok(true, "document.createEvent(" + kCreateEventArgs[i] + ") threw an error");
+ }
+ }
+
+ var wheelEvent = new WheelEvent("wheel");
+ ok(wheelEvent instanceof WheelEvent,
+ "new WheelEvent() should create an instance of WheelEvent");
+ ok(typeof(wheelEvent.initWheelEvent) != "function",
+ "WheelEvent must not have initWheelEvent()");
+}
+
+// delta_multiplier prefs should cause changing delta values of trusted events only.
+// And also legacy events' detail value should be changed too.
+function* testDeltaMultiplierPrefs()
+{
+ const kModifierAlt = 0x01;
+ const kModifierControl = 0x02;
+ const kModifierMeta = 0x04;
+ const kModifierShift = 0x08;
+ const kModifierWin = 0x10;
+
+ const kTests = [
+ { name: "default",
+ expected: [ 0, kModifierShift | kModifierAlt, kModifierShift | kModifierControl,
+ kModifierShift | kModifierMeta, kModifierShift | kModifierWin,
+ kModifierControl | kModifierAlt, kModifierMeta | kModifierAlt ],
+ unexpected: [ kModifierAlt, kModifierControl, kModifierMeta, kModifierShift, kModifierWin ] },
+ { name: "with_alt",
+ expected: [ kModifierAlt ],
+ unexpected: [0, kModifierControl, kModifierMeta, kModifierShift, kModifierWin,
+ kModifierShift | kModifierAlt, kModifierControl | kModifierAlt,
+ kModifierMeta | kModifierAlt ] },
+ { name: "with_control",
+ expected: [ kModifierControl ],
+ unexpected: [0, kModifierAlt, kModifierMeta, kModifierShift, kModifierWin,
+ kModifierShift | kModifierControl, kModifierControl | kModifierAlt,
+ kModifierMeta | kModifierControl ] },
+ { name: "with_meta",
+ expected: [ kModifierMeta ],
+ unexpected: [0, kModifierAlt, kModifierControl, kModifierShift, kModifierWin,
+ kModifierShift | kModifierMeta, kModifierControl | kModifierMeta,
+ kModifierMeta | kModifierAlt ] },
+ { name: "with_shift",
+ expected: [ kModifierShift ],
+ unexpected: [0, kModifierAlt, kModifierControl, kModifierMeta, kModifierWin,
+ kModifierShift | kModifierAlt, kModifierControl | kModifierShift,
+ kModifierMeta | kModifierShift ] },
+ { name: "with_win",
+ expected: [ kModifierWin ],
+ unexpected: [0, kModifierAlt, kModifierControl, kModifierMeta, kModifierShift,
+ kModifierShift | kModifierWin ] },
+ ];
+
+ // Note that this test doesn't support complicated lineOrPageDelta values which are computed with
+ // accumulated delta values by the prefs. If you need to test the lineOrPageDelta accumulation,
+ // use test_continuous_dom_wheel_event.html.
+ const kEvents = [
+ { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: gHorizontalLine, deltaY: gLineHeight, deltaZ: gLineHeight, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -gHorizontalLine, deltaY: -gLineHeight, deltaZ: -gLineHeight, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ ];
+
+ const kDeltaMultiplierPrefs = [
+ "delta_multiplier_x", "delta_multiplier_y", "delta_multiplier_z"
+ ];
+
+ const kPrefValues = [
+ 200, 50, 0, -50, -150
+ ];
+
+ var currentTest, currentModifiers, currentEvent, currentPref, currentMultiplier, testingExpected;
+ var expectedAsyncHandlerCalls;
+ var description;
+ var calledHandlers = { wheel: false,
+ DOMMouseScroll: { horizontal: false, vertical: false },
+ MozMousePixelScroll: { horizontal: false, vertical: false } };
+
+ function wheelEventHandler(aEvent) {
+ calledHandlers.wheel = true;
+
+ var expectedDeltaX = currentEvent.deltaX;
+ var expectedDeltaY = currentEvent.deltaY;
+ var expectedDeltaZ = currentEvent.deltaZ;
+
+ if (testingExpected) {
+ switch (currentPref.charAt(currentPref.length - 1)) {
+ case "x":
+ expectedDeltaX *= currentMultiplier;
+ break;
+ case "y":
+ expectedDeltaY *= currentMultiplier;
+ break;
+ case "z":
+ expectedDeltaZ *= currentMultiplier;
+ break;
+ }
+ }
+ is(aEvent.deltaX, expectedDeltaX, description + "deltaX (" + currentEvent.deltaX + ") was invalid");
+ is(aEvent.deltaY, expectedDeltaY, description + "deltaY (" + currentEvent.deltaY + ") was invalid");
+ is(aEvent.deltaZ, expectedDeltaZ, description + "deltaZ (" + currentEvent.deltaZ + ") was invalid");
+
+ if (expectedAsyncHandlerCalls > 0 && --expectedAsyncHandlerCalls == 0) {
+ setTimeout(continueTest, 0);
+ }
+ }
+
+ function legacyEventHandler(aEvent) {
+ var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS);
+ var isScrollEvent = (aEvent.type == "DOMMouseScroll");
+ if (isScrollEvent) {
+ if (isHorizontal) {
+ calledHandlers.DOMMouseScroll.horizontal = true;
+ } else {
+ calledHandlers.DOMMouseScroll.vertical = true;
+ }
+ } else {
+ if (isHorizontal) {
+ calledHandlers.MozMousePixelScroll.horizontal = true;
+ } else {
+ calledHandlers.MozMousePixelScroll.vertical = true;
+ }
+ }
+ var eventName = (isHorizontal ? "Horizontal " : "Vertical ") + aEvent.type + " ";
+ var expectedDetail;
+ if (isScrollEvent) {
+ expectedDetail = isHorizontal ? currentEvent.lineOrPageDeltaX : currentEvent.lineOrPageDeltaY;
+ if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE && expectedDetail) {
+ expectedDetail = ((expectedDetail > 0) ? UIEvent.SCROLL_PAGE_DOWN : UIEvent.SCROLL_PAGE_UP);
+ }
+ } else {
+ expectedDetail = isHorizontal ? currentEvent.deltaX : currentEvent.deltaY;
+ if (expectedDetail) {
+ if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_LINE) {
+ expectedDetail *= (isHorizontal ? gHorizontalLine : gLineHeight);
+ } else if (currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE) {
+ if (expectedDetail > 0) {
+ expectedDetail = (isHorizontal ? gPageWidth : gPageHeight);
+ } else {
+ expectedDetail = (isHorizontal ? -gPageWidth : -gPageHeight);
+ }
+ }
+ }
+ }
+ if (testingExpected) {
+ if ((isHorizontal && currentPref.charAt(currentPref.length - 1) == "x") ||
+ (!isHorizontal && currentPref.charAt(currentPref.length - 1) == "y")) {
+ // If it's a page scroll event, the detail value is UIEvent.SCROLL_PAGE_DOWN or
+ // UIEvent.SCROLL_PAGE_UP. If the delta value sign is reverted, we need to
+ // revert the expected detail value too. Otherwise, don't touch it.
+ if (isScrollEvent && currentEvent.deltaMode == WheelEvent.DOM_DELTA_PAGE) {
+ if (currentMultiplier < 0) {
+ expectedDetail = ((expectedDetail == UIEvent.SCROLL_PAGE_UP) ? UIEvent.SCROLL_PAGE_DOWN : UIEvent.SCROLL_PAGE_UP);
+ }
+ } else {
+ expectedDetail *= currentMultiplier;
+ expectedDetail = expectedDetail < 0 ? Math.ceil(expectedDetail) : Math.floor(expectedDetail);
+ }
+ }
+ }
+ is(aEvent.detail, expectedDetail, description + eventName + "detail was invalid");
+
+ aEvent.preventDefault();
+
+ if (expectedAsyncHandlerCalls > 0 && --expectedAsyncHandlerCalls == 0) {
+ setTimeout(continueTest, 0);
+ }
+ }
+
+ window.addEventListener("wheel", wheelEventHandler, true);
+ window.addEventListener("DOMMouseScroll", legacyEventHandler, true);
+ window.addEventListener("MozMousePixelScroll", legacyEventHandler, true);
+
+ function* dispatchEvent(aIsExpected) {
+ for (var i = 0; i < kEvents.length; i++) {
+ currentEvent = kEvents[i];
+ currentEvent.shiftKey = (currentModifiers & kModifierShift) != 0;
+ currentEvent.ctrlKey = (currentModifiers & kModifierControl) != 0;
+ currentEvent.altKey = (currentModifiers & kModifierAlt) != 0;
+ currentEvent.metaKey = (currentModifiers & kModifierMeta) != 0;
+ currentEvent.osKey = (currentModifiers & kModifierWin) != 0;
+ var modifierList = "";
+ if (currentEvent.shiftKey) {
+ modifierList += "Shift ";
+ }
+ if (currentEvent.ctrlKey) {
+ modifierList += "Control ";
+ }
+ if (currentEvent.altKey) {
+ modifierList += "Alt ";
+ }
+ if (currentEvent.metaKey) {
+ modifierList += "Meta ";
+ }
+ if (currentEvent.osKey) {
+ modifierList += "Win ";
+ }
+
+ for (var j = 0; j < kPrefValues.length; j++) {
+ currentMultiplier = kPrefValues[j] / 100;
+ for (var k = 0; k < kDeltaMultiplierPrefs.length; k++) {
+ currentPref = "mousewheel." + currentTest.name + "." + kDeltaMultiplierPrefs[k];
+
+ yield SpecialPowers.pushPrefEnv({"set": [[currentPref, kPrefValues[j]]]}, continueTest);
+
+ gScrollableElement.scrollTop = gScrollableElement.scrollBottom = 1000;
+
+ // trusted event's delta valuses should be reverted by the pref.
+ testingExpected = aIsExpected;
+
+ var expectedProps = {
+ deltaX: currentEvent.deltaX * currentMultiplier,
+ deltaY: currentEvent.deltaY * currentMultiplier,
+ dletaZ: currentEvent.deltaZ * currentMultiplier,
+ lineOrPageDeltaX: currentEvent.lineOrPageDeltaX * currentMultiplier,
+ lineOrPageDeltaY: currentEvent.lineOrPageDeltaY * currentMultiplier,
+ };
+
+ var expectedWheel = expectedProps.deltaX != 0 || expectedProps.deltaY != 0 || expectedProps.deltaZ != 0;
+ var expectedDOMMouseX = expectedProps.lineOrPageDeltaX >= 1 || expectedProps.lineOrPageDeltaX <= -1;
+ var expectedDOMMouseY = expectedProps.lineOrPageDeltaY >= 1 || expectedProps.lineOrPageDeltaY <= -1;
+ var expectedMozMouseX = expectedProps.deltaX >= 1 || expectedProps.deltaX <= -1;
+ var expectedMozMouseY = expectedProps.deltaY >= 1 || expectedProps.deltaY <= -1;
+
+ expectedAsyncHandlerCalls = 0;
+ if (expectedWheel) ++expectedAsyncHandlerCalls;
+ if (expectedDOMMouseX) ++expectedAsyncHandlerCalls;
+ if (expectedDOMMouseY) ++expectedAsyncHandlerCalls;
+ if (expectedMozMouseX) ++expectedAsyncHandlerCalls;
+ if (expectedMozMouseY) ++expectedAsyncHandlerCalls;
+
+ description = "testDeltaMultiplierPrefs, pref: " + currentPref + "=" + kPrefValues[j] +
+ ", deltaMode: " + currentEvent.deltaMode + ", modifiers: \"" + modifierList + "\", (trusted event): ";
+ yield synthesizeWheel(gScrollableElement, 10, 10, currentEvent);
+
+ is(calledHandlers.wheel,
+ expectedWheel,
+ description + "wheel event was (not) fired");
+ is(calledHandlers.DOMMouseScroll.horizontal,
+ expectedDOMMouseX,
+ description + "Horizontal DOMMouseScroll event was (not) fired");
+ is(calledHandlers.DOMMouseScroll.vertical,
+ expectedDOMMouseY,
+ description + "Vertical DOMMouseScroll event was (not) fired");
+ is(calledHandlers.MozMousePixelScroll.horizontal,
+ expectedMozMouseX,
+ description + "Horizontal MozMousePixelScroll event was (not) fired");
+ is(calledHandlers.MozMousePixelScroll.vertical,
+ expectedMozMouseY,
+ description + "Vertical MozMousePixelScroll event was (not) fired");
+
+ calledHandlers = { wheel: false,
+ DOMMouseScroll: { horizontal: false, vertical: false },
+ MozMousePixelScroll: { horizontal: false, vertical: false } };
+
+ // untrusted event's delta values shouldn't be reverted by the pref.
+ testingExpected = false;
+ var props = {
+ bubbles: true,
+ cancelable: true,
+ shiftKey: currentEvent.shiftKey,
+ ctrlKey: currentEvent.ctrlKey,
+ altKey: currentEvent.altKey,
+ metaKey: currentEvent.metaKey,
+ deltaX: currentEvent.deltaX,
+ deltaY: currentEvent.deltaY,
+ deltaZ: currentEvent.deltaZ,
+ deltaMode: currentEvent.deltaMode,
+ };
+ var untrustedEvent = new WheelEvent("wheel", props);
+
+ description = "testDeltaMultiplierPrefs, pref: " + currentPref + "=" + kPrefValues[j] +
+ ", deltaMode: " + currentEvent.deltaMode + ", modifiers: \"" + modifierList + "\", (untrusted event): ";
+ gScrollableElement.dispatchEvent(untrustedEvent);
+
+ ok(calledHandlers.wheel, description + "wheel event was not fired for untrusted event");
+ ok(!calledHandlers.DOMMouseScroll.horizontal,
+ description + "Horizontal DOMMouseScroll event was fired for untrusted event");
+ ok(!calledHandlers.DOMMouseScroll.vertical,
+ description + "Vertical DOMMouseScroll event was fired for untrusted event");
+ ok(!calledHandlers.MozMousePixelScroll.horizontal,
+ description + "Horizontal MozMousePixelScroll event was fired for untrusted event");
+ ok(!calledHandlers.MozMousePixelScroll.vertical,
+ description + "Vertical MozMousePixelScroll event was fired for untrusted event");
+
+ yield SpecialPowers.pushPrefEnv({"set": [[currentPref, 100]]}, continueTest);
+
+ calledHandlers = { wheel: false,
+ DOMMouseScroll: { horizontal: false, vertical: false },
+ MozMousePixelScroll: { horizontal: false, vertical: false } };
+
+ }
+ // We should skip other value tests if testing with modifier key.
+ // If we didn't do so, it would test too many times, but we don't need to do so.
+ if (kTests.name != "default") {
+ break;
+ }
+ }
+ }
+ }
+
+ for (var i = 0; i < kTests.length; i++) {
+ currentTest = kTests[i];
+ for (var j = 0; j < currentTest.expected.length; j++) {
+ currentModifiers = currentTest.expected[j];
+ yield* dispatchEvent(true);
+ }
+ for (var k = 0; k < currentTest.unexpected.length; k++) {
+ currentModifiers = currentTest.unexpected[k];
+ yield* dispatchEvent(false);
+ }
+ }
+
+ window.removeEventListener("wheel", wheelEventHandler, true);
+ window.removeEventListener("DOMMouseScroll", legacyEventHandler, true);
+ window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true);
+}
+
+// Untrusted wheel events shouldn't cause legacy mouse scroll events.
+function testDispatchingUntrustEvent()
+{
+ var descriptionBase = "testDispatchingUntrustEvent, ";
+ var description, wheelEventFired;
+ function wheelEventHandler(aEvent)
+ {
+ wheelEventFired = true;
+ }
+
+ function legacyEventHandler(aEvent)
+ {
+ ok(false, aEvent.type + " must not be fired");
+ }
+
+ window.addEventListener("wheel", wheelEventHandler, true);
+ window.addEventListener("DOMMouseScroll", legacyEventHandler, true);
+ window.addEventListener("MozMousePixelScroll", legacyEventHandler, true);
+
+ description = descriptionBase + "dispatching a pixel wheel event: ";
+ wheelEventFired = false;
+ var untrustedPixelEvent = new WheelEvent("wheel", {
+ bubbles: true, cancelable: true,
+ deltaX: 24.0, deltaY: 24.0,
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ });
+ gScrolledElement.dispatchEvent(untrustedPixelEvent);
+ ok(wheelEventFired, description + "wheel event wasn't fired");
+
+ description = descriptionBase + "dispatching a line wheel event: ";
+ wheelEventFired = false;
+ var untrustedLineEvent = new WheelEvent("wheel", {
+ bubbles: true, cancelable: true,
+ deltaX: 3.0, deltaY: 3.0,
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ });
+ gScrolledElement.dispatchEvent(untrustedLineEvent);
+ ok(wheelEventFired, description + "wheel event wasn't fired");
+
+ description = descriptionBase + "dispatching a page wheel event: ";
+ wheelEventFired = false;
+ var untrustedPageEvent = new WheelEvent("wheel", {
+ bubbles: true, cancelable: true,
+ deltaX: 1.0, deltaY: 1.0,
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ });
+ gScrolledElement.dispatchEvent(untrustedPageEvent);
+ ok(wheelEventFired, description + "wheel event wasn't fired");
+
+ window.removeEventListener("wheel", wheelEventHandler, true);
+ window.removeEventListener("DOMMouseScroll", legacyEventHandler, true);
+ window.removeEventListener("MozMousePixelScroll", legacyEventHandler, true);
+}
+
+function* testEventOrder()
+{
+ const kWheelEvent = 0x0001;
+ const kDOMMouseScrollEvent = 0x0002;
+ const kMozMousePixelScrollEvent = 0x0004;
+ const kVerticalScrollEvent = 0x0010;
+ const kHorizontalScrollEvent = 0x0020;
+ const kInSystemGroup = 0x0100;
+ const kDefaultPrevented = 0x1000;
+
+ var currentTest;
+
+ const kTests = [
+ {
+ description: "Testing the order of the events without preventDefault()",
+ expectedEvents: [ kWheelEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kWheelEvent | kInSystemGroup],
+ resultEvents: [],
+ doPreventDefaultAt: 0,
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at default group wheel event",
+ expectedEvents: [ kWheelEvent,
+ kWheelEvent | kInSystemGroup | kDefaultPrevented],
+ resultEvents: [],
+ doPreventDefaultAt: kWheelEvent,
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at default group DOMMouseScroll event",
+ expectedEvents: [ kWheelEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kDefaultPrevented,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kWheelEvent | kInSystemGroup | kDefaultPrevented],
+ resultEvents: [],
+ doPreventDefaultAt: kDOMMouseScrollEvent | kVerticalScrollEvent,
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at default group MozMousePixelScroll event",
+ expectedEvents: [ kWheelEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kWheelEvent | kInSystemGroup | kDefaultPrevented],
+ resultEvents: [],
+ doPreventDefaultAt: kMozMousePixelScrollEvent | kVerticalScrollEvent,
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at system group DOMMouseScroll event",
+ expectedEvents: [ kWheelEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kDefaultPrevented,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup | kDefaultPrevented,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kWheelEvent | kInSystemGroup | kDefaultPrevented],
+ resultEvents: [],
+ doPreventDefaultAt: kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ },
+ {
+ description: "Testing the order of the events, calling preventDefault() at system group MozMousePixelScroll event",
+ expectedEvents: [ kWheelEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent,
+ kDOMMouseScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent,
+ kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent,
+ kDOMMouseScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent,
+ kMozMousePixelScrollEvent | kHorizontalScrollEvent | kInSystemGroup,
+ kWheelEvent | kInSystemGroup | kDefaultPrevented],
+ resultEvents: [],
+ doPreventDefaultAt: kMozMousePixelScrollEvent | kVerticalScrollEvent | kInSystemGroup,
+ },
+ ];
+
+ function getEventDescription(aEvent)
+ {
+ var result = "";
+ if (aEvent & kWheelEvent) {
+ result = "wheel"
+ } else {
+ if (aEvent & kDOMMouseScrollEvent) {
+ result = "DOMMouseScroll";
+ } else if (aEvent & kMozMousePixelScrollEvent) {
+ result = "MozMousePixelScroll";
+ }
+ if (aEvent & kVerticalScrollEvent) {
+ result += ", vertical";
+ } else {
+ result += ", horizontal";
+ }
+ }
+ if (aEvent & kInSystemGroup) {
+ result += ", system group";
+ }
+ if (aEvent & kDefaultPrevented) {
+ result += ", defaultPrevented";
+ }
+ return result;
+ }
+
+ function pushEvent(aEvent, aIsSystemGroup)
+ {
+ var event = 0;
+ if (aEvent.type == "wheel") {
+ event = kWheelEvent;
+ } else {
+ if (aEvent.type == "DOMMouseScroll") {
+ event = kDOMMouseScrollEvent;
+ } else if (aEvent.type == "MozMousePixelScroll") {
+ event = kMozMousePixelScrollEvent;
+ }
+ if (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS) {
+ event |= kHorizontalScrollEvent;
+ } else {
+ event |= kVerticalScrollEvent;
+ }
+ }
+ if (aIsSystemGroup) {
+ event |= kInSystemGroup;
+ }
+ if (aEvent.defaultPrevented) {
+ event |= kDefaultPrevented;
+ }
+ currentTest.resultEvents.push(event);
+
+ if (event == currentTest.doPreventDefaultAt) {
+ aEvent.preventDefault();
+ }
+
+ if (currentTest.resultEvents.length == currentTest.expectedEvents.length) {
+ setTimeout(continueTest, 0);
+ }
+ }
+
+ function handler(aEvent)
+ {
+ pushEvent(aEvent, false);
+ }
+
+ function systemHandler(aEvent)
+ {
+ pushEvent(aEvent, true);
+ }
+
+ window.addEventListener("wheel", handler, true);
+ window.addEventListener("DOMMouseScroll", handler, true);
+ window.addEventListener("MozMousePixelScroll", handler, true);
+
+ SpecialPowers.addSystemEventListener(window, "wheel", systemHandler, true);
+ SpecialPowers.addSystemEventListener(window, "DOMMouseScroll", systemHandler, true);
+ SpecialPowers.addSystemEventListener(window, "MozMousePixelScroll", systemHandler, true);
+
+ for (var i = 0; i < kTests.length; i++) {
+ currentTest = kTests[i];
+ yield synthesizeWheel(gScrollableElement, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE, deltaX: 1.0, deltaY: 1.0 });
+
+ for (var j = 0; j < currentTest.expectedEvents.length; j++) {
+ if (currentTest.resultEvents.length == j) {
+ ok(false, currentTest.description + ": " +
+ getEventDescription(currentTest.expectedEvents[j]) + " wasn't fired");
+ break;
+ }
+ is(getEventDescription(currentTest.resultEvents[j]),
+ getEventDescription(currentTest.expectedEvents[j]),
+ currentTest.description + ": " + (j + 1) + "th event is mismatched");
+ }
+ if (currentTest.expectedEvents.length < currentTest.resultEvents.length) {
+ ok(false, currentTest.description + ": " +
+ getEventDescription(currentTest.resultEvents[currentTest.expectedEvents.length]) +
+ " was fired unexpectedly");
+ }
+ }
+
+ window.removeEventListener("wheel", handler, true);
+ window.removeEventListener("DOMMouseScroll", handler, true);
+ window.removeEventListener("MozMousePixelScroll", handler, true);
+
+ SpecialPowers.removeSystemEventListener(window, "wheel", systemHandler, true);
+ SpecialPowers.removeSystemEventListener(window, "DOMMouseScroll", systemHandler, true);
+ SpecialPowers.removeSystemEventListener(window, "MozMousePixelScroll", systemHandler, true);
+}
+
+var gOnWheelAttrHandled = new Array;
+var gOnWheelAttrCount = 0;
+
+function* testOnWheelAttr()
+{
+ function onWheelHandledString(attr) {
+ return `gOnWheelAttrHandled['${attr}'] = true;
+ ++gOnWheelAttrCount;
+ if (gOnWheelAttrCount == 3) {
+ setTimeout(continueTest, 0);
+ };`;
+ }
+
+ document.documentElement.setAttribute("onwheel", onWheelHandledString("html"));
+ document.body.setAttribute("onwheel", onWheelHandledString("body"));
+ gScrollableElement.setAttribute("onwheel", onWheelHandledString("div"));
+ var target = document.getElementById("onwheel");
+ yield synthesizeWheel(gScrollableElement, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 2.0 });
+ ok(gOnWheelAttrHandled['html'], "html element's onwheel attribute isn't performed");
+ ok(gOnWheelAttrHandled['body'], "body element's onwheel attribute isn't performed");
+ ok(gOnWheelAttrHandled['div'], "div element's onwheel attribute isn't performed");
+}
+
+var gOnWheelPropHandled = new Array;
+var gOnWheelPropCount = 0;
+
+function* testOnWheelProperty()
+{
+ const handleOnWheelProp = prop => e => {
+ gOnWheelPropHandled[prop] = true;
+ ++gOnWheelPropCount;
+ if (gOnWheelPropCount == 5) {
+ setTimeout(continueTest, 0);
+ }
+ }
+
+ window.onwheel = handleOnWheelProp('window');
+ document.onwheel = handleOnWheelProp('document');
+ document.documentElement.onwheel = handleOnWheelProp('html');
+ document.body.onwheel = handleOnWheelProp('body');
+ gScrollableElement.onwheel = handleOnWheelProp('div');
+
+ var target = document.getElementById("onwheel");
+ yield synthesizeWheel(gScrollableElement, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 2.0 });
+
+ ok(gOnWheelPropHandled['window'], "window's onwheel property isn't performed");
+ ok(gOnWheelPropHandled['document'], "document's onwheel property isn't performed");
+ ok(gOnWheelPropHandled['html'], "html element's onwheel property isn't performed");
+ ok(gOnWheelPropHandled['body'], "body element's onwheel property isn't performed");
+ ok(gOnWheelPropHandled['div'], "div element's onwheel property isn't performed");
+}
+
+function* testBody()
+{
+ yield* prepareScrollUnits();
+ testMakingUntrustedEvent();
+ yield* testDeltaMultiplierPrefs();
+ testDispatchingUntrustEvent();
+ yield* testEventOrder();
+ yield* testOnWheelAttr();
+ yield* testOnWheelProperty();
+}
+
+var gTestContinuation = null;
+
+function continueTest()
+{
+ if (!gTestContinuation) {
+ gTestContinuation = testBody();
+ }
+ var ret = gTestContinuation.next();
+ if (ret.done) {
+ SimpleTest.finish();
+ }
+}
+
+function runTest()
+{
+ SpecialPowers.pushPrefEnv({"set": [
+ ["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100],
+ ["mousewheel.default.delta_multiplier_z", 100],
+ ["mousewheel.with_alt.delta_multiplier_x", 100],
+ ["mousewheel.with_alt.delta_multiplier_y", 100],
+ ["mousewheel.with_alt.delta_multiplier_z", 100],
+ ["mousewheel.with_control.delta_multiplier_x", 100],
+ ["mousewheel.with_control.delta_multiplier_y", 100],
+ ["mousewheel.with_control.delta_multiplier_z", 100],
+ ["mousewheel.with_meta.delta_multiplier_x", 100],
+ ["mousewheel.with_meta.delta_multiplier_y", 100],
+ ["mousewheel.with_meta.delta_multiplier_z", 100],
+ ["mousewheel.with_shift.delta_multiplier_x", 100],
+ ["mousewheel.with_shift.delta_multiplier_y", 100],
+ ["mousewheel.with_shift.delta_multiplier_z", 100],
+ ["mousewheel.with_win.delta_multiplier_x", 100],
+ ["mousewheel.with_win.delta_multiplier_y", 100],
+ ["mousewheel.with_win.delta_multiplier_z", 100]]},
+ continueTest);
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_draggableprop.html b/dom/events/test/test_draggableprop.html
new file mode 100644
index 000000000..7a5b5914d
--- /dev/null
+++ b/dom/events/test/test_draggableprop.html
@@ -0,0 +1,89 @@
+<html>
+<head>
+ <title>Tests for the draggable property on HTML elements</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+ <script type="application/javascript"
+ src="/tests/SimpleTest/SimpleTest.js"></script>
+
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+
+<span id="elem1">One</span>
+<span id="elem2" draggable="true">Two</span>
+<span id="elem3" draggable="">Three</span>
+<span id="elem4" draggable="false">Four</span>
+<span id="elem5" draggable="other">Five</span>
+
+<img id="img1" src="../happy.png">
+<img id="img2" src="../happy.png" draggable="true">
+<img id="img3" src="../happy.png" draggable="">
+<img id="img4" src="../happy.png" draggable="false">
+<img id="img5" src="../happy.png" draggable="other">
+
+<a id="a1">One</a>
+<a id="a2" draggable="true">Two</a>
+<a id="a3" draggable="">Three</a>
+<a id="a4" draggable="false">Four</a>
+<a id="a5" draggable="other">Five</a>
+
+<a id="ahref1" href="http://www.mozilla.org">One</a>
+<a id="ahref2" href="http://www.mozilla.org" draggable="true">Two</a>
+<a id="ahref3" href="http://www.mozilla.org" draggable="">Three</a>
+<a id="ahref4" href="http://www.mozilla.org" draggable="false">Four</a>
+<a id="ahref5" href="http://www.mozilla.org" draggable="other">Five</a>
+
+<script>
+function check()
+{
+ try {
+ checkElements(1, false, true, false, true);
+ checkElements(2, true, true, true, true);
+ checkElements(3, false, true, false, true);
+ checkElements(4, false, false, false, false);
+ checkElements(5, false, true, false, true);
+ }
+ catch (ex) {
+ is("script error", ex, "fail");
+ }
+}
+
+function checkElements(idx, estate, istate, astate, ahrefstate)
+{
+ checkElement("elem" + idx, estate, false);
+ checkElement("img" + idx, istate, true);
+ checkElement("a" + idx, astate, false);
+ checkElement("ahref" + idx, ahrefstate, true);
+}
+
+function checkElement(elemid, state, statedef)
+{
+ var elem = document.getElementById(elemid);
+
+ is(elem.draggable, state, elemid + "-initial");
+ elem.draggable = true;
+ is(elem.draggable, true, elemid + "-true");
+ elem.draggable = false;
+ is(elem.draggable, false, elemid + "-false");
+
+ elem.setAttribute("draggable", "true");
+ is(elem.draggable, true, elemid + "-attr-true");
+ elem.setAttribute("draggable", "false");
+ is(elem.draggable, false, elemid + "-attr-false");
+ elem.setAttribute("draggable", "other");
+ is(elem.draggable, statedef, elemid + "-attr-other");
+ elem.setAttribute("draggable", "");
+ is(elem.draggable, statedef, elemid + "-attr-empty");
+ elem.removeAttribute("draggable");
+ is(elem.draggable, statedef, elemid + "-attr-removed");
+}
+
+check();
+
+</script>
+
+</body>
+</html>
+
+
diff --git a/dom/events/test/test_dragstart.html b/dom/events/test/test_dragstart.html
new file mode 100644
index 000000000..3c76d4f16
--- /dev/null
+++ b/dom/events/test/test_dragstart.html
@@ -0,0 +1,585 @@
+<html>
+<head>
+ <title>Tests for the dragstart event</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<!--
+ This test checks the dragstart event and the DataTransfer object
+ -->
+
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+var gDragInfo;
+var gDataTransfer = null;
+var gExtraDragTests = 0;
+
+function runTests()
+{
+ // first, create a selection and try dragging it
+ var draggable = $("draggable");
+ window.getSelection().selectAllChildren(draggable);
+ synthesizeMouse(draggable, 6, 6, { type: "mousedown" });
+ synthesizeMouse(draggable, 14, 14, { type: "mousemove" });
+ // drags are asynchronous on Linux, so this extra event is needed to make
+ // sure the drag gets processed
+ synthesizeMouse(draggable, 15, 15, { type: "mousemove" });
+}
+
+function afterDragTests()
+{
+ // the dragstart should have occurred due to moving the mouse. gDataTransfer
+ // caches the dataTransfer that was used, however it should now be empty and
+ // be read only.
+ ok(gDataTransfer instanceof DataTransfer, "DataTransfer after dragstart event");
+ checkTypes(gDataTransfer, [], 0, "after dragstart event");
+
+ expectError(() => gDataTransfer.setData("text/plain", "Some Text"),
+ "NoModificationAllowedError", "setData when read only");
+ expectError(() => gDataTransfer.clearData("text/plain"),
+ "NoModificationAllowedError", "clearData when read only");
+ expectError(() => gDataTransfer.mozSetDataAt("text/plain", "Some Text", 0),
+ "NoModificationAllowedError", "setDataAt when read only");
+ expectError(() => gDataTransfer.mozClearDataAt("text/plain", 0),
+ "NoModificationAllowedError", "clearDataAt when read only");
+ expectError(() => gDataTransfer.setDragImage(draggable, 10, 10),
+ "NoModificationAllowedError", "setDragImage when read only");
+ expectError(() => gDataTransfer.addElement(draggable),
+ "NoModificationAllowedError", "addElement when read only");
+
+ var evt = document.createEvent("dragevent");
+ ok(evt instanceof DragEvent, "synthetic dragevent class")
+ ok(evt instanceof MouseEvent, "synthetic event inherits from MouseEvent")
+ evt.initDragEvent("dragstart", true, true, window, 1, 40, 35, 20, 15,
+ false, true, false, false, 0, null, null);
+ $("synthetic").dispatchEvent(evt);
+
+ var evt = document.createEvent("dragevent");
+ ok(evt instanceof DragEvent, "synthetic dragevent class")
+ evt.initDragEvent("dragover", true, true, window, 0, 40, 35, 20, 15,
+ true, false, true, true, 2, document.documentElement, null);
+ $("synthetic2").dispatchEvent(evt);
+
+ // next, dragging links and images
+ sendMouseEventsForDrag("link");
+ sendMouseEventsForDrag("image");
+
+// disable testing input dragging for now, as it doesn't seem to be testable
+// draggable = $("input");
+// draggable.setSelectionRange(0, 4);
+// synthesizeMouse(draggable, 8, 8, { type: "mousedown" });
+// synthesizeMouse(draggable, 15, 15, { type: "mousemove" });
+// sendMouseEventsForDrag("input");
+
+ // next, check if the draggable attribute can be used to adjust the drag target
+ gDragInfo = { target: $("dragtrue"), testid: "draggable true node" };
+ sendMouseEventsForDrag("dragtrue");
+ gDragInfo = { target: $("dragtrue"), testid: "draggable true child" };
+ sendMouseEventsForDrag("spantrue");
+ gDragInfo = { target: $("dragfalse").firstChild, testid: "draggable false node" };
+ sendMouseEventsForDrag("dragfalse");
+ gDragInfo = { target: $("spanfalse").firstChild, testid: "draggable false child" };
+ sendMouseEventsForDrag("spanfalse");
+
+ synthesizeMouse(draggable, 12, 12, { type: "mouseup" });
+ if (gExtraDragTests == 4)
+ SimpleTest.finish();
+}
+
+function sendMouseEventsForDrag(nodeid)
+{
+ var draggable = $(nodeid);
+ synthesizeMouse(draggable, 3, 3, { type: "mousedown" });
+ synthesizeMouse(draggable, 10, 10, { type: "mousemove" });
+ synthesizeMouse(draggable, 12, 12, { type: "mousemove" });
+}
+
+function doDragStartSelection(event)
+{
+ is(event.type, "dragstart", "dragstart event type");
+ is(event.target, $("draggable").firstChild, "dragstart event target");
+ is(event.bubbles, true, "dragstart event bubbles");
+ is(event.cancelable, true, "dragstart event cancelable");
+
+ is(event.clientX, 14, "dragstart clientX");
+ is(event.clientY, 14, "dragstart clientY");
+ ok(event.screenX > 0, "dragstart screenX");
+ ok(event.screenY > 0, "dragstart screenY");
+ is(event.layerX, 14, "dragstart layerX");
+ is(event.layerY, 14, "dragstart layerY");
+ is(event.pageX, 14, "dragstart pageX");
+ is(event.pageY, 14, "dragstart pageY");
+
+ var dt = event.dataTransfer;
+ ok(dt instanceof DataTransfer, "dataTransfer is DataTransfer");
+ gDataTransfer = dt;
+
+ var types = dt.types;
+ ok(Array.isArray(types), "initial types is an Array");
+ checkTypes(dt, ["text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial selection");
+
+ is(dt.getData("text/plain"), "This is a draggable bit of text.", "initial selection text/plain");
+ is(dt.getData("text/html"), "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>",
+ "initial selection text/html");
+
+ // text/unicode and Text are available for compatibility. They retrieve the
+ // text/plain data
+ is(dt.getData("text/unicode"), "This is a draggable bit of text.", "initial selection text/unicode");
+ is(dt.getData("Text"), "This is a draggable bit of text.", "initial selection Text");
+ is(dt.getData("TEXT"), "This is a draggable bit of text.", "initial selection TEXT");
+ is(dt.getData("text/UNICODE"), "This is a draggable bit of text.", "initial selection text/UNICODE");
+
+ is(dt.mozItemCount, 1, "initial selection item count");
+
+ dt.clearData("text/plain");
+ dt.clearData("text/html");
+ dt.clearData("text/_moz_htmlinfo");
+ dt.clearData("text/_moz_htmlcontext");
+
+ test_DataTransfer(dt);
+ setTimeout(afterDragTests, 0);
+}
+
+function test_DataTransfer(dt)
+{
+ is(dt.mozItemCount, 0, "empty itemCount");
+
+ var types = dt.types;
+ ok(Array.isArray(types), "empty types is an Array");
+ checkTypes(dt, [], 0, "empty");
+ is(dt.getData("text/plain"), "", "empty data is empty");
+
+ // calling setDataAt requires an index that is 0 <= index <= dt.itemCount
+ expectError(() => dt.mozSetDataAt("text/plain", "Some Text", 1),
+ "IndexSizeError", "setDataAt index too high");
+
+ is(dt.mozUserCancelled, false, "userCancelled");
+
+ // because an exception occurred, the data should not have been added
+ is(dt.mozItemCount, 0, "empty setDataAt index too high itemCount");
+ dt.getData("text/plain", "", "empty setDataAt index too high getData");
+
+ // if the type is '', do nothing, or return ''
+ dt.setData("", "Invalid Type");
+ is(dt.types.length, 0, "invalid type setData");
+ is(dt.getData(""), "", "invalid type getData"),
+ dt.mozSetDataAt("", "Invalid Type", 0);
+ is(dt.types.length, 0, "invalid type setDataAt");
+ is(dt.mozGetDataAt("", 0), null, "invalid type getDataAt"),
+
+ // similar with clearDataAt and getDataAt
+ expectError(() => dt.mozGetDataAt("text/plain", 1),
+ "IndexSizeError", "getDataAt index too high");
+ expectError(() => dt.mozClearDataAt("text/plain", 1),
+ "IndexSizeError", "clearDataAt index too high");
+
+ dt.setData("text/plain", "Sample Text");
+ is(dt.mozItemCount, 1, "added plaintext itemCount");
+ checkOneDataItem(dt, ["text/plain"], ["Sample Text"], 0, "added plaintext");
+
+ // after all those exceptions, the data should still be the same
+ checkOneDataItem(dt, ["text/plain"], ["Sample Text"], 0, "added plaintext after exception");
+
+ // modifying the data associated with the format should give it the new value
+ dt.setData("text/plain", "Modified Text");
+ is(dt.mozItemCount, 1, "modified plaintext itemCount");
+ checkOneDataItem(dt, ["text/plain"], ["Modified Text"], 0, "modified plaintext");
+
+ dt.setData("text/html", "<strong>Modified Text</strong>");
+ is(dt.mozItemCount, 1, "modified html itemCount");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["Modified Text", "<strong>Modified Text</strong>"],
+ 0, "modified html");
+
+ // modifying data for a type that already exists should adjust it in place,
+ // not reinsert it at the beginning
+ dt.setData("text/plain", "New Text");
+ is(dt.mozItemCount, 1, "modified text again itemCount");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["New Text", "<strong>Modified Text</strong>"],
+ 0, "modified text again");
+
+ var draggable = $("draggable");
+ dt.setData("application/-moz-node", draggable);
+ checkOneDataItem(dt, ["text/plain", "text/html", "application/-moz-node"],
+ ["New Text", "<strong>Modified Text</strong>", draggable.toString()],
+ 0, "added node");
+
+ dt.clearData(""); // null means clear all
+ is(dt.mozItemCount, 0, "itemCount after clearData empty string");
+ checkTypes(dt, [], 0, "empty after clearData empty string");
+
+ dt.setData("text/plain", 22);
+ dt.setData("text/html", 5.6);
+ dt.setData("text/xml", 5.6);
+ checkTypes(dt, ["text/plain", "text/html", "text/xml"], ["22", "5.6", ""], 0, "add numeric and empty data");
+
+ dt.clearData(); // no argument means clear all
+ is(dt.mozItemCount, 0, "itemCount after clearData no argument");
+ checkTypes(dt, [], 0, "empty after clearData no argument");
+
+ // check 'Text' type which should convert into text/plain
+ dt.setData("Text", "Sample Text");
+ checkOneDataItem(dt, ["text/plain"], ["Sample Text"], 0, "set Text");
+ is(dt.getData("Text"), "Sample Text", "getData Text");
+ is(dt.mozGetDataAt("Text", 0), "Sample Text", "getDataAt Text");
+ dt.setData("text/plain", "More Text");
+ checkOneDataItem(dt, ["text/plain"], ["More Text"], 0, "set text/plain after set Text");
+
+ dt.mozClearDataAt("", 0); // null means clear all
+ is(dt.mozItemCount, 0, "itemCount after clearDataAt empty string");
+ checkTypes(dt, [], 0, "empty after clearDataAt empty string");
+
+ // check text/uri-list type
+ dt.setData("text/uri-list", "http://www.mozilla.org");
+ checkURL(dt, "http://www.mozilla.org", "http://www.mozilla.org", 0, "set text/uri-list");
+
+ // check URL type which should add text/uri-list data
+ dt.setData("URL", "ftp://ftp.example.com");
+ checkURL(dt, "ftp://ftp.example.com", "ftp://ftp.example.com", 0, "set URL");
+ checkTypes(dt, ["text/uri-list"], ["ftp://ftp.example.com"], "url types");
+
+ // clearing text/uri-list data
+ dt.clearData("text/uri-list");
+ is(dt.mozItemCount, 0, "itemCount after clear url-list");
+ is(dt.getData("text/uri-list"), "", "text/uri-list after clear url-list");
+ is(dt.getData("URL"), "", "URL after clear url-list");
+
+ // check text/uri-list parsing
+ dt.setData("text/uri-list", "#http://www.mozilla.org\nhttp://www.xulplanet.com\nhttp://www.example.com");
+ checkURL(dt, "http://www.xulplanet.com",
+ "#http://www.mozilla.org\nhttp://www.xulplanet.com\nhttp://www.example.com",
+ 0, "uri-list 3 lines");
+
+ dt.setData("text/uri-list", "#http://www.mozilla.org");
+ is(dt.getData("URL"), "", "uri-list commented");
+ dt.setData("text/uri-list", "#http://www.mozilla.org\n");
+ is(dt.getData("URL"), "", "uri-list commented with newline");
+
+ // check that clearing the URL type also clears the text/uri-list type
+ dt.clearData("URL");
+ is(dt.getData("text/uri-list"), "", "clear URL");
+
+ dt.setData("text/uri-list", "#http://www.mozilla.org\n\n\n\n\n");
+ is(dt.getData("URL"), "", "uri-list with blank lines");
+ dt.setData("text/uri-list", "");
+ is(dt.getData("URL"), "", "empty uri-list");
+ dt.setData("text/uri-list", "#http://www.mozilla.org\n#Sample\nhttp://www.xulplanet.com \r\n");
+ is(dt.getData("URL"), "http://www.xulplanet.com", "uri-list mix");
+ dt.setData("text/uri-list", "\nhttp://www.mozilla.org");
+ is(dt.getData("URL"), "", "empty line to start uri-list");
+ dt.setData("text/uri-list", " http://www.mozilla.org#anchor ");
+ is(dt.getData("URL"), "http://www.mozilla.org#anchor", "uri-list with spaces and hash");
+
+ // ensure that setDataAt works the same way
+ dt.mozSetDataAt("text/uri-list", "#http://www.mozilla.org\n#Sample\nhttp://www.xulplanet.com \r\n", 0);
+ checkURL(dt, "http://www.xulplanet.com",
+ "#http://www.mozilla.org\n#Sample\nhttp://www.xulplanet.com \r\n",
+ 0, "uri-list mix setDataAt");
+
+ // now test adding multiple items to be dragged using the setDataAt method
+ dt.clearData();
+ dt.mozSetDataAt("text/plain", "First Item", 0);
+ dt.mozSetDataAt("text/plain", "Second Item", 1);
+ expectError(() => dt.mozSetDataAt("text/plain", "Some Text", 3),
+ "IndexSizeError", "setDataAt index too high with two items");
+ is(dt.mozItemCount, 2, "setDataAt item itemCount");
+ checkOneDataItem(dt, ["text/plain"], ["First Item"], 0, "setDataAt item at index 0");
+ checkOneDataItem(dt, ["text/plain"], ["Second Item"], 1, "setDataAt item at index 1");
+
+ dt.mozSetDataAt("text/html", "<em>First Item</em>", 0);
+ dt.mozSetDataAt("text/html", "<em>Second Item</em>", 1);
+ is(dt.mozItemCount, 2, "setDataAt two types item itemCount");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "<em>First Item</em>"], 0, "setDataAt two types item at index 0");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["Second Item", "<em>Second Item</em>"], 1, "setDataAt two types item at index 1");
+
+ dt.mozSetDataAt("text/html", "<em>Changed First Item</em>", 0);
+ dt.mozSetDataAt("text/plain", "Changed Second Item", 1);
+ is(dt.mozItemCount, 2, "changed with setDataAt item itemCount");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "<em>Changed First Item</em>"], 0, "changed with setDataAt item at index 0");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["Changed Second Item", "<em>Second Item</em>"], 1, "changed with setDataAt item at index 1");
+
+ dt.setData("text/html", "Changed with setData");
+ is(dt.mozItemCount, 2, "changed with setData");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "Changed with setData"], 0, "changed with setData item at index 0");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["Changed Second Item", "<em>Second Item</em>"], 1, "changed with setData item at index 1");
+
+ dt.mozSetDataAt("application/-moz-node", "draggable", 2);
+ is(dt.mozItemCount, 3, "setDataAt node itemCount");
+ checkOneDataItem(dt, ["application/-moz-node"], ["draggable"], 2, "setDataAt node item at index 2");
+
+ dt.mozClearDataAt("text/html", 1);
+ is(dt.mozItemCount, 3, "clearDataAt itemCount");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "Changed with setData"], 0, "clearDataAt item at index 0");
+ checkOneDataItem(dt, ["text/plain"], ["Changed Second Item"], 1, "clearDataAt item at index 1");
+
+ dt.mozClearDataAt("text/plain", 1);
+ is(dt.mozItemCount, 2, "clearDataAt last type itemCount");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "Changed with setData"], 0, "clearDataAt last type at index 0");
+ checkOneDataItem(dt, ["application/-moz-node"], ["draggable"], 1, "clearDataAt last type item at index 2");
+ expectError(() => dt.mozGetDataAt("text/plain", 2),
+ "IndexSizeError", "getDataAt after item removed index too high");
+
+ dt.mozSetDataAt("text/unknown", "Unknown type", 2);
+ dt.mozSetDataAt("text/unknown", "Unknown type", 1);
+ is(dt.mozItemCount, 3, "add unknown type");
+ checkOneDataItem(dt, ["application/-moz-node", "text/unknown"],
+ ["draggable", "Unknown type"], 1, "add unknown type item at index 1");
+ checkOneDataItem(dt, ["text/unknown"], ["Unknown type"], 2, "add unknown type item at index 2");
+
+ dt.mozClearDataAt("", 1);
+ is(dt.mozItemCount, 2, "clearDataAt empty string");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "Changed with setData"], 0, "clearDataAt empty string item at index 0");
+ checkOneDataItem(dt, ["text/unknown"],
+ ["Unknown type"], 1, "clearDataAt empty string item at index 1");
+
+ // passing a format that doesn't exist to clearData or clearDataAt should just
+ // do nothing
+ dt.clearData("text/something");
+ dt.mozClearDataAt("text/something", 1);
+ is(dt.mozItemCount, 2, "clearData type that does not exist");
+ checkOneDataItem(dt, ["text/plain", "text/html"],
+ ["First Item", "Changed with setData"], 0, "clearData type that does not exist item at index 0");
+ checkOneDataItem(dt, ["text/unknown"],
+ ["Unknown type"], 1, "clearData type that does not exist item at index 1");
+
+ expectError(() => dt.mozClearDataAt("text/plain", 3),
+ "IndexSizeError", "clearData index too high with two items");
+
+ // ensure that clearData() removes all data associated with the first item, but doesn't
+ // shift the second item down into the first item's slot.
+ dt.clearData();
+ is(dt.mozItemCount, 2, "clearData no argument with multiple items itemCount");
+ checkOneDataItem(dt, [], [], 0,
+ "clearData no argument with multiple items item at index 0");
+ checkOneDataItem(dt, ["text/unknown"],
+ ["Unknown type"], 1, "clearData no argument with multiple items item at index 1");
+
+ // remove tha remaining data in index 1. As index 0 is empty at this point, this will actually
+ // drop mozItemCount to 0. (XXX: This is because of spec-compliance reasons related
+ // to the more-recent dt.item API. It's an unfortunate, but hopefully rare edge case)
+ dt.mozClearDataAt("", 1);
+ is(dt.mozItemCount, 0, "all data cleared");
+
+ // now check the effectAllowed and dropEffect properties
+ is(dt.dropEffect, "none", "initial dropEffect");
+ is(dt.effectAllowed, "uninitialized", "initial effectAllowed");
+
+ ["copy", "none", "link", "", "other", "copyMove", "all", "uninitialized", "move"].forEach(
+ function (i) {
+ dt.dropEffect = i;
+ is(dt.dropEffect, i == "" || i == "other" || i == "copyMove" ||
+ i == "all" || i == "uninitialized" ? "link" : i,
+ "dropEffect set to " + i);
+ is(dt.effectAllowed, "uninitialized", "effectAllowed not modified by dropEffect set to " + i);
+ }
+ );
+
+ ["move", "copy", "link", "", "other", "moveCopy", "copyMove",
+ "linkMove", "copyLink", "all", "uninitialized", "none"].forEach(
+ function (i) {
+ dt.effectAllowed = i;
+ is(dt.dropEffect, "move", "dropEffect not modified by effectAllowed set to " + i);
+ is(dt.effectAllowed, i == "" || i == "other" || i == "moveCopy" ? "link" : i,
+ "effectAllowed set to " + i);
+ }
+ );
+}
+
+function doDragStartLink(event)
+{
+ var dt = event.dataTransfer;
+ checkTypes(dt, ["text/x-moz-url", "text/x-moz-url-data", "text/x-moz-url-desc", "text/uri-list",
+ "text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial link");
+
+ is(dt.mozItemCount, 1, "initial link item count");
+ is(dt.getData("text/uri-list"), "http://www.mozilla.org/", "link text/uri-list");
+ is(dt.getData("text/plain"), "http://www.mozilla.org/", "link text/plain");
+
+ event.preventDefault();
+
+ gExtraDragTests++;
+}
+
+function doDragStartImage(event)
+{
+ var dataurl = $("image").src;
+
+ var dt = event.dataTransfer;
+ checkTypes(dt, ["text/x-moz-url", "text/x-moz-url-data", "text/x-moz-url-desc", "text/uri-list",
+ "text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial image");
+
+ is(dt.mozItemCount, 1, "initial image item count");
+ is(dt.getData("text/uri-list"), dataurl, "image text/uri-list");
+ is(dt.getData("text/plain"), dataurl, "image text/plain");
+
+ event.preventDefault();
+
+ gExtraDragTests++;
+}
+
+function doDragStartInput(event)
+{
+ var dt = event.dataTransfer;
+ checkTypes(dt, ["text/plain"], 0, "initial input");
+
+ is(dt.mozItemCount, 1, "initial input item count");
+// is(dt.getData("text/plain"), "Text", "input text/plain");
+
+// event.preventDefault();
+}
+
+function doDragStartSynthetic(event)
+{
+ is(event.type, "dragstart", "synthetic dragstart event type");
+
+ var dt = event.dataTransfer;
+ todo(dt instanceof DataTransfer, "synthetic dragstart dataTransfer is DataTransfer");
+// Uncomment next line once the todo instanceof above is fixed.
+// checkTypes(dt, [], 0, "synthetic dragstart");
+
+ is(event.detail, 1, "synthetic dragstart detail");
+ is(event.screenX, 40, "synthetic dragstart screenX");
+ is(event.screenY, 35, "synthetic dragstart screenY");
+ is(event.clientX, 20, "synthetic dragstart clientX");
+ is(event.clientY, 15, "synthetic dragstart clientY");
+ is(event.ctrlKey, false, "synthetic dragstart ctrlKey");
+ is(event.altKey, true, "synthetic dragstart altKey");
+ is(event.shiftKey, false, "synthetic dragstart shiftKey");
+ is(event.metaKey, false, "synthetic dragstart metaKey");
+ is(event.button, 0, "synthetic dragstart button ");
+ is(event.relatedTarget, null, "synthetic dragstart relatedTarget");
+
+// Uncomment next two lines once the todo instanceof above is fixed.
+// dt.setData("text/plain", "Text");
+// is(dt.getData("text/plain"), "Text", "synthetic dragstart data is set after adding");
+}
+
+function doDragOverSynthetic(event)
+{
+ is(event.type, "dragover", "synthetic dragover event type");
+
+ var dt = event.dataTransfer;
+ todo(dt instanceof DataTransfer, "synthetic dragover dataTransfer is DataTransfer");
+// Uncomment next line once the todo instanceof above is fixed.
+// checkTypes(dt, [], 0, "synthetic dragover");
+
+ is(event.detail, 0, "synthetic dragover detail");
+ is(event.screenX, 40, "synthetic dragover screenX");
+ is(event.screenY, 35, "synthetic dragover screenY");
+ is(event.clientX, 20, "synthetic dragover clientX");
+ is(event.clientY, 15, "synthetic dragover clientY");
+ is(event.ctrlKey, true, "synthetic dragover ctrlKey");
+ is(event.altKey, false, "synthetic dragover altKey");
+ is(event.shiftKey, true, "synthetic dragover shiftKey");
+ is(event.metaKey, true, "synthetic dragover metaKey");
+ is(event.button, 2, "synthetic dragover button");
+ is(event.relatedTarget, document.documentElement, "synthetic dragover relatedTarget");
+
+// Uncomment next two lines once the todo instanceof above is fixed.
+// dt.setData("text/plain", "Text");
+// is(dt.getData("text/plain"), "Text", "synthetic dragover data is set after adding");
+}
+
+function onDragStartDraggable(event)
+{
+ var dt = event.dataTransfer;
+ ok(dt.mozItemCount == 0 && dt.types.length == 0 && event.originalTarget == gDragInfo.target, gDragInfo.testid);
+
+ gExtraDragTests++;
+}
+
+function checkOneDataItem(dt, expectedtypes, expecteddata, index, testid)
+{
+ checkTypes(dt, expectedtypes, index, testid);
+ for (var f = 0; f < expectedtypes.length; f++) {
+ if (index == 0)
+ is(dt.getData(expectedtypes[f]), expecteddata[f], testid + " getData " + expectedtypes[f]);
+ is(dt.mozGetDataAt(expectedtypes[f], index), expecteddata[f] ? expecteddata[f] : null,
+ testid + " getDataAt " + expectedtypes[f]);
+ }
+}
+
+function checkTypes(dt, expectedtypes, index, testid)
+{
+ if (index == 0) {
+ var types = dt.types;
+ is(types.length, expectedtypes.length, testid + " types length");
+ for (var f = 0; f < expectedtypes.length; f++) {
+ is(types[f], expectedtypes[f], testid + " " + types[f] + " check");
+ }
+ }
+
+ types = dt.mozTypesAt(index);
+ is(types.length, expectedtypes.length, testid + " typesAt length");
+ for (var f = 0; f < expectedtypes.length; f++) {
+ is(types[f], expectedtypes[f], testid + " " + types[f] + " at " + index + " check");
+ }
+}
+
+function checkURL(dt, url, fullurllist, index, testid)
+{
+ is(dt.getData("text/uri-list"), fullurllist, testid + " text/uri-list");
+ is(dt.getData("URL"), url, testid + " URL");
+ is(dt.mozGetDataAt("text/uri-list", 0), fullurllist, testid + " text/uri-list");
+ is(dt.mozGetDataAt("URL", 0), fullurllist, testid + " URL");
+}
+
+function expectError(fn, eid, testid)
+{
+ var error = "";
+ try {
+ fn();
+ } catch (ex) {
+ error = ex.name;
+ }
+ is(error, eid, testid + " causes exception " + eid);
+}
+
+</script>
+
+</head>
+
+<body style="height: 300px; overflow: auto;" onload="setTimeout(runTests, 0)">
+
+<div id="draggable" ondragstart="doDragStartSelection(event)">This is a <em>draggable</em> bit of text.</div>
+
+<fieldset>
+<a id="link" href="http://www.mozilla.org/" ondragstart="doDragStartLink(event)">mozilla.org</a>
+</fieldset>
+
+<label>
+<img id="image" src="data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%18%00%00%00%18%02%03%00%00%00%9D%19%D5k%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%0CPLTE%FF%FF%FF%FF%FF%FF%F7%DC%13%00%00%00%03%80%01X%00%00%00%01tRNS%08N%3DPT%00%00%00%01bKGD%00%88%05%1DH%00%00%00%09pHYs%00%00%0B%11%00%00%0B%11%01%7Fd_%91%00%00%00%07tIME%07%D2%05%0C%14%0C%0D%D8%3F%1FQ%00%00%00%5CIDATx%9C%7D%8E%CB%09%C0%20%10D%07r%B7%20%2F%E9wV0%15h%EA%D9%12D4%BB%C1x%CC%5C%1E%0C%CC%07%C0%9C0%9Dd7()%C0A%D3%8D%E0%B8%10%1DiCHM%D0%AC%D2d%C3M%F1%B4%E7%FF%10%0BY%AC%25%93%CD%CBF%B5%B2%C0%3Alh%CD%AE%13%DF%A5%F7%E0%03byW%09A%B4%F3%E2%00%00%00%00IEND%AEB%60%82"
+ ondragstart="doDragStartImage(event)">
+</label>
+
+<input id="input" value="Text in a box" ondragstart="doDragStartInput(event)">
+
+<div ondragstart="onDragStartDraggable(event)">
+ <div id="dragtrue" draggable="true">
+ This is a <span id="spantrue">draggable</span> area.
+ </div>
+ <div id="dragfalse" draggable="false">
+ This is a <span id="spanfalse">non-draggable</span> area.
+ </div>
+</div>
+
+<!--iframe src="http://www.mozilla.org" width="400" height="400"></iframe-->
+
+<div id="synthetic" ondragstart="doDragStartSynthetic(event)">Synthetic Event Dispatch</div>
+<div id="synthetic2" ondragover="doDragOverSynthetic(event)">Synthetic Event Dispatch</div>
+
+</body>
+</html>
diff --git a/dom/events/test/test_error_events.html b/dom/events/test/test_error_events.html
new file mode 100644
index 000000000..62cbb68de
--- /dev/null
+++ b/dom/events/test/test_error_events.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for error events being ErrorEvent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ setup({allow_uncaught_exception:true});
+ var errorEvent;
+ var file;
+ var line;
+ var msg;
+ var column;
+ var error;
+ window.addEventListener("error", function errorListener(e) {
+ window.removeEventListener("error", errorListener);
+ errorEvent = e;
+ });
+ var oldOnerror = window.onerror;
+ window.onerror = function(message, filename, lineno, columnno, errorObject) {
+ window.onerror = oldOnerror;
+ file = filename;
+ line = lineno;
+ msg = message;
+ column = columnno;
+ error = errorObject;
+ }
+ var thrown = new Error("hello");
+ throw thrown;
+</script>
+<script>
+ generate_tests(assert_equals, [
+ [ "Event filename", errorEvent.filename, location.href ],
+ [ "Callback filename", file, location.href ],
+ [ "Event line number", errorEvent.lineno, 28 ],
+ [ "Callback line number", line, 28 ],
+ [ "Event message", errorEvent.message, "Error: hello" ],
+ [ "Callback message", msg, "Error: hello" ],
+ [ "Event error-object", errorEvent.error, thrown],
+ [ "Callback error-object", error, thrown ],
+ [ "Event column", errorEvent.colno, 16 ],
+ [ "Callback column", column, 16 ]
+ ]);
+</script>
+<script>
+ var workerLocation = location.protocol + "//" + location.host +
+ location.pathname.replace("test_error_events.html", "error_event_worker.js");
+ var eventFileTest = async_test("Worker event filename");
+ var eventLineTest = async_test("Worker event line number");
+ var eventMessageTest = async_test("Worker event message");
+ var callbackFileTest = async_test("Worker callback filename");
+ var callbackLineTest = async_test("Worker callback line number");
+ var callbackMessageTest = async_test("Worker callback message");
+ var w = new Worker("error_event_worker.js");
+ w.addEventListener("message", function(msg) {
+ if (msg.data.type == "event") {
+ eventFileTest.step(function() { assert_equals(msg.data.filename, workerLocation); });
+ eventFileTest.done();
+ eventLineTest.step(function() { assert_equals(msg.data.lineno, 15); });
+ eventLineTest.done();
+ eventMessageTest.step(function() { assert_equals(msg.data.message, "Error: workerhello"); });
+ eventMessageTest.done();
+ } else {
+ callbackFileTest.step(function() { assert_equals(msg.data.filename, workerLocation); });
+ callbackFileTest.done();
+ callbackLineTest.step(function() { assert_equals(msg.data.lineno, 15); });
+ callbackLineTest.done();
+ callbackMessageTest.step(function() { assert_equals(msg.data.message, "Error: workerhello"); });
+ callbackMessageTest.done();
+ }
+ });
+</script>
diff --git a/dom/events/test/test_eventTimeStamp.html b/dom/events/test/test_eventTimeStamp.html
new file mode 100644
index 000000000..a3d096432
--- /dev/null
+++ b/dom/events/test/test_eventTimeStamp.html
@@ -0,0 +1,121 @@
+<!doctype html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=77992
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Event.timeStamp (Bug 77992)</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=77992">Mozilla Bug 77992</a>
+<p id="display"></p>
+<pre id="test">
+<script type="text/js-worker" id="worker-src">
+ // Simply returns the event timestamp
+ onmessage = function(evt) {
+ postMessage(evt.timeStamp);
+ }
+</script>
+<script type="text/js-worker" id="shared-worker-src">
+ // Simply returns the event timestamp
+ onconnect = function(evt) {
+ var port = evt.ports[0];
+ port.onmessage = function(messageEvt) {
+ port.postMessage(messageEvt.timeStamp);
+ };
+ };
+</script>
+<script type="application/javascript">
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+
+// We don't use SpecialPowers.pushPrefEnv since it can delay the test
+// function until after the load event has fired which means we can't
+// test the timestamp of the load event.
+const kPrefName = "dom.event.highrestimestamp.enabled";
+var prevPrefValue = SpecialPowers.getBoolPref(kPrefName);
+SpecialPowers.setBoolPref(kPrefName, true);
+testRegularEvents();
+
+// Event.timeStamp should be relative to the time origin which is:
+//
+// Non-worker context: navigation start
+// Dedicated worker: navigation start of the document that created the worker
+// Shared worker: creation time of the shared worker
+//
+// See: https://w3c.github.io/web-performance/specs/HighResolutionTime2/Overview.html#sec-time-origin
+
+function testRegularEvents() {
+ if (document.readyState === "complete") {
+ ok(false, "Onload event has already fired");
+ finishTests();
+ return;
+ }
+ var timeBeforeEvent = window.performance.now();
+ window.addEventListener("load", function(evt) {
+ var timeAfterEvent = window.performance.now();
+ ok(evt.timeStamp > timeBeforeEvent &&
+ evt.timeStamp < timeAfterEvent,
+ "Event timestamp (" + evt.timeStamp + ") is in expected range: (" +
+ timeBeforeEvent + ", " + timeAfterEvent + ")");
+ testWorkerEvents();
+ });
+}
+
+function testWorkerEvents() {
+ var blob = new Blob([ document.getElementById("worker-src").textContent ],
+ { type: "text/javascript" });
+ var worker = new Worker(window.URL.createObjectURL(blob));
+ worker.onmessage = function(evt) {
+ var timeAfterEvent = window.performance.now();
+ ok(evt.data > timeBeforeEvent &&
+ evt.data < timeAfterEvent,
+ "Event timestamp in dedicated worker (" + evt.data +
+ ") is in expected range: (" +
+ timeBeforeEvent + ", " + timeAfterEvent + ")");
+ worker.terminate();
+ testSharedWorkerEvents();
+ };
+ var timeBeforeEvent = window.performance.now();
+ worker.postMessage("");
+}
+
+function testSharedWorkerEvents() {
+ var blob =
+ new Blob([ document.getElementById("shared-worker-src").textContent ],
+ { type: "text/javascript" });
+ // Delay creation of worker slightly so it is easier to distinguish
+ // shared worker creation time from this document's navigation start
+ window.setTimeout(function() {
+ var timeBeforeWorkerCreation = window.performance.now();
+ var worker = new SharedWorker(window.URL.createObjectURL(blob));
+ worker.port.onmessage = function(evt) {
+ var timeAfterEvent = window.performance.now();
+ ok(evt.data > 0 &&
+ evt.data < timeAfterEvent - timeBeforeWorkerCreation,
+ "Event timestamp in shared worker (" + evt.data +
+ ") is in expected range: (0, " +
+ (timeAfterEvent - timeBeforeWorkerCreation) + ")");
+ worker.port.close();
+ finishTests();
+ };
+ worker.port.start();
+ worker.port.postMessage("");
+ }, 500);
+}
+
+var finishTests = function() {
+ SpecialPowers.setBoolPref(kPrefName, prevPrefValue);
+ SimpleTest.finish();
+};
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_eventctors.html b/dom/events/test/test_eventctors.html
new file mode 100644
index 000000000..a18c2a5ed
--- /dev/null
+++ b/dom/events/test/test_eventctors.html
@@ -0,0 +1,953 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=675884
+-->
+<head>
+ <title>Test for Bug 675884</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=675884">Mozilla Bug 675884</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 675884 **/
+
+var receivedEvent;
+document.addEventListener("hello", function(e) { receivedEvent = e; }, true);
+
+function isMethodResultInitializer(aPropName)
+{
+ return aPropName.startsWith("modifier");
+}
+
+function getPropValue(aEvent, aPropName)
+{
+ if (aPropName.startsWith("modifier")) {
+ return aEvent.getModifierState(aPropName.substr("modifier".length));
+ }
+ return aEvent[aPropName];
+}
+
+// Event
+var e;
+var ex = false;
+try {
+ e = new Event();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+try {
+ e = new Event("foo", 123);
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "2nd parameter should be an object!");
+ex = false;
+
+try {
+ e = new Event("foo", "asdf");
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "2nd parameter should be an object!");
+ex = false;
+
+
+try {
+ e = new Event("foo", false);
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "2nd parameter should be an object!");
+ex = false;
+
+
+e = new Event("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+e.isTrusted = true;
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+
+try {
+ e.__defineGetter__("isTrusted", function() { return true });
+} catch (exp) {
+ ex = true;
+}
+ok(ex, "Shouldn't be able to re-define the getter for isTrusted.");
+ex = false;
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+
+ok(!("isTrusted" in Object.getPrototypeOf(e)))
+
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+document.dispatchEvent(e);
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+is(receivedEvent, e, "Wrong event!");
+
+e = new Event("hello", null);
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+document.dispatchEvent(e);
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+is(receivedEvent, e, "Wrong event!");
+
+e = new Event("hello", undefined);
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+document.dispatchEvent(e);
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+is(receivedEvent, e, "Wrong event!");
+
+e = new Event("hello", {});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+document.dispatchEvent(e);
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+is(receivedEvent, e, "Wrong event!");
+
+e = new Event("hello", { bubbles: true, cancelable: true });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// CustomEvent
+
+try {
+ e = new CustomEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new CustomEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new CustomEvent("hello", { bubbles: true, cancelable: true, detail: window });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.detail, window , "Wrong event.detail!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new CustomEvent("hello", { cancelable: true, detail: window });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.detail, window , "Wrong event.detail!");
+
+e = new CustomEvent("hello", { detail: 123 });
+is(e.detail, 123, "Wrong event.detail!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+
+var dict = { get detail() { return document.body } };
+e = new CustomEvent("hello", dict);
+is(e.detail, dict.detail, "Wrong event.detail!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+
+var dict = { get detail() { throw "foo"; } };
+
+try {
+ e = new CustomEvent("hello", dict);
+} catch (exp) {
+ ex = true;
+}
+ok(ex, "Should have thrown an exception!");
+ex = false;
+
+// BlobEvent
+
+try {
+ e = new BlobEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new BlobEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+try {
+ e.__defineGetter__("isTrusted", function() { return true });
+} catch (exp) {
+ ex = true;
+}
+ok(ex, "Shouldn't be able to re-define the getter for isTrusted.");
+ex = false;
+ok(!e.isTrusted, "BlobEvent shouldn't be trusted!");
+
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+var blob = new Blob();
+e = new BlobEvent("hello", { bubbles: true, cancelable: true, data: blob });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.data, blob , "Wrong event.data!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+
+e = new BlobEvent("hello", {data: blob});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event should be cancelable1!");
+is(e.data, blob , "Wrong event.data!");
+
+e = new BlobEvent("hello", { data: null });
+is(e.data, null, "Wrong event.data!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+blob = null;
+// CloseEvent
+
+try {
+ e = new CloseEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new CloseEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.wasClean, false, "wasClean should be false!");
+is(e.code, 0, "code should be 0!");
+is(e.reason, "", "reason should be ''!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new CloseEvent("hello",
+ { bubbles: true, cancelable: true, wasClean: true, code: 1, reason: "foo" });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.wasClean, true, "wasClean should be true!");
+is(e.code, 1, "code should be 1!");
+is(e.reason, "foo", "reason should be 'foo'!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new CloseEvent("hello",
+ { bubbles: true, cancelable: true, wasClean: true, code: 1 });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.wasClean, true, "wasClean should be true!");
+is(e.code, 1, "code should be 1!");
+is(e.reason, "", "reason should be ''!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+
+// HashChangeEvent
+
+try {
+ e = new HashChangeEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new HashChangeEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.oldURL, "", "oldURL should be ''");
+is(e.newURL, "", "newURL should be ''");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new HashChangeEvent("hello",
+ { bubbles: true, cancelable: true, oldURL: "old", newURL: "new" });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.oldURL, "old", "oldURL should be 'old'");
+is(e.newURL, "new", "newURL should be 'new'");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new HashChangeEvent("hello",
+ { bubbles: true, cancelable: true, newURL: "new" });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.oldURL, "", "oldURL should be ''");
+is(e.newURL, "new", "newURL should be 'new'");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// InputEvent
+
+e = new InputEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.detail, 0, "detail should be 0");
+ok(!e.isComposing, "isComposing should be false");
+
+e = new InputEvent("hi!", { bubbles: true, detail: 5, isComposing: false });
+is(e.type, "hi!", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.detail, 5, "detail should be 5");
+ok(!e.isComposing, "isComposing should be false");
+
+e = new InputEvent("hi!", { cancelable: true, detail: 0, isComposing: true });
+is(e.type, "hi!", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.detail, 0, "detail should be 0");
+ok(e.isComposing, "isComposing should be true");
+
+// KeyboardEvent
+
+try {
+ e = new KeyboardEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "KeyboardEvent: First parameter is required!");
+ex = false;
+
+e = new KeyboardEvent("hello");
+ok(e.type, "hello", "KeyboardEvent: Wrong event type!");
+ok(!e.isTrusted, "KeyboardEvent: Event shouldn't be trusted!");
+ok(!e.bubbles, "KeyboardEvent: Event shouldn't bubble!");
+ok(!e.cancelable, "KeyboardEvent: Event shouldn't be cancelable!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "KeyboardEvent: Wrong event!");
+
+var keyboardEventProps =
+[
+ { bubbles: false },
+ { cancelable: false },
+ { view: null },
+ { detail: 0 },
+ { key: "" },
+ { code: "" },
+ { location: 0 },
+ { ctrlKey: false },
+ { shiftKey: false },
+ { altKey: false },
+ { metaKey: false },
+ { modifierAltGraph: false },
+ { modifierCapsLock: false },
+ { modifierFn: false },
+ { modifierFnLock: false },
+ { modifierNumLock: false },
+ { modifierOS: false },
+ { modifierScrollLock: false },
+ { modifierSymbol: false },
+ { modifierSymbolLock: false },
+ { repeat: false },
+ { isComposing: false },
+ { charCode: 0 },
+ { keyCode: 0 },
+ { which: 0 },
+];
+
+var testKeyboardProps =
+[
+ { bubbles: true },
+ { cancelable: true },
+ { view: window },
+ { detail: 1 },
+ { key: "CustomKey" },
+ { code: "CustomCode" },
+ { location: 1 },
+ { ctrlKey: true },
+ { shiftKey: true },
+ { altKey: true },
+ { metaKey: true },
+ { modifierAltGraph: true },
+ { modifierCapsLock: true },
+ { modifierFn: true },
+ { modifierFnLock: true },
+ { modifierNumLock: true },
+ { modifierOS: true },
+ { modifierScrollLock: true },
+ { modifierSymbol: true },
+ { modifierSymbolLock: true },
+ { repeat: true },
+ { isComposing: true },
+ { charCode: 2 },
+ { keyCode: 3 },
+ { which: 4 },
+ { charCode: 5, which: 6 },
+ { keyCode: 7, which: 8 },
+ { keyCode: 9, charCode: 10 },
+ { keyCode: 11, charCode: 12, which: 13 },
+];
+
+var codeEnabled = SpecialPowers.getBoolPref("dom.keyboardevent.code.enabled");
+var defaultKeyboardEventValues = {};
+for (var i = 0; i < keyboardEventProps.length; ++i) {
+ for (prop in keyboardEventProps[i]) {
+ if (!codeEnabled && prop == "code") {
+ continue;
+ }
+ if (!isMethodResultInitializer(prop)) {
+ ok(prop in e, "keyboardEvent: KeyboardEvent doesn't have property " + prop + "!");
+ }
+ defaultKeyboardEventValues[prop] = keyboardEventProps[i][prop];
+ }
+}
+
+while (testKeyboardProps.length) {
+ var p = testKeyboardProps.shift();
+ e = new KeyboardEvent("foo", p);
+ for (var def in defaultKeyboardEventValues) {
+ if (!codeEnabled && def == "code") {
+ continue;
+ }
+ if (!(def in p)) {
+ is(getPropValue(e, def), defaultKeyboardEventValues[def],
+ "KeyboardEvent: Wrong default value for " + def + "!");
+ } else {
+ is(getPropValue(e, def), p[def],
+ "KeyboardEvent: Wrong event init value for " + def + "!");
+ }
+ }
+}
+
+// PageTransitionEvent
+
+try {
+ e = new PageTransitionEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new PageTransitionEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.persisted, false, "persisted should be false");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new PageTransitionEvent("hello",
+ { bubbles: true, cancelable: true, persisted: true});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.persisted, true, "persisted should be true");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new PageTransitionEvent("hello", { persisted: true});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.persisted, true, "persisted should be true");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// PopStateEvent
+
+try {
+ e = new PopStateEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new PopStateEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.state, null, "persisted should be null");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new PopStateEvent("hello",
+ { bubbles: true, cancelable: true, state: window});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.state, window, "persisted should be window");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+
+e = new PopStateEvent("hello", { state: window});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.state, window, "persisted should be window");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// UIEvent
+
+try {
+ e = new UIEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+try {
+ e = new UIEvent("foo", { view: {} });
+ e.view.onunload;
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "{} isn't a valid value.");
+ex = false;
+
+try {
+ e = new UIEvent("foo", { view: null });
+} catch(exp) {
+ ex = true;
+}
+ok(!ex, "null is a valid value.");
+is(e.view, null);
+ex = false;
+
+e = new UIEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.detail, 0, "detail should be 0");
+is(e.view, null, "view should be null");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new UIEvent("hello",
+ { bubbles: true, cancelable: true, view: window, detail: 1});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.detail, 1, "detail should be 1");
+is(e.view, window, "view should be window");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// StorageEvent
+
+e = document.createEvent("StorageEvent");
+ok(e, "Should have created an event!");
+
+try {
+ e = new StorageEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "First parameter is required!");
+ex = false;
+
+e = new StorageEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(!e.bubbles, "Event shouldn't bubble!");
+ok(!e.cancelable, "Event shouldn't be cancelable!");
+is(e.key, null, "key should be null");
+is(e.oldValue, null, "oldValue should be null");
+is(e.newValue, null, "newValue should be null");
+is(e.url, "", "url should be ''");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+e = new StorageEvent("hello",
+ { bubbles: true, cancelable: true, key: "key",
+ oldValue: "oldValue", newValue: "newValue", url: "url",
+ storageArea: localStorage });
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event shouldn't be trusted!");
+ok(e.bubbles, "Event should bubble!");
+ok(e.cancelable, "Event should be cancelable!");
+is(e.key, "key", "Wrong value");
+is(e.oldValue, "oldValue", "Wrong value");
+is(e.newValue, "newValue", "Wrong value");
+is(e.url, "url", "Wrong value");
+is(e.storageArea, localStorage, "Wrong value");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// DeviceProximityEvent
+e = new DeviceProximityEvent("hello", {min: 0, value: 1, max: 2});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.value, 1, "value should be 1");
+is(e.min, 0, "min should be 0");
+is(e.max, 2, "max should be 2");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+e = new DeviceProximityEvent("hello");
+is(e.value, Infinity, "Uninitialized value should be infinity");
+is(e.min, -Infinity, "Uninitialized min should be -infinity");
+is(e.max, Infinity, "Uninitialized max should be infinity");
+
+// UserProximityEvent
+e = new UserProximityEvent("hello", {near: true});
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.near, true, "near should be true");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// DeviceLightEvent
+e = new DeviceLightEvent("hello", {value: 1} );
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.value, 1, "value should be 1");
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+e = new DeviceLightEvent("hello", {value: Infinity} );
+is(e.value, Infinity, "value should be positive infinity");
+e = new DeviceLightEvent("hello", {value: -Infinity} );
+is(e.value, -Infinity, "value should be negative infinity");
+e = new DeviceLightEvent("hello");
+is(e.value, Infinity, "Uninitialized value should be positive infinity");
+
+// DeviceOrientationEvent
+e = new DeviceOrientationEvent("hello");
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.alpha, null);
+is(e.beta, null);
+is(e.gamma, null);
+is(e.absolute, false);
+
+e = new DeviceOrientationEvent("hello", { alpha: 1, beta: 2, gamma: 3, absolute: true } );
+is(e.type, "hello", "Wrong event type!");
+ok(!e.isTrusted, "Event should not be trusted");
+is(e.alpha, 1);
+is(e.beta, 2);
+is(e.gamma, 3);
+is(e.absolute, true);
+document.dispatchEvent(e);
+is(receivedEvent, e, "Wrong event!");
+
+// MouseEvent
+
+try {
+ e = new MouseEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "MouseEvent: First parameter is required!");
+ex = false;
+
+e = new MouseEvent("hello", { buttons: 1, movementX: 2, movementY: 3});
+is(e.type, "hello", "MouseEvent: Wrong event type!");
+ok(!e.isTrusted, "MouseEvent: Event shouldn't be trusted!");
+ok(!e.bubbles, "MouseEvent: Event shouldn't bubble!");
+ok(!e.cancelable, "MouseEvent: Event shouldn't be cancelable!");
+is(e.buttons, 1);
+is(e.movementX, 2);
+is(e.movementY, 3);
+document.dispatchEvent(e);
+is(receivedEvent, e, "MouseEvent: Wrong event!");
+
+var mouseEventProps =
+[ { screenX: 0 },
+ { screenY: 0 },
+ { clientX: 0 },
+ { clientY: 0 },
+ { ctrlKey: false },
+ { shiftKey: false },
+ { altKey: false },
+ { metaKey: false },
+ { modifierAltGraph: false },
+ { modifierCapsLock: false },
+ { modifierFn: false },
+ { modifierFnLock: false },
+ { modifierNumLock: false },
+ { modifierOS: false },
+ { modifierScrollLock: false },
+ { modifierSymbol: false },
+ { modifierSymbolLock: false },
+ { button: 0 },
+ { buttons: 0 },
+ { relatedTarget: null },
+];
+
+var testProps =
+[
+ { screenX: 1 },
+ { screenY: 2 },
+ { clientX: 3 },
+ { clientY: 4 },
+ { ctrlKey: true },
+ { shiftKey: true },
+ { altKey: true },
+ { metaKey: true },
+ { modifierAltGraph: true },
+ { modifierCapsLock: true },
+ { modifierFn: true },
+ { modifierFnLock: true },
+ { modifierNumLock: true },
+ { modifierOS: true },
+ { modifierScrollLock: true },
+ { modifierSymbol: true },
+ { modifierSymbolLock: true },
+ { button: 5 },
+ { buttons: 6 },
+ { relatedTarget: window }
+];
+
+var defaultMouseEventValues = {};
+for (var i = 0; i < mouseEventProps.length; ++i) {
+ for (prop in mouseEventProps[i]) {
+ if (!isMethodResultInitializer(prop)) {
+ ok(prop in e, "MouseEvent: MouseEvent doesn't have property " + prop + "!");
+ }
+ defaultMouseEventValues[prop] = mouseEventProps[i][prop];
+ }
+}
+
+while (testProps.length) {
+ var p = testProps.shift();
+ e = new MouseEvent("foo", p);
+ for (var def in defaultMouseEventValues) {
+ if (!(def in p)) {
+ is(getPropValue(e, def), defaultMouseEventValues[def],
+ "MouseEvent: Wrong default value for " + def + "!");
+ } else {
+ is(getPropValue(e, def), p[def], "MouseEvent: Wrong event init value for " + def + "!");
+ }
+ }
+}
+
+// PopupBlockedEvent
+
+try {
+ e = new PopupBlockedEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "PopupBlockedEvent: First parameter is required!");
+ex = false;
+
+e = new PopupBlockedEvent("hello");
+is(e.type, "hello", "PopupBlockedEvent: Wrong event type!");
+ok(!e.isTrusted, "PopupBlockedEvent: Event shouldn't be trusted!");
+ok(!e.bubbles, "PopupBlockedEvent: Event shouldn't bubble!");
+ok(!e.cancelable, "PopupBlockedEvent: Event shouldn't be cancelable!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "PopupBlockedEvent: Wrong event!");
+
+e = new PopupBlockedEvent("hello",
+ { requestingWindow: window,
+ popupWindowFeatures: "features",
+ popupWindowName: "name"
+ });
+is(e.requestingWindow, window);
+is(e.popupWindowFeatures, "features");
+is(e.popupWindowName, "name");
+
+// WheelEvent
+
+try {
+ e = new WheelEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "WheelEvent: First parameter is required!");
+ex = false;
+
+e = new WheelEvent("hello", { buttons: 1, movementX: 2, movementY: 3});
+is(e.type, "hello", "WheelEvent: Wrong event type!");
+is(e.buttons, 1);
+is(e.movementX, 2);
+is(e.movementY, 3);
+ok(!e.isTrusted, "WheelEvent: Event shouldn't be trusted!");
+ok(!e.bubbles, "WheelEvent: Event shouldn't bubble!");
+ok(!e.cancelable, "WheelEvent: Event shouldn't be cancelable!");
+document.dispatchEvent(e);
+is(receivedEvent, e, "WheelEvent: Wrong event!");
+
+var wheelEventProps =
+[ { screenX: 0 },
+ { screenY: 0 },
+ { clientX: 0 },
+ { clientY: 0 },
+ { ctrlKey: false },
+ { shiftKey: false },
+ { altKey: false },
+ { metaKey: false },
+ { modifierAltGraph: false },
+ { modifierCapsLock: false },
+ { modifierFn: false },
+ { modifierFnLock: false },
+ { modifierNumLock: false },
+ { modifierOS: false },
+ { modifierScrollLock: false },
+ { modifierSymbol: false },
+ { modifierSymbolLock: false },
+ { button: 0 },
+ { buttons: 0 },
+ { relatedTarget: null },
+ { deltaX: 0.0 },
+ { deltaY: 0.0 },
+ { deltaZ: 0.0 },
+ { deltaMode: 0 }
+];
+
+var testWheelProps =
+[
+ { screenX: 1 },
+ { screenY: 2 },
+ { clientX: 3 },
+ { clientY: 4 },
+ { ctrlKey: true },
+ { shiftKey: true },
+ { altKey: true },
+ { metaKey: true },
+ { modifierAltGraph: true },
+ { modifierCapsLock: true },
+ { modifierFn: true },
+ { modifierFnLock: true },
+ { modifierNumLock: true },
+ { modifierOS: true },
+ { modifierScrollLock: true },
+ { modifierSymbol: true },
+ { modifierSymbolLock: true },
+ { button: 5 },
+ { buttons: 6 },
+ { relatedTarget: window },
+ { deltaX: 7.8 },
+ { deltaY: 9.1 },
+ { deltaZ: 2.3 },
+ { deltaMode: 4 }
+];
+
+var defaultWheelEventValues = {};
+for (var i = 0; i < wheelEventProps.length; ++i) {
+ for (prop in wheelEventProps[i]) {
+ if (!isMethodResultInitializer(prop)) {
+ ok(prop in e, "WheelEvent: WheelEvent doesn't have property " + prop + "!");
+ }
+ defaultWheelEventValues[prop] = wheelEventProps[i][prop];
+ }
+}
+
+while (testWheelProps.length) {
+ var p = testWheelProps.shift();
+ e = new WheelEvent("foo", p);
+ for (var def in defaultWheelEventValues) {
+ if (!(def in p)) {
+ is(getPropValue(e, def), defaultWheelEventValues[def],
+ "WheelEvent: Wrong default value for " + def + "!");
+ } else {
+ is(getPropValue(e, def), p[def], "WheelEvent: Wrong event init value for " + def + "!");
+ }
+ }
+}
+
+// DragEvent
+
+try {
+ e = new DragEvent();
+} catch(exp) {
+ ex = true;
+}
+ok(ex, "DragEvent: First parameter is required!");
+ex = false;
+
+e = new DragEvent("hello", { buttons: 1, movementX: 2, movementY: 3});
+is(e.type, "hello", "DragEvent: Wrong event type!");
+is(e.buttons, 1);
+is(e.movementX, 2);
+is(e.movementY, 3);
+document.dispatchEvent(e);
+is(receivedEvent, e, "DragEvent: Wrong event!");
+
+// TransitionEvent
+e = new TransitionEvent("hello", { propertyName: "color", elapsedTime: 3.5, pseudoElement: "", foobar: "baz" })
+is("propertyName" in e, true, "Transition events have propertyName property");
+is("foobar" in e, false, "Transition events do not copy random properties from event init");
+is(e.propertyName, "color", "Transition event copies propertyName from TransitionEventInit");
+is(e.elapsedTime, 3.5, "Transition event copies elapsedTime from TransitionEventInit");
+is(e.pseudoElement, "", "Transition event copies pseudoElement from TransitionEventInit");
+is(e.bubbles, false, "Lack of bubbles property in TransitionEventInit");
+is(e.cancelable, false, "Lack of cancelable property in TransitionEventInit");
+is(e.type, "hello", "Wrong event type!");
+is(e.isTrusted, false, "Event shouldn't be trusted!");
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+
+// AnimationEvent
+e = new AnimationEvent("hello", { animationName: "bounce3", elapsedTime: 3.5, pseudoElement: "", foobar: "baz" })
+is("animationName" in e, true, "Animation events have animationName property");
+is("foobar" in e, false, "Animation events do not copy random properties from event init");
+is(e.animationName, "bounce3", "Animation event copies animationName from AnimationEventInit");
+is(e.elapsedTime, 3.5, "Animation event copies elapsedTime from AnimationEventInit");
+is(e.pseudoElement, "", "Animation event copies pseudoElement from AnimationEventInit");
+is(e.bubbles, false, "Lack of bubbles property in AnimationEventInit");
+is(e.cancelable, false, "Lack of cancelable property in AnimationEventInit");
+is(e.type, "hello", "Wrong event type!");
+is(e.isTrusted, false, "Event shouldn't be trusted!");
+is(e.eventPhase, Event.NONE, "Wrong event phase");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_eventctors.xul b/dom/events/test/test_eventctors.xul
new file mode 100644
index 000000000..ba3c81c8a
--- /dev/null
+++ b/dom/events/test/test_eventctors.xul
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=675884
+-->
+<window title="Mozilla Bug 675884"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=675884"
+ target="_blank">Mozilla Bug 675884</a>
+ </body>
+
+ <!-- test code goes here -->
+ <script type="application/javascript">
+ <![CDATA[
+ /** Test for Bug 675884 **/
+
+ // Most of the tests are in .html file, but test here that
+ // isTrusted is handled correctly in chrome.
+
+ var receivedEvent;
+ document.addEventListener("hello", function(e) { receivedEvent = e; }, true);
+
+ // Event
+ var e;
+ var ex = false;
+ try {
+ e = new Event();
+ } catch(exp) {
+ ex = true;
+ }
+ ok(ex, "First parameter is required!");
+ ex = false;
+
+ e = new Event("hello");
+ ok(e.type, "hello", "Wrong event type!");
+ ok(e.isTrusted, "Event should be trusted!");
+ ok(!e.bubbles, "Event shouldn't bubble!");
+ ok(!e.cancelable, "Event shouldn't be cancelable!");
+ document.dispatchEvent(e);
+ is(receivedEvent, e, "Wrong event!");
+
+ ]]>
+ </script>
+</window>
diff --git a/dom/events/test/test_eventhandler_scoping.html b/dom/events/test/test_eventhandler_scoping.html
new file mode 100644
index 000000000..f15238a0c
--- /dev/null
+++ b/dom/events/test/test_eventhandler_scoping.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for event handler scoping</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var queryResult;
+test(function() {
+ var d = document.createElement("div");
+ d.setAttribute("onclick", "queryResult = querySelector('span')");
+ var s = document.createElement("span");
+ d.appendChild(s);
+ d.dispatchEvent(new Event("click"));
+ assert_equals(queryResult, s, "Should have gotten the right object");
+}, "Test for bareword calls in an event handler using the element as 'this'");
+</script>
diff --git a/dom/events/test/test_focus_disabled.html b/dom/events/test/test_focus_disabled.html
new file mode 100644
index 000000000..52748226a
--- /dev/null
+++ b/dom/events/test/test_focus_disabled.html
@@ -0,0 +1,125 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=375008
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 375008</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=375008">Mozilla Bug 375008</a>
+<p id="display"></p>
+<div id="content">
+ <div id='not-focusable'>
+ <!-- Disabled elements -->
+ <button hidden disabled>foo</button>
+ <input hidden disabled>
+ <fieldset hidden disabled>foo</fieldset>
+ <select hidden disabled><option>foo</option></select>
+ <textarea hidden disabled></textarea>
+ <optgroup hidden disabled><option>foo</option></optgroup>
+ <option hidden disabled>foo</option>
+ </div>
+
+ <div id='focusable'>
+ <button hidden>foo</button>
+ <input hidden>
+ <select hidden><option>foo</option></select>
+ <textarea hidden></textarea>
+
+ <!-- Those elements are not focusable by default. -->
+ <fieldset tabindex=1 hidden>foo</fieldset>
+ <optgroup tabindex=1 hidden><option>foo</option></optgroup>
+ <option tabindex=1 hidden>foo</option>
+ </div>
+
+ <!-- Hidden elements, they have a frame but focus will go through them. -->
+ <div id='hidden' style='visibility: hidden;'>
+ <button hidden>foo</button>
+ <input hidden>
+ <fieldset hidden>foo</fieldset>
+ <select hidden><option>foo</option></select>
+ <textarea hidden></textarea>
+ <optgroup hidden><option>foo</option></optgroup>
+ <option hidden>foo</option>
+ </div>
+
+ <div>
+ <input id='witness'>
+ </div>
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 375008 **/
+
+/*
+ * This test is divided in three parts:
+ * - cases where focus isn't doable but blur should not happen;
+ * - cases where focus is doable;
+ * - cases where focus isn't doable but blur should still happen.
+ */
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ // On Mac, this preference needs to be turned on to be able to focus all the
+ // form controls we want to focus.
+ SpecialPowers.pushPrefEnv({"set": [[ "accessibility.mouse_focuses_formcontrol", true ]]},
+ runTest);
+});
+
+function runTest()
+{
+ var witness = document.getElementById('witness');
+ witness.focus();
+
+ var notFocusableElements = document.getElementById('not-focusable').children;
+ for (var i=0; i<notFocusableElements.length; ++i) {
+ var element = notFocusableElements[i];
+ element.hidden = false;
+ synthesizeMouseAtCenter(element, {});
+ is(document.activeElement, witness,
+ "[" + element.tagName + "] witness should still be focused");
+
+ // Cleanup.
+ element.hidden = true;
+ witness.focus();
+ }
+
+ var focusableElements = document.getElementById('focusable').children;
+ for (var i=0; i<focusableElements.length; ++i) {
+ var element = focusableElements[i];
+ element.hidden = false;
+ synthesizeMouseAtCenter(element, {});
+ is(document.activeElement, element, "focus should have moved to " + element);
+
+ // Cleanup.
+ element.hidden = true;
+ witness.focus();
+ }
+
+ var hiddenElements = document.getElementById('hidden').children;
+ for (var i=0; i<hiddenElements.length; ++i) {
+ var element = hiddenElements[i];
+ element.hidden = false;
+ synthesizeMouseAtCenter(element, {});
+ is(document.activeElement, document.body,
+ "focus should have moved to the body");
+
+ // Cleanup.
+ element.hidden = true;
+ witness.focus();
+ }
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_legacy_event.html b/dom/events/test/test_legacy_event.html
new file mode 100644
index 000000000..d772be106
--- /dev/null
+++ b/dom/events/test/test_legacy_event.html
@@ -0,0 +1,304 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1236979
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1236979 (events that have legacy alternative versions)</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ @keyframes anim1 {
+ 0% { margin-left: 0px }
+ 100% { margin-left: 100px }
+ }
+ </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1236979">Mozilla Bug 1236979</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1236979 **/
+
+'use strict';
+SimpleTest.waitForExplicitFinish();
+
+// Array of info-bundles about each legacy event to be tested:
+var gLegacyEventInfo = [
+ {
+ legacy_name: "webkitTransitionEnd",
+ modern_name: "transitionend",
+ trigger_event: triggerShortTransition,
+ },
+ {
+ legacy_name: "webkitAnimationStart",
+ modern_name: "animationstart",
+ trigger_event: triggerShortAnimation,
+ },
+ {
+ legacy_name: "webkitAnimationEnd",
+ modern_name: "animationend",
+ trigger_event: triggerShortAnimation,
+ },
+ {
+ legacy_name: "webkitAnimationIteration",
+ modern_name: "animationiteration",
+ trigger_event: triggerAnimationIteration,
+ }
+];
+
+// EVENT-TRIGGERING FUNCTIONS
+// --------------------------
+// This function triggers a very short (1ms long) transition, which will cause
+// events to fire for the transition ending.
+function triggerShortTransition(node) {
+ node.style.transition = "1ms color linear" ;
+ node.style.color = "purple";
+ // Flush style, so that the above assignment value actually takes effect
+ // in the computed style, so that a transition will get triggered when it
+ // changes.
+ window.getComputedStyle(node, "").color;
+ node.style.color = "teal";
+}
+
+// This function triggers a very short (1ms long) animation, which will cause
+// events to fire for the animation beginning & ending.
+function triggerShortAnimation(node) {
+ node.style.animation = "anim1 1ms linear";
+}
+
+// This function triggers a long animation with two iterations, which is
+// *nearly* at the end of its first iteration. It will hit the end of that
+// iteration (firing an event) almost immediately, 1ms in the future.
+//
+// NOTE: It's important that this animation have a *long* duration. If it were
+// short (e.g. 1ms duration), then we might jump past all its iterations in
+// a single refresh-driver tick. And if that were to happens, we'd *never* fire
+// any animationiteration events -- the CSS Animations spec says this event
+// must not be fired "...when an animationend event would fire at the same time"
+// (which would be the case in this example with a 1ms duration). So, to make
+// sure our event does fire, we use a long duration and a nearly-as-long
+// negative delay. This ensures we hit the end of the first iteration right
+// away, and that we don't risk hitting the end of the second iteration at the
+// same time.
+function triggerAnimationIteration(node) {
+ node.style.animation = "anim1 300s -299.999s linear 2";
+}
+
+// GENERAL UTILITY FUNCTIONS
+// -------------------------
+// Creates a new div and appends it as a child of the specified parentNode, or
+// (if no parent is specified) as a child of the element with ID 'display'.
+function createChildDiv(parentNode) {
+ if (!parentNode) {
+ parentNode = document.getElementById("display");
+ if (!parentNode) {
+ ok(false, "no 'display' element to append to");
+ }
+ }
+ var div = document.createElement("div");
+ parentNode.appendChild(div);
+ return div;
+}
+
+// Returns an event-handler function, which (when invoked) simply checks that
+// the event's type matches what's expected. If a callback is passed in, then
+// the event-handler will invoke that callback as well.
+function createHandlerWithTypeCheck(expectedEventType, extraHandlerLogic) {
+ var handler = function(e) {
+ is(e.type, expectedEventType,
+ "When an event handler for '" + expectedEventType + "' is invoked, " +
+ "the event's type field should be '" + expectedEventType + "'.");
+ if (extraHandlerLogic) {
+ extraHandlerLogic(e);
+ }
+ }
+ return handler;
+}
+
+// TEST FUNCTIONS
+// --------------
+// These functions expect to be passed an entry from gEventInfo, and they
+// return a Promise which performs the test & resolves when it's complete.
+// The function names all begin with "mp", which stands for "make promise".
+// So e.g. "mpTestLegacyEventSent" means "make a promise to test that the
+// legacy event is sent".
+
+// Tests that the legacy event type is sent, when only a legacy handler is
+// registered.
+function mpTestLegacyEventSent(eventInfo) {
+ return new Promise(
+ function(resolve, reject) {
+ // Create a node & register an event-handler for the legacy event:
+ var div = createChildDiv();
+
+ var handler = createHandlerWithTypeCheck(eventInfo.legacy_name,
+ function() {
+ // When event-handler is done, clean up & resolve:
+ div.parentNode.removeChild(div);
+ resolve();
+ });
+ div.addEventListener(eventInfo.legacy_name, handler);
+
+ // Trigger the event:
+ eventInfo.trigger_event(div);
+ }
+ );
+}
+
+// Test that the modern event type (and only the modern event type) is fired,
+// when listeners of both modern & legacy types are registered. The legacy
+// listener should not be invoked.
+function mpTestModernBeatsLegacy(eventInfo) {
+ return new Promise(
+ function(resolve, reject) {
+ var div = createChildDiv();
+
+ var legacyHandler = function(e) {
+ reject("Handler for legacy event '" + eventInfo.legacy_name +
+ "' should not be invoked when there's a handler registered " +
+ "for both modern & legacy event type on the same node");
+ };
+
+ var modernHandler = createHandlerWithTypeCheck(eventInfo.modern_name,
+ function() {
+ // Indicate that the test has passed (we invoked the modern handler):
+ ok(true, "Handler for modern event '" + eventInfo.modern_name +
+ "' should be invoked when there's a handler registered for " +
+ "both modern & legacy event type on the same node");
+ // When event-handler is done, clean up & resolve:
+ div.parentNode.removeChild(div);
+ resolve();
+ });
+
+ div.addEventListener(eventInfo.legacy_name, legacyHandler);
+ div.addEventListener(eventInfo.modern_name, modernHandler);
+ eventInfo.trigger_event(div);
+ }
+ );
+}
+
+// Test that an event which bubbles may fire listeners of different flavors
+// (modern vs. legacy) at each bubbling level, depending on what's registered
+// at that level.
+function mpTestDiffListenersEventBubbling(eventInfo) {
+ return new Promise(
+ function(resolve, reject) {
+ var grandparent = createChildDiv();
+ var parent = createChildDiv(grandparent);
+ var target = createChildDiv(parent);
+ var didEventFireOnTarget = false;
+ var didEventFireOnParent = false;
+ var eventSentToTarget;
+
+ target.addEventListener(eventInfo.modern_name,
+ createHandlerWithTypeCheck(eventInfo.modern_name, function(e) {
+ ok(e.bubbles, "Expecting event to bubble");
+ eventSentToTarget = e;
+ didEventFireOnTarget = true;
+ }));
+
+ parent.addEventListener(eventInfo.legacy_name,
+ createHandlerWithTypeCheck(eventInfo.legacy_name, function(e) {
+ is(e, eventSentToTarget,
+ "Same event object should bubble, despite difference in type");
+ didEventFireOnParent = true;
+ }));
+
+ grandparent.addEventListener(eventInfo.modern_name,
+ createHandlerWithTypeCheck(eventInfo.modern_name, function(e) {
+ ok(didEventFireOnTarget,
+ "Event should have fired on child");
+ ok(didEventFireOnParent,
+ "Event should have fired on parent");
+ is(e, eventSentToTarget,
+ "Same event object should bubble, despite difference in type");
+ // Clean up.
+ grandparent.parentNode.removeChild(grandparent);
+ resolve();
+ }));
+
+ eventInfo.trigger_event(target);
+ }
+ );
+}
+
+// Test that an event in the capture phase may fire listeners of different
+// flavors (modern vs. legacy) at each level, depending on what's registered
+// at that level.
+function mpTestDiffListenersEventCapturing(eventInfo) {
+ return new Promise(
+ function(resolve, reject) {
+ var grandparent = createChildDiv();
+ var parent = createChildDiv(grandparent);
+ var target = createChildDiv(parent);
+ var didEventFireOnTarget = false;
+ var didEventFireOnParent = false;
+ var didEventFireOnGrandparent = false;
+ var eventSentToGrandparent;
+
+ grandparent.addEventListener(eventInfo.modern_name,
+ createHandlerWithTypeCheck(eventInfo.modern_name, function(e) {
+ eventSentToGrandparent = e;
+ didEventFireOnGrandparent = true;
+ }), true);
+
+ parent.addEventListener(eventInfo.legacy_name,
+ createHandlerWithTypeCheck(eventInfo.legacy_name, function(e) {
+ is(e.eventPhase, Event.CAPTURING_PHASE,
+ "event should be in capturing phase");
+ is(e, eventSentToGrandparent,
+ "Same event object should capture, despite difference in type");
+ ok(didEventFireOnGrandparent,
+ "Event should have fired on grandparent");
+ didEventFireOnParent = true;
+ }), true);
+
+ target.addEventListener(eventInfo.modern_name,
+ createHandlerWithTypeCheck(eventInfo.modern_name, function(e) {
+ is(e.eventPhase, Event.AT_TARGET,
+ "event should be at target phase");
+ is(e, eventSentToGrandparent,
+ "Same event object should capture, despite difference in type");
+ ok(didEventFireOnParent,
+ "Event should have fired on parent");
+ // Clean up.
+ grandparent.parentNode.removeChild(grandparent);
+ resolve();
+ }), true);
+
+ eventInfo.trigger_event(target);
+ }
+ );
+}
+
+// MAIN FUNCTION: Kick off the tests.
+function main() {
+ Promise.resolve().then(function() {
+ return Promise.all(gLegacyEventInfo.map(mpTestLegacyEventSent))
+ }).then(function() {
+ return Promise.all(gLegacyEventInfo.map(mpTestModernBeatsLegacy));
+ }).then(function() {
+ return Promise.all(gLegacyEventInfo.map(mpTestDiffListenersEventCapturing));
+ }).then(function() {
+ return Promise.all(gLegacyEventInfo.map(mpTestDiffListenersEventBubbling));
+ }).then(function() {
+ SimpleTest.finish();
+ }).catch(function(reason) {
+ ok(false, "Test failed: " + reason);
+ SimpleTest.finish();
+ });
+}
+
+main();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_messageEvent.html b/dom/events/test/test_messageEvent.html
new file mode 100644
index 000000000..0402649af
--- /dev/null
+++ b/dom/events/test/test_messageEvent.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=848294
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 848294</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+ <script type="application/javascript">
+ function testMessageEvent(e, test) {
+ ok(e, "MessageEvent created");
+ is(e.type, 'message', 'MessageEvent.type is right');
+
+ is(e.data, 'data' in test ? test.data : null, 'MessageEvent.data is ok');
+ is(e.origin, 'origin' in test ? test.origin : '', 'MessageEvent.origin is ok');
+ is(e.lastEventId, 'lastEventId' in test ? test.lastEventId : '', 'MessageEvent.lastEventId is ok');
+ is(e.source, 'source' in test ? test.source : null, 'MessageEvent.source is ok');
+
+ if (test.ports != undefined) {
+ is(e.ports.length, test.ports.length, 'MessageEvent.ports is ok');
+ is(e.ports, e.ports, 'MessageEvent.ports is ok');
+ } else {
+ ok(!('ports' in test) || test.ports == null, 'MessageEvent.ports is ok');
+ }
+ }
+
+ function runTest() {
+ var channel = new MessageChannel();
+
+ var tests = [
+ {},
+ { data: 42 },
+ { data: {} },
+ { data: true, origin: 'wow' },
+ { data: [], lastEventId: 'wow2' },
+ { data: null, source: null },
+ { data: window, source: window },
+ { data: window, source: channel.port1 },
+ { data: window, source: channel.port1, ports: [ channel.port1, channel.port2 ] },
+ { data: null, ports: [] },
+ ];
+
+ while (tests.length) {
+ var test = tests.shift();
+
+ var e = new MessageEvent('message', test);
+ testMessageEvent(e, test);
+
+ e = new MessageEvent('message');
+ e.initMessageEvent('message', true, true,
+ 'data' in test ? test.data : null,
+ 'origin' in test ? test.origin : '',
+ 'lastEventId' in test ? test.lastEventId : '',
+ 'source' in test ? test.source : null,
+ 'ports' in test ? test.ports : []);
+ testMessageEvent(e, test);
+ }
+
+ try {
+ var e = new MessageEvent('foobar', { source: 42 });
+ ok(false, "Source has to be a window or a port");
+ } catch(e) {
+ ok(true, "Source has to be a window or a port");
+ }
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ runTest();
+ </script>
+</body>
+</html>
diff --git a/dom/events/test/test_messageEvent_init.html b/dom/events/test/test_messageEvent_init.html
new file mode 100644
index 000000000..0e015b3be
--- /dev/null
+++ b/dom/events/test/test_messageEvent_init.html
@@ -0,0 +1,25 @@
+<html><head>
+<title>Test for bug 1308956</title>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<body>
+ <script>
+
+var a = new MessageEvent("message")
+ok(!!a, "We have a MessageEvent");
+is(a.ports.length, 0, "By default MessageEvent.ports is an empty array");
+
+a.initMessageEvent("message", true, false, {}, window.location.href, "", null, []);
+ok(Array.isArray(a.ports), "After InitMessageEvent() we have an array");
+is(a.ports.length, 0, "Length is 0");
+
+var mc = new MessageChannel();
+a.initMessageEvent("message", true, false, {}, window.location.href, "", null, [mc.port1]);
+ok(Array.isArray(a.ports), "After InitMessageEvent() we have an array");
+is(a.ports.length, 1, "Length is 1");
+
+ </script>
+</body>
+</html>
diff --git a/dom/events/test/test_moz_mouse_pixel_scroll_event.html b/dom/events/test/test_moz_mouse_pixel_scroll_event.html
new file mode 100644
index 000000000..c2919ce44
--- /dev/null
+++ b/dom/events/test/test_moz_mouse_pixel_scroll_event.html
@@ -0,0 +1,1363 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for MozMousePixelScroll events</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <style>
+ .scrollable {
+ overflow: auto;
+ line-height: 1;
+ margin: 15px;
+ }
+ .scrollable > div {
+ width: 1000px;
+ height: 1000px;
+ font-size: 1000px;
+ line-height: 1;
+ }
+ </style>
+</head>
+<body>
+<p id="display"></p>
+<div id="Scrollable128" class="scrollable" style="font-size: 128px; width: 100px; height: 100px;">
+ <div>
+ <div id="Scrollable96" class="scrollable" style="font-size: 96px; width: 150px; height: 150px;">
+ <div>
+ <div id="Scrollable64" class="scrollable" style="font-size: 64px; width: 200px; height: 200px;">
+ <div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+<div id="Scrollable32" class="scrollable" style="font-size: 32px; width: 50px; height: 50px;">
+ <div>
+ </div>
+</div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(startTest, window);
+
+var gScrollable128 = document.getElementById("Scrollable128");
+var gScrollable96 = document.getElementById("Scrollable96");
+var gScrollable64 = document.getElementById("Scrollable64");
+var gScrollable32 = document.getElementById("Scrollable32");
+var gRoot = document.documentElement;
+
+function* prepareScrollUnits()
+{
+ var result = -1;
+ function handler(aEvent)
+ {
+ result = aEvent.detail;
+ aEvent.preventDefault();
+ setTimeout(runTest, 0);
+ }
+ window.addEventListener("MozMousePixelScroll", handler, true);
+
+ yield waitForAllPaints(function () { setTimeout(runTest, 0); });
+
+ yield synthesizeWheel(gScrollable128, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable128.wheelLineHeight = result;
+ ok(result > 96 && result < 200, "prepareScrollUnits: gScrollable128.wheelLineHeight may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable96, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable96.wheelLineHeight = result;
+ ok(result > 64 && result < gScrollable128.wheelLineHeight, "prepareScrollUnits: gScrollable96.wheelLineHeight may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable64, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable64.wheelLineHeight = result;
+ ok(result > 32 && result < gScrollable96.wheelLineHeight, "prepareScrollUnits: gScrollable64.wheelLineHeight may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable32, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable32.wheelLineHeight = result;
+ ok(result > 16 && result < gScrollable64.wheelLineHeight, "prepareScrollUnits: gScrollable32.wheelLineHeight may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gRoot, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gRoot.wheelLineHeight = result;
+ ok(result > 10 && result < gScrollable32.wheelLineHeight, "prepareScrollUnits: gRoot.wheelLineHeight may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable128, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable128.wheelHorizontalLine = result;
+ ok(result > 50 && result < 200, "prepareScrollUnits: gScrollable128.wheelHorizontalLine may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable96, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable96.wheelHorizontalLine = result;
+ ok(result > 30 && result < gScrollable128.wheelHorizontalLine, "prepareScrollUnits: gScrollable96.wheelHorizontalLine may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable64, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable64.wheelHorizontalLine = result;
+ ok(result > 20 && result < gScrollable96.wheelHorizontalLine, "prepareScrollUnits: gScrollable64.wheelHorizontalLine may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable32, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable32.wheelHorizontalLine = result;
+ ok(result > 12 && result < gScrollable64.wheelHorizontalLine, "prepareScrollUnits: gScrollable32.wheelHorizontalLine may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gRoot, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gRoot.wheelHorizontalLine = result;
+ ok(result > 5 && result < gScrollable32.wheelHorizontalLine, "prepareScrollUnits: gRoot.wheelHorizontalLine may be illegal value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable128, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable128.wheelPageHeight = result;
+ ok(result >= (100 - gScrollable128.wheelLineHeight * 2) && result <= 100,
+ "prepareScrollUnits: gScrollable128.wheelLineHeight is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable96, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable96.wheelPageHeight = result;
+ ok(result >= (150 - gScrollable96.wheelLineHeight * 2) && result <= 150,
+ "prepareScrollUnits: gScrollable96.wheelLineHeight is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable64, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable64.wheelPageHeight = result;
+ ok(result >= (200 - gScrollable64.wheelLineHeight * 2) && result <= 200,
+ "prepareScrollUnits: gScrollable64.wheelLineHeight is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable32, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gScrollable32.wheelPageHeight = result;
+ ok(result >= (50 - gScrollable32.wheelLineHeight * 2) && result <= 50,
+ "prepareScrollUnits: gScrollable32.wheelLineHeight is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gRoot, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaY: 1.0, lineOrPageDeltaY: 1 });
+ gRoot.wheelPageHeight = result;
+ ok(window.innerHeight - result < 100 && window.innerHeight - result > 0,
+ "prepareScrollUnits: gRoot.wheelLineHeight is strange value, got " + result);
+
+
+ result = -1;
+ yield synthesizeWheel(gScrollable128, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable128.wheelPageWidth = result;
+ ok(result >= (100 - gScrollable128.wheelLineHeight * 2) && result <= 100,
+ "prepareScrollUnits: gScrollable128.wheelPageWidth is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable96, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable96.wheelPageWidth = result;
+ ok(result >= (150 - gScrollable96.wheelLineHeight * 2) && result <= 150,
+ "prepareScrollUnits: gScrollable96.wheelPageWidth is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable64, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable64.wheelPageWidth = result;
+ ok(result >= (200 - gScrollable64.wheelLineHeight * 2) && result <= 200,
+ "prepareScrollUnits: gScrollable64.wheelPageWidth is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gScrollable32, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gScrollable32.wheelPageWidth = result;
+ ok(result >= (50 - gScrollable32.wheelLineHeight * 2) && result <= 50,
+ "prepareScrollUnits: gScrollable32.wheelPageWidth is strange value, got " + result);
+
+ result = -1;
+ yield synthesizeWheel(gRoot, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, lineOrPageDeltaX: 1 });
+ gRoot.wheelPageWidth = result;
+ ok(window.innerWidth - result < 100 && window.innerWidth - result > 0,
+ "prepareScrollUnits: gRoot.wheelPageWidth is strange value, got " + result);
+
+ window.removeEventListener("MozMousePixelScroll", handler, true);
+}
+
+function* doTests()
+{
+ const kTests = [
+ // DOM_DELTA_LINE
+ { description: "Should be computed from nearest scrollable element, 128",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from root element if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: gRoot
+ }
+ },
+ { description: "Should be computed from root element, even if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: gRoot
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 128",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from root element if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gRoot
+ }
+ },
+ { description: "Should be computed from root element, even if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gRoot
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 128",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: null
+ }
+ },
+ { description: "Should be computed from root element if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: null
+ }
+ },
+ { description: "Should be computed from root element, even if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: null
+ }
+ },
+
+ // DOM_DELTA_PAGE
+ { description: "Should be computed from nearest scrollable element, 128",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from root element if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: gRoot
+ }
+ },
+ { description: "Should be computed from root element, even if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: gRoot
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 128",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable128
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable96
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gScrollable32
+ }
+ },
+ { description: "Should be computed from root element if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gRoot
+ }
+ },
+ { description: "Should be computed from root element, even if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: null, y: gRoot
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 128",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction",
+ target: gScrollable128,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable128.scrollLeft = 0;
+ gScrollable128.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable128, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 96",
+ target: gScrollable96,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable96, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable64, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element, even if not scrollable to the direction, 32",
+ target: gScrollable32,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable32.scrollLeft = 0;
+ gScrollable32.scrollTop = 0;
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gScrollable32, y: null
+ }
+ },
+ { description: "Should be computed from root element if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: null
+ }
+ },
+ { description: "Should be computed from root element, even if there is no scrollable element, root",
+ target: gRoot,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0, lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ },
+ cleanup: function () {
+ },
+ expected: {
+ x: gRoot, y: null
+ }
+ },
+
+ // Overflow: hidden; boxes shouldn't be ignored.
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content, 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.style.overflow = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content (X), 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.style.overflowX = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content (Y), 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.style.overflowY = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: gScrollable64, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content (X), 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.style.overflowX = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: null, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content (Y), 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ prepare: function () {
+ gScrollable64.style.overflowY = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: null, y: gScrollable64
+ }
+ },
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content (X), 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable64.style.overflowX = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: gScrollable64, y: null
+ }
+ },
+ { description: "Should be computed from nearest scrollable element even if it hides overflow content (Y), 64",
+ target: gScrollable64,
+ event: {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0, lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ prepare: function () {
+ gScrollable64.style.overflowY = "hidden";
+ gScrollable96.scrollLeft = 0;
+ gScrollable96.scrollTop = 0;
+ gScrollable64.scrollLeft = 0;
+ gScrollable64.scrollTop = 0;
+ },
+ cleanup: function () {
+ gScrollable64.style.overflow = "auto";
+ },
+ expected: {
+ x: gScrollable64, y: null
+ }
+ },
+ ];
+
+ var currentTest, description, firedX, firedY;
+ var expectedHandlerCalls;
+
+ function handler(aEvent)
+ {
+ aEvent.preventDefault();
+
+ if (aEvent.axis != MouseScrollEvent.HORIZONTAL_AXIS &&
+ aEvent.axis != MouseScrollEvent.VERTICAL_AXIS) {
+ ok(false,
+ description + "The event had invalid axis (" + aEvent.axis + ")");
+ if (--expectedHandlerCalls == 0) {
+ setTimeout(runTest, 0);
+ }
+ return;
+ }
+
+ var isHorizontal = (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS);
+ if ((isHorizontal && !currentTest.expected.x) ||
+ (!isHorizontal && !currentTest.expected.y)) {
+ ok(false,
+ description + "The event fired unexpectedly (" +
+ (isHorizontal ? "Horizontal" : "Vertical") + ")");
+ if (--expectedHandlerCalls == 0) {
+ setTimeout(runTest, 0);
+ }
+ return;
+ }
+
+ if (isHorizontal) {
+ firedX = true;
+ } else {
+ firedY = true;
+ }
+
+ var expectedDetail =
+ (currentTest.event.deltaMode == WheelEvent.DOM_DELTA_LINE) ?
+ (isHorizontal ? currentTest.expected.x.wheelHorizontalLine :
+ currentTest.expected.y.wheelLineHeight) :
+ (isHorizontal ? currentTest.expected.x.wheelPageWidth :
+ currentTest.expected.y.wheelPageHeight);
+ is(Math.abs(aEvent.detail), expectedDetail,
+ description + ((isHorizontal) ? "horizontal" : "vertical") + " event detail is wrong");
+
+ if (--expectedHandlerCalls == 0) {
+ setTimeout(runTest, 0);
+ }
+ }
+
+ window.addEventListener("MozMousePixelScroll", handler, true);
+
+ for (var i = 0; i < kTests.length; i++) {
+ currentTest = kTests[i];
+ description = "doTests, " + currentTest.description + " (deltaMode: " +
+ (currentTest.event.deltaMode == WheelEvent.DOM_DELTA_LINE ?
+ "DOM_DELTA_LINE" : "DOM_DELTA_PAGE") +
+ ", deltaX: " + currentTest.event.deltaX +
+ ", deltaY: " + currentTest.event.deltaY + "): ";
+ currentTest.prepare();
+ firedX = firedY = false;
+ expectedHandlerCalls = (currentTest.expected.x ? 1 : 0)
+ + (currentTest.expected.y ? 1 : 0);
+ yield synthesizeWheel(currentTest.target, 10, 10, currentTest.event);
+ if (currentTest.expected.x) {
+ ok(firedX, description + "Horizontal MozMousePixelScroll event wasn't fired");
+ }
+ if (currentTest.expected.y) {
+ ok(firedY, description + "Vertical MozMousePixelScroll event wasn't fired");
+ }
+ currentTest.cleanup();
+ }
+
+ window.removeEventListener("MozMousePixelScroll", handler, true);
+}
+
+function* testBody()
+{
+ yield* prepareScrollUnits();
+ yield* doTests();
+}
+
+var gTestContinuation = null;
+
+function runTest()
+{
+ if (!gTestContinuation) {
+ gTestContinuation = testBody();
+ }
+ var ret = gTestContinuation.next();
+ if (ret.done) {
+ SimpleTest.finish();
+ }
+}
+
+function startTest() {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.delta_multiplier_x", 100],
+ ["mousewheel.default.delta_multiplier_y", 100],
+ ["mousewheel.default.delta_multiplier_z", 100],
+ ["mousewheel.with_alt.delta_multiplier_x", 100],
+ ["mousewheel.with_alt.delta_multiplier_y", 100],
+ ["mousewheel.with_alt.delta_multiplier_z", 100],
+ ["mousewheel.with_control.delta_multiplier_x", 100],
+ ["mousewheel.with_control.delta_multiplier_y", 100],
+ ["mousewheel.with_control.delta_multiplier_z", 100],
+ ["mousewheel.with_meta.delta_multiplier_x", 100],
+ ["mousewheel.with_meta.delta_multiplier_y", 100],
+ ["mousewheel.with_meta.delta_multiplier_z", 100],
+ ["mousewheel.with_shift.delta_multiplier_x", 100],
+ ["mousewheel.with_shift.delta_multiplier_y", 100],
+ ["mousewheel.with_shift.delta_multiplier_z", 100],
+ ["mousewheel.with_win.delta_multiplier_x", 100],
+ ["mousewheel.with_win.delta_multiplier_y", 100],
+ ["mousewheel.with_win.delta_multiplier_z", 100],
+ // If APZ is enabled we should ensure the preventDefault calls work even
+ // if the test is running slowly.
+ ["apz.content_response_timeout", 2000],
+ ]}, runTest);
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_offsetxy.html b/dom/events/test/test_offsetxy.html
new file mode 100644
index 000000000..849b1ea67
--- /dev/null
+++ b/dom/events/test/test_offsetxy.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for DOM MouseEvent offsetX/Y</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<div id="d" style="position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px"></div>
+<div id="d2" style="position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px; transform:translateX(100px)"></div>
+<div id="d3" style="display:none; position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px"></div>
+<div id="d4" style="transform:scale(0); position:absolute; top:100px; left:100px; width:100px; border:5px dotted black; height:100px"></div>
+
+<pre id="test">
+<script type="application/javascript">
+
+var offsetX = -1, offsetY = -1;
+var ev = new MouseEvent("click", {clientX:110, clientY:110});
+is(ev.offsetX, 110);
+is(ev.offsetY, 110);
+is(ev.offsetX, ev.pageX);
+is(ev.offsetY, ev.pageY);
+d.addEventListener("click", function (event) {
+ is(ev, event, "Event objects must match");
+ offsetX = event.offsetX;
+ offsetY = event.offsetY;
+});
+d.dispatchEvent(ev);
+is(offsetX, 5);
+is(offsetY, 5);
+is(ev.offsetX, 5);
+is(ev.offsetY, 5);
+
+var ev2 = new MouseEvent("click", {clientX:220, clientY:130});
+is(ev2.offsetX, 220);
+is(ev2.offsetY, 130);
+is(ev2.offsetX, ev2.pageX);
+is(ev2.offsetY, ev2.pageY);
+d2.addEventListener("click", function (event) {
+ is(ev2, event, "Event objects must match");
+ offsetX = event.offsetX;
+ offsetY = event.offsetY;
+});
+d2.dispatchEvent(ev2);
+is(offsetX, 15);
+is(offsetY, 25);
+is(ev2.offsetX, 15);
+is(ev2.offsetY, 25);
+
+var ev3 = new MouseEvent("click", {clientX:110, clientY:110});
+is(ev3.offsetX, 110);
+is(ev3.offsetY, 110);
+is(ev3.offsetX, ev3.pageX);
+is(ev3.offsetY, ev3.pageY);
+d3.addEventListener("click", function (event) {
+ is(ev3, event, "Event objects must match");
+ offsetX = event.offsetX;
+ offsetY = event.offsetY;
+});
+d3.dispatchEvent(ev3);
+is(offsetX, 0);
+is(offsetY, 0);
+is(ev3.offsetX, 0);
+is(ev3.offsetY, 0);
+
+var ev4 = new MouseEvent("click", {clientX:110, clientY:110});
+is(ev4.offsetX, 110);
+is(ev4.offsetY, 110);
+is(ev4.offsetX, ev4.pageX);
+is(ev4.offsetY, ev4.pageY);
+d4.addEventListener("click", function (event) {
+ is(ev4, event, "Event objects must match");
+ offsetX = event.offsetX;
+ offsetY = event.offsetY;
+});
+d4.dispatchEvent(ev4);
+is(offsetX, 0);
+is(offsetY, 0);
+is(ev4.offsetX, 0);
+is(ev4.offsetY, 0);
+
+// Now redispatch ev4 to "d" to make sure that its offsetX gets updated
+// relative to the new target. Have to set "ev" to "ev4", because the listener
+// on "d" expects to see "ev" as the event.
+ev = ev4;
+d.dispatchEvent(ev4);
+is(offsetX, 5);
+is(offsetY, 5);
+is(ev.offsetX, 5);
+is(ev.offsetY, 5);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_onerror_handler_args.html b/dom/events/test/test_onerror_handler_args.html
new file mode 100644
index 000000000..629434814
--- /dev/null
+++ b/dom/events/test/test_onerror_handler_args.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1007790
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1007790</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1007790 **/
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(function() {
+ is(frames[0].onerror.toString(),
+ "function onerror(event, source, lineno, colno, error) {\n\n}",
+ "Should have the right arguments for onerror on window");
+ is($("content").onerror.toString(),
+ "function onerror(event) {\n\n}",
+ "Should have the right arguments for onerror on element");
+ SimpleTest.finish();
+ });
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1007790">Mozilla Bug 1007790</a>
+<p id="display"></p>
+<div id="content" style="display: none" onerror="">
+ <iframe src="data:text/html,<body onerror=''>"></iframe>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/test_passive_listeners.html b/dom/events/test/test_passive_listeners.html
new file mode 100644
index 000000000..d55d16a5f
--- /dev/null
+++ b/dom/events/test/test_passive_listeners.html
@@ -0,0 +1,118 @@
+<html>
+<head>
+ <title>Tests for passive event listeners</title>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+
+<body>
+<p id="display"></p>
+<div id="dummy">
+</div>
+
+<script>
+var listenerHitCount;
+var doPreventDefault;
+
+function listener(e)
+{
+ listenerHitCount++;
+ if (doPreventDefault) {
+ // When this function is registered as a passive listener, this
+ // call should be a no-op and might report a console warning.
+ e.preventDefault();
+ }
+}
+
+function listener2(e)
+{
+ if (doPreventDefault) {
+ e.preventDefault();
+ }
+}
+
+var elem = document.getElementById('dummy');
+
+function doTest(description, passiveArg)
+{
+ listenerHitCount = 0;
+
+ elem.addEventListener('test', listener, { passive: passiveArg });
+
+ // Test with a cancelable event
+ var e1 = new Event('test', { cancelable: true });
+ elem.dispatchEvent(e1);
+ is(listenerHitCount, 1, description + ' | hit count');
+ var expectedDefaultPrevented = (doPreventDefault && !passiveArg);
+ is(e1.defaultPrevented, expectedDefaultPrevented, description + ' | default prevented');
+
+ // Test with a non-cancelable event
+ var e2 = new Event('test', { cancelable: false });
+ elem.dispatchEvent(e2);
+ is(listenerHitCount, 2, description + ' | hit count after non-cancelable event');
+ is(e2.defaultPrevented, false, description + ' | default prevented on non-cancelable event');
+
+ // Test combining passive-enabled and "traditional" listeners
+ elem.addEventListener('test', listener2, false);
+ var e3 = new Event('test', { cancelable: true });
+ elem.dispatchEvent(e3);
+ is(listenerHitCount, 3, description + ' | hit count with second listener');
+ is(e3.defaultPrevented, doPreventDefault, description + ' | default prevented with second listener');
+ elem.removeEventListener('test', listener2, false);
+
+ elem.removeEventListener('test', listener, false);
+}
+
+function testAddListenerKey(passiveListenerFirst)
+{
+ listenerHitCount = 0;
+ doPreventDefault = true;
+
+ elem.addEventListener('test', listener, { capture: false, passive: passiveListenerFirst });
+ // This second listener should not be registered, because the "key" of
+ // { type, callback, capture } is the same, even though the 'passive' flag
+ // is different.
+ elem.addEventListener('test', listener, { capture: false, passive: !passiveListenerFirst });
+
+ var e1 = new Event('test', { cancelable: true });
+ elem.dispatchEvent(e1);
+
+ is(listenerHitCount, 1, 'Duplicate addEventListener was correctly ignored');
+ is(e1.defaultPrevented, !passiveListenerFirst, 'Prevent-default result based on first registered listener');
+
+ // Even though passive is the opposite of the first addEventListener call, it
+ // should remove the listener registered above.
+ elem.removeEventListener('test', listener, { capture: false, passive: !passiveListenerFirst });
+
+ var e2 = new Event('test', { cancelable: true });
+ elem.dispatchEvent(e2);
+
+ is(listenerHitCount, 1, 'non-passive listener was correctly unregistered');
+ is(e2.defaultPrevented, false, 'no listener was registered to preventDefault this event');
+}
+
+function test()
+{
+ doPreventDefault = false;
+
+ doTest('base case', undefined);
+ doTest('non-passive listener', false);
+ doTest('passive listener', true);
+
+ doPreventDefault = true;
+
+ doTest('base case', undefined);
+ doTest('non-passive listener', false);
+ doTest('passive listener', true);
+
+ testAddListenerKey(false);
+ testAddListenerKey(true);
+}
+
+test();
+
+</script>
+
+</body>
+</html>
+
+
diff --git a/dom/events/test/test_paste_image.html b/dom/events/test/test_paste_image.html
new file mode 100644
index 000000000..716fafeaf
--- /dev/null
+++ b/dom/events/test/test_paste_image.html
@@ -0,0 +1,196 @@
+<html><head>
+<title>Test for bug 891247</title>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<script class="testbody" type="application/javascript">
+ function ImageTester() {
+ var counter = 0;
+ var images = [];
+ var that = this;
+
+ this.add = function(aFile) {
+ images.push(aFile);
+ };
+
+ this.test = function() {
+ for (var i = 0; i < images.length; i++) {
+ testImageSize(images[i]);
+ }
+ };
+
+ this.returned = function() {
+ counter++;
+ info("returned=" + counter + " images.length=" + images.length);
+ if (counter == images.length) {
+ info("test finish");
+ SimpleTest.finish();
+ }
+ };
+
+ function testImageSize(aFile) {
+ var source = window.URL.createObjectURL(aFile);
+ var image = new Image();
+ image.src = source;
+ var imageTester = that;
+ image.onload = function() {
+ is(this.width, 62, "Check generated image width");
+ is(this.height, 71, "Check generated image height");
+ if (aFile.type == "image/gif") {
+ // this test fails for image/jpeg and image/png because the images
+ // generated are slightly different
+ testImageCanvas(image);
+ }
+
+ imageTester.returned();
+ }
+
+ document.body.appendChild(image);
+ };
+
+ function testImageCanvas(aImage) {
+ var canvas = drawToCanvas(aImage);
+
+ var refImage = document.getElementById('image');
+ var refCanvas = drawToCanvas(refImage);
+
+ is(canvas.toDataURL(), refCanvas.toDataURL(), "Image should map pixel-by-pixel");
+ }
+
+ function drawToCanvas(aImage) {
+ var canvas = document.createElement("CANVAS");
+ document.body.appendChild(canvas);
+ canvas.width = aImage.width;
+ canvas.height = aImage.height;
+ canvas.getContext('2d').drawImage(aImage, 0, 0);
+ return canvas;
+ }
+ }
+
+ function copyImage(aImageId) {
+ // selection of the node
+ var node = document.getElementById(aImageId);
+ var webnav = SpecialPowers.wrap(window)
+ .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
+ .getInterface(SpecialPowers.Ci.nsIWebNavigation)
+
+ var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell);
+
+ // let's copy the node
+ var documentViewer = docShell.contentViewer
+ .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
+ documentViewer.setCommandNode(node);
+ documentViewer.copyImage(documentViewer.COPY_IMAGE_ALL);
+ }
+
+ function doTest() {
+ SimpleTest.waitForExplicitFinish();
+
+ copyImage('image');
+
+ //--------- now check the content of the clipboard
+ var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
+ .getService(SpecialPowers.Ci.nsIClipboard);
+ // does the clipboard contain text/unicode data ?
+ ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard),
+ "clipboard contains unicode text");
+ // does the clipboard contain text/html data ?
+ ok(clipboard.hasDataMatchingFlavors(["text/html"], 1, clipboard.kGlobalClipboard),
+ "clipboard contains html text");
+ // does the clipboard contain image data ?
+ ok(clipboard.hasDataMatchingFlavors(["image/png"], 1, clipboard.kGlobalClipboard),
+ "clipboard contains image");
+
+ window.addEventListener("paste", onPaste);
+
+ var textarea = SpecialPowers.wrap(document.getElementById('textarea'));
+ textarea.focus();
+ textarea.editor.paste(clipboard.kGlobalClipboard);
+ }
+
+ function onPaste(e) {
+ var imageTester = new ImageTester;
+ testFiles(e, imageTester);
+ testItems(e, imageTester);
+ imageTester.test();
+ }
+
+ function testItems(e, imageTester) {
+ var items = e.clipboardData.items;
+ is(items, e.clipboardData.items,
+ "Getting @items twice should return the same object");
+ var haveFiles = false;
+ ok(items instanceof DataTransferItemList, "@items implements DataTransferItemList");
+ ok(items.length > 0, "@items is not empty");
+ for (var i = 0; i < items.length; i++) {
+ var item = items[i];
+ ok(item instanceof DataTransferItem, "each element of @items must implement DataTransferItem");
+ if (item.kind == "file") {
+ var file = item.getAsFile();
+ ok(file instanceof File, ".getAsFile() returns a File object");
+ ok(file.size > 0, "Files shouldn't have size 0");
+ imageTester.add(file);
+ }
+ }
+ }
+
+ function testFiles(e, imageTester) {
+ var files = e.clipboardData.files;
+
+ is(files, e.clipboardData.files,
+ "Getting the files array twice should return the same array");
+ ok(files.length > 0, "There should be at least one file in the clipboard");
+ for (var i = 0; i < files.length; i++) {
+ var file = files[i];
+ ok(file instanceof File, ".files should contain only File objects");
+ ok(file.size > 0, "This file shouldn't have size 0");
+ if (file.name == "image.png") {
+ is(file.type, "image/png", "This file should be a image/png");
+ } else if (file.name == "image.jpeg") {
+ is(file.type, "image/jpeg", "This file should be a image/jpeg");
+ } else if (file.name == "image.gif") {
+ is(file.type, "image/gif", "This file should be a image/gif");
+ } else {
+ info("file.name=" + file.name);
+ ok(false, "Unexpected file name");
+ }
+
+ testSlice(file);
+ imageTester.add(file);
+ // Adding the same image again so we can test concurrency
+ imageTester.add(file);
+ }
+ }
+
+ function testSlice(aFile) {
+ var blob = aFile.slice();
+ ok(blob instanceof Blob, ".slice returns a blob");
+ is(blob.size, aFile.size, "the blob has the same size");
+
+ blob = aFile.slice(123123);
+ is(blob.size, 0, ".slice overflow check");
+
+ blob = aFile.slice(123, 123141);
+ is(blob.size, aFile.size - 123, ".slice @size check");
+
+ blob = aFile.slice(123, 12);
+ is(blob.size, 0, ".slice @size check 2");
+
+ blob = aFile.slice(124, 134, "image/png");
+ is(blob.size, 10, ".slice @size check 3");
+ is(blob.type, "image/png", ".slice @type check");
+ }
+
+</script>
+<body onload="doTest();">
+ <img id="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABHCA
+ IAAADQjmMaAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3goUAwAgSAORBwAAABl0RVh0Q29
+ tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABPSURBVGje7c4BDQAACAOga//OmuMbJGAurTbq
+ 6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6s31B0IqAY2/t
+ QVCAAAAAElFTkSuQmCC" />
+ <form>
+ <textarea id="textarea"></textarea>
+ </form>
+</body>
+</html>
diff --git a/dom/events/test/test_wheel_default_action.html b/dom/events/test/test_wheel_default_action.html
new file mode 100644
index 000000000..5ead8be63
--- /dev/null
+++ b/dom/events/test/test_wheel_default_action.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for default action of WheelEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("untriaged");
+SpecialPowers.pushPrefEnv({"set": [
+ ["mousewheel.system_scroll_override_on_root_content.enabled", false]
+]}, runTest);
+
+var subWin = null;
+
+function runTest() {
+ subWin = window.open("window_wheel_default_action.html", "_blank",
+ "width=500,height=500,scrollbars=yes");
+}
+
+function finish()
+{
+ subWin.close();
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/events/test/window_bug493251.html b/dom/events/test/window_bug493251.html
new file mode 100644
index 000000000..d2891a9ef
--- /dev/null
+++ b/dom/events/test/window_bug493251.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script>
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.waitForFocus(window.opener.doTest, window);
+ </script>
+</head>
+<body>
+ <input>
+</body>
+</html>
diff --git a/dom/events/test/window_bug617528.xul b/dom/events/test/window_bug617528.xul
new file mode 100644
index 000000000..fc87f9d78
--- /dev/null
+++ b/dom/events/test/window_bug617528.xul
@@ -0,0 +1,9 @@
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ width="640" height="480">
+
+ <browser id="browser" type="content-primary" flex="1" src="about:blank"
+ disablehistory="true" disablesecurity="true"/>
+
+</window>
diff --git a/dom/events/test/window_bug659071.html b/dom/events/test/window_bug659071.html
new file mode 100644
index 000000000..5fb2efed4
--- /dev/null
+++ b/dom/events/test/window_bug659071.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Bug 659071</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<video id="v" controls></video>
+<script type="application/javascript">
+
+SimpleTest.waitForFocus(startTests, window);
+SimpleTest.requestFlakyTimeout("untriaged");
+
+function is()
+{
+ window.opener.is.apply(window.opener, arguments);
+}
+
+function isnot()
+{
+ window.opener.isnot.apply(window.opener, arguments);
+}
+
+function hitEventLoop(aFunc, aTimes)
+{
+ if (--aTimes) {
+ setTimeout(hitEventLoop, 0, aFunc, aTimes);
+ } else {
+ setTimeout(aFunc, 20);
+ }
+}
+
+function startTests() {
+ SpecialPowers.pushPrefEnv({"set": [["mousewheel.with_control.action", 3]]}, runTests);
+}
+
+function runTests()
+{
+ synthesizeKey("0", { accelKey: true });
+
+ var video = document.getElementById("v");
+ hitEventLoop(function () {
+ is(SpecialPowers.getFullZoom(window), 1.0,
+ "failed to reset zoom");
+ synthesizeWheel(video, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE, ctrlKey: true,
+ deltaX: 0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 });
+ hitEventLoop(function () {
+ isnot(SpecialPowers.getFullZoom(window), 1.0,
+ "failed to zoom by ctrl+wheel");
+
+ synthesizeWheel(video, 10, 10,
+ { deltaMode: WheelEvent.DOM_DELTA_LINE, ctrlKey: true,
+ deltaX: 0, deltaY: 1.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 });
+ hitEventLoop(function () {
+ is(SpecialPowers.getFullZoom(window), 1.0,
+ "failed to reset zoom");
+
+ hitEventLoop(window.opener.finish, 20);
+ }, 20);
+ }, 20);
+ }, 20);
+}
+
+</script>
+</body>
+</html>
diff --git a/dom/events/test/window_wheel_default_action.html b/dom/events/test/window_wheel_default_action.html
new file mode 100644
index 000000000..fa6abf188
--- /dev/null
+++ b/dom/events/test/window_wheel_default_action.html
@@ -0,0 +1,1848 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for default action of WheelEvent</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="scrollable" style="overflow: auto; width: 200px; height: 200px;">
+ <div id="clipper" style="margin: 0; padding: 0; overflow: hidden; width: 3000px; height: 3000px;">
+ <div id="scrolled" style="width: 5000px; height: 5000px;">
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text. Tere is a lot of text.<br>
+ </div>
+ </div>
+</div>
+<div id="spacerForBody"></div>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForFocus(runTests, window);
+SimpleTest.requestFlakyTimeout("untriaged");
+
+var winUtils = SpecialPowers.getDOMWindowUtils(window);
+// grab refresh driver
+winUtils.advanceTimeAndRefresh(100);
+
+var gScrollableElement = document.getElementById("scrollable");
+var gScrolledElement = document.getElementById("scrolled");
+var gSpacerForBodyElement = document.getElementById("spacerForBody");
+
+function is()
+{
+ window.opener.is.apply(window.opener, arguments);
+}
+
+function ok()
+{
+ window.opener.ok.apply(window.opener, arguments);
+}
+
+function sendWheelAndWait(aX, aY, aEvent, aCallback)
+{
+ sendWheelAndPaint(gScrollableElement, aX, aY, aEvent, aCallback);
+}
+
+function hitEventLoop(aFunc, aTimes)
+{
+ winUtils.advanceTimeAndRefresh(100);
+
+ if (--aTimes) {
+ setTimeout(hitEventLoop, 0, aFunc, aTimes);
+ } else {
+ setTimeout(aFunc, 20);
+ }
+}
+
+const zoomResetTopic = "browser-fullZoom:zoomReset";
+SpecialPowers.registerObservers(zoomResetTopic);
+
+function onZoomReset(aCallback) {
+ var specialPowersTopic = "specialpowers-" + zoomResetTopic;
+ SpecialPowers.addObserver(function observe() {
+ SpecialPowers.removeObserver(observe, specialPowersTopic);
+ SimpleTest.executeSoon(aCallback);
+ }, specialPowersTopic, false);
+}
+
+function setDeltaMultiplierSettings(aSettings, aCallback)
+{
+ SpecialPowers.pushPrefEnv({"set": [
+ ["mousewheel.default.delta_multiplier_x", aSettings.deltaMultiplierX * 100],
+ ["mousewheel.default.delta_multiplier_y", aSettings.deltaMultiplierY * 100],
+ ["mousewheel.default.delta_multiplier_z", aSettings.deltaMultiplierZ * 100],
+ ["mousewheel.with_alt.delta_multiplier_x", aSettings.deltaMultiplierX * 100],
+ ["mousewheel.with_alt.delta_multiplier_y", aSettings.deltaMultiplierY * 100],
+ ["mousewheel.with_alt.delta_multiplier_z", aSettings.deltaMultiplierZ * 100],
+ ["mousewheel.with_control.delta_multiplier_x", aSettings.deltaMultiplierX * 100],
+ ["mousewheel.with_control.delta_multiplier_y", aSettings.deltaMultiplierY * 100],
+ ["mousewheel.with_control.delta_multiplier_z", aSettings.deltaMultiplierZ * 100],
+ ["mousewheel.with_meta.delta_multiplier_x", aSettings.deltaMultiplierX * 100],
+ ["mousewheel.with_meta.delta_multiplier_y", aSettings.deltaMultiplierY * 100],
+ ["mousewheel.with_meta.delta_multiplier_z", aSettings.deltaMultiplierZ * 100],
+ ["mousewheel.with_shift.delta_multiplier_x", aSettings.deltaMultiplierX * 100],
+ ["mousewheel.with_shift.delta_multiplier_y", aSettings.deltaMultiplierY * 100],
+ ["mousewheel.with_shift.delta_multiplier_z", aSettings.deltaMultiplierZ * 100],
+ ["mousewheel.with_win.delta_multiplier_x", aSettings.deltaMultiplierX * 100],
+ ["mousewheel.with_win.delta_multiplier_y", aSettings.deltaMultiplierY * 100],
+ ["mousewheel.with_win.delta_multiplier_z", aSettings.deltaMultiplierZ * 100]
+ ]}, aCallback);
+}
+
+function doTestScroll(aSettings, aCallback)
+{
+ const kNoScroll = 0x00;
+ const kScrollUp = 0x01;
+ const kScrollDown = 0x02;
+ const kScrollLeft = 0x04;
+ const kScrollRight = 0x08;
+
+ const kTests = [
+ { description: "Scroll to bottom by pixel scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to bottom by pixel scroll when lineOrPageDelta is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to top by pixel scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to top by pixel scroll when lineOrPageDelta is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to right by pixel scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to right by pixel scroll when lineOrPageDelta is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to left by pixel scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to left by pixel scroll when lineOrPageDelta is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to bottom-right by pixel scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollRight },
+ { description: "Scroll to bottom-left by pixel scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollLeft },
+ { description: "Scroll to top-left by pixel scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollLeft },
+ { description: "Scroll to top-right by pixel scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollRight },
+ { description: "Not Scroll by pixel scroll for z",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+
+ { description: "Scroll to bottom by line scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to bottom by line scroll when lineOrPageDelta is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to top by line scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to top by line scroll when lineOrPageDelta is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to right by line scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to right by line scroll when lineOrPageDelta is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to left by line scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to left by line scroll when lineOrPageDelta is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to bottom-right by line scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollRight },
+ { description: "Scroll to bottom-left by line scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.5, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollLeft },
+ { description: "Scroll to top-left by line scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.5, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollLeft },
+ { description: "Scroll to top-right by line scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollRight },
+ { description: "Not Scroll by line scroll for z",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+
+ { description: "Scroll to bottom by page scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to bottom by page scroll when lineOrPageDelta is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to top by page scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to top by page scroll when lineOrPageDelta is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to right by page scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to right by page scroll when lineOrPageDelta is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to left by page scroll even if lineOrPageDelta is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to left by page scroll when lineOrPageDelta is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to bottom-right by page scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollRight },
+ { description: "Scroll to bottom-left by page scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.5, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollLeft },
+ { description: "Scroll to top-left by page scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.5, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollLeft },
+ { description: "Scroll to top-right by page scroll",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollRight },
+ { description: "Not Scroll by page scroll for z",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: false,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+
+ // special cases.
+
+ // momentum scroll should cause scroll even if the action is zoom, but if the default action is none,
+ // shouldn't do it.
+ { description: "Scroll to bottom by momentum pixel scroll when lineOrPageDelta is 0, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to bottom by momentum pixel scroll when lineOrPageDelta is 1, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to top by momentum pixel scroll when lineOrPageDelta is 0, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to top by momentum pixel scroll when lineOrPageDelta is -1, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to right by momentum pixel scroll when lineOrPageDelta is 0, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to right by momentum pixel scroll when lineOrPageDelta is 1, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to left by momentum pixel scroll when lineOrPageDelta is 0, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to left by momentum pixel scroll when lineOrPageDelta is -1, even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to bottom-right by momentum pixel scroll even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollRight },
+ { description: "Scroll to bottom-left by momentum pixel scroll even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollLeft },
+ { description: "Scroll to top-left by momentum pixel scroll even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollLeft },
+ { description: "Scroll to top-right by momentum pixel scroll even if the action is zoom",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollRight },
+ { description: "Not Scroll by momentum pixel scroll for z (action is zoom)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+ { description: "Not Scroll by momentum pixel scroll if default action is none (action is zoom)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: true, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll,
+ prepare: function (cb) { SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.action", 0]]}, cb); },
+ cleanup: function (cb) { SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.action", 1]]}, cb); } },
+
+ // momentum scroll should cause scroll even if the action is history, but if the default action is none,
+ // shouldn't do it.
+ { description: "Scroll to bottom by momentum pixel scroll when lineOrPageDelta is 0, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to bottom by momentum pixel scroll when lineOrPageDelta is 1, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to top by momentum pixel scroll when lineOrPageDelta is 0, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to top by momentum pixel scroll when lineOrPageDelta is -1, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to right by momentum pixel scroll when lineOrPageDelta is 0, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to right by momentum pixel scroll when lineOrPageDelta is 1, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to left by momentum pixel scroll when lineOrPageDelta is 0, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to left by momentum pixel scroll when lineOrPageDelta is -1, even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to bottom-right by momentum pixel scroll even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollRight },
+ { description: "Scroll to bottom-left by momentum pixel scroll even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown | kScrollLeft },
+ { description: "Scroll to top-left by momentum pixel scroll even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollLeft },
+ { description: "Scroll to top-right by momentum pixel scroll even if the action is history",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp | kScrollRight },
+ { description: "Not Scroll by momentum pixel scroll for z (action is history)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+ { description: "Not Scroll by momentum pixel scroll if default action is none (action is history)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0, isMomentum: true,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: true, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll,
+ prepare: function (cb) { SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.action", 0]]}, cb); },
+ cleanup: function (cb) { SpecialPowers.pushPrefEnv({"set": [["mousewheel.default.action", 1]]}, cb); } },
+
+ // Don't scroll along axis whose overflow style is hidden.
+ { description: "Scroll to only bottom by oblique pixel wheel event with overflow-x: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 1, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown,
+ prepare: function(cb) { gScrollableElement.style.overflowX = "hidden"; cb(); } },
+ { description: "Scroll to only bottom by oblique line wheel event with overflow-x: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 1, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to only bottom by oblique page wheel event with overflow-x: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 1, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to only top by oblique pixel wheel event with overflow-x: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: -16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: -1, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to only top by oblique line wheel event with overflow-x: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: -1, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to only top by oblique page wheel event with overflow-x: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: -1, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp,
+ cleanup: function (cb) { gScrollableElement.style.overflowX = "auto"; cb(); } },
+ { description: "Scroll to only right by oblique pixel wheel event with overflow-y: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight,
+ prepare: function(cb) { gScrollableElement.style.overflowY = "hidden"; cb(); } },
+ { description: "Scroll to only right by oblique line wheel event with overflow-y: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to only right by oblique page wheel event with overflow-y: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to only left by oblique pixel wheel event with overflow-y: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: -16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: -1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to only top by oblique line wheel event with overflow-y: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: -1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to only top by oblique page wheel event with overflow-y: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: -1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft,
+ cleanup: function (cb) { gScrollableElement.style.overflowY = "auto"; cb(); } },
+ { description: "Don't be scrolled by oblique pixel wheel event with overflow: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 1, expectedOverflowDeltaY: 1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll,
+ prepare: function(cb) { gScrollableElement.style.overflow = "hidden"; cb(); } },
+ { description: "Don't be scrolled by oblique line wheel event with overflow: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 1, expectedOverflowDeltaY: 1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+ { description: "Don't be scrolled by oblique page wheel event with overflow: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 1, expectedOverflowDeltaY: 1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+ { description: "Don't be scrolled by oblique pixel wheel event with overflow: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: -16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: -1, expectedOverflowDeltaY: -1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+ { description: "Don't be scrolled by oblique line wheel event with overflow: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: -1, expectedOverflowDeltaY: -1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll },
+ { description: "Don't be scrolled by oblique page wheel event with overflow: hidden",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: -1, expectedOverflowDeltaY: -1,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kNoScroll,
+ cleanup: function (cb) { gScrollableElement.style.overflow = "auto"; cb(); } },
+
+ // Don't scroll along axis whose overflow style is hidden and overflow delta values should
+ // be zero if there is ancestor scrollable element.
+ { description: "Scroll to only bottom by oblique pixel wheel event with overflow-x: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown,
+ prepare: function(cb) {
+ gScrollableElement.style.overflowX = "hidden";
+ gScrollableElement.style.position = "fixed";
+ gScrollableElement.style.top = "30px";
+ gScrollableElement.style.left = "30px";
+ // Make body element scrollable.
+ gSpacerForBodyElement.style.width = "5000px";
+ gSpacerForBodyElement.style.height = "5000px";
+ document.documentElement.scrollTop = 500;
+ document.documentElement.scrollLeft = 500;
+ cb();
+ } },
+ { description: "Scroll to only bottom by oblique line wheel event with overflow-x: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to only bottom by oblique page wheel event with overflow-x: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollDown },
+ { description: "Scroll to only top by oblique pixel wheel event with overflow-x: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: -16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to only top by oblique line wheel event with overflow-x: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp },
+ { description: "Scroll to only top by oblique page wheel event with overflow-x: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollUp,
+ cleanup: function (cb) { gScrollableElement.style.overflowX = "auto"; cb(); } },
+ { description: "Scroll to only right by oblique pixel wheel event with overflow-y: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0, deltaY: 16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight,
+ prepare: function(cb) { gScrollableElement.style.overflowY = "hidden"; cb(); } },
+ { description: "Scroll to only right by oblique line wheel event with overflow-y: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to only right by oblique page wheel event with overflow-y: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollRight },
+ { description: "Scroll to only left by oblique pixel wheel event with overflow-y: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -16.0, deltaY: -16.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to only top by oblique line wheel event with overflow-y: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft },
+ { description: "Scroll to only top by oblique page wheel event with overflow-y: hidden (body is scrollable)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: -1.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0,
+ shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, osKey: false },
+ expected: kScrollLeft,
+ cleanup: function (cb) {
+ gScrollableElement.style.overflowY = "auto";
+ gScrollableElement.style.position = "static";
+ gSpacerForBodyElement.style.width = "";
+ gSpacerForBodyElement.style.height = "";
+ cb();
+ } },
+ ];
+
+ var description;
+
+ var currentTestIndex = -1;
+ var isXReverted = (aSettings.deltaMultiplierX < 0);
+ var isYReverted = (aSettings.deltaMultiplierY < 0);
+
+ function doNextTest()
+ {
+ if (++currentTestIndex >= kTests.length) {
+ SimpleTest.executeSoon(aCallback);
+ return;
+ }
+
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+
+ var currentTest = kTests[currentTestIndex];
+ description = "doTestScroll(aSettings=" + aSettings.description + "), " + currentTest.description + ": ";
+ if (currentTest.prepare) {
+ currentTest.prepare(doTestCurrentScroll);
+ } else {
+ doTestCurrentScroll();
+ }
+ }
+
+ function doTestCurrentScroll() {
+ var currentTest = kTests[currentTestIndex];
+ sendWheelAndWait(10, 10, currentTest.event, function () {
+ if (currentTest.expected == kNoScroll) {
+ is(gScrollableElement.scrollTop, 1000, description + "scrolled vertical");
+ is(gScrollableElement.scrollLeft, 1000, description + "scrolled horizontal");
+ } else {
+ var scrollUp = !isYReverted ? (currentTest.expected & kScrollUp) :
+ (currentTest.expected & kScrollDown);
+ var scrollDown = !isYReverted ? (currentTest.expected & kScrollDown) :
+ (currentTest.expected & kScrollUp);
+ if (scrollUp) {
+ ok(gScrollableElement.scrollTop < 1000, description + "not scrolled up, got " + gScrollableElement.scrollTop);
+ } else if (scrollDown) {
+ ok(gScrollableElement.scrollTop > 1000, description + "not scrolled down, got " + gScrollableElement.scrollTop);
+ } else {
+ is(gScrollableElement.scrollTop, 1000, description + "scrolled vertical");
+ }
+ var scrollLeft = !isXReverted ? (currentTest.expected & kScrollLeft) :
+ (currentTest.expected & kScrollRight);
+ var scrollRight = !isXReverted ? (currentTest.expected & kScrollRight) :
+ (currentTest.expected & kScrollLeft);
+ if (scrollLeft) {
+ ok(gScrollableElement.scrollLeft < 1000, description + "not scrolled to left, got " + gScrollableElement.scrollLeft);
+ } else if (scrollRight) {
+ ok(gScrollableElement.scrollLeft > 1000, description + "not scrolled to right, got " + gScrollableElement.scrollLeft);
+ } else {
+ is(gScrollableElement.scrollLeft, 1000, description + "scrolled horizontal");
+ }
+ }
+ if (currentTest.cleanup) {
+ currentTest.cleanup(nextStep);
+ } else {
+ nextStep();
+ }
+
+ function nextStep() {
+ winUtils.advanceTimeAndRefresh(100);
+ doNextTest();
+ }
+ });
+ }
+ doNextTest();
+}
+
+function doTestZoom(aSettings, aCallback)
+{
+ if ((aSettings.deltaMultiplierX != 1.0 && aSettings.deltaMultiplierX != -1.0) ||
+ (aSettings.deltaMultiplierY != 1.0 && aSettings.deltaMultiplierY != -1.0)) {
+ todo(false, "doTestZoom doesn't support to test with aSettings=" + aSettings.description);
+ SimpleTest.executeSoon(aCallback);
+ return;
+ }
+
+ const kNone = 0x00;
+ const kPositive = 0x01;
+ const kNegative = 0x02;
+ const kUseX = 0x10;
+ const kUseY = 0x20;
+ const kTests = [
+ { description: "by vertical/positive pixel event when its lineOrPageDeltaY is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by vertical/positive pixel event when its lineOrPageDeltaY is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kPositive | kUseY },
+ { description: "by vertical/negative pixel event when its lineOrPageDeltaY is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by vertical/negative pixel event when its lineOrPageDeltaY is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -8.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNegative | kUseY },
+ { description: "by horizotal/positive pixel event when its lineOrPageDeltaX is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by horizotal/positive pixel event when its lineOrPageDeltaX is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kPositive | kUseX },
+ { description: "by horizotal/negative pixel event when its lineOrPageDeltaX is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by horizotal/negative pixel event when its lineOrPageDeltaX is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -8.0, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNegative | kUseX },
+ { description: "by z pixel event",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 16.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+
+ { description: "by vertical/positive line event when its lineOrPageDeltaY is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by vertical/positive line event when its lineOrPageDeltaY is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kPositive | kUseY },
+ { description: "by vertical/negative line event when its lineOrPageDeltaY is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by vertical/negative line event when its lineOrPageDeltaY is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNegative | kUseY },
+ { description: "by horizotal/positive line event when its lineOrPageDeltaX is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by horizotal/positive line event when its lineOrPageDeltaX is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kPositive | kUseX },
+ { description: "by horizotal/negative line event when its lineOrPageDeltaX is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by horizotal/negative line event when its lineOrPageDeltaX is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNegative | kUseX },
+ { description: "by z line event",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+
+ { description: "by vertical/positive page event when its lineOrPageDeltaY is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by vertical/positive page event when its lineOrPageDeltaY is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kPositive | kUseY },
+ { description: "by vertical/negative page event when its lineOrPageDeltaY is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by vertical/negative page event when its lineOrPageDeltaY is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -0.5, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNegative | kUseY },
+ { description: "by horizotal/positive page event when its lineOrPageDeltaX is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by horizotal/positive page event when its lineOrPageDeltaX is 1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kPositive | kUseX },
+ { description: "by horizotal/negative page event when its lineOrPageDeltaX is 0",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ { description: "by horizotal/negative page event when its lineOrPageDeltaX is -1",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -0.5, deltaY: 0.0, deltaZ: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNegative | kUseX },
+ { description: "by z page event",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 0.0, deltaZ: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0,
+ expectedOverflowDeltaX: 0, expectedOverflowDeltaY: 0 },
+ expected: kNone },
+ ];
+
+ var description, currentTest;
+ var currentTestIndex = -1;
+ var isXReverted = (aSettings.deltaMultiplierX < 0);
+ var isYReverted = (aSettings.deltaMultiplierY < 0);
+
+ function doNextTest()
+ {
+ if (++currentTestIndex >= kTests.length) {
+ SimpleTest.executeSoon(aCallback);
+ return;
+ }
+
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+
+ currentTest = kTests[currentTestIndex];
+ description = "doTestZoom(aSettings=" + aSettings.description + "), ";
+ if (currentTest.expected == kNone) {
+ description += "Shouldn't ";
+ } else {
+ description += "Should ";
+ }
+ description += "zoom " + currentTest.description + ": ";
+
+ var event = currentTest.event;
+ event.ctrlKey = true;
+
+ // NOTE: Zooming might change scrollTop and scrollLeft by rounding fraction.
+ // This test assume that zoom happens synchronously and scrolling
+ // happens asynchronously.
+ var scrollTop = gScrollableElement.scrollTop;
+ var scrollLeft = gScrollableElement.scrollLeft;
+
+ sendWheelAndWait(10, 10, event, function () {
+ is(gScrollableElement.scrollTop, scrollTop, description + "scrolled vertical");
+ is(gScrollableElement.scrollLeft, scrollLeft, description + "scrolled horizontal");
+ if (!(currentTest.expected & (kNegative | kPositive))) {
+ is(SpecialPowers.getFullZoom(window), 1.0, description + "zoomed");
+ } else {
+ var isReverted = (currentTest.expected & kUseX) ? isXReverted :
+ (currentTest.expected & kUseY) ? isYReverted : false;
+ if ((!isReverted && (currentTest.expected & kNegative)) ||
+ (isReverted && (currentTest.expected & kPositive))) {
+ ok(SpecialPowers.getFullZoom(window) > 1.0,
+ description + "not zoomed in, got " + SpecialPowers.getFullZoom(window));
+ } else {
+ ok(SpecialPowers.getFullZoom(window) < 1.0,
+ description + "not zoomed out, got " + SpecialPowers.getFullZoom(window));
+ }
+ }
+
+ synthesizeKey("0", { accelKey: true });
+ onZoomReset(function () {
+ hitEventLoop(doNextTest, 20);
+ });
+ });
+ }
+ doNextTest();
+}
+
+function doTestZoomedScroll(aCallback)
+{
+ var zoom = 1.0;
+ function setFullZoom(aWindow, aZoom)
+ {
+ zoom = aZoom;
+ SpecialPowers.setFullZoom(aWindow, aZoom);
+ }
+
+ function prepareTestZoomedPixelScroll()
+ {
+ // Reset zoom and store the scroll amount into the data.
+ synthesizeKey("0", { accelKey: true });
+ zoom = 1.0;
+ onZoomReset(testZoomedPixelScroll);
+ }
+
+ function testZoomedPixelScroll()
+ {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ // Ensure not to be in reflow.
+ hitEventLoop(function () {
+ function mousePixelScrollHandler(aEvent)
+ {
+ if (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS) {
+ is(aEvent.detail, 16,
+ "doTestZoomedScroll: The detail of horizontal MozMousePixelScroll for pixel wheel event is wrong");
+ } else if (aEvent.axis == MouseScrollEvent.VERTICAL_AXIS) {
+ is(aEvent.detail, 16,
+ "doTestZoomedScroll: The detail of vertical MozMousePixelScroll for pixel wheel event is wrong");
+ } else {
+ ok(false, "doTestZoomedScroll: The axis of MozMousePixelScroll for pixel wheel event is invalid, got " + aEvent.axis);
+ }
+ }
+ function wheelHandler(aEvent)
+ {
+ is(aEvent.deltaX, 16.0 / zoom,
+ "doTestZoomedScroll: The deltaX of wheel for pixel is wrong");
+ is(aEvent.deltaY, 16.0 / zoom,
+ "doTestZoomedScroll: The deltaY of wheel for pixel is wrong");
+ }
+ window.addEventListener("MozMousePixelScroll", mousePixelScrollHandler, true);
+ window.addEventListener("wheel", wheelHandler, true);
+ var event = {
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0,
+ deltaY: 16.0,
+ lineOrPageDeltaX: 0,
+ lineOrPageDeltaY: 0
+ };
+ // wait scrolled actually.
+ sendWheelAndWait(10, 10, event, function () {
+ var scrolledX = gScrollableElement.scrollLeft;
+ var scrolledY = gScrollableElement.scrollTop;
+ ok(scrolledX > 1000,
+ "doTestZoomedScroll: scrolledX must be larger than 1000 for pixel wheel event, got " + scrolledX);
+ ok(scrolledY > 1000,
+ "doTestZoomedScroll: scrolledY must be larger than 1000 for pixel wheel event, got " + scrolledY);
+
+ // Zoom
+ setFullZoom(window, 2.0);
+ // Ensure not to be in reflow.
+ hitEventLoop(function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ var event = {
+ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 16.0,
+ deltaY: 16.0,
+ lineOrPageDeltaX: 0,
+ lineOrPageDeltaY: 0
+ };
+ // wait scrolled actually.
+ sendWheelAndWait(10, 10, event, function () {
+ ok(Math.abs(gScrollableElement.scrollLeft - (1000 + (scrolledX - 1000) / 2)) <= 1,
+ "doTestZoomedScroll: zoomed horizontal scroll amount by pixel wheel event is different from normal, scrollLeft=" +
+ gScrollableElement.scrollLeft + ", scrolledX=" + scrolledX);
+ ok(Math.abs(gScrollableElement.scrollTop - (1000 + (scrolledY - 1000) / 2)) <= 1,
+ "doTestZoomedScroll: zoomed vertical scroll amount by pixel wheel event is different from normal, scrollTop=" +
+ gScrollableElement.scrollTop + ", scrolledY=" + scrolledY);
+ window.removeEventListener("MozMousePixelScroll", mousePixelScrollHandler, true);
+ window.removeEventListener("wheel", wheelHandler, true);
+
+ synthesizeKey("0", { accelKey: true });
+ onZoomReset(prepareTestZoomedLineScroll);
+ });
+ }, 20);
+ });
+ }, 20);
+ }
+
+ function prepareTestZoomedLineScroll()
+ {
+ // Reset zoom and store the scroll amount into the data.
+ synthesizeKey("0", { accelKey: true });
+ zoom = 1.0;
+ onZoomReset(testZoomedLineScroll);
+ }
+ function testZoomedLineScroll()
+ {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ // Ensure not to be in reflow.
+ hitEventLoop(function () {
+ var lineHeightX, lineHeightY;
+ function handler(aEvent)
+ {
+ if (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS) {
+ if (lineHeightX == undefined) {
+ lineHeightX = aEvent.detail;
+ } else {
+ ok(Math.abs(aEvent.detail - lineHeightX) <= 1,
+ "doTestZoomedScroll: The detail of horizontal MozMousePixelScroll for line wheel event is wrong, aEvent.detail=" +
+ aEvent.detail + ", lineHeightX=" + lineHeightX);
+ }
+ } else if (aEvent.axis == MouseScrollEvent.VERTICAL_AXIS) {
+ if (lineHeightY == undefined) {
+ lineHeightY = aEvent.detail;
+ } else {
+ ok(Math.abs(aEvent.detail - lineHeightY) <= 1,
+ "doTestZoomedScroll: The detail of vertical MozMousePixelScroll for line wheel event is wrong, aEvent.detail=" +
+ aEvent.detail + ", lineHeightY=" + lineHeightY);
+ }
+ } else {
+ ok(false, "doTestZoomedScroll: The axis of MozMousePixelScroll for line wheel event is invalid, got " + aEvent.axis);
+ }
+ }
+ window.addEventListener("MozMousePixelScroll", handler, true);
+ var event = {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0,
+ deltaY: 1.0,
+ lineOrPageDeltaX: 1,
+ lineOrPageDeltaY: 1
+ };
+ // wait scrolled actually.
+ sendWheelAndWait(10, 10, event, function () {
+ var scrolledX = gScrollableElement.scrollLeft;
+ var scrolledY = gScrollableElement.scrollTop;
+ ok(scrolledX > 1000,
+ "doTestZoomedScroll: scrolledX must be larger than 1000 for line wheel event, got " + scrolledX);
+ ok(scrolledY > 1000,
+ "doTestZoomedScroll: scrolledY must be larger than 1000 for line wheel event, got " + scrolledY);
+
+ // Zoom
+ setFullZoom(window, 2.0);
+ // Ensure not to be in reflow.
+ hitEventLoop(function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ var event = {
+ deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0,
+ deltaY: 1.0,
+ lineOrPageDeltaX: 1,
+ lineOrPageDeltaY: 1
+ };
+ // wait scrolled actually.
+ sendWheelAndWait(10, 10, event, function () {
+ ok(Math.abs(gScrollableElement.scrollLeft - scrolledX) <= 1,
+ "doTestZoomedScroll: zoomed horizontal scroll amount by line wheel event is different from normal, scrollLeft=" +
+ gScrollableElement.scrollLeft + ", scrolledX=" + scrolledX);
+ ok(Math.abs(gScrollableElement.scrollTop - scrolledY) <= 1,
+ "doTestZoomedScroll: zoomed vertical scroll amount by line wheel event is different from normal, scrollTop=" +
+ gScrollableElement.scrollTop + ", scrolledY=" + scrolledY);
+
+ window.removeEventListener("MozMousePixelScroll", handler, true);
+
+ synthesizeKey("0", { accelKey: true });
+ onZoomReset(aCallback);
+ });
+ }, 20);
+ });
+ }, 20);
+ }
+
+ // XXX It's too difficult to test page scroll because the page scroll amount
+ // is computed by complex logic.
+
+ prepareTestZoomedPixelScroll();
+}
+
+function doTestWholeScroll(aCallback)
+{
+ SpecialPowers.pushPrefEnv({"set": [
+ ["mousewheel.default.delta_multiplier_x", 999999],
+ ["mousewheel.default.delta_multiplier_y", 999999]]},
+ function() { doTestWholeScroll2(aCallback); });
+}
+
+function doTestWholeScroll2(aCallback)
+{
+ const kTests = [
+ { description: "try whole-scroll to top (line)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ expectedScrollTop: 0,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to top when scrollTop is already top-most (line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: -1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ expectedScrollTop: 0,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to bottom (line)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.0, deltaY: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ expectedScrollTop: gScrollableElement.scrollTopMax,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to bottom when scrollTop is already bottom-most (line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0, deltaY: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ expectedScrollTop: gScrollableElement.scrollTopMax,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to left (line)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: 0
+ },
+ { description: "try whole-scroll to left when scrollLeft is already left-most (line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: -1.0, deltaY: 0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: 0
+ },
+ { description: "try whole-scroll to right (line)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: gScrollableElement.scrollLeftMax
+ },
+ { description: "try whole-scroll to right when scrollLeft is already right-most (line)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: gScrollableElement.scrollLeftMax
+ },
+
+
+ { description: "try whole-scroll to top (pixel)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 0,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to top when scrollTop is already top-most (pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: -1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 0,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to bottom (pixel)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0.0, deltaY: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: gScrollableElement.scrollTopMax,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to bottom when scrollTop is already bottom-most (pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 0, deltaY: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: gScrollableElement.scrollTopMax,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to left (pixel)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: 0
+ },
+ { description: "try whole-scroll to left when scrollLeft is already left-most (pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: -1.0, deltaY: 0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: 0
+ },
+ { description: "try whole-scroll to right (pixel)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: gScrollableElement.scrollLeftMax
+ },
+ { description: "try whole-scroll to right when scrollLeft is already right-most (pixel)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PIXEL,
+ deltaX: 1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: gScrollableElement.scrollLeftMax
+ },
+
+
+ { description: "try whole-scroll to top (page)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ expectedScrollTop: 0,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to top when scrollTop is already top-most (page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: -1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: -1 },
+ expectedScrollTop: 0,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to bottom (page)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0.0, deltaY: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ expectedScrollTop: gScrollableElement.scrollTopMax,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to bottom when scrollTop is already bottom-most (page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 0, deltaY: 1.0,
+ lineOrPageDeltaX: 0, lineOrPageDeltaY: 1 },
+ expectedScrollTop: gScrollableElement.scrollTopMax,
+ expectedScrollLeft: 1000
+ },
+ { description: "try whole-scroll to left (page)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0.0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: 0
+ },
+ { description: "try whole-scroll to left when scrollLeft is already left-most (page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: -1.0, deltaY: 0,
+ lineOrPageDeltaX: -1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: 0
+ },
+ { description: "try whole-scroll to right (page)",
+ prepare: function () {
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ },
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: gScrollableElement.scrollLeftMax
+ },
+ { description: "try whole-scroll to right when scrollLeft is already right-most (page)",
+ event: { deltaMode: WheelEvent.DOM_DELTA_PAGE,
+ deltaX: 1.0, deltaY: 0.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 0 },
+ expectedScrollTop: 1000,
+ expectedScrollLeft: gScrollableElement.scrollLeftMax
+ },
+ ];
+
+ var index = 0;
+
+ function doIt()
+ {
+ const kTest = kTests[index];
+ if (kTest.prepare) {
+ kTest.prepare();
+ }
+ sendWheelAndWait(10, 10, kTest.event, function () {
+ is(gScrollableElement.scrollTop, kTest.expectedScrollTop,
+ "doTestWholeScroll, " + kTest.description + ": unexpected scrollTop");
+ is(gScrollableElement.scrollLeft, kTest.expectedScrollLeft,
+ "doTestWholeScroll, " + kTest.description + ": unexpected scrollLeft");
+ if (++index == kTests.length) {
+ SimpleTest.executeSoon(aCallback);
+ } else {
+ doIt();
+ }
+ });
+ }
+ doIt();
+}
+
+function doTestActionOverride(aCallback)
+{
+ const kNoScroll = 0x00;
+ const kScrollUp = 0x01;
+ const kScrollDown = 0x02;
+ const kScrollLeft = 0x04;
+ const kScrollRight = 0x08;
+
+ const kTests = [
+ { action: 1, override_x: -1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 1, override_x: 0,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 1, override_x: 1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 0, override_x: -1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 0, override_x: 0,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 0, override_x: 1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 1, override_x: -1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.5,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 1, override_x: 0,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.5,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 1, override_x: 1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.5,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 0, override_x: -1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.5,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 0, override_x: 0,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.5,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 0, override_x: 1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 1.0, deltaY: 0.5,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 1, override_x: -1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 1, override_x: 0,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 1, override_x: 1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kScrollDown | kScrollRight
+ },
+ { action: 0, override_x: -1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 0, override_x: 0,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ { action: 0, override_x: 1,
+ event: { deltaMode: WheelEvent.DOM_DELTA_LINE,
+ deltaX: 0.5, deltaY: 1.0,
+ lineOrPageDeltaX: 1, lineOrPageDeltaY: 1 },
+ expected: kNoScroll
+ },
+ ];
+
+ var index = 0;
+
+ function doIt()
+ {
+ const kTest = kTests[index];
+ SpecialPowers.pushPrefEnv({"set": [
+ ["mousewheel.default.action", kTest.action],
+ ["mousewheel.default.action.override_x", kTest.override_x]]},
+ doIt2
+ );
+ }
+
+ function doIt2()
+ {
+ const kTest = kTests[index];
+ description = "doTestActionOverride(action=" + kTest.action + ", " +
+ "override_x=" + kTest.override_x + ", " +
+ "deltaX=" + kTest.event.deltaX + ", " +
+ "deltaY=" + kTest.event.deltaY + "): ";
+ gScrollableElement.scrollTop = 1000;
+ gScrollableElement.scrollLeft = 1000;
+ sendWheelAndWait(10, 10, kTest.event, function () {
+ if (kTest.expected & kScrollUp) {
+ ok(gScrollableElement.scrollTop < 1000, description + "not scrolled up, got " + gScrollableElement.scrollTop);
+ } else if (kTest.expected & kScrollDown) {
+ ok(gScrollableElement.scrollTop > 1000, description + "not scrolled down, got " + gScrollableElement.scrollTop);
+ } else {
+ is(gScrollableElement.scrollTop, 1000, description + "scrolled vertical");
+ }
+ if (kTest.expected & kScrollLeft) {
+ ok(gScrollableElement.scrollLeft < 1000, description + "not scrolled to left, got " + gScrollableElement.scrollLeft);
+ } else if (kTest.expected & kScrollRight) {
+ ok(gScrollableElement.scrollLeft > 1000, description + "not scrolled to right, got " + gScrollableElement.scrollLeft);
+ } else {
+ is(gScrollableElement.scrollLeft, 1000, description + "scrolled horizontal");
+ }
+ if (++index == kTests.length) {
+ SimpleTest.executeSoon(aCallback);
+ } else {
+ doIt();
+ }
+ });
+ }
+ doIt();
+}
+
+function runTests()
+{
+ SpecialPowers.pushPrefEnv({"set": [
+ ["test.events.async.enabled", true],
+ ["general.smoothScroll", false],
+ ["mousewheel.default.action", 1], // scroll
+ ["mousewheel.default.action.override_x", -1],
+ ["mousewheel.with_shift.action", 2], // history
+ ["mousewheel.with_shift.action.override_x", -1],
+ ["mousewheel.with_control.action", 3], // zoom
+ ["mousewheel.with_control.action.override_x", -1]]},
+ runTests2);
+}
+
+function runTests2()
+{
+ const kSettings = [
+ { description: "all delta values are not customized",
+ deltaMultiplierX: 1.0, deltaMultiplierY: 1.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaX is reverted",
+ deltaMultiplierX: -1.0, deltaMultiplierY: 1.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaY is reverted",
+ deltaMultiplierX: 1.0, deltaMultiplierY: -1.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaZ is reverted",
+ deltaMultiplierX: 1.0, deltaMultiplierY: 1.0, deltaMultiplierZ: -1.0 },
+ { description: "deltaX is 2.0",
+ deltaMultiplierX: 2.0, deltaMultiplierY: 1.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaY is 2.0",
+ deltaMultiplierX: 1.0, deltaMultiplierY: 2.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaZ is 2.0",
+ deltaMultiplierX: 1.0, deltaMultiplierY: 1.0, deltaMultiplierZ: 2.0 },
+ { description: "deltaX is -2.0",
+ deltaMultiplierX: -2.0, deltaMultiplierY: 1.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaY is -2.0",
+ deltaMultiplierX: 1.0, deltaMultiplierY: -2.0, deltaMultiplierZ: 1.0 },
+ { description: "deltaZ is -2.0",
+ deltaMultiplierX: 1.0, deltaMultiplierY: 1.0, deltaMultiplierZ: -2.0 },
+ ];
+
+ var index = 0;
+
+ function doTest() {
+ setDeltaMultiplierSettings(kSettings[index], function () {
+ doTestScroll(kSettings[index], function () {
+ doTestZoom(kSettings[index], function() {
+ if (++index == kSettings.length) {
+ setDeltaMultiplierSettings(kSettings[0], function() {
+ doTestZoomedScroll(function() {
+ doTestWholeScroll(function() {
+ doTestActionOverride(function() {
+ finishTests();
+ });
+ });
+ });
+ });
+ } else {
+ doTest();
+ }
+ });
+ });
+ });
+ }
+ doTest();
+}
+
+function finishTests()
+{
+ winUtils.restoreNormalRefresh();
+
+ window.opener.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>