Tests: Import a bunch of WPT tests from /dom/events

This commit is contained in:
Andreas Kling 2024-11-17 11:29:31 +01:00 committed by Andreas Kling
parent 0339ece565
commit aa9ed71ff3
Notes: github-actions[bot] 2024-11-17 13:57:32 +00:00
125 changed files with 6002 additions and 0 deletions

View file

@ -0,0 +1,58 @@
Summary
Harness status: OK
Rerun
Found 48 tests
48 Pass
Details
Result Test Name MessagePass Set HTMLBodyElement.onblur
Pass Enumerate HTMLBodyElement.onblur
Pass Reflect HTMLBodyElement.onblur
Pass Forward HTMLBodyElement.onblur to Window
Pass Set HTMLFrameSetElement.onblur
Pass Enumerate HTMLFrameSetElement.onblur
Pass Reflect HTMLFrameSetElement.onblur
Pass Forward HTMLFrameSetElement.onblur to Window
Pass Set HTMLBodyElement.onerror
Pass Enumerate HTMLBodyElement.onerror
Pass Reflect HTMLBodyElement.onerror
Pass Forward HTMLBodyElement.onerror to Window
Pass Set HTMLFrameSetElement.onerror
Pass Enumerate HTMLFrameSetElement.onerror
Pass Reflect HTMLFrameSetElement.onerror
Pass Forward HTMLFrameSetElement.onerror to Window
Pass Set HTMLBodyElement.onfocus
Pass Enumerate HTMLBodyElement.onfocus
Pass Reflect HTMLBodyElement.onfocus
Pass Forward HTMLBodyElement.onfocus to Window
Pass Set HTMLFrameSetElement.onfocus
Pass Enumerate HTMLFrameSetElement.onfocus
Pass Reflect HTMLFrameSetElement.onfocus
Pass Forward HTMLFrameSetElement.onfocus to Window
Pass Set HTMLBodyElement.onload
Pass Enumerate HTMLBodyElement.onload
Pass Reflect HTMLBodyElement.onload
Pass Forward HTMLBodyElement.onload to Window
Pass Set HTMLFrameSetElement.onload
Pass Enumerate HTMLFrameSetElement.onload
Pass Reflect HTMLFrameSetElement.onload
Pass Forward HTMLFrameSetElement.onload to Window
Pass Set HTMLBodyElement.onscroll
Pass Enumerate HTMLBodyElement.onscroll
Pass Reflect HTMLBodyElement.onscroll
Pass Forward HTMLBodyElement.onscroll to Window
Pass Set HTMLFrameSetElement.onscroll
Pass Enumerate HTMLFrameSetElement.onscroll
Pass Reflect HTMLFrameSetElement.onscroll
Pass Forward HTMLFrameSetElement.onscroll to Window
Pass Set HTMLBodyElement.onresize
Pass Enumerate HTMLBodyElement.onresize
Pass Reflect HTMLBodyElement.onresize
Pass Forward HTMLBodyElement.onresize to Window
Pass Set HTMLFrameSetElement.onresize
Pass Enumerate HTMLFrameSetElement.onresize
Pass Reflect HTMLFrameSetElement.onresize
Pass Forward HTMLFrameSetElement.onresize to Window

View file

@ -0,0 +1,13 @@
Summary
Harness status: OK
Rerun
Found 3 tests
3 Pass
Details
Result Test Name MessagePass CustomEvent dispatching.
Pass First parameter to initCustomEvent should be mandatory.
Pass initCustomEvent's default parameter values.

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 8 tests
8 Pass
Details
Result Test Name MessagePass cancelBubble must be false when an event is initially created.
Pass Initializing an event must set cancelBubble to false.
Pass stopPropagation() must set cancelBubble to true.
Pass stopImmediatePropagation() must set cancelBubble to true.
Pass Event.cancelBubble=false must have no effect.
Pass Event.cancelBubble=false must have no effect during event propagation.
Pass cancelBubble must be false after an event has been dispatched.
Pass Event.cancelBubble=true must set the stop propagation flag.

View file

@ -0,0 +1,10 @@
Summary
Harness status: Error
Rerun
Found tests
Details
Result Test Name Message

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass Default prevention via preventDefault
Pass Default prevention via returnValue

View file

@ -0,0 +1,18 @@
Summary
Harness status: OK
Rerun
Found 8 tests
8 Pass
Details
Result Test Name MessagePass When an event is created, defaultPrevented should be initialized to false.
Pass initEvent should work correctly (not cancelable).
Pass preventDefault() should not change defaultPrevented if cancelable is false.
Pass returnValue should not change defaultPrevented if cancelable is false.
Pass initEvent should work correctly (cancelable).
Pass preventDefault() should change defaultPrevented if cancelable is true.
Pass returnValue should change defaultPrevented if cancelable is true.
Pass initEvent should unset defaultPrevented.

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Setting cancelBubble=true prior to dispatchEvent()

View file

@ -0,0 +1,16 @@
Summary
Harness status: OK
Rerun
Found 5 tests
4 Pass
1 Fail
Details
Result Test Name MessageFail In window.document with click event
Pass In window.document with load event
Pass In window.document.cloneNode(true)
Pass In new Document()
Pass In DOMImplementation.createHTMLDocument()

View file

@ -0,0 +1,16 @@
Summary
Harness status: OK
Rerun
Found 5 tests
4 Pass
1 Fail
Details
Result Test Name MessageFail In window.document with click event
Pass In window.document with load event
Pass In window.document.cloneNode(true)
Pass In new Document()
Pass In DOMImplementation.createHTMLDocument()

View file

@ -0,0 +1,17 @@
Summary
Harness status: OK
Rerun
Found 6 tests
4 Pass
2 Fail
Details
Result Test Name MessagePass disabled checkbox should not be checked from label click
Pass disabled radio should not be checked from label click
Pass disabled checkbox should not be checked from label click by dispatchEvent
Pass disabled radio should not be checked from label click by dispatchEvent
Fail checkbox morphed into another type should not mutate checked state
Fail radio morphed into another type should not steal the existing checked state

View file

@ -0,0 +1,44 @@
Summary
Harness status: OK
Rerun
Found 33 tests
30 Pass
3 Fail
Details
Result Test Name MessagePass basic with click()
Pass basic with dispatchEvent()
Pass basic with wrong event class
Pass look at parents only when event bubbles
Pass look at parents when event bubbles
Pass pick the first with activation behavior <input type=checkbox>
Pass pick the first with activation behavior <a href>
Pass pick the first with activation behavior <input type=radio>
Pass event state during post-click handling
Pass redispatch during post-click handling
Pass disabled checkbox still has activation behavior
Pass disabled checkbox still has activation behavior, part 2
Pass disabled radio still has activation behavior
Pass disconnected checkbox should be checked
Pass disconnected radio should be checked
Pass disconnected checkbox should be checked from dispatchEvent(new MouseEvent('click'))
Pass disconnected radio should be checked from dispatchEvent(new MouseEvent('click'))
Pass disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))
Pass disabled radio should be checked from dispatchEvent(new MouseEvent("click"))
Pass disabled checkbox should fire onclick
Pass disabled radio should fire onclick
Pass disabled checkbox should get legacy-canceled-activation behavior
Pass disabled radio should get legacy-canceled-activation behavior
Pass disabled checkbox should get legacy-canceled-activation behavior 2
Pass disabled radio should get legacy-canceled-activation behavior 2
Pass disabling checkbox in onclick listener shouldn't suppress oninput
Pass disabling checkbox in onclick listener shouldn't suppress onchange
Pass disabling radio in onclick listener shouldn't suppress oninput
Pass disabling radio in onclick listener shouldn't suppress onchange
Pass disconnected form should not submit
Fail disabled submit button should not activate
Fail submit button should not activate if the event listener disables it
Fail submit button that morphed from checkbox should not activate

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass Click event on an element not in the document
Pass Click event can be dispatched to an element that is not in the document.

View file

@ -0,0 +1,22 @@
Summary
Harness status: OK
Rerun
Found 12 tests
12 Pass
Details
Result Test Name MessagePass detached checkbox should not emit input or change events on click().
Pass detached radio should not emit input or change events on click().
Pass detached checkbox should not emit input or change events on dispatchEvent(new MouseEvent('click')).
Pass detached radio should not emit input or change events on dispatchEvent(new MouseEvent('click')).
Pass attached checkbox should emit input and change events on click().
Pass attached radio should emit input and change events on click().
Pass attached checkbox should emit input and change events on dispatchEvent(new MouseEvent('click')).
Pass attached radio should emit input and change events on dispatchEvent(new MouseEvent('click')).
Pass attached to shadow dom checkbox should emit input and change events on click().
Pass attached to shadow dom radio should emit input and change events on click().
Pass attached to shadow dom checkbox should emit input and change events on dispatchEvent(new MouseEvent('click')).
Pass attached to shadow dom radio should emit input and change events on dispatchEvent(new MouseEvent('click')).

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Dispatch additional events inside an event listener

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Multiple dispatchEvent() and cancelBubble

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Multiple dispatchEvent() and stopPropagation()

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail EventTarget.addEventListener with the capture argument omitted

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Listeners are invoked in correct order (AT_TARGET phase)

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Event phases order

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Custom event on an element in another document

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Calling stopPropagation() prior to dispatchEvent()

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Dispatch additional events inside an event listener

View file

@ -0,0 +1,143 @@
Summary
Harness status: OK
Rerun
Found 132 tests
103 Pass
29 Fail
Details
Result Test Name MessagePass When clicking child <INPUT type=checkbox></INPUT> of parent <INPUT type=radio></INPUT>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <A></A>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <INPUT type=checkbox></INPUT> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <A></A>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <INPUT type=radio></INPUT> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.
Fail When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Fail When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <A></A>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <FORM><INPUT type=submit></INPUT></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.
Fail When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Fail When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <A></A>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <FORM><INPUT type=image></INPUT></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Fail When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <A></A>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <FORM><INPUT type=reset></INPUT></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.
Fail When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Fail When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <A></A>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=submit></BUTTON></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <INPUT type=radio></INPUT>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Fail When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <A></A>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <FORM><BUTTON type=reset></BUTTON></FORM> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <A></A> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <A></A> of parent <INPUT type=radio></INPUT>, only child should be activated.
Pass When clicking child <A></A> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <A></A> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <A></A> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <A></A> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <A></A> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <A></A> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <A></A> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <A></A> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <A></A> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <INPUT type=radio></INPUT>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <AREA></AREA> of parent <A></A>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Fail When clicking child <AREA></AREA> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <INPUT type=radio></INPUT>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <A></A>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.
Pass When clicking child <DETAILS><SUMMARY></SUMMARY></DETAILS> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <INPUT type=radio></INPUT>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <A></A>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <AREA></AREA>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Fail When clicking child <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL> of parent <LABEL><BUTTON type=button></BUTTON></LABEL>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <INPUT type=checkbox></INPUT>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <INPUT type=radio></INPUT>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <FORM><INPUT type=submit></INPUT></FORM>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <FORM><INPUT type=image></INPUT></FORM>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <FORM><INPUT type=reset></INPUT></FORM>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <FORM><BUTTON type=submit></BUTTON></FORM>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <FORM><BUTTON type=reset></BUTTON></FORM>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <A></A>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <AREA></AREA>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <DETAILS><SUMMARY></SUMMARY></DETAILS>, only child should be activated.
Pass When clicking child <LABEL><BUTTON type=button></BUTTON></LABEL> of parent <LABEL><INPUT type=checkbox></INPUT><SPAN></SPAN></LABEL>, only child should be activated.

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Event propagation path when an element in it is moved within the DOM

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Event propagation path when an element in it is removed from the DOM

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Fail
Details
Result Test Name MessageFail exception thrown in event listener function should result in error event on listener's global
Fail exception thrown in event listener interface object should result in error event on listener's global

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass Throwing in event listener with a single listeners
Pass Throwing in event listener with multiple listeners

View file

@ -0,0 +1,16 @@
Summary
Harness status: OK
Rerun
Found 5 tests
4 Pass
1 Fail
Details
Result Test Name MessagePass Calling initKeyboardEvent while dispatching.
Pass Calling initMouseEvent while dispatching.
Pass Calling initCustomEvent while dispatching.
Fail Calling initUIEvent while dispatching. Not an object of type Window
Pass Calling initEvent while dispatching.

View file

@ -0,0 +1,22 @@
Summary
Harness status: OK
Rerun
Found 12 tests
12 Pass
Details
Result Test Name MessagePass Properties of initEvent(type, true, true)
Pass Properties of initEvent(type, true, false)
Pass Properties of initEvent(type, false, true)
Pass Properties of initEvent(type, false, false)
Pass Calling initEvent multiple times (getting type).
Pass Calling initEvent multiple times (not getting type).
Pass Calling initEvent must not have an effect during dispatching.
Pass Calling initEvent must unset the stop propagation flag.
Pass Calling initEvent must unset the stop immediate propagation flag.
Pass Calling initEvent during propagation.
Pass First parameter to initEvent should be mandatory.
Pass Tests initEvent's default parameter values.

View file

@ -0,0 +1,17 @@
Summary
Harness status: OK
Rerun
Found 7 tests
7 Pass
Details
Result Test Name MessagePass Newly-created Event
Pass After stopPropagation()
Pass Reinitialized after stopPropagation()
Pass After stopImmediatePropagation()
Pass Reinitialized after stopImmediatePropagation()
Pass After cancelBubble=true
Pass Reinitialized after cancelBubble=true

View file

@ -0,0 +1,17 @@
Summary
Harness status: OK
Rerun
Found 7 tests
7 Pass
Details
Result Test Name MessagePass When an event is created, returnValue should be initialized to true.
Pass preventDefault() should not change returnValue if cancelable is false.
Pass returnValue=false should have no effect if cancelable is false.
Pass preventDefault() should change returnValue if cancelable is true.
Pass returnValue should change returnValue if cancelable is true.
Pass initEvent should unset returnValue.
Pass returnValue=true should have no effect once the canceled flag was set.

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Event's stopImmediatePropagation

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass Event-stopPropagation-cancel-bubbling

View file

