2010-09-22 Kent Tamura <tkent@chromium.org>
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Sep 2010 08:09:43 +0000 (08:09 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Sep 2010 08:09:43 +0000 (08:09 +0000)
        Reviewed by Chris Fleizach.

        Support keyboard operations for <input type=range>.
        https://bugs.webkit.org/show_bug.cgi?id=45803

        * fast/forms/range-keyoperation-expected.txt: Added.
        * fast/forms/range-keyoperation.html: Added.
2010-09-22  Kent Tamura  <tkent@chromium.org>

        Reviewed by Chris Fleizach.

        Support keyboard operations for <input type=range>.
        https://bugs.webkit.org/show_bug.cgi?id=45803

        Increasing the value with Up/Right arrow keys by its step value,
        and decreasing with Down/Left arrow keys. If an input element has
        step=any attribute, increasing/decreasing by 1/100 of max-min.

        Note: This change is not useful on Mac because users can't set
        focus on range controls.

        Test: fast/forms/range-keyoperation.html

        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::defaultEventHandler):
          Calls handleKeyEventForRange() for RANGE and key events.
        (WebCore::HTMLInputElement::handleKeyEventForRange):
        * html/HTMLInputElement.h: Add handleKeyEventForRange() declaration.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@68024 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/forms/range-keyoperation-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/range-keyoperation.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/HTMLInputElement.cpp
WebCore/html/HTMLInputElement.h

index 85768de3e66b8896e60bcbf3d1acc18bd7daa51f..1e5eda4bca7ac714f39c0b74cef44671e0c5b6fc 100644 (file)
@@ -1,3 +1,13 @@
+2010-09-22  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Chris Fleizach.
+
+        Support keyboard operations for <input type=range>.
+        https://bugs.webkit.org/show_bug.cgi?id=45803
+
+        * fast/forms/range-keyoperation-expected.txt: Added.
+        * fast/forms/range-keyoperation.html: Added.
+
 2010-09-22  Mario Sanchez Prada  <msanchez@igalia.com>
 
         Reviewed by Chris Fleizach.
diff --git a/LayoutTests/fast/forms/range-keyoperation-expected.txt b/LayoutTests/fast/forms/range-keyoperation-expected.txt
new file mode 100644 (file)
index 0000000..723970e
--- /dev/null
@@ -0,0 +1,50 @@
+Test for keyboard operations of <input type=range>
+
+Tests for a horizontal range
+Press the up arrow key:
+PASS input.value is "51"
+PASS changeEventCounter is lastChangeEventCounter + 1
+Press the down arrow key:
+PASS input.value is "50"
+Press the left arrow key:
+PASS input.value is "49"
+Press the right arrow key:
+PASS input.value is "50"
+Edge cases
+PASS input.value is "0"
+PASS changeEventCounter is lastChangeEventCounter
+PASS input.value is "1"
+PASS input.value is "100"
+PASS input.value is "99"
+
+Tests for a vertical range
+Press the up arrow key:
+PASS input.value is "51"
+Press the down arrow key:
+PASS input.value is "50"
+Press the left arrow key:
+PASS input.value is "49"
+Press the right arrow key:
+PASS input.value is "50"
+
+step=any cases
+Press the up arrow key:
+PASS input.value is "102"
+PASS changeEventCounter is lastChangeEventCounter + 1
+Press the down arrow key:
+PASS input.value is "100"
+PASS changeEventCounter is lastChangeEventCounter + 1
+Edge cases
+PASS input.value is "200"
+PASS input.value is "200"
+PASS changeEventCounter is lastChangeEventCounter
+PASS input.value is "198"
+PASS input.value is "0"
+PASS input.value is "0"
+PASS changeEventCounter is lastChangeEventCounter
+PASS input.value is "2"
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/forms/range-keyoperation.html b/LayoutTests/fast/forms/range-keyoperation.html
new file mode 100644 (file)
index 0000000..7d90e3b
--- /dev/null
@@ -0,0 +1,129 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description">Test for keyboard operations of &lt;input type=range></p>
+<div id="console"></div>
+<script>
+
+function sendKey(element, keyName) {
+    var event = document.createEvent('KeyboardEvent');
+    event.initKeyboardEvent('keydown', true, true, document.defaultView, keyName);
+    element.dispatchEvent(event);
+}
+
+var changeEventCounter = 0;
+function handleChange() {
+  changeEventCounter++;
+}
+
+var parent = document.createElement('div');
+document.body.appendChild(parent);
+parent.innerHTML = '<input type=range id=range min=0 max=100 value=50>';
+
+var input = document.getElementById('range');
+input.onchange = handleChange;
+input.focus();
+
+debug('Tests for a horizontal range');
+debug('Press the up arrow key:');
+var lastChangeEventCounter = changeEventCounter;
+sendKey(input, 'Up');
+shouldBe('input.value', '"51"');
+shouldBe('changeEventCounter', 'lastChangeEventCounter + 1');
+
+debug('Press the down arrow key:');
+sendKey(input, 'Down');
+shouldBe('input.value', '"50"');
+
+debug('Press the left arrow key:');
+sendKey(input, 'Left');
+shouldBe('input.value', '"49"');
+
+debug('Press the right arrow key:');
+sendKey(input, 'Right');
+shouldBe('input.value', '"50"');
+
+debug('Edge cases');
+input.valueAsNumber = 0;
+lastChangeEventCounter = changeEventCounter;
+sendKey(input, 'Left');
+shouldBe('input.value', '"0"');
+shouldBe('changeEventCounter', 'lastChangeEventCounter');
+sendKey(input, 'Right');
+shouldBe('input.value', '"1"');
+input.valueAsNumber = 100;
+sendKey(input, 'Right');
+shouldBe('input.value', '"100"');
+sendKey(input, 'Left');
+shouldBe('input.value', '"99"');
+
+
+debug('');
+input.setAttribute('style', '-webkit-appearance:slider-vertical; height: 40px;');
+input.valueAsNumber = 50;
+debug('Tests for a vertical range');
+debug('Press the up arrow key:');
+sendKey(input, 'Up');
+shouldBe('input.value', '"51"');
+
+debug('Press the down arrow key:');
+sendKey(input, 'Down');
+shouldBe('input.value', '"50"');
+
+debug('Press the left arrow key:');
+sendKey(input, 'Left');
+shouldBe('input.value', '"49"');
+
+debug('Press the right arrow key:');
+sendKey(input, 'Right');
+shouldBe('input.value', '"50"');
+
+debug('');
+debug('step=any cases');
+input.step = 'any';
+input.min = '0';
+input.max = '200';
+input.valueAsNumber = 100;
+
+debug('Press the up arrow key:');
+lastChangeEventCounter = changeEventCounter;
+sendKey(input, 'Up');
+shouldBe('input.value', '"102"');
+shouldBe('changeEventCounter', 'lastChangeEventCounter + 1');
+
+debug('Press the down arrow key:');
+lastChangeEventCounter = changeEventCounter;
+sendKey(input, 'Down');
+shouldBe('input.value', '"100"');
+shouldBe('changeEventCounter', 'lastChangeEventCounter + 1');
+
+debug('Edge cases');
+input.valueAsNumber = 199;
+sendKey(input, 'Up');
+shouldBe('input.value', '"200"');
+lastChangeEventCounter = changeEventCounter;
+sendKey(input, 'Up');
+shouldBe('input.value', '"200"');
+shouldBe('changeEventCounter', 'lastChangeEventCounter');
+sendKey(input, 'Down');
+shouldBe('input.value', '"198"');
+input.valueAsNumber = 1;
+sendKey(input, 'Down');
+shouldBe('input.value', '"0"');
+lastChangeEventCounter = changeEventCounter;
+sendKey(input, 'Down');
+shouldBe('input.value', '"0"');
+shouldBe('changeEventCounter', 'lastChangeEventCounter');
+sendKey(input, 'Up');
+shouldBe('input.value', '"2"');
+
+debug('');
+var successfullyParsed = true;
+</script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 030cea9dfd2d2bfd09a2e434b2282d9ec0e47868..5088eb58981714e1a5d202bcbd3547bfa7535bca 100644 (file)
@@ -1,3 +1,25 @@
+2010-09-22  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Chris Fleizach.
+
+        Support keyboard operations for <input type=range>.
+        https://bugs.webkit.org/show_bug.cgi?id=45803
+
+        Increasing the value with Up/Right arrow keys by its step value,
+        and decreasing with Down/Left arrow keys. If an input element has
+        step=any attribute, increasing/decreasing by 1/100 of max-min.
+
+        Note: This change is not useful on Mac because users can't set
+        focus on range controls.
+
+        Test: fast/forms/range-keyoperation.html
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::defaultEventHandler):
+          Calls handleKeyEventForRange() for RANGE and key events.
+        (WebCore::HTMLInputElement::handleKeyEventForRange):
+        * html/HTMLInputElement.h: Add handleKeyEventForRange() declaration.
+
 2010-09-22  Mario Sanchez Prada  <msanchez@igalia.com>
 
         Reviewed by Chris Fleizach.
