Title: [227984] trunk/Source/WebKit
Revision
227984
Author
wenson_hs...@apple.com
Date
2018-02-01 15:17:22 -0800 (Thu, 01 Feb 2018)

Log Message

[Extra zoom mode] Implement basic support for interacting with text form controls
https://bugs.webkit.org/show_bug.cgi?id=182401
<rdar://problem/35143035>

Reviewed by Tim Horton.

Add UI support for interacting with and editing text form controls when extra zoom mode is enabled. See below
for more details.

* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):
(-[WKWebViewConfiguration encodeWithCoder:]):
(-[WKWebViewConfiguration initWithCoder:]):
(-[WKWebViewConfiguration copyWithZone:]):
(-[WKWebViewConfiguration _textInteractionGesturesEnabled]):
(-[WKWebViewConfiguration _setTextInteractionGesturesEnabled:]):
(-[WKWebViewConfiguration _longPressActionsEnabled]):
(-[WKWebViewConfiguration _setLongPressActionsEnabled:]):

Introduce two new web view configuration flags: `textInteractionGesturesEnabled` and `longPressActionsEnabled`.
The former determines whether text interaction gestures (i.e. text selection, moving the caret, showing UI for
IME, etc.) are enabled. The latter determines whether or not long press actions (i.e. touch callout, share
sheet, etc.) are enabled. These are disabled by default only in extra zoom mode.

* UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setTextAsync):

Add a way to set the text value of a currently edited text form control. This will either set the text value of
an input, a. la. autofill, or overwrite the contents of a contenteditable area by selecting everything and
inserting the given text.

* UIProcess/WebPageProxy.h:
(WebKit::WebPageProxy::focusNextAssistedNode):

Add a default argument for the completion callback.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setupInteraction]):
(-[WKContentView _displayFormNodeInputView]):
(-[WKContentView _actionForLongPressFromPositionInformation:]):
(-[WKContentView hasSelectablePositionAtPoint:]):
(-[WKContentView pointIsNearMarkedText:]):
(-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
(-[WKContentView insertionPointColor]):

Respect the web view configuration flags above by bailing early from text interaction and long press action
sheet methods.

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

Add a flag indicating whether we are in the process of changing focus from one node to another. We use this to
decide whether or not we want to present the text input view controller right away, or just reload the focused
form control overlay. When we stop "assisting" a node, we also keep the focused form control overlay up if we're
only changing focus to another form control.

(-[WKContentView _stopAssistingNode]):
(-[WKContentView presentFocusedFormControlViewController:]):
(-[WKContentView dismissFocusedFormControlViewController:]):
(-[WKContentView shouldPresentTextInputViewController:]):
(-[WKContentView presentTextInputViewController:]):
(-[WKContentView dismissTextInputViewController:]):

Introduce helpers for managing presentation of the focused form control overlay and text input view controller.
All -present and -dismiss helpers here are idempotent. These view controllers are presented from the content
view's view controller for fullscreen presentation.

(-[WKContentView textInputController:didCommitText:]):
(-[WKContentView textInputController:didRequestDismissalWithAction:]):
(-[WKContentView focusedFormControlControllerDidSubmit:]):
(-[WKContentView focusedFormControlControllerDidCancel:]):
(-[WKContentView focusedFormControlControllerDidBeginEditing:]):
(-[WKContentView highlightedRectForFocusedFormControlController:inCoordinateSpace:]):
(-[WKContentView actionNameForFocusedFormControlController:]):
(-[WKContentView focusedFormControlControllerDidRequestNextNode:]):
(-[WKContentView focusedFormControlControllerDidRequestPreviousNode:]):
(-[WKContentView hasNextNodeForFocusedFormControlController:]):
(-[WKContentView hasPreviousNodeForFocusedFormControlController:]):

Implement delegate methods for the focused form control and text input view controllers. This mainly involves
straightforward plumbing of pieces of AssistedNodeInformation on the content view.

(-[WKContentView pointIsInAssistedNode:]): Deleted.

Remove a method that was still implemented only for binary compatibility with iOS 10.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setTextAsync):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (227983 => 227984)


--- trunk/Source/WebKit/ChangeLog	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/ChangeLog	2018-02-01 23:17:22 UTC (rev 227984)
@@ -1,3 +1,98 @@
+2018-02-01  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        [Extra zoom mode] Implement basic support for interacting with text form controls
+        https://bugs.webkit.org/show_bug.cgi?id=182401
+        <rdar://problem/35143035>
+
+        Reviewed by Tim Horton.
+
+        Add UI support for interacting with and editing text form controls when extra zoom mode is enabled. See below
+        for more details.
+
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration init]):
+        (-[WKWebViewConfiguration encodeWithCoder:]):
+        (-[WKWebViewConfiguration initWithCoder:]):
+        (-[WKWebViewConfiguration copyWithZone:]):
+        (-[WKWebViewConfiguration _textInteractionGesturesEnabled]):
+        (-[WKWebViewConfiguration _setTextInteractionGesturesEnabled:]):
+        (-[WKWebViewConfiguration _longPressActionsEnabled]):
+        (-[WKWebViewConfiguration _setLongPressActionsEnabled:]):
+
+        Introduce two new web view configuration flags: `textInteractionGesturesEnabled` and `longPressActionsEnabled`.
+        The former determines whether text interaction gestures (i.e. text selection, moving the caret, showing UI for
+        IME, etc.) are enabled. The latter determines whether or not long press actions (i.e. touch callout, share
+        sheet, etc.) are enabled. These are disabled by default only in extra zoom mode.
+
+        * UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::setTextAsync):
+
+        Add a way to set the text value of a currently edited text form control. This will either set the text value of
+        an input, a. la. autofill, or overwrite the contents of a contenteditable area by selecting everything and
+        inserting the given text.
+
+        * UIProcess/WebPageProxy.h:
+        (WebKit::WebPageProxy::focusNextAssistedNode):
+
+        Add a default argument for the completion callback.
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView setupInteraction]):
+        (-[WKContentView _displayFormNodeInputView]):
+        (-[WKContentView _actionForLongPressFromPositionInformation:]):
+        (-[WKContentView hasSelectablePositionAtPoint:]):
+        (-[WKContentView pointIsNearMarkedText:]):
+        (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):
+        (-[WKContentView insertionPointColor]):
+
+        Respect the web view configuration flags above by bailing early from text interaction and long press action
+        sheet methods.
+
+        (-[WKContentView _startAssistingKeyboard]):
+        (-[WKContentView _startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
+
+        Add a flag indicating whether we are in the process of changing focus from one node to another. We use this to
+        decide whether or not we want to present the text input view controller right away, or just reload the focused
+        form control overlay. When we stop "assisting" a node, we also keep the focused form control overlay up if we're
+        only changing focus to another form control.
+
+        (-[WKContentView _stopAssistingNode]):
+        (-[WKContentView presentFocusedFormControlViewController:]):
+        (-[WKContentView dismissFocusedFormControlViewController:]):
+        (-[WKContentView shouldPresentTextInputViewController:]):
+        (-[WKContentView presentTextInputViewController:]):
+        (-[WKContentView dismissTextInputViewController:]):
+
+        Introduce helpers for managing presentation of the focused form control overlay and text input view controller.
+        All -present and -dismiss helpers here are idempotent. These view controllers are presented from the content
+        view's view controller for fullscreen presentation.
+
+        (-[WKContentView textInputController:didCommitText:]):
+        (-[WKContentView textInputController:didRequestDismissalWithAction:]):
+        (-[WKContentView focusedFormControlControllerDidSubmit:]):
+        (-[WKContentView focusedFormControlControllerDidCancel:]):
+        (-[WKContentView focusedFormControlControllerDidBeginEditing:]):
+        (-[WKContentView highlightedRectForFocusedFormControlController:inCoordinateSpace:]):
+        (-[WKContentView actionNameForFocusedFormControlController:]):
+        (-[WKContentView focusedFormControlControllerDidRequestNextNode:]):
+        (-[WKContentView focusedFormControlControllerDidRequestPreviousNode:]):
+        (-[WKContentView hasNextNodeForFocusedFormControlController:]):
+        (-[WKContentView hasPreviousNodeForFocusedFormControlController:]):
+
+        Implement delegate methods for the focused form control and text input view controllers. This mainly involves
+        straightforward plumbing of pieces of AssistedNodeInformation on the content view.
+
+        (-[WKContentView pointIsInAssistedNode:]): Deleted.
+
+        Remove a method that was still implemented only for binary compatibility with iOS 10.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::setTextAsync):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2018-02-01  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [GTK] Shift + mouse scroll should scroll horizontally

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm (227983 => 227984)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm	2018-02-01 23:17:22 UTC (rev 227984)
@@ -130,6 +130,8 @@
     BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute;
     BOOL _allowsInlineMediaPlaybackAfterFullscreen;
     _WKDragLiftDelay _dragLiftDelay;
+    BOOL _textInteractionGesturesEnabled;
+    BOOL _longPressActionsEnabled;
 #endif
 
     BOOL _invisibleAutoplayNotPermitted;
@@ -225,7 +227,14 @@
 #if PLATFORM(IOS)
     _selectionGranularity = WKSelectionGranularityDynamic;
     _dragLiftDelay = toDragLiftDelay([[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitDebugDragLiftDelay"]);
+#if ENABLE(EXTRA_ZOOM_MODE)
+    _textInteractionGesturesEnabled = NO;
+    _longPressActionsEnabled = NO;
+#else
+    _textInteractionGesturesEnabled = YES;
+    _longPressActionsEnabled = YES;
 #endif
+#endif // PLATFORM(IOS)
 
     _mediaContentTypesRequiringHardwareSupport = Settings::defaultMediaContentTypesRequiringHardwareSupport();
     _allowMediaContentTypesRequiringHardwareSupportAsFallback = YES;
@@ -265,6 +274,8 @@
     [coder encodeBool:self.allowsPictureInPictureMediaPlayback forKey:@"allowsPictureInPictureMediaPlayback"];
     [coder encodeBool:self.ignoresViewportScaleLimits forKey:@"ignoresViewportScaleLimits"];
     [coder encodeInteger:self._dragLiftDelay forKey:@"dragLiftDelay"];
+    [coder encodeBool:self._textInteractionGesturesEnabled forKey:@"textInteractionGesturesEnabled"];
+    [coder encodeBool:self._longPressActionsEnabled forKey:@"longPressActionsEnabled"];
 #else
     [coder encodeInteger:self.userInterfaceDirectionPolicy forKey:@"userInterfaceDirectionPolicy"];
 #endif
@@ -293,6 +304,8 @@
     self.allowsPictureInPictureMediaPlayback = [coder decodeBoolForKey:@"allowsPictureInPictureMediaPlayback"];
     self.ignoresViewportScaleLimits = [coder decodeBoolForKey:@"ignoresViewportScaleLimits"];
     self._dragLiftDelay = toDragLiftDelay([coder decodeIntegerForKey:@"dragLiftDelay"]);
+    self._textInteractionGesturesEnabled = [coder decodeBoolForKey:@"textInteractionGesturesEnabled"];
+    self._longPressActionsEnabled = [coder decodeBoolForKey:@"longPressActionsEnabled"];
 #else
     auto userInterfaceDirectionPolicyCandidate = static_cast<WKUserInterfaceDirectionPolicy>([coder decodeIntegerForKey:@"userInterfaceDirectionPolicy"]);
     if (userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicyContent || userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicySystem)
@@ -347,6 +360,8 @@
     configuration->_selectionGranularity = self->_selectionGranularity;
     configuration->_ignoresViewportScaleLimits = self->_ignoresViewportScaleLimits;
     configuration->_dragLiftDelay = self->_dragLiftDelay;
+    configuration->_textInteractionGesturesEnabled = self->_textInteractionGesturesEnabled;
+    configuration->_longPressActionsEnabled = self->_longPressActionsEnabled;
 #endif
 #if PLATFORM(MAC)
     configuration->_cpuLimit = self->_cpuLimit;
@@ -664,6 +679,28 @@
 {
     _dragLiftDelay = dragLiftDelay;
 }
+
+- (BOOL)_textInteractionGesturesEnabled
+{
+    return _textInteractionGesturesEnabled;
+}
+
+- (void)_setTextInteractionGesturesEnabled:(BOOL)enabled
+{
+    _textInteractionGesturesEnabled = enabled;
+}
+
+- (BOOL)_longPressActionsEnabled
+{
+    return _longPressActionsEnabled;
+}
+
+- (void)_setLongPressActionsEnabled:(BOOL)enabled
+{
+    _longPressActionsEnabled = enabled;
+}
+
+
 #endif // PLATFORM(IOS)
 
 - (BOOL)_invisibleAutoplayNotPermitted

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h (227983 => 227984)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h	2018-02-01 23:17:22 UTC (rev 227984)
@@ -76,6 +76,8 @@
 @property (nonatomic, setter=_setInlineMediaPlaybackRequiresPlaysInlineAttribute:) BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute WK_API_AVAILABLE(ios(10.0));
 @property (nonatomic, setter=_setAllowsInlineMediaPlaybackAfterFullscreen:) BOOL _allowsInlineMediaPlaybackAfterFullscreen  WK_API_AVAILABLE(ios(10.0));
 @property (nonatomic, setter=_setDragLiftDelay:) _WKDragLiftDelay _dragLiftDelay WK_API_AVAILABLE(ios(11.0));
+@property (nonatomic, setter=_setTextInteractionGesturesEnabled:) BOOL _textInteractionGesturesEnabled WK_API_AVAILABLE(ios(WK_IOS_TBA));
+@property (nonatomic, setter=_setLongPressActionsEnabled:) BOOL _longPressActionsEnabled WK_API_AVAILABLE(ios(WK_IOS_TBA));
 #else
 @property (nonatomic, setter=_setShowsURLsInToolTips:) BOOL _showsURLsInToolTips WK_API_AVAILABLE(macosx(10.12));
 @property (nonatomic, setter=_setServiceControlsEnabled:) BOOL _serviceControlsEnabled WK_API_AVAILABLE(macosx(10.12));

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (227983 => 227984)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2018-02-01 23:17:22 UTC (rev 227984)
@@ -6560,6 +6560,12 @@
 
 #if PLATFORM(COCOA)
 
+void WebPageProxy::setTextAsync(const String& text)
+{
+    if (isValid())
+        process().send(Messages::WebPage::SetTextAsync(text), m_pageID);
+}
+
 void WebPageProxy::insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup, EditingRangeIsRelativeTo editingRangeIsRelativeTo, bool suppressSelectionUpdate)
 {
     if (!isValid())

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (227983 => 227984)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-02-01 23:17:22 UTC (rev 227984)
@@ -572,7 +572,7 @@
 #if __IPHONE_OS_VERSION_MAX_ALLOWED < 120000
     void didUpdateBlockSelectionWithTouch(uint32_t touch, uint32_t flags, float growThreshold, float shrinkThreshold);
 #endif
-    void focusNextAssistedNode(bool isForward, WTF::Function<void (CallbackBase::Error)>&&);
+    void focusNextAssistedNode(bool isForward, WTF::Function<void (CallbackBase::Error)>&& = [] (auto) { });
     void setAssistedNodeValue(const String&);
     void setAssistedNodeValueAsNumber(double);
     void setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection = false);
@@ -638,6 +638,7 @@
     void setAcceleratedCompositingRootLayer(LayerOrView*);
     LayerOrView* acceleratedCompositingRootLayer() const;
 
+    void setTextAsync(const String&);
     void insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup = false, EditingRangeIsRelativeTo = EditingRangeIsRelativeTo::EditableRoot, bool suppressSelectionUpdate = false);
     void getMarkedRangeAsync(WTF::Function<void (EditingRange, CallbackBase::Error)>&&);
     void getSelectedRangeAsync(WTF::Function<void (EditingRange, CallbackBase::Error)>&&);

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (227983 => 227984)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2018-02-01 23:17:22 UTC (rev 227984)
@@ -83,8 +83,9 @@
 @class _UIHighlightView;
 @class _UIWebHighlightLongPressGestureRecognizer;
 
-#if ENABLE(DATA_INTERACTION)
-@class _UITextDragCaretView;
+#if ENABLE(EXTRA_ZOOM_MODE)
+@class WKFocusedFormControlViewController;
+@class WKTextInputViewController;
 #endif
 
 typedef void (^UIWKAutocorrectionCompletionHandler)(UIWKAutocorrectionRects *rectsForInput);
@@ -229,6 +230,7 @@
     BOOL _becomingFirstResponder;
     BOOL _resigningFirstResponder;
     BOOL _needsDeferredEndScrollingSelectionUpdate;
+    BOOL _isChangingFocus;
 
 #if ENABLE(DATA_INTERACTION)
     WebKit::DragDropInteractionState _dragDropInteractionState;
@@ -239,6 +241,11 @@
     RetainPtr<UIView> _visibleContentViewSnapshot;
     RetainPtr<_UITextDragCaretView> _editDropCaretView;
 #endif
+
+#if ENABLE(EXTRA_ZOOM_MODE)
+    RetainPtr<WKTextInputViewController> _textInputViewController;
+    RetainPtr<WKFocusedFormControlViewController> _focusedFormControlViewController;
+#endif
 }
 
 @end

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (227983 => 227984)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-02-01 23:17:22 UTC (rev 227984)
@@ -41,6 +41,7 @@
 #import "UIKitSPI.h"
 #import "WKActionSheetAssistant.h"
 #import "WKError.h"
+#import "WKFocusedFormControlViewController.h"
 #import "WKFormInputControl.h"
 #import "WKFormSelectControl.h"
 #import "WKImagePreviewViewController.h"
@@ -49,6 +50,7 @@
 #import "WKPreviewActionItemIdentifiers.h"
 #import "WKPreviewActionItemInternal.h"
 #import "WKPreviewElementInfoInternal.h"
+#import "WKTextInputViewController.h"
 #import "WKUIDelegatePrivate.h"
 #import "WKWebViewConfiguration.h"
 #import "WKWebViewConfigurationPrivate.h"
@@ -70,6 +72,7 @@
 #import <WebCore/Color.h>
 #import <WebCore/DataDetection.h>
 #import <WebCore/FloatQuad.h>
+#import <WebCore/LocalizedStrings.h>
 #import <WebCore/NotImplemented.h>
 #import <WebCore/Pasteboard.h>
 #import <WebCore/Path.h>
@@ -116,6 +119,13 @@
 
 @end
 
+#if ENABLE(EXTRA_ZOOM_MODE)
+
+@interface WKContentView (ExtraZoomMode) <WKTextFormControlViewControllerDelegate, WKFocusedFormControlViewControllerDelegate>
+@end
+
+#endif
+
 using namespace WebCore;
 using namespace WebKit;
 
@@ -626,6 +636,7 @@
     _isDoubleTapPending = NO;
     _showDebugTapHighlightsForFastClicking = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitShowFastClickDebugTapHighlights"];
     _needsDeferredEndScrollingSelectionUpdate = NO;
+    _isChangingFocus = NO;
 }
 
 - (void)cleanupInteraction
