Skip to content
Permalink
Browse files
[Forms] Spin buttons of number input type should fire both input and …
…change event

https://bugs.webkit.org/show_bug.cgi?id=75067

Patch by Yosifumi Inoue <yosin@chromium.org> on 2012-02-20
Reviewed by Kent Tamura.

Source/WebCore:

This patch makes spin button in number input field clicks to fire input and change events as described in WHATWG HTML5 specification.
To implement this behavior, this patch introduces new value DispatchInputAndChangeEvent in TextFieldEventBehavior.

Test: fast/forms/number/spin-button-events.html

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::stepUpFromRenderer): Pass DispatchInputAndChangeEvent instead of DispatchChangeEvent to applyStep, setValue, and setValueAsNumber.
* html/HTMLTextFormControlElement.h: Add new enum value DispatchInputAndChangeEvent to TextFieldEventBehavior.
* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::setValue): Handle DispatchInputAndChangeEvent and use RefPtr for element to keep reference.

LayoutTests:

* fast/forms/number/spin-button-events-expected.txt: Added.
* fast/forms/number/spin-button-events.html: Added.

Canonical link: https://commits.webkit.org/96049@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@108228 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
yosinch authored and webkit-commit-queue committed Feb 20, 2012
1 parent 8b12f74 commit e2fd194a748899caaf604941b67a6ae500ede104
@@ -1,3 +1,13 @@
2012-02-20 Yosifumi Inoue <yosin@chromium.org>

[Forms] Spin buttons of number input type should fire both input and change event
https://bugs.webkit.org/show_bug.cgi?id=75067

Reviewed by Kent Tamura.

* fast/forms/number/spin-button-events-expected.txt: Added.
* fast/forms/number/spin-button-events.html: Added.

2012-02-20 Shinya Kawanaka <shinyak@chromium.org>

Attached/Detached state must be testable
@@ -0,0 +1,13 @@
BUG 75067 - [Forms] Spin buttons of number input type should fire both input and change event


Manualt test steps

Click Up part of spin button
See "Result" section
There are "oninput(1)" and "onchange(1)".
Result

oninput(1)
onchange(1)

@@ -0,0 +1,32 @@
<h1>BUG <a href="https://bugs.webkit.org/show_bug.cgi?id=75067">75067</a> - [Forms] Spin buttons of number input type should fire both input and change event</h1>
<input id="num1" type="number" value="0">
<h2>Manualt test steps</h2>
<ol>
<li>Click Up part of spin button</li>
<li>See "Result" section</li>
<li>There are "oninput(1)" and "onchange(1)".
</ol>
<h2>Result</h2>
<div id="logs"></div>
<script>
var logs = document.getElementById("logs");
var num1 = document.getElementById("num1");
function log(msg) { logs.innerHTML += msg + "<br>"; }
num1.onchange = function () { log("onchange(" + num1.value + ")"); }
num1.oninput = function () { log("oninput(" + num1.value + ")"); }

function testIt() {
layoutTestController.dumpAsText();

// Click spin Up button
eventSender.mouseMoveTo(
num1.offsetLeft + num1.offsetWidth - 5,
num1.offsetTop + 5)
eventSender.mouseDown();
eventSender.mouseUp();
}

if (window.layoutTestController) {
testIt();
}
</script>
@@ -1,3 +1,21 @@
2012-02-20 Yosifumi Inoue <yosin@chromium.org>

[Forms] Spin buttons of number input type should fire both input and change event
https://bugs.webkit.org/show_bug.cgi?id=75067

Reviewed by Kent Tamura.

This patch makes spin button in number input field clicks to fire input and change events as described in WHATWG HTML5 specification.
To implement this behavior, this patch introduces new value DispatchInputAndChangeEvent in TextFieldEventBehavior.