index baff6c4f1f9a06381efdc57ff279c0e5d6c7fc22..b06aa35b7da02ac90349a2be3ef3371516883a59 100644 (file)
@@ -2266,6 +2266,11 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
             return;
         }
     }
+    if (deprecatedInputType() == RANGE && evt->isKeyboardEvent()) {
+        handleKeyEventForRange(static_cast<KeyboardEvent*>(evt));
+        if (evt->defaultHandled())
+            return;
+    }
  
    if (isTextField()
             && evt->type() == eventNames().keydownEvent
@@ -2572,6 +2577,47 @@ void HTMLInputElement::handleBeforeTextInsertedEvent(Event* event)
     InputElement::handleBeforeTextInsertedEvent(m_data, this, this, event);
 }
 
+void HTMLInputElement::handleKeyEventForRange(KeyboardEvent* event)
+{
+    if (event->type() != eventNames().keydownEvent)
+        return;
+    String key = event->keyIdentifier();
+    if (key != "Up" && key != "Right" && key != "Down" && key != "Left")
+        return;
+
+    ExceptionCode ec;
+    if (equalIgnoringCase(getAttribute(stepAttr), "any")) {
+        double min = minimum();
+        double max = maximum();
+        // FIXME: Is 1/100 reasonable?
+        double step = (max - min) / 100;
+        double current = parseToDouble(value(), numeric_limits<double>::quiet_NaN());
+        ASSERT(isfinite(current));
+        double newValue;
+        if (key == "Up" || key == "Right") {
+            newValue = current + step;
+            if (newValue > max)
+                newValue = max;
+        } else {
+            newValue = current - step;
+            if (newValue < min)
+                newValue = min;
+        }
+        if (newValue != current) {
+            setValueAsNumber(newValue, ec);
+            dispatchFormControlChangeEvent();
+        }
+    } else {
+        int stepMagnification = (key == "Up" || key == "Right") ? 1 : -1;
+        String lastStringValue = value();
+        stepUp(stepMagnification, ec);
+        if (lastStringValue != value())
+            dispatchFormControlChangeEvent();
+    }
+    event->setDefaultHandled();
+    return;
+}
+
 PassRefPtr<HTMLFormElement> HTMLInputElement::createTemporaryFormForIsIndex()
 {
     RefPtr<HTMLFormElement> form = HTMLFormElement::create(document());
index 7e601cacbcfeb120cd39e62ceab4419adf22b0c6..e068c8cb676f4f4632cf1676b8b807de20ca459b 100644 (file)
@@ -325,6 +325,7 @@ private:
     void updateCheckedRadioButtons();
     
     void handleBeforeTextInsertedEvent(Event*);
+    void handleKeyEventForRange(KeyboardEvent*);
     PassRefPtr<HTMLFormElement> createTemporaryFormForIsIndex();
     // Helper for getAllowedValueStep();
     bool getStepParameters(double* defaultStep, double* stepScaleFactor) const;