@ -0,0 +1,60 @@
Summary
Harness status: OK
Rerun
Found 49 tests
43 Pass
6 Fail
Details
Result Test Name MessagePass Event constructor (no argument)
Pass Event constructor (undefined argument)
Pass Event constructor (null argument)
Pass Event constructor (empty argument)
Pass Event constructor (argument with default values)
Pass Event constructor (argument with non-default values)
Pass UIEvent constructor (no argument)
Pass UIEvent constructor (undefined argument)
Pass UIEvent constructor (null argument)
Pass UIEvent constructor (empty argument)
Pass UIEvent constructor (argument with default values)
Fail UIEvent constructor (argument with non-default values) Not an object of type Window
Pass FocusEvent constructor (no argument)
Pass FocusEvent constructor (undefined argument)
Pass FocusEvent constructor (null argument)
Pass FocusEvent constructor (empty argument)
Pass FocusEvent constructor (argument with default values)
Fail FocusEvent constructor (argument with non-default values) Not an object of type Window
Pass MouseEvent constructor (no argument)
Pass MouseEvent constructor (undefined argument)
Pass MouseEvent constructor (null argument)
Pass MouseEvent constructor (empty argument)
Pass MouseEvent constructor (argument with default values)
Fail MouseEvent constructor (argument with non-default values) Not an object of type Window
Pass WheelEvent constructor (no argument)
Pass WheelEvent constructor (undefined argument)
Pass WheelEvent constructor (null argument)
Pass WheelEvent constructor (empty argument)
Pass WheelEvent constructor (argument with default values)
Fail WheelEvent constructor (argument with non-default values) Not an object of type Window
Pass KeyboardEvent constructor (no argument)
Pass KeyboardEvent constructor (undefined argument)
Pass KeyboardEvent constructor (null argument)
Pass KeyboardEvent constructor (empty argument)
Pass KeyboardEvent constructor (argument with default values)
Fail KeyboardEvent constructor (argument with non-default values) Not an object of type Window
Pass CompositionEvent constructor (no argument)
Pass CompositionEvent constructor (undefined argument)
Pass CompositionEvent constructor (null argument)
Pass CompositionEvent constructor (empty argument)
Pass CompositionEvent constructor (argument with default values)
Fail CompositionEvent constructor (argument with non-default values) Not an object of type Window
Pass SubclassedEvent constructor (no argument)
Pass SubclassedEvent constructor (undefined argument)
Pass SubclassedEvent constructor (null argument)
Pass SubclassedEvent constructor (empty argument)
Pass SubclassedEvent constructor (argument with default values)
Pass SubclassedEvent constructor (argument with non-default values)
Pass UIEvent constructor (view argument with wrong type)

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass event.timeStamp is initialized using event's relevant global object

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Constructed GamepadEvent timestamp should be high resolution and have the same time origin as performance.now() undefined is not a constructor (evaluated from 'window[<computed>]')

View file

@ -0,0 +1,14 @@
Summary
Harness status: OK
Rerun
Found 4 tests
4 Pass
Details
Result Test Name MessagePass Constructed MouseEvent timestamp should be high resolution and have the same time origin as performance.now()
Pass Constructed KeyboardEvent timestamp should be high resolution and have the same time origin as performance.now()
Pass Constructed WheelEvent timestamp should be high resolution and have the same time origin as performance.now()
Pass Constructed FocusEvent timestamp should be high resolution and have the same time origin as performance.now()

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail Event timestamp should not have a resolution better than 5 microseconds

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass initEvent
Pass Constructor

View file

@ -0,0 +1,13 @@
Summary
Harness status: OK
Rerun
Found 3 tests
3 Pass
Details
Result Test Name MessagePass Event.type should initially be the empty string
Pass Event.type should be initialized by initEvent
Pass Event.type should be initialized by the constructor

View file

@ -0,0 +1,16 @@
Summary
Harness status: OK
Rerun
Found 6 tests
6 Pass
Details
Result Test Name MessagePass calls `handleEvent` method of `EventListener`
Pass performs `Get` every time event is dispatched
Pass doesn't call `handleEvent` method on callable `EventListener`
Pass rethrows errors when getting `handleEvent`
Pass throws if `handleEvent` is falsy and not callable
Pass throws if `handleEvent` is thruthy and not callable

View file

@ -0,0 +1,14 @@
Summary
Harness status: OK
Rerun
Found 4 tests
4 Pass
Details
Result Test Name MessagePass Capture boolean should be honored correctly
Pass Capture option should be honored correctly
Pass Supports capture option
Pass Equivalence of option values

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass addEventListener with a platform object

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Pass
Details
Result Test Name MessagePass Return value of EventTarget.dispatchEvent() affected by preventDefault().
Pass Return value of EventTarget.dispatchEvent() affected by returnValue.

View file

@ -0,0 +1,35 @@
Summary
Harness status: OK
Rerun
Found 25 tests
25 Pass
Details
Result Test Name MessagePass Calling dispatchEvent(null).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (BeforeUnloadEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (CompositionEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (CustomEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (DeviceMotionEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (DeviceOrientationEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (DragEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (Event).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (Events).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (FocusEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (HashChangeEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (HTMLEvents).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (KeyboardEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (MessageEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (MouseEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (MouseEvents).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (StorageEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (SVGEvents).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (TextEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (UIEvent).
Pass If the event's initialized flag is not set, an InvalidStateError must be thrown (UIEvents).
Pass If the event's dispatch flag is set, an InvalidStateError must be thrown.
Pass Exceptions from event listeners must not be propagated.
Pass Event listeners added during dispatch should be called
Pass Capturing event listeners should be called before non-capturing ones

View file

@ -0,0 +1,16 @@
Summary
Harness status: OK
Rerun
Found 6 tests
6 Pass
Details
Result Test Name MessagePass the this value inside the event listener callback should be the node
Pass the this value inside the event listener object handleEvent should be the object
Pass dispatchEvent should invoke the current handleEvent method of the object
Pass addEventListener should not require handleEvent to be defined on object listeners
Pass handleEvent properties added to a function before addEventListener are not reached
Pass handleEvent properties added to a function after addEventListener are not reached

View file

@ -0,0 +1,13 @@
Summary
Harness status: OK
Rerun
Found 3 tests
3 Pass
Details
Result Test Name MessagePass KeyboardEvent.initKeyEvent shouldn't be defined (created by createEvent("KeyboardEvent")
Pass KeyboardEvent.initKeyEvent shouldn't be defined (created by constructor)
Pass KeyboardEvent.prototype.initKeyEvent shouldn't be defined

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass disabled is honored properly in presence of dynamic changes

View file

@ -0,0 +1,19 @@
Summary
Harness status: OK
Rerun
Found 8 tests
7 Pass
1 Fail
Details
Result Test Name MessagePass event exists on window, which is initially set to undefined
Pass window.event is only defined during dispatch
Pass window.event is undefined if the target is in a shadow tree (event dispatched outside shadow tree)
Pass window.event is undefined if the target is in a shadow tree (event dispatched inside shadow tree)
Fail window.event is undefined inside window.onerror if the target is in a shadow tree (ErrorEvent dispatched inside shadow tree)
Pass window.event is set to the current event during dispatch
Pass window.event is set to the current event, which is the event passed to dispatch
Pass window.event is set to the current event, which is the event passed to dispatch (2)

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Fail
Details
Result Test Name MessageFail offsetX is correctly adjusted

View file

@ -0,0 +1,111 @@
Summary
Harness status: OK
Rerun
Found 100 tests
68 Pass
32 Fail
Details
Result Test Name MessageFail touchstart listener is passive by default for Window
Fail touchstart listener is passive with {passive:undefined} for Window
Pass touchstart listener is non-passive with {passive:false} for Window
Pass touchstart listener is passive with {passive:true} for Window
Fail touchstart listener is passive by default for HTMLDocument
Fail touchstart listener is passive with {passive:undefined} for HTMLDocument
Pass touchstart listener is non-passive with {passive:false} for HTMLDocument
Pass touchstart listener is passive with {passive:true} for HTMLDocument
Fail touchstart listener is passive by default for HTMLHtmlElement
Fail touchstart listener is passive with {passive:undefined} for HTMLHtmlElement
Pass touchstart listener is non-passive with {passive:false} for HTMLHtmlElement
Pass touchstart listener is passive with {passive:true} for HTMLHtmlElement
Fail touchstart listener is passive by default for HTMLBodyElement
Fail touchstart listener is passive with {passive:undefined} for HTMLBodyElement
Pass touchstart listener is non-passive with {passive:false} for HTMLBodyElement
Pass touchstart listener is passive with {passive:true} for HTMLBodyElement
Pass touchstart listener is non-passive by default for HTMLDivElement
Pass touchstart listener is non-passive with {passive:undefined} for HTMLDivElement
Pass touchstart listener is non-passive with {passive:false} for HTMLDivElement
Pass touchstart listener is passive with {passive:true} for HTMLDivElement
Fail touchmove listener is passive by default for Window
Fail touchmove listener is passive with {passive:undefined} for Window
Pass touchmove listener is non-passive with {passive:false} for Window
Pass touchmove listener is passive with {passive:true} for Window
Fail touchmove listener is passive by default for HTMLDocument
Fail touchmove listener is passive with {passive:undefined} for HTMLDocument
Pass touchmove listener is non-passive with {passive:false} for HTMLDocument
Pass touchmove listener is passive with {passive:true} for HTMLDocument
Fail touchmove listener is passive by default for HTMLHtmlElement
Fail touchmove listener is passive with {passive:undefined} for HTMLHtmlElement
Pass touchmove listener is non-passive with {passive:false} for HTMLHtmlElement
Pass touchmove listener is passive with {passive:true} for HTMLHtmlElement
Fail touchmove listener is passive by default for HTMLBodyElement
Fail touchmove listener is passive with {passive:undefined} for HTMLBodyElement
Pass touchmove listener is non-passive with {passive:false} for HTMLBodyElement
Pass touchmove listener is passive with {passive:true} for HTMLBodyElement
Pass touchmove listener is non-passive by default for HTMLDivElement
Pass touchmove listener is non-passive with {passive:undefined} for HTMLDivElement
Pass touchmove listener is non-passive with {passive:false} for HTMLDivElement
Pass touchmove listener is passive with {passive:true} for HTMLDivElement
Fail wheel listener is passive by default for Window
Fail wheel listener is passive with {passive:undefined} for Window
Pass wheel listener is non-passive with {passive:false} for Window
Pass wheel listener is passive with {passive:true} for Window
Fail wheel listener is passive by default for HTMLDocument
Fail wheel listener is passive with {passive:undefined} for HTMLDocument
Pass wheel listener is non-passive with {passive:false} for HTMLDocument
Pass wheel listener is passive with {passive:true} for HTMLDocument
Fail wheel listener is passive by default for HTMLHtmlElement
Fail wheel listener is passive with {passive:undefined} for HTMLHtmlElement
Pass wheel listener is non-passive with {passive:false} for HTMLHtmlElement
Pass wheel listener is passive with {passive:true} for HTMLHtmlElement
Fail wheel listener is passive by default for HTMLBodyElement
Fail wheel listener is passive with {passive:undefined} for HTMLBodyElement
Pass wheel listener is non-passive with {passive:false} for HTMLBodyElement
Pass wheel listener is passive with {passive:true} for HTMLBodyElement
Pass wheel listener is non-passive by default for HTMLDivElement
Pass wheel listener is non-passive with {passive:undefined} for HTMLDivElement
Pass wheel listener is non-passive with {passive:false} for HTMLDivElement
Pass wheel listener is passive with {passive:true} for HTMLDivElement
Fail mousewheel listener is passive by default for Window
Fail mousewheel listener is passive with {passive:undefined} for Window
Pass mousewheel listener is non-passive with {passive:false} for Window
Pass mousewheel listener is passive with {passive:true} for Window
Fail mousewheel listener is passive by default for HTMLDocument
Fail mousewheel listener is passive with {passive:undefined} for HTMLDocument
Pass mousewheel listener is non-passive with {passive:false} for HTMLDocument
Pass mousewheel listener is passive with {passive:true} for HTMLDocument
Fail mousewheel listener is passive by default for HTMLHtmlElement
Fail mousewheel listener is passive with {passive:undefined} for HTMLHtmlElement
Pass mousewheel listener is non-passive with {passive:false} for HTMLHtmlElement
Pass mousewheel listener is passive with {passive:true} for HTMLHtmlElement
Fail mousewheel listener is passive by default for HTMLBodyElement
Fail mousewheel listener is passive with {passive:undefined} for HTMLBodyElement
Pass mousewheel listener is non-passive with {passive:false} for HTMLBodyElement
Pass mousewheel listener is passive with {passive:true} for HTMLBodyElement
Pass mousewheel listener is non-passive by default for HTMLDivElement
Pass mousewheel listener is non-passive with {passive:undefined} for HTMLDivElement
Pass mousewheel listener is non-passive with {passive:false} for HTMLDivElement
Pass mousewheel listener is passive with {passive:true} for HTMLDivElement
Pass touchend listener is non-passive by default for Window
Pass touchend listener is non-passive with {passive:undefined} for Window
Pass touchend listener is non-passive with {passive:false} for Window
Pass touchend listener is passive with {passive:true} for Window
Pass touchend listener is non-passive by default for HTMLDocument
Pass touchend listener is non-passive with {passive:undefined} for HTMLDocument
Pass touchend listener is non-passive with {passive:false} for HTMLDocument
Pass touchend listener is passive with {passive:true} for HTMLDocument
Pass touchend listener is non-passive by default for HTMLHtmlElement
Pass touchend listener is non-passive with {passive:undefined} for HTMLHtmlElement
Pass touchend listener is non-passive with {passive:false} for HTMLHtmlElement
Pass touchend listener is passive with {passive:true} for HTMLHtmlElement
Pass touchend listener is non-passive by default for HTMLBodyElement
Pass touchend listener is non-passive with {passive:undefined} for HTMLBodyElement
Pass touchend listener is non-passive with {passive:false} for HTMLBodyElement
Pass touchend listener is passive with {passive:true} for HTMLBodyElement
Pass touchend listener is non-passive by default for HTMLDivElement
Pass touchend listener is non-passive with {passive:undefined} for HTMLDivElement
Pass touchend listener is non-passive with {passive:false} for HTMLDivElement
Pass touchend listener is passive with {passive:true} for HTMLDivElement

View file

@ -0,0 +1,11 @@
Summary
Harness status: OK
Rerun
Found 1 tests
1 Pass
Details
Result Test Name MessagePass behavior of preventDefault during activation behavior

View file

@ -0,0 +1,13 @@
Summary
Harness status: OK
Rerun
Found 2 tests
1 Pass
1 Fail
Details
Result Test Name MessagePass Removing all listeners and then adding a new one should work.
Fail Nested usage of once listeners should work.

View file

@ -0,0 +1,12 @@
Summary
Harness status: OK
Rerun
Found 2 tests
2 Fail
Details
Result Test Name MessageFail relatedTarget should not leak at capturing phase, at window object.
Fail relatedTarget should not leak at target.

View file

@ -0,0 +1,96 @@
// META: title=AddEventListenerOptions.once
"use strict";
test(function() {
var invoked_once = false;
var invoked_normal = false;
function handler_once() {
invoked_once = true;
}
function handler_normal() {
invoked_normal = true;
}
const et = new EventTarget();
et.addEventListener('test', handler_once, {once: true});
et.addEventListener('test', handler_normal);
et.dispatchEvent(new Event('test'));
assert_equals(invoked_once, true, "Once handler should be invoked");
assert_equals(invoked_normal, true, "Normal handler should be invoked");
invoked_once = false;
invoked_normal = false;
et.dispatchEvent(new Event('test'));
assert_equals(invoked_once, false, "Once handler shouldn't be invoked again");
assert_equals(invoked_normal, true, "Normal handler should be invoked again");
et.removeEventListener('test', handler_normal);
}, "Once listener should be invoked only once");
test(function() {
const et = new EventTarget();
var invoked_count = 0;
function handler() {
invoked_count++;
if (invoked_count == 1)
et.dispatchEvent(new Event('test'));
}
et.addEventListener('test', handler, {once: true});
et.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 1, "Once handler should only be invoked once");
invoked_count = 0;
function handler2() {
invoked_count++;
if (invoked_count == 1)
et.addEventListener('test', handler2, {once: true});
if (invoked_count <= 2)
et.dispatchEvent(new Event('test'));
}
et.addEventListener('test', handler2, {once: true});
et.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 2, "Once handler should only be invoked once after each adding");
}, "Once listener should be invoked only once even if the event is nested");
test(function() {
var invoked_count = 0;
function handler() {
invoked_count++;
}
const et = new EventTarget();
et.addEventListener('test', handler, {once: true});
et.addEventListener('test', handler);
et.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 1, "The handler should only be added once");
invoked_count = 0;
et.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 0, "The handler was added as a once listener");
invoked_count = 0;
et.addEventListener('test', handler, {once: true});
et.removeEventListener('test', handler);
et.dispatchEvent(new Event('test'));
assert_equals(invoked_count, 0, "The handler should have been removed");
}, "Once listener should be added / removed like normal listeners");
test(function() {
const et = new EventTarget();
var invoked_count = 0;
for (let n = 4; n > 0; n--) {
et.addEventListener('test', (e) => {
invoked_count++;
e.stopImmediatePropagation();
}, {once: true});
}
for (let n = 4; n > 0; n--) {
et.dispatchEvent(new Event('test'));
}
assert_equals(invoked_count, 4, "The listeners should be invoked");
}, "Multiple once listeners should be invoked even if the stopImmediatePropagation is set");

View file

@ -0,0 +1,134 @@
// META: title=AddEventListenerOptions.passive
test(function() {
var supportsPassive = false;
var query_options = {
get passive() {
supportsPassive = true;
return false;
},
get dummy() {
assert_unreached("dummy value getter invoked");
return false;
}
};
const et = new EventTarget();
et.addEventListener('test_event', null, query_options);
assert_true(supportsPassive, "addEventListener doesn't support the passive option");
supportsPassive = false;
et.removeEventListener('test_event', null, query_options);
assert_false(supportsPassive, "removeEventListener supports the passive option when it should not");
}, "Supports passive option on addEventListener only");
function testPassiveValue(optionsValue, expectedDefaultPrevented, existingEventTarget) {
var defaultPrevented = undefined;
var handler = function handler(e) {
assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented");
e.preventDefault();
defaultPrevented = e.defaultPrevented;
}
const et = existingEventTarget || new EventTarget();
et.addEventListener('test', handler, optionsValue);
var uncanceled = et.dispatchEvent(new Event('test', {bubbles: true, cancelable: true}));
assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue));
assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent");
et.removeEventListener('test', handler, optionsValue);
}
test(function() {
testPassiveValue(undefined, true);
testPassiveValue({}, true);
testPassiveValue({passive: false}, true);
testPassiveValue({passive: true}, false);
testPassiveValue({passive: 0}, true);
testPassiveValue({passive: 1}, false);
}, "preventDefault should be ignored if-and-only-if the passive option is true");
function testPassiveValueOnReturnValue(test, optionsValue, expectedDefaultPrevented) {
var defaultPrevented = undefined;
var handler = test.step_func(e => {
assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented");
e.returnValue = false;
defaultPrevented = e.defaultPrevented;
});
const et = new EventTarget();
et.addEventListener('test', handler, optionsValue);
var uncanceled = et.dispatchEvent(new Event('test', {bubbles: true, cancelable: true}));
assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue));
assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent");
et.removeEventListener('test', handler, optionsValue);
}
async_test(t => {
testPassiveValueOnReturnValue(t, undefined, true);
testPassiveValueOnReturnValue(t, {}, true);
testPassiveValueOnReturnValue(t, {passive: false}, true);
testPassiveValueOnReturnValue(t, {passive: true}, false);
testPassiveValueOnReturnValue(t, {passive: 0}, true);
testPassiveValueOnReturnValue(t, {passive: 1}, false);
t.done();
}, "returnValue should be ignored if-and-only-if the passive option is true");
function testPassiveWithOtherHandlers(optionsValue, expectedDefaultPrevented) {
var handlerInvoked1 = false;
var dummyHandler1 = function() {
handlerInvoked1 = true;
};
var handlerInvoked2 = false;
var dummyHandler2 = function() {
handlerInvoked2 = true;
};
const et = new EventTarget();
et.addEventListener('test', dummyHandler1, {passive:true});
et.addEventListener('test', dummyHandler2);
testPassiveValue(optionsValue, expectedDefaultPrevented, et);
assert_true(handlerInvoked1, "Extra passive handler not invoked");
assert_true(handlerInvoked2, "Extra non-passive handler not invoked");
et.removeEventListener('test', dummyHandler1);
et.removeEventListener('test', dummyHandler2);
}
test(function() {
testPassiveWithOtherHandlers({}, true);
testPassiveWithOtherHandlers({passive: false}, true);
testPassiveWithOtherHandlers({passive: true}, false);
}, "passive behavior of one listener should be unaffected by the presence of other listeners");
function testOptionEquivalence(optionValue1, optionValue2, expectedEquality) {
var invocationCount = 0;
var handler = function handler(e) {
invocationCount++;
}
const et = new EventTarget();
et.addEventListener('test', handler, optionValue1);
et.addEventListener('test', handler, optionValue2);
et.dispatchEvent(new Event('test', {bubbles: true}));
assert_equals(invocationCount, expectedEquality ? 1 : 2, "equivalence of options " +
JSON.stringify(optionValue1) + " and " + JSON.stringify(optionValue2));
et.removeEventListener('test', handler, optionValue1);
et.removeEventListener('test', handler, optionValue2);
}
test(function() {
// Sanity check options that should be treated as distinct handlers
testOptionEquivalence({capture:true}, {capture:false, passive:false}, false);
testOptionEquivalence({capture:true}, {passive:true}, false);
// Option values that should be treated as equivalent
testOptionEquivalence({}, {passive:false}, true);
testOptionEquivalence({passive:true}, {passive:false}, true);
testOptionEquivalence(undefined, {passive:true}, true);
testOptionEquivalence({capture: true, passive: false}, {capture: true, passive: true}, true);
}, "Equivalence of option values");

View file

@ -0,0 +1,143 @@
'use strict';
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', handler, { signal: controller.signal });
et.dispatchEvent(new Event('test'));
assert_equals(count, 1, "Adding a signal still adds a listener");
et.dispatchEvent(new Event('test'));
assert_equals(count, 2, "The listener was not added with the once flag");
controller.abort();
et.dispatchEvent(new Event('test'));
assert_equals(count, 2, "Aborting on the controller removes the listener");
et.addEventListener('test', handler, { signal: controller.signal });
et.dispatchEvent(new Event('test'));
assert_equals(count, 2, "Passing an aborted signal never adds the handler");
}, "Passing an AbortSignal to addEventListener options should allow removing a listener");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', handler, { signal: controller.signal });
et.removeEventListener('test', handler);
et.dispatchEvent(new Event('test'));
assert_equals(count, 0, "The listener was still removed");
}, "Passing an AbortSignal to addEventListener does not prevent removeEventListener");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', handler, { signal: controller.signal, once: true });
controller.abort();
et.dispatchEvent(new Event('test'));
assert_equals(count, 0, "The listener was still removed");
}, "Passing an AbortSignal to addEventListener works with the once flag");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', handler, { signal: controller.signal, once: true });
et.removeEventListener('test', handler);
et.dispatchEvent(new Event('test'));
assert_equals(count, 0, "The listener was still removed");
}, "Removing a once listener works with a passed signal");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('first', handler, { signal: controller.signal, once: true });
et.addEventListener('second', handler, { signal: controller.signal, once: true });
controller.abort();
et.dispatchEvent(new Event('first'));
et.dispatchEvent(new Event('second'));
assert_equals(count, 0, "The listener was still removed");
}, "Passing an AbortSignal to multiple listeners");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', handler, { signal: controller.signal, capture: true });
controller.abort();
et.dispatchEvent(new Event('test'));
assert_equals(count, 0, "The listener was still removed");
}, "Passing an AbortSignal to addEventListener works with the capture flag");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', () => {
controller.abort();
}, { signal: controller.signal });
et.addEventListener('test', handler, { signal: controller.signal });
et.dispatchEvent(new Event('test'));
assert_equals(count, 0, "The listener was still removed");
}, "Aborting from a listener does not call future listeners");
test(function() {
let count = 0;
function handler() {
count++;
}
const et = new EventTarget();
const controller = new AbortController();
et.addEventListener('test', () => {
et.addEventListener('test', handler, { signal: controller.signal });
controller.abort();
}, { signal: controller.signal });
et.dispatchEvent(new Event('test'));
assert_equals(count, 0, "The listener was still removed");
}, "Adding then aborting a listener in another listener does not call it");
test(function() {
const et = new EventTarget();
const ac = new AbortController();
let count = 0;
et.addEventListener('foo', () => {
et.addEventListener('foo', () => {
count++;
if (count > 5) ac.abort();
et.dispatchEvent(new Event('foo'));
}, { signal: ac.signal });
et.dispatchEvent(new Event('foo'));
}, { once: true });
et.dispatchEvent(new Event('foo'));
}, "Aborting from a nested listener should remove it");
test(function() {
const et = new EventTarget();
assert_throws_js(TypeError, () => { et.addEventListener("foo", () => {}, { signal: null }); });
}, "Passing null as the signal should throw");
test(function() {
const et = new EventTarget();
assert_throws_js(TypeError, () => { et.addEventListener("foo", null, { signal: null }); });
}, "Passing null as the signal should throw (listener is also null)");

View file

@ -0,0 +1,123 @@
<!DOCTYPE html>
<html>
<title>HTMLBodyElement and HTMLFrameSetElement Event Handler Tests</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
function getObject(interface) {
switch(interface) {
case "Element":
var e = document.createElementNS("http://example.com/", "example");
assert_true(e instanceof Element);
assert_false(e instanceof HTMLElement);
assert_false(e instanceof SVGElement);
return e;
case "HTMLElement":
var e = document.createElement("html");
assert_true(e instanceof HTMLElement);
return e;
case "HTMLBodyElement":
var e = document.createElement("body");
assert_true(e instanceof HTMLBodyElement);
return e;
case "HTMLFormElement":
var e = document.createElement("form");
assert_true(e instanceof HTMLFormElement);
return e;
case "HTMLFrameSetElement":
var e = document.createElement("frameset");
assert_true(e instanceof HTMLFrameSetElement);
return e;
case "SVGElement":
var e = document.createElementNS("http://www.w3.org/2000/svg", "rect");
assert_true(e instanceof SVGElement);
return e;
case "Document":
assert_true(document instanceof Document);
return document;
case "Window":
assert_true(window instanceof Window);
return window;
}
assert_unreached();
}
function testSet(interface, attribute) {
test(function() {
var object = getObject(interface);
function nop() {}
assert_equals(object[attribute], null, "Initially null");
object[attribute] = nop;
assert_equals(object[attribute], nop, "Return same function");
object[attribute] = "";
assert_equals(object[attribute], null, "Return null after setting string");
object[attribute] = null;
assert_equals(object[attribute], null, "Finally null");
}, "Set " + interface + "." + attribute);
}
function testReflect(interface, attribute) {
test(function() {
var element = getObject(interface);
assert_false(element.hasAttribute(attribute), "Initially missing");
element.setAttribute(attribute, "return");
assert_equals(element.getAttribute(attribute), "return", "Return same string");
assert_equals(typeof element[attribute], "function", "Convert to function");
element.removeAttribute(attribute);
}, "Reflect " + interface + "." + attribute);
}
function testForwardToWindow(interface, attribute) {
test(function() {
var element = getObject(interface);
window[attribute] = null;
element.setAttribute(attribute, "return");
assert_equals(typeof window[attribute], "function", "Convert to function");
assert_equals(window[attribute], element[attribute], "Forward content attribute");
function nop() {}
element[attribute] = nop;
assert_equals(window[attribute], nop, "Forward IDL attribute");
window[attribute] = null;
}, "Forward " + interface + "." + attribute + " to Window");
}
// Object.propertyIsEnumerable cannot be used because it doesn't
// work with properties inherited through the prototype chain.
function getEnumerable(interface) {
var enumerable = {};
for (var attribute in getObject(interface)) {
enumerable[attribute] = true;
}
return enumerable;
}
var enumerableCache = {};
function testEnumerate(interface, attribute) {
if (!(interface in enumerableCache)) {
enumerableCache[interface] = getEnumerable(interface);
}
test(function() {
assert_true(enumerableCache[interface][attribute]);
}, "Enumerate " + interface + "." + attribute);
}
[
"onblur",
"onerror",
"onfocus",
"onload",
"onscroll",
"onresize"
].forEach(function(attribute) {
testSet("HTMLBodyElement", attribute);
testEnumerate("HTMLBodyElement", attribute);
testReflect("HTMLBodyElement", attribute);
testForwardToWindow("HTMLBodyElement", attribute);
testSet("HTMLFrameSetElement", attribute);
testEnumerate("HTMLFrameSetElement", attribute);
testReflect("HTMLFrameSetElement", attribute);
testForwardToWindow("HTMLFrameSetElement", attribute);
});
</script>
</html>

View file

