Changeset 202132 in webkit


Ignore:
Timestamp:
Jun 16, 2016 11:49:14 AM (8 years ago)
Author:
Simon Fraser
Message:

[iOS WK2] On iPad, indirect focussing of a text field doesn't always scroll to the correct location
https://bugs.webkit.org/show_bug.cgi?id=158828

Reviewed by Enrica Casucci.

Source/WebKit2:

WebPage::getAssistedNodeInformation() unconditionally set information.selectionRect()
to a 1x1 rect at the last interaction location. This caused -[WKWebView _zoomToFocusRect:...]
to early return under the !forceScroll clause if the last interaction rect was visible, but
the elementRect was not. This would happen, for example, if a click in a <button> focussed
an input on some other portion of the page. This behavior is iPad-only, because forceScroll
is only NO there.

Fix by making getAssistedNodeInformation() only set the selectionRect to the last interaction
location if that is inside of the elementRect (this caters to the case where a tap is inside
an input which is larger than the screen). Otherwise, set it to the empty rect.

Make this testable by allowing a test to opt into the iPad-style scrolling/zooming behavior
in this code path (essentially, making forceScroll NO for testing), via testing SPI on WKWebView,
plumbed through to WKContentView.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView forceIPadStyleZoomOnInputFocus]):
(-[WKWebView setForceIPadStyleZoomOnInputFocus:]):

  • UIProcess/API/Cocoa/WKWebViewPrivate.h:
  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView _displayFormNodeInputView]):
(-[WKContentView requiresAccessoryView:]):
(-[WKContentView inputAccessoryView]):
(-[WKContentView forceIPadStyleZoomOnInputFocus]):
(-[WKContentView setForceIPadStyleZoomOnInputFocus:]):
(-[WKContentView requiresAccessoryView]): Remove redundant returns, and allow testing to
override the "isIPad" condition.

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::getAssistedNodeInformation):

Tools:

Expose "forceIPadStyleZoomOnInputFocus" on UIScriptController, which allows iPad-style
zooming behavior on <input> focus in the iPhone simulator, which is used for testing.

  • WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl:
  • WebKitTestRunner/UIScriptContext/UIScriptController.cpp:

(WTR::UIScriptController::forceIPadStyleZoomOnInputFocus):
(WTR::UIScriptController::setForceIPadStyleZoomOnInputFocus):

  • WebKitTestRunner/UIScriptContext/UIScriptController.h:
  • WebKitTestRunner/ios/TestControllerIOS.mm:

(WTR::TestController::platformResetStateToConsistentValues):

  • WebKitTestRunner/ios/UIScriptControllerIOS.mm:

(WTR::UIScriptController::forceIPadStyleZoomOnInputFocus):
(WTR::UIScriptController::setForceIPadStyleZoomOnInputFocus):

LayoutTests:

Add various tests for focusing form fields. focus-input-via-button-ipad.html tests
the change in the current patch.

  • fast/forms/ios/focus-input-in-fixed-expected.txt: Added.
  • fast/forms/ios/focus-input-in-fixed.html: Added.
  • fast/forms/ios/focus-input-via-button-ipad-expected.txt: Added.
  • fast/forms/ios/focus-input-via-button-ipad.html: Added.
  • fast/forms/ios/focus-long-textarea-expected.txt: Added.
  • fast/forms/ios/focus-long-textarea.html: Added.
  • fast/forms/ios/resources/zooming-test-utils.js:

(testZoomAfterTap):

Location:
trunk
Files:
6 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r202130 r202132  
     12016-06-15  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS WK2] On iPad, indirect focussing of a text field doesn't always scroll to the correct location
     4        https://bugs.webkit.org/show_bug.cgi?id=158828
     5
     6        Reviewed by Enrica Casucci.
     7       
     8        Add various tests for focusing form fields. focus-input-via-button-ipad.html tests
     9        the change in the current patch.
     10
     11        * fast/forms/ios/focus-input-in-fixed-expected.txt: Added.
     12        * fast/forms/ios/focus-input-in-fixed.html: Added.
     13        * fast/forms/ios/focus-input-via-button-ipad-expected.txt: Added.
     14        * fast/forms/ios/focus-input-via-button-ipad.html: Added.
     15        * fast/forms/ios/focus-long-textarea-expected.txt: Added.
     16        * fast/forms/ios/focus-long-textarea.html: Added.
     17        * fast/forms/ios/resources/zooming-test-utils.js:
     18        (testZoomAfterTap):
     19
    1202016-06-16  Adam Bergkvist  <adam.bergkvist@ericsson.com>
    221
  • trunk/LayoutTests/fast/forms/ios/resources/zooming-test-utils.js

    r202116 r202132  
    11
    2 function testZoomAfterTap(targetElement, xOffset, yOffset)
     2function testZoomAfterTap(targetElement, xOffset, yOffset, useIPadBehavior)
    33{
    44    if (!window.testRunner || !testRunner.runUIScript)
     
    77    var point = getPointInsideElement(targetElement, xOffset, yOffset);
    88
    9     var uiScript = zoomAfterSingleTapUIScript(point.x, point.y);
     9    var uiScript = zoomAfterSingleTapUIScript(point.x, point.y, useIPadBehavior);
    1010    testRunner.runUIScript(uiScript, function(result) {
    1111        var results = tableFromJSON(result);
     
    1515}
    1616
    17 function zoomAfterSingleTapUIScript(x, y)
     17function zoomAfterSingleTapUIScript(x, y, useIPadBehavior)
    1818{
    1919    return `
     
    3535            };
    3636
     37            if (${useIPadBehavior})
     38                uiController.forceIPadStyleZoomOnInputFocus = true;
    3739            uiController.singleTapAtPoint(${x}, ${y}, function() {});
    3840        })();`
  • trunk/Source/WebKit2/ChangeLog

    r202129 r202132  
     12016-06-15  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS WK2] On iPad, indirect focussing of a text field doesn't always scroll to the correct location
     4        https://bugs.webkit.org/show_bug.cgi?id=158828
     5
     6        Reviewed by Enrica Casucci.
     7       
     8        WebPage::getAssistedNodeInformation() unconditionally set information.selectionRect()
     9        to a 1x1 rect at the last interaction location. This caused -[WKWebView _zoomToFocusRect:...]
     10        to early return under the !forceScroll clause if the last interaction rect was visible, but
     11        the elementRect was not. This would happen, for example, if a click in a <button> focussed
     12        an input on some other portion of the page. This behavior is iPad-only, because forceScroll
     13        is only NO there.
     14       
     15        Fix by making getAssistedNodeInformation() only set the selectionRect to the last interaction
     16        location if that is inside of the elementRect (this caters to the case where a tap is inside
     17        an input which is larger than the screen). Otherwise, set it to the empty rect.
     18       
     19        Make this testable by allowing a test to opt into the iPad-style scrolling/zooming behavior
     20        in this code path (essentially, making forceScroll NO for testing), via testing SPI on WKWebView,
     21        plumbed through to WKContentView.
     22
     23        * UIProcess/API/Cocoa/WKWebView.mm:
     24        (-[WKWebView forceIPadStyleZoomOnInputFocus]):
     25        (-[WKWebView setForceIPadStyleZoomOnInputFocus:]):
     26        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
     27        * UIProcess/ios/WKContentViewInteraction.h:
     28        * UIProcess/ios/WKContentViewInteraction.mm:
     29        (-[WKContentView _displayFormNodeInputView]):
     30        (-[WKContentView requiresAccessoryView:]):
     31        (-[WKContentView inputAccessoryView]):
     32        (-[WKContentView forceIPadStyleZoomOnInputFocus]):
     33        (-[WKContentView setForceIPadStyleZoomOnInputFocus:]):
     34        (-[WKContentView requiresAccessoryView]): Remove redundant returns, and allow testing to
     35        override the "isIPad" condition.
     36        * WebProcess/WebPage/ios/WebPageIOS.mm:
     37        (WebKit::WebPage::getAssistedNodeInformation):
     38
    1392016-06-15  Sam Weinig  <sam@webkit.org>
    240
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm

    r202129 r202132  
    44874487}
    44884488
     4489- (BOOL)forceIPadStyleZoomOnInputFocus
     4490{
     4491    return [_contentView forceIPadStyleZoomOnInputFocus];
     4492}
     4493
     4494- (void)setForceIPadStyleZoomOnInputFocus:(BOOL)forceIPadStyleZoom
     4495{
     4496    [_contentView setForceIPadStyleZoomOnInputFocus:forceIPadStyleZoom];
     4497}
     4498
    44894499#endif // PLATFORM(IOS)
    44904500
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h

    r202120 r202132  
    256256- (CGPoint)_convertPointFromViewToContents:(CGPoint)point WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
    257257
    258 - (void)keyboardAccessoryBarNext;
    259 - (void)keyboardAccessoryBarPrevious;
     258- (void)keyboardAccessoryBarNext WK_AVAILABLE(NA, WK_IOS_TBA);
     259- (void)keyboardAccessoryBarPrevious WK_AVAILABLE(NA, WK_IOS_TBA);
     260
     261@property (nonatomic) BOOL forceIPadStyleZoomOnInputFocus WK_AVAILABLE(NA, WK_IOS_TBA);
    260262#endif
    261263
  • trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h

    r199558 r202132  
    172172
    173173    BOOL _resigningFirstResponder;
     174
     175    // For testing.
     176    BOOL _forceIPadStyleZoomOnInputFocus;
    174177}
    175178
     
    232235#endif
    233236
     237@interface WKContentView (WKInteractionTesting)
     238
     239@property (nonatomic) BOOL forceIPadStyleZoomOnInputFocus;
     240
     241@end
     242
    234243#endif // PLATFORM(IOS)
  • trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm

    r201347 r202132  
    10681068              minimumScale:_assistedNodeInformation.minimumScaleFactor
    10691069              maximumScale:_assistedNodeInformation.maximumScaleFactor
    1070               allowScaling:(_assistedNodeInformation.allowsUserScalingIgnoringForceAlwaysScaling && !UICurrentUserInterfaceIdiomIsPad())
    1071                forceScroll:[self requiresAccessoryView]];
     1070              allowScaling:(_assistedNodeInformation.allowsUserScalingIgnoringForceAlwaysScaling && (!UICurrentUserInterfaceIdiomIsPad() || _forceIPadStyleZoomOnInputFocus))
     1071               forceScroll:[self requiresAccessoryView:_forceIPadStyleZoomOnInputFocus]];
     1072
    10721073    _didAccessoryTabInitiateFocus = NO;
    10731074    [self _ensureFormAccessoryView];
     
    15801581}
    15811582
    1582 - (BOOL)requiresAccessoryView
     1583- (BOOL)requiresAccessoryView:(BOOL)forceIPadBehavior
    15831584{
    15841585    if ([_formInputSession accessoryViewShouldNotShow])
     
    15961597    case InputType::Number:
    15971598    case InputType::NumberPad:
    1598         return !UICurrentUserInterfaceIdiomIsPad();
    15991599    case InputType::ContentEditable:
    16001600    case InputType::TextArea:
    1601         return !UICurrentUserInterfaceIdiomIsPad();
    16021601    case InputType::Select:
    16031602    case InputType::Date:
     
    16071606    case InputType::Week:
    16081607    case InputType::Time:
    1609         return !UICurrentUserInterfaceIdiomIsPad();
     1608        return !(UICurrentUserInterfaceIdiomIsPad() || forceIPadBehavior);
    16101609    }
    16111610}
     
    16221621- (UIView *)inputAccessoryView
    16231622{
    1624     if (![self requiresAccessoryView])
     1623    if (![self requiresAccessoryView:NO])
    16251624        return nil;
    16261625
     
    41134112#endif
    41144113
     4114@implementation WKContentView (WKInteractionTesting)
     4115
     4116- (BOOL)forceIPadStyleZoomOnInputFocus
     4117{
     4118    return _forceIPadStyleZoomOnInputFocus;
     4119}
     4120
     4121- (void)setForceIPadStyleZoomOnInputFocus:(BOOL)forceIPadStyleZoom
     4122{
     4123    _forceIPadStyleZoomOnInputFocus = forceIPadStyleZoom;
     4124}
     4125
     4126@end
     4127
     4128
    41154129// UITextRange, UITextPosition and UITextSelectionRect implementations for WK2
    41164130
  • trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

    r201888 r202132  
    25172517    layoutIfNeeded();
    25182518
    2519     // FIXME: This should return the selection rect, but when this is called at focus time
     2519    // FIXME: information.selectionRect should be set to the actual selection rect, but when this is called at focus time
    25202520    // we don't have a selection yet. Using the last interaction location is a reasonable approximation for now.
    2521     // FIXME: should the selection rect always be inside the elementRect?
    25222521    information.selectionRect = IntRect(m_lastInteractionLocation, IntSize(1, 1));
    25232522
     
    25392538            frameView->setCustomFixedPositionLayoutRect(currentFixedPositionRect);
    25402539           
    2541             if (!information.elementRect.contains(information.selectionRect))
     2540            if (!information.elementRect.contains(m_lastInteractionLocation))
    25422541                information.selectionRect.setLocation(information.elementRect.location());
     2542        } else {
     2543            // Don't use the selection rect if interaction was outside the element rect.
     2544            if (!information.elementRect.contains(m_lastInteractionLocation))
     2545                information.selectionRect = IntRect();
    25432546        }
    25442547    } else
  • trunk/Tools/ChangeLog

    r202129 r202132  
     12016-06-15  Simon Fraser  <simon.fraser@apple.com>
     2
     3        [iOS WK2] On iPad, indirect focussing of a text field doesn't always scroll to the correct location
     4        https://bugs.webkit.org/show_bug.cgi?id=158828
     5
     6        Reviewed by Enrica Casucci.
     7       
     8        Expose "forceIPadStyleZoomOnInputFocus" on UIScriptController, which allows iPad-style
     9        zooming behavior on <input> focus in the iPhone simulator, which is used for testing.
     10
     11        * WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl:
     12        * WebKitTestRunner/UIScriptContext/UIScriptController.cpp:
     13        (WTR::UIScriptController::forceIPadStyleZoomOnInputFocus):
     14        (WTR::UIScriptController::setForceIPadStyleZoomOnInputFocus):
     15        * WebKitTestRunner/UIScriptContext/UIScriptController.h:
     16        * WebKitTestRunner/ios/TestControllerIOS.mm:
     17        (WTR::TestController::platformResetStateToConsistentValues):
     18        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
     19        (WTR::UIScriptController::forceIPadStyleZoomOnInputFocus):
     20        (WTR::UIScriptController::setForceIPadStyleZoomOnInputFocus):
     21
    1222016-06-15  Sam Weinig  <sam@webkit.org>
    223
  • trunk/Tools/WebKitTestRunner/UIScriptContext/Bindings/UIScriptController.idl

    r202116 r202132  
    6161    readonly attribute object contentVisibleRect; // Returned object has 'left', 'top', 'width', 'height' properties.
    6262
     63    // Behavior
     64    attribute boolean forceIPadStyleZoomOnInputFocus;
     65
    6366    void uiScriptComplete(DOMString result);
    6467};
  • trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp

    r202116 r202132  
    179179}
    180180
     181bool UIScriptController::forceIPadStyleZoomOnInputFocus() const
     182{
     183    return false;
     184}
     185
     186void UIScriptController::setForceIPadStyleZoomOnInputFocus(bool)
     187{
     188}
     189
    181190void UIScriptController::platformSetWillBeginZoomingCallback()
    182191{
  • trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h

    r202116 r202132  
    8181
    8282    JSObjectRef contentVisibleRect() const;
     83   
     84    bool forceIPadStyleZoomOnInputFocus() const;
     85    void setForceIPadStyleZoomOnInputFocus(bool);
    8386
    8487    void uiScriptComplete(JSStringRef result);
  • trunk/Tools/WebKitTestRunner/ios/TestControllerIOS.mm

    r200534 r202132  
    3030#import "TestInvocation.h"
    3131#import <Foundation/Foundation.h>
     32#import <UIKit/UIKit.h>
    3233#import <WebKit/WKPreferencesRefPrivate.h>
    3334#import <WebKit/WKProcessPoolPrivate.h>
    3435#import <WebKit/WKStringCF.h>
    3536#import <WebKit/WKUserContentControllerPrivate.h>
    36 #import <WebKit/WKWebView.h>
    37 #import <WebKit/WKWebViewConfiguration.h>
    3837#import <WebKit/WKWebViewConfigurationPrivate.h>
     38#import <WebKit/WKWebViewPrivate.h>
    3939#import <wtf/MainThread.h>
    4040
     
    8484{
    8585    cocoaResetStateToConsistentValues();
     86    [mainWebView()->platformView() setForceIPadStyleZoomOnInputFocus:NO];
    8687}
    8788
  • trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

    r202116 r202132  
    210210}
    211211
     212bool UIScriptController::forceIPadStyleZoomOnInputFocus() const
     213{
     214    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
     215    return webView.forceIPadStyleZoomOnInputFocus;
     216}
     217
     218void UIScriptController::setForceIPadStyleZoomOnInputFocus(bool value)
     219{
     220    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
     221    webView.forceIPadStyleZoomOnInputFocus = value;
     222}
     223
    212224void UIScriptController::platformSetWillBeginZoomingCallback()
    213225{
Note: See TracChangeset for help on using the changeset viewer.