Auto merge of #25488 - pshaughn:clickactivate, r=jdm

Event dispatch rewritten to align to spec, activate on clicks better

I went over the changes to the event dispatch spec that had accumulated over the past few years, rewriting dispatch/invoke/inner-invoke almost completely and modifying other code where it was relevant. Most of the remaining obvious deviations from spec are things that will only come up when we start handling events in shadow DOM.

I am pushing now because I want to see CI test results, but please do not approve this PR just if automated test improvements look good. I may have broken some actual UI interactions in the course of fixing synthetic events, and some manual testing is needed, including checking that manual interactions with interactive content continue to fire the events they're supposed to.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #25384 and fix #22783 and fix #25199

<!-- Either: -->
- [ ] There are automated tests for the synthetic-click parts of these changes, BUT the effects on real UI events need some manual testing before merging

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2020-02-13 17:37:12 -05:00 committed by GitHub
commit e697e6cca7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 466 additions and 556 deletions

View file

@ -1,20 +1,4 @@
[Event-dispatch-click.html]
type: testharness
expected: TIMEOUT
[basic with dispatchEvent()]
expected: FAIL
[look at parents when event bubbles]
expected: FAIL
[pick the first with activation behavior <input type=checkbox>]
expected: FAIL
[pick the first with activation behavior <a href>]
expected: TIMEOUT
[event state during post-click handling]
expected: TIMEOUT
[redispatch during post-click handling]
expected: TIMEOUT
expected: FAIL

View file

@ -1,4 +0,0 @@
[Event-dispatch-handlers-changed.html]
[ Dispatch additional events inside an event listener ]
expected: FAIL

View file

@ -1,4 +0,0 @@
[Event-dispatch-order-at-target.html]
[Listeners are invoked in correct order (AT_TARGET phase)]
expected: FAIL

View file

@ -30,6 +30,4 @@
[If the event's initialized flag is not set, an InvalidStateError must be thrown (WheelEvent).]
expected: FAIL
[Capturing event listeners should be called before non-capturing ones]
expected: FAIL

View file

@ -1,12 +0,0 @@
[button-click-submits.html]
type: testharness
expected: TIMEOUT
[clicking a button by dispatching an event should trigger a submit (form connected)]
expected: TIMEOUT
[clicking the child of a button by dispatching a bubbling event should trigger a submit]
expected: TIMEOUT
[clicking the child of a button with .click() should trigger a submit]
expected: TIMEOUT

View file

@ -1,11 +0,0 @@
[checkbox-click-events.html]
type: testharness
[clicking and preventDefaulting a checkbox causes the checkbox to be checked during the click handler but reverted]
expected: FAIL
[a checkbox input emits click, input, change events in order after dispatching click event]
expected: FAIL
[checkbox input respects cancel behavior on synthetic clicks]
expected: FAIL

View file

@ -1,5 +0,0 @@
[checkbox-detached-change-event.html]
expected: TIMEOUT
[This test will pass if <input type=checkbox> emits change events while detached from document.body]
expected: TIMEOUT

View file

@ -1,8 +0,0 @@
[checkbox.html]
type: testharness
[canceled activation steps on unchecked checkbox]
expected: FAIL
[canceled activation steps on unchecked checkbox (indeterminate=true in onclick)]
expected: FAIL

View file

@ -1,5 +0,0 @@
[radio-detached-change-event.html]
expected: TIMEOUT
[This test will pass if <input type=radio> emits change events while detached from document.body]
expected: TIMEOUT

View file

@ -1,5 +0,0 @@
[radio-input-cancel.html]
type: testharness
[radio input cancel behavior reverts state]
expected: FAIL

View file

@ -1,5 +0,0 @@
[proxy-click-to-associated-element.html]
type: testharness
[clicking a label that prevents the event's default should not proxy click events]
expected: FAIL

View file

@ -1,5 +0,0 @@
[task_microtask_ordering.html]
expected: TIMEOUT
[Level 1 bossfight (synthetic click)]
expected: TIMEOUT

View file

@ -1,5 +0,0 @@
[dispatchEvent.click.checkbox.html]
type: testharness
[Test Description: MouseEvent: Default action is performed when a synthetic click event is dispatched on a checkbox element]
expected: FAIL

View file

@ -18848,7 +18848,7 @@
"testharness"
],
"mozilla/event_dispatch_order.html": [
"48513cfff42b8635eb8822a903e7e85250a7ac51",
"172ae368c707e695fc334df491d62c44dfb81566",
"testharness"
],
"mozilla/event_handler_syntax_error.html": [

View file

@ -1,5 +1,6 @@
<html>
<head>
<title>Even in the AT_TARGET phase, capture handlers fire before bubble handlers.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
@ -7,25 +8,33 @@
<div id="foo"></div>
<script>
test(function() {
var sawBubble = false;
var sawCapture = false;
var sawBubbleTwice = false;
function handler(ev) {
// Added first, but it's a bubble so it shouldn't fire until
// after the capture.
assert_equals(ev.eventPhase, ev.AT_TARGET);
assert_equals(sawCapture, true);
assert_equals(sawBubble, false);
assert_equals(sawCapture, false);
assert_equals(sawBubbleTwice, false);
sawBubble = true;
}
function handler2(ev) {
// Capture: this should fire before both bubbles
assert_equals(ev.eventPhase, ev.AT_TARGET);
assert_equals(sawBubble, true);
assert_equals(sawCapture, false);
assert_equals(sawBubble, false);
assert_equals(sawBubbleTwice, false);
sawCapture = true;
}
function handler3(ev) {
// And this one fires last.
assert_equals(ev.eventPhase, ev.AT_TARGET);
assert_equals(sawBubble, true);
assert_equals(sawCapture, true);
assert_equals(sawBubble, true);
assert_equals(sawBubbleTwice, false);
sawBubbleTwice = true;
}