@ -0,0 +1,35 @@
<!doctype html>
<title>CustomEvent</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var type = "foo";
var target = document.createElement("div");
target.addEventListener(type, this.step_func(function(evt) {
assert_equals(evt.type, type);
}), true);
var fooEvent = document.createEvent("CustomEvent");
fooEvent.initEvent(type, true, true);
target.dispatchEvent(fooEvent);
}, "CustomEvent dispatching.");
test(function() {
var e = document.createEvent("CustomEvent");
assert_throws_js(TypeError, function() {
e.initCustomEvent();
});
}, "First parameter to initCustomEvent should be mandatory.");
test(function() {
var e = document.createEvent("CustomEvent");
e.initCustomEvent("foo");
assert_equals(e.type, "foo", "type");
assert_false(e.bubbles, "bubbles");
assert_false(e.cancelable, "cancelable");
assert_equals(e.detail, null, "detail");
}, "initCustomEvent's default parameter values.");
</script>

View file

@ -0,0 +1,132 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Event.cancelBubble</title>
<link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-cancelbubble">
<meta name="flags" content="dom">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="outer">
<div id="middle">
<div id="inner"></div>
</div>
</div>
<script>
test(function () {
// See https://dom.spec.whatwg.org/#stop-propagation-flag
var e = document.createEvent('Event');
assert_false(e.cancelBubble, "cancelBubble must be false after event creation.");
}, "cancelBubble must be false when an event is initially created.");
test(function () {
// See https://dom.spec.whatwg.org/#concept-event-initialize
// Event which bubbles.
var one = document.createEvent('Event');
one.cancelBubble = true;
one.initEvent('foo', true/*bubbles*/, false/*cancelable*/);
assert_false(one.cancelBubble, "initEvent() must set cancelBubble to false. [bubbles=true]");
// Re-initialization.
one.cancelBubble = true;
one.initEvent('foo', true/*bubbles*/, false/*cancelable*/);
assert_false(one.cancelBubble, "2nd initEvent() call must set cancelBubble to false. [bubbles=true]");
// Event which doesn't bubble.
var two = document.createEvent('Event');
two.cancelBubble = true;
two.initEvent('foo', false/*bubbles*/, false/*cancelable*/);
assert_false(two.cancelBubble, "initEvent() must set cancelBubble to false. [bubbles=false]");
// Re-initialization.
two.cancelBubble = true;
two.initEvent('foo', false/*bubbles*/, false/*cancelable*/);
assert_false(two.cancelBubble, "2nd initEvent() call must set cancelBubble to false. [bubbles=false]");
}, "Initializing an event must set cancelBubble to false.");
test(function () {
// See https://dom.spec.whatwg.org/#dom-event-stoppropagation
var e = document.createEvent('Event');
e.stopPropagation();
assert_true(e.cancelBubble, "stopPropagation() must set cancelBubble to true.");
}, "stopPropagation() must set cancelBubble to true.");
test(function () {
// See https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation
var e = document.createEvent('Event');
e.stopImmediatePropagation();
assert_true(e.cancelBubble, "stopImmediatePropagation() must set cancelBubble to true.");
}, "stopImmediatePropagation() must set cancelBubble to true.");
test(function () {
var one = document.createEvent('Event');
one.stopPropagation();
one.cancelBubble = false;
assert_true(one.cancelBubble, "cancelBubble must still be true after attempting to set it to false.");
}, "Event.cancelBubble=false must have no effect.");
test(function (t) {
var outer = document.getElementById('outer');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
outer.addEventListener('barbaz', t.step_func(function () {
assert_unreached("Setting Event.cancelBubble=false after setting Event.cancelBubble=true should have no effect.");
}), false/*useCapture*/);
middle.addEventListener('barbaz', function (e) {
e.cancelBubble = true;// Stop propagation.
e.cancelBubble = false;// Should be a no-op.
}, false/*useCapture*/);
var barbazEvent = document.createEvent('Event');
barbazEvent.initEvent('barbaz', true/*bubbles*/, false/*cancelable*/);
inner.dispatchEvent(barbazEvent);
}, "Event.cancelBubble=false must have no effect during event propagation.");
test(function () {
// See https://dom.spec.whatwg.org/#concept-event-dispatch
// "14. Unset events [...] stop propagation flag,"
var e = document.createEvent('Event');
e.initEvent('foobar', true/*bubbles*/, true/*cancelable*/);
document.body.addEventListener('foobar', function listener(e) {
e.stopPropagation();
});
document.body.dispatchEvent(e);
assert_false(e.cancelBubble, "cancelBubble must be false after an event has been dispatched.");
}, "cancelBubble must be false after an event has been dispatched.");
test(function (t) {
var outer = document.getElementById('outer');
var middle = document.getElementById('middle');
var inner = document.getElementById('inner');
var propagationStopper = function (e) {
e.cancelBubble = true;
};
// Bubble phase
middle.addEventListener('bar', propagationStopper, false/*useCapture*/);
outer.addEventListener('bar', t.step_func(function listenerOne() {
assert_unreached("Setting cancelBubble=true should stop the event from bubbling further.");
}), false/*useCapture*/);
var barEvent = document.createEvent('Event');
barEvent.initEvent('bar', true/*bubbles*/, false/*cancelable*/);
inner.dispatchEvent(barEvent);
// Capture phase
outer.addEventListener('qux', propagationStopper, true/*useCapture*/);
middle.addEventListener('qux', t.step_func(function listenerTwo() {
assert_unreached("Setting cancelBubble=true should stop the event from propagating further, including during the Capture Phase.");
}), true/*useCapture*/);
var quxEvent = document.createEvent('Event');
quxEvent.initEvent('qux', false/*bubbles*/, false/*cancelable*/);
inner.dispatchEvent(quxEvent);
}, "Event.cancelBubble=true must set the stop propagation flag.");
</script>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!doctype html>
<title>Event constants</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../constants.js"></script>
<div id="log"></div>
<script>
var objects;
setup(function() {
objects = [
[Event, "Event interface object"],
[Event.prototype, "Event prototype object"],
[document.createEvent("Event"), "Event object"],
[document.createEvent("CustomEvent"), "CustomEvent object"]
]
})
testConstants(objects, [
["NONE", 0],
["CAPTURING_PHASE", 1],
["AT_TARGET", 2],
["BUBBLING_PHASE", 3]
], "eventPhase")
</script>

View file

@ -0,0 +1,120 @@
// META: title=Event constructors
test(function() {
assert_throws_js(
TypeError,
() => Event(""),
"Calling Event constructor without 'new' must throw")
})
test(function() {
assert_throws_js(TypeError, function() {
new Event()
})
})
test(function() {
var test_error = { name: "test" }
assert_throws_exactly(test_error, function() {
new Event({ toString: function() { throw test_error; } })
})
})
test(function() {
var ev = new Event("")
assert_equals(ev.type, "")
assert_equals(ev.target, null)
assert_equals(ev.srcElement, null)
assert_equals(ev.currentTarget, null)
assert_equals(ev.eventPhase, Event.NONE)
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
assert_equals(ev.defaultPrevented, false)
assert_equals(ev.returnValue, true)
assert_equals(ev.isTrusted, false)
assert_true(ev.timeStamp > 0)
assert_true("initEvent" in ev)
})
test(function() {
var ev = new Event("test")
assert_equals(ev.type, "test")
assert_equals(ev.target, null)
assert_equals(ev.srcElement, null)
assert_equals(ev.currentTarget, null)
assert_equals(ev.eventPhase, Event.NONE)
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
assert_equals(ev.defaultPrevented, false)
assert_equals(ev.returnValue, true)
assert_equals(ev.isTrusted, false)
assert_true(ev.timeStamp > 0)
assert_true("initEvent" in ev)
})
test(function() {
assert_throws_js(TypeError, function() { Event("test") },
'Calling Event constructor without "new" must throw');
})
test(function() {
var ev = new Event("I am an event", { bubbles: true, cancelable: false})
assert_equals(ev.type, "I am an event")
assert_equals(ev.bubbles, true)
assert_equals(ev.cancelable, false)
})
test(function() {
var ev = new Event("@", { bubblesIGNORED: true, cancelable: true})
assert_equals(ev.type, "@")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
})
test(function() {
var ev = new Event("@", { "bubbles\0IGNORED": true, cancelable: true})
assert_equals(ev.type, "@")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
})
test(function() {
var ev = new Event("Xx", { cancelable: true})
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
})
test(function() {
var ev = new Event("Xx", {})
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, false)
})
test(function() {
var ev = new Event("Xx", {bubbles: true, cancelable: false, sweet: "x"})
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, true)
assert_equals(ev.cancelable, false)
assert_equals(ev.sweet, undefined)
})
test(function() {
var called = []
var ev = new Event("Xx", {
get cancelable() {
called.push("cancelable")
return false
},
get bubbles() {
called.push("bubbles")
return true;
},
get sweet() {
called.push("sweet")
return "x"
}
})
assert_array_equals(called, ["bubbles", "cancelable"])
assert_equals(ev.type, "Xx")
assert_equals(ev.bubbles, true)
assert_equals(ev.cancelable, false)
assert_equals(ev.sweet, undefined)
})
test(function() {
var ev = new CustomEvent("$", {detail: 54, sweet: "x", sweet2: "x", cancelable:true})
assert_equals(ev.type, "$")
assert_equals(ev.bubbles, false)
assert_equals(ev.cancelable, true)
assert_equals(ev.sweet, undefined)
assert_equals(ev.detail, 54)
})

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Event.defaultPrevented is not reset after dispatchEvent()</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<input id="target" type="hidden" value=""/>
<script>
test(function() {
var EVENT = "foo";
var TARGET = document.getElementById("target");
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
TARGET.addEventListener(EVENT, this.step_func(function(e) {
e.preventDefault();
assert_true(e.defaultPrevented, "during dispatch");
}), true);
TARGET.dispatchEvent(evt);
assert_true(evt.defaultPrevented, "after dispatch");
assert_equals(evt.target, TARGET);
assert_equals(evt.srcElement, TARGET);
}, "Default prevention via preventDefault");
test(function() {
var EVENT = "foo";
var TARGET = document.getElementById("target");
var evt = document.createEvent("Event");
evt.initEvent(EVENT, true, true);
TARGET.addEventListener(EVENT, this.step_func(function(e) {
e.returnValue = false;
assert_true(e.defaultPrevented, "during dispatch");
}), true);
TARGET.dispatchEvent(evt);
assert_true(evt.defaultPrevented, "after dispatch");
assert_equals(evt.target, TARGET);
assert_equals(evt.srcElement, TARGET);
}, "Default prevention via returnValue");
</script>

View file

@ -0,0 +1,55 @@
<!doctype html>
<title>Event.defaultPrevented</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var ev;
test(function() {
ev = document.createEvent("Event");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "When an event is created, defaultPrevented should be initialized to false.");
test(function() {
ev.initEvent("foo", true, false);
assert_equals(ev.bubbles, true, "bubbles");
assert_equals(ev.cancelable, false, "cancelable");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "initEvent should work correctly (not cancelable).");
test(function() {
assert_equals(ev.cancelable, false, "cancelable (before)");
ev.preventDefault();
assert_equals(ev.cancelable, false, "cancelable (after)");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "preventDefault() should not change defaultPrevented if cancelable is false.");
test(function() {
assert_equals(ev.cancelable, false, "cancelable (before)");
ev.returnValue = false;
assert_equals(ev.cancelable, false, "cancelable (after)");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "returnValue should not change defaultPrevented if cancelable is false.");
test(function() {
ev.initEvent("foo", true, true);
assert_equals(ev.bubbles, true, "bubbles");
assert_equals(ev.cancelable, true, "cancelable");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "initEvent should work correctly (cancelable).");
test(function() {
assert_equals(ev.cancelable, true, "cancelable (before)");
ev.preventDefault();
assert_equals(ev.cancelable, true, "cancelable (after)");
assert_equals(ev.defaultPrevented, true, "defaultPrevented");
}, "preventDefault() should change defaultPrevented if cancelable is true.");
test(function() {
ev.initEvent("foo", true, true);
assert_equals(ev.cancelable, true, "cancelable (before)");
ev.returnValue = false;
assert_equals(ev.cancelable, true, "cancelable (after)");
assert_equals(ev.defaultPrevented, true, "defaultPrevented");
}, "returnValue should change defaultPrevented if cancelable is true.");
test(function() {
ev.initEvent("foo", true, true);
assert_equals(ev.bubbles, true, "bubbles");
assert_equals(ev.cancelable, true, "cancelable");
assert_equals(ev.defaultPrevented, false, "defaultPrevented");
}, "initEvent should unset defaultPrevented.");
</script>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title>Setting cancelBubble=true prior to dispatchEvent()</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var current_targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [];
var actual_targets = [];
var expected_phases = [];
var actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
};
for (var i = 0; i < current_targets.length; ++i) {
current_targets[i].addEventListener(event, test_event, true);
current_targets[i].addEventListener(event, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event, true, true);
evt.cancelBubble = true;
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_phases, expected_phases, "actual_phases");
});
</script>
</body>
</html>

View file

@ -0,0 +1,98 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Event.bubbles attribute is set to false </title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-initevent">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
function targetsForDocumentChain(document) {
return [
document,
document.documentElement,
document.getElementsByTagName("body")[0],
document.getElementById("table"),
document.getElementById("table-body"),
document.getElementById("parent")
];
}
function testChain(document, targetParents, phases, event_type) {
var target = document.getElementById("target");
var targets = targetParents.concat(target);
var expected_targets = targets.concat(target);
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, false, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}
var phasesForDocumentChain = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
];
test(function () {
var chainWithWindow = [window].concat(targetsForDocumentChain(document));
testChain(
document, chainWithWindow, [Event.CAPTURING_PHASE].concat(phasesForDocumentChain), "click");
}, "In window.document with click event");
test(function () {
testChain(document, targetsForDocumentChain(document), phasesForDocumentChain, "load");
}, "In window.document with load event")
test(function () {
var documentClone = document.cloneNode(true);
testChain(
documentClone, targetsForDocumentChain(documentClone), phasesForDocumentChain, "click");
}, "In window.document.cloneNode(true)");
test(function () {
var newDocument = new Document();
newDocument.appendChild(document.documentElement.cloneNode(true));
testChain(
newDocument, targetsForDocumentChain(newDocument), phasesForDocumentChain, "click");
}, "In new Document()");
test(function () {
var HTMLDocument = document.implementation.createHTMLDocument();
HTMLDocument.body.appendChild(document.getElementById("table").cloneNode(true));
testChain(
HTMLDocument, targetsForDocumentChain(HTMLDocument), phasesForDocumentChain, "click");
}, "In DOMImplementation.createHTMLDocument()");
</script>

View file

@ -0,0 +1,108 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Event.bubbles attribute is set to false </title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-initevent">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
function concatReverse(a) {
return a.concat(a.map(function(x) { return x }).reverse());
}
function targetsForDocumentChain(document) {
return [
document,
document.documentElement,
document.getElementsByTagName("body")[0],
document.getElementById("table"),
document.getElementById("table-body"),
document.getElementById("parent")
];
}
function testChain(document, targetParents, phases, event_type) {
var target = document.getElementById("target");
var targets = targetParents.concat(target);
var expected_targets = concatReverse(targets);
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}
var phasesForDocumentChain = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
];
test(function () {
var chainWithWindow = [window].concat(targetsForDocumentChain(document));
var phases = [Event.CAPTURING_PHASE].concat(phasesForDocumentChain, Event.BUBBLING_PHASE);
testChain(document, chainWithWindow, phases, "click");
}, "In window.document with click event");
test(function () {
testChain(document, targetsForDocumentChain(document), phasesForDocumentChain, "load");
}, "In window.document with load event")
test(function () {
var documentClone = document.cloneNode(true);
testChain(
documentClone, targetsForDocumentChain(documentClone), phasesForDocumentChain, "click");
}, "In window.document.cloneNode(true)");
test(function () {
var newDocument = new Document();
newDocument.appendChild(document.documentElement.cloneNode(true));
testChain(
newDocument, targetsForDocumentChain(newDocument), phasesForDocumentChain, "click");
}, "In new Document()");
test(function () {
var HTMLDocument = document.implementation.createHTMLDocument();
HTMLDocument.body.appendChild(document.getElementById("table").cloneNode(true));
testChain(
HTMLDocument, targetsForDocumentChain(HTMLDocument), phasesForDocumentChain, "click");
}, "In DOMImplementation.createHTMLDocument()");
</script>

