Skip to content

Commit

Permalink
[iOS] Update WKSETextInput/WKSETextInteraction adoption
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=267555
rdar://121011826

Reviewed by Tim Horton.

Since 272018@main landed, there have been numerous minor adjustments to the async text input API in
ServiceExtensions; now that the API shape is finally stable, we adjust the WebKit preadoption to use
these new method and symbol names when `SERVICE_EXTENSIONS_TEXT_INPUT_IS_AVAILABLE` is set, while
ensuring binary compatibility with the old UIKit async text input symbols.

See below for more details.

* Source/WebCore/platform/ios/WebEvent.mm:
(webEventType):
(isChangingKeyModifiers):
(-[WebEvent initWithKeyEntry:]):
(-[WebEvent originalKeyEntry]):
(-[WebEvent initWithKeyEvent:]): Deleted.
(-[WebEvent originalKeyEvent]): Deleted.

Rename `WebSEKeyEvent` to `WebSEKeyEntry`, and `WebSEKeyEventType` to `WebSEKeyPressState`.

* Source/WebCore/platform/ios/WebEventPrivate.h:
* Source/WebCore/platform/ios/WebSEDefinitions.h:
* Source/WebKit/Platform/spi/ios/UIKitSPI.h:

Remove `HAVE_UI_ASYNC_TEXT_INTERACTION_DELEGATE`, since it's been in SDKs where
`HAVE_UI_ASYNC_TEXT_INTERACTION` is set for months now.

* Source/WebKit/Shared/DocumentEditingContext.mm:

Import the relevant system headers.

* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:

Rename numerous text input delegate method implementations, to fit the new API shape.

(-[WKContentView textInteractionGesture:shouldBeginAtPoint:]):

Also address the fact that calls to `-hasSelectablePositionAtPoint:` have been replaced with calls
to `-textInteractionGesture:shouldBeginAtPoint:` with `WKSEGestureTypeForceTouch`, since the former
was only used in a few places for the purposes of handling force touch.

(-[WKContentView replaceForWebView:]):
(-[WKContentView selectionBarColor]):

Replace `-selectionBarColor` with `-selectionHandleColor`.

(-[WKContentView canPerformAction:withSender:]):

Replace `-moveInDirection:byGranularity:` with `-moveInStorageDirection:byGranularity:`.

(toGestureType):
(toWKSEGestureType):
(toSelectionTouch):
(toWKSESelectionTouchPhase):
(selectionChangedWithTouch):
(-[WKContentView changeSelectionWithTouchAt:withSelectionTouch:baseIsStart:withFlags:]):
(logTextInteraction):
(-[WKContentView _internalBeginSelectionChange]):
(-[WKContentView _internalEndSelectionChange]):
(-[WKContentView addTextAlternatives:]):
(-[WKContentView _updateTextInputTraits:]):
(shiftKeyState):
(-[WKContentView modifierFlagsDidChangeFrom:to:]):
(-[WKContentView _deferKeyEventToInputMethodEditing:]):
(-[WKContentView _interpretKeyEvent:isCharEvent:]):
(-[WKContentView _transpose]):
(-[WKContentView _updateInputContextAfterBlurringAndRefocusingElement]):
(-[WKContentView _selectionChanged]):
(-[WKContentView _provideSuggestionsToInputDelegate:]):
(-[WKContentView _provideUITextSuggestionsToInputDelegate:]):
(toWebDocumentRequestOptions):
(toWebRequest):
(-[WKContentView requestDocumentContext:completionHandler:]):
(-[WKContentView asWKSETextInput]):

The following method implementations represent the set of final API names, which wrap calls to
`UIAsyncTextInput` methods.

(-[WKContentView systemWillPresentEditMenuWithAnimator:]):
(-[WKContentView systemWillDismissEditMenuWithAnimator:]):
(-[WKContentView insertTextAlternatives:]):
(-[WKContentView insertText:textAlternatives:style:]):

Note: `-insertText:textAlternatives:style:` was renamed to `-insertTextAlternatives:` here, but we
implement both versions of this new delegate method for now to ensure binary compatibility with
both versions of ServiceExtensions.

