Title: [236779] trunk
Revision
236779
Author
[email protected]
Date
2018-10-02 17:28:21 -0700 (Tue, 02 Oct 2018)

Log Message

radio / checkbox inputs should fire "click, input, change" events in order when clicked
https://bugs.webkit.org/show_bug.cgi?id=190223

Reviewed by Ryosuke Niwa.

LayoutTests/imported/w3c:

Rebaseline a few WPT tests that are now passing. I have verified that those are passing in Gecko and Blink
as well.

* web-platform-tests/html/semantics/forms/the-input-element/checkbox-click-events-expected.txt:
* web-platform-tests/html/semantics/forms/the-input-element/checkbox-expected.txt:
* web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt:

Source/WebCore:

radio / checkbox inputs should fire "click, input, change" events in order when clicked:
- https://html.spec.whatwg.org/#radio-button-state-(type=radio)
- https://html.spec.whatwg.org/#checkbox-state-(type=checkbox)
- https://dom.spec.whatwg.org/#ref-for-eventtarget-activation-behaviorâ‘¢ (step 11)

Gecko and Blink already behave this way. However, WebKit has the following issues:
- the input event is not fired
- the click event is fired after the change event

No new tests, updated / rebaselined existing tests.

* html/BaseCheckableInputType.cpp:
(WebCore::BaseCheckableInputType::fireInputAndChangeEvents):
* html/BaseCheckableInputType.h:
* html/CheckboxInputType.cpp:
(WebCore::CheckboxInputType::willDispatchClick):
(WebCore::CheckboxInputType::didDispatchClick):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::setChecked):
* html/HTMLInputElement.h:
* html/RadioInputType.cpp:
(WebCore::RadioInputType::willDispatchClick):
(WebCore::RadioInputType::didDispatchClick):

LayoutTests:

Update existing test to reflect behavior change. I have verified that our new behavior
on this test is consistent with Gecko and Chrome.

* fast/forms/radio/radio-group-keyboard-change-event-expected.txt:
* fast/forms/radio/radio-group-keyboard-change-event.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (236778 => 236779)


--- trunk/LayoutTests/ChangeLog	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/ChangeLog	2018-10-03 00:28:21 UTC (rev 236779)
@@ -1,5 +1,18 @@
 2018-10-02  Chris Dumez  <[email protected]>
 
+        radio / checkbox inputs should fire "click, input, change" events in order when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=190223
+
+        Reviewed by Ryosuke Niwa.
+
+        Update existing test to reflect behavior change. I have verified that our new behavior
+        on this test is consistent with Gecko and Chrome.
+
+        * fast/forms/radio/radio-group-keyboard-change-event-expected.txt:
+        * fast/forms/radio/radio-group-keyboard-change-event.html:
+
+2018-10-02  Chris Dumez  <[email protected]>
+
         fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection
         https://bugs.webkit.org/show_bug.cgi?id=190218
 

Modified: trunk/LayoutTests/fast/forms/radio/radio-group-keyboard-change-event-expected.txt (236778 => 236779)


--- trunk/LayoutTests/fast/forms/radio/radio-group-keyboard-change-event-expected.txt	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/fast/forms/radio/radio-group-keyboard-change-event-expected.txt	2018-10-03 00:28:21 UTC (rev 236779)
@@ -8,10 +8,22 @@
 
 d e f
 
+b dispatched click event
+PASS: b is checked
+b dispatched input event
+PASS: b is checked
 b dispatched change event
+PASS: b is checked
+c dispatched click event
+PASS: c is checked
+c dispatched input event
+PASS: c is checked
 c dispatched change event
-e dispatched change event
-f dispatched change event
+PASS: c is checked
+e dispatched click event
+PASS: e is checked
+f dispatched click event
+PASS: f is checked
 PASS: a is not checked
 PASS: b is not checked
 PASS: c is checked

Modified: trunk/LayoutTests/fast/forms/radio/radio-group-keyboard-change-event.html (236778 => 236779)