View file

@ -0,0 +1,425 @@
<!doctype html>
<title>Synthetic click event "magic"</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<div id=dump style=display:none></div>
<script>
var dump = document.getElementById("dump")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
input.onclick = t.step_func_done(function() {
assert_true(input.checked)
})
input.click()
}, "basic with click()")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
input.onclick = t.step_func_done(function() {
assert_true(input.checked)
})
input.dispatchEvent(new MouseEvent("click", {bubbles:true})) // equivalent to the above
}, "basic with dispatchEvent()")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
input.onclick = t.step_func_done(function() {
assert_false(input.checked)
})
input.dispatchEvent(new Event("click", {bubbles:true})) // no MouseEvent
}, "basic with wrong event class")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
var child = input.appendChild(new Text("does not matter"))
child.dispatchEvent(new MouseEvent("click")) // does not bubble
assert_false(input.checked)
t.done()
}, "look at parents only when event bubbles")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
input.onclick = t.step_func_done(function() {
assert_true(input.checked)
})
var child = input.appendChild(new Text("does not matter"))
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
}, "look at parents when event bubbles")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
input.onclick = t.step_func(function() {
assert_false(input.checked, "input pre-click must not be triggered")
})
var child = input.appendChild(document.createElement("input"))
child.type = "checkbox"
child.onclick = t.step_func(function() {
assert_true(child.checked, "child pre-click must be triggered")
})
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
t.done()
}, "pick the first with activation behavior <input type=checkbox>")
async_test(function(t) { // as above with <a>
window.hrefComplete = t.step_func(function(a) {
assert_equals(a, 'child');
t.done();
});
var link = document.createElement("a")
link.href = "javascript:hrefComplete('link')" // must not be triggered
dump.appendChild(link)
var child = link.appendChild(document.createElement("a"))
child.href = "javascript:hrefComplete('child')"
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
}, "pick the first with activation behavior <a href>")
async_test(function(t) {
var input = document.createElement("input")
input.type = "radio"
dump.appendChild(input)
input.onclick = t.step_func(function() {
assert_false(input.checked, "input pre-click must not be triggered")
})
var child = input.appendChild(document.createElement("input"))
child.type = "radio"
child.onclick = t.step_func(function() {
assert_true(child.checked, "child pre-click must be triggered")
})
child.dispatchEvent(new MouseEvent("click", {bubbles:true}))
t.done()
}, "pick the first with activation behavior <input type=radio>")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
var clickEvent = new MouseEvent("click")
input.onchange = t.step_func_done(function() {
assert_false(clickEvent.defaultPrevented)
assert_true(clickEvent.returnValue)
assert_equals(clickEvent.eventPhase, 0)
assert_equals(clickEvent.currentTarget, null)
assert_equals(clickEvent.target, input)
assert_equals(clickEvent.srcElement, input)
assert_equals(clickEvent.composedPath().length, 0)
})
input.dispatchEvent(clickEvent)
}, "event state during post-click handling")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
var clickEvent = new MouseEvent("click")
var finalTarget = document.createElement("doesnotmatter")
finalTarget.onclick = t.step_func_done(function() {
assert_equals(clickEvent.target, finalTarget)
assert_equals(clickEvent.srcElement, finalTarget)
})
input.onchange = t.step_func(function() {
finalTarget.dispatchEvent(clickEvent)
})
input.dispatchEvent(clickEvent)
}, "redispatch during post-click handling")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
dump.appendChild(input)
var child = input.appendChild(document.createElement("input"))
child.type = "checkbox"
child.disabled = true
child.click()
assert_false(input.checked)
assert_false(child.checked)
t.done()
}, "disabled checkbox still has activation behavior")
async_test(function(t) {
var state = "start"
var form = document.createElement("form")
form.onsubmit = t.step_func(() => {
if(state == "start" || state == "checkbox") {
state = "failure"
} else if(state == "form") {
state = "done"
}
return false
})
dump.appendChild(form)
var button = form.appendChild(document.createElement("button"))
button.type = "submit"
var checkbox = button.appendChild(document.createElement("input"))
checkbox.type = "checkbox"
checkbox.onclick = t.step_func(() => {
if(state == "start") {
assert_unreached()
} else if(state == "checkbox") {
assert_true(checkbox.checked)
}
})
checkbox.disabled = true
checkbox.click()
assert_equals(state, "start")
state = "checkbox"
checkbox.disabled = false
checkbox.click()
assert_equals(state, "checkbox")
state = "form"
button.click()
assert_equals(state, "done")
t.done()
}, "disabled checkbox still has activation behavior, part 2")
async_test(function(t) {
var state = "start"
var form = document.createElement("form")
form.onsubmit = t.step_func(() => {
if(state == "start" || state == "radio") {
state = "failure"
} else if(state == "form") {
state = "done"
}
return false
})
dump.appendChild(form)
var button = form.appendChild(document.createElement("button"))
button.type = "submit"
var radio = button.appendChild(document.createElement("input"))
radio.type = "radio"
radio.onclick = t.step_func(() => {
if(state == "start") {
assert_unreached()
} else if(state == "radio") {
assert_true(radio.checked)
}
})
radio.disabled = true
radio.click()
assert_equals(state, "start")
state = "radio"
radio.disabled = false
radio.click()
assert_equals(state, "radio")
state = "form"
button.click()
assert_equals(state, "done")
t.done()
}, "disabled radio still has activation behavior")
async_test(function(t) {
var input = document.createElement("input")
input.type = "checkbox"
input.onclick = t.step_func_done(function() {
assert_true(input.checked)
})
input.click()
}, "disconnected checkbox should be checked")
async_test(function(t) {
var input = document.createElement("input")
input.type = "radio"
input.onclick = t.step_func_done(function() {
assert_true(input.checked)
})
input.click()
}, "disconnected radio should be checked")
async_test(t => {
const input = document.createElement('input');
input.type = 'checkbox';
input.onclick = t.step_func_done(() => {
assert_true(input.checked);
});
input.dispatchEvent(new MouseEvent('click'));
}, `disconnected checkbox should be checked from dispatchEvent(new MouseEvent('click'))`);
async_test(t => {
const input = document.createElement('input');
input.type = 'radio';
input.onclick = t.step_func_done(() => {
assert_true(input.checked);
});
input.dispatchEvent(new MouseEvent('click'));
}, `disconnected radio should be checked from dispatchEvent(new MouseEvent('click'))`);
test(() => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
input.dispatchEvent(new MouseEvent("click"));
assert_true(input.checked);
}, `disabled checkbox should be checked from dispatchEvent(new MouseEvent("click"))`);
test(() => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
input.dispatchEvent(new MouseEvent("click"));
assert_true(input.checked);
}, `disabled radio should be checked from dispatchEvent(new MouseEvent("click"))`);
async_test(t => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
input.onclick = t.step_func_done();
input.dispatchEvent(new MouseEvent("click"));
}, `disabled checkbox should fire onclick`);
async_test(t => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
input.onclick = t.step_func_done();
input.dispatchEvent(new MouseEvent("click"));
}, `disabled radio should fire onclick`);
async_test(t => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
input.onclick = t.step_func(ev => {
assert_true(input.checked);
ev.preventDefault();
queueMicrotask(t.step_func_done(() => {
assert_false(input.checked);
}));
});
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
}, `disabled checkbox should get legacy-canceled-activation behavior`);
async_test(t => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
input.onclick = t.step_func(ev => {
assert_true(input.checked);
ev.preventDefault();
queueMicrotask(t.step_func_done(() => {
assert_false(input.checked);
}));
});
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
}, `disabled radio should get legacy-canceled-activation behavior`);
test(t => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
const ev = new MouseEvent("click", { cancelable: true });
ev.preventDefault();
input.dispatchEvent(ev);
assert_false(input.checked);
}, `disabled checkbox should get legacy-canceled-activation behavior 2`);
test(t => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
const ev = new MouseEvent("click", { cancelable: true });
ev.preventDefault();
input.dispatchEvent(ev);
assert_false(input.checked);
}, `disabled radio should get legacy-canceled-activation behavior 2`);
for (const type of ["checkbox", "radio"]) {
for (const handler of ["oninput", "onchange"]) {
async_test(t => {
const input = document.createElement("input");
input.type = type;
input.onclick = t.step_func(ev => {
input.disabled = true;
});
input[handler] = t.step_func(ev => {
assert_equals(input.checked, true);
t.done();
});
dump.append(input);
input.click();
}, `disabling ${type} in onclick listener shouldn't suppress ${handler}`);
}
}
async_test(function(t) {
var form = document.createElement("form")
var didSubmit = false
form.onsubmit = t.step_func(() => {
didSubmit = true
return false
})
var input = form.appendChild(document.createElement("input"))
input.type = "submit"
input.click()
assert_false(didSubmit)
t.done()
}, "disconnected form should not submit")
async_test(t => {
const form = document.createElement("form");
form.onsubmit = t.step_func(ev => {
ev.preventDefault();
assert_unreached("The form is unexpectedly submitted.");
});
dump.append(form);
const input = form.appendChild(document.createElement("input"));
input.type = "submit"
input.disabled = true;
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
t.done();
}, "disabled submit button should not activate");
async_test(t => {
const form = document.createElement("form");
form.onsubmit = t.step_func(ev => {
ev.preventDefault();
assert_unreached("The form is unexpectedly submitted.");
});
dump.append(form);
const input = form.appendChild(document.createElement("input"));
input.onclick = t.step_func(() => {
input.disabled = true;
});
input.type = "submit"
input.dispatchEvent(new MouseEvent("click", { cancelable: true }));
t.done();
}, "submit button should not activate if the event listener disables it");
async_test(t => {
const form = document.createElement("form");
form.onsubmit = t.step_func(ev => {
ev.preventDefault();
assert_unreached("The form is unexpectedly submitted.");
});
dump.append(form);
const input = form.appendChild(document.createElement("input"));
input.onclick = t.step_func(() => {
input.type = "submit"
input.disabled = true;
});
input.click();
t.done();
}, "submit button that morphed from checkbox should not activate");
</script>

View file

@ -0,0 +1,78 @@
<!doctype html>
<title>Clicks on input element</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=dump style=display:none></div>
<script>
var dump = document.getElementById("dump")
test(t => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
const label = document.createElement("label");
label.append(input);
dump.append(label);
label.click();
assert_false(input.checked);
}, "disabled checkbox should not be checked from label click");
test(t => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
const label = document.createElement("label");
label.append(input);
dump.append(label);
label.click();
assert_false(input.checked);
}, "disabled radio should not be checked from label click");
test(t => {
const input = document.createElement("input");
input.type = "checkbox";
input.disabled = true;
const label = document.createElement("label");
label.append(input);
dump.append(label);
label.dispatchEvent(new MouseEvent("click"));
assert_false(input.checked);
}, "disabled checkbox should not be checked from label click by dispatchEvent");
test(t => {
const input = document.createElement("input");
input.type = "radio";
input.disabled = true;
const label = document.createElement("label");
label.append(input);
dump.append(label);
label.dispatchEvent(new MouseEvent("click"));
assert_false(input.checked);
}, "disabled radio should not be checked from label click by dispatchEvent");
test(t => {
const checkbox = dump.appendChild(document.createElement("input"));
checkbox.type = "checkbox";
checkbox.onclick = ev => {
checkbox.type = "date";
ev.preventDefault();
};
checkbox.dispatchEvent(new MouseEvent("click", { cancelable: true }));
assert_false(checkbox.checked);
}, "checkbox morphed into another type should not mutate checked state");
test(t => {
const radio1 = dump.appendChild(document.createElement("input"));
const radio2 = dump.appendChild(radio1.cloneNode());
radio1.type = radio2.type = "radio";
radio1.name = radio2.name = "foo";
radio2.checked = true;
radio1.onclick = ev => {
radio1.type = "date";
ev.preventDefault();
};
radio1.dispatchEvent(new MouseEvent("click", { cancelable: true }));
assert_false(radio1.checked);
assert_true(radio2.checked);
}, "radio morphed into another type should not steal the existing checked state");
</script>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<title>Click event on an element not in the document</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var EVENT = "click";
var TARGET = document.createElement("somerandomelement");
var t = async_test("Click event can be dispatched to an element that is not in the document.")
TARGET.addEventListener(EVENT, t.step_func(function(evt) {
assert_equals(evt.target, TARGET);
assert_equals(evt.srcElement, TARGET);
t.done();
}), true);
var e = document.createEvent("Event");
e.initEvent(EVENT, true, true);
TARGET.dispatchEvent(e);
});
</script>

View file

