Changeset 239441 in webkit


Ignore:
Timestamp:
Dec 20, 2018 8:28:55 AM (5 years ago)
Author:
Wenson Hsieh
Message:

[iOS] Focusing an editable element should scroll to reveal the selection
https://bugs.webkit.org/show_bug.cgi?id=192802
<rdar://problem/46781759>

Reviewed by Tim Horton.

Source/WebKit:

Currently, when tapping on an editable element, logic in -[WKWebView _zoomToFocusRect:…:] attempts to adjust the
visible viewport such that the rect containing the selection is visible. However, AssistedNodeInformation's
selectionRect is used here, which (as the FIXME in WebPage::getAssistedNodeInformation notes) is either the last
touch location, or the top left of the element if the touch location is outside of the element's bounding rect.
This leads to confusing and undesirable behavior when tapping near the bottom of a large contenteditable element
to focus it, since the actual selection will end up near the top of the element, yet we'll try to scroll to
reveal the bottom of the element, which causes the visible selection to scroll offscreen. Notably, this affects
scenarios involving editable web views embedded in apps, such as Mail compose.

Right now, we use the last touch location as an approximation for the selection rect because the selection may
have not yet been updated at the moment when focus moves into an editable element. To fix this, we defer the
process of zooming to the focused element rect until after the selection changes and the UI process is updated
with information about the new selection rects.

Test: editing/selection/ios/selection-is-visible-after-focusing-editable-area.html

  • Shared/AssistedNodeInformation.cpp:

(WebKit::AssistedNodeInformation::encode const):
(WebKit::AssistedNodeInformation::decode):

  • Shared/AssistedNodeInformation.h:

Rename selectionRect to elementInteractionLocation, to more accurately reflect its value and purpose. This isn't
strictly always the last touch location, since we may default to the focused element location instead if the
last touch location is outside of the element rect.

  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):

Tweak a constant that determines the minimum amount of margin to leave between the selection rect and the edge
of the window when scrolling to reveal the focused element. Previously, this was larger than necessary to
accomodate for the fact that the "selection rect" used when zooming to the focused element did not take the
actual selection into account at all, and was simply a 1 by 1 rect; this meant that the margin needed to be
large enough to exceed the usual height of a text caret in editable content. Since we now use the real selection
rect, we can be much less generous with this margin.

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView cleanupInteraction]):
(-[WKContentView observeValueForKeyPath:ofObject:change:context:]):

Don't additionally update the selection in the middle of triggering zooming to the focused element; on
particular versions of iOS, this now attempts to scroll the selection rect on-screen, which then conflicts with
zooming to reveal the focused element.

(-[WKContentView _zoomToRevealFocusedElement]):

Renamed from _displayFormNodeInputView to _zoomToRevealFocusedElement, to make the purpose of this function more
clear. Additionally, pull logic to update the accessory view out of this method, so that it's strictly concerned
with zooming to the focused element.

(-[WKContentView inputView]):

Add a FIXME describing the implications of zooming to the focused element in the implementation of -inputView.
See also: <https://bugs.webkit.org/show_bug.cgi?id=192878>.

(-[WKContentView accessoryTab:]):

Fix a subtle issue when keeping track of _didAccessoryTabInitiateFocus. Currently, this is set to YES in
-accessoryTab: and unset in _displayFormNodeInputView, but since _displayFormNodeInputView may be invoked
multiple times for the same focused element (see: -inputView), we might end up zooming to the focused element
with _didAccessoryTabInitiateFocus set to NO, even though we initiated focus with the previous/next buttons.

Instead, temporarily set a different ivar, _isChangingFocusUsingAccessoryTab, to YES in -accessoryTab:, and
unset it in the completion handler after the focused element has changed. Then, when we _startAssistingNode:,
set _didAccessoryTabInitiateFocus to _isChangingFocusUsingAccessoryTab. This ensures that the correctness of
_didAccessoryTabInitiateFocus isn't tied to the number of times -[WKContentView inputView] is invoked when
focusing an element.

(shouldZoomToRevealSelectionRect):
(rectToRevealWhenZoomingToFocusedElement):

Add a helper method to determine the selection rect to use when zooming to reveal the focused element. ASSERTs
that we have post-layout data in the EditorState.

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

