Diff
Modified: trunk/Source/WebCore/en.lproj/Localizable.strings (261657 => 261658)
--- trunk/Source/WebCore/en.lproj/Localizable.strings 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebCore/en.lproj/Localizable.strings 2020-05-13 21:54:51 UTC (rev 261658)
@@ -211,9 +211,6 @@
/* Title for file button used in HTML forms for media files */
"Choose Media (Single)" = "Choose Media (Single)";
-/* Clear button in date input popover */
-"Clear Button Date Popover" = "Clear";
-
/* menu item in Recent Searches menu that empties menu's contents */
"Clear Recent Searches" = "Clear Recent Searches";
@@ -1327,6 +1324,9 @@
/* HTTP result code string */
"requested range not satisfiable" = "requested range not satisfiable";
+/* Reset button in date input popover */
+"Reset Button Date/Time Context Menu" = "Reset";
+
/* HTTP result code string */
"reset content" = "reset content";
Modified: trunk/Source/WebKit/ChangeLog (261657 => 261658)
--- trunk/Source/WebKit/ChangeLog 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/ChangeLog 2020-05-13 21:54:51 UTC (rev 261658)
@@ -1,3 +1,59 @@
+2020-05-13 Megan Gardner <[email protected]>
+
+ Change Date/Time popovers to contextMenus.
+ https://bugs.webkit.org/show_bug.cgi?id=211825
+ <rdar://problem/63102524>
+
+ Reviewed by Wenson Hsieh.
+
+ Update the Date/Time picker to use UIContextMenus instead of popovers.
+ Removed all the unneeded popover code.
+ Renamed WKFormInputControl to WKDateTimeInputControl because it was only used
+ for date and time controls, unneccessary abstraction.
+ We need to ensure the poisition information is up to date before presenting
+ the context menu, or the position it will be presented from can be stale.
+
+ * SourcesCocoa.txt:
+ * UIProcess/ios/WKContentViewInteraction.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView _shouldShowAutomaticKeyboardUIIgnoringInputMode]):
+ (-[WKContentView requiresAccessoryView]):
+ (-[WKContentView _updateAccessory]):
+ (mayContainSelectableText):
+ (createInputPeripheralWithView):
+ (-[WKContentView inputLabelText]):
+ (-[WKContentView _removeContextMenuViewIfPossible]):
+ (-[WKContentView inputLabelTextForViewController:]):
+ (-[WKContentView formInputControl]):
+ (-[WKContentView setTimePickerValueToHour:minute:]):
+ (-[WKContentView timePickerValueHour]):
+ (-[WKContentView timePickerValueMinute]):
+ * UIProcess/ios/forms/WKDateTimeInputControl.h: Renamed from Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h.
+ * UIProcess/ios/forms/WKDateTimeInputControl.mm: Renamed from Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm.
+ (-[WKDateTimeContextMenuViewController init]):
+ (-[WKDateTimeContextMenuViewController preferredContentSize]):
+ (-[WKDateTimePicker initWithView:datePickerMode:]):
+ (-[WKDateTimePicker contextMenuInteraction:previewForHighlightingMenuWithConfiguration:]):
+ (-[WKDateTimePicker _contextMenuInteraction:styleForMenuWithConfiguration:]):
+ (-[WKDateTimePicker contextMenuInteraction:configurationForMenuAtLocation:]):
+ (-[WKDateTimePicker contextMenuInteraction:willEndForConfiguration:animator:]):
+ (-[WKDateTimePicker removeContextMenuInteraction]):
+ (-[WKDateTimePicker ensureContextMenuInteraction]):
+ (-[WKDateTimePicker showDateTimePicker]):
+ (-[WKDateTimePicker reset:]):
+ (-[WKDateTimePicker calendarType]):
+ (-[WKDateTimePicker dealloc]):
+ (-[WKDateTimePicker setDateTimePickerToInitialValue]):
+ (-[WKDateTimePicker controlBeginEditing]):
+ (-[WKDateTimePicker viewController]):
+ (-[WKDateTimePicker controlEndEditing]):
+ (-[WKDateTimeInputControl initWithView:]):
+ (-[WKDateTimeInputControl setTimePickerHour:minute:]):
+ (-[WKDateTimeInputControl dateTimePickerCalendarType]):
+ (-[WKDateTimeInputControl timePickerValueHour]):
+ (-[WKDateTimeInputControl timePickerValueMinute]):
+ * WebKit.xcodeproj/project.pbxproj:
+
2020-05-13 Wenson Hsieh <[email protected]>
Unreviewed, fix tvOS and watchOS builds after r261638
Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (261657 => 261658)
--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h 2020-05-13 21:54:51 UTC (rev 261658)
@@ -1152,10 +1152,12 @@
typedef NS_ENUM(NSUInteger, _UIContextMenuLayout) {
_UIContextMenuLayoutActionsOnly = 1,
_UIContextMenuLayoutCompactMenu = 3,
+ _UIContextMenuLayoutAutomatic = 100,
};
@interface _UIContextMenuStyle : NSObject <NSCopying>
@property (nonatomic) _UIContextMenuLayout preferredLayout;
+@property (nonatomic) BOOL hasInteractivePreview;
+ (instancetype)defaultStyle;
@end
Modified: trunk/Source/WebKit/SourcesCocoa.txt (261657 => 261658)
--- trunk/Source/WebKit/SourcesCocoa.txt 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/SourcesCocoa.txt 2020-05-13 21:54:51 UTC (rev 261658)
@@ -416,11 +416,11 @@
UIProcess/ios/forms/WKAirPlayRoutePicker.mm
UIProcess/ios/forms/WKDatePickerViewController.mm
+UIProcess/ios/forms/WKDateTimeInputControl.mm
UIProcess/ios/forms/WKFileUploadPanel.mm
UIProcess/ios/forms/WKFocusedFormControlView.mm
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
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (261657 => 261658)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h 2020-05-13 21:54:51 UTC (rev 261658)
@@ -101,9 +101,9 @@
@class WebEvent;
@class WKActionSheetAssistant;
@class WKContextMenuElementInfo;
+@class WKDateTimeInputControl;
@class WKDrawingCoordinator;
@class WKFocusedFormControlView;
-@class WKFormInputControl;
@class WKFormInputSession;
@class WKHighlightLongPressGestureRecognizer;
@class WKMouseGestureRecognizer;
@@ -542,6 +542,8 @@
- (BOOL)hasHiddenContentEditable;
- (void)generateSyntheticEditingCommand:(WebKit::SyntheticEditingCommandType)command;
+- (NSString *)inputLabelText;
+
- (void)preserveFocus;
- (void)releaseFocus;
@@ -627,7 +629,7 @@
@property (nonatomic, readonly) NSString *textContentTypeForTesting;
@property (nonatomic, readonly) NSString *selectFormPopoverTitle;
@property (nonatomic, readonly) NSString *formInputLabel;
-@property (nonatomic, readonly) WKFormInputControl *formInputControl;
+@property (nonatomic, readonly) WKDateTimeInputControl *dateTimeInputControl;
@end
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (261657 => 261658)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2020-05-13 21:54:51 UTC (rev 261658)
@@ -50,10 +50,10 @@
#import "WKContextMenuElementInfoInternal.h"
#import "WKContextMenuElementInfoPrivate.h"
#import "WKDatePickerViewController.h"
+#import "WKDateTimeInputControl.h"
#import "WKDrawingCoordinator.h"
#import "WKError.h"
#import "WKFocusedFormControlView.h"
-#import "WKFormInputControl.h"
#import "WKFormSelectControl.h"
#import "WKFrameInfoInternal.h"
#import "WKHighlightLongPressGestureRecognizer.h"
@@ -1906,16 +1906,15 @@
switch (_focusedElementInformation.elementType) {
case WebKit::InputType::None:
case WebKit::InputType::Drawing:
+ case WebKit::InputType::Date:
+ case WebKit::InputType::Month:
+ case WebKit::InputType::DateTimeLocal:
+ case WebKit::InputType::Time:
return NO;
case WebKit::InputType::Select:
#if ENABLE(INPUT_TYPE_COLOR)
case WebKit::InputType::Color:
#endif
- case WebKit::InputType::Date:
- case WebKit::InputType::Month:
- case WebKit::InputType::DateTimeLocal:
- case WebKit::InputType::Time:
- return !WebKit::currentUserInterfaceIdiomIsPad();
default:
return !_focusedElementInformation.isReadOnly;
}
@@ -2918,6 +2917,10 @@
switch (_focusedElementInformation.elementType) {
case WebKit::InputType::None:
case WebKit::InputType::Drawing:
+ case WebKit::InputType::Date:
+ case WebKit::InputType::DateTimeLocal:
+ case WebKit::InputType::Month:
+ case WebKit::InputType::Time:
return NO;
case WebKit::InputType::Text:
case WebKit::InputType::Password:
@@ -2930,12 +2933,8 @@
case WebKit::InputType::ContentEditable:
case WebKit::InputType::TextArea:
case WebKit::InputType::Select:
- case WebKit::InputType::Date:
case WebKit::InputType::DateTime:
- case WebKit::InputType::DateTimeLocal:
- case WebKit::InputType::Month:
- case WebKit:: InputType::Week:
- case WebKit::InputType::Time:
+ case WebKit::InputType::Week:
#if ENABLE(INPUT_TYPE_COLOR)
case WebKit::InputType::Color:
#endif
@@ -4406,8 +4405,8 @@
switch (_focusedElementInformation.elementType) {
case WebKit::InputType::Date:
+ case WebKit::InputType::DateTimeLocal:
case WebKit::InputType::Month:
- case WebKit::InputType::DateTimeLocal:
case WebKit::InputType::Time:
[accessoryView setClearVisible:YES];
return;
@@ -5733,7 +5732,6 @@
return false;
// The following types look and behave like a text field.
case WebKit::InputType::ContentEditable:
- case WebKit::InputType::DateTime:
case WebKit::InputType::Email:
case WebKit::InputType::Number:
case WebKit::InputType::NumberPad:
@@ -5743,6 +5741,7 @@
case WebKit::InputType::Text:
case WebKit::InputType::TextArea:
case WebKit::InputType::URL:
+ case WebKit::InputType::DateTime:
case WebKit::InputType::Week:
return true;
}
@@ -5805,8 +5804,13 @@
case WebKit::InputType::Color:
return adoptNS([[WKFormColorControl alloc] initWithView:view]);
#endif // ENABLE(INPUT_TYPE_COLOR)
+ case WebKit::InputType::Date:
+ case WebKit::InputType::DateTimeLocal:
+ case WebKit::InputType::Month:
+ case WebKit::InputType::Time:
+ return adoptNS([[WKDateTimeInputControl alloc] initWithView:view]);
default:
- return adoptNS([[WKFormInputControl alloc] initWithView:view]);
+ return nil;
}
#endif
}
@@ -6755,6 +6759,20 @@
}
#endif
+- (NSString *)inputLabelText
+{
+ if (!_focusedElementInformation.label.isEmpty())
+ return _focusedElementInformation.label;
+
+ if (!_focusedElementInformation.ariaLabel.isEmpty())
+ return _focusedElementInformation.ariaLabel;
+
+ if (!_focusedElementInformation.title.isEmpty())
+ return _focusedElementInformation.title;
+
+ return _focusedElementInformation.placeholder;
+}
+
#pragma mark - UITextInputMultiDocument
- (BOOL)_restoreFocusWithToken:(id <NSCopying, NSSecureCoding>)token
@@ -7696,10 +7714,14 @@
if ([_actionSheetAssistant hasContextMenuInteraction])
return;
#endif
- // and for the file upload panel.
+ // and for the file upload panel...
if (_fileUploadPanel)
return;
+ // and for the date/time picker.
+ if ([self dateTimeInputControl])
+ return;
+
[std::exchange(_contextMenuHintContainerView, nil) removeFromSuperview];
}
@@ -8315,16 +8337,7 @@
- (NSString *)inputLabelTextForViewController:(PUICQuickboardViewController *)controller
{
- if (!_focusedElementInformation.label.isEmpty())
- return _focusedElementInformation.label;
-
- if (!_focusedElementInformation.ariaLabel.isEmpty())
- return _focusedElementInformation.ariaLabel;
-
- if (!_focusedElementInformation.title.isEmpty())
- return _focusedElementInformation.title;
-
- return _focusedElementInformation.placeholder;
+ return [self inputLabelText];
}
- (NSString *)initialValueForViewController:(PUICQuickboardViewController *)controller
@@ -8699,10 +8712,10 @@
action();
}
-- (WKFormInputControl *)formInputControl
+- (WKDateTimeInputControl *)dateTimeInputControl
{
- if ([_inputPeripheral isKindOfClass:WKFormInputControl.class])
- return (WKFormInputControl *)_inputPeripheral.get();
+ if ([_inputPeripheral isKindOfClass:WKDateTimeInputControl.class])
+ return (WKDateTimeInputControl *)_inputPeripheral.get();
return nil;
}
@@ -8778,8 +8791,8 @@
if ([_presentedFullScreenInputViewController isKindOfClass:[WKTimePickerViewController class]])
[(WKTimePickerViewController *)_presentedFullScreenInputViewController.get() setHour:hour minute:minute];
#elif PLATFORM(IOS_FAMILY)
- if ([_inputPeripheral isKindOfClass:[WKFormInputControl class]])
- [(WKFormInputControl *)_inputPeripheral.get() setTimePickerHour:hour minute:minute];
+ if ([_inputPeripheral isKindOfClass:[WKDateTimeInputControl class]])
+ [(WKDateTimeInputControl *)_inputPeripheral.get() setTimePickerHour:hour minute:minute];
#endif
}
@@ -8786,8 +8799,8 @@
- (double)timePickerValueHour
{
#if PLATFORM(IOS_FAMILY)
- if ([_inputPeripheral isKindOfClass:[WKFormInputControl class]])
- return [(WKFormInputControl *)_inputPeripheral.get() timePickerValueHour];
+ if ([_inputPeripheral isKindOfClass:[WKDateTimeInputControl class]])
+ return [(WKDateTimeInputControl *)_inputPeripheral.get() timePickerValueHour];
#endif
return -1;
}
@@ -8795,8 +8808,8 @@
- (double)timePickerValueMinute
{
#if PLATFORM(IOS_FAMILY)
- if ([_inputPeripheral isKindOfClass:[WKFormInputControl class]])
- return [(WKFormInputControl *)_inputPeripheral.get() timePickerValueMinute];
+ if ([_inputPeripheral isKindOfClass:[WKDateTimeInputControl class]])
+ return [(WKDateTimeInputControl *)_inputPeripheral.get() timePickerValueMinute];
#endif
return -1;
}
Copied: trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.h (from rev 261656, trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h) (0 => 261658)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.h 2020-05-13 21:54:51 UTC (rev 261658)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014 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 "WKFormPeripheralBase.h"
+
+@class WKContentView;
+
+@interface WKDateTimeInputControl : WKFormPeripheralBase
+- (instancetype)initWithView:(WKContentView *)view;
+@end
+
+@interface WKDateTimeInputControl (WKTesting)
+@property (nonatomic, readonly) NSString *dateTimePickerCalendarType;
+@property (nonatomic, readonly) double timePickerValueHour;
+@property (nonatomic, readonly) double timePickerValueMinute;
+- (void)setTimePickerHour:(NSInteger)hour minute:(NSInteger)minute;
+@end
+
+#endif // PLATFORM(IOS_FAMILY)
Copied: trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm (from rev 261656, trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm) (0 => 261658)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm 2020-05-13 21:54:51 UTC (rev 261658)
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2014 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 "WKDateTimeInputControl.h"
+
+#if PLATFORM(IOS_FAMILY)
+
+#import "UserInterfaceIdiom.h"
+#import "WKContentView.h"
+#import "WKContentViewInteraction.h"
+#import "WebPageProxy.h"
+#import <UIKit/UIBarButtonItem.h>
+#import <UIKit/UIDatePicker.h>
+#import <WebCore/LocalizedStrings.h>
+#import <wtf/RetainPtr.h>
+
+using namespace WebKit;
+
+@interface WKDateTimeContextMenuViewController : UIViewController
+@end
+
+@interface WKDateTimePicker : NSObject<WKFormControl
+#if USE(UICONTEXTMENU)
+, UIContextMenuInteractionDelegate
+#endif
+> {
+ RetainPtr<UIDatePicker> _datePicker;
+ NSString *_formatString;
+ NSString *_initialValue;
+ NSTimeInterval _initialValueAsNumber;
+ BOOL _shouldRemoveTimeZoneInformation;
+ BOOL _isTimeInput;
+ WKContentView *_view;
+ CGPoint _interactionPoint;
+ RetainPtr<WKDateTimeContextMenuViewController> _viewController;
+#if USE(UICONTEXTMENU)
+ RetainPtr<UIContextMenuInteraction> _dateTimeContextMenuInteraction;
+#endif
+ BOOL _presenting;
+ BOOL _preservingFocus;
+}
+- (instancetype)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)mode;
+- (WKDateTimeContextMenuViewController *)viewController;
+@property (nonatomic, readonly) NSString *calendarType;
+@property (nonatomic, readonly) double hour;
+@property (nonatomic, readonly) double minute;
+- (void)setHour:(NSInteger)hour minute:(NSInteger)minute;
+@end
+
+#if USE(APPLE_INTERNAL_SDK)
+#import <WebKitAdditions/WKFormInputControlAdditions.mm>
+#endif
+
+
+@implementation WKDateTimeContextMenuViewController
+
+- (CGSize)preferredContentSize
+{
+ return [self.view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
+}
+
+@end
+
+@implementation WKDateTimePicker
+
+static NSString * const kDateFormatString = @"yyyy-MM-dd"; // "2011-01-27".
+static NSString * const kMonthFormatString = @"yyyy-MM"; // "2011-01".
+static NSString * const kTimeFormatString = @"HH:mm"; // "13:45".
+static const NSTimeInterval kMillisecondsPerSecond = 1000;
+
+#if !USE(APPLE_INTERNAL_SDK) && HAVE(UIDATEPICKER_STYLE)
+- (UIDatePickerStyle)datePickerStyle
+{
+ return UIDatePickerStyleAutomatic;
+}
+#endif
+
+- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)mode
+{
+ if (!(self = [super init]))
+ return nil;
+ _view = view;
+ _interactionPoint = [_view lastInteractionLocation];
+ _shouldRemoveTimeZoneInformation = NO;
+ _isTimeInput = NO;
+ switch (view.focusedElementInformation.elementType) {
+ case InputType::Date:
+ _formatString = kDateFormatString;
+ break;
+ case InputType::Month:
+ _formatString = kMonthFormatString;
+ break;
+ case InputType::Time:
+ _formatString = kTimeFormatString;
+ _isTimeInput = YES;
+ break;
+ case InputType::DateTimeLocal:
+ _shouldRemoveTimeZoneInformation = YES;
+ break;
+ default:
+ break;
+ }
+
+ _datePicker = adoptNS([[UIDatePicker alloc] init]);
+
+ [_datePicker setDatePickerMode:mode];
+ [_datePicker setHidden:NO];
+
+#if HAVE(UIDATEPICKER_STYLE)
+ [_datePicker setPreferredDatePickerStyle:[self datePickerStyle]];
+#endif
+ if ([self shouldPresentGregorianCalendar:view.focusedElementInformation])
+ _datePicker.get().calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
+
+ [_datePicker addTarget:self action:@selector(_dateChangeHandler:) forControlEvents:UIControlEventValueChanged];
+
+ return self;
+}
+
+#if USE(UICONTEXTMENU)
+
+- (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForHighlightingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration
+{
+ return [_view _createTargetedContextMenuHintPreviewIfPossible];
+}
+
+- (_UIContextMenuStyle *)_contextMenuInteraction:(UIContextMenuInteraction *)interaction styleForMenuWithConfiguration:(UIContextMenuConfiguration *)configuration
+{
+ _UIContextMenuStyle *style = [_UIContextMenuStyle defaultStyle];
+ style.hasInteractivePreview = YES;
+ style.preferredLayout = _UIContextMenuLayoutAutomatic;
+ return style;
+}
+
+- (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location
+{
+ return [UIContextMenuConfiguration configurationWithIdentifier:@"_UIDatePickerCompactEditor" previewProvider:^{
+
+ _viewController = adoptNS([[WKDateTimeContextMenuViewController alloc] init]);
+ RetainPtr<UINavigationController> navigationController = adoptNS([[UINavigationController alloc] initWithRootViewController:_viewController.get()]);
+ NSString *resetString = WEB_UI_STRING_KEY("Reset", "Reset Button Date/Time Context Menu", "Reset button in date input context menu");
+
+ RetainPtr<UIBarButtonItem> blankBarButton = adoptNS([[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]);
+ RetainPtr<UIBarButtonItem> resetBarButton = adoptNS([[UIBarButtonItem alloc] initWithTitle:resetString style:UIBarButtonItemStylePlain target:self action:@selector(reset:)]);
+
+ [_viewController setToolbarItems:@[blankBarButton.get(), resetBarButton.get()]];
+ [navigationController setToolbarHidden:NO];
+
+ [_viewController setView:_datePicker.get()];
+
+ NSString *titleText = _view.inputLabelText;
+ if (![titleText isEqual:@""]) {
+ RetainPtr<UILabel> title = adoptNS([[UILabel alloc] init]);
+ [title setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]];
+ [title setText:titleText];
+ [title setTextColor:[UIColor secondaryLabelColor]];
+ [title setTextAlignment:NSTextAlignmentNatural];
+ RetainPtr<UIBarButtonItem> titleButton = adoptNS([[UIBarButtonItem alloc] initWithCustomView:title.get()]);
+ [_viewController navigationItem].leftBarButtonItem = titleButton.get();
+ } else
+ [navigationController setNavigationBarHidden:YES animated:NO];
+
+ [navigationController navigationBar].backgroundColor = UIColor.clearColor;
+ [navigationController navigationBar].translucent = NO;
+ [navigationController toolbar].backgroundColor = UIColor.clearColor;
+ [navigationController toolbar].translucent = NO;
+ return navigationController.get();
+ } actionProvider:nil];
+}
+
+- (void)contextMenuInteraction:(UIContextMenuInteraction *)interaction willEndForConfiguration:(UIContextMenuConfiguration *)configuration animator:(id<UIContextMenuInteractionAnimating>)animator
+{
+ [animator addCompletion:^{
+ [_view accessoryDone];
+ }];
+}
+
+- (void)removeContextMenuInteraction
+{
+ if (_dateTimeContextMenuInteraction) {
+ [_view removeInteraction:_dateTimeContextMenuInteraction.get()];
+ _dateTimeContextMenuInteraction = nil;
+ [_view _removeContextMenuViewIfPossible];
+ }
+}
+
+- (void)ensureContextMenuInteraction
+{
+ if (!_dateTimeContextMenuInteraction) {
+ _dateTimeContextMenuInteraction = adoptNS([[UIContextMenuInteraction alloc] initWithDelegate:self]);
+ [_view addInteraction:_dateTimeContextMenuInteraction.get()];
+ }
+}
+
+- (void)showDateTimePicker
+{
+#if HAVE(UICONTEXTMENU_LOCATION)
+ [self ensureContextMenuInteraction];
+ [_dateTimeContextMenuInteraction _presentMenuAtLocation:_interactionPoint];
+#endif
+}
+
+#endif
+
+- (void)reset:(id)sender
+{
+ [self setDateTimePickerToInitialValue];
+ [_view page]->setFocusedElementValue(String());
+}
+
+- (NSString *)calendarType
+{
+ return [_datePicker calendar].calendarIdentifier;
+}
+
+- (double)hour
+{
+ NSCalendar *calendar = [NSCalendar currentCalendar];
+ NSDateComponents *components = [calendar components:NSCalendarUnitHour fromDate:[_datePicker date]];
+
+ return [components hour];
+}
+
+- (double)minute
+{
+ NSCalendar *calendar = [NSCalendar currentCalendar];
+ NSDateComponents *components = [calendar components:NSCalendarUnitMinute fromDate:[_datePicker date]];
+
+ return [components minute];
+}
+
+- (void)dealloc
+{
+ [_datePicker removeTarget:self action:NULL forControlEvents:UIControlEventValueChanged];
+ [self removeContextMenuInteraction];
+ [super dealloc];
+}
+
+- (BOOL)shouldPresentGregorianCalendar:(const FocusedElementInformation&)nodeInfo
+{
+ return nodeInfo.autofillFieldName == WebCore::AutofillFieldName::CcExpMonth
+ || nodeInfo.autofillFieldName == WebCore::AutofillFieldName::CcExp
+ || nodeInfo.autofillFieldName == WebCore::AutofillFieldName::CcExpYear;
+}
+
+- (UIView *)controlView
+{
+ return _datePicker.get();
+}
+
+- (NSInteger)_timeZoneOffsetFromGMT:(NSDate *)date
+{
+ if (!_shouldRemoveTimeZoneInformation)
+ return 0;
+
+ return [_datePicker.get().timeZone secondsFromGMTForDate:date];
+}
+
+- (NSString *)_sanitizeInputValueForFormatter:(NSString *)value
+{
+ // The "time" input type may have seconds and milliseconds information which we
+ // just ignore. For example: "01:56:20.391" is shortened to just "01:56".
+ if (_isTimeInput)
+ return [value substringToIndex:[kTimeFormatString length]];
+
+ return value;
+}
+
+- (void)_dateChangedSetAsNumber
+{
+ NSDate *date = [_datePicker date];
+ [_view updateFocusedElementValueAsNumber:([date timeIntervalSince1970] + [self _timeZoneOffsetFromGMT:date]) * kMillisecondsPerSecond];
+}
+
+- (RetainPtr<NSDateFormatter>)dateFormatterForPicker
+{
+ RetainPtr<NSLocale> englishLocale = adoptNS([[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]);
+ RetainPtr<NSDateFormatter> dateFormatter = adoptNS([[NSDateFormatter alloc] init]);
+ [dateFormatter setTimeZone:_datePicker.get().timeZone];
+ [dateFormatter setDateFormat:_formatString];
+ [dateFormatter setLocale:englishLocale.get()];
+ return dateFormatter;
+}
+
+- (void)_dateChangedSetAsString
+{
+ // Force English locale because that is what HTML5 value parsing expects.
+ RetainPtr<NSDateFormatter> dateFormatter = [self dateFormatterForPicker];
+ [_view updateFocusedElementValue:[dateFormatter stringFromDate:[_datePicker date]]];
+}
+
+- (void)_dateChanged
+{
+ // Internally, DOMHTMLInputElement setValueAs* each take different values for
+ // different date types. It is sometimes easier to set the date in different ways:
+ // - use setValueAsString for "date", "month", and "time".
+ // - use setValueAsNumber for "datetime-local".
+ if (_formatString)
+ [self _dateChangedSetAsString];
+ else
+ [self _dateChangedSetAsNumber];
+}
+
+- (void)_dateChangeHandler:(id)sender
+{
+ [self _dateChanged];
+}
+
+- (void)setDateTimePickerToInitialValue
+{
+ if ([_initialValue isEqual: @""]) {
+ [_datePicker setDate:[NSDate date]];
+ [self _dateChanged];
+ } else if (_formatString) {
+ // Convert the string value to a date object for the fields where we have a format string.
+ RetainPtr<NSDateFormatter> dateFormatter = [self dateFormatterForPicker];
+ NSDate *parsedDate = [dateFormatter dateFromString:[self _sanitizeInputValueForFormatter:_initialValue]];
+ [_datePicker setDate:parsedDate ? parsedDate : [NSDate date]];
+ } else {
+ // Convert the number value to a date object for the fields affected by timezones.
+ NSTimeInterval secondsSince1970 = _initialValueAsNumber / kMillisecondsPerSecond;
+ NSInteger timeZoneOffset = [self _timeZoneOffsetFromGMT:[NSDate dateWithTimeIntervalSince1970:secondsSince1970]];
+ NSTimeInterval adjustedSecondsSince1970 = secondsSince1970 - timeZoneOffset;
+ [_datePicker setDate:[NSDate dateWithTimeIntervalSince1970:adjustedSecondsSince1970]];
+ }
+}
+
+- (void)controlBeginEditing
+{
+
+ if (_presenting)
+ return;
+ _presenting = YES;
+
+ if (!_preservingFocus && (_view.focusedElementInformation.elementType == InputType::Time || _view.focusedElementInformation.elementType == InputType::DateTimeLocal)) {
+ [_view preserveFocus];
+ _preservingFocus = YES;
+ }
+
+ // Set the time zone in case it changed.
+ _datePicker.get().timeZone = [NSTimeZone localTimeZone];
+
+ // Currently no value for the <input>. Start the picker with the current time.
+ // Also, update the actual <input> value.
+ _initialValue = _view.focusedElementInformation.value;
+ _initialValueAsNumber = _view.focusedElementInformation.valueAsNumber;
+ [self setDateTimePickerToInitialValue];
+
+ WebKit::InteractionInformationRequest positionInformationRequest { WebCore::IntPoint(_view.focusedElementInformation.lastInteractionLocation) };
+ [_view doAfterPositionInformationUpdate:^(WebKit::InteractionInformationAtPosition interactionInformation) {
+ [self showDateTimePicker];
+ } forRequest:positionInformationRequest];
+
+}
+
+- (void)setHour:(NSInteger)hour minute:(NSInteger)minute
+{
+ NSString *timeString = [NSString stringWithFormat:@"%.2ld:%.2ld", (long)hour, (long)minute];
+ [_datePicker setDate:[[self dateFormatterForPicker] dateFromString:timeString]];
+ [self _dateChanged];
+}
+
+- (WKDateTimeContextMenuViewController *)viewController
+{
+ return _viewController.get();
+}
+
+- (void)controlEndEditing
+{
+ _presenting = NO;
+ if (_preservingFocus) {
+ [_view releaseFocus];
+ _preservingFocus = NO;
+ }
+ [self removeContextMenuInteraction];
+}
+@end
+
+@implementation WKDateTimeInputControl
+
+- (instancetype)initWithView:(WKContentView *)view
+{
+ UIDatePickerMode mode;
+
+ switch (view.focusedElementInformation.elementType) {
+ 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;
+ }
+
+ return [super initWithView:view control:adoptNS([[WKDateTimePicker alloc] initWithView:view datePickerMode:mode])];
+}
+
+@end
+
+@implementation WKDateTimeInputControl (WKTesting)
+
+- (void)setTimePickerHour:(NSInteger)hour minute:(NSInteger)minute
+{
+ if ([self.control isKindOfClass:WKDateTimePicker.class])
+ [(WKDateTimePicker *)self.control setHour:hour minute:minute];
+}
+
+- (NSString *)dateTimePickerCalendarType
+{
+ if ([self.control isKindOfClass:WKDateTimePicker.class])
+ return [(WKDateTimePicker *)self.control calendarType];
+ return nil;
+}
+
+- (double)timePickerValueHour
+{
+ if ([self.control isKindOfClass:WKDateTimePicker.class])
+ return [(WKDateTimePicker *)self.control hour];
+ return -1;
+}
+
+- (double)timePickerValueMinute
+{
+ if ([self.control isKindOfClass:WKDateTimePicker.class])
+ return [(WKDateTimePicker *)self.control minute];
+ return -1;
+}
+
+@end
+
+#endif // PLATFORM(IOS_FAMILY)
Deleted: trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h (261657 => 261658)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.h 2020-05-13 21:54:51 UTC (rev 261658)
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 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 "WKFormPeripheralBase.h"
-
-@class WKContentView;
-
-@interface WKFormInputControl : WKFormPeripheralBase
-- (instancetype)initWithView:(WKContentView *)view;
-@end
-
-@interface WKFormInputControl (WKTesting)
-@property (nonatomic, readonly) NSString *dateTimePickerCalendarType;
-@property (nonatomic, readonly) double timePickerValueHour;
-@property (nonatomic, readonly) double timePickerValueMinute;
-- (void)setTimePickerHour:(NSInteger)hour minute:(NSInteger)minute;
-@end
-
-#endif // PLATFORM(IOS_FAMILY)
Deleted: trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm (261657 => 261658)
--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormInputControl.mm 2020-05-13 21:54:51 UTC (rev 261658)
@@ -1,502 +0,0 @@
-/*
- * Copyright (C) 2014 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 "WKFormInputControl.h"
-
-#if PLATFORM(IOS_FAMILY)
-
-#import "UserInterfaceIdiom.h"
-#import "WKContentView.h"
-#import "WKContentViewInteraction.h"
-#import "WKFormPopover.h"
-#import "WebPageProxy.h"
-#import <UIKit/UIBarButtonItem.h>
-#import <UIKit/UIDatePicker.h>
-#import <WebCore/LocalizedStrings.h>
-#import <wtf/RetainPtr.h>
-
-using namespace WebKit;
-
-@interface WKDateTimePopoverViewController : UIViewController {
- RetainPtr<NSObject<WKFormControl>> _innerControl;
-}
-- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)datePickerMode;
-- (NSObject<WKFormControl> *)innerControl;
-@end
-
-@interface WKDateTimePopover : WKFormRotatingAccessoryPopover<WKFormControl> {
- RetainPtr<WKDateTimePopoverViewController> _viewController;
- WKContentView *_view;
- BOOL _presenting;
- BOOL _preservingFocus;
-}
-- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)mode;
-- (WKDateTimePopoverViewController *)viewController;
-@property (nonatomic, readonly) NSString *calendarType;
-@property (nonatomic, readonly) double hour;
-@property (nonatomic, readonly) double minute;
-- (void)setHour:(NSInteger)hour minute:(NSInteger)minute;
-@end
-
-@interface WKDateTimePicker : NSObject<WKFormControl> {
- RetainPtr<UIDatePicker> _datePicker;
- NSString *_formatString;
- BOOL _shouldRemoveTimeZoneInformation;
- BOOL _isTimeInput;
- WKContentView* _view;
-}
-- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)mode;
-- (UIDatePicker *)datePicker;
-
-@end
-
-#if USE(APPLE_INTERNAL_SDK)
-#import <WebKitAdditions/WKFormInputControlAdditions.mm>
-#endif
-
-@implementation WKDateTimePicker
-
-static NSString * const kDateFormatString = @"yyyy-MM-dd"; // "2011-01-27".
-static NSString * const kMonthFormatString = @"yyyy-MM"; // "2011-01".
-static NSString * const kTimeFormatString = @"HH:mm"; // "13:45".
-static const NSTimeInterval kMillisecondsPerSecond = 1000;
-
-- (UIDatePicker *)datePicker
-{
- return _datePicker.get();
-}
-
-#if !USE(APPLE_INTERNAL_SDK) && HAVE(UIDATEPICKER_STYLE)
-- (UIDatePickerStyle)datePickerStyle
-{
- return UIDatePickerStyleAutomatic;
-}
-#endif
-
-- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)mode
-{
- if (!(self = [super init]))
- return nil;
-
- _view = view;
- _shouldRemoveTimeZoneInformation = NO;
- _isTimeInput = NO;
- switch (view.focusedElementInformation.elementType) {
- case InputType::Date:
- _formatString = kDateFormatString;
- break;
- case InputType::Month:
- _formatString = kMonthFormatString;
- break;
- case InputType::Time:
- _formatString = kTimeFormatString;
- _isTimeInput = YES;
- break;
- case InputType::DateTimeLocal:
- _shouldRemoveTimeZoneInformation = YES;
- break;
- default:
- break;
- }
-
- _datePicker = adoptNS([[UIDatePicker alloc] init]);
-
- [_datePicker setDatePickerMode:mode];
- [_datePicker setHidden:NO];
-
-#if HAVE(UIDATEPICKER_STYLE)
- [_datePicker setPreferredDatePickerStyle:[self datePickerStyle]];
-#endif
-
- auto size = [_datePicker sizeThatFits:CGSizeMake(view.frame.size.width, 0)];
- [_datePicker setFrame:CGRectMake(0, 0, size.width, size.height)];
-
- if ([self shouldPresentGregorianCalendar:view.focusedElementInformation])
- _datePicker.get().calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
-
- [_datePicker addTarget:self action:@selector(_dateChangeHandler:) forControlEvents:UIControlEventValueChanged];
-
- return self;
-}
-
-- (NSString *)calendarType
-{
- return _datePicker.get().calendar.calendarIdentifier;
-}
-
-- (double)hour
-{
- NSCalendar *calendar = [NSCalendar currentCalendar];
- NSDateComponents *components = [calendar components:NSCalendarUnitHour fromDate:[_datePicker date]];
-
- return [components hour];
-}
-
-- (double)minute
-{
- NSCalendar *calendar = [NSCalendar currentCalendar];
- NSDateComponents *components = [calendar components:NSCalendarUnitMinute fromDate:[_datePicker date]];
-
- return [components minute];
-}
-
-- (void)dealloc
-{
- [_datePicker removeTarget:self action:NULL forControlEvents:UIControlEventValueChanged];
- [super dealloc];
-}
-
-- (BOOL)shouldPresentGregorianCalendar:(const FocusedElementInformation&)nodeInfo
-{
- return nodeInfo.autofillFieldName == WebCore::AutofillFieldName::CcExpMonth
- || nodeInfo.autofillFieldName == WebCore::AutofillFieldName::CcExp
- || nodeInfo.autofillFieldName == WebCore::AutofillFieldName::CcExpYear;
-}
-
-- (UIView *)controlView
-{
- return _datePicker.get();
-}
-
-- (NSInteger)_timeZoneOffsetFromGMT:(NSDate *)date
-{
- if (!_shouldRemoveTimeZoneInformation)
- return 0;
-
- return [_datePicker.get().timeZone secondsFromGMTForDate:date];
-}
-
-- (NSString *)_sanitizeInputValueForFormatter:(NSString *)value
-{
- // The "time" input type may have seconds and milliseconds information which we
- // just ignore. For example: "01:56:20.391" is shortened to just "01:56".
- if (_isTimeInput)
- return [value substringToIndex:[kTimeFormatString length]];
-
- return value;
-}
-
-- (void)_dateChangedSetAsNumber
-{
- NSDate *date = [_datePicker date];
- [_view updateFocusedElementValueAsNumber:([date timeIntervalSince1970] + [self _timeZoneOffsetFromGMT:date]) * kMillisecondsPerSecond];
-}
-
-- (RetainPtr<NSDateFormatter>)dateFormatterForPicker
-{
- RetainPtr<NSLocale> englishLocale = adoptNS([[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]);
- RetainPtr<NSDateFormatter> dateFormatter = adoptNS([[NSDateFormatter alloc] init]);
- [dateFormatter setTimeZone:_datePicker.get().timeZone];
- [dateFormatter setDateFormat:_formatString];
- [dateFormatter setLocale:englishLocale.get()];
- return dateFormatter;
-}
-
-- (void)_dateChangedSetAsString
-{
- // Force English locale because that is what HTML5 value parsing expects.
- RetainPtr<NSDateFormatter> dateFormatter = [self dateFormatterForPicker];
- [_view updateFocusedElementValue:[dateFormatter stringFromDate:[_datePicker date]]];
-}
-
-- (void)_dateChanged
-{
- // Internally, DOMHTMLInputElement setValueAs* each take different values for
- // different date types. It is sometimes easier to set the date in different ways:
- // - use setValueAsString for "date", "month", and "time".
- // - use setValueAsNumber for "datetime-local".
- if (_formatString)
- [self _dateChangedSetAsString];
- else
- [self _dateChangedSetAsNumber];
-}
-
-- (void)_dateChangeHandler:(id)sender
-{
- [self _dateChanged];
-}
-
-- (void)controlBeginEditing
-{
- // Set the time zone in case it changed.
- _datePicker.get().timeZone = [NSTimeZone localTimeZone];
-
- // Currently no value for the <input>. Start the picker with the current time.
- // Also, update the actual <input> value.
- NSString *value = _view.focusedElementInformation.value;
- if (_view.focusedElementInformation.value.isEmpty()) {
- [_datePicker setDate:[NSDate date]];
- [self _dateChanged];
- return;
- }
-
- // Convert the string value to a date object for the fields where we have a format string.
- if (_formatString) {
- value = [self _sanitizeInputValueForFormatter:value];
- RetainPtr<NSDateFormatter> dateFormatter = [self dateFormatterForPicker];
- NSDate *parsedDate = [dateFormatter dateFromString:value];
- [_datePicker setDate:parsedDate ? parsedDate : [NSDate date]];
- return;
- }
-
- // Convert the number value to a date object for the fields affected by timezones.
- NSTimeInterval secondsSince1970 = _view.focusedElementInformation.valueAsNumber / kMillisecondsPerSecond;
- NSInteger timeZoneOffset = [self _timeZoneOffsetFromGMT:[NSDate dateWithTimeIntervalSince1970:secondsSince1970]];
- NSTimeInterval adjustedSecondsSince1970 = secondsSince1970 - timeZoneOffset;
- [_datePicker setDate:[NSDate dateWithTimeIntervalSince1970:adjustedSecondsSince1970]];
-}
-
-- (void)controlEndEditing
-{
-}
-
-- (void)setHour:(NSInteger)hour minute:(NSInteger)minute
-{
- NSString *timeString = [NSString stringWithFormat:@"%.2ld:%.2ld", (long)hour, (long)minute];
- [_datePicker setDate:[[self dateFormatterForPicker] dateFromString:timeString]];
- [self _dateChanged];
-}
-
-@end
-
-// WKFormInputControl
-@implementation WKFormInputControl
-
-- (instancetype)initWithView:(WKContentView *)view
-{
- UIDatePickerMode mode;
-
- switch (view.focusedElementInformation.elementType) {
- 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]);
- else
- control = adoptNS([[WKDateTimePicker alloc] initWithView:view datePickerMode:mode]);
- return [super initWithView:view control:WTFMove(control)];
-}
-
-@end
-
-@implementation WKFormInputControl (WKTesting)
-
-- (void)setTimePickerHour:(NSInteger)hour minute:(NSInteger)minute
-{
- if ([self.control isKindOfClass:WKDateTimePicker.class])
- [(WKDateTimePicker *)self.control setHour:hour minute:minute];
- if ([self.control isKindOfClass:WKDateTimePopover.class])
- [(WKDateTimePopover *)self.control setHour:hour minute:minute];
-}
-
-- (NSString *)dateTimePickerCalendarType
-{
- if ([self.control isKindOfClass:WKDateTimePicker.class])
- return [(WKDateTimePicker *)self.control calendarType];
- if ([self.control isKindOfClass:WKDateTimePopover.class])
- return [(WKDateTimePopover *)self.control calendarType];
- return nil;
-}
-
-- (double)timePickerValueHour
-{
- if ([self.control isKindOfClass:WKDateTimePicker.class])
- return [(WKDateTimePicker *)self.control hour];
- if ([self.control isKindOfClass:WKDateTimePopover.class])
- return [(WKDateTimePopover *)self.control hour];
- return -1;
-}
-
-- (double)timePickerValueMinute
-{
- if ([self.control isKindOfClass:WKDateTimePicker.class])
- return [(WKDateTimePicker *)self.control minute];
- if ([self.control isKindOfClass:WKDateTimePopover.class])
- return [(WKDateTimePopover *)self.control minute];
- return -1;
-}
-
-@end
-
-@implementation WKDateTimePopoverViewController
-
-- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)datePickerMode
-{
- if (!(self = [super init]))
- return nil;
-
- _innerControl = adoptNS([[WKDateTimePicker alloc] initWithView:view datePickerMode:datePickerMode]);
-
- return self;
-}
-
-- (NSObject<WKFormControl> *)innerControl
-{
- return _innerControl.get();
-}
-
-- (void)loadView
-{
- self.view = [_innerControl controlView];
-}
-
-@end
-
-@implementation WKDateTimePopover
-
-- (void)clear:(id)sender
-{
- [_view page]->setFocusedElementValue(String());
-}
-
-- (void)popoverWasDismissed:(WKRotatingPopover *)popover
-{
- [super popoverWasDismissed:popover];
-
- if (popover == self) {
- if (_preservingFocus) {
- [_view releaseFocus];
- _preservingFocus = NO;
- }
- }
-}
-
-- (id)initWithView:(WKContentView *)view datePickerMode:(UIDatePickerMode)mode
-{
- if (!(self = [super initWithView:view]))
- return nil;
-
- _view = view;
- _viewController = adoptNS([[WKDateTimePopoverViewController alloc] initWithView:view datePickerMode:mode]);
- UIDatePicker *datePicker = [(WKDateTimePicker *)_viewController.get().innerControl datePicker];
-
- if (view.focusedElementInformation.elementType == InputType::Month) {
- CGFloat popoverWidth = [datePicker _contentWidth];
- CGFloat popoverHeight = _viewController.get().view.frame.size.height;
- [_viewController setPreferredContentSize:CGSizeMake(popoverWidth, popoverHeight)];
- } else {
- [_viewController setPreferredContentSize:CGSizeMake(datePicker.frame.size.width+16, datePicker.frame.size.height)];
- }
-
- [_viewController setEdgesForExtendedLayout:UIRectEdgeNone];
- [_viewController setTitle:_view.focusedElementInformation.title];
-
- // Always have a navigation controller with a clear button, and a title if the input element has a title.
- RetainPtr<UINavigationController> navigationController = adoptNS([[UINavigationController alloc] initWithRootViewController:_viewController.get()]);
- UINavigationItem *navigationItem = navigationController.get().navigationBar.topItem;
- NSString *clearString = WEB_UI_STRING_KEY("Clear", "Clear Button Date Popover", "Clear button in date input popover");
- ALLOW_DEPRECATED_DECLARATIONS_BEGIN
- UIBarButtonItem *clearButton = [[[UIBarButtonItem alloc] initWithTitle:clearString style:UIBarButtonItemStyleBordered target:self action:@selector(clear:)] autorelease];
- ALLOW_DEPRECATED_DECLARATIONS_END
- [navigationItem setRightBarButtonItem:clearButton];
-
- ALLOW_DEPRECATED_DECLARATIONS_BEGIN
- RetainPtr<UIPopoverController> controller = adoptNS([[UIPopoverController alloc] initWithContentViewController:navigationController.get()]);
- ALLOW_DEPRECATED_DECLARATIONS_END
- [self setPopoverController:controller.get()];
-
- return self;
-}
-
-- (WKDateTimePopoverViewController *)viewController
-{
- return _viewController.get();
-}
-
-- (void)controlBeginEditing
-{
- if (!_presenting) {
- _presenting = YES;
- [self presentPopoverAnimated:NO];
- [_viewController.get().innerControl controlBeginEditing];
-
- if (_view.focusedElementInformation.elementType == InputType::Time || _view.focusedElementInformation.elementType == InputType::DateTimeLocal) {
- _preservingFocus = YES;
- [_view preserveFocus];
- }
- }
-}
-
-- (void)controlEndEditing
-{
- _presenting = NO;
- [self dismissPopoverAnimated:NO];
- [_viewController.get().innerControl controlEndEditing];
-}
-
-- (UIView *)controlView
-{
- return nil;
-}
-
-- (void)setHour:(NSInteger)hour minute:(NSInteger)minute
-{
- WKDateTimePicker *dateTimePicker = (WKDateTimePicker *)self.viewController.innerControl;
- [dateTimePicker setHour:hour minute:minute];
-}
-
-- (NSString *)calendarType
-{
- WKDateTimePicker *dateTimePicker = (WKDateTimePicker *)self.viewController.innerControl;
- return dateTimePicker.datePicker.calendar.calendarIdentifier;
-}
-
-- (double)hour
-{
- WKDateTimePicker *dateTimePicker = (WKDateTimePicker *)self.viewController.innerControl;
- NSCalendar *calendar = [NSCalendar currentCalendar];
- NSDateComponents *components = [calendar components:(NSCalendarUnitHour) fromDate:dateTimePicker.datePicker.date];
-
- return [components hour];
-}
-
-- (double)minute
-{
- WKDateTimePicker *dateTimePicker = (WKDateTimePicker *)self.viewController.innerControl;
- NSCalendar *calendar = [NSCalendar currentCalendar];
- NSDateComponents *components = [calendar components:(NSCalendarUnitMinute) fromDate:dateTimePicker.datePicker.date];
-
- return [components minute];
-}
-
-@end
-
-#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (261657 => 261658)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-05-13 21:54:51 UTC (rev 261658)
@@ -1688,7 +1688,7 @@
C18173612058424700DFDA65 /* DisplayLink.h in Headers */ = {isa = PBXBuildFile; fileRef = C18173602058424700DFDA65 /* DisplayLink.h */; };
C1E123BA20A11573002646F4 /* PDFContextMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = C1E123B920A11572002646F4 /* PDFContextMenu.h */; };
C517388112DF8F4F00EE3F47 /* DragControllerAction.h in Headers */ = {isa = PBXBuildFile; fileRef = C517388012DF8F4F00EE3F47 /* DragControllerAction.h */; };
- C54256B518BEC18C00DE4179 /* WKFormInputControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */; };
+ C54256B518BEC18C00DE4179 /* WKDateTimeInputControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C54256AF18BEC18B00DE4179 /* WKDateTimeInputControl.h */; };
C54256B718BEC18C00DE4179 /* WKFormPeripheral.h in Headers */ = {isa = PBXBuildFile; fileRef = C54256B118BEC18B00DE4179 /* WKFormPeripheral.h */; };
C54256B818BEC18C00DE4179 /* WKFormPopover.h in Headers */ = {isa = PBXBuildFile; fileRef = C54256B218BEC18B00DE4179 /* WKFormPopover.h */; };
C54256BA18BEC18C00DE4179 /* WKFormSelectControl.h in Headers */ = {isa = PBXBuildFile; fileRef = C54256B418BEC18C00DE4179 /* WKFormSelectControl.h */; };
@@ -5025,8 +5025,8 @@
C1E123B920A11572002646F4 /* PDFContextMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PDFContextMenu.h; sourceTree = "<group>"; };
C517388012DF8F4F00EE3F47 /* DragControllerAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DragControllerAction.h; sourceTree = "<group>"; };
C5237F5F12441CA300780472 /* WebEditorClientMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebEditorClientMac.mm; sourceTree = "<group>"; };
- C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFormInputControl.h; path = ios/forms/WKFormInputControl.h; sourceTree = "<group>"; };
- C54256B018BEC18B00DE4179 /* WKFormInputControl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormInputControl.mm; path = ios/forms/WKFormInputControl.mm; sourceTree = "<group>"; };
+ C54256AF18BEC18B00DE4179 /* WKDateTimeInputControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKDateTimeInputControl.h; path = ios/forms/WKDateTimeInputControl.h; sourceTree = "<group>"; };
+ C54256B018BEC18B00DE4179 /* WKDateTimeInputControl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKDateTimeInputControl.mm; path = ios/forms/WKDateTimeInputControl.mm; sourceTree = "<group>"; };
C54256B118BEC18B00DE4179 /* WKFormPeripheral.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFormPeripheral.h; path = ios/forms/WKFormPeripheral.h; sourceTree = "<group>"; };
C54256B218BEC18B00DE4179 /* WKFormPopover.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WKFormPopover.h; path = ios/forms/WKFormPopover.h; sourceTree = "<group>"; };
C54256B318BEC18B00DE4179 /* WKFormPopover.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormPopover.mm; path = ios/forms/WKFormPopover.mm; sourceTree = "<group>"; };
@@ -10267,6 +10267,8 @@
C5FA1ED218E1062200B3F402 /* WKAirPlayRoutePicker.mm */,
2E94FC1420351A6D00974BA0 /* WKDatePickerViewController.h */,
2E94FC1520351A6D00974BA0 /* WKDatePickerViewController.mm */,
+ C54256AF18BEC18B00DE4179 /* WKDateTimeInputControl.h */,
+ C54256B018BEC18B00DE4179 /* WKDateTimeInputControl.mm */,
A58B6F0618FCA733008CBA53 /* WKFileUploadPanel.h */,
A58B6F0718FCA733008CBA53 /* WKFileUploadPanel.mm */,
2E16B6CD2017B7AC008996D6 /* WKFocusedFormControlView.h */,
@@ -10275,8 +10277,6 @@
E5CB07DB20E1678F0022C183 /* WKFormColorControl.mm */,
E548EBCF21015F0E00BE3C32 /* WKFormColorPicker.h */,
E548EBD021015F0E00BE3C32 /* WKFormColorPicker.mm */,
- C54256AF18BEC18B00DE4179 /* WKFormInputControl.h */,
- C54256B018BEC18B00DE4179 /* WKFormInputControl.mm */,
C54256B118BEC18B00DE4179 /* WKFormPeripheral.h */,
CE70EE5C22442BD000E0AF0F /* WKFormPeripheralBase.h */,
CE70EE5A22442BB300E0AF0F /* WKFormPeripheralBase.mm */,
@@ -11527,6 +11527,7 @@
37A709A71E3EA0FD00CA5969 /* WKDataDetectorTypes.h in Headers */,
37A709A91E3EA40C00CA5969 /* WKDataDetectorTypesInternal.h in Headers */,
2E94FC1620351A6D00974BA0 /* WKDatePickerViewController.h in Headers */,
+ C54256B518BEC18C00DE4179 /* WKDateTimeInputControl.h in Headers */,
377EAD4517E2C51A002D193D /* WKDeclarationSpecifiers.h in Headers */,
F44815642387820000982657 /* WKDeferringGestureRecognizer.h in Headers */,
5C359C0D2154739F009E7948 /* WKDeprecated.h in Headers */,
@@ -11559,7 +11560,6 @@
2E16B6CF2017B7AD008996D6 /* WKFocusedFormControlView.h in Headers */,
E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */,
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 */,
Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (261657 => 261658)
--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2020-05-13 21:38:40 UTC (rev 261657)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm 2020-05-13 21:54:51 UTC (rev 261658)
@@ -1230,7 +1230,7 @@
JSObjectRef UIScriptControllerIOS::calendarType() const
{
UIView *contentView = [webView() valueForKeyPath:@"_currentContentView"];
- NSString *calendarTypeString = [contentView valueForKeyPath:@"formInputControl.dateTimePickerCalendarType"];
+ NSString *calendarTypeString = [contentView valueForKeyPath:@"dateTimeInputControl.dateTimePickerCalendarType"];
auto jsContext = m_context->jsContext();
return JSValueToObject(jsContext, [JSValue valueWithObject:calendarTypeString inContext:[JSContext contextWithJSGlobalContextRef:jsContext]].JSValueRef, nullptr);
}