[iOS] Web pages shouldn't be able to present a keyboard after the web view resigns...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Feb 2019 23:54:02 +0000 (23:54 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Feb 2019 23:54:02 +0000 (23:54 +0000)
commitc16059cf11faa3d2d59686a5d9d78c01b98f2374
tree2df8d3efe511becdc37593202c021ea39f7db8cd
parentcb45d2db0a3e61afe0a0075e84cdcaebd1249ea0
[iOS] Web pages shouldn't be able to present a keyboard after the web view resigns first responder
https://bugs.webkit.org/show_bug.cgi?id=195118
<rdar://problem/43411940>

Reviewed by Tim Horton.

Source/WebKit:

It's currently possible for websites to redirect focus into an editable element on the page by programmatically
requesting focus within the "blur" event handler. This is because our current heuristics:

(1) Allow programmatic focus to show the keyboard when an element is already focused; this is meant to handle
    the case where the page moves focus between different elements on the page.
(2) And also allow programmatic focus to show the keyboard when changing activity state; this is meant to handle
    the case where a focused element should show the keyboard when first responder is restored on a web view
    (e.g. in the case where a modal view controller is dismissed, and the web view regains first responder once
    again).

In both of these scenarios, we actually only want the keyboard to appear if the web view itself is either
becoming the first responder, or is already the first responder. Importantly, when blurring the focused element
by calling -[WKWebViewe resignFirstResponder] (as is the case when dismissing the keyboard by tapping 'Done' or
focusing other platform UI), we don't want to allow the page to show the keyboard due to element focus.

To fix this issue, we enforce that we're either becoming the first responder or already are the first responder
before showing the keyboard due to activity state change or focused element change.

Test: fast/events/ios/do-not-show-keyboard-when-focusing-after-blur.html

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setupInteraction]):
(-[WKContentView textInputTraits]):

Quick drive-by tweak: rename _isBlurringFocusedNode to _isBlurringFocusedElement, to match the rest of the
terminology used in WebKit.

(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):

Make our heuristics for determining whether to show the keyboard a tiny bit easier to follow, by moving the
logic into a lambda function and using early returns. See above for more details.

(-[WKContentView _elementDidBlur]):
(-[WKContentView focusedFormControllerDidUpdateSuggestions:]):

LayoutTests:

Add a test to verify that after resigning first responder (e.g. tapping 'Done' on the keyboard, or focusing a
native input field elsewhere in the app), the page cannot force the keyboard to appear by focusing an input
field.

* fast/events/ios/do-not-show-keyboard-when-focusing-after-blur-expected.txt: Added.
* fast/events/ios/do-not-show-keyboard-when-focusing-after-blur.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242173 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/fast/events/ios/do-not-show-keyboard-when-focusing-after-blur-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/do-not-show-keyboard-when-focusing-after-blur.html [new file with mode: 0644]
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm