- Revision
- 275760
- Author
- [email protected]
- Date
- 2021-04-09 06:25:32 -0700 (Fri, 09 Apr 2021)
Log Message
[iOS][FCR] Use context menus for text input datalist dropdowns
https://bugs.webkit.org/show_bug.cgi?id=224287
<rdar://problem/76351317>
Reviewed by Wenson Hsieh.
Source/WebKit:
Use context menus rather than popovers to present suggested values for
text inputs with an associated datalist element.
* Platform/spi/ios/UIKitSPI.h:
* UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
Expose _isShowingDatalistSuggestions for testing. Previously, the test
runner traversed the view hierarchy in order to determine whether the
suggestions were visible. However, that approach is not reliable since
we no longer own the presented view, and UIKit could change the
implementation details of context menus.
* UIProcess/API/ios/WKWebViewTestingIOS.mm:
(-[WKWebView _isShowingDataListSuggestions]):
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView doAfterEditorStateUpdateAfterFocusingElement:]):
Add a mechanism to perform actions after an editor state update when
focusing an element. If an update is not expected, run the block
immediately.
See below for details on why this is necessary.
(-[WKContentView _didUpdateEditorState]):
Run any pending blocks that were awaiting an editor state update.
(-[WKContentView isShowingDataListSuggestions]):
* UIProcess/ios/WebDataListSuggestionsDropdownIOS.h:
* UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm:
(-[WKDataListSuggestionsDropdown invalidate]):
(-[WKDataListSuggestionsDropdown didSelectOptionAtIndex:]):
(-[WKDataListSuggestionsDropdown _showSuggestions]):
Present a context menu displaying the suggestions if one is not already
presented.
Note that focusing text fields can result in automatic zooming of the
webview. This zooming occurs after an editor state update for focused
elements. The presentation of the context menu is deferred to run
after an editor state update to ensure any zooming occurs before
showing the menu. Without this deferred presentation mechanism, the
context menu can be presented before the state update, partially
obscuring the webview and resulting in an incorrect zoom once the
update occurs.
If a menu is already presented, use `updateVisibleMenuWithBlock:` to
update the contents of the menu.
(-[WKDataListSuggestionsDropdown _updateTextSuggestions]):
(-[WKDataListSuggestionsDropdown _updateSuggestionsMenuElements]):
(-[WKDataListSuggestionsDropdown _removeContextMenuInteraction]):
(-[WKDataListSuggestionsDropdown _suggestionsMenuDidPresent]):
(-[WKDataListSuggestionsDropdown _suggestionsMenuDidDismiss]):
(-[WKDataListSuggestionsDropdown _preferredEdgeInsetsForSuggestionsMenu]):
By default, context menus can obscure the presenting element if there
are too many options. Inset the menu so that it does not overlap the
text field. Present the menu above the text field if there is less
space underneath the field.
(-[WKDataListSuggestionsDropdown contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]):
(-[WKDataListSuggestionsDropdown _contextMenuInteraction:styleForMenuWithConfiguration:]):
(-[WKDataListSuggestionsDropdown contextMenuInteraction:configurationForMenuAtLocation:]):
(-[WKDataListSuggestionsDropdown contextMenuInteraction:willDisplayMenuForConfiguration:animator:]):
(-[WKDataListSuggestionsDropdown contextMenuInteraction:willEndForConfiguration:animator:]):
Tools:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::isShowingDataListSuggestions const):
Use the exposed information from the webview to determine whether the
datalist suggestions are visible, rather than traversing the view
hierarchy.
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (275759 => 275760)
--- trunk/Source/WebKit/ChangeLog 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/ChangeLog 2021-04-09 13:25:32 UTC (rev 275760)
@@ -1,3 +1,79 @@
+2021-04-09 Aditya Keerthi <[email protected]>
+
+ [iOS][FCR] Use context menus for text input datalist dropdowns
+ https://bugs.webkit.org/show_bug.cgi?id=224287
+ <rdar://problem/76351317>
+
+ Reviewed by Wenson Hsieh.
+
+ Use context menus rather than popovers to present suggested values for
+ text inputs with an associated datalist element.
+
+ * Platform/spi/ios/UIKitSPI.h:
+ * UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h:
+
+ Expose _isShowingDatalistSuggestions for testing. Previously, the test
+ runner traversed the view hierarchy in order to determine whether the
+ suggestions were visible. However, that approach is not reliable since
+ we no longer own the presented view, and UIKit could change the
+ implementation details of context menus.
+
+ * UIProcess/API/ios/WKWebViewTestingIOS.mm:
+ (-[WKWebView _isShowingDataListSuggestions]):
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView doAfterEditorStateUpdateAfterFocusingElement:]):
+
+ Add a mechanism to perform actions after an editor state update when
+ focusing an element. If an update is not expected, run the block
+ immediately.
+
+ See below for details on why this is necessary.
+
+ (-[WKContentView _didUpdateEditorState]):
+
+ Run any pending blocks that were awaiting an editor state update.
+
+ (-[WKContentView isShowingDataListSuggestions]):
+ * UIProcess/ios/WebDataListSuggestionsDropdownIOS.h:
+ * UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm:
+ (-[WKDataListSuggestionsDropdown invalidate]):
+ (-[WKDataListSuggestionsDropdown didSelectOptionAtIndex:]):
+ (-[WKDataListSuggestionsDropdown _showSuggestions]):
+
+ Present a context menu displaying the suggestions if one is not already
+ presented.
+
+ Note that focusing text fields can result in automatic zooming of the
+ webview. This zooming occurs after an editor state update for focused
+ elements. The presentation of the context menu is deferred to run
+ after an editor state update to ensure any zooming occurs before
+ showing the menu. Without this deferred presentation mechanism, the
+ context menu can be presented before the state update, partially
+ obscuring the webview and resulting in an incorrect zoom once the
+ update occurs.
+
+ If a menu is already presented, use `updateVisibleMenuWithBlock:` to
+ update the contents of the menu.
+
+ (-[WKDataListSuggestionsDropdown _updateTextSuggestions]):
+ (-[WKDataListSuggestionsDropdown _updateSuggestionsMenuElements]):
+ (-[WKDataListSuggestionsDropdown _removeContextMenuInteraction]):
+ (-[WKDataListSuggestionsDropdown _suggestionsMenuDidPresent]):
+ (-[WKDataListSuggestionsDropdown _suggestionsMenuDidDismiss]):
+ (-[WKDataListSuggestionsDropdown _preferredEdgeInsetsForSuggestionsMenu]):
+
+ By default, context menus can obscure the presenting element if there
+ are too many options. Inset the menu so that it does not overlap the
+ text field. Present the menu above the text field if there is less
+ space underneath the field.
+
+ (-[WKDataListSuggestionsDropdown contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]):
+ (-[WKDataListSuggestionsDropdown _contextMenuInteraction:styleForMenuWithConfiguration:]):
+ (-[WKDataListSuggestionsDropdown contextMenuInteraction:configurationForMenuAtLocation:]):
+ (-[WKDataListSuggestionsDropdown contextMenuInteraction:willDisplayMenuForConfiguration:animator:]):
+ (-[WKDataListSuggestionsDropdown contextMenuInteraction:willEndForConfiguration:animator:]):
+
2021-04-08 Fujii Hironori <[email protected]>
[Win] Wrong KeyboardEvent.key for numeric key pad with NumLock
Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (275759 => 275760)
--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2021-04-09 13:25:32 UTC (rev 275760)
@@ -1212,6 +1212,7 @@
@interface _UIContextMenuStyle : NSObject <NSCopying>
@property (nonatomic) _UIContextMenuLayout preferredLayout;
+@property (nonatomic) UIEdgeInsets preferredEdgeInsets;
@property (nonatomic) BOOL hasInteractivePreview;
@property (nonatomic, strong) NSArray *preferredBackgroundEffects;
+ (instancetype)defaultStyle;
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h (275759 => 275760)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h 2021-04-09 13:25:32 UTC (rev 275760)
@@ -54,6 +54,7 @@
- (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex;
- (void)setSelectedColorForColorPicker:(UIColor *)color;
- (void)_selectDataListOption:(int)optionIndex;
+- (BOOL)_isShowingDataListSuggestions;
- (BOOL)_mayContainEditableElementsInRect:(CGRect)rect;
- (void)_requestTextInputContextsInRect:(CGRect)rect completionHandler:(void (^)(NSArray<_WKTextInputContext *> *))completionHandler;
Modified: trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm (275759 => 275760)
--- trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm 2021-04-09 13:25:32 UTC (rev 275760)
@@ -179,6 +179,15 @@
#endif
}
+- (BOOL)_isShowingDataListSuggestions
+{
+#if ENABLE(DATALIST_ELEMENT)
+ return [_contentView isShowingDataListSuggestions];
+#else
+ return NO;
+#endif
+}
+
- (NSString *)textContentTypeForTesting
{
return [_contentView textContentTypeForTesting];
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (275759 => 275760)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2021-04-09 13:25:32 UTC (rev 275760)
@@ -378,6 +378,8 @@
RetainPtr<WKKeyboardScrollViewAnimator> _keyboardScrollingAnimator;
+ Vector<BlockPtr<void()>> _actionsToPerformAfterEditorStateUpdate;
+
#if ENABLE(DATALIST_ELEMENT)
RetainPtr<UIView <WKFormControl>> _dataListTextSuggestionsInputView;
RetainPtr<NSArray<UITextSuggestion *>> _dataListTextSuggestions;
@@ -642,6 +644,8 @@
- (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request;
- (BOOL)ensurePositionInformationIsUpToDate:(WebKit::InteractionInformationRequest)request;
+- (void)doAfterEditorStateUpdateAfterFocusingElement:(dispatch_block_t)block;
+
#if ENABLE(DRAG_SUPPORT)
- (void)_didChangeDragInteractionPolicy;
- (void)_didPerformDragOperation:(BOOL)handled;
@@ -678,6 +682,8 @@
- (void)setContinuousSpellCheckingEnabled:(BOOL)enabled;
#if USE(UICONTEXTMENU)
+- (UIView *)textEffectsWindow;
+
- (UITargetedPreview *)_createTargetedContextMenuHintPreviewForFocusedElement;
- (UITargetedPreview *)_createTargetedContextMenuHintPreviewIfPossible;
- (void)_removeContextMenuViewIfPossible;
@@ -732,6 +738,8 @@
#if ENABLE(DATALIST_ELEMENT)
- (void)_selectDataListOption:(NSInteger)optionIndex;
- (void)_setDataListSuggestionsControl:(WKDataListSuggestionsControl *)control;
+
+@property (nonatomic, readonly) BOOL isShowingDataListSuggestions;
#endif
@property (nonatomic, readonly) NSString *textContentTypeForTesting;
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (275759 => 275760)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2021-04-09 13:25:32 UTC (rev 275760)
@@ -6461,6 +6461,16 @@
[UIMenuController.sharedMenuController showMenuFromView:self rect:menuControllerRect];
}
+- (void)doAfterEditorStateUpdateAfterFocusingElement:(dispatch_block_t)block
+{
+ if (!_page->waitingForPostLayoutEditorStateUpdateAfterFocusingElement()) {
+ block();
+ return;
+ }
+
+ _actionsToPerformAfterEditorStateUpdate.append(makeBlockPtr(block));
+}
+
- (void)_didUpdateEditorState
{
[self _updateInitialWritingDirectionIfNecessary];
@@ -6471,6 +6481,9 @@
[self _zoomToRevealFocusedElement];
_treatAsContentEditableUntilNextEditorStateUpdate = NO;
+
+ for (auto block : std::exchange(_actionsToPerformAfterEditorStateUpdate, { }))
+ block();
}
- (void)_updateInitialWritingDirectionIfNecessary
@@ -9791,7 +9804,7 @@
#if ENABLE(DATALIST_ELEMENT)
- (void)_selectDataListOption:(NSInteger)optionIndex
{
- [_dataListSuggestionsControl.getAutoreleased() didSelectOptionAtIndex:optionIndex];
+ [_dataListSuggestionsControl didSelectOptionAtIndex:optionIndex];
}
- (void)_setDataListSuggestionsControl:(WKDataListSuggestionsControl *)control
@@ -9798,6 +9811,11 @@
{
_dataListSuggestionsControl = control;
}
+
+- (BOOL)isShowingDataListSuggestions
+{
+ return [_dataListSuggestionsControl isShowingSuggestions];
+}
#endif
@end
Modified: trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h (275759 => 275760)
--- trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h 2021-04-09 13:25:32 UTC (rev 275760)
@@ -36,10 +36,14 @@
@end
@interface WKDataListSuggestionsControl : NSObject
+
+@property (nonatomic, readonly) BOOL isShowingSuggestions;
+
- (instancetype)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(WKContentView *)view;
- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information;
- (void)didSelectOptionAtIndex:(NSInteger)index;
- (void)invalidate;
+
@end
namespace WebKit {
Modified: trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm (275759 => 275760)
--- trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm 2021-04-09 13:25:32 UTC (rev 275760)
@@ -34,6 +34,7 @@
#import "WKContentViewInteraction.h"
#import "WKFormPeripheral.h"
#import "WKFormPopover.h"
+#import "WKWebViewPrivateForTesting.h"
#import "WebPageProxy.h"
static const CGFloat maxVisibleSuggestions = 5;
@@ -44,6 +45,7 @@
@interface WKDataListSuggestionsControl ()
@property (nonatomic, weak) WKContentView *view;
+@property (nonatomic) BOOL isShowingSuggestions;
- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownIOS&)dropdown activationType:(WebCore::DataListSuggestionActivationType)activationType;
@@ -71,7 +73,11 @@
@end
#if ENABLE(IOS_FORM_CONTROL_REFRESH)
-@interface WKDataListSuggestionsDropdown : WKDataListSuggestionsControl <UIPopoverPresentationControllerDelegate>
+#if USE(UICONTEXTMENU)
+@interface WKDataListSuggestionsDropdown : WKDataListSuggestionsControl <UIContextMenuInteractionDelegate>
+#else
+@interface WKDataListSuggestionsDropdown : WKDataListSuggestionsControl
+#endif
@end
#endif
@@ -397,8 +403,10 @@
#pragma mark - WKDataListSuggestionsDropdown
@implementation WKDataListSuggestionsDropdown {
- RetainPtr<WKDataListSuggestionsViewController> _suggestionsViewController;
- RetainPtr<NSObject> _keyboardDismissalObserver;
+#if USE(UICONTEXTMENU)
+ RetainPtr<NSArray<UIMenuElement *>> _suggestionsMenuElements;
+ RetainPtr<UIContextMenuInteraction> _suggestionsContextMenuInteraction;
+#endif
}
- (instancetype)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(WKContentView *)view
@@ -425,23 +433,17 @@
- (void)invalidate
{
- [[_suggestionsViewController presentingViewController] dismissViewControllerAnimated:NO completion:nil];
- [_suggestionsViewController setControl:nil];
+#if USE(UICONTEXTMENU)
+ [self _removeContextMenuInteraction];
+#endif
}
- (void)didSelectOptionAtIndex:(NSInteger)index
{
- [[_suggestionsViewController presentingViewController] dismissViewControllerAnimated:NO completion:nil];
[self.view updateFocusedElementFocusedWithDataListDropdown:NO];
[super didSelectOptionAtIndex:index];
}
-- (void)dealloc
-{
- [self _removeKeyboardDismissalObserver];
- [super dealloc];
-}
-
- (void)_displayWithActivationType:(WebCore::DataListSuggestionActivationType)activationType
{
if (activationType == WebCore::DataListSuggestionActivationType::IndicatorClicked)
@@ -459,74 +461,141 @@
- (void)_showSuggestions
{
- if (!_suggestionsViewController) {
- _suggestionsViewController = adoptNS([[WKDataListSuggestionsViewController alloc] initWithStyle:UITableViewStylePlain]);
- [_suggestionsViewController setModalPresentationStyle:UIModalPresentationPopover];
- [[_suggestionsViewController tableView] setSeparatorInset:UIEdgeInsetsZero];
- [_suggestionsViewController setControl:self];
+#if USE(UICONTEXTMENU)
+ [self _updateSuggestionsMenuElements];
+
+ if (!_suggestionsContextMenuInteraction) {
+ _suggestionsContextMenuInteraction = adoptNS([[UIContextMenuInteraction alloc] initWithDelegate:self]);
+ [self.view addInteraction:_suggestionsContextMenuInteraction.get()];
+
+ [self.view doAfterEditorStateUpdateAfterFocusingElement:[weakSelf = WeakObjCPtr<WKDataListSuggestionsDropdown>(self)] {
+ auto strongSelf = weakSelf.get();
+ if (!strongSelf)
+ return;
+
+ [strongSelf->_suggestionsContextMenuInteraction _presentMenuAtLocation:[[strongSelf view] lastInteractionLocation]];
+ }];
+ } else {
+ [_suggestionsContextMenuInteraction updateVisibleMenuWithBlock:[&](UIMenu *visibleMenu) -> UIMenu * {
+ return [visibleMenu menuByReplacingChildren:_suggestionsMenuElements.get()];
+ }];
}
+#endif
+}
- [_suggestionsViewController reloadData];
+- (void)_updateTextSuggestions
+{
+ self.view.dataListTextSuggestions = self.textSuggestions;
+}
- if ([_suggestionsViewController isBeingPresented] || [[_suggestionsViewController viewIfLoaded] window] != nil)
- return;
+#if USE(UICONTEXTMENU)
- UIPopoverPresentationController *presentationController = [_suggestionsViewController popoverPresentationController];
- presentationController.sourceView = self.view;
- presentationController.sourceRect = CGRectIntegral(self.view.focusedElementInformation.interactionRect);
- presentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
- presentationController.delegate = self;
- [presentationController _setShouldHideArrow:YES];
- [presentationController _setPreferredHorizontalAlignment:_UIPopoverPresentationHorizontalAlignmentLeading];
+- (void)_updateSuggestionsMenuElements
+{
+ NSMutableArray *suggestions = [NSMutableArray arrayWithCapacity:self.suggestionsCount];
- // When a hardware keyboard is not used, the suggestions dropdown and software keyboard cannot be
- // displayed at the same time. We wait until the keyboard is dismissed prior to presenting the
- // suggestions, to avoid the keyboard's dismissal repositioning the dropdown.
-
- if ([UIKeyboard isOnScreen] && ![UIKeyboard isInHardwareKeyboardMode]) {
- _keyboardDismissalObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardDidHideNotification object:nil queue:nil usingBlock:[weakSelf = WeakObjCPtr<WKDataListSuggestionsDropdown>(self)] (NSNotification *) {
+ for (NSInteger index = 0; index < self.suggestionsCount; index++) {
+ UIAction *suggestionAction = [UIAction actionWithTitle:[self suggestionAtIndex:index] image:nil identifier:nil handler:[weakSelf = WeakObjCPtr<WKDataListSuggestionsDropdown>(self), index] (UIAction *) {
auto strongSelf = weakSelf.get();
if (!strongSelf)
return;
- [strongSelf _presentSuggestionsViewController];
- [strongSelf _removeKeyboardDismissalObserver];
+ [strongSelf didSelectOptionAtIndex:index];
}];
- } else
- [self _presentSuggestionsViewController];
+
+ [suggestions addObject:suggestionAction];
+ }
+
+ _suggestionsMenuElements = adoptNS([suggestions copy]);
}
-- (void)_presentSuggestionsViewController
+- (void)_removeContextMenuInteraction
{
- UIViewController *presentingViewController = [UIViewController _viewControllerForFullScreenPresentationFromView:self.view];
- [presentingViewController presentViewController:_suggestionsViewController.get() animated:NO completion:nil];
+ if (!_suggestionsContextMenuInteraction)
+ return;
+
+ [self.view removeInteraction:_suggestionsContextMenuInteraction.get()];
+ _suggestionsContextMenuInteraction = nil;
+ [self.view _removeContextMenuViewIfPossible];
+ [self.view.webView _didDismissContextMenu];
}
-- (void)_updateTextSuggestions
+- (void)_suggestionsMenuDidPresent
{
- self.view.dataListTextSuggestions = self.textSuggestions;
+ self.isShowingSuggestions = YES;
+
+ [self.view.webView _didShowContextMenu];
}
-- (void)_removeKeyboardDismissalObserver
+- (void)_suggestionsMenuDidDismiss
{
- [[NSNotificationCenter defaultCenter] removeObserver:_keyboardDismissalObserver.get()];
- _keyboardDismissalObserver = nil;
+ self.isShowingSuggestions = NO;
+
+ [self.view updateFocusedElementFocusedWithDataListDropdown:NO];
+ [self _updateTextSuggestions];
+
+ [self _removeContextMenuInteraction];
}
-#pragma mark UIPopoverPresentationControllerDelegate
+- (UIEdgeInsets)_preferredEdgeInsetsForSuggestionsMenu
+{
+ CGRect windowBounds = self.view.textEffectsWindow.bounds;
+ CGRect elementFrameInWindowCoordinates = [self.view convertRect:self.view.focusedElementInformation.interactionRect toView:nil];
-- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController
+ if (CGRectGetMidY(elementFrameInWindowCoordinates) > CGRectGetMidY(windowBounds))
+ return UIEdgeInsetsMake(0, 0, CGRectGetMaxY(windowBounds) - CGRectGetMinY(elementFrameInWindowCoordinates), 0);
+
+ // Use MinY rather than MaxY to account for the hint preview.
+ return UIEdgeInsetsMake(CGRectGetMinY(elementFrameInWindowCoordinates), 0, 0, 0);
+}
+
+#pragma mark UIContextMenuInteractionDelegate
+
+- (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForHighlightingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration
{
- [self.view updateFocusedElementFocusedWithDataListDropdown:NO];
- [self _updateTextSuggestions];
+ return [self.view _createTargetedContextMenuHintPreviewForFocusedElement];
}
-- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection
+- (_UIContextMenuStyle *)_contextMenuInteraction:(UIContextMenuInteraction *)interaction styleForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration
{
- // Forces a popover presentation.
- return UIModalPresentationNone;
+ _UIContextMenuStyle *style = [_UIContextMenuStyle defaultStyle];
+ style.preferredLayout = _UIContextMenuLayoutCompactMenu;
+ style.preferredEdgeInsets = [self _preferredEdgeInsetsForSuggestionsMenu];
+
+ return style;
}
+- (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location
+{
+ UIContextMenuActionProvider actionMenuProvider = [weakSelf = WeakObjCPtr<WKDataListSuggestionsDropdown>(self)] (NSArray<UIMenuElement *> *) -> UIMenu * {
+ auto strongSelf = weakSelf.get();
+ if (!strongSelf)
+ return nil;
+
+ return [UIMenu menuWithTitle:@"" children:strongSelf->_suggestionsMenuElements.get()];
+ };
+
+ return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:actionMenuProvider];
+}
+
+- (void)contextMenuInteraction:(UIContextMenuInteraction *)interaction willDisplayMenuForConfiguration:(UIContextMenuConfiguration *)configuration animator:(id <UIContextMenuInteractionAnimating>)animator
+{
+ [animator addCompletion:[weakSelf = WeakObjCPtr<WKDataListSuggestionsDropdown>(self)] {
+ if (auto strongSelf = weakSelf.get())
+ [strongSelf _suggestionsMenuDidPresent];
+ }];
+}
+
+- (void)contextMenuInteraction:(UIContextMenuInteraction *)interaction willEndForConfiguration:(UIContextMenuConfiguration *)configuration animator:(id <UIContextMenuInteractionAnimating>)animator
+{
+ [animator addCompletion:[weakSelf = WeakObjCPtr<WKDataListSuggestionsDropdown>(self)] {
+ if (auto strongSelf = weakSelf.get())
+ [strongSelf _suggestionsMenuDidDismiss];
+ }];
+}
+
+#endif // USE(UICONTEXTMENU)
+
@end
#endif // ENABLE(IOS_FORM_CONTROL_REFRESH)
Modified: trunk/Tools/ChangeLog (275759 => 275760)
--- trunk/Tools/ChangeLog 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Tools/ChangeLog 2021-04-09 13:25:32 UTC (rev 275760)
@@ -1,3 +1,18 @@
+2021-04-09 Aditya Keerthi <[email protected]>
+
+ [iOS][FCR] Use context menus for text input datalist dropdowns
+ https://bugs.webkit.org/show_bug.cgi?id=224287
+ <rdar://problem/76351317>
+
+ Reviewed by Wenson Hsieh.
+
+ * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+ (WTR::UIScriptControllerIOS::isShowingDataListSuggestions const):
+
+ Use the exposed information from the webview to determine whether the
+ datalist suggestions are visible, rather than traversing the view
+ hierarchy.
+
2021-04-08 Jiewen Tan <[email protected]>
PCM: Write more blinded secret tests
Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (275759 => 275760)
--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2021-04-09 11:43:11 UTC (rev 275759)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2021-04-09 13:25:32 UTC (rev 275760)
@@ -1115,12 +1115,8 @@
bool UIScriptControllerIOS::isShowingDataListSuggestions() const
{
#if ENABLE(IOS_FORM_CONTROL_REFRESH)
- UIViewController *presentedViewController = [UIViewController _viewControllerForFullScreenPresentationFromView:webView()];
- Class suggestionsViewControllerClass = NSClassFromString(@"WKDataListSuggestionsViewController");
- if ([presentedViewController isKindOfClass:suggestionsViewControllerClass])
- return true;
-#endif
-
+ return [webView() _isShowingDataListSuggestions];
+#else
Class remoteKeyboardWindowClass = NSClassFromString(@"UIRemoteKeyboardWindow");
Class suggestionsPickerViewClass = NSClassFromString(@"WKDataListSuggestionsPickerView");
UIWindow *remoteInputHostingWindow = nil;
@@ -1141,6 +1137,7 @@
*stop = YES;
});
return foundDataListSuggestionsPickerView;
+#endif
}
void UIScriptControllerIOS::setSelectedColorForColorPicker(double red, double green, double blue)