Diff
Modified: trunk/LayoutTests/ChangeLog (243807 => 243808)
--- trunk/LayoutTests/ChangeLog 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/LayoutTests/ChangeLog 2019-04-03 17:06:04 UTC (rev 243808)
@@ -1,3 +1,16 @@
+2019-04-03 Daniel Bates <[email protected]>
+
+ [iOS] Should be able to dismiss picker or popover using the keyboard
+ https://bugs.webkit.org/show_bug.cgi?id=196272
+ <rdar://problem/48943170>
+
+ Reviewed by Wenson Hsieh.
+
+ Add test to ensure that pressing Escape or Command + . dismisses a picker.
+
+ * fast/forms/ios/dismiss-picker-using-keyboard-expected.txt: Added.
+ * fast/forms/ios/dismiss-picker-using-keyboard.html: Added.
+
2019-04-03 Sihui Liu <[email protected]>
Blob type cannot be stored correctly in IDB when IDBObjectStore has autoIncrement and keyPath options
Added: trunk/LayoutTests/fast/forms/ios/dismiss-picker-using-keyboard-expected.txt (0 => 243808)
--- trunk/LayoutTests/fast/forms/ios/dismiss-picker-using-keyboard-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/dismiss-picker-using-keyboard-expected.txt 2019-04-03 17:06:04 UTC (rev 243808)
@@ -0,0 +1,49 @@
+Tests that pressing the Escape key or Command + . dismisses a picker without causing a value change.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Dismiss by pressing escape:
+
+For color:
+PASS elementToTest.value is "#000000"
+
+For date:
+PASS elementToTest.value is "2019-03-26"
+
+For datetime-local:
+PASS elementToTest.value is "2019-03-26T14:28:05.455"
+
+For month:
+PASS elementToTest.value is "2019-03"
+
+For select:
+PASS elementToTest.value is "First"
+
+For time:
+PASS elementToTest.value is "14:28"
+
+Dismiss by pressing Command + .:
+
+For color:
+PASS elementToTest.value is "#000000"
+
+For date:
+PASS elementToTest.value is "2019-03-26"
+
+For datetime-local:
+PASS elementToTest.value is "2019-03-26T14:28:05.455"
+
+For month:
+PASS elementToTest.value is "2019-03"
+
+For select:
+PASS elementToTest.value is "First"
+
+For time:
+PASS elementToTest.value is "14:28"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/forms/ios/dismiss-picker-using-keyboard.html (0 => 243808)
--- trunk/LayoutTests/fast/forms/ios/dismiss-picker-using-keyboard.html (rev 0)
+++ trunk/LayoutTests/fast/forms/ios/dismiss-picker-using-keyboard.html 2019-04-03 17:06:04 UTC (rev 243808)
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<!-- Place the test container above the console output to avoid the need to compensate for page scroll. -->
+<div id="test-container">
+ <p><input type="color" class="test" data-test-name="color"></p>
+ <p><input type="date" class="test" data-test-name="date" value="2019-03-26"></p>
+ <p><input type="datetime-local" class="test" data-test-name="datetime-local" value="2019-03-26T14:28:05.455"></p>
+ <p><input type="month" class="test" data-test-name="month" value="2019-03"></p>
+ <p><select class="test" data-test-name="select">
+ <option>First</option>
+ <option>Second</option>
+ </select></p>
+ <p><input type="time" class="test" data-test-name="time" value="14:28"></p>
+</div>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+window.jsTestIsAsync = true;
+
+let elementToTest;
+
+const modifierDisplayNameMap = {
+ "altKey": "Option",
+ "ctrlKey": "Control",
+ "metaKey": "Command",
+ "shiftKey": "Shift",
+ "capsLockKey": "Caps Lock",
+}
+
+class KeyCommand {
+ constructor(key, modifiers = [])
+ {
+ this.key = key;
+ this.modifiers = modifiers;
+ }
+
+ toString()
+ {
+ let readableCommand = this.modifiers.map((modifier) => modifierDisplayNameMap[modifier]);
+ readableCommand.push(this.key);
+ return readableCommand.join(" + ");
+ }
+}
+
+function done()
+{
+ let testContainer = document.getElementById("test-container");
+ document.body.removeChild(testContainer);
+ finishJSTest()
+}
+
+async function runTest()
+{
+ if (!window.testRunner) {
+ testFailed("Must be run in WebKitTestRunner.");
+ done();
+ return;
+ }
+
+ let elementsToTest = document.getElementsByClassName("test");
+ for (let keyCommand of [new KeyCommand("escape"), new KeyCommand(".", ["metaKey"])]) {
+ debug(`<br>Dismiss by pressing ${keyCommand}:`);
+ for (elementToTest of elementsToTest) {
+ debug(`<br>For ${elementToTest.dataset.testName}:`);
+ let expectedValue = elementToTest.value;
+ await UIHelper.activateElementAndWaitForInputSession(elementToTest);
+ UIHelper.keyDown(keyCommand.key, keyCommand.modifiers);
+ await UIHelper.waitForKeyboardToHide();
+ shouldBeEqualToString("elementToTest.value", expectedValue);
+ }
+ }
+ elementToTest = null;
+ done();
+}
+
+description("Tests that pressing the Escape key or Command + . dismisses a picker without causing a value change.");
+
+runTest();
+</script>
+</body>
+</html>
Modified: trunk/Source/WebKit/ChangeLog (243807 => 243808)
--- trunk/Source/WebKit/ChangeLog 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/ChangeLog 2019-04-03 17:06:04 UTC (rev 243808)
@@ -1,3 +1,79 @@
+2019-04-03 Daniel Bates <[email protected]>
+
+ [iOS] Should be able to dismiss picker or popover using the keyboard
+ https://bugs.webkit.org/show_bug.cgi?id=196272
+ <rdar://problem/48943170>
+
+ Reviewed by Wenson Hsieh.
+
+ Intercept key events and route them to the current input peripheral (if we have one). Add a base key event handler
+ for all form peripherals that dismisses the accessory when either the Escape key is pressed or Command + . is pressed.
+ I will fix this issue for the file upload picker/popover in <https://bugs.webkit.org/show_bug.cgi?id=196287>.
+
+ * SourcesCocoa.txt: Add file WKFormPeripheralBase.mm.
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView endEditingAndUpdateFocusAppearanceWithReason]): Added.
+ (-[WKContentView resignFirstResponderForWebView]): Write in terms of -endEditingAndUpdateFocusAppearance.
+ (-[WKContentView inputView]): Code style nit while I am here; add an empty line to demarcate the "crazy"
+ code that the FIXME is referring to and should ideally be removed from the code that is sane to always do.
+ (-[WKContentView accessoryDone]): When the accessory is dismissed via the Done button (iPhone) or by pressing
+ Escape or Command + . using a hardware keyboard (iPhone or iPad) then end the current editing session, but
+ do not resign first responder status as the page activation state should not be changed.
+ (-[WKContentView _handleKeyUIEvent:]): Bring back this code when building with USE(UIKIT_KEYBOARD_ADDITIONS)
+ as we need to route key events to the input peripheral (if we have one). If the input peripheral handles it
+ then we're done: no need to let UIKit or WebKit handle it when building with USE(UIKIT_KEYBOARD_ADDITIONS),
+ respectively. If the input peripheral does not handle it then do what we do now.
+ (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:]):
+ If the element is re-focused and we have an input peripheral then we want to ensure we are first responder,
+ reveal the focused element, update the accessory and tell the peripheral that editing has begun (again).
+ For all other element re-focusing where we don't have a peripheral do what we do now. Also, update _isEditable
+ to reflect whether the focused element contains selectable text. This is what UIKit wants to know when it queries
+ -isEditable. Now that we no longer blur the focused element on iPad when the popover is dismissed and keep the
+ peripheral until there is a focus change we need to ensure that we give the correct answer to UIKit on view
+ editability. Otherwise, UIKit thinks it needs to update the text selection state when a popup button is tapped
+ again (as part of its gesture recognizer logic) and this causes an assertion failure in UIKit after it calls back
+ into us to ask for selection details, which we correctly respond with the equivalent of "we have none" and is
+ not the answer UIKit expects since we told it we are editable. (Currently we manage to get away with telling UIKit
+ we are always editable because it is not possible to perform a selection operation when we have a popover open.
+ Closing the popover blurs the element, setting -isEditable to NO and deallocates the peripheral avoiding this issue).
+ * UIProcess/ios/forms/WKFormColorControl.h:
+ * UIProcess/ios/forms/WKFormColorControl.mm:
+ (-[WKColorPopover controlEndEditing]): Dismiss the popover.
+ (-[WKFormColorControl initWithView:]): Modified to call base class initializer.
+ (-[WKFormColorControl assistantView]): Deleted.
+ (-[WKFormColorControl beginEditing]): Deleted.
+ (-[WKFormColorControl endEditing]): Deleted.
+ * UIProcess/ios/forms/WKFormInputControl.h:
+ * UIProcess/ios/forms/WKFormInputControl.mm:
+ (-[WKFormInputControl initWithView:]): Modified to call base class initializer.
+ (-[WKFormInputControl dateTimePickerCalendarType]): Write in terms of self.control.
+ (-[WKDateTimePopover controlEndEditing]): Dismiss the popover and tell the controller that editing ended.
+ (-[WKFormInputControl beginEditing]): Deleted.
+ (-[WKFormInputControl endEditing]): Deleted.
+ (-[WKFormInputControl assistantView]): Deleted.
+ * UIProcess/ios/forms/WKFormPeripheral.h:
+ * UIProcess/ios/forms/WKFormPeripheralBase.h: Added.
+ * UIProcess/ios/forms/WKFormPeripheralBase.mm: Added.
+ (-[WKFormPeripheralBase initWithView:control:]): Take ownership of the passed WKFormControl.
+ (-[WKFormPeripheralBase beginEditing]): Turn around and tell the control.
+ (-[WKFormPeripheralBase endEditing]): Ditto.
+ (-[WKFormPeripheralBase assistantView]): Ditto.
+ (-[WKFormPeripheralBase control]): Return the control.
+ (-[WKFormPeripheralBase handleKeyEvent:]): Dismiss the accessory (in the same way we dismiss when the Done
+ button is pressed on iPhone) on keydown of the Escape key or when we receive a UIKeyInputEscape event (for
+ Command + .).
+ * UIProcess/ios/forms/WKFormSelectControl.h:
+ * UIProcess/ios/forms/WKFormSelectControl.mm:
+ (-[WKFormSelectControl initWithView:]): Modified to call base class initializer.
+ (-[WKFormSelectControl selectRow:inComponent:extendingSelection:]): Write in terms of self.control.
+ (-[WKFormSelectControl selectFormPopoverTitle]): Ditto.
+ (-[WKFormSelectControl assistantView]): Deleted.
+ (-[WKFormSelectControl beginEditing]): Deleted.
+ (-[WKFormSelectControl endEditing]): Deleted.
+ * UIProcess/ios/forms/WKFormSelectPopover.mm:
+ (-[WKSelectPopover controlEndEditing]): Dismiss the popover.
+ * WebKit.xcodeproj/project.pbxproj: Add files WKFormPeripheralBase.{h, mm}.
+
2019-04-03 Youenn Fablet <[email protected]>
Resetting quota should take into account third party origins
Modified: trunk/Source/WebKit/SourcesCocoa.txt (243807 => 243808)
--- trunk/Source/WebKit/SourcesCocoa.txt 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/SourcesCocoa.txt 2019-04-03 17:06:04 UTC (rev 243808)
@@ -367,6 +367,7 @@
UIProcess/ios/forms/WKFormColorControl.mm
UIProcess/ios/forms/WKFormColorPicker.mm
UIProcess/ios/forms/WKFormInputControl.mm
+UIProcess/ios/forms/WKFormPeripheralBase.mm
UIProcess/ios/forms/WKFormPopover.mm
UIProcess/ios/forms/WKFormSelectControl.mm
UIProcess/ios/forms/WKFormSelectPicker.mm
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2019-04-03 17:06:04 UTC (rev 243808)
@@ -312,7 +312,6 @@
BOOL _becomingFirstResponder;
BOOL _resigningFirstResponder;
- BOOL _dismissingAccessory;
BOOL _needsDeferredEndScrollingSelectionUpdate;
BOOL _isChangingFocus;
BOOL _isBlurringFocusedElement;
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2019-04-03 17:06:04 UTC (rev 243808)
@@ -1169,25 +1169,35 @@
return [_webView resignFirstResponder];
}
-- (BOOL)resignFirstResponderForWebView
+typedef NS_ENUM(NSInteger, EndEditingReason) {
+ EndEditingReasonAccessoryDone,
+ EndEditingReasonResigningFirstResponder,
+};
+
+- (void)endEditingAndUpdateFocusAppearanceWithReason:(EndEditingReason)reason
{
- // FIXME: Maybe we should call resignFirstResponder on the superclass
- // and do nothing if the return value is NO.
-
- SetForScope<BOOL> resigningFirstResponderScope { _resigningFirstResponder, YES };
-
if (!_webView._retainingActiveFocusedState) {
// We need to complete the editing operation before we blur the element.
[self _endEditing];
- if (_dismissingAccessory || _keyboardDidRequestDismissal)
+ if ((reason == EndEditingReasonAccessoryDone && !currentUserInterfaceIdiomIsPad()) || _keyboardDidRequestDismissal)
_page->blurFocusedElement();
}
[self _cancelInteraction];
[_textSelectionAssistant deactivateSelection];
-
+
[self _resetInputViewDeferral];
+}
+- (BOOL)resignFirstResponderForWebView
+{
+ // FIXME: Maybe we should call resignFirstResponder on the superclass
+ // and do nothing if the return value is NO.
+
+ SetForScope<BOOL> resigningFirstResponderScope { _resigningFirstResponder, YES };
+
+ [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonResigningFirstResponder];
+
// If the user explicitly dismissed the keyboard then we will lose first responder
// status only to gain it back again. Just don't resign in that case.
if (_keyboardDidRequestDismissal) {
@@ -3758,8 +3768,8 @@
- (void)accessoryDone
{
- SetForScope<BOOL> dismissingAccessoryScope { _dismissingAccessory, YES };
- [self resignFirstResponder];
+ [self endEditingAndUpdateFocusAppearanceWithReason:EndEditingReasonAccessoryDone];
+ _page->setIsShowingInputViewForFocusedElement(false);
}
- (void)accessoryTab:(BOOL)isNext
@@ -4362,15 +4372,21 @@
return YES;
}
-#if !USE(UIKIT_KEYBOARD_ADDITIONS)
- (void)_handleKeyUIEvent:(::UIEvent *)event
{
bool isHardwareKeyboardEvent = !!event._hidEvent;
-
// We only want to handle key event from the hardware keyboard when we are
// first responder and we are not interacting with editable content.
- if ([self isFirstResponder] && isHardwareKeyboardEvent && !_page->editorState().isContentEditable) {
+ if ([self isFirstResponder] && isHardwareKeyboardEvent && (_inputPeripheral || !_page->editorState().isContentEditable)) {
+ if ([_inputPeripheral respondsToSelector:@selector(handleKeyEvent:)]) {
+ if ([_inputPeripheral handleKeyEvent:event])
+ return;
+ }
+#if USE(UIKIT_KEYBOARD_ADDITIONS)
+ [super _handleKeyUIEvent:event];
+#else
[self handleKeyEvent:event];
+#endif
return;
}
@@ -4377,6 +4393,7 @@
[super _handleKeyUIEvent:event];
}
+#if !USE(UIKIT_KEYBOARD_ADDITIONS)
- (void)handleKeyEvent:(::UIEvent *)event
{
// WebCore has already seen the event, no need for custom processing.
@@ -4969,8 +4986,16 @@
// FIXME: We should remove this check when we manage to send ElementDidFocus from the WebProcess
// only when it is truly time to show the keyboard.
- if (_focusedElementInformation.elementType == information.elementType && _focusedElementInformation.elementRect == information.elementRect)
+ if (_focusedElementInformation.elementType == information.elementType && _focusedElementInformation.elementRect == information.elementRect) {
+ if (_inputPeripheral) {
+ if (!self.isFirstResponder)
+ [self becomeFirstResponder];
+ [self _zoomToRevealFocusedElement];
+ [self _updateAccessory];
+ [_inputPeripheral beginEditing];
+ }
return;
+ }
[_webView _resetFocusPreservationCount];
@@ -4989,7 +5014,8 @@
if (delegateImplementsWillStartInputSession)
[inputDelegate _webView:_webView willStartInputSession:_formInputSession.get()];
- BOOL editableChanged = [self setIsEditable:YES];
+ BOOL isSelectable = mayContainSelectableText(information.elementType);
+ BOOL editableChanged = [self setIsEditable:isSelectable];
_focusedElementInformation = information;
_traits = nil;
@@ -5006,7 +5032,7 @@
[self reloadInputViews];
#endif
- if (mayContainSelectableText(_focusedElementInformation.elementType))
+ if (isSelectable)
[self _showKeyboard];
// The custom fixed position rect behavior is affected by -isFocusingElement, so if that changes we need to recompute rects.
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormColorControl.h (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormColorControl.h 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormColorControl.h 2019-04-03 17:06:04 UTC (rev 243808)
@@ -25,11 +25,11 @@
#if ENABLE(INPUT_TYPE_COLOR) && PLATFORM(IOS_FAMILY)
-#import "WKFormPeripheral.h"
+#import "WKFormPeripheralBase.h"
@class WKContentView;
-@interface WKFormColorControl : NSObject<WKFormPeripheral>
+@interface WKFormColorControl : WKFormPeripheralBase
- (instancetype)initWithView:(WKContentView *)view;
@end
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormColorControl.mm (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormColorControl.mm 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormColorControl.mm 2019-04-03 17:06:04 UTC (rev 243808)
@@ -86,6 +86,7 @@
- (void)controlEndEditing
{
+ [self dismissPopoverAnimated:NO];
}
@end
@@ -92,38 +93,18 @@
#pragma mark - WKFormColorControl
-@implementation WKFormColorControl {
- RetainPtr<id<WKFormControl>> _control;
-}
+@implementation WKFormColorControl
- (instancetype)initWithView:(WKContentView *)view
{
- if (!(self = [super init]))
- return nil;
-
+ RetainPtr<NSObject <WKFormControl>> control;
if (currentUserInterfaceIdiomIsPad())
- _control = adoptNS([[WKColorPopover alloc] initWithView:view]);
+ control = adoptNS([[WKColorPopover alloc] initWithView:view]);
else
- _control = adoptNS([[WKColorPicker alloc] initWithView:view]);
-
- return self;
+ control = adoptNS([[WKColorPicker alloc] initWithView:view]);
+ return [super initWithView:view control:WTFMove(control)];
}
-- (UIView *)assistantView
-{
- return [_control controlView];
-}
-
-- (void)beginEditing
-{
- [_control controlBeginEditing];
-}
-
-- (void)endEditing
-{
- [_control controlEndEditing];
-}
-
@end
#endif // ENABLE(INPUT_TYPE_COLOR) && PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h 2019-04-03 17:06:04 UTC (rev 243808)
@@ -25,11 +25,11 @@
#if PLATFORM(IOS_FAMILY)
-#import "WKFormPeripheral.h"
+#import "WKFormPeripheralBase.h"
@class WKContentView;
-@interface WKFormInputControl : NSObject<WKFormPeripheral>
+@interface WKFormInputControl : WKFormPeripheralBase
- (instancetype)initWithView:(WKContentView *)view;
@end
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm 2019-04-03 17:06:04 UTC (rev 243808)
@@ -239,15 +239,10 @@
@end
// WKFormInputControl
-@implementation WKFormInputControl {
- RetainPtr<NSObject <WKFormControl>> _control;
-}
+@implementation WKFormInputControl
- (instancetype)initWithView:(WKContentView *)view
{
- if (!(self = [super init]))
- return nil;
-
UIDatePickerMode mode;
switch (view.focusedElementInformation.elementType) {
@@ -254,48 +249,28 @@
case InputType::Date:
mode = UIDatePickerModeDate;
break;
-
case InputType::DateTimeLocal:
mode = UIDatePickerModeDateAndTime;
break;
-
case InputType::Time:
mode = UIDatePickerModeTime;
break;
-
case InputType::Month:
mode = (UIDatePickerMode)UIDatePickerModeYearAndMonth;
break;
-
default:
[self release];
return nil;
}
+ RetainPtr<NSObject <WKFormControl>> control;
if (currentUserInterfaceIdiomIsPad())
- _control = adoptNS([[WKDateTimePopover alloc] initWithView:view datePickerMode:mode]);
+ control = adoptNS([[WKDateTimePopover alloc] initWithView:view datePickerMode:mode]);
else
- _control = adoptNS([[WKDateTimePicker alloc] initWithView:view datePickerMode:mode]);
-
- return self;
-
+ control = adoptNS([[WKDateTimePicker alloc] initWithView:view datePickerMode:mode]);
+ return [super initWithView:view control:WTFMove(control)];
}
-- (void)beginEditing
-{
- [_control controlBeginEditing];
-}
-
-- (void)endEditing
-{
- [_control controlEndEditing];
-}
-
-- (UIView *)assistantView
-{
- return [_control controlView];
-}
-
@end
@implementation WKFormInputControl (WKTesting)
@@ -302,12 +277,10 @@
- (NSString *)dateTimePickerCalendarType
{
- if ([_control isKindOfClass:WKDateTimePicker.class])
- return [(WKDateTimePicker *)_control.get() calendarType];
-
- if ([_control isKindOfClass:WKDateTimePopover.class])
- return [(WKDateTimePopover *)_control.get() calendarType];
-
+ if ([self.control isKindOfClass:WKDateTimePicker.class])
+ return [(WKDateTimePicker *)self.control calendarType];
+ if ([self.control isKindOfClass:WKDateTimePopover.class])
+ return [(WKDateTimePopover *)self.control calendarType];
return nil;
}
@@ -388,6 +361,8 @@
- (void)controlEndEditing
{
+ [self dismissPopoverAnimated:NO];
+ [_viewController.get().innerControl controlEndEditing];
}
- (UIView *)controlView
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheral.h (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheral.h 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheral.h 2019-04-03 17:06:04 UTC (rev 243808)
@@ -23,6 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+@class UIEvent;
@class UIView;
@protocol WKFormPeripheral
@@ -29,6 +30,8 @@
- (void)beginEditing;
- (void)endEditing;
- (UIView *)assistantView;
+@optional
+- (BOOL)handleKeyEvent:(UIEvent *)event;
@end
@protocol WKFormControl
@@ -35,4 +38,6 @@
- (UIView *)controlView;
- (void)controlBeginEditing;
- (void)controlEndEditing;
+@optional
+- (BOOL)controlHandleKeyEvent:(UIEvent *)event;
@end
Copied: trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.h (from rev 243807, trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h) (0 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.h 2019-04-03 17:06:04 UTC (rev 243808)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#if PLATFORM(IOS_FAMILY)
+
+#import "WKFormPeripheral.h"
+#import <wtf/Forward.h>
+
+@class WKContentView;
+
+@interface WKFormPeripheralBase : NSObject <WKFormPeripheral>
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initWithView:(WKContentView *)view control:(RetainPtr<NSObject <WKFormControl>>&&)control NS_DESIGNATED_INITIALIZER;
+
+- (void)beginEditing;
+- (void)endEditing;
+- (UIView *)assistantView;
+- (BOOL)handleKeyEvent:(UIEvent *)event;
+
+@property (nonatomic, readonly) WKContentView *view;
+@property (nonatomic, readonly) NSObject <WKFormControl> *control;
+@property (nonatomic, readonly, getter=isEditing) BOOL editing;
+
+@end
+
+#endif
Added: trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.mm (0 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormPeripheralBase.mm 2019-04-03 17:06:04 UTC (rev 243808)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 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 "WKFormPeripheralBase.h"
+
+#if PLATFORM(IOS_FAMILY)
+
+#import "WKContentView.h"
+#import <pal/spi/cocoa/IOKitSPI.h>
+#import <wtf/RetainPtr.h>
+
+@implementation WKFormPeripheralBase {
+ RetainPtr<NSObject <WKFormControl>> _control;
+}
+
+- (instancetype)initWithView:(WKContentView *)view control:(RetainPtr<NSObject <WKFormControl>>&&)control
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _view = view;
+ _control = WTFMove(control);
+ return self;
+}
+
+- (void)beginEditing
+{
+ _editing = YES;
+ [_control controlBeginEditing];
+}
+
+- (void)endEditing
+{
+ _editing = NO;
+ [_control controlEndEditing];
+}
+
+- (UIView *)assistantView
+{
+ return [_control controlView];
+}
+
+- (NSObject <WKFormControl> *)control
+{
+ return _control.get();
+}
+
+- (BOOL)handleKeyEvent:(UIEvent *)event
+{
+ ASSERT(event._hidEvent);
+ if ([_control respondsToSelector:@selector(controlHandleKeyEvent:)]) {
+ if ([_control controlHandleKeyEvent:event])
+ return YES;
+ }
+ if (!event._isKeyDown)
+ return NO;
+ UIPhysicalKeyboardEvent *keyEvent = (UIPhysicalKeyboardEvent *)event;
+ if (keyEvent._inputFlags & kUIKeyboardInputModifierFlagsChanged)
+ return NO;
+ if (_editing && (keyEvent._keyCode == kHIDUsage_KeyboardEscape || [keyEvent._unmodifiedInput isEqualToString:UIKeyInputEscape])) {
+ [_view accessoryDone];
+ return YES;
+ }
+ return NO;
+}
+
+@end
+
+#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.h (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.h 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.h 2019-04-03 17:06:04 UTC (rev 243808)
@@ -27,7 +27,7 @@
#import "FocusedElementInformation.h"
#import "UIKitSPI.h"
-#import "WKFormPeripheral.h"
+#import "WKFormPeripheralBase.h"
#import "WKFormPopover.h"
#import <UIKit/UIPickerView.h>
@@ -35,7 +35,7 @@
@class WKContentView;
-@interface WKFormSelectControl : NSObject<WKFormPeripheral>
+@interface WKFormSelectControl : WKFormPeripheralBase
- (instancetype)initWithView:(WKContentView *)view;
@end
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.mm (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.mm 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.mm 2019-04-03 17:06:04 UTC (rev 243808)
@@ -65,9 +65,6 @@
- (instancetype)initWithView:(WKContentView *)view
{
- if (!(self = [super init]))
- return nil;
-
bool hasGroups = false;
for (size_t i = 0; i < view.focusedElementInformation.selectOptions.size(); ++i) {
if (view.focusedElementInformation.selectOptions[i].isGroup) {
@@ -76,31 +73,17 @@
}
}
+ RetainPtr<NSObject <WKFormControl>> control;
if (currentUserInterfaceIdiomIsPad())
- _control = adoptNS([[WKSelectPopover alloc] initWithView:view hasGroups:hasGroups]);
+ control = adoptNS([[WKSelectPopover alloc] initWithView:view hasGroups:hasGroups]);
else if (view.focusedElementInformation.isMultiSelect || hasGroups)
- _control = adoptNS([[WKMultipleSelectPicker alloc] initWithView:view]);
+ control = adoptNS([[WKMultipleSelectPicker alloc] initWithView:view]);
else
- _control = adoptNS([[WKSelectSinglePicker alloc] initWithView:view]);
-
- return self;
-}
+ control = adoptNS([[WKSelectSinglePicker alloc] initWithView:view]);
-- (UIView *)assistantView
-{
- return [_control controlView];
+ return [super initWithView:view control:WTFMove(control)];
}
-- (void)beginEditing
-{
- [_control controlBeginEditing];
-}
-
-- (void)endEditing
-{
- [_control controlEndEditing];
-}
-
@end
@implementation WKFormSelectControl(WKTesting)
@@ -107,16 +90,15 @@
- (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection
{
- if ([_control respondsToSelector:@selector(selectRow:inComponent:extendingSelection:)])
- [id<WKSelectTesting>(_control.get()) selectRow:rowIndex inComponent:componentIndex extendingSelection:extendingSelection];
+ if ([self.control respondsToSelector:@selector(selectRow:inComponent:extendingSelection:)])
+ [id<WKSelectTesting>(self.control) selectRow:rowIndex inComponent:componentIndex extendingSelection:extendingSelection];
}
- (NSString *)selectFormPopoverTitle
{
- if (![_control isKindOfClass:[WKSelectPopover class]])
+ if (![self.control isKindOfClass:[WKSelectPopover class]])
return nil;
-
- return [(WKSelectPopover *)_control.get() tableViewController].title;
+ return [(WKSelectPopover *)self.control tableViewController].title;
}
@end
Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPopover.mm (243807 => 243808)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPopover.mm 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPopover.mm 2019-04-03 17:06:04 UTC (rev 243808)
@@ -36,6 +36,7 @@
#import "WebPageProxy.h"
#import <UIKit/UIPickerView.h>
#import <WebCore/LocalizedStrings.h>
+#import <pal/spi/cocoa/IOKitSPI.h>
#import <wtf/RetainPtr.h>
using namespace WebKit;
@@ -446,6 +447,7 @@
- (void)controlEndEditing
{
+ [self dismissPopoverAnimated:NO];
}
- (void)_userActionDismissedPopover:(id)sender
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (243807 => 243808)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-04-03 17:03:59 UTC (rev 243807)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-04-03 17:06:04 UTC (rev 243808)
@@ -1589,6 +1589,7 @@
CE1A0BD61A48E6C60054EF74 /* TCCSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1A0BD01A48E6C60054EF74 /* TCCSPI.h */; };
CE1A0BD71A48E6C60054EF74 /* TextInputSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1A0BD11A48E6C60054EF74 /* TextInputSPI.h */; };
CE5B4C8821B73D870022E64F /* WKSyntheticFlagsChangedWebEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = CE5B4C8621B73D870022E64F /* WKSyntheticFlagsChangedWebEvent.h */; };
+ CE70EE5D22442BD000E0AF0F /* WKFormPeripheralBase.h in Headers */ = {isa = PBXBuildFile; fileRef = CE70EE5C22442BD000E0AF0F /* WKFormPeripheralBase.h */; };
CEC8F9CB1FDF5870002635E7 /* WKWebProcessPlugInNodeHandlePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = CEC8F9CA1FDF5870002635E7 /* WKWebProcessPlugInNodeHandlePrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
CEDA12E3152CD1B300D9E08D /* WebAlternativeTextClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CEDA12DE152CCAE800D9E08D /* WebAlternativeTextClient.h */; };
CEE4AE2B1A5DCF430002F49B /* UIKitSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CEE4AE2A1A5DCF430002F49B /* UIKitSPI.h */; };
@@ -4470,6 +4471,8 @@
CE1A0BD11A48E6C60054EF74 /* TextInputSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextInputSPI.h; sourceTree = "<group>"; };
CE5B4C8621B73D870022E64F /* WKSyntheticFlagsChangedWebEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKSyntheticFlagsChangedWebEvent.h; path = ios/WKSyntheticFlagsChangedWebEvent.h; sourceTree = "<group>"; };
CE5B4C8721B73D870022E64F /* WKSyntheticFlagsChangedWebEvent.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKSyntheticFlagsChangedWebEvent.mm; path = ios/WKSyntheticFlagsChangedWebEvent.mm; sourceTree = "<group>"; };
+ CE70EE5A22442BB300E0AF0F /* WKFormPeripheralBase.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormPeripheralBase.mm; path = ios/forms/WKFormPeripheralBase.mm; sourceTree = "<group>"; };
+ CE70EE5C22442BD000E0AF0F /* WKFormPeripheralBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFormPeripheralBase.h; path = ios/forms/WKFormPeripheralBase.h; sourceTree = "<group>"; };
CEC8F9CA1FDF5870002635E7 /* WKWebProcessPlugInNodeHandlePrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKWebProcessPlugInNodeHandlePrivate.h; sourceTree = "<group>"; };
CEDA12DE152CCAE800D9E08D /* WebAlternativeTextClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAlternativeTextClient.h; sourceTree = "<group>"; };
CEDA12DF152CCAE800D9E08D /* WebAlternativeTextClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebAlternativeTextClient.cpp; sourceTree = "<group>"; };
@@ -8731,6 +8734,8 @@
C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */,
C54256B018BEC18B00DE4179 /* WKFormInputControl.mm */,
C54256B118BEC18B00DE4179 /* WKFormPeripheral.h */,
+ CE70EE5C22442BD000E0AF0F /* WKFormPeripheralBase.h */,
+ CE70EE5A22442BB300E0AF0F /* WKFormPeripheralBase.mm */,
C54256B218BEC18B00DE4179 /* WKFormPopover.h */,
C54256B318BEC18B00DE4179 /* WKFormPopover.mm */,
C54256B418BEC18C00DE4179 /* WKFormSelectControl.h */,
@@ -9855,6 +9860,7 @@
E548EBD121015F0E00BE3C32 /* WKFormColorPicker.h in Headers */,
C54256B518BEC18C00DE4179 /* WKFormInputControl.h in Headers */,
C54256B718BEC18C00DE4179 /* WKFormPeripheral.h in Headers */,
+ CE70EE5D22442BD000E0AF0F /* WKFormPeripheralBase.h in Headers */,
C54256B818BEC18C00DE4179 /* WKFormPopover.h in Headers */,
C54256BA18BEC18C00DE4179 /* WKFormSelectControl.h in Headers */,
0F08CF521D63C13A00B48DF1 /* WKFormSelectPicker.h in Headers */,