--- trunk/LayoutTests/fast/forms/radio/radio-group-keyboard-change-event.html	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/fast/forms/radio/radio-group-keyboard-change-event.html	2018-10-03 00:28:21 UTC (rev 236779)
@@ -8,17 +8,17 @@
 radio button should fire change events.
 
 <p>
-<input type=radio name=aaa value=a checked _onchange_="handleChange(event)" _onclick_="handleClick(event)">a
-<input type=radio name=aaa value=b _onchange_="handleChange(event)" _onclick_="handleClick(event)">b
-<input type=radio name=aaa value=c _onchange_="handleChange(event)" _onclick_="handleClick(event)">c
+<input type=radio name=aaa value=a checked _onchange_="handleChange(event)" _onclick_="handleClick(event)" _oninput_="handleInput(event)">a
+<input type=radio name=aaa value=b _onchange_="handleChange(event)" _onclick_="handleClick(event)" _oninput_="handleInput(event)">b
+<input type=radio name=aaa value=c _onchange_="handleChange(event)" _onclick_="handleClick(event)" _oninput_="handleInput(event)">c
 
 <p>For manual testing, focus a radio button in the second group and use the arrow keys. Change events
 should still be dispatched but the checked radio should not change.
 
 <p>
-<input type=radio name=bbb value=d checked _onchange_="handleChange(event)" _onclick_="handleClick(event)">d
-<input type=radio name=bbb value=e _onchange_="handleChange(event)" _onclick_="handleClick(event)">e
-<input type=radio name=bbb value=f _onchange_="handleChange(event)" _onclick_="handleClick(event)">f
+<input type=radio name=bbb value=d checked _onchange_="handleChange(event)" _onclick_="handleClick(event)" _oninput_="handleInput(event)">d
+<input type=radio name=bbb value=e _onchange_="handleChange(event)" _onclick_="handleClick(event)" _oninput_="handleInput(event)">e
+<input type=radio name=bbb value=f _onchange_="handleChange(event)" _onclick_="handleClick(event)" _oninput_="handleInput(event)">f
 
 <pre id=out></pre>
 
@@ -26,15 +26,25 @@
 
 var preventClickValues = 'def';
 
+function handleInput(e)
+{
+    var value = e.target.value;
+    print(value + ' dispatched input event');
+    assertChecked(e.target.value);
+}
+
 function handleChange(e)
 {
     var value = e.target.value;
     print(value + ' dispatched change event');
+    assertChecked(e.target.value);
 }
 
 function handleClick(e)
 {
     var value = e.target.value;
+    print(value + ' dispatched click event');
+    assertChecked(e.target.value);
     if (preventClickValues.indexOf(value) !== -1)
         e.preventDefault();
 }

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (236778 => 236779)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-10-03 00:28:21 UTC (rev 236779)
@@ -1,5 +1,19 @@
 2018-10-02  Chris Dumez  <[email protected]>
 
+        radio / checkbox inputs should fire "click, input, change" events in order when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=190223
+
+        Reviewed by Ryosuke Niwa.
+
+        Rebaseline a few WPT tests that are now passing. I have verified that those are passing in Gecko and Blink
+        as well.
+
+        * web-platform-tests/html/semantics/forms/the-input-element/checkbox-click-events-expected.txt:
+        * web-platform-tests/html/semantics/forms/the-input-element/checkbox-expected.txt:
+        * web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt:
+
+2018-10-02  Chris Dumez  <[email protected]>
+
         fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection
         https://bugs.webkit.org/show_bug.cgi?id=190218
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/checkbox-click-events-expected.txt (236778 => 236779)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/checkbox-click-events-expected.txt	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/checkbox-click-events-expected.txt	2018-10-03 00:28:21 UTC (rev 236779)
@@ -1,7 +1,7 @@
 
 
 PASS clicking and preventDefaulting a checkbox causes the checkbox to be checked during the click handler but reverted 
-FAIL a checkbox input emits click, input, change events in order after synthetic click assert_array_equals: lengths differ, expected 3 got 2
-FAIL a checkbox input emits click, input, change events in order after dispatching click event assert_array_equals: lengths differ, expected 3 got 2
-FAIL checkbox input respects cancel behavior on synthetic clicks assert_array_equals: lengths differ, expected 1 got 2
+PASS a checkbox input emits click, input, change events in order after synthetic click 
+PASS a checkbox input emits click, input, change events in order after dispatching click event 
+PASS checkbox input respects cancel behavior on synthetic clicks 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/checkbox-expected.txt (236778 => 236779)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/checkbox-expected.txt	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/checkbox-expected.txt	2018-10-03 00:28:21 UTC (rev 236779)
@@ -1,5 +1,5 @@
 
-FAIL click on mutable checkbox fires a click event, then an input event, then a change event assert_true: change event should fire after click event expected true got false
+PASS click on mutable checkbox fires a click event, then an input event, then a change event 
 PASS click on non-mutable checkbox doesn't fire the input or change event 
 PASS pre-activation steps on unchecked checkbox 
 PASS pre-activation steps on checked checkbox 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt (236778 => 236779)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/forms/the-input-element/radio-expected.txt	2018-10-03 00:28:21 UTC (rev 236779)
@@ -1,5 +1,5 @@
 
-FAIL click on mutable radio fires click event, then input event, then change event Can't find variable: click_fired
+PASS click on mutable radio fires click event, then input event, then change event 
 PASS click on non-mutable radio doesn't fire the input event 
 PASS click on non-mutable radio doesn't fire the change event 
 PASS canceled activation steps on unchecked radio 

Modified: trunk/Source/WebCore/ChangeLog (236778 => 236779)


--- trunk/Source/WebCore/ChangeLog	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/ChangeLog	2018-10-03 00:28:21 UTC (rev 236779)
@@ -1,5 +1,36 @@
 2018-10-02  Chris Dumez  <[email protected]>
 
+        radio / checkbox inputs should fire "click, input, change" events in order when clicked
+        https://bugs.webkit.org/show_bug.cgi?id=190223
+
+        Reviewed by Ryosuke Niwa.
+
+        radio / checkbox inputs should fire "click, input, change" events in order when clicked:
+        - https://html.spec.whatwg.org/#radio-button-state-(type=radio)
+        - https://html.spec.whatwg.org/#checkbox-state-(type=checkbox)
+        - https://dom.spec.whatwg.org/#ref-for-eventtarget-activation-behaviorâ‘¢ (step 11)
+
+        Gecko and Blink already behave this way. However, WebKit has the following issues:
+        - the input event is not fired
+        - the click event is fired after the change event
+
+        No new tests, updated / rebaselined existing tests.
+
+        * html/BaseCheckableInputType.cpp:
+        (WebCore::BaseCheckableInputType::fireInputAndChangeEvents):
+        * html/BaseCheckableInputType.h:
+        * html/CheckboxInputType.cpp:
+        (WebCore::CheckboxInputType::willDispatchClick):
+        (WebCore::CheckboxInputType::didDispatchClick):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::setChecked):
+        * html/HTMLInputElement.h:
+        * html/RadioInputType.cpp:
+        (WebCore::RadioInputType::willDispatchClick):
+        (WebCore::RadioInputType::didDispatchClick):
+
+2018-10-02  Chris Dumez  <[email protected]>
+
         fieldset.elements should return an HTMLCollection instead of an HTMLFormControlsCollection
         https://bugs.webkit.org/show_bug.cgi?id=190218
 

Modified: trunk/Source/WebCore/html/BaseCheckableInputType.cpp (236778 => 236779)


--- trunk/Source/WebCore/html/BaseCheckableInputType.cpp	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/html/BaseCheckableInputType.cpp	2018-10-03 00:28:21 UTC (rev 236779)
@@ -119,4 +119,17 @@
     return true;
 }
 
