Title: [91353] trunk
Revision
91353
Author
commit-qu...@webkit.org
Date
2011-07-20 03:23:42 -0700 (Wed, 20 Jul 2011)

Log Message

The value of a number input form continues to increase/decrease even if we disable the input form.
https://bugs.webkit.org/show_bug.cgi?id=64786

Patch by Kentaro Hara <hara...@google.com> on 2011-07-20
Reviewed by Kent Tamura.

Source/WebCore:

The value of the number input form continues to increase/decrease in the following scenario:
(1) Click the spin button of the input form.
(2) Hook the 'mouseup' event and disable the input form.
(3) Enable the input form after some delay (e.g. 50ms).

What is happening above is as follows:
(1) When the 'mousedown' event happens, the repeating timer of the spin button starts.
(2) If the input form is not disabled, the repeating timer stops at the 'mouseup' event.
However, if the input form is disabled, the 'mouseup' event is ignored, failing to stop
the repeating timer.
(3) The value continues to increase/decrease, since the repeating timer is still working.

This patch stops the repeating timer when the input form gets disabled or readonly.

Test: fast/forms/spin-button-gets-disabled-or-readonly.html

* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::parseMappedAttribute): Calls disabledAttributeChanged() when 'disabled' attribute gets changed. Calls readonlyAttributeChanged() when 'readonly' attribute gets changed.
* html/InputType.cpp:
(WebCore::InputType::disabledAttributeChanged): Stops the repeating timer and releases mouse capturing.
(WebCore::InputType::readonlyAttributeChanged): Ditto.
* html/InputType.h:
* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::disabledAttributeChanged): Ditto.
(WebCore::TextFieldInputType::readonlyAttributeChanged): Ditto.
* html/TextFieldInputType.h:
* html/shadow/TextControlInnerElements.cpp:
(WebCore::SpinButtonElement::detach): Replased the code with releaseCapture().
(WebCore::SpinButtonElement::defaultEventHandler): Ditto.
(WebCore::SpinButtonElement::releaseCapture): Stops the repeating timer and releases mouse capturing.
* html/shadow/TextControlInnerElements.h:

LayoutTests:

The value of the number input form continues to increase/decrease in the following scenario:
(1) Click the spin button of the number input form.
(2) Hook the 'mouseup' event and disable the number input form.
(3) Enable the number input form after some delay (e.g. 50ms).

What is happening above is as follows:
(1) When the 'mousedown' event happens, the repeating timer of the spin button starts.
(2) If the input form is not disabled, the repeating timer stops at the 'mouseup' event.
However, if the input form is disabled, the 'mouseup' event is ignored, failing to stop
the repeating timer.
(3) The value continues to increase/decrease, since the repeating timer is still working.

The added test checks if the value does not continue to increase/decrease when we do the above operation.

* fast/forms/spin-button-gets-disabled-or-readonly-expected.txt: Added.
* fast/forms/spin-button-gets-disabled-or-readonly.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (91352 => 91353)


--- trunk/LayoutTests/ChangeLog	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/LayoutTests/ChangeLog	2011-07-20 10:23:42 UTC (rev 91353)
@@ -1,3 +1,27 @@
+2011-07-20  Kentaro Hara  <hara...@google.com>
+
+        The value of a number input form continues to increase/decrease even if we disable the input form.
+        https://bugs.webkit.org/show_bug.cgi?id=64786
+
+        Reviewed by Kent Tamura.
+
+        The value of the number input form continues to increase/decrease in the following scenario:
+        (1) Click the spin button of the number input form.
+        (2) Hook the 'mouseup' event and disable the number input form.
+        (3) Enable the number input form after some delay (e.g. 50ms).
+
+        What is happening above is as follows:
+        (1) When the 'mousedown' event happens, the repeating timer of the spin button starts.
+        (2) If the input form is not disabled, the repeating timer stops at the 'mouseup' event.
+        However, if the input form is disabled, the 'mouseup' event is ignored, failing to stop
+        the repeating timer.
+        (3) The value continues to increase/decrease, since the repeating timer is still working.
+
+        The added test checks if the value does not continue to increase/decrease when we do the above operation.
+
+        * fast/forms/spin-button-gets-disabled-or-readonly-expected.txt: Added.
+        * fast/forms/spin-button-gets-disabled-or-readonly.html: Added.
+
 2011-07-20  Kent Tamura  <tk...@chromium.org>
 
         [Chromium] Expectation update for some forms and speech tests.

Added: trunk/LayoutTests/fast/forms/spin-button-gets-disabled-or-readonly-expected.txt (0 => 91353)


--- trunk/LayoutTests/fast/forms/spin-button-gets-disabled-or-readonly-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/spin-button-gets-disabled-or-readonly-expected.txt	2011-07-20 10:23:42 UTC (rev 91353)
@@ -0,0 +1,27 @@
+ 
+This tests if the value of a number input form does not continue to increase/decrease in the following scenario.
+(1) Click the spin button of the input form.
+(2) Hook the 'mouseup' event and disable the input form.
+(3) Enable the input form after some delay.
+To run this test manually, input any value in the input form and then click the spin-down button. At this point, click the spin-down button quickly and do not move the cursor from the spin-down button after the click. If the value decreases by just 1, this test passes.
+
+
+Test on a readonly number input form:
+delay = 1 ms
+PASS input.value is "1234566"
+delay = 10 ms
+PASS input.value is "1234566"
+delay = 100 ms
+PASS input.value is "1234566"
+
+Test on a disabled number input form:
+delay = 1 ms
+PASS input.value is "1234566"
+delay = 10 ms
+PASS input.value is "1234566"
+delay = 100 ms
+PASS input.value is "1234566"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/forms/spin-button-gets-disabled-or-readonly.html (0 => 91353)


--- trunk/LayoutTests/fast/forms/spin-button-gets-disabled-or-readonly.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/spin-button-gets-disabled-or-readonly.html	2011-07-20 10:23:42 UTC (rev 91353)
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<input id="readonlyNumber" type="number" _onmouseup_="mouseupEventOnReadonlyNumber()" />
+<input id="disabledNumber" type="number" _onmouseup_="mouseupEventOnDisabledNumber()" />
+<div id="console">
+<p>
+This tests if the value of a number input form does not continue
+to increase/decrease in the following scenario.<br/>
+(1) Click the spin button of the input form.<br/>
+(2) Hook the 'mouseup' event and disable the input form.<br/>
+(3) Enable the input form after some delay.<br/>
+To run this test manually, input any value in the input form
+and then click the spin-down button.
+At this point, click the spin-down button quickly and
+do not move the cursor from the spin-down button after the click.
+If the value decreases by just 1, this test passes.
+</p>
+</div>
+<script>
+var testInputs;
+var testDelays;
+var input;
+var delay;
+window.jsTestIsAsync = true;
+
+if (window.layoutTestController && window.eventSender) {
+    testInputs = [document.getElementById("readonlyNumber"), document.getElementById("disabledNumber")];
+    setTimeout(function() {
+        nextInputTest();
+    }, 0);
+}
+
+function nextInputTest() {
+    if (testInputs.length == 0) {
+        finishJSTest();
+    } else {
+        input = testInputs.shift();
+        testDelays = [1, 10, 100];
+        debug("");
+        debug("Test on a " + (input.id == "readonlyNumber" ? "readonly" : "disabled") + " number input form:");
+        nextDelayTest();
+    }
+}
+
+function nextDelayTest() {
+    if (testDelays.length == 0) {
+        nextInputTest();
+    } else {
+        delay = testDelays.shift();
+        initializeInputAttributes(input, 1234567);
+        debug("delay = " + delay + " ms");
+        clickSpinDownButton(input);
+        setTimeout(function() {
+            shouldBeEqualToString('input.value', "1234566");
+            nextDelayTest();
+        }, 500);
+    }
+}
+
+function mouseupEventOnReadonlyNumber() {
+    input.readOnly = true;
+    setTimeout(function() {
+        input.readOnly = false;
+    }, delay);
+}
+
+function mouseupEventOnDisabledNumber() {
+    input.disabled = true;
+    setTimeout(function() {
+        input.disabled = false;
+    }, delay);
+}
+
+function initializeInputAttributes(input, value) {
+    input.value = value;
+    input.disabled = false;
+    input.readOnly = false;
+}
+
+function clickSpinDownButton(input) {
+    var x = input.offsetLeft + input.offsetWidth - 6;
+    var y = input.offsetTop + input.offsetHeight - 6;
+    eventSender.mouseMoveTo(x, y);
+    eventSender.mouseDown();
+    eventSender.mouseUp();
+}
+
+var successfullyParsed = true;
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (91352 => 91353)