@ -0,0 +1,190 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="Joey Arhar" href="mailto:jarhar@chromium.org">
<title>input and change events for detached checkbox and radio elements</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<script>
test(() => {
const input = document.createElement('input');
input.type = 'checkbox';
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.click();
assert_false(inputEventFired);
assert_false(changeEventFired);
}, 'detached checkbox should not emit input or change events on click().');
test(() => {
const input = document.createElement('input');
input.type = 'radio';
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.click();
assert_false(inputEventFired);
assert_false(changeEventFired);
}, 'detached radio should not emit input or change events on click().');
test(() => {
const input = document.createElement('input');
input.type = 'checkbox';
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.dispatchEvent(new MouseEvent('click'));
assert_false(inputEventFired);
assert_false(changeEventFired);
}, `detached checkbox should not emit input or change events on dispatchEvent(new MouseEvent('click')).`);
test(() => {
const input = document.createElement('input');
input.type = 'radio';
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.dispatchEvent(new MouseEvent('click'));
assert_false(inputEventFired);
assert_false(changeEventFired);
}, `detached radio should not emit input or change events on dispatchEvent(new MouseEvent('click')).`);
test(() => {
const input = document.createElement('input');
input.type = 'checkbox';
document.body.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.click();
assert_true(inputEventFired);
assert_true(changeEventFired);
}, 'attached checkbox should emit input and change events on click().');
test(() => {
const input = document.createElement('input');
input.type = 'radio';
document.body.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.click();
assert_true(inputEventFired);
assert_true(changeEventFired);
}, 'attached radio should emit input and change events on click().');
test(() => {
const input = document.createElement('input');
input.type = 'checkbox';
document.body.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.dispatchEvent(new MouseEvent('click'));
assert_true(inputEventFired);
assert_true(changeEventFired);
}, `attached checkbox should emit input and change events on dispatchEvent(new MouseEvent('click')).`);
test(() => {
const input = document.createElement('input');
input.type = 'radio';
document.body.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.dispatchEvent(new MouseEvent('click'));
assert_true(inputEventFired);
assert_true(changeEventFired);
}, `attached radio should emit input and change events on dispatchEvent(new MouseEvent('click')).`);
test(() => {
const input = document.createElement('input');
input.type = 'checkbox';
const shadowHost = document.createElement('div');
document.body.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
shadowRoot.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.click();
assert_true(inputEventFired);
assert_true(changeEventFired);
}, 'attached to shadow dom checkbox should emit input and change events on click().');
test(() => {
const input = document.createElement('input');
input.type = 'radio';
const shadowHost = document.createElement('div');
document.body.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
shadowRoot.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.click();
assert_true(inputEventFired);
assert_true(changeEventFired);
}, 'attached to shadow dom radio should emit input and change events on click().');
test(() => {
const input = document.createElement('input');
input.type = 'checkbox';
const shadowHost = document.createElement('div');
document.body.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
shadowRoot.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.dispatchEvent(new MouseEvent('click'));
assert_true(inputEventFired);
assert_true(changeEventFired);
}, `attached to shadow dom checkbox should emit input and change events on dispatchEvent(new MouseEvent('click')).`);
test(() => {
const input = document.createElement('input');
input.type = 'radio';
const shadowHost = document.createElement('div');
document.body.appendChild(shadowHost);
const shadowRoot = shadowHost.attachShadow({mode: 'open'});
shadowRoot.appendChild(input);
let inputEventFired = false;
input.addEventListener('input', () => inputEventFired = true);
let changeEventFired = false;
input.addEventListener('change', () => changeEventFired = true);
input.dispatchEvent(new MouseEvent('click'));
assert_true(inputEventFired);
assert_true(changeEventFired);
}, `attached to shadow dom radio should emit input and change events on dispatchEvent(new MouseEvent('click')).`);
</script>
</body>

View file

@ -0,0 +1,91 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Dispatch additional events inside an event listener </title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "bar";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [
window,
document,
html,
body,
table,
tbody,
parent,
target,
target,
target, // The additional listener for target runs as we copy its listeners twice
parent,
tbody,
table,
body,
html,
document,
window
];
var expected_listeners = [0,0,0,0,0,0,0,0,1,3,1,1,1,1,1,1,1];
var actual_targets = [], actual_listeners = [];
var test_event_function = function(i) {
return this.step_func(function(evt) {
actual_targets.push(evt.currentTarget);
actual_listeners.push(i);
if (evt.eventPhase != evt.BUBBLING_PHASE && evt.currentTarget.foo != 1) {
evt.currentTarget.removeEventListener(event_type, event_handlers[0], true);
evt.currentTarget.addEventListener(event_type, event_handlers[2], true);
evt.currentTarget.foo = 1;
}
if (evt.eventPhase != evt.CAPTURING_PHASE && evt.currentTarget.foo != 3) {
evt.currentTarget.removeEventListener(event_type, event_handlers[0], false);
evt.currentTarget.addEventListener(event_type, event_handlers[3], false);
evt.currentTarget.foo = 3;
}
});
}.bind(this);
var event_handlers = [
test_event_function(0),
test_event_function(1),
test_event_function(2),
test_event_function(3),
];
for (var i = 0; i < targets.length; ++i) {
targets[i].addEventListener(event_type, event_handlers[0], true);
targets[i].addEventListener(event_type, event_handlers[1], false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_listeners, expected_listeners, "actual_listeners");
});
</script>

View file

@ -0,0 +1,20 @@
test(t => {
const hostParent = document.createElement("section"),
host = hostParent.appendChild(document.createElement("div")),
shadowRoot = host.attachShadow({ mode: "closed" }),
targetParent = shadowRoot.appendChild(document.createElement("p")),
target = targetParent.appendChild(document.createElement("span")),
path = [hostParent, host, shadowRoot, targetParent, target],
expected = [],
result = [];
path.forEach((node, index) => {
expected.splice(index, 0, "capturing " + node.nodeName);
expected.splice(index + 1, 0, "bubbling " + node.nodeName);
});
path.forEach(node => {
node.addEventListener("test", () => { result.push("bubbling " + node.nodeName) });
node.addEventListener("test", () => { result.push("capturing " + node.nodeName) }, true);
});
target.dispatchEvent(new CustomEvent('test', { detail: {}, bubbles: true, composed: true }));
assert_array_equals(result, expected);
});

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title>Multiple dispatchEvent() and cancelBubble</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<div id="parent" style="display: none">
<input id="target" type="hidden" value=""/>
</div>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var actual_result;
var test_event = function(evt) {
actual_result.push(evt.currentTarget);
if (parent == evt.currentTarget) {
evt.cancelBubble = true;
}
};
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.addEventListener(event_type, test_event, false);
parent.addEventListener(event_type, test_event, false);
document.addEventListener(event_type, test_event, false);
window.addEventListener(event_type, test_event, false);
actual_result = [];
target.dispatchEvent(evt);
assert_array_equals(actual_result, [target, parent]);
actual_result = [];
parent.dispatchEvent(evt);
assert_array_equals(actual_result, [parent]);
actual_result = [];
document.dispatchEvent(evt);
assert_array_equals(actual_result, [document, window]);
});
</script>
</body>
</html>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html>
<head>
<title> Multiple dispatchEvent() and stopPropagation() </title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<div id="parent" style="display: none">
<input id="target" type="hidden" value=""/>
</div>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var actual_result;
var test_event = function(evt) {
actual_result.push(evt.currentTarget);
if (parent == evt.currentTarget) {
evt.stopPropagation();
}
};
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.addEventListener(event_type, test_event, false);
parent.addEventListener(event_type, test_event, false);
document.addEventListener(event_type, test_event, false);
window.addEventListener(event_type, test_event, false);
actual_result = [];
target.dispatchEvent(evt);
assert_array_equals(actual_result, [target, parent]);
actual_result = [];
parent.dispatchEvent(evt);
assert_array_equals(actual_result, [parent]);
actual_result = [];
document.dispatchEvent(evt);
assert_array_equals(actual_result, [document, window]);
});
</script>
</body>
</html>

View file

@ -0,0 +1,70 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>EventTarget.addEventListener: capture argument omitted</title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-eventtarget-addeventlistener">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var targets = [
target,
document.getElementById("parent"),
document.getElementById("table-body"),
document.getElementById("table"),
document.body,
document.documentElement,
document,
window
];
var phases = [
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE
];
var actual_targets = [], actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
}
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
for (var i = 0; i < targets.length; i++) {
targets[i].removeEventListener(event_type, test_event);
}
target.dispatchEvent(evt);
assert_array_equals(actual_targets, targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "EventTarget.addEventListener with the capture argument omitted");
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Listeners are invoked in correct order (AT_TARGET phase)</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
"use strict";
test(() => {
const el = document.createElement("div");
const expectedOrder = ["capturing", "bubbling"];
let actualOrder = [];
el.addEventListener("click", evt => {
assert_equals(evt.eventPhase, Event.AT_TARGET);
actualOrder.push("bubbling");
}, false);
el.addEventListener("click", evt => {
assert_equals(evt.eventPhase, Event.AT_TARGET);
actualOrder.push("capturing");
}, true);
el.dispatchEvent(new Event("click", {bubbles: true}));
assert_array_equals(actualOrder, expectedOrder, "bubbles: true");
actualOrder = [];
el.dispatchEvent(new Event("click", {bubbles: false}));
assert_array_equals(actualOrder, expectedOrder, "bubbles: false");
}, "Listeners are invoked in correct order (AT_TARGET phase)");
</script>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<title>Event phases order</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
async_test(function() {
document.addEventListener('DOMContentLoaded', this.step_func_done(function() {
var parent = document.getElementById('parent');
var child = document.getElementById('child');
var order = [];
parent.addEventListener('click', this.step_func(function(){ order.push(1) }), true);
child.addEventListener('click', this.step_func(function(){ order.push(2) }), false);
parent.addEventListener('click', this.step_func(function(){ order.push(3) }), false);
child.dispatchEvent(new Event('click', {bubbles: true}));
assert_array_equals(order, [1, 2, 3]);
}));
}, "Event phases order");
</script>
<div id="parent">
<div id="child"></div>
</div>

View file

@ -0,0 +1,23 @@
<!doctype html>
<title>Custom event on an element in another document</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var doc = document.implementation.createHTMLDocument("Demo");
var element = doc.createElement("div");
var called = false;
element.addEventListener("foo", this.step_func(function(ev) {
assert_false(called);
called = true;
assert_equals(ev.target, element);
assert_equals(ev.srcElement, element);
}));
doc.body.appendChild(element);
var event = new Event("foo");
element.dispatchEvent(event);
assert_true(called);
});
</script>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title> Calling stopPropagation() prior to dispatchEvent() </title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var current_targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [];
var actual_targets = [];
var expected_phases = [];
var actual_phases = [];
var test_event = function(evt) {
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
};
for (var i = 0; i < current_targets.length; ++i) {
current_targets[i].addEventListener(event, test_event, true);
current_targets[i].addEventListener(event, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event, true, true);
evt.stopPropagation();
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_phases, expected_phases, "actual_phases");
});
</script>
</body>
</html>

View file

@ -0,0 +1,66 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Dispatch additional events inside an event listener </title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = [
window, document, html, body, table,
target, parent, tbody,
table, body, html, document, window,
tbody, parent, target];
var actual_targets = [];
var expected_types = [
"foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar",
"bar", "bar", "bar", "bar", "bar",
"foo", "foo", "foo"
];
var actual_targets = [], actual_types = [];
var test_event = this.step_func(function(evt) {
actual_targets.push(evt.currentTarget);
actual_types.push(evt.type);
if (table == evt.currentTarget && event_type == evt.type) {
var e = document.createEvent("Event");
e.initEvent("bar", true, true);
target.dispatchEvent(e);
}
});
for (var i = 0; i < targets.length; ++i) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener("bar", test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, false, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "actual_targets");
assert_array_equals(actual_types, expected_types, "actual_types");
});
</script>

View file

