-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adopt UIAsyncTextInteraction behind the "Async UIKit Interactions" se…
…tting https://bugs.webkit.org/show_bug.cgi?id=264020 Reviewed by Megan Gardner. Replace the existing `_textInteractionAssistant` in `WKContentView` with a `_textInteractionWrapper` object instead, which wraps either a `UIWKTextInteractionAssistant` (in the case where the "Async UIKit Interactions" feature flag is off), or a `UIAsyncTextInteraction` (in the case where the feature flag is on). For the legacy codepath, all methods on this new wrapper object correspond directly to the existing methods already on `UIWKTextInteractionAssistant`, so there's no change in behavior; however, in the case where we're using the new `UIAsyncTextInteraction`, only a subset of the methods have been implemented so far, so we only plumb calls into `WKTextInteractionWrapper` through in those cases. As we continue iterating on the modern async text interaction, we'll implement the remainder of these methods which are currently no-ops when using `UIAsyncTextInteraction`. * Source/WebKit/Platform/spi/ios/UIKitSPI.h: * Source/WebKit/SourcesCocoa.txt: * Source/WebKit/UIProcess/ios/WKContentView.mm: (-[WKContentView _didExitStableState]): * Source/WebKit/UIProcess/ios/WKContentViewInteraction.h: * Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm: (-[WKContentView shouldUseAsyncInteractions]): (-[WKContentView _shouldUseUIContextMenuAsyncConfiguration]): (-[WKContentView _shouldUseTextCursorDragAnimator]): (-[WKContentView _updateRuntimeProtocolConformanceIfNeeded]): Additionally declare conformance to `UIAsyncTextInputClient`, which extends from `UIAsyncTextInput` and provides some additional functionality around text input via dictation (and more areas in the near future). (-[WKContentView cleanUpInteraction]): (-[WKContentView becomeFirstResponderForWebView]): (-[WKContentView endEditingAndUpdateFocusAppearanceWithReason:]): (-[WKContentView _scrollingNodeScrollingWillBegin:]): (-[WKContentView _scrollingNodeScrollingDidEnd:]): (-[WKContentView setUpTextSelectionAssistant]): Initialize a `WKTextInteractionWrapper` instead of a `UIWKTextInteractionAssistant`; this object internally wraps either a legacy `UIWKTextInteractionAssistant`, or a new `UIAsyncTextInteraction`. (-[WKContentView _willStartScrollingOrZooming]): (-[WKContentView _didEndScrollingOrZooming]): (-[WKContentView _lookupForWebView:]): (-[WKContentView _shareForWebView:]): (-[WKContentView _translateForWebView:]): (-[WKContentView _addShortcutForWebView:]): (-[WKContentView _promptForReplaceForWebView:]): (-[WKContentView _transliterateChineseForWebView:]): (-[WKContentView tintColorDidChange]): (-[WKContentView selectForWebView:]): (-[WKContentView selectAllForWebView:]): (-[WKContentView _showDictionary:]): (selectionChangedWithGesture): (selectionChangedWithTouch): (-[WKContentView changeSelectionWithGestureAt:withGesture:withState:withFlags:]): (-[WKContentView changeSelectionWithTouchAt:withSelectionTouch:baseIsStart:withFlags:]): (-[WKContentView changeSelectionWithTouchesFrom:to:withGesture:withState:]): (-[WKContentView interactionAssistant]): (-[WKContentView _showKeyboard]): (-[WKContentView _hideKeyboard]): (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]): (-[WKContentView _updateChangedSelection:]): (-[WKContentView prepareSelectionForContextMenuWithLocationInView:completionHandler:]): (-[WKContentView _startSuppressingSelectionAssistantForReason:]): (-[WKContentView _stopSuppressingSelectionAssistantForReason:]): (-[WKContentView _dragInteractionClass]): (-[WKContentView _restoreEditMenuIfNeeded]): (-[WKContentView dragInteraction:willAnimateLiftWithAnimator:session:]): (-[WKContentView textInteractionAssistant]): (-[WKContentView contextMenuInteraction]): (-[WKContentView _registerPreview]): Mechanically replace `_textInteractionAssistant` with `_textInteractionWrapper` in the content view. * Source/WebKit/UIProcess/ios/WKTextInteractionWrapper.h: Added. * Source/WebKit/UIProcess/ios/WKTextInteractionWrapper.mm: Added. (SOFT_LINK_CLASS_OPTIONAL): (-[WKTextInteractionWrapper initWithView:]): (-[WKTextInteractionWrapper textInteractionAssistant]): (-[WKTextInteractionWrapper activateSelection]): (-[WKTextInteractionWrapper deactivateSelection]): (-[WKTextInteractionWrapper didEndScrollingOverflow]): (-[WKTextInteractionWrapper selectionChanged]): (-[WKTextInteractionWrapper setGestureRecognizers]): (-[WKTextInteractionWrapper willStartScrollingOverflow]): (-[WKTextInteractionWrapper selectionChangedWithGestureAt:withGesture:withState:withFlags:]): (-[WKTextInteractionWrapper showDictionaryFor:fromRect:]): (-[WKTextInteractionWrapper selectionChangedWithTouchAt:withSelectionTouch:withFlags:]): (-[WKTextInteractionWrapper lookup:withRange:fromRect:]): (-[WKTextInteractionWrapper showShareSheetFor:fromRect:]): (-[WKTextInteractionWrapper showTextServiceFor:fromRect:]): (-[WKTextInteractionWrapper scheduleReplacementsForText:]): (-[WKTextInteractionWrapper scheduleChineseTransliterationForText:]): (-[WKTextInteractionWrapper willStartScrollingOrZooming]): (-[WKTextInteractionWrapper didEndScrollingOrZooming]): (-[WKTextInteractionWrapper selectWord]): (-[WKTextInteractionWrapper selectAll:]): (-[WKTextInteractionWrapper contextMenuInteraction]): (-[WKTextInteractionWrapper setExternalContextMenuInteractionDelegate:]): (-[WKTextInteractionWrapper translate:fromRect:]): Plumb from the text interaction wrapper to the inner interaction assistant; we also call into the `_textInteractionWrapper` in only the methods that currently have parity with `UIWKTextInteractionAssistant`. * Source/WebKit/WebKit.xcodeproj/project.pbxproj: Canonical link: https://commits.webkit.org/270136@main
- Loading branch information
Showing
8 changed files
with
367 additions
and
75 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
152 changes: 79 additions & 73 deletions
152
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright (C) 2023 Apple Inc. All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | ||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
* THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#if PLATFORM(IOS_FAMILY) | ||
|
||
#import "UIKitSPI.h" | ||
|
||
@class WKContentView; | ||
|
||
@interface WKTextInteractionWrapper : NSObject | ||
|
||
- (instancetype)initWithView:(WKContentView *)contentView; | ||
|
||
- (void)activateSelection; | ||
- (void)deactivateSelection; | ||
- (void)didEndScrollingOverflow; | ||
- (void)selectionChanged; | ||
- (void)setGestureRecognizers; | ||
- (void)willStartScrollingOverflow; | ||
- (void)selectionChangedWithGestureAt:(CGPoint)point withGesture:(UIWKGestureType)gestureType withState:(UIGestureRecognizerState)gestureState withFlags:(UIWKSelectionFlags)flags; | ||
- (void)showDictionaryFor:(NSString *)selectedTerm fromRect:(CGRect)presentationRect; | ||
- (void)selectionChangedWithTouchAt:(CGPoint)point withSelectionTouch:(UIWKSelectionTouch)touch withFlags:(UIWKSelectionFlags)flags; | ||
- (void)lookup:(NSString *)textWithContext withRange:(NSRange)range fromRect:(CGRect)presentationRect; | ||
- (void)showShareSheetFor:(NSString *)selectedTerm fromRect:(CGRect)presentationRect; | ||
- (void)showTextServiceFor:(NSString *)selectedTerm fromRect:(CGRect)presentationRect; | ||
- (void)scheduleReplacementsForText:(NSString *)text; | ||
- (void)scheduleChineseTransliterationForText:(NSString *)text; | ||
- (void)willStartScrollingOrZooming; | ||
- (void)didEndScrollingOrZooming; | ||
- (void)selectWord; | ||
- (void)selectAll:(id)sender; | ||
- (void)translate:(NSString *)text fromRect:(CGRect)presentationRect; | ||
|
||
#if USE(UICONTEXTMENU) | ||
- (void)setExternalContextMenuInteractionDelegate:(id<UIContextMenuInteractionDelegate>)delegate; | ||
@property (nonatomic, strong, readonly) UIContextMenuInteraction *contextMenuInteraction; | ||
#endif | ||
|
||
@property (nonatomic, readonly) UIWKTextInteractionAssistant *textInteractionAssistant; | ||
|
||
@end | ||
|
||
#endif // PLATFORM(IOS_FAMILY) |
205 changes: 205 additions & 0 deletions
205
Source/WebKit/UIProcess/ios/WKTextInteractionWrapper.mm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
/* | ||
* Copyright (C) 2023 Apple Inc. All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS | ||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
* THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
|
||
#import "config.h" | ||
#import "WKTextInteractionWrapper.h" | ||
|
||
#if PLATFORM(IOS_FAMILY) | ||
|
||
#import "WKContentViewInteraction.h" | ||
#import <wtf/SoftLinking.h> | ||
|
||
SOFT_LINK_FRAMEWORK(UIKit) // NOLINT | ||
SOFT_LINK_CLASS_OPTIONAL(UIKit, UIAsyncTextInteraction) | ||
|
||
@implementation WKTextInteractionWrapper { | ||
RetainPtr<UIWKTextInteractionAssistant> _textInteractionAssistant; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
RetainPtr<UIAsyncTextInteraction> _asyncTextInteraction; | ||
#endif | ||
} | ||
|
||
- (instancetype)initWithView:(WKContentView *)view | ||
{ | ||
if (!(self = [super init])) | ||
return nil; | ||
|
||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
static bool hasAsyncTextInteraction = !!getUIAsyncTextInteractionClass(); | ||
if (hasAsyncTextInteraction && view.shouldUseAsyncInteractions) { | ||
_asyncTextInteraction = adoptNS([allocUIAsyncTextInteractionInstance() init]); | ||
[view addInteraction:_asyncTextInteraction.get()]; | ||
} else | ||
#endif | ||
_textInteractionAssistant = adoptNS([[UIWKTextInteractionAssistant alloc] initWithView:view]); | ||
|
||
return self; | ||
} | ||
|
||
- (UIWKTextInteractionAssistant *)textInteractionAssistant | ||
{ | ||
return _textInteractionAssistant.get(); | ||
} | ||
|
||
- (void)activateSelection | ||
{ | ||
[_textInteractionAssistant activateSelection]; | ||
} | ||
|
||
- (void)deactivateSelection | ||
{ | ||
[_textInteractionAssistant deactivateSelection]; | ||
} | ||
|
||
- (void)selectionChanged | ||
{ | ||
[_textInteractionAssistant selectionChanged]; | ||
} | ||
|
||
- (void)setGestureRecognizers | ||
{ | ||
[_textInteractionAssistant setGestureRecognizers]; | ||
} | ||
|
||
- (void)willStartScrollingOverflow | ||
{ | ||
[_textInteractionAssistant willStartScrollingOverflow]; | ||
} | ||
|
||
- (void)didEndScrollingOverflow | ||
{ | ||
[_textInteractionAssistant didEndScrollingOverflow]; | ||
} | ||
|
||
- (void)willStartScrollingOrZooming | ||
{ | ||
[_textInteractionAssistant willStartScrollingOrZooming]; | ||
} | ||
|
||
- (void)didEndScrollingOrZooming | ||
{ | ||
[_textInteractionAssistant didEndScrollingOrZooming]; | ||
} | ||
|
||
- (void)selectionChangedWithGestureAt:(CGPoint)point withGesture:(UIWKGestureType)gestureType withState:(UIGestureRecognizerState)gestureState withFlags:(UIWKSelectionFlags)flags | ||
{ | ||
[_textInteractionAssistant selectionChangedWithGestureAt:point withGesture:gestureType withState:gestureState withFlags:flags]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction selectionChangedWithGestureAt:point withGesture:gestureType withState:gestureState withFlags:flags]; | ||
#endif | ||
} | ||
|
||
- (void)showDictionaryFor:(NSString *)selectedTerm fromRect:(CGRect)presentationRect | ||
{ | ||
[_textInteractionAssistant showDictionaryFor:selectedTerm fromRect:presentationRect]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction showDictionaryFor:selectedTerm fromRect:presentationRect]; | ||
#endif | ||
} | ||
|
||
- (void)selectionChangedWithTouchAt:(CGPoint)point withSelectionTouch:(UIWKSelectionTouch)touch withFlags:(UIWKSelectionFlags)flags | ||
{ | ||
[_textInteractionAssistant selectionChangedWithTouchAt:point withSelectionTouch:touch withFlags:flags]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction selectionChangedWithTouchAt:point withSelectionTouch:touch withFlags:flags]; | ||
#endif | ||
} | ||
|
||
- (void)lookup:(NSString *)textWithContext withRange:(NSRange)range fromRect:(CGRect)presentationRect | ||
{ | ||
[_textInteractionAssistant lookup:textWithContext withRange:range fromRect:presentationRect]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction lookup:textWithContext withRange:range fromRect:presentationRect]; | ||
#endif | ||
} | ||
|
||
- (void)showShareSheetFor:(NSString *)selectedTerm fromRect:(CGRect)presentationRect | ||
{ | ||
[_textInteractionAssistant showShareSheetFor:selectedTerm fromRect:presentationRect]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction showShareSheetFor:selectedTerm fromRect:presentationRect]; | ||
#endif | ||
} | ||
|
||
- (void)showTextServiceFor:(NSString *)selectedTerm fromRect:(CGRect)presentationRect | ||
{ | ||
[_textInteractionAssistant showTextServiceFor:selectedTerm fromRect:presentationRect]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction showTextServiceFor:selectedTerm fromRect:presentationRect]; | ||
#endif | ||
} | ||
|
||
- (void)scheduleReplacementsForText:(NSString *)text | ||
{ | ||
[_textInteractionAssistant scheduleReplacementsForText:text]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction scheduleReplacementsForText:text]; | ||
#endif | ||
} | ||
|
||
- (void)scheduleChineseTransliterationForText:(NSString *)text | ||
{ | ||
[_textInteractionAssistant scheduleChineseTransliterationForText:text]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction scheduleChineseTransliterationForText:text]; | ||
#endif | ||
} | ||
|
||
- (void)translate:(NSString *)text fromRect:(CGRect)presentationRect | ||
{ | ||
[_textInteractionAssistant translate:text fromRect:presentationRect]; | ||
#if HAVE(UI_ASYNC_TEXT_INTERACTION) | ||
[_asyncTextInteraction translate:text fromRect:presentationRect]; | ||
#endif | ||
} | ||
|
||
- (void)selectWord | ||
{ | ||
[_textInteractionAssistant selectWord]; | ||
} | ||
|
||
- (void)selectAll:(id)sender | ||
{ | ||
[_textInteractionAssistant selectAll:sender]; | ||
} | ||
|
||
#if USE(UICONTEXTMENU) | ||
|
||
- (UIContextMenuInteraction *)contextMenuInteraction | ||
{ | ||
return [_textInteractionAssistant contextMenuInteraction]; | ||
} | ||
|
||
- (void)setExternalContextMenuInteractionDelegate:(id<UIContextMenuInteractionDelegate>)delegate | ||
{ | ||
[_textInteractionAssistant setExternalContextMenuInteractionDelegate:delegate]; | ||
} | ||
|
||
#endif // USE(UICONTEXTMENU) | ||
|
||
@end | ||
|
||
#endif // PLATFORM(IOS_FAMILY) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters