[iOS] Should not scroll when checkbox, radio, submit, reset, or button is spacebar...
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Mar 2019 23:40:08 +0000 (23:40 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Mar 2019 23:40:08 +0000 (23:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195281
<rdar://problem/48564347>

Reviewed by Simon Fraser.

Source/WebCore:

Do not call the base class's default event handler (HTMLTextFormControlElement::defaultEventHandler())
when WebCore sees a keydown of the spacebar as we consider such an event as handled.
Otherwise, calling the base class's default event handler ultimately gives the embedding
client a chance to wrongly handle the event. In the case of iOS, keydown of the spacebar
causes the page to scroll.

WebCore implements spacebar activation on keydown for form controls. For IE compatibility
WebCore does not mark such keydown events as handled so that a DOM keypress event will
be subsequently dispatched. The current logic only skips calling the base class's default
event handler if the DOM event was not marked handled. This is insufficient. We need to
know whether WebCore handled the event. If asking the input type to handle the key down
marks the DOM event as handled then, clearly, WebCore handled the event. However, if the
event is not marked as handled, but WebCore actually accounted for this event then we need
to know this so that we do not call the base class's default event handler and ultimately
the embedding client asking for an interpretation of the key event. Towards this, have
InputType::handleKeydownEvent() return a bit whether or not the base class's default
event handler should be invoked.

Tests: fast/events/ios/activating-button-should-not-scroll-page.html
       fast/events/ios/activating-checkbox-should-not-scroll-page.html
       fast/events/ios/activating-radio-button-should-not-scroll-page.html
       fast/events/ios/activating-reset-button-should-not-scroll-page.html
       fast/events/ios/activating-submit-button-should-not-scroll-page.html

* html/BaseCheckableInputType.cpp:
(WebCore::BaseCheckableInputType::handleKeydownEvent): Return ShouldCallBaseEventHandler::No
if WebCore handled the spacebar activation. Otherewise, return ShouldCallBaseEventHandler::Yes.
* html/BaseCheckableInputType.h:
* html/BaseChooserOnlyDateAndTimeInputType.cpp:
(WebCore::BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent): Ditto.
* html/BaseChooserOnlyDateAndTimeInputType.h:
* html/BaseClickableWithKeyInputType.cpp:
(WebCore::BaseClickableWithKeyInputType::handleKeydownEvent): Keep our current behavior by returning ShouldCallBaseEventHandler::Yes.
* html/BaseClickableWithKeyInputType.h:
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::defaultEventHandler): Do not fallthrough and call the base class's default
event handler if the input type told us it handled the event regardless of whether the event was handled
from the perspective of the DOM.
* html/InputType.cpp:
(WebCore::InputType::handleKeydownEvent): Keep our current behavior by returning ShouldCallBaseEventHandler::Yes.
* html/InputType.h:

* html/NumberInputType.cpp:
(WebCore::NumberInputType::handleKeydownEvent):
* html/NumberInputType.h:
* html/RadioInputType.cpp:
(WebCore::RadioInputType::handleKeydownEvent):
* html/RadioInputType.h:
* html/RangeInputType.cpp:
(WebCore::RangeInputType::handleKeydownEvent):
* html/RangeInputType.h:
* html/SearchInputType.cpp:
(WebCore::SearchInputType::handleKeydownEvent):
* html/SearchInputType.h:
* html/TextFieldInputType.cpp:
(WebCore::TextFieldInputType::handleKeydownEvent):
* html/TextFieldInputType.h:
Keep our current behavior by returning ShouldCallBaseEventHandler::Yes.

LayoutTests:

Add some tests to ensure that we do not scroll when a checkbox, radio, submit, reset, or button
is spacebar activated.

* fast/events/ios/activating-button-should-not-scroll-page-expected.txt: Added.
* fast/events/ios/activating-button-should-not-scroll-page.html: Added.
* fast/events/ios/activating-checkbox-should-not-scroll-page-expected.txt: Added.
* fast/events/ios/activating-checkbox-should-not-scroll-page.html: Added.
* fast/events/ios/activating-radio-button-should-not-scroll-page-expected.txt: Added.
* fast/events/ios/activating-radio-button-should-not-scroll-page.html: Added.
* fast/events/ios/activating-reset-button-should-not-scroll-page-expected.txt: Added.
* fast/events/ios/activating-reset-button-should-not-scroll-page.html: Added.
* fast/events/ios/activating-submit-button-should-not-scroll-page-expected.txt: Added.
* fast/events/ios/activating-submit-button-should-not-scroll-page.html: Added.
* fast/events/ios/resources/press-spacebar-at-element-and-check-for-page-scroll.js: Added.
(done):
(handleInteraction.checkForScrollAndDone):
(handleInteraction):
(handleScroll):
(handleFocus):
(checkActivatingElementUsingSpacebarDoesNotScrollPage):
* platform/ios/TestExpectations: Skip the tests for now until ENABLE(FULL_KEYBOARD_ACCESS) is enabled
by default on iOS.

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

33 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/ios/activating-button-should-not-scroll-page-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-button-should-not-scroll-page.html [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-checkbox-should-not-scroll-page-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-checkbox-should-not-scroll-page.html [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-radio-button-should-not-scroll-page-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-radio-button-should-not-scroll-page.html [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-reset-button-should-not-scroll-page-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-reset-button-should-not-scroll-page.html [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-submit-button-should-not-scroll-page-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/activating-submit-button-should-not-scroll-page.html [new file with mode: 0644]
LayoutTests/fast/events/ios/resources/press-spacebar-at-element-and-check-for-page-scroll.js [new file with mode: 0644]
LayoutTests/platform/ios/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/html/BaseCheckableInputType.cpp
Source/WebCore/html/BaseCheckableInputType.h
Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.cpp
Source/WebCore/html/BaseChooserOnlyDateAndTimeInputType.h
Source/WebCore/html/BaseClickableWithKeyInputType.cpp
Source/WebCore/html/BaseClickableWithKeyInputType.h
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/InputType.cpp
Source/WebCore/html/InputType.h
Source/WebCore/html/NumberInputType.cpp
Source/WebCore/html/NumberInputType.h
Source/WebCore/html/RadioInputType.cpp
Source/WebCore/html/RadioInputType.h
Source/WebCore/html/RangeInputType.cpp
Source/WebCore/html/RangeInputType.h
Source/WebCore/html/SearchInputType.cpp
Source/WebCore/html/SearchInputType.h
Source/WebCore/html/TextFieldInputType.cpp
Source/WebCore/html/TextFieldInputType.h

index a63b092..c680aba 100644 (file)
@@ -1,3 +1,34 @@
+2019-03-05  Daniel Bates  <dabates@apple.com>
+
+        [iOS] Should not scroll when checkbox, radio, submit, reset, or button is spacebar activated
+        https://bugs.webkit.org/show_bug.cgi?id=195281
+        <rdar://problem/48564347>
+
+        Reviewed by Simon Fraser.
+
+        Add some tests to ensure that we do not scroll when a checkbox, radio, submit, reset, or button
+        is spacebar activated.
+
+        * fast/events/ios/activating-button-should-not-scroll-page-expected.txt: Added.
+        * fast/events/ios/activating-button-should-not-scroll-page.html: Added.
+        * fast/events/ios/activating-checkbox-should-not-scroll-page-expected.txt: Added.
+        * fast/events/ios/activating-checkbox-should-not-scroll-page.html: Added.
+        * fast/events/ios/activating-radio-button-should-not-scroll-page-expected.txt: Added.
+        * fast/events/ios/activating-radio-button-should-not-scroll-page.html: Added.
+        * fast/events/ios/activating-reset-button-should-not-scroll-page-expected.txt: Added.
+        * fast/events/ios/activating-reset-button-should-not-scroll-page.html: Added.
+        * fast/events/ios/activating-submit-button-should-not-scroll-page-expected.txt: Added.
+        * fast/events/ios/activating-submit-button-should-not-scroll-page.html: Added.
+        * fast/events/ios/resources/press-spacebar-at-element-and-check-for-page-scroll.js: Added.
+        (done):
+        (handleInteraction.checkForScrollAndDone):
+        (handleInteraction):
+        (handleScroll):
+        (handleFocus):
+        (checkActivatingElementUsingSpacebarDoesNotScrollPage):
+        * platform/ios/TestExpectations: Skip the tests for now until ENABLE(FULL_KEYBOARD_ACCESS) is enabled
+        by default on iOS.
+
 2019-03-05  Takashi Komori  <Takashi.Komori@sony.com>
 
         [Curl] Implement Cookie Accept Policy.
diff --git a/LayoutTests/fast/events/ios/activating-button-should-not-scroll-page-expected.txt b/LayoutTests/fast/events/ios/activating-button-should-not-scroll-page-expected.txt
new file mode 100644 (file)
index 0000000..f246952
--- /dev/null
@@ -0,0 +1,10 @@
+Tests that activating a button (focusing it and pressing the spacebar) does not cause the page to scroll.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.scrollY is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/ios/activating-button-should-not-scroll-page.html b/LayoutTests/fast/events/ios/activating-button-should-not-scroll-page.html
new file mode 100644 (file)
index 0000000..01f4e0e
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/press-spacebar-at-element-and-check-for-page-scroll.js"></script>
+</head>
+<body style="height: 4096px"> <!-- Make the page really long to force vertical scrollbars. -->
+<p id="description"></p>
+<p id="test-container"><button id="test">Tap me</button></p>
+<div id="console"></div>
+<script>
+description("Tests that activating a button (focusing it and pressing the spacebar) does not cause the page to scroll.");
+checkActivatingElementUsingSpacebarDoesNotScrollPage(document.getElementById("test-container"), document.getElementById("test"), "click");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/ios/activating-checkbox-should-not-scroll-page-expected.txt b/LayoutTests/fast/events/ios/activating-checkbox-should-not-scroll-page-expected.txt
new file mode 100644 (file)
index 0000000..09519b2
--- /dev/null
@@ -0,0 +1,10 @@
+Tests that activating a checkbox (focusing it and pressing the spacebar) does not cause the page to scroll.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.scrollY is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/ios/activating-checkbox-should-not-scroll-page.html b/LayoutTests/fast/events/ios/activating-checkbox-should-not-scroll-page.html
new file mode 100644 (file)
index 0000000..794e0e1
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/press-spacebar-at-element-and-check-for-page-scroll.js"></script>
+</head>
+<body style="height: 4096px"> <!-- Make the page really long to force vertical scrollbars. -->
+<p id="description"></p>
+<p id="test-container"><input id="test" type="checkbox"></p>
+<div id="console"></div>
+<script>
+description("Tests that activating a checkbox (focusing it and pressing the spacebar) does not cause the page to scroll.");
+checkActivatingElementUsingSpacebarDoesNotScrollPage(document.getElementById("test-container"), document.getElementById("test"), "change");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/ios/activating-radio-button-should-not-scroll-page-expected.txt b/LayoutTests/fast/events/ios/activating-radio-button-should-not-scroll-page-expected.txt
new file mode 100644 (file)
index 0000000..b8df60e
--- /dev/null
@@ -0,0 +1,10 @@
+Tests that activating a radio button (focusing it and pressing the spacebar) does not cause the page to scroll.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.scrollY is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/ios/activating-radio-button-should-not-scroll-page.html b/LayoutTests/fast/events/ios/activating-radio-button-should-not-scroll-page.html
new file mode 100644 (file)
index 0000000..30b742a
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/press-spacebar-at-element-and-check-for-page-scroll.js"></script>
+</head>
+<body style="height: 4096px"> <!-- Make the page really long to force vertical scrollbars. -->
+<p id="description"></p>
+<p id="test-container"><input id="test" type="radio"></p>
+<div id="console"></div>
+<script>
+description("Tests that activating a radio button (focusing it and pressing the spacebar) does not cause the page to scroll.");
+checkActivatingElementUsingSpacebarDoesNotScrollPage(document.getElementById("test-container"), document.getElementById("test"), "change");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/ios/activating-reset-button-should-not-scroll-page-expected.txt b/LayoutTests/fast/events/ios/activating-reset-button-should-not-scroll-page-expected.txt
new file mode 100644 (file)
index 0000000..9dc35fb
--- /dev/null
@@ -0,0 +1,10 @@
+Tests that activating a Reset button (focusing it and pressing the spacebar) does not cause the page to scroll.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.scrollY is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/ios/activating-reset-button-should-not-scroll-page.html b/LayoutTests/fast/events/ios/activating-reset-button-should-not-scroll-page.html
new file mode 100644 (file)
index 0000000..2f24971
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/press-spacebar-at-element-and-check-for-page-scroll.js"></script>
+</head>
+<body style="height: 4096px"> <!-- Make the page really long to force vertical scrollbars. -->
+<p id="description"></p>
+<p id="test-container"><input type="reset" id="test"></p>
+<div id="console"></div>
+<script>
+description("Tests that activating a Reset button (focusing it and pressing the spacebar) does not cause the page to scroll.");
+checkActivatingElementUsingSpacebarDoesNotScrollPage(document.getElementById("test-container"), document.getElementById("test"), "click");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/ios/activating-submit-button-should-not-scroll-page-expected.txt b/LayoutTests/fast/events/ios/activating-submit-button-should-not-scroll-page-expected.txt
new file mode 100644 (file)
index 0000000..cf90641
--- /dev/null
@@ -0,0 +1,10 @@
+Tests that activating a Submit button (focusing it and pressing the spacebar) does not cause the page to scroll.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS window.scrollY is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/ios/activating-submit-button-should-not-scroll-page.html b/LayoutTests/fast/events/ios/activating-submit-button-should-not-scroll-page.html
new file mode 100644 (file)
index 0000000..f6d5309
--- /dev/null
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+<script src="resources/press-spacebar-at-element-and-check-for-page-scroll.js"></script>
+</head>
+<body style="height: 4096px"> <!-- Make the page really long to force vertical scrollbars. -->
+<p id="description"></p>
+<p id="test-container"><input type="submit" id="test"></p>
+<div id="console"></div>
+<script>
+description("Tests that activating a Submit button (focusing it and pressing the spacebar) does not cause the page to scroll.");
+checkActivatingElementUsingSpacebarDoesNotScrollPage(document.getElementById("test-container"), document.getElementById("test"), "click");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/events/ios/resources/press-spacebar-at-element-and-check-for-page-scroll.js b/LayoutTests/fast/events/ios/resources/press-spacebar-at-element-and-check-for-page-scroll.js
new file mode 100644 (file)
index 0000000..1a24f82
--- /dev/null
@@ -0,0 +1,51 @@
+window.jsTestIsAsync = true;
+
+let g_testElement;
+let g_testContainer;
+let g_activationEventName;
+let checkForScrollTimerId;
+
+function done()
+{
+    document.body.removeChild(g_testContainer);
+    finishJSTest();
+}
+
+function handleInteraction(event)
+{
+    function checkForScrollAndDone() {
+        window.removeEventListener("scroll", handleScroll);
+        shouldBeZero("window.scrollY");
+        done();
+    }
+    // FIXME: Wait up to 100ms for a possible scroll to happen. Note that we will
+    // end the test as soon as a scroll happens.
+    checkForScrollTimerId = window.setTimeout(checkForScrollAndDone, 100);
+}
+
+function handleScroll()
+{
+    testFailed("Page should not have scrolled.");
+
+    window.clearTimeout(checkForScrollTimerId);
+    g_testElement.removeEventListener(g_activationEventName, handleInteraction);
+    done();
+}
+
+function checkActivatingElementUsingSpacebarDoesNotScrollPage(testContainer, testElement, activationEventName)
+{
+    g_testContainer = testContainer;
+    g_testElement = testElement;
+    g_activationEventName = activationEventName;
+
+    function handleFocus(event) {
+        console.assert(event.target == g_testElement);
+        window.addEventListener("scroll", handleScroll, { once: true });
+        g_testElement.addEventListener(g_activationEventName, handleInteraction, { once: true });
+        if (window.testRunner)
+            UIHelper.keyDown(" ");
+    }
+    g_testElement.addEventListener("focus", handleFocus, { once: true });
+    if (window.testRunner)
+        UIHelper.keyDown("\t", ["altKey"]);
+}
index 0613600..ef37c19 100644 (file)
@@ -3228,3 +3228,8 @@ fast/forms/ios/focus-search-field.html [ Skip ]
 fast/forms/ios/focus-submit-button.html [ Skip ]
 fast/forms/ios/focus-text-field.html [ Skip ]
 fast/forms/ios/focus-textarea.html [ Skip ]
+fast/events/ios/activating-button-should-not-scroll-page.html [ Skip ]
+fast/events/ios/activating-checkbox-should-not-scroll-page.html [ Skip ]
+fast/events/ios/activating-radio-button-should-not-scroll-page.html [ Skip ]
+fast/events/ios/activating-reset-button-should-not-scroll-page.html [ Skip ]
+fast/events/ios/activating-submit-button-should-not-scroll-page.html [ Skip ]
index 7118567..63ebf23 100644 (file)
@@ -1,3 +1,70 @@
+2019-03-05  Daniel Bates  <dabates@apple.com>
+
+        [iOS] Should not scroll when checkbox, radio, submit, reset, or button is spacebar activated
+        https://bugs.webkit.org/show_bug.cgi?id=195281
+        <rdar://problem/48564347>
+
+        Reviewed by Simon Fraser.
+
+        Do not call the base class's default event handler (HTMLTextFormControlElement::defaultEventHandler())
+        when WebCore sees a keydown of the spacebar as we consider such an event as handled.
+        Otherwise, calling the base class's default event handler ultimately gives the embedding
+        client a chance to wrongly handle the event. In the case of iOS, keydown of the spacebar
+        causes the page to scroll.
+
+        WebCore implements spacebar activation on keydown for form controls. For IE compatibility
+        WebCore does not mark such keydown events as handled so that a DOM keypress event will
+        be subsequently dispatched. The current logic only skips calling the base class's default
+        event handler if the DOM event was not marked handled. This is insufficient. We need to
+        know whether WebCore handled the event. If asking the input type to handle the key down
+        marks the DOM event as handled then, clearly, WebCore handled the event. However, if the
+        event is not marked as handled, but WebCore actually accounted for this event then we need
+        to know this so that we do not call the base class's default event handler and ultimately
+        the embedding client asking for an interpretation of the key event. Towards this, have
+        InputType::handleKeydownEvent() return a bit whether or not the base class's default
+        event handler should be invoked.
+
+        Tests: fast/events/ios/activating-button-should-not-scroll-page.html
+               fast/events/ios/activating-checkbox-should-not-scroll-page.html
+               fast/events/ios/activating-radio-button-should-not-scroll-page.html
+               fast/events/ios/activating-reset-button-should-not-scroll-page.html
+               fast/events/ios/activating-submit-button-should-not-scroll-page.html
+
+        * html/BaseCheckableInputType.cpp:
+        (WebCore::BaseCheckableInputType::handleKeydownEvent): Return ShouldCallBaseEventHandler::No
+        if WebCore handled the spacebar activation. Otherewise, return ShouldCallBaseEventHandler::Yes.
+        * html/BaseCheckableInputType.h:
+        * html/BaseChooserOnlyDateAndTimeInputType.cpp:
+        (WebCore::BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent): Ditto.
+        * html/BaseChooserOnlyDateAndTimeInputType.h:
+        * html/BaseClickableWithKeyInputType.cpp:
+        (WebCore::BaseClickableWithKeyInputType::handleKeydownEvent): Keep our current behavior by returning ShouldCallBaseEventHandler::Yes.
+        * html/BaseClickableWithKeyInputType.h:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::defaultEventHandler): Do not fallthrough and call the base class's default
+        event handler if the input type told us it handled the event regardless of whether the event was handled
+        from the perspective of the DOM.
+        * html/InputType.cpp:
+        (WebCore::InputType::handleKeydownEvent): Keep our current behavior by returning ShouldCallBaseEventHandler::Yes.
+        * html/InputType.h:
+
+        * html/NumberInputType.cpp:
+        (WebCore::NumberInputType::handleKeydownEvent):
+        * html/NumberInputType.h:
+        * html/RadioInputType.cpp:
+        (WebCore::RadioInputType::handleKeydownEvent):
+        * html/RadioInputType.h:
+        * html/RangeInputType.cpp:
+        (WebCore::RangeInputType::handleKeydownEvent):
+        * html/RangeInputType.h:
+        * html/SearchInputType.cpp:
+        (WebCore::SearchInputType::handleKeydownEvent):
+        * html/SearchInputType.h:
+        * html/TextFieldInputType.cpp:
+        (WebCore::TextFieldInputType::handleKeydownEvent):
+        * html/TextFieldInputType.h:
+        Keep our current behavior by returning ShouldCallBaseEventHandler::Yes.
+
 2019-03-05  Takashi Komori  <Takashi.Komori@sony.com>
 
         [Curl] Implement Cookie Accept Policy.
index 14fa248..4fdae44 100644 (file)
@@ -64,7 +64,7 @@ bool BaseCheckableInputType::appendFormData(DOMFormData& formData, bool) const
     return true;
 }
 
-void BaseCheckableInputType::handleKeydownEvent(KeyboardEvent& event)
+auto BaseCheckableInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     const String& key = event.keyIdentifier();
     if (key == "U+0020") {
@@ -72,7 +72,9 @@ void BaseCheckableInputType::handleKeydownEvent(KeyboardEvent& event)
         element()->setActive(true, true);
         // No setDefaultHandled(), because IE dispatches a keypress in this case
         // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+        return ShouldCallBaseEventHandler::No;
     }
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 void BaseCheckableInputType::handleKeypressEvent(KeyboardEvent& event)
index 1b74d5e..562bb9d 100644 (file)
@@ -38,7 +38,7 @@ namespace WebCore {
 class BaseCheckableInputType : public InputType {
 protected:
     explicit BaseCheckableInputType(HTMLInputElement& element) : InputType(element) { }
-    void handleKeydownEvent(KeyboardEvent&) override;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
     void fireInputAndChangeEvents();
 
 private:
index 21fede1..7828ea1 100644 (file)
@@ -113,10 +113,10 @@ void BaseChooserOnlyDateAndTimeInputType::closeDateTimeChooser()
         m_dateTimeChooser->endChooser();
 }
 
-void BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent(KeyboardEvent& event)
+auto BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     ASSERT(element());
-    BaseClickableWithKeyInputType::handleKeydownEvent(*element(), event);
+    return BaseClickableWithKeyInputType::handleKeydownEvent(*element(), event);
 }
 
 void BaseChooserOnlyDateAndTimeInputType::handleKeypressEvent(KeyboardEvent& event)
index 4c98d37..451d50c 100644 (file)
@@ -49,7 +49,7 @@ private:
     void detach() override;
     void setValue(const String&, bool valueChanged, TextFieldEventBehavior) override;
     void handleDOMActivateEvent(Event&) override;
-    void handleKeydownEvent(KeyboardEvent&) override;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
     void handleKeypressEvent(KeyboardEvent&) override;
     void handleKeyupEvent(KeyboardEvent&) override;
     void accessKeyAction(bool sendMouseEvents) override;
index 2c4dd55..3559724 100644 (file)
@@ -39,14 +39,16 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-void BaseClickableWithKeyInputType::handleKeydownEvent(HTMLInputElement& element, KeyboardEvent& event)
+auto BaseClickableWithKeyInputType::handleKeydownEvent(HTMLInputElement& element, KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     const String& key = event.keyIdentifier();
     if (key == "U+0020") {
         element.setActive(true, true);
         // No setDefaultHandled(), because IE dispatches a keypress in this case
         // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+        return ShouldCallBaseEventHandler::No;
     }
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 void BaseClickableWithKeyInputType::handleKeypressEvent(HTMLInputElement& element, KeyboardEvent& event)
@@ -78,10 +80,10 @@ void BaseClickableWithKeyInputType::accessKeyAction(HTMLInputElement& element, b
     element.dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents);
 }
 
-void BaseClickableWithKeyInputType::handleKeydownEvent(KeyboardEvent& event)
+auto BaseClickableWithKeyInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     ASSERT(element());
-    handleKeydownEvent(*element(), event);
+    return handleKeydownEvent(*element(), event);
 }
 
 void BaseClickableWithKeyInputType::handleKeypressEvent(KeyboardEvent& event)
index cc54571..8b6c592 100644 (file)
@@ -37,7 +37,7 @@ namespace WebCore {
 // Base of input types that dispatches a simulated click on space/return key.
 class BaseClickableWithKeyInputType : public InputType {
 public:
-    static void handleKeydownEvent(HTMLInputElement&, KeyboardEvent&);
+    static ShouldCallBaseEventHandler handleKeydownEvent(HTMLInputElement&, KeyboardEvent&);
     static void handleKeypressEvent(HTMLInputElement&, KeyboardEvent&);
     static void handleKeyupEvent(InputType&, KeyboardEvent&);
     static void accessKeyAction(HTMLInputElement&, bool sendMouseEvents);
@@ -46,7 +46,7 @@ protected:
     explicit BaseClickableWithKeyInputType(HTMLInputElement& element) : InputType(element) { }
 
 private:
-    void handleKeydownEvent(KeyboardEvent&) override;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
     void handleKeypressEvent(KeyboardEvent&) override;
     void handleKeyupEvent(KeyboardEvent&) override;
     void accessKeyAction(bool sendMouseEvents) override;
index ae9a9cd..e2094f3 100644 (file)
@@ -1169,8 +1169,8 @@ void HTMLInputElement::defaultEventHandler(Event& event)
 #endif
 
     if (is<KeyboardEvent>(event) && event.type() == eventNames().keydownEvent) {
-        m_inputType->handleKeydownEvent(downcast<KeyboardEvent>(event));
-        if (event.defaultHandled())
+        auto shouldCallBaseEventHandler = m_inputType->handleKeydownEvent(downcast<KeyboardEvent>(event));
+        if (event.defaultHandled() || shouldCallBaseEventHandler == InputType::ShouldCallBaseEventHandler::No)
             return;
     }
 
index c43ebf8..04d325d 100644 (file)
@@ -453,8 +453,9 @@ void InputType::handleDOMActivateEvent(Event&)
 {
 }
 
-void InputType::handleKeydownEvent(KeyboardEvent&)
+auto InputType::handleKeydownEvent(KeyboardEvent&) -> ShouldCallBaseEventHandler
 {
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 void InputType::handleKeypressEvent(KeyboardEvent&)
index b5256e0..f025a15 100644 (file)
@@ -182,7 +182,10 @@ public:
     virtual void willDispatchClick(InputElementClickState&);
     virtual void didDispatchClick(Event&, const InputElementClickState&);
     virtual void handleDOMActivateEvent(Event&);
-    virtual void handleKeydownEvent(KeyboardEvent&);
+
+    enum ShouldCallBaseEventHandler { No, Yes };
+    virtual ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&);
+
     virtual void handleKeypressEvent(KeyboardEvent&);
     virtual void handleKeyupEvent(KeyboardEvent&);
     virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent&);
index 3a92afc..05ff07d 100644 (file)
@@ -213,11 +213,12 @@ bool NumberInputType::isSteppable() const
     return true;
 }
 
-void NumberInputType::handleKeydownEvent(KeyboardEvent& event)
+auto NumberInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     handleKeydownEventForSpinButton(event);
     if (!event.defaultHandled())
-        TextFieldInputType::handleKeydownEvent(event);
+        return TextFieldInputType::handleKeydownEvent(event);
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 Decimal NumberInputType::parseToNumber(const String& src, const Decimal& defaultValue) const
index 689f529..fed1aba 100644 (file)
@@ -51,7 +51,7 @@ private:
     float decorationWidth() const final;
     bool isSteppable() const final;
     StepRange createStepRange(AnyStepHandling) const final;
-    void handleKeydownEvent(KeyboardEvent&) final;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
     Decimal parseToNumber(const String&, const Decimal&) const final;
     String serialize(const Decimal&) const final;
     String localizeValue(const String&) const final;
index 613d545..ac9a9c2 100644 (file)
@@ -58,14 +58,15 @@ void RadioInputType::handleClickEvent(MouseEvent& event)
     event.setDefaultHandled();
 }
 
-void RadioInputType::handleKeydownEvent(KeyboardEvent& event)
+auto RadioInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
-    BaseCheckableInputType::handleKeydownEvent(event);
+    if (BaseCheckableInputType::handleKeydownEvent(event) == ShouldCallBaseEventHandler::No)
+        return ShouldCallBaseEventHandler::No;
     if (event.defaultHandled())
-        return;
+        return ShouldCallBaseEventHandler::Yes;
     const String& key = event.keyIdentifier();
     if (key != "Up" && key != "Down" && key != "Left" && key != "Right")
-        return;
+        return ShouldCallBaseEventHandler::Yes;
 
     ASSERT(element());
     // Left and up mean "previous radio button".
@@ -74,7 +75,7 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent& event)
     // to the right).  Seems strange, but we'll match it.
     // However, when using Spatial Navigation, we need to be able to navigate without changing the selection.
     if (isSpatialNavigationEnabled(element()->document().frame()))