@ -0,0 +1,164 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Only one activation behavior is executed during dispatch</title>
<link rel="author" title="Vincent Hilla" href="mailto:vhilla@mozilla.com">
<link rel="help" href="https://dom.spec.whatwg.org/#eventtarget-activation-behavior">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<div id=test_container></div>
<!--
Three classes:
click
Element to be clicked to cause activation behavior
activates
Element that registers the activation behavior
container
Element in which other elements with activation behavior are placed.
We test that those won't be activated too.
-->
<template>
<!--input, change event bubble, so have to check if checked is true-->
<input class="click activates container" type="checkbox" oninput="this.checked ? activated(this) : null">
<input class="click activates container" type="radio" oninput="this.checked ? activated(this) : null">
<form onsubmit="activated(this); return false" class="activates">
<input class="click container" type="submit">
</form>
<form onsubmit="activated(this); return false" class="activates">
<input class="click container" type="image">
</form>
<form onreset="activated(this)" class="activates">
<input class="click container" type="reset">
</form>
<form onsubmit="activated(this); return false" class="activates">
<button class="click container" type="submit"></button>
</form>
<form onreset="activated(this)" class="activates">
<button class="click container" type="reset"></button>
</form>
<a href="#link" class="click container activates"></a>
<area href="#link" class="click container activates">
<details ontoggle="activated(this)" class="activates">
<summary class="click container"></summary>
</details>
<label>
<input type=checkbox onclick="this.checked ? activated(this) : null" class="activates">
<span class="click container">label</span>
</label>
<!--activation behavior of label for event targeted at interactive content descendant is to do nothing-->
<label class="container">
<button class="click" type="button"></button>
</label>
</template>
<script>
let activations = [];
function activated(e) {
activations.push(e);
}
function getActivations(testidx) {
return activations.filter(a =>
(a.endsWith && a.endsWith("test"+testidx+"_link"))
|| (a.classList && a.classList.contains("test"+testidx))
);
}
// for a and area elements
window.onhashchange = function(e) {
if (e.newURL.endsWith("link")) {
activated(e.newURL);
}
window.location.hash = "";
};
function getElementsByClassNameInclusive(e, clsname) {
let ls = Array.from(e.getElementsByClassName(clsname));
if (e.classList.contains(clsname)) ls.push(e);
return ls;
}
function getClickTarget(e) {
return getElementsByClassNameInclusive(e, "click")[0];
}
function getContainer(e) {
return getElementsByClassNameInclusive(e, "container")[0];
}
function getExpectedActivations(e) {
let ls = getElementsByClassNameInclusive(e, "activates");
// special case, for a and area the window registers the activation
// have to use string, as testrunner cannot stringify the window object
ls = ls.map(e => e.tagName === "A" || e.tagName === "AREA" ? e.href : e);
return ls;
}
function toString(e) {
const children = Array.from(e.children);
const childstr = (children.map(toString)).join("");
const tag = e.tagName;
const typestr = e.type ? " type="+e.type : "";
return `<${tag}${typestr}>${childstr}</${tag}>`;
}
// generate O(n^2) test combinations
const template = document.querySelector("template");
const elements = Array.from(template.content.children);
const tests = []
for (const target of elements) {
for (const parent of elements) {
if (target === parent) continue;
tests.push([target.cloneNode(true), parent.cloneNode(true)])
}
}
const test_container = document.getElementById("test_container");
/**
* Test that if two elements in an event target chain have activation behavior,
* only one of them will be activated.
*
* Each child of <template> represents one case of activation behavior.
* The behavior should be triggered by clicking the element of class click
* and will manifest as a call to activated().
*
* For each [target, parent] in tests, we make target a descendant of parent
* and test that only target gets activated when dispatching a click.
*/
for (let i = 0; i < tests.length; i++) {
let [target, parent] = tests[i];
async_test(function(t) {
let test = document.createElement("div");
test_container.appendChild(test);
test.appendChild(parent);
getContainer(parent).appendChild(target);
// for later filtering out the activations belonging to this test
for (let e of test.getElementsByClassName("activates")) {
e.classList.add("test"+i);
}
for (let e of test.querySelectorAll("a, area")) {
e.href = "#test"+i+"_link";
}
getClickTarget(target).click();
// Need to spin event loop twice, as some clicks might dispatch another task
t.step_timeout(() => {
t.step_timeout(t.step_func_done(() => {
assert_array_equals(getActivations(i), getExpectedActivations(target));
}), 0);
}, 0);
t.add_cleanup(function() {
test_container.removeChild(test);
});
}, `When clicking child ${toString(target)} of parent ${toString(parent)}, only child should be activated.`);
}
</script>

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title> Determined event propagation path - target moved </title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = targets.concat([target, parent, tbody, table, body, html, document, window]);
var phases = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
];
var actual_targets = [], actual_phases = [];
var test_event = this.step_func(function(evt) {
if (parent === target.parentNode) {
var table_row = document.getElementById("table-row");
table_row.appendChild(parent.removeChild(target));
}
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
});
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "Event propagation path when an element in it is moved within the DOM");
</script>

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Determined event propagation path - target removed</title>
<link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<table id="table" border="1" style="display: none">
<tbody id="table-body">
<tr id="table-row">
<td id="table-cell">Shady Grove</td>
<td>Aeolian</td>
</tr>
<tr id="parent">
<td id="target">Over the river, Charlie</td>
<td>Dorian</td>
</tr>
</tbody>
</table>
<script>
test(function() {
var event_type = "foo";
var target = document.getElementById("target");
var parent = document.getElementById("parent");
var tbody = document.getElementById("table-body");
var table = document.getElementById("table");
var body = document.body;
var html = document.documentElement;
var targets = [window, document, html, body, table, tbody, parent, target];
var expected_targets = targets.concat([target, parent, tbody, table, body, html, document, window]);
var phases = [
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.CAPTURING_PHASE,
Event.AT_TARGET,
Event.AT_TARGET,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
Event.BUBBLING_PHASE,
];
var actual_targets = [], actual_phases = [];
var test_event = this.step_func(function(evt) {
if (parent === target.parentNode) {
parent.removeChild(target);
}
actual_targets.push(evt.currentTarget);
actual_phases.push(evt.eventPhase);
});
for (var i = 0; i < targets.length; i++) {
targets[i].addEventListener(event_type, test_event, true);
targets[i].addEventListener(event_type, test_event, false);
}
var evt = document.createEvent("Event");
evt.initEvent(event_type, true, true);
target.dispatchEvent(evt);
assert_array_equals(actual_targets, expected_targets, "targets");
assert_array_equals(actual_phases, phases, "phases");
}, "Event propagation path when an element in it is removed from the DOM");
</script>

View file

@ -0,0 +1,69 @@
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<script>
function createIframe(t, srcdoc = '') {
let iframe = document.createElement('iframe');
iframe.srcdoc = srcdoc;
t.add_cleanup(() => iframe.remove());
return new Promise((resolve, reject) => {
iframe.addEventListener('load', () => resolve(iframe.contentWindow));
document.body.appendChild(iframe);
});
}
// Returns a promise which will resolve with the next error event fired at any
// of `windows`, after the invocation of this function. Once one does, this
// function removes its listeners and produces that error event so that it can
// be examined (most notably for which global proxy it was targeted at).
async function nextErrorEvent(windows) {
let listener;
let p = new Promise((resolve, reject) => {
listener = (event) => { resolve(event); event.preventDefault(); };
});
for (let w of windows) {
w.addEventListener('error', listener);
}
try {
return await p;
} finally {
for (let w of windows) {
w.removeEventListener('error', listener);
}
}
}
promise_test(async t => {
let w = await createIframe(t, `<script>function listener() { throw new Error(); }<`+`/script>`);
let w2 = await createIframe(t);
let target = new w2.EventTarget();
target.addEventListener('party', w.listener);
let nextErrorPromise = nextErrorEvent([self, w, w2]);
target.dispatchEvent(new Event('party'));
let errorEvent = await nextErrorPromise;
if (errorEvent.error) {
assert_true(errorEvent.error instanceof w.Error, 'error should be an instance created inside the listener function');
}
assert_equals(errorEvent.target, w, `error event should target listener's global but instead targets ${event.currentTarget === w2 ? 'target\'s global' : 'test harness global'}`);
}, 'exception thrown in event listener function should result in error event on listener\'s global');
promise_test(async t => {
let w = await createIframe(t, `<script>listener = {};<`+`/script>`);
let w2 = await createIframe(t, `<script>handleEvent = () => { throw new Error; };<`+`/script>`);
let w3 = await createIframe(t);
w.listener.handleEvent = w2.handleEvent;
let target = new w3.EventTarget();
target.addEventListener('party', w.listener);
let nextErrorPromise = nextErrorEvent([self, w, w2, w3]);
target.dispatchEvent(new Event('party'));
let errorEvent = await nextErrorPromise;
if (errorEvent.error) {
assert_true(errorEvent.error instanceof w2.Error, 'error should be an instance created inside the listener function');
}
assert_equals(errorEvent.target, w, `error event should target listener's global but instead targets ${event.currentTarget === w2 ? 'target\'s global' : event.currentTarget === w3 ? 'function\'s global' : 'test harness global'}`);
}, 'exception thrown in event listener interface object should result in error event on listener\'s global');
</script>
</body>

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<title>Throwing in event listeners</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
setup({allow_uncaught_exception:true})
test(function() {
var errorEvents = 0;
window.onerror = this.step_func(function(e) {
assert_equals(typeof e, 'string');
++errorEvents;
});
var element = document.createElement('div');
element.addEventListener('click', function() {
throw new Error('Error from only listener');
});
element.dispatchEvent(new Event('click'));
assert_equals(errorEvents, 1);
}, "Throwing in event listener with a single listeners");
test(function() {
var errorEvents = 0;
window.onerror = this.step_func(function(e) {
assert_equals(typeof e, 'string');
++errorEvents;
});
var element = document.createElement('div');
var secondCalled = false;
element.addEventListener('click', function() {
throw new Error('Error from first listener');
});
element.addEventListener('click', this.step_func(function() {
secondCalled = true;
}), false);
element.dispatchEvent(new Event('click'));
assert_equals(errorEvents, 1);
assert_true(secondCalled);
}, "Throwing in event listener with multiple listeners");
</script>

View file

@ -0,0 +1,83 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Re-initializing events while dispatching them</title>
<link rel="author" title="Josh Matthews" href="mailto:josh@joshmatthews.net">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var events = {
'KeyboardEvent': {
'constructor': function() { return new KeyboardEvent("type", {key: "A"}); },
'init': function(ev) { ev.initKeyboardEvent("type2", true, true, null, "a", 1, "", true, "") },
'check': function(ev) {
assert_equals(ev.key, "A", "initKeyboardEvent key setter should short-circuit");
assert_false(ev.repeat, "initKeyboardEvent repeat setter should short-circuit");
assert_equals(ev.location, 0, "initKeyboardEvent location setter should short-circuit");
}
},
'MouseEvent': {
'constructor': function() { return new MouseEvent("type"); },
'init': function(ev) { ev.initMouseEvent("type2", true, true, null, 0, 1, 1, 1, 1, true, true, true, true, 1, null) },
'check': function(ev) {
assert_equals(ev.screenX, 0, "initMouseEvent screenX setter should short-circuit");
assert_equals(ev.screenY, 0, "initMouseEvent screenY setter should short-circuit");
assert_equals(ev.clientX, 0, "initMouseEvent clientX setter should short-circuit");
assert_equals(ev.clientY, 0, "initMouseEvent clientY setter should short-circuit");
assert_false(ev.ctrlKey, "initMouseEvent ctrlKey setter should short-circuit");
assert_false(ev.altKey, "initMouseEvent altKey setter should short-circuit");
assert_false(ev.shiftKey, "initMouseEvent shiftKey setter should short-circuit");
assert_false(ev.metaKey, "initMouseEvent metaKey setter should short-circuit");
assert_equals(ev.button, 0, "initMouseEvent button setter should short-circuit");
}
},
'CustomEvent': {
'constructor': function() { return new CustomEvent("type") },
'init': function(ev) { ev.initCustomEvent("type2", true, true, 1) },
'check': function(ev) {
assert_equals(ev.detail, null, "initCustomEvent detail setter should short-circuit");
}
},
'UIEvent': {
'constructor': function() { return new UIEvent("type") },
'init': function(ev) { ev.initUIEvent("type2", true, true, window, 1) },
'check': function(ev) {
assert_equals(ev.view, null, "initUIEvent view setter should short-circuit");
assert_equals(ev.detail, 0, "initUIEvent detail setter should short-circuit");
}
},
'Event': {
'constructor': function() { return new Event("type") },
'init': function(ev) { ev.initEvent("type2", true, true) },
'check': function(ev) {
assert_equals(ev.bubbles, false, "initEvent bubbles setter should short-circuit");
assert_equals(ev.cancelable, false, "initEvent cancelable setter should short-circuit");
assert_equals(ev.type, "type", "initEvent type setter should short-circuit");
}
}
};
var names = Object.keys(events);
for (var i = 0; i < names.length; i++) {
var t = async_test("Calling init" + names[i] + " while dispatching.");
t.step(function() {
var e = events[names[i]].constructor();
var target = document.createElement("div")
target.addEventListener("type", t.step_func(function() {
events[names[i]].init(e);
var o = e;
while ((o = Object.getPrototypeOf(o))) {
if (!(o.constructor.name in events)) {
break;
}
events[o.constructor.name].check(e);
}
}), false);
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
});
t.done();
}
</script>

View file

@ -0,0 +1,136 @@
<!DOCTYPE html>
<title>Event.initEvent</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
var booleans = [true, false];
booleans.forEach(function(bubbles) {
booleans.forEach(function(cancelable) {
test(function() {
var e = document.createEvent("Event")
e.initEvent("type", bubbles, cancelable)
// Step 2.
// Stop (immediate) propagation flag is tested later
assert_equals(e.defaultPrevented, false, "defaultPrevented")
assert_equals(e.returnValue, true, "returnValue")
// Step 3.
assert_equals(e.isTrusted, false, "isTrusted")
// Step 4.
assert_equals(e.target, null, "target")
assert_equals(e.srcElement, null, "srcElement")
// Step 5.
assert_equals(e.type, "type", "type")
// Step 6.
assert_equals(e.bubbles, bubbles, "bubbles")
// Step 7.
assert_equals(e.cancelable, cancelable, "cancelable")
}, "Properties of initEvent(type, " + bubbles + ", " + cancelable + ")")
})
})
test(function() {
var e = document.createEvent("Event")
e.initEvent("type 1", true, false)
assert_equals(e.type, "type 1", "type (first init)")
assert_equals(e.bubbles, true, "bubbles (first init)")
assert_equals(e.cancelable, false, "cancelable (first init)")
e.initEvent("type 2", false, true)
assert_equals(e.type, "type 2", "type (second init)")
assert_equals(e.bubbles, false, "bubbles (second init)")
assert_equals(e.cancelable, true, "cancelable (second init)")
}, "Calling initEvent multiple times (getting type).")
test(function() {
// https://bugzilla.mozilla.org/show_bug.cgi?id=998809
var e = document.createEvent("Event")
e.initEvent("type 1", true, false)
assert_equals(e.bubbles, true, "bubbles (first init)")
assert_equals(e.cancelable, false, "cancelable (first init)")
e.initEvent("type 2", false, true)
assert_equals(e.type, "type 2", "type (second init)")
assert_equals(e.bubbles, false, "bubbles (second init)")
assert_equals(e.cancelable, true, "cancelable (second init)")
}, "Calling initEvent multiple times (not getting type).")
// Step 2.
async_test(function() {
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=17715
var e = document.createEvent("Event")
e.initEvent("type", false, false)
assert_equals(e.type, "type", "type (first init)")
assert_equals(e.bubbles, false, "bubbles (first init)")
assert_equals(e.cancelable, false, "cancelable (first init)")
var target = document.createElement("div")
target.addEventListener("type", this.step_func(function() {
e.initEvent("fail", true, true)
assert_equals(e.type, "type", "type (second init)")
assert_equals(e.bubbles, false, "bubbles (second init)")
assert_equals(e.cancelable, false, "cancelable (second init)")
}), false)
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
this.done()
}, "Calling initEvent must not have an effect during dispatching.")
test(function() {
var e = document.createEvent("Event")
e.stopPropagation()
e.initEvent("type", false, false)
var target = document.createElement("div")
var called = false
target.addEventListener("type", function() { called = true }, false)
assert_false(e.cancelBubble, "cancelBubble must be false")
assert_true(target.dispatchEvent(e), "dispatchEvent must return true")
assert_true(called, "Listener must be called")
}, "Calling initEvent must unset the stop propagation flag.")
test(function() {
var e = document.createEvent("Event")
e.stopImmediatePropagation()
e.initEvent("type", false, false)
var target = document.createElement("div")
var called = false
target.addEventListener("type", function() { called = true }, false)
assert_true(target.dispatchEvent(e), "dispatchEvent must return true")
assert_true(called, "Listener must be called")
}, "Calling initEvent must unset the stop immediate propagation flag.")
async_test(function() {
var e = document.createEvent("Event")
e.initEvent("type", false, false)
var target = document.createElement("div")
target.addEventListener("type", this.step_func(function() {
e.initEvent("type2", true, true);
assert_equals(e.type, "type", "initEvent type setter should short-circuit");
assert_false(e.bubbles, "initEvent bubbles setter should short-circuit");
assert_false(e.cancelable, "initEvent cancelable setter should short-circuit");
}), false)
assert_equals(target.dispatchEvent(e), true, "dispatchEvent must return true")
this.done()
}, "Calling initEvent during propagation.")
test(function() {
var e = document.createEvent("Event")
assert_throws_js(TypeError, function() {
e.initEvent()
})
}, "First parameter to initEvent should be mandatory.")
test(function() {
var e = document.createEvent("Event")
e.initEvent("type")
assert_equals(e.type, "type", "type")
assert_false(e.bubbles, "bubbles")
assert_false(e.cancelable, "cancelable")
}, "Tests initEvent's default parameter values.")
</script>