(-[WKContentView isPointNearMarkedText:]):
(-[WKContentView replaceSelectedText:withText:]):
(-[WKContentView updateCurrentSelectionTo:fromGesture:inState:]):
(-[WKContentView setSelectionFromPoint:toPoint:gesture:state:]):
(-[WKContentView adjustSelectionBoundaryToPoint:touchPhase:baseIsStart:flags:]):
(-[WKContentView moveSelectionAtBoundary:inStorageDirection:completionHandler:]):
(-[WKContentView extendedTextInputTraits]):
(-[WKContentView selectTextForEditMenuWithLocationInView:completionHandler:]):
(-[WKContentView isSelectionAtDocumentStart]):
(-[WKContentView automaticallyPresentEditMenu]):
(-[WKContentView asyncSystemInputDelegate]):
(-[WKContentView setAsyncInputDelegate:setAsyncSystemInputDelegate:]):
(-[WKContentView handleKeyEntry:withCompletionHandler:handleAsyncKeyEvent:withCompletionHandler:]):
(-[WKContentView replaceText:withText:options:completionHandler:replaceText:withText:options:withCompletionHandler:]):
(-[WKContentView moveInStorageDirection:byGranularity:moveInDirection:byGranularity:]):
(-[WKContentView extendInStorageDirection:byGranularity:extendInDirection:byGranularity:]):
(-[WKContentView adjustSelectionByRange:completionHandler:adjustSelection:completionHandler:]):
(-[WKContentView transposeCharacters]):
(-[WKContentView shiftKeyStateChangedFromState:toState:shiftKeyStateChangedFrom:to:]):
(-[WKContentView systemWillChangeSelectionForInteraction:selectionWillChange:]):
(-[WKContentView systemDidChangeSelectionForInteraction:selectionDidChange:]):
(-[WKContentView _showDictionary:]): Deleted.

Remove this altogether, since it's now just dead code with recent versions of UIKit.

(toWKSESelectionTouch): Deleted.
(-[WKContentView setAsyncSystemInputDelegate:]): Deleted.
(-[WKContentView handleAsyncKeyEvent:withCompletionHandler:]): Deleted.
(-[WKContentView replaceText:withText:options:withCompletionHandler:]): Deleted.
(-[WKContentView moveInDirection:byGranularity:]): Deleted.
(-[WKContentView extendInDirection:byGranularity:]): Deleted.
(-[WKContentView adjustSelection:completionHandler:]): Deleted.
(-[WKContentView shiftKeyStateChangedFrom:to:]): Deleted.
(-[WKContentView selectionWillChange:]): Deleted.
(-[WKContentView selectionDidChange:]): Deleted.
* Source/WebKit/UIProcess/ios/WKExtendedTextInputTraits.h:
* Source/WebKit/UIProcess/ios/WKExtendedTextInputTraits.mm:
(-[WKExtendedTextInputTraits setSelectionHandleColor:]):
(-[WKExtendedTextInputTraits selectionHandleColor]):
(-[WKExtendedTextInputTraits setSelectionBarColor:]):
(-[WKExtendedTextInputTraits selectionBarColor]):
(-[WKExtendedTextInputTraits setSelectionColorsToMatchTintColor:]):
* Source/WebKit/UIProcess/ios/WKSEDefinitions.h:
* Source/WebKit/UIProcess/ios/WKTextInteractionWrapper.h:
* Source/WebKit/UIProcess/ios/WKTextInteractionWrapper.mm:
(-[WKTextInteractionWrapper initWithView:]):
(-[WKTextInteractionWrapper selectionChanged]):
(-[WKTextInteractionWrapper selectionChangedWithGestureAt:withGesture:withState:withFlags:]):
(-[WKTextInteractionWrapper selectionChangedWithTouchAt:withSelectionTouch:withFlags:]):
(-[WKTextInteractionWrapper lookup:withRange:fromRect:]):
(-[WKTextInteractionWrapper showShareSheetFor:fromRect:]):
(-[WKTextInteractionWrapper showTextServiceFor:fromRect:]):
(-[WKTextInteractionWrapper scheduleReplacementsForText:]):
(-[WKTextInteractionWrapper scheduleChineseTransliterationForText:]):
(-[WKTextInteractionWrapper translate:fromRect:]):
(-[WKTextInteractionWrapper showDictionaryFor:fromRect:]): Deleted.
* Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm:
* Tools/TestWebKitAPI/Tests/ios/AutocorrectionTestsIOS.mm:
(TEST):
* Tools/TestWebKitAPI/cocoa/TestWKWebView.mm:
(-[WKWebView moveSelectionToStartOfParagraph]):
(-[WKWebView extendSelectionToStartOfParagraph]):
(-[WKWebView moveSelectionToEndOfParagraph]):
(-[WKWebView extendSelectionToEndOfParagraph]):
(-[WKWebView extendedTextInputTraits]):
(-[WKWebView autocorrectionContext]):
(-[WKWebView replaceText:withText:shouldUnderline:completion:]):
(wrap):
(unwrap):

Update `TestWKWebView` API testing helpers to use the new API shape when
`SERVICE_EXTENSIONS_TEXT_INPUT_IS_AVAILABLE` is set.

(-[WKWebView synchronouslyAdjustSelectionWithDelta:]):
(-[WKWebView selectTextForContextMenuWithLocationInView:completion:]):
(-[WKWebView handleKeyEvent:completion:]):
* Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::applyAutocorrection):

Canonical link: https://commits.webkit.org/273093@main
  • Loading branch information
whsieh committed Jan 16, 2024
1 parent cef6ec4 commit 27dbd34
Show file tree
Hide file tree
Showing 18 changed files with 583 additions and 222 deletions.
4 changes: 0 additions & 4 deletions Source/WTF/wtf/PlatformHave.h
Original file line number Diff line number Diff line change
Expand Up @@ -1677,10 +1677,6 @@
#define HAVE_UI_ASYNC_TEXT_INTERACTION 1
#endif

#if __has_include(<UIKit/UIAsyncTextInteractionDelegate.h>)
#define HAVE_UI_ASYNC_TEXT_INTERACTION_DELEGATE 1
#endif

#if CPU(ARM64)
#define HAVE_FP16_HALF_SUPPORT 1
#endif
44 changes: 29 additions & 15 deletions Source/WebCore/platform/ios/WebEvent.mm
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,16 @@
#import <pal/spi/ios/GraphicsServicesSPI.h>
#import <pal/spi/ios/UIKitSPI.h>

#if USE(APPLE_INTERNAL_SDK)
#import <WebKitAdditions/ServiceExtensionsAdditions.h>
#endif

using WebCore::windowsKeyCodeForKeyCode;
using WebCore::windowsKeyCodeForCharCode;

@implementation WebEvent {
#if HAVE(UI_ASYNC_TEXT_INTERACTION)
RetainPtr<WebSEKeyEvent> _originalKeyEvent;
RetainPtr<WebSEKeyEntry> _originalKeyEntry;
#endif
}

Expand Down Expand Up @@ -496,14 +500,14 @@ + (WebEventFlags)modifierFlags

#if HAVE(UI_ASYNC_TEXT_INTERACTION)

@implementation WebEvent (WebSEKeyEventSupport)
@implementation WebEvent (WebSEKeyEntrySupport)

static inline WebEventType webEventType(WebSEKeyEventType type)
static inline WebEventType webEventType(WebSEKeyPressState type)
{
switch (type) {
case WebSEKeyEventKeyDown:
case WebSEKeyPressStateKeyDown:
return WebEventKeyDown;
case WebSEKeyEventKeyUp:
case WebSEKeyPressStateKeyUp:
return WebEventKeyUp;
}
ASSERT_NOT_REACHED();
Expand All @@ -526,9 +530,14 @@ static inline WebEventFlags webEventModifierFlags(UIKeyModifierFlags flags)
return modifiers;
}