-        return;
+        return ShouldCallBaseEventHandler::Yes;
     bool forward = (key == "Down" || key == "Right");
 
     // We can only stay within the form's children if the form hasn't been demoted to a leaf because
@@ -94,9 +95,10 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent& event)
             element()->document().setFocusedElement(inputElement.get());
             inputElement->dispatchSimulatedClick(&event, SendNoEvents, DoNotShowPressedLook);
             event.setDefaultHandled();
-            return;
+            return ShouldCallBaseEventHandler::Yes;
         }
     }
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 void RadioInputType::handleKeyupEvent(KeyboardEvent& event)
index 7595010..720dd4e 100644 (file)
@@ -44,7 +44,7 @@ private:
     bool valueMissing(const String&) const final;
     String valueMissingText() const final;
     void handleClickEvent(MouseEvent&) final;
-    void handleKeydownEvent(KeyboardEvent&) final;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
     void handleKeyupEvent(KeyboardEvent&) final;
     bool isKeyboardFocusable(KeyboardEvent*) const final;
     bool shouldSendChangeEventAfterCheckedChanged() final;
index 6ac3b01..16df1d5 100644 (file)
@@ -195,11 +195,11 @@ void RangeInputType::disabledStateChanged()
     typedSliderThumbElement().hostDisabledStateChanged();
 }
 
-void RangeInputType::handleKeydownEvent(KeyboardEvent& event)
+auto RangeInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     ASSERT(element());
     if (element()->isDisabledFormControl())
-        return;
+        return ShouldCallBaseEventHandler::Yes;
 
     const String& key = event.keyIdentifier();
 
@@ -208,7 +208,6 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event)
 
     StepRange stepRange(createStepRange(RejectAny));
 
-
     // FIXME: We can't use stepUp() for the step value "any". So, we increase
     // or decrease the value by 1/100 of the value range. Is it reasonable?
     const Decimal step = equalLettersIgnoringASCIICase(element()->attributeWithoutSynchronization(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step();
@@ -238,7 +237,7 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event)
     else if (key == "End")
         newValue = isVertical ? stepRange.minimum() : stepRange.maximum();
     else
-        return; // Did not match any key binding.
+        return ShouldCallBaseEventHandler::Yes; // Did not match any key binding.
 
     newValue = stepRange.clampValue(newValue);
 
@@ -251,6 +250,7 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event)
     }
 
     event.setDefaultHandled();
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 void RangeInputType::createShadowSubtree()
index 706642b..08666f5 100644 (file)
@@ -53,7 +53,7 @@ private:
 #if !PLATFORM(IOS_FAMILY)
     void handleMouseDownEvent(MouseEvent&) final;
 #endif