View file

@ -0,0 +1,11 @@
test(function() {
var desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
assert_not_equals(desc1, undefined);
assert_equals(typeof desc1.get, "function");
var desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
assert_not_equals(desc2, undefined);
assert_equals(typeof desc2.get, "function");
assert_equals(desc1.get, desc2.get);
});

View file

@ -0,0 +1,48 @@
<!doctype html>
<title>Event propagation tests</title>
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
<div id=log></div>
<script src=../../resources/testharness.js></script>
<script src=../../resources/testharnessreport.js></script>
<script>
"use strict";
function testPropagationFlag(ev, expected, desc) {
test(function() {
var called = false;
var callback = function() { called = true };
this.add_cleanup(function() {
document.head.removeEventListener("foo", callback)
});
document.head.addEventListener("foo", callback);
document.head.dispatchEvent(ev);
assert_equals(called, expected, "Propagation flag");
// dispatchEvent resets the propagation flags so it will happily dispatch
// the event the second time around.
document.head.dispatchEvent(ev);
assert_equals(called, true, "Propagation flag after first dispatch");
}, desc);
}
var ev = document.createEvent("Event");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Newly-created Event");
ev.stopPropagation();
testPropagationFlag(ev, false, "After stopPropagation()");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after stopPropagation()");
var ev = document.createEvent("Event");
ev.initEvent("foo", true, false);
ev.stopImmediatePropagation();
testPropagationFlag(ev, false, "After stopImmediatePropagation()");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after stopImmediatePropagation()");
var ev = document.createEvent("Event");
ev.initEvent("foo", true, false);
ev.cancelBubble = true;
testPropagationFlag(ev, false, "After cancelBubble=true");
ev.initEvent("foo", true, false);
testPropagationFlag(ev, true, "Reinitialized after cancelBubble=true");
</script>

View file

@ -0,0 +1,64 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Event.returnValue</title>
<link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-returnvalue">
<meta name="flags" content="dom">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(function() {
var ev = new Event("foo");
assert_true(ev.returnValue, "returnValue");
}, "When an event is created, returnValue should be initialized to true.");
test(function() {
var ev = new Event("foo", {"cancelable": false});
assert_false(ev.cancelable, "cancelable (before)");
ev.preventDefault();
assert_false(ev.cancelable, "cancelable (after)");
assert_true(ev.returnValue, "returnValue");
}, "preventDefault() should not change returnValue if cancelable is false.");
test(function() {
var ev = new Event("foo", {"cancelable": false});
assert_false(ev.cancelable, "cancelable (before)");
ev.returnValue = false;
assert_false(ev.cancelable, "cancelable (after)");
assert_true(ev.returnValue, "returnValue");
}, "returnValue=false should have no effect if cancelable is false.");
test(function() {
var ev = new Event("foo", {"cancelable": true});
assert_true(ev.cancelable, "cancelable (before)");
ev.preventDefault();
assert_true(ev.cancelable, "cancelable (after)");
assert_false(ev.returnValue, "returnValue");
}, "preventDefault() should change returnValue if cancelable is true.");
test(function() {
var ev = new Event("foo", {"cancelable": true});
assert_true(ev.cancelable, "cancelable (before)");
ev.returnValue = false;
assert_true(ev.cancelable, "cancelable (after)");
assert_false(ev.returnValue, "returnValue");
}, "returnValue should change returnValue if cancelable is true.");
test(function() {
var ev = document.createEvent("Event");
ev.returnValue = false;
ev.initEvent("foo", true, true);
assert_true(ev.bubbles, "bubbles");
assert_true(ev.cancelable, "cancelable");
assert_true(ev.returnValue, "returnValue");
}, "initEvent should unset returnValue.");
test(function() {
var ev = new Event("foo", {"cancelable": true});
ev.preventDefault();
ev.returnValue = true;// no-op
assert_true(ev.defaultPrevented);
assert_false(ev.returnValue);
}, "returnValue=true should have no effect once the canceled flag was set.");
</script>
</body>
</html>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Event's stopImmediatePropagation</title>
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-stopimmediatepropagation">
<link rel="author" href="mailto:d@domenic.me" title="Domenic Denicola">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="target"></div>
<script>
"use strict";
setup({ single_test: true });
const target = document.querySelector("#target");
let timesCalled = 0;
target.addEventListener("test", e => {
++timesCalled;
e.stopImmediatePropagation();
assert_equals(e.cancelBubble, true, "The stop propagation flag must have been set");
});
target.addEventListener("test", () => {
++timesCalled;
});
const e = new Event("test");
target.dispatchEvent(e);
assert_equals(timesCalled, 1, "The second listener must not have been called");
done();
</script>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" title="Joey Arhar" href="mailto:jarhar@chromium.org">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<script>
test(t => {
const element = document.createElement('div');
element.addEventListener('click', () => {
event.stopPropagation();
}, { capture: true });
element.addEventListener('click',
t.unreached_func('stopPropagation in the capture handler should have canceled this bubble handler.'));
element.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
});
</script>

View file

@ -0,0 +1,179 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Event constructors</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function assert_props(iface, event, defaults) {
assert_true(event instanceof self[iface]);
expected[iface].properties.forEach(function(p) {
var property = p[0], value = p[defaults ? 1 : 2];
assert_true(property in event,
"Event " + format_value(event) + " should have a " +
property + " property");
assert_equals(event[property], value,
"The value of the " + property + " property should be " +
format_value(value));
});
if ("parent" in expected[iface]) {
assert_props(expected[iface].parent, event, defaults);
}
}
// Class declarations don't go on the global by default, so put it there ourselves:
self.SubclassedEvent = class SubclassedEvent extends Event {
constructor(name, props) {
super(name, props);
if (props && typeof(props) == "object" && "customProp" in props) {
this.customProp = props.customProp;
} else {
this.customProp = 5;
}
}
get fixedProp() {
return 17;
}
}
var EventModifierInit = [
["ctrlKey", false, true],
["shiftKey", false, true],
["altKey", false, true],
["metaKey", false, true],
];
var expected = {
"Event": {
"properties": [
["bubbles", false, true],
["cancelable", false, true],
["isTrusted", false, false],
],
},
"UIEvent": {
"parent": "Event",
"properties": [
["view", null, window],
["detail", 0, 7],
],
},
"FocusEvent": {
"parent": "UIEvent",
"properties": [
["relatedTarget", null, document],
],
},
"MouseEvent": {
"parent": "UIEvent",
"properties": EventModifierInit.concat([
["screenX", 0, 40],
["screenY", 0, 40],
["clientX", 0, 40],
["clientY", 0, 40],
["button", 0, 40],
["buttons", 0, 40],
["relatedTarget", null, document],
]),
},
"WheelEvent": {
"parent": "MouseEvent",
"properties": [
["deltaX", 0.0, 3.1],
["deltaY", 0.0, 3.1],
["deltaZ", 0.0, 3.1],
["deltaMode", 0, 40],
],
},
"KeyboardEvent": {
"parent": "UIEvent",
"properties": EventModifierInit.concat([
["key", "", "string"],
["code", "", "string"],
["location", 0, 7],
["repeat", false, true],
["isComposing", false, true],
["charCode", 0, 7],
["keyCode", 0, 7],
["which", 0, 7],
]),
},
"CompositionEvent": {
"parent": "UIEvent",
"properties": [
["data", "", "string"],
],
},
"SubclassedEvent": {
"parent": "Event",
"properties": [
["customProp", 5, 8],
["fixedProp", 17, 17],
],
},
};
Object.keys(expected).forEach(function(iface) {
test(function() {
var event = new self[iface]("type");
assert_props(iface, event, true);
}, iface + " constructor (no argument)");
test(function() {
var event = new self[iface]("type", undefined);
assert_props(iface, event, true);
}, iface + " constructor (undefined argument)");
test(function() {
var event = new self[iface]("type", null);
assert_props(iface, event, true);
}, iface + " constructor (null argument)");
test(function() {
var event = new self[iface]("type", {});
assert_props(iface, event, true);
}, iface + " constructor (empty argument)");
test(function() {
var dictionary = {};
expected[iface].properties.forEach(function(p) {
var property = p[0], value = p[1];
dictionary[property] = value;
});
var event = new self[iface]("type", dictionary);
assert_props(iface, event, true);
}, iface + " constructor (argument with default values)");
test(function() {
function fill_in(iface, dictionary) {
if ("parent" in expected[iface]) {
fill_in(expected[iface].parent, dictionary)
}
expected[iface].properties.forEach(function(p) {
var property = p[0], value = p[2];
dictionary[property] = value;
});
}
var dictionary = {};
fill_in(iface, dictionary);
var event = new self[iface]("type", dictionary);
assert_props(iface, event, false);
}, iface + " constructor (argument with non-default values)");
});
test(function () {
assert_throws_js(TypeError, function() {
new UIEvent("x", { view: 7 })
});
}, "UIEvent constructor (view argument with wrong type)")
</script>

View file

@ -0,0 +1,27 @@
<!doctype html>
<meta charset="utf-8">
<title>event.timeStamp is initialized using event's relevant global object</title>
<link rel="help" href="https://dom.spec.whatwg.org/#ref-for-dom-event-timestamp%E2%91%A1">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<body>
<script>
const t = async_test();
t.step_timeout(() => {
const iframeDelayed = document.createElement("iframe");
iframeDelayed.onload = t.step_func_done(() => {
// Use eval() to eliminate false-positive test result for WebKit builds before r280256,
// which invoked WebIDL accessors in context of lexical (caller) global object.
const timeStampExpected = iframeDelayed.contentWindow.eval(`new Event("foo").timeStamp`);
const eventDelayed = new iframeDelayed.contentWindow.Event("foo");
const {get} = Object.getOwnPropertyDescriptor(Event.prototype, "timeStamp");
assert_approx_equals(get.call(eventDelayed), timeStampExpected, 5, "via Object.getOwnPropertyDescriptor");
Object.setPrototypeOf(eventDelayed, Event.prototype);
assert_approx_equals(eventDelayed.timeStamp, timeStampExpected, 5, "via Object.setPrototypeOf");
});
document.body.append(iframeDelayed);
}, 1000);
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script type="text/javascript">
'use strict';
for (let eventType of ["MouseEvent", "KeyboardEvent", "WheelEvent", "FocusEvent"]) {
test(function() {
let before = performance.now();
let e = new window[eventType]('test');
let after = performance.now();
assert_greater_than_equal(e.timeStamp, before, "Event timestamp should be greater than performance.now() timestamp taken before its creation");
assert_less_than_equal(e.timeStamp, after, "Event timestamp should be less than performance.now() timestamp taken after its creation");
}, `Constructed ${eventType} timestamp should be high resolution and have the same time origin as performance.now()`);
}
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script type="text/javascript">
'use strict';
for (let eventType of ["GamepadEvent"]) {
test(function() {
let before = performance.now();
let e = new window[eventType]('test');
let after = performance.now();
assert_greater_than_equal(e.timeStamp, before, "Event timestamp should be greater than performance.now() timestamp taken before its creation");
assert_less_than_equal(e.timeStamp, after, "Event timestamp should be less than performance.now() timestamp taken after its creation");
}, `Constructed ${eventType} timestamp should be high resolution and have the same time origin as performance.now()`);
}
</script>

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script type="text/javascript">
'use strict';
// Computes greatest common divisor of a and b using Euclid's algorithm
function computeGCD(a, b) {
if (!Number.isInteger(a) || !Number.isInteger(b)) {
throw new Error('Parameters must be integer numbers');
}
var r;
while (b != 0) {
r = a % b;
a = b;
b = r;
}
return (a < 0) ? -a : a;
}
// Finds minimum resolution Δ given a set of samples which are known to be in the form of N*Δ.
// We use GCD of all samples as a simple estimator.
function estimateMinimumResolution(samples) {
var gcd;
for (const sample of samples) {
gcd = gcd ? computeGCD(gcd, sample) : sample;
}
return gcd;
}
test(function() {
const samples = [];
for (var i = 0; i < 1e3; i++) {
var deltaInMicroSeconds = 0;
const e1 = new MouseEvent('test1');
do {
const e2 = new MouseEvent('test2');
deltaInMicroSeconds = Math.round((e2.timeStamp - e1.timeStamp) * 1000);
} while (deltaInMicroSeconds == 0) // only collect non-zero samples
samples.push(deltaInMicroSeconds);
}
const minResolution = estimateMinimumResolution(samples);
assert_greater_than_equal(minResolution, 5);
}, 'Event timestamp should not have a resolution better than 5 microseconds');
</script>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<title>Event.type set to the empty string</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-type">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
function do_test(t, e) {
assert_equals(e.type, "", "type");
assert_equals(e.bubbles, false, "bubbles");
assert_equals(e.cancelable, false, "cancelable");
var target = document.createElement("div");
var handled = false;
target.addEventListener("", t.step_func(function(e) {
handled = true;
}));
assert_true(target.dispatchEvent(e));
assert_true(handled);
}
async_test(function() {
var e = document.createEvent("Event");
e.initEvent("", false, false);
do_test(this, e);
this.done();
}, "initEvent");
async_test(function() {
var e = new Event("");
do_test(this, e);
this.done();
}, "Constructor");
</script>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<title>Event.type</title>
<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-type">
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id="log"></div>
<script>
test(function() {
var e = document.createEvent("Event")
assert_equals(e.type, "");
}, "Event.type should initially be the empty string");
test(function() {
var e = document.createEvent("Event")
e.initEvent("foo", false, false)
assert_equals(e.type, "foo")
}, "Event.type should be initialized by initEvent");
test(function() {
var e = new Event("bar")
assert_equals(e.type, "bar")
}, "Event.type should be initialized by the constructor");
</script>

Some files were not shown because too many files have changed in this diff Show more