Test: fast/forms/number/spin-button-events.html

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::stepUpFromRenderer): Pass DispatchInputAndChangeEvent instead of DispatchChangeEvent to applyStep, setValue, and setValueAsNumber.
* html/HTMLTextFormControlElement.h: Add new enum value DispatchInputAndChangeEvent to TextFieldEventBehavior.
* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::setValue): Handle DispatchInputAndChangeEvent and use RefPtr for element to keep reference.

2012-02-20 Shinya Kawanaka <shinyak@chromium.org>

Attached/Detached state must be testable
@@ -1636,10 +1636,10 @@ void HTMLInputElement::stepUpFromRenderer(int n)
current = m_inputType->minimum() - nextDiff;
if (current > m_inputType->maximum() - nextDiff)
current = m_inputType->maximum() - nextDiff;
setValueAsNumber(current, ec, DispatchChangeEvent);
setValueAsNumber(current, ec, DispatchInputAndChangeEvent);
}
if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()), DispatchChangeEvent);
setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()), DispatchInputAndChangeEvent);
else {
ExceptionCode ec;
if (stepMismatch(value())) {
@@ -1659,14 +1659,14 @@ void HTMLInputElement::stepUpFromRenderer(int n)
if (newValue > m_inputType->maximum())
newValue = m_inputType->maximum();

setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchChangeEvent : DispatchNoEvent);
setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
current = newValue;
if (n > 1)
applyStep(n - 1, AnyIsDefaultStep, DispatchChangeEvent, ec);
applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
else if (n < -1)
applyStep(n + 1, AnyIsDefaultStep, DispatchChangeEvent, ec);
applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
} else
applyStep(n, AnyIsDefaultStep, DispatchChangeEvent, ec);
applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
}
}

@@ -34,7 +34,7 @@ class RenderTextControl;
class VisiblePosition;

enum TextFieldSelectionDirection { SelectionHasNoDirection, SelectionHasForwardDirection, SelectionHasBackwardDirection };
enum TextFieldEventBehavior { DispatchNoEvent, DispatchChangeEvent };
enum TextFieldEventBehavior { DispatchNoEvent, DispatchChangeEvent, DispatchInputAndChangeEvent };

class HTMLTextFormControlElement : public HTMLFormControlElementWithState {
public:
@@ -80,34 +80,49 @@ bool TextFieldInputType::canSetSuggestedValue()

void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
{
// Grab this input element to keep reference even if JS event handler
// changes input type.
RefPtr<HTMLInputElement> input(element());

// We don't ask InputType::setValue to dispatch events because
// TextFieldInputType dispatches events different way from InputType.
InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent);

if (valueChanged)
element()->updateInnerTextValue();
input->updateInnerTextValue();

unsigned max = visibleValue().length();
if (element()->focused())
element()->setSelectionRange(max, max);
if (input->focused())
input->setSelectionRange(max, max);
else
element()->cacheSelectionInResponseToSetValue(max);
input->cacheSelectionInResponseToSetValue(max);

if (!valueChanged)
return;

if (eventBehavior != DispatchNoEvent) {
switch (eventBehavior) {
case DispatchChangeEvent:
// If the user is still editing this field, dispatch an input event rather than a change event.
// The change event will be dispatched when editing finishes.
if (element()->focused())
element()->dispatchFormControlInputEvent();
if (input->focused())
input->dispatchFormControlInputEvent();
else
element()->dispatchFormControlChangeEvent();
input->dispatchFormControlChangeEvent();
break;

case DispatchInputAndChangeEvent: {
input->dispatchFormControlInputEvent();
input->dispatchFormControlChangeEvent();
break;
}

case DispatchNoEvent:
break;
}

// FIXME: Why do we do this when eventBehavior == DispatchNoEvent
if (!element()->focused() || eventBehavior == DispatchNoEvent)
element()->setTextAsOfLastFormControlChangeEvent(sanitizedValue);
if (!input->focused() || eventBehavior == DispatchNoEvent)
input->setTextAsOfLastFormControlChangeEvent(sanitizedValue);
}

void TextFieldInputType::handleKeydownEvent(KeyboardEvent* event)

0 comments on commit e2fd194

Please sign in to comment.