When "assisting" a focused element, immediately zoom to it if we don't need selection information to compute the
rect to zoom to; otherwise, defer zooming until we receive the first editor state update in the UI process that
contains information about our selection rects.

(-[WKContentView _stopAssistingNode]):
(-[WKContentView _didReceiveEditorStateUpdateAfterFocus]):

If necessary, reveal the focused element by zooming.

(-[WKContentView _updateInitialWritingDirectionIfNecessary]):

Pull this initial writing direction update logic out into a separate helper method.

(-[WKContentView _displayFormNodeInputView]): Deleted.

Replaced by _zoomToRevealFocusedElement.

  • WebProcess/WebCoreSupport/WebChromeClient.cpp:

(WebKit::WebChromeClient::elementDidRefocus):

This currently calls WebChromeClient::elementDidFocus; instead, call the new WebPage::elementDidRefocus;
additionally, make this available on all PLATFORM(COCOA), rather than just IOS_FAMILY.

  • WebProcess/WebCoreSupport/WebChromeClient.h:
  • WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:

(WebKit::WebChromeClient::elementDidRefocus): Deleted.

Replaced by the PLATFORM(COCOA) version.

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::elementDidRefocus):

When refocusing an element, ensure that post-layout editor state data is sent to the UI process by including a
full EditorState in the next layer tree transaction.

  • WebProcess/WebPage/WebPage.h:
  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::completeSyntheticClick):

Call elementDidRefocus instead of elementDidFocus, in the case where the existing focused element is clicked.

(WebKit::WebPage::getAssistedNodeInformation):

Adjust for the change from selectionRect to elementInteractionLocation.

LayoutTests:

Adds a new layout test to verify that tapping near the bottom of a tall editable element to focus it doesn't
cause the page to scroll up (and, as a result, leave the selection caret obscured).

  • editing/selection/ios/selection-is-visible-after-focusing-editable-area-expected.txt: Added.
  • editing/selection/ios/selection-is-visible-after-focusing-editable-area.html: Added.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r239424 r239441  
     12018-12-20  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Focusing an editable element should scroll to reveal the selection
     4        https://bugs.webkit.org/show_bug.cgi?id=192802
     5        <rdar://problem/46781759>
     6
     7        Reviewed by Tim Horton.
     8
     9        Adds a new layout test to verify that tapping near the bottom of a tall editable element to focus it doesn't
     10        cause the page to scroll up (and, as a result, leave the selection caret obscured).
     11
     12        * editing/selection/ios/selection-is-visible-after-focusing-editable-area-expected.txt: Added.
     13        * editing/selection/ios/selection-is-visible-after-focusing-editable-area.html: Added.
     14
    1152018-12-19  Ross Kirsling  <ross.kirsling@sony.com>
    216
  • trunk/Source/WebKit/ChangeLog

    r239440 r239441  
     12018-12-20  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        [iOS] Focusing an editable element should scroll to reveal the selection
     4        https://bugs.webkit.org/show_bug.cgi?id=192802
     5        <rdar://problem/46781759>
     6
     7        Reviewed by Tim Horton.
     8
     9        Currently, when tapping on an editable element, logic in -[WKWebView _zoomToFocusRect:…:] attempts to adjust the
     10        visible viewport such that the rect containing the selection is visible. However, AssistedNodeInformation's
     11        selectionRect is used here, which (as the FIXME in WebPage::getAssistedNodeInformation notes) is either the last
     12        touch location, or the top left of the element if the touch location is outside of the element's bounding rect.
     13        This leads to confusing and undesirable behavior when tapping near the bottom of a large contenteditable element
     14        to focus it, since the actual selection will end up near the top of the element, yet we'll try to scroll to
     15        reveal the bottom of the element, which causes the visible selection to scroll offscreen. Notably, this affects
     16        scenarios involving editable web views embedded in apps, such as Mail compose.
     17
     18        Right now, we use the last touch location as an approximation for the selection rect because the selection may
     19        have not yet been updated at the moment when focus moves into an editable element. To fix this, we defer the
     20        process of zooming to the focused element rect until after the selection changes and the UI process is updated
     21        with information about the new selection rects.
     22
     23        Test: editing/selection/ios/selection-is-visible-after-focusing-editable-area.html
     24
     25        * Shared/AssistedNodeInformation.cpp:
     26        (WebKit::AssistedNodeInformation::encode const):
     27        (WebKit::AssistedNodeInformation::decode):
     28        * Shared/AssistedNodeInformation.h:
     29
     30        Rename selectionRect to elementInteractionLocation, to more accurately reflect its value and purpose. This isn't
     31        strictly always the last touch location, since we may default to the focused element location instead if the
     32        last touch location is outside of the element rect.
     33
     34        * UIProcess/API/Cocoa/WKWebView.mm:
     35        (-[WKWebView _zoomToFocusRect:selectionRect:insideFixed:fontSize:minimumScale:maximumScale:allowScaling:forceScroll:]):
     36
     37        Tweak a constant that determines the minimum amount of margin to leave between the selection rect and the edge
     38        of the window when scrolling to reveal the focused element. Previously, this was larger than necessary to
     39        accomodate for the fact that the "selection rect" used when zooming to the focused element did not take the
     40        actual selection into account at all, and was simply a 1 by 1 rect; this meant that the margin needed to be
     41        large enough to exceed the usual height of a text caret in editable content. Since we now use the real selection
     42        rect, we can be much less generous with this margin.
     43
     44        * UIProcess/ios/WKContentViewInteraction.h:
     45        * UIProcess/ios/WKContentViewInteraction.mm:
     46        (-[WKContentView cleanupInteraction]):
     47        (-[WKContentView observeValueForKeyPath:ofObject:change:context:]):
     48
     49        Don't additionally update the selection in the middle of triggering zooming to the focused element; on
     50        particular versions of iOS, this now attempts to scroll the selection rect on-screen, which then conflicts with
     51        zooming to reveal the focused element.
     52
     53        (-[WKContentView _zoomToRevealFocusedElement]):
     54
     55        Renamed from _displayFormNodeInputView to _zoomToRevealFocusedElement, to make the purpose of this function more
     56        clear. Additionally, pull logic to update the accessory view out of this method, so that it's strictly concerned
     57        with zooming to the focused element.
     58
     59        (-[WKContentView inputView]):
     60
     61        Add a FIXME describing the implications of zooming to the focused element in the implementation of -inputView.
     62        See also: <https://bugs.webkit.org/show_bug.cgi?id=192878>.
     63
     64        (-[WKContentView accessoryTab:]):
     65
     66        Fix a subtle issue when keeping track of _didAccessoryTabInitiateFocus. Currently, this is set to YES in
     67        -accessoryTab: and unset in _displayFormNodeInputView, but since _displayFormNodeInputView may be invoked
     68        multiple times for the same focused element (see: -inputView), we might end up zooming to the focused element
     69        with _didAccessoryTabInitiateFocus set to NO, even though we initiated focus with the previous/next buttons.
     70
     71        Instead, temporarily set a different ivar, _isChangingFocusUsingAccessoryTab, to YES in -accessoryTab:, and
     72        unset it in the completion handler after the focused element has changed. Then, when we _startAssistingNode:,
     73        set _didAccessoryTabInitiateFocus to _isChangingFocusUsingAccessoryTab. This ensures that the correctness of
     74        _didAccessoryTabInitiateFocus isn't tied to the number of times -[WKContentView inputView] is invoked when
     75        focusing an element.
     76
     77        (shouldZoomToRevealSelectionRect):
     78        (rectToRevealWhenZoomingToFocusedElement):
     79
     80        Add a helper method to determine the selection rect to use when zooming to reveal the focused element. ASSERTs
     81        that we have post-layout data in the EditorState.
     82
     83        (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
     84
     85        When "assisting" a focused element, immediately zoom to it if we don't need selection information to compute the
     86        rect to zoom to; otherwise, defer zooming until we receive the first editor state update in the UI process that
     87        contains information about our selection rects.
     88
     89        (-[WKContentView _stopAssistingNode]):
     90        (-[WKContentView _didReceiveEditorStateUpdateAfterFocus]):
     91
     92        If necessary, reveal the focused element by zooming.
     93
     94        (-[WKContentView _updateInitialWritingDirectionIfNecessary]):
     95
     96        Pull this initial writing direction update logic out into a separate helper method.
     97
     98        (-[WKContentView _displayFormNodeInputView]): Deleted.
     99
     100        Replaced by _zoomToRevealFocusedElement.
     101
     102        * WebProcess/WebCoreSupport/WebChromeClient.cpp:
     103        (WebKit::WebChromeClient::elementDidRefocus):
     104
     105        This currently calls WebChromeClient::elementDidFocus; instead, call the new WebPage::elementDidRefocus;
     106        additionally, make this available on all PLATFORM(COCOA), rather than just IOS_FAMILY.
     107
     108        * WebProcess/WebCoreSupport/WebChromeClient.h:
     109        * WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm:
     110        (WebKit::WebChromeClient::elementDidRefocus): Deleted.
     111
     112        Replaced by the PLATFORM(COCOA) version.
     113
     114        * WebProcess/WebPage/WebPage.cpp:
     115        (WebKit::WebPage::elementDidRefocus):
     116
     117        When refocusing an element, ensure that post-layout editor state data is sent to the UI process by including a
     118        full EditorState in the next layer tree transaction.
     119
     120        * WebProcess/WebPage/WebPage.h:
     121        * WebProcess/WebPage/ios/WebPageIOS.mm:
     122        (WebKit::WebPage::completeSyntheticClick):
     123
     124        Call elementDidRefocus instead of elementDidFocus, in the case where the existing focused element is clicked.
     125
     126        (WebKit::WebPage::getAssistedNodeInformation):
     127
     128        Adjust for the change from selectionRect to elementInteractionLocation.
     129
    11302018-12-20  Patrick Griffis  <pgriffis@igalia.com>
    2131
  • trunk/Source/WebKit/Shared/AssistedNodeInformation.cpp

    r239427 r239441  
    6565{
    6666    encoder << elementRect;
    67     encoder << selectionRect;
     67    encoder << elementInteractionLocation;
    6868    encoder << minimumScaleFactor;
    6969    encoder << maximumScaleFactor;
     
    113113        return false;
    114114
    115     if (!decoder.decode(result.selectionRect))
     115    if (!decoder.decode(result.elementInteractionLocation))
    116116        return false;
    117117
  • trunk/Source/WebKit/Shared/AssistedNodeInformation.h

    r239427 r239441  
    9696struct AssistedNodeInformation {
    9797    WebCore::IntRect elementRect;
    98     WebCore::IntRect selectionRect;
     98    WebCore::IntPoint elementInteractionLocation;
    9999    double minimumScaleFactor { -INFINITY };
    100100    double maximumScaleFactor { INFINITY };
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r239427 r239441  
    22482248    const double minimumHeightToShowContentAboveKeyboard = 106;
    22492249    const CFTimeInterval formControlZoomAnimationDuration = 0.25;
    2250     const double caretOffsetFromWindowEdge = 20;
     2250    const double caretOffsetFromWindowEdge = 8;
    22512251
    22522252    UIWindow *window = [_scrollView window];
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r239427 r239441  
    302302    BOOL _usingGestureForSelection;
    303303    BOOL _inspectorNodeSearchEnabled;
     304    BOOL _isChangingFocusUsingAccessoryTab;
    304305    BOOL _didAccessoryTabInitiateFocus;
    305306    BOOL _isExpectingFastSingleTapCommit;
    306307    BOOL _showDebugTapHighlightsForFastClicking;
     308    BOOL _isZoomingToRevealFocusedElement;
    307309
    308310    BOOL _becomingFirstResponder;
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r239427 r239441  
    758758    _smartMagnificationController = nil;
    759759    _didAccessoryTabInitiateFocus = NO;
     760    _isChangingFocusUsingAccessoryTab = NO;
    760761    _isExpectingFastSingleTapCommit = NO;
    761762    _needsDeferredEndScrollingSelectionUpdate = NO;
     
    855856    _hasSetUpInteractions = NO;
    856857    _suppressSelectionAssistantReasons = { };
     858    _isZoomingToRevealFocusedElement = NO;
    857859}
    858860
     
    942944    }
    943945
     946    [self _updateTapHighlight];
     947
     948    if (_isZoomingToRevealFocusedElement) {
     949        // When zooming to the focused element, avoid additionally scrolling to reveal the selection. Since the scale transform has not yet been
     950        // applied to the content view at this point, we'll end up scrolling to reveal a rect that is computed using the wrong scale.
     951        return;
     952    }
     953
    944954    _selectionNeedsUpdate = YES;
    945955    [self _updateChangedSelection:YES];
    946     [self _updateTapHighlight];
    947956}
    948957
     
    13881397}
    13891398
    1390 - (void)_displayFormNodeInputView
    1391 {
    1392     if (!_suppressSelectionAssistantReasons.contains(WebKit::FocusedElementIsTransparent)) {
    1393         // In case user scaling is force enabled, do not use that scaling when zooming in with an input field.
    1394         // Zooming above the page's default scale factor should only happen when the user performs it.
    1395         [self _zoomToFocusRect:_assistedNodeInformation.elementRect
    1396             selectionRect:_didAccessoryTabInitiateFocus ? WebCore::IntRect() : _assistedNodeInformation.selectionRect
    1397             insideFixed:_assistedNodeInformation.insideFixedPosition
    1398             fontSize:_assistedNodeInformation.nodeFontSize
    1399             minimumScale:_assistedNodeInformation.minimumScaleFactor
    1400             maximumScale:_assistedNodeInformation.maximumScaleFactorIgnoringAlwaysScalable
    1401             allowScaling:_assistedNodeInformation.allowsUserScalingIgnoringAlwaysScalable && !currentUserInterfaceIdiomIsPad()
    1402             forceScroll:(_assistedNodeInformation.inputMode == WebCore::InputMode::None) ? !currentUserInterfaceIdiomIsPad() : [self requiresAccessoryView]];
    1403     }
    1404 
    1405     _didAccessoryTabInitiateFocus = NO;
    1406     [self _ensureFormAccessoryView];
    1407     [self _updateAccessory];
     1399- (void)_zoomToRevealFocusedElement
     1400{
     1401    if (_suppressSelectionAssistantReasons.contains(WebKit::FocusedElementIsTransparent))
     1402        return;
     1403
     1404    SetForScope<BOOL> isZoomingToRevealFocusedElementForScope { _isZoomingToRevealFocusedElement, YES };
     1405    // In case user scaling is force enabled, do not use that scaling when zooming in with an input field.
     1406    // Zooming above the page's default scale factor should only happen when the user performs it.
     1407    [self _zoomToFocusRect:_assistedNodeInformation.elementRect
     1408        selectionRect:_didAccessoryTabInitiateFocus ? WebCore::FloatRect() : rectToRevealWhenZoomingToFocusedElement(_assistedNodeInformation, _page->editorState())
     1409        insideFixed:_assistedNodeInformation.insideFixedPosition
     1410        fontSize:_assistedNodeInformation.nodeFontSize
     1411        minimumScale:_assistedNodeInformation.minimumScaleFactor
     1412        maximumScale:_assistedNodeInformation.maximumScaleFactorIgnoringAlwaysScalable
     1413        allowScaling:_assistedNodeInformation.allowsUserScalingIgnoringAlwaysScalable && !currentUserInterfaceIdiomIsPad()
     1414        forceScroll:(_assistedNodeInformation.inputMode == WebCore::InputMode::None) ? !currentUserInterfaceIdiomIsPad() : [self requiresAccessoryView]];
    14081415}
    14091416
     
    14301437            break;
    14311438        }
    1432     } else
    1433         [self _displayFormNodeInputView];
     1439    } else {
     1440        // FIXME: UIKit may invoke -[WKContentView inputView] at any time when WKContentView is the first responder;
     1441        // as such, it doesn't make sense to change the enclosing scroll view's zoom scale and content offset to reveal
     1442        // the focused element here. It seems this behavior was added to match logic in legacy WebKit (refer to
     1443        // UIWebBrowserView). Instead, we should find the places where we currently assume that UIKit (or other clients)
     1444        // invoke -inputView to zoom to the focused element, and either surface SPI for clients to zoom to the focused
     1445        // element, or explicitly trigger the zoom from WebKit.
     1446        // For instance, one use case that currently relies on this detail is adjusting the zoom scale and viewport upon
     1447        // rotation, when a select element is focused. See <https://webkit.org/b/192878> for more information.
     1448        [self _zoomToRevealFocusedElement];
     1449        [self _ensureFormAccessoryView];
     1450        [self _updateAccessory];
     1451    }
    14341452
    14351453    if (UIView *customInputView = [_formInputSession customInputView])
     
    33313349    _inputPeripheral = nil;
    33323350
    3333     _didAccessoryTabInitiateFocus = YES; // Will be cleared in either -_displayFormNodeInputView or -cleanupInteraction.
     3351    _isChangingFocusUsingAccessoryTab = YES;
    33343352    [self beginSelectionChange];
    33353353    RetainPtr<WKContentView> view = self;
     
    33373355        [view endSelectionChange];
    33383356        [view reloadInputViews];
     3357        view->_isChangingFocusUsingAccessoryTab = NO;
    33393358    });
    33403359}
     
    43494368}
    43504369
     4370static bool shouldZoomToRevealSelectionRect(WebKit::InputType type)
     4371{
     4372    switch (type) {
     4373    case WebKit::InputType::ContentEditable:
     4374    case WebKit::InputType::Text:
     4375    case WebKit::InputType::Password:
     4376    case WebKit::InputType::TextArea:
     4377    case WebKit::InputType::Search:
     4378    case WebKit::InputType::Email:
     4379    case WebKit::InputType::URL:
     4380    case WebKit::InputType::Phone:
     4381    case WebKit::InputType::Number:
     4382    case WebKit::InputType::NumberPad:
     4383        return true;
     4384    default:
     4385        return false;
     4386    }
     4387}
     4388
     4389static WebCore::FloatRect rectToRevealWhenZoomingToFocusedElement(const WebKit::AssistedNodeInformation& elementInfo, const WebKit::EditorState& editorState)
     4390{
     4391    WebCore::IntRect elementInteractionRect(elementInfo.elementInteractionLocation, { 1, 1 });
     4392    if (!shouldZoomToRevealSelectionRect(elementInfo.elementType))
     4393        return elementInteractionRect;
     4394
     4395    if (editorState.isMissingPostLayoutData) {
     4396        ASSERT_NOT_REACHED();
     4397        return elementInteractionRect;
     4398    }
     4399
     4400    if (editorState.selectionIsNone)
     4401        return { };
     4402
     4403    WebCore::FloatRect selectionBoundingRect;
     4404    auto& postLayoutData = editorState.postLayoutData();
     4405    if (editorState.selectionIsRange) {
     4406        for (auto& rect : postLayoutData.selectionRects)
     4407            selectionBoundingRect.unite(rect.rect());
     4408    } else
     4409        selectionBoundingRect = postLayoutData.caretRectAtStart;
     4410
     4411    selectionBoundingRect.intersect(elementInfo.elementRect);
     4412    return selectionBoundingRect;
     4413}
     4414
    43514415static bool isAssistableInputType(WebKit::InputType type)
    43524416{
     
    43884452    _inputViewUpdateDeferrer = nullptr;
    43894453
     4454    _didAccessoryTabInitiateFocus = _isChangingFocusUsingAccessoryTab;
     4455
    43904456    id <_WKInputDelegate> inputDelegate = [_webView _inputDelegate];
    43914457    RetainPtr<WKFocusedElementInfo> focusedElementInfo = adoptNS([[WKFocusedElementInfo alloc] initWithAssistedNodeInformation:information isUserInitiated:userIsInteracting userObject:userObject]);
     
    45074573        [_webView _scheduleVisibleContentRectUpdate];
    45084574   
    4509     [self _displayFormNodeInputView];
     4575    if (!shouldZoomToRevealSelectionRect(_assistedNodeInformation.elementType))
     4576        [self _zoomToRevealFocusedElement];
     4577
     4578    [self _ensureFormAccessoryView];
     4579    [self _updateAccessory];
    45104580
    45114581#if PLATFORM(WATCHOS)
     
    45644634
    45654635    [self _stopSuppressingSelectionAssistantForReason:WebKit::FocusedElementIsTransparent];
     4636
     4637    if (!_isChangingFocus)
     4638        _didAccessoryTabInitiateFocus = NO;
    45664639}
    45674640
    45684641- (void)_didReceiveEditorStateUpdateAfterFocus
     4642{
     4643    [self _updateInitialWritingDirectionIfNecessary];
     4644
     4645    // FIXME: If the initial writing direction just changed, we should wait until we get the next post-layout editor state
     4646    // before zooming to reveal the selection rect.
     4647    if (shouldZoomToRevealSelectionRect(_assistedNodeInformation.elementType))
     4648        [self _zoomToRevealFocusedElement];
     4649}
     4650
     4651- (void)_updateInitialWritingDirectionIfNecessary
    45694652{
    45704653    if (!_page->isEditable())
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp

    r239427 r239441  
    204204}
    205205
     206void WebChromeClient::elementDidRefocus(Element& element)
     207{
     208    m_page.elementDidRefocus(&element);
     209}
     210
    206211void WebChromeClient::elementDidBlur(Element& element)
    207212{
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h

    r239427 r239441  
    253253#endif
    254254
    255 #if PLATFORM(IOS_FAMILY)
    256     void elementDidRefocus(WebCore::Element&) final;
    257 #endif
    258 
    259255#if (PLATFORM(IOS_FAMILY) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
    260256    bool supportsVideoFullscreen(WebCore::HTMLMediaElementEnums::VideoFullscreenMode) final;
     
    279275    void elementDidFocus(WebCore::Element&) final;
    280276    void elementDidBlur(WebCore::Element&) final;
     277    void elementDidRefocus(WebCore::Element&) final;
    281278
    282279    void makeFirstResponder() final;
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/ios/WebChromeClientIOS.mm

    r238538 r239441  
    5353
    5454#endif
    55 
    56 void WebChromeClient::elementDidRefocus(WebCore::Element& element)
    57 {
    58     elementDidFocus(element);
    59 }
    6055
    6156void WebChromeClient::didReceiveMobileDocType(bool isMobileDoctype)
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r239427 r239441  
    52795279}
    52805280
     5281void WebPage::elementDidRefocus(WebCore::Node* node)
     5282{
     5283    elementDidFocus(node);
     5284    m_hasPendingEditorStateUpdate = true;
     5285}
     5286
    52815287void WebPage::elementDidFocus(WebCore::Node* node)
    52825288{
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r239427 r239441  
    586586#endif
    587587
     588    // FIXME: These should all take Element& instead of Node*.
    588589    void elementDidFocus(WebCore::Node*);
     590    void elementDidRefocus(WebCore::Node*);
    589591    void elementDidBlur(WebCore::Node*);
    590592    void resetAssistedNodeForFrame(WebFrame*);
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r239427 r239441  
    616616    // keyboard is not on screen.
    617617    if (newFocusedElement && newFocusedElement == oldFocusedElement)
    618         elementDidFocus(newFocusedElement.get());
     618        elementDidRefocus(newFocusedElement.get());
    619619
    620620    if (!tapWasHandled || !nodeRespondingToClick || !nodeRespondingToClick->isElementNode())
     
    23642364    layoutIfNeeded();
    23652365
    2366     // FIXME: information.selectionRect should be set to the actual selection rect, but when this is called at focus time
    2367     // we don't have a selection yet. Using the last interaction location is a reasonable approximation for now.
    2368     information.selectionRect = IntRect(m_lastInteractionLocation, IntSize(1, 1));
     2366    information.elementInteractionLocation = m_lastInteractionLocation;
    23692367
    23702368    if (RenderObject* renderer = m_assistedNode->renderer()) {
     
    23872385           
    23882386            if (!information.elementRect.contains(m_lastInteractionLocation))
    2389                 information.selectionRect.setLocation(information.elementRect.location());
     2387                information.elementInteractionLocation = information.elementRect.location();
    23902388        } else {
    23912389            // Don't use the selection rect if interaction was outside the element rect.
    23922390            if (!information.elementRect.contains(m_lastInteractionLocation))
    2393                 information.selectionRect = IntRect();
     2391                information.elementInteractionLocation = { };
    23942392        }
    23952393    } else
Note: See TracChangeset for help on using the changeset viewer.