--- trunk/Source/WebCore/ChangeLog	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/ChangeLog	2011-07-20 10:23:42 UTC (rev 91353)
@@ -1,3 +1,42 @@
+2011-07-20  Kentaro Hara  <hara...@google.com>
+
+        The value of a number input form continues to increase/decrease even if we disable the input form.
+        https://bugs.webkit.org/show_bug.cgi?id=64786
+
+        Reviewed by Kent Tamura.
+
+        The value of the number input form continues to increase/decrease in the following scenario:
+        (1) Click the spin button of the input form.
+        (2) Hook the 'mouseup' event and disable the input form.
+        (3) Enable the input form after some delay (e.g. 50ms).
+
+        What is happening above is as follows:
+        (1) When the 'mousedown' event happens, the repeating timer of the spin button starts.
+        (2) If the input form is not disabled, the repeating timer stops at the 'mouseup' event.
+        However, if the input form is disabled, the 'mouseup' event is ignored, failing to stop
+        the repeating timer.
+        (3) The value continues to increase/decrease, since the repeating timer is still working.
+
+        This patch stops the repeating timer when the input form gets disabled or readonly.
+
+        Test: fast/forms/spin-button-gets-disabled-or-readonly.html
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::parseMappedAttribute): Calls disabledAttributeChanged() when 'disabled' attribute gets changed. Calls readonlyAttributeChanged() when 'readonly' attribute gets changed.
+        * html/InputType.cpp:
+        (WebCore::InputType::disabledAttributeChanged): Stops the repeating timer and releases mouse capturing.
+        (WebCore::InputType::readonlyAttributeChanged): Ditto.
+        * html/InputType.h:
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::disabledAttributeChanged): Ditto.
+        (WebCore::TextFieldInputType::readonlyAttributeChanged): Ditto.
+        * html/TextFieldInputType.h:
+        * html/shadow/TextControlInnerElements.cpp:
+        (WebCore::SpinButtonElement::detach): Replased the code with releaseCapture().
+        (WebCore::SpinButtonElement::defaultEventHandler): Ditto.
+        (WebCore::SpinButtonElement::releaseCapture): Stops the repeating timer and releases mouse capturing.
+        * html/shadow/TextControlInnerElements.h:
+
 2011-07-20  Sheriff Bot  <webkit.review....@gmail.com>
 
         Unreviewed, rolling out r91285.

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (91352 => 91353)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2011-07-20 10:23:42 UTC (rev 91353)
@@ -789,6 +789,13 @@
         setNeedsValidityCheck();
     } else if (attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
         setNeedsValidityCheck();
+    else if (attr->name() == disabledAttr) {
+        m_inputType->disabledAttributeChanged();
+        HTMLTextFormControlElement::parseMappedAttribute(attr);
+    } else if (attr->name() == readonlyAttr) {
+        m_inputType->readonlyAttributeChanged();
+        HTMLTextFormControlElement::parseMappedAttribute(attr);
+    }
 #if ENABLE(DATALIST)
     else if (attr->name() == listAttr)
         m_hasNonEmptyList = !attr->isEmpty();

Modified: trunk/Source/WebCore/html/InputType.cpp (91352 => 91353)


--- trunk/Source/WebCore/html/InputType.cpp	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/InputType.cpp	2011-07-20 10:23:42 UTC (rev 91353)
@@ -673,6 +673,14 @@
 {
 }
 
+void InputType::disabledAttributeChanged()
+{
+}
+
+void InputType::readonlyAttributeChanged()
+{
+}
+
 namespace InputTypeNames {
 
 // The type names must be lowercased because they will be the return values of

Modified: trunk/Source/WebCore/html/InputType.h (91352 => 91353)


--- trunk/Source/WebCore/html/InputType.h	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/InputType.h	2011-07-20 10:23:42 UTC (rev 91353)
@@ -229,6 +229,8 @@
     virtual bool supportsPlaceholder() const;
     virtual void updatePlaceholderText();
     virtual void multipleAttributeChanged();
+    virtual void disabledAttributeChanged();
+    virtual void readonlyAttributeChanged();
 
     // Parses the specified string for the type, and return
     // the double value for the parsing result if the parsing

Modified: trunk/Source/WebCore/html/TextFieldInputType.cpp (91352 => 91353)


--- trunk/Source/WebCore/html/TextFieldInputType.cpp	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/TextFieldInputType.cpp	2011-07-20 10:23:42 UTC (rev 91353)
@@ -238,6 +238,18 @@
     m_container.clear();
 }
 
+void TextFieldInputType::disabledAttributeChanged()
+{
+    if (m_innerSpinButton)
+        m_innerSpinButton->releaseCapture();
+}
+
+void TextFieldInputType::readonlyAttributeChanged()
+{
+    if (m_innerSpinButton)
+        m_innerSpinButton->releaseCapture();
+}
+
 bool TextFieldInputType::shouldUseInputMethod() const
 {
     return true;

Modified: trunk/Source/WebCore/html/TextFieldInputType.h (91352 => 91353)


--- trunk/Source/WebCore/html/TextFieldInputType.h	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/TextFieldInputType.h	2011-07-20 10:23:42 UTC (rev 91353)
@@ -35,6 +35,8 @@
 
 namespace WebCore {
 
+class SpinButtonElement;
+
 // The class represents types of which UI contain text fields.
 // It supports not only the types for BaseTextInputType but also type=number.
 class TextFieldInputType : public InputType {
@@ -58,6 +60,8 @@
     virtual bool needsContainer() const;
     virtual void createShadowSubtree();
     virtual void destroyShadowSubtree();
+    virtual void disabledAttributeChanged();
+    virtual void readonlyAttributeChanged();
 
 private:
     virtual bool isTextField() const;
@@ -76,7 +80,7 @@
     RefPtr<HTMLElement> m_innerBlock;
     RefPtr<HTMLElement> m_innerText;
     RefPtr<HTMLElement> m_placeholder;
-    RefPtr<HTMLElement> m_innerSpinButton;
+    RefPtr<SpinButtonElement> m_innerSpinButton;
 #if ENABLE(INPUT_SPEECH)
     RefPtr<HTMLElement> m_speechButton;
 #endif

Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp (91352 => 91353)


--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp	2011-07-20 10:23:42 UTC (rev 91353)
@@ -252,13 +252,7 @@
 
 void SpinButtonElement::detach()
 {
-    stopRepeatingTimer();
-    if (m_capturing) {
-        if (Frame* frame = document()->frame()) {
-            frame->eventHandler()->setCapturingMouseEventsNode(0);
-            m_capturing = false;
-        }
-    }
+    releaseCapture();
     HTMLDivElement::detach();
 }
 
@@ -315,21 +309,25 @@
             m_upDownState = local.y() < box->height() / 2 ? Up : Down;
             if (m_upDownState != oldUpDownState)
                 renderer()->repaint();
-        } else {
-            if (m_capturing) {
-                stopRepeatingTimer();
-                if (Frame* frame = document()->frame()) {
-                    frame->eventHandler()->setCapturingMouseEventsNode(0);
-                    m_capturing = false;
-                }
-            }
-        }
+        } else
+            releaseCapture();
     }
 
     if (!event->defaultHandled())
         HTMLDivElement::defaultEventHandler(event);
 }
 
+void SpinButtonElement::releaseCapture()
+{
+    stopRepeatingTimer();
+    if (m_capturing) {
+        if (Frame* frame = document()->frame()) {
+            frame->eventHandler()->setCapturingMouseEventsNode(0);
+            m_capturing = false;
+        }
+    }
+}
+
 void SpinButtonElement::startRepeatingTimer()
 {
     m_pressStartingState = m_upDownState;

Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.h (91352 => 91353)


--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.h	2011-07-20 10:09:44 UTC (rev 91352)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.h	2011-07-20 10:23:42 UTC (rev 91353)
@@ -98,6 +98,7 @@
 
     static PassRefPtr<SpinButtonElement> create(Document*);
     UpDownState upDownState() const { return m_upDownState; }
+    virtual void releaseCapture();
 
 private:
     SpinButtonElement(Document*);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to