@@ -1205,13 +1216,13 @@
     // In case user scaling is force enabled, do not use that scaling when zooming in with an input field.
     // Zooming above the page's default scale factor should only happen when the user performs it.
     [self _zoomToFocusRect:_assistedNodeInformation.elementRect
-             selectionRect:_didAccessoryTabInitiateFocus ? IntRect() : _assistedNodeInformation.selectionRect
-               insideFixed:_assistedNodeInformation.insideFixedPosition
-                  fontSize:_assistedNodeInformation.nodeFontSize
-              minimumScale:_assistedNodeInformation.minimumScaleFactor
-              maximumScale:_assistedNodeInformation.maximumScaleFactorIgnoringAlwaysScalable
-              allowScaling:(_assistedNodeInformation.allowsUserScalingIgnoringAlwaysScalable && !currentUserInterfaceIdiomIsPad())
-               forceScroll:[self requiresAccessoryView]];
+        selectionRect:_didAccessoryTabInitiateFocus ? IntRect() : _assistedNodeInformation.selectionRect
+        insideFixed:_assistedNodeInformation.insideFixedPosition
+        fontSize:_assistedNodeInformation.nodeFontSize
+        minimumScale:_assistedNodeInformation.minimumScaleFactor
+        maximumScale:_assistedNodeInformation.maximumScaleFactorIgnoringAlwaysScalable
+        allowScaling:_assistedNodeInformation.allowsUserScalingIgnoringAlwaysScalable && [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone
+        forceScroll:[self requiresAccessoryView]];
 
     _didAccessoryTabInitiateFocus = NO;
     [self _ensureFormAccessoryView];