+void BaseCheckableInputType::fireInputAndChangeEvents()
+{
+    if (!element()->isConnected())
+        return;
+
+    if (!shouldSendChangeEventAfterCheckedChanged())
+        return;
+
+    element()->setTextAsOfLastFormControlChangeEvent(String());
+    element()->dispatchInputEvent();
+    element()->dispatchFormControlChangeEvent();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/BaseCheckableInputType.h (236778 => 236779)


--- trunk/Source/WebCore/html/BaseCheckableInputType.h	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/html/BaseCheckableInputType.h	2018-10-03 00:28:21 UTC (rev 236779)
@@ -39,6 +39,7 @@
 protected:
     explicit BaseCheckableInputType(HTMLInputElement& element) : InputType(element) { }
     void handleKeydownEvent(KeyboardEvent&) override;
+    void fireInputAndChangeEvents();
 
 private:
     FormControlState saveFormControlState() const override;

Modified: trunk/Source/WebCore/html/CheckboxInputType.cpp (236778 => 236779)


--- trunk/Source/WebCore/html/CheckboxInputType.cpp	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/html/CheckboxInputType.cpp	2018-10-03 00:28:21 UTC (rev 236779)
@@ -76,7 +76,7 @@
     if (state.indeterminate)
         element()->setIndeterminate(false);
 
-    element()->setChecked(!state.checked, DispatchChangeEvent);
+    element()->setChecked(!state.checked);
 }
 
 void CheckboxInputType::didDispatchClick(Event& event, const InputElementClickState& state)
@@ -85,7 +85,8 @@
         ASSERT(element());
         element()->setIndeterminate(state.indeterminate);
         element()->setChecked(state.checked);
-    }
+    } else
+        fireInputAndChangeEvents();
 
     // The work we did in willDispatchClick was default handling.
     event.setDefaultHandled();

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (236778 => 236779)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2018-10-03 00:28:21 UTC (rev 236779)
@@ -912,7 +912,7 @@
     return m_inputType->isTextType();
 }
 
-void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventBehavior)
+void HTMLInputElement::setChecked(bool nowChecked)
 {
     if (checked() == nowChecked)
         return;
@@ -935,16 +935,6 @@
             cache->checkedStateChanged(this);
     }
 
-    // Only send a change event for items in the document (avoid firing during
-    // parsing) and don't send a change event for a radio button that's getting
-    // unchecked to match other browsers. DOM is not a useful standard for this
-    // because it says only to fire change events at "lose focus" time, which is
-    // definitely wrong in practice for these types of elements.
-    if (eventBehavior != DispatchNoEvent && isConnected() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
-        setTextAsOfLastFormControlChangeEvent(String());
-        dispatchFormControlChangeEvent();
-    }
-
     invalidateStyleForSubtree();
 }
 

Modified: trunk/Source/WebCore/html/HTMLInputElement.h (236778 => 236779)


--- trunk/Source/WebCore/html/HTMLInputElement.h	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/html/HTMLInputElement.h	2018-10-03 00:28:21 UTC (rev 236779)
@@ -155,7 +155,7 @@
 #endif
 
     bool checked() const { return m_isChecked; }
-    WEBCORE_EXPORT void setChecked(bool, TextFieldEventBehavior = DispatchNoEvent);
+    WEBCORE_EXPORT void setChecked(bool);
 
     // 'indeterminate' is a state independent of the checked state that causes the control to draw in a way that hides the actual state.
     bool indeterminate() const { return m_isIndeterminate; }

Modified: trunk/Source/WebCore/html/RadioInputType.cpp (236778 => 236779)


--- trunk/Source/WebCore/html/RadioInputType.cpp	2018-10-03 00:26:41 UTC (rev 236778)
+++ trunk/Source/WebCore/html/RadioInputType.cpp	2018-10-03 00:28:21 UTC (rev 236779)
@@ -157,7 +157,7 @@
     state.checked = element()->checked();
     state.checkedRadioButton = element()->checkedRadioButtonForGroup();
 
-    element()->setChecked(true, DispatchChangeEvent);
+    element()->setChecked(true);
 }
 
 void RadioInputType::didDispatchClick(Event& event, const InputElementClickState& state)
@@ -169,7 +169,8 @@
         ASSERT(element());
         if (button && button->isRadioButton() && button->form() == element()->form() && button->name() == element()->name())
             button->setChecked(true);
-    }
+    } else
+        fireInputAndChangeEvents();
 
     // The work we did in willDispatchClick was default handling.
     event.setDefaultHandled();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to