- Revision
- 247158
- Author
- wenson_hs...@apple.com
- Date
- 2019-07-05 09:22:42 -0700 (Fri, 05 Jul 2019)
Log Message
Touching media controls sometimes shows software keyboard
https://bugs.webkit.org/show_bug.cgi?id=199490
<rdar://problem/52076270>
Reviewed by Eric Carlson.
Source/WebKit:
In r243044, we added a compatibility hack for Google Slides (and other G-suite properties) to allow the on-
screen keyboard to show up after a prevented touch event in the case where an element was already focused, even
if the touch event handler doesn't explicitly refocus the element. However, this means that if a regular text
field (or other form control) has been programmatically focused, then interacting with any other element that
prevents default on touchstart will cause us to show the keyboard for that focused element.
To mitigate this, only fall down this refocusing codepath in the case where the focused element is a hidden
editable element (in the style of many Google productivity web apps). For non-hidden editable elements that are
already focused, this refocusing logic is not necessary, since the user should be able to interact with the
control to show the keyboard anyways; for hidden editable areas, this compatibility hack is actually needed,
since there is typically no other way for a user to focus these elements and show an on-screen keyboard.
Tests: fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html
fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::dispatchTouchEvent):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::isTransparentOrFullyClipped const):
Renamed from enclosingLayerIsTransparentOrFullyClipped, and pulled out into a private helper method.
(WebKit::WebPage::platformEditorState const):
(WebKit::WebPage::requestEvasionRectsAboveSelection):
(WebKit::WebPage::getFocusedElementInformation):
(WebKit::enclosingLayerIsTransparentOrFullyClipped): Deleted.
Tools:
Adds plumbing for a new testing hook to check whether or not there is an active input session. See other
ChangeLog entries for more detail.
* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::hasInputSession const):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::hasInputSession const):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::hasInputSession const):
LayoutTests:
Adds a new layout test to verify that the keyboard only appears after a handled touch event if the focused
element is inside a hidden editable area; otherwise, the keyboard should not be present.
* fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt: Added.
* fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html: Added.
This test passes as long as we didn't begin showing the keyboard after tapping.
* fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt:
* fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html:
Adjust this existing test to make the focused textarea hidden.
* resources/ui-helper.js:
(window.UIHelper.hasInputSession):
Add a new testing hook to check whether there is an active input session.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (247157 => 247158)
--- trunk/LayoutTests/ChangeLog 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/LayoutTests/ChangeLog 2019-07-05 16:22:42 UTC (rev 247158)
@@ -1,3 +1,29 @@
+2019-07-05 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Touching media controls sometimes shows software keyboard
+ https://bugs.webkit.org/show_bug.cgi?id=199490
+ <rdar://problem/52076270>
+
+ Reviewed by Eric Carlson.
+
+ Adds a new layout test to verify that the keyboard only appears after a handled touch event if the focused
+ element is inside a hidden editable area; otherwise, the keyboard should not be present.
+
+ * fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt: Added.
+ * fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html: Added.
+
+ This test passes as long as we didn't begin showing the keyboard after tapping.
+
+ * fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt:
+ * fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html:
+
+ Adjust this existing test to make the focused textarea hidden.
+
+ * resources/ui-helper.js:
+ (window.UIHelper.hasInputSession):
+
+ Add a new testing hook to check whether there is an active input session.
+
2019-07-05 Antoine Quint <grao...@apple.com>
[Pointer Events] Respect pointer capture when dispatching mouse boundary events and updating :hover
Added: trunk/LayoutTests/fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt (0 => 247158)
--- trunk/LayoutTests/fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart-expected.txt 2019-07-05 16:22:42 UTC (rev 247158)
@@ -0,0 +1,11 @@
+
+Verifies that the keyboard does not show up even after preventing default on touchstart when a regular input field is focused. To manually test, tap the red box; the keyboard should not appear.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS hasInputSession is false
+PASS document.activeElement is textarea
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html (0 => 247158)
--- trunk/LayoutTests/fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html 2019-07-05 16:22:42 UTC (rev 247158)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<style>
+html, body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+}
+
+textarea, #target {
+ width: 100%;
+ height: 100px;
+}
+
+#target {
+ background-color: tomato;
+ opacity: 0.25;
+}
+</style>
+</head>
+<body>
+ <textarea></textarea>
+ <div id="target"></div>
+ <pre id="description"></pre>
+ <pre id="console"></pre>
+</body>
+<script>
+ jsTestIsAsync = true;
+ textarea = document.querySelector("textarea");
+ target = document.getElementById("target");
+ target.addEventListener("touchstart", event => event.preventDefault());
+
+ description("Verifies that the keyboard does not show up even after preventing default on touchstart when a regular input field is focused. To manually test, tap the red box; the keyboard should not appear.");
+
+ addEventListener("load", async () => {
+ textarea.focus();
+ await UIHelper.activateElement(target);
+ await UIHelper.ensurePresentationUpdate();
+ hasInputSession = await UIHelper.hasInputSession();
+ shouldBe("hasInputSession", "false");
+ shouldBe("document.activeElement", "textarea");
+ finishJSTest();
+ });
+</script>
+</html>
Modified: trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt (247157 => 247158)
--- trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart-expected.txt 2019-07-05 16:22:42 UTC (rev 247158)
@@ -1,5 +1,5 @@
-Verifies that the keyboard shows up even after preventing default on touchstart. To manually test, tap the textarea; the textarea should remain focused, and the keyboard should appear.
+Verifies that the keyboard shows up even after preventing default on touchstart when focusing a hidden editable area. To manually test, tap the red box; the textarea should remain focused, and the keyboard should appear.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Modified: trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html (247157 => 247158)
--- trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/LayoutTests/fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html 2019-07-05 16:22:42 UTC (rev 247158)
@@ -10,16 +10,31 @@
margin: 0;
}
-textarea {
+textarea, #target {
width: 100%;
height: 100px;
- font-size: 50px;
- text-align: center;
+ position: absolute;
+ top: 0;
}
+
+#target {
+ background-color: tomato;
+ z-index: 1;
+ opacity: 0.25;
+}
+
+textarea {
+ opacity: 0;
+}
+
+#description {
+ margin-top: 100px;
+}
</style>
</head>
<body>
<textarea></textarea>
+ <div id="target"></div>
<pre id="description"></pre>
<pre id="console"></pre>
</body>
@@ -26,13 +41,14 @@
<script>
jsTestIsAsync = true;
textarea = document.querySelector("textarea");
+ target = document.getElementById("target");
+ target.addEventListener("touchstart", event => event.preventDefault());
- description("Verifies that the keyboard shows up even after preventing default on touchstart. To manually test, tap the textarea; the textarea should remain focused, and the keyboard should appear.");
+ description("Verifies that the keyboard shows up even after preventing default on touchstart when focusing a hidden editable area. To manually test, tap the red box; the textarea should remain focused, and the keyboard should appear.");
- textarea.addEventListener("touchstart", event => event.preventDefault());
addEventListener("load", async () => {
textarea.focus();
- await UIHelper.activateElementAndWaitForInputSession(textarea);
+ await UIHelper.activateElementAndWaitForInputSession(target);
testPassed("keyboard was shown.");
shouldBe("document.activeElement", "textarea");
textarea.blur();
Modified: trunk/LayoutTests/resources/ui-helper.js (247157 => 247158)
--- trunk/LayoutTests/resources/ui-helper.js 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/LayoutTests/resources/ui-helper.js 2019-07-05 16:22:42 UTC (rev 247158)
@@ -372,6 +372,13 @@
});
}
+ static hasInputSession()
+ {
+ return new Promise(resolve => {
+ testRunner.runUIScript("uiController.hasInputSession", result => resolve(result === "true"));
+ });
+ }
+
static isPresentingModally()
{
return new Promise(resolve => {
Modified: trunk/Source/WebKit/ChangeLog (247157 => 247158)
--- trunk/Source/WebKit/ChangeLog 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Source/WebKit/ChangeLog 2019-07-05 16:22:42 UTC (rev 247158)
@@ -1,3 +1,39 @@
+2019-07-05 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Touching media controls sometimes shows software keyboard
+ https://bugs.webkit.org/show_bug.cgi?id=199490
+ <rdar://problem/52076270>
+
+ Reviewed by Eric Carlson.
+
+ In r243044, we added a compatibility hack for Google Slides (and other G-suite properties) to allow the on-
+ screen keyboard to show up after a prevented touch event in the case where an element was already focused, even
+ if the touch event handler doesn't explicitly refocus the element. However, this means that if a regular text
+ field (or other form control) has been programmatically focused, then interacting with any other element that
+ prevents default on touchstart will cause us to show the keyboard for that focused element.
+
+ To mitigate this, only fall down this refocusing codepath in the case where the focused element is a hidden
+ editable element (in the style of many Google productivity web apps). For non-hidden editable elements that are
+ already focused, this refocusing logic is not necessary, since the user should be able to interact with the
+ control to show the keyboard anyways; for hidden editable areas, this compatibility hack is actually needed,
+ since there is typically no other way for a user to focus these elements and show an on-screen keyboard.
+
+ Tests: fast/events/touch/ios/show-keyboard-after-preventing-touchstart.html
+ fast/events/touch/ios/do-not-show-keyboard-after-preventing-touchstart.html
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::dispatchTouchEvent):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::isTransparentOrFullyClipped const):
+
+ Renamed from enclosingLayerIsTransparentOrFullyClipped, and pulled out into a private helper method.
+
+ (WebKit::WebPage::platformEditorState const):
+ (WebKit::WebPage::requestEvasionRectsAboveSelection):
+ (WebKit::WebPage::getFocusedElementInformation):
+ (WebKit::enclosingLayerIsTransparentOrFullyClipped): Deleted.
+
2019-07-04 Chris Dumez <cdu...@apple.com>
Simplify logic that handles registering WebProcessProxy objects with their WebsiteDataStore
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (247157 => 247158)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-07-05 16:22:42 UTC (rev 247158)
@@ -2896,7 +2896,7 @@
if (handled && oldFocusedElement) {
auto newFocusedFrame = makeRefPtr(m_page->focusController().focusedFrame());
auto newFocusedElement = makeRefPtr(newFocusedFrame ? newFocusedFrame->document()->focusedElement() : nullptr);
- if (oldFocusedElement == newFocusedElement)
+ if (oldFocusedElement == newFocusedElement && isTransparentOrFullyClipped(*newFocusedElement))
elementDidRefocus(*newFocusedElement);
}
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (247157 => 247158)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-07-05 16:22:42 UTC (rev 247158)
@@ -1448,6 +1448,7 @@
#if PLATFORM(IOS_FAMILY)
void didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>&, const String& displayString, const IPC::DataReference& iconData);
+ bool isTransparentOrFullyClipped(const WebCore::Element&) const;
#endif
#if ENABLE(SANDBOX_EXTENSIONS)
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (247157 => 247158)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2019-07-05 16:22:42 UTC (rev 247158)
@@ -185,9 +185,13 @@
data.hasPlainText = data.hasContent && hasAnyPlainText(Range::create(root->document(), VisiblePosition { startInEditableRoot }, VisiblePosition { lastPositionInNode(root) }));
}
-static bool enclosingLayerIsTransparentOrFullyClipped(const RenderObject& renderer)
+bool WebPage::isTransparentOrFullyClipped(const Element& element) const
{
- auto* enclosingLayer = renderer.enclosingLayer();
+ auto* renderer = element.renderer();
+ if (!renderer)
+ return false;
+
+ auto* enclosingLayer = renderer->enclosingLayer();
return enclosingLayer && enclosingLayer->isTransparentOrFullyClippedRespectingParentFrames();
}
@@ -264,9 +268,8 @@
postLayoutData.caretColor = renderer.style().caretColor();
}
if (result.isContentEditable) {
- auto container = makeRefPtr(selection.rootEditableElement());
- if (container && container->renderer())
- postLayoutData.editableRootIsTransparentOrFullyClipped = enclosingLayerIsTransparentOrFullyClipped(*container->renderer());
+ if (auto container = makeRefPtr(selection.rootEditableElement()))
+ postLayoutData.editableRootIsTransparentOrFullyClipped = isTransparentOrFullyClipped(*container);
}
computeEditableRootHasContentAndPlainText(selection, postLayoutData);
}
@@ -1801,7 +1804,7 @@
return;
}
- if (!m_focusedElement || !m_focusedElement->renderer() || enclosingLayerIsTransparentOrFullyClipped(*m_focusedElement->renderer())) {
+ if (!m_focusedElement || !m_focusedElement->renderer() || isTransparentOrFullyClipped(*m_focusedElement)) {
reply({ });
return;
}
@@ -2991,7 +2994,7 @@
information.isReadOnly = false;
}
- if (m_focusedElement->document().quirks().shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAreas() && m_focusedElement->renderer() && enclosingLayerIsTransparentOrFullyClipped(*m_focusedElement->renderer())) {
+ if (m_focusedElement->document().quirks().shouldSuppressAutocorrectionAndAutocaptializationInHiddenEditableAreas() && isTransparentOrFullyClipped(*m_focusedElement)) {
information.autocapitalizeType = AutocapitalizeTypeNone;
information.isAutocorrect = false;
}
Modified: trunk/Tools/ChangeLog (247157 => 247158)
--- trunk/Tools/ChangeLog 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Tools/ChangeLog 2019-07-05 16:22:42 UTC (rev 247158)
@@ -1,3 +1,23 @@
+2019-07-05 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Touching media controls sometimes shows software keyboard
+ https://bugs.webkit.org/show_bug.cgi?id=199490
+ <rdar://problem/52076270>
+
+ Reviewed by Eric Carlson.
+
+ Adds plumbing for a new testing hook to check whether or not there is an active input session. See other
+ ChangeLog entries for more detail.
+
+ * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+ (WTR::UIScriptController::hasInputSession const):
+ * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+ * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+ (WTR::UIScriptController::hasInputSession const):
+ * TestRunnerShared/UIScriptContext/UIScriptController.h:
+ * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+ (WTR::UIScriptController::hasInputSession const):
+
2019-07-04 Aakash Jain <aakash_j...@apple.com>
[ews-build] Remove GTK and WPE queue from old EWS and dashboard
Modified: trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm (247157 => 247158)
--- trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm 2019-07-05 16:22:42 UTC (rev 247158)
@@ -287,6 +287,11 @@
return false;
}
+bool UIScriptController::hasInputSession() const
+{
+ return false;
+}
+
double UIScriptController::minimumZoomScale() const
{
return gWebScrollView.minimumZoomScale;
Modified: trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl (247157 => 247158)
--- trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl 2019-07-05 16:22:42 UTC (rev 247158)
@@ -224,6 +224,7 @@
attribute object didShowKeyboardCallback;
attribute object didHideKeyboardCallback;
readonly attribute boolean isShowingKeyboard;
+ readonly attribute boolean hasInputSession;
attribute object didShowMenuCallback;
attribute object didHideMenuCallback;
Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp (247157 => 247158)
--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp 2019-07-05 16:22:42 UTC (rev 247158)
@@ -453,6 +453,11 @@
return false;
}
+bool UIScriptController::hasInputSession() const
+{
+ return false;
+}
+
double UIScriptController::zoomScale() const
{
return 1;
Modified: trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h (247157 => 247158)
--- trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h 2019-07-05 16:22:42 UTC (rev 247158)
@@ -163,6 +163,7 @@
JSValueRef didHideKeyboardCallback() const;
bool isShowingKeyboard() const;
+ bool hasInputSession() const;
void setDidHideMenuCallback(JSValueRef);
JSValueRef didHideMenuCallback() const;
Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (247157 => 247158)
--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2019-07-05 15:29:11 UTC (rev 247157)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2019-07-05 16:22:42 UTC (rev 247158)
@@ -625,6 +625,11 @@
return TestController::singleton().mainWebView()->platformView().showingKeyboard;
}
+bool UIScriptController::hasInputSession() const
+{
+ return TestController::singleton().mainWebView()->platformView().isInteractingWithFormControl;
+}
+
void UIScriptController::applyAutocorrection(JSStringRef newString, JSStringRef oldString, JSValueRef callback)
{
unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);