@@ -1323,6 +1334,9 @@
 
 - (SEL)_actionForLongPressFromPositionInformation:(const InteractionInformationAtPosition&)positionInformation
 {
+    if (!_webView.configuration._longPressActionsEnabled)
+        return nil;
+
     if (!positionInformation.touchCalloutEnabled)
         return nil;
 
@@ -1549,6 +1563,9 @@
 
 - (BOOL)hasSelectablePositionAtPoint:(CGPoint)point
 {
+    if (!_webView.configuration._textInteractionGesturesEnabled)
+        return NO;
+
     if (_inspectorNodeSearchEnabled)
         return NO;
 
@@ -1569,21 +1586,20 @@
 
 - (BOOL)pointIsNearMarkedText:(CGPoint)point
 {
+    if (!_webView.configuration._textInteractionGesturesEnabled)
+        return NO;
+
     InteractionInformationRequest request(roundedIntPoint(point));
     if (![self ensurePositionInformationIsUpToDate:request])
         return NO;
     return _positionInformation.isNearMarkedText;
 }
-#if __IPHONE_OS_VERSION_MAX_ALLOWED < 110000
-- (BOOL)pointIsInAssistedNode:(CGPoint)point
-{
-    // This method is still implemented for backwards compatibility with older UIKit versions.
-    return [self textInteractionGesture:UIWKGestureLoupe shouldBeginAtPoint:point];
-}
-#endif
 
 - (BOOL)textInteractionGesture:(UIWKGestureType)gesture shouldBeginAtPoint:(CGPoint)point
 {
+    if (!_webView.configuration._textInteractionGesturesEnabled)
+        return NO;
+
     InteractionInformationRequest request(roundedIntPoint(point));
     if (![self ensurePositionInformationIsUpToDate:request])
         return NO;
@@ -2103,6 +2119,9 @@
 
 - (UIColor *)insertionPointColor
 {
+    if (!_webView.configuration._textInteractionGesturesEnabled)
+        return [UIColor clearColor];
+
     if (!_page->editorState().isMissingPostLayoutData) {
         WebCore::Color caretColor = _page->editorState().postLayoutData().caretColor;
         if (caretColor.isValid())
@@ -3903,7 +3922,13 @@
 - (void)_startAssistingKeyboard
 {
     [self useSelectionAssistantWithGranularity:WKSelectionGranularityCharacter];
+
+#if ENABLE(EXTRA_ZOOM_MODE)
+    if (!_isChangingFocus && [self shouldPresentTextInputViewController:_assistedNodeInformation])
+        [self presentTextInputViewController:YES];
+#else
     [self reloadInputViews];
+#endif
 }
 
 - (void)_stopAssistingKeyboard
@@ -3959,6 +3984,7 @@
 
 - (void)_startAssistingNode:(const AssistedNodeInformation&)information userIsInteracting:(BOOL)userIsInteracting blurPreviousNode:(BOOL)blurPreviousNode changingActivityState:(BOOL)changingActivityState userObject:(NSObject <NSSecureCoding> *)userObject
 {
+    SetForScope<BOOL> isChangingFocusForScope { _isChangingFocus, _assistedNodeInformation.elementType != InputType::None };
     _inputViewUpdateDeferrer = nullptr;
 
     id <_WKInputDelegate> inputDelegate = [_webView _inputDelegate];
@@ -3992,6 +4018,11 @@
     _assistedNodeInformation = information;
     _inputPeripheral = nil;
     _traits = nil;
+
+#if ENABLE(EXTRA_ZOOM_MODE)
+    [self presentFocusedFormControlViewController:NO];
+#endif
+
     if (![self isFirstResponder])
         [self becomeFirstResponder];
 
@@ -4015,6 +4046,11 @@
     
     [self _displayFormNodeInputView];
 
+#if ENABLE(EXTRA_ZOOM_MODE)
+    if (_isChangingFocus)
+        [_focusedFormControlViewController reloadData:YES];
+#endif
+
     // _inputPeripheral has been initialized in inputView called by reloadInputViews.
     [_inputPeripheral beginEditing];
 
@@ -4043,6 +4079,12 @@
     // The name is misleading, but this actually clears the selection views and removes any selection.
     [_webSelectionAssistant resignedFirstResponder];
 
+#if ENABLE(EXTRA_ZOOM_MODE)
+    [self dismissTextInputViewController:YES];
+    if (!_isChangingFocus)
+        [self dismissFocusedFormControlViewController:[_focusedFormControlViewController isVisible]];
+#endif
+
     // The custom fixed position rect behavior is affected by -isAssistingNode, so if that changes we need to recompute rects.
     if (editableChanged)
         [_webView _scheduleVisibleContentRectUpdate];
@@ -4050,6 +4092,140 @@
     [_webView didEndFormControlInteraction];
 }
 
+#if ENABLE(EXTRA_ZOOM_MODE)
+
+- (void)presentFocusedFormControlViewController:(BOOL)animated
+{
+    if (_focusedFormControlViewController)
+        return;
+
+    _focusedFormControlViewController = adoptNS([[WKFocusedFormControlViewController alloc] init]);
+    [_focusedFormControlViewController setDelegate:self];
+    [[UIViewController _viewControllerForFullScreenPresentationFromView:self] presentViewController:_focusedFormControlViewController.get() animated:animated completion:nil];
+}
+
+- (void)dismissFocusedFormControlViewController:(BOOL)animated
+{
+    if (!_focusedFormControlViewController)
+        return;
+
+    [_focusedFormControlViewController dismissViewControllerAnimated:animated completion:nil];
+    _focusedFormControlViewController = nil;
+}
+
+- (BOOL)shouldPresentTextInputViewController:(const AssistedNodeInformation&)info
+{
+    switch (info.elementType) {
+    case InputType::ContentEditable:
+    case InputType::Text:
+    case InputType::Password:
+    case InputType::TextArea:
+    case InputType::Search:
+    case InputType::Email:
+    case InputType::URL:
+        return true;
+    default:
+        return false;
+    }
+}
+
+- (void)presentTextInputViewController:(BOOL)animated
+{
+    if (_textInputViewController)
+        return;
+
+    _textInputViewController = adoptNS([[WKTextInputViewController alloc] initWithText:_assistedNodeInformation.value textSuggestions:@[ ]]);
+    [_textInputViewController setDelegate:self];
+    [_focusedFormControlViewController presentViewController:_textInputViewController.get() animated:animated completion:nil];
+}
+
+- (void)dismissTextInputViewController:(BOOL)animated
+{
+    if (!_textInputViewController)
+        return;
+
+    auto textInputViewController = WTFMove(_textInputViewController);
+    [textInputViewController dismissViewControllerAnimated:animated completion:nil];
+}
+
+- (void)textInputController:(WKTextFormControlViewController *)controller didCommitText:(NSString *)text
+{
+    // FIXME: Update cached AssistedNodeInformation state in the UI process.
+    _page->setTextAsync(text);
+}
+
+- (void)textInputController:(WKTextFormControlViewController *)controller didRequestDismissalWithAction:(WKFormControlAction)action
+{
+    if (action == WKFormControlActionCancel) {
+        _page->blurAssistedNode();
+        return;
+    }
+
+    if (_assistedNodeInformation.formAction.isEmpty() && !_assistedNodeInformation.hasNextNode && !_assistedNodeInformation.hasPreviousNode) {
+        // In this case, there's no point in collapsing down to the form control focus UI because there's nothing the user could potentially do
+        // besides dismiss the UI, so we just automatically dismiss the focused form control UI.
+        _page->blurAssistedNode();
+        return;
+    }
+
+    [_focusedFormControlViewController show:NO];
+    [self dismissTextInputViewController:YES];
+}
+
+- (void)focusedFormControlControllerDidSubmit:(WKFocusedFormControlViewController *)controller
+{
+    [self insertText:@"\n"];
+    _page->blurAssistedNode();
+}
+
+- (void)focusedFormControlControllerDidCancel:(WKFocusedFormControlViewController *)controller
+{
+    _page->blurAssistedNode();
+}
+
+- (void)focusedFormControlControllerDidBeginEditing:(WKFocusedFormControlViewController *)controller
+{
+    if ([self shouldPresentTextInputViewController:_assistedNodeInformation])
+        [self presentTextInputViewController:YES];
+}
+
+- (CGRect)highlightedRectForFocusedFormControlController:(WKFocusedFormControlViewController *)controller inCoordinateSpace:(id <UICoordinateSpace>)coordinateSpace
+{
+    return [self convertRect:_assistedNodeInformation.elementRect toCoordinateSpace:coordinateSpace];
+}
+
+- (NSString *)actionNameForFocusedFormControlController:(WKFocusedFormControlViewController *)controller
+{
+    if (_assistedNodeInformation.formAction.isEmpty())
+        return nil;
+
+    return _assistedNodeInformation.elementType == InputType::Search ? formControlSearchButtonTitle() : formControlGoButtonTitle();
+}
+
+- (void)focusedFormControlControllerDidRequestNextNode:(WKFocusedFormControlViewController *)controller
+{
+    if (_assistedNodeInformation.hasNextNode)
+        _page->focusNextAssistedNode(true);
+}
+
+- (void)focusedFormControlControllerDidRequestPreviousNode:(WKFocusedFormControlViewController *)controller
+{
+    if (_assistedNodeInformation.hasPreviousNode)
+        _page->focusNextAssistedNode(false);
+}
+
+- (BOOL)hasNextNodeForFocusedFormControlController:(WKFocusedFormControlViewController *)controller
+{
+    return _assistedNodeInformation.hasNextNode;
+}
+
+- (BOOL)hasPreviousNodeForFocusedFormControlController:(WKFocusedFormControlViewController *)controller
+{
+    return _assistedNodeInformation.hasPreviousNode;
+}
+
+#endif // ENABLE(EXTRA_ZOOM_MODE)
+
 - (void)_selectionChanged
 {
     _selectionNeedsUpdate = YES;

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (227983 => 227984)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2018-02-01 23:17:22 UTC (rev 227984)
@@ -4590,6 +4590,21 @@
 
 #if PLATFORM(COCOA)
 
+void WebPage::setTextAsync(const String& text)
+{
+    if (is<HTMLInputElement>(m_assistedNode.get())) {
+        downcast<HTMLInputElement>(*m_assistedNode).setValueForUser(text);
+        return;
+    }
+
+    auto frame = makeRef(m_page->focusController().focusedOrMainFrame());
+    if (!frame->selection().selection().isContentEditable())
+        return;
+
+    frame->selection().selectAll();
+    frame->editor().insertText(text, nullptr, TextEventInputKeyboard);
+}
+
 void WebPage::insertTextAsync(const String& text, const EditingRange& replacementEditingRange, bool registerUndoGroup, uint32_t editingRangeIsRelativeTo, bool suppressSelectionUpdate)
 {
     Frame& frame = m_page->focusController().focusedOrMainFrame();

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (227983 => 227984)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2018-02-01 23:17:22 UTC (rev 227984)
@@ -708,6 +708,7 @@
     
     void sendComplexTextInputToPlugin(uint64_t pluginComplexTextInputIdentifier, const String& textInput);
 
+    void setTextAsync(const String&);
     void insertTextAsync(const String& text, const EditingRange& replacementRange, bool registerUndoGroup = false, uint32_t editingRangeIsRelativeTo = (uint32_t)EditingRangeIsRelativeTo::EditableRoot, bool suppressSelectionUpdate = false);
     void getMarkedRangeAsync(CallbackID);
     void getSelectedRangeAsync(CallbackID);

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (227983 => 227984)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-02-01 23:11:13 UTC (rev 227983)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2018-02-01 23:17:22 UTC (rev 227984)
@@ -390,6 +390,7 @@
     ShouldDelayWindowOrderingEvent(WebKit::WebMouseEvent event) -> (bool result)
     AcceptsFirstMouse(int eventNumber, WebKit::WebMouseEvent event) -> (bool result)
 
+    SetTextAsync(String text)
     InsertTextAsync(String text, struct WebKit::EditingRange replacementRange, bool registerUndoGroup, uint32_t editingRangeIsRelativeTo, bool suppressSelectionUpdate)
     GetMarkedRangeAsync(WebKit::CallbackID callbackID)
     GetSelectedRangeAsync(WebKit::CallbackID callbackID)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to