-    void handleKeydownEvent(KeyboardEvent&) final;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
     RenderPtr<RenderElement> createInputRenderer(RenderStyle&&) final;
     void createShadowSubtree() final;
     Decimal parseToNumber(const String&, const Decimal&) const final;
index 2a25ed8..5343bed 100644 (file)
@@ -134,13 +134,11 @@ HTMLElement* SearchInputType::cancelButtonElement() const
     return m_cancelButton.get();
 }
 
-void SearchInputType::handleKeydownEvent(KeyboardEvent& event)
+auto SearchInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     ASSERT(element());
-    if (element()->isDisabledOrReadOnly()) {
-        TextFieldInputType::handleKeydownEvent(event);
-        return;
-    }
+    if (element()->isDisabledOrReadOnly())
+        return TextFieldInputType::handleKeydownEvent(event);
 
     const String& key = event.keyIdentifier();
     if (key == "U+001B") {
@@ -148,9 +146,9 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent& event)
         protectedInputElement->setValueForUser(emptyString());
         protectedInputElement->onSearch();
         event.setDefaultHandled();
-        return;
+        return ShouldCallBaseEventHandler::Yes;
     }
-    TextFieldInputType::handleKeydownEvent(event);
+    return TextFieldInputType::handleKeydownEvent(event);
 }
 
 void SearchInputType::destroyShadowSubtree()
index 7de2851..28d6a8b 100644 (file)
@@ -55,7 +55,7 @@ private:
     void destroyShadowSubtree() final;
     HTMLElement* resultsButtonElement() const final;
     HTMLElement* cancelButtonElement() const final;
-    void handleKeydownEvent(KeyboardEvent&) final;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) final;
     void didSetValueByUserEdit() final;
     bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const final;
     float decorationWidth() const final;
index eaf6d2c..1401f33 100644 (file)
@@ -182,11 +182,11 @@ void TextFieldInputType::handleClickEvent(MouseEvent&)
 }
 #endif
 
-void TextFieldInputType::handleKeydownEvent(KeyboardEvent& event)
+auto TextFieldInputType::handleKeydownEvent(KeyboardEvent& event) -> ShouldCallBaseEventHandler
 {
     ASSERT(element());
     if (!element()->focused())
-        return;
+        return ShouldCallBaseEventHandler::Yes;
 #if ENABLE(DATALIST_ELEMENT)
     const String& key = event.keyIdentifier();
     if (m_suggestionPicker && (key == "Enter" || key == "Up" || key == "Down")) {
@@ -195,9 +195,9 @@ void TextFieldInputType::handleKeydownEvent(KeyboardEvent& event)
     }
 #endif
     RefPtr<Frame> frame = element()->document().frame();
-    if (!frame || !frame->editor().doTextFieldCommandFromEvent(element(), &event))
-        return;
-    event.setDefaultHandled();
+    if (frame && frame->editor().doTextFieldCommandFromEvent(element(), &event))
+        event.setDefaultHandled();
+    return ShouldCallBaseEventHandler::Yes;
 }
 
 void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent& event)
index 2ffa7b2..4e33f05 100644 (file)
@@ -53,7 +53,7 @@ class TextFieldInputType : public InputType, protected SpinButtonElement::SpinBu
 protected:
     explicit TextFieldInputType(HTMLInputElement&);
     virtual ~TextFieldInputType();
-    void handleKeydownEvent(KeyboardEvent&) override;
+    ShouldCallBaseEventHandler handleKeydownEvent(KeyboardEvent&) override;
     void handleKeydownEventForSpinButton(KeyboardEvent&);
 #if ENABLE(DATALIST_ELEMENT)
     void handleClickEvent(MouseEvent&) final;