static inline bool isChangingKeyModifiers(WebSEKeyEvent *event)
static inline bool isChangingKeyModifiers(WebSEKeyEntry *event)
{
switch (event.keyCode) {
#if SERVICE_EXTENSIONS_KEY_ENTRY_IS_AVAILABLE
auto keyCode = event.key.keyCode;
#else
auto keyCode = event.keyCode;
#endif
switch (keyCode) {
case VK_LWIN:
case VK_APPS:
case VK_CAPITAL:
Expand All @@ -544,33 +553,38 @@ static inline bool isChangingKeyModifiers(WebSEKeyEvent *event)
}
}

- (instancetype)initWithKeyEvent:(WebSEKeyEvent *)event
- (instancetype)initWithKeyEntry:(WebSEKeyEntry *)event
{
if (!(self = [super init]))
return nil;

_type = webEventType(event.type);
_timestamp = static_cast<CFTimeInterval>(event.timestamp);
_modifierFlags = webEventModifierFlags(event.modifierFlags);
_keyboardFlags = 0;
if (isChangingKeyModifiers(event))
_keyboardFlags |= WebEventKeyboardInputModifierFlagsChanged;
if (event.keyRepeating)
_keyboardFlags |= WebEventKeyboardInputRepeat;

_keyCode = static_cast<uint16_t>(event.keyCode);
_characters = [event.characters retain];
_charactersIgnoringModifiers = [event.charactersIgnoringModifiers retain];
#if SERVICE_EXTENSIONS_KEY_ENTRY_IS_AVAILABLE
auto keyInfo = event.key;
#else
auto keyInfo = event;
#endif
_modifierFlags = webEventModifierFlags(keyInfo.modifierFlags);
_keyCode = static_cast<uint16_t>(keyInfo.keyCode);
_characters = [keyInfo.characters retain];
_charactersIgnoringModifiers = [keyInfo.charactersIgnoringModifiers retain];
_tabKey = NO; // FIXME: Populate this field appropriately.
_keyRepeating = event.keyRepeating;
_originalKeyEvent = event;
_originalKeyEntry = event;

return self;
}

- (WebSEKeyEvent *)originalKeyEvent
- (WebSEKeyEntry *)originalKeyEntry
{
return _originalKeyEvent.get();
return _originalKeyEntry.get();
}

@end
Expand Down
8 changes: 4 additions & 4 deletions Source/WebCore/platform/ios/WebEventPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
#import "WebSEDefinitions.h"
#import <WebCore/WebEvent.h>

@class WebSEKeyEvent;
@class WebSEKeyEntry;

@interface WebEvent (WebSEKeyEventSupport)
@interface WebEvent (WebSEKeyEntrySupport)

- (instancetype)initWithKeyEvent:(WebSEKeyEvent *)event;
@property (nonatomic, readonly) WebSEKeyEvent *originalKeyEvent;
- (instancetype)initWithKeyEntry:(WebSEKeyEntry *)event;
@property (nonatomic, readonly) WebSEKeyEntry *originalKeyEntry;

@end

Expand Down
8 changes: 8 additions & 0 deletions Source/WebCore/platform/ios/WebSEDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@
#if USE(APPLE_INTERNAL_SDK)
#import <WebKitAdditions/WebSEDefinitionsAdditions.h>
#endif

#if !defined(SERVICE_EXTENSIONS_KEY_ENTRY_IS_AVAILABLE)
#define WebSEKeyEntry UIKeyEvent
#define WebSEKeyPressState UIKeyEventType
#define WebSEKeyPressStateKeyDown UIKeyEventKeyDown
#define WebSEKeyPressStateKeyUp UIKeyEventKeyUp
#define SERVICE_EXTENSIONS_KEY_ENTRY_IS_AVAILABLE 0
#endif
6 changes: 1 addition & 5 deletions Source/WebKit/Platform/spi/ios/UIKitSPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,8 @@
#import <UIKit/UIAsyncTextInput.h>
#import <UIKit/UIAsyncTextInputClient.h>
#import <UIKit/UIAsyncTextInteraction.h>
#import <UIKit/UIKeyEventContext.h>
#endif

#if HAVE(UI_ASYNC_TEXT_INTERACTION_DELEGATE)
#import <UIKit/UIAsyncTextInteractionDelegate.h>
#import <UIKit/UIKeyEventContext.h>
#endif

#if HAVE(UI_ASYNC_DRAG_INTERACTION)
Expand Down Expand Up @@ -697,7 +694,6 @@ typedef NS_ENUM(NSInteger, UIWKGestureType) {

@interface UIWKTextInteractionAssistant ()
- (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;
Expand Down
4 changes: 4 additions & 0 deletions Source/WebKit/Shared/DocumentEditingContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#import <WebCore/ElementContext.h>
#import <wtf/cocoa/VectorCocoa.h>

#if USE(APPLE_INTERNAL_SDK)
#import <WebKitAdditions/ServiceExtensionsAdditions.h>
#endif

namespace WebKit {

static inline NSRange toNSRange(DocumentEditingContext::Range range)
Expand Down
8 changes: 6 additions & 2 deletions Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ class WebPageProxy;
#endif
#endif

#if USE(APPLE_INTERNAL_SDK)
#import <WebKitAdditions/ServiceExtensionsAdditions.h>
#endif

typedef BlockPtr<void(WebKit::InteractionInformationAtPosition)> InteractionInformationCallback;
typedef std::pair<WebKit::InteractionInformationRequest, InteractionInformationCallback> InteractionInformationRequestAndCallback;

Expand Down Expand Up @@ -585,7 +589,7 @@ struct ImageAnalysisContextMenuActionData {
std::optional<WebKit::RemoveBackgroundData> _removeBackgroundData;
#endif
#if HAVE(UI_ASYNC_TEXT_INTERACTION)
__weak id<WKSETextInputDelegate> _asyncSystemInputDelegate;
__weak id<WKSETextInputDelegate> _asyncInputDelegate;
#endif
}

Expand Down Expand Up @@ -613,7 +617,7 @@ struct ImageAnalysisContextMenuActionData {
#elif ENABLE(DRAG_SUPPORT)
, UIDragInteractionDelegate
#endif
#if HAVE(UI_ASYNC_TEXT_INTERACTION_DELEGATE)
#if HAVE(UI_ASYNC_TEXT_INTERACTION)
, WKSETextInteractionDelegate
#endif
>
Expand Down
Loading

0 comments on commit 27dbd34

Please sign in to comment.