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();