Title: [276325] trunk/Source
Revision
276325
Author
[email protected]
Date
2021-04-20 15:45:13 -0700 (Tue, 20 Apr 2021)

Log Message

[iOS][FCR] Update date/time picker appearance
https://bugs.webkit.org/show_bug.cgi?id=224794
<rdar://problem/76785859>

Reviewed by Wenson Hsieh.

Source/WebCore:

* en.lproj/Localizable.strings:

Remove now unused string.

* platform/LocalizedStrings.cpp:
* platform/LocalizedStrings.h:
* platform/cocoa/LocalizedStringsCocoa.mm:
(WebCore::formControlDoneButtonTitle):

Moved definition out of PLATFORM(WATCHOS) in LocalizedStrings.cpp and
into LocalizedStringsCocoa, so that the "Done" string can be used by
PLATFORM(IOS_FAMILY).

Source/WebKit:

Date/time pickers should have a system material background and should
avoid obscuring the associated element when possible.

* Platform/spi/ios/UIKitSPI.h:

Add new SPI declarations to support date/time picker modifications.

* UIProcess/ios/WKContentViewInteraction.mm:
(createTargetedPreview):
(createFallbackTargetedPreview):
(-[WKContentView _createTargetedContextMenuHintPreviewForFocusedElement]):

Set the UITargetedPreview background color to clearColor when
presenting a date/time picker, so that the presented picker has a
visible material effect. Without this change, the picker would have a
solid white or black background.

* UIProcess/ios/forms/WKDateTimeInputControl.mm:
(-[WKDateTimePickerViewController initWithDelegate:]):
(-[WKDateTimePickerViewController viewDidLoad]):

Add a system material background to the date picker using
UIVisualEffectView.

(-[WKDateTimePickerViewController datePickerChanged:]):
(-[WKDateTimePickerViewController resetButtonPressed:]):
(-[WKDateTimePickerViewController doneButtonPressed:]):
(-[WKDateTimePickerViewController datePickerInsets]):
(-[WKDateTimePickerViewController preferredDatePickerSize]):
(-[WKDateTimePickerViewController preferredContentSize]):
(-[WKDateTimePickerViewController date]):
(-[WKDateTimePickerViewController setDate:]):
(-[WKDateTimePickerViewController setDatePickerMode:]):
(-[WKDateTimePickerViewController timeZone]):
(-[WKDateTimePickerViewController setTimeZone:]):
(-[WKDateTimePickerViewController calendar]):
(-[WKDateTimePicker initWithView:datePickerMode:]):
(-[WKDateTimePicker _preferredEdgeInsetsForDateTimePicker]):

Attempt to present the date picker in a way that does not obscure the
element.

(-[WKDateTimePicker _contextMenuInteraction:styleForMenuWithConfiguration:]):
(-[WKDateTimePicker contextMenuInteraction:configurationForMenuAtLocation:]):
(-[WKDateTimePicker dateTimePickerViewControllerDidChangeDate:]):
(-[WKDateTimePicker dateTimePickerViewControllerDidPressResetButton:]):
(-[WKDateTimePicker dateTimePickerViewControllerDidPressDoneButton:]):
(-[WKDateTimePicker shouldForceGregorianCalendar]):
(-[WKDateTimePicker dealloc]):
(-[WKDateTimePicker _timeZoneOffsetFromGMT:]):
(-[WKDateTimePicker _sanitizeInputValueForFormatter:]):
(-[WKDateTimePicker dateFormatterForPicker]):
(-[WKDateTimePicker _dateChangedSetAsNumber]):
(-[WKDateTimePicker _dateChangedSetAsString]):
(-[WKDateTimePicker setDateTimePickerToInitialValue]):
(-[WKDateTimePicker controlView]):

Updated this method to return nil, matching other form controls that
do not present a keyboard input view (example: <select>).

(-[WKDateTimePicker controlBeginEditing]):
(-[WKDateTimePicker controlEndEditing]):
(-[WKDateTimePicker calendarType]):
(-[WKDateTimePicker hour]):
(-[WKDateTimePicker minute]):
(-[WKDateTimePicker setHour:minute:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (276324 => 276325)


--- trunk/Source/WebCore/ChangeLog	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebCore/ChangeLog	2021-04-20 22:45:13 UTC (rev 276325)
@@ -1,3 +1,24 @@
+2021-04-20  Aditya Keerthi  <[email protected]>
+
+        [iOS][FCR] Update date/time picker appearance
+        https://bugs.webkit.org/show_bug.cgi?id=224794
+        <rdar://problem/76785859>
+
+        Reviewed by Wenson Hsieh.
+
+        * en.lproj/Localizable.strings:
+
+        Remove now unused string.
+
+        * platform/LocalizedStrings.cpp:
+        * platform/LocalizedStrings.h:
+        * platform/cocoa/LocalizedStringsCocoa.mm:
+        (WebCore::formControlDoneButtonTitle):
+
+        Moved definition out of PLATFORM(WATCHOS) in LocalizedStrings.cpp and
+        into LocalizedStringsCocoa, so that the "Done" string can be used by
+        PLATFORM(IOS_FAMILY).
+
 2021-04-20  Fujii Hironori  <[email protected]>
 
         editing/execCommand/insert-image-in-composed-list.html is crashing

Modified: trunk/Source/WebCore/en.lproj/Localizable.strings (276324 => 276325)


--- trunk/Source/WebCore/en.lproj/Localizable.strings	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebCore/en.lproj/Localizable.strings	2021-04-20 22:45:13 UTC (rev 276325)
@@ -331,7 +331,7 @@
 /* Label for the donate with Apple Pay button. */
 "Donate with Apple Pay" = "Donate with Apple Pay";
 
-/* Title of the Done button for zoomed form controls. */
+/* Title of the Done button for form controls. */
 "Done" = "Done";
 
 /* Disallow button title in geolocation prompt */
@@ -586,9 +586,6 @@
 /* Option in segmented control for inserting a numbered list in text editing */
 "Numbered list" = "Numbered list";
 
-/* Title of the OK button in date/time form controls. */
-"OK (OK button title in date/time picker)" = "OK";
-
 /* Title of the OK button for the number pad in zoomed form controls. */
 "OK (OK button title in extra zoomed number pad)" = "OK";
 

Modified: trunk/Source/WebCore/platform/LocalizedStrings.cpp (276324 => 276325)


--- trunk/Source/WebCore/platform/LocalizedStrings.cpp	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebCore/platform/LocalizedStrings.cpp	2021-04-20 22:45:13 UTC (rev 276325)
@@ -1189,11 +1189,6 @@
     return WEB_UI_STRING_KEY("OK", "OK (OK button title in extra zoomed number pad)", "Title of the OK button for the number pad in zoomed form controls.");
 }
 
-String formControlDoneButtonTitle()
-{
-    return WEB_UI_STRING("Done", "Title of the Done button for zoomed form controls.");
-}
-
 String formControlCancelButtonTitle()
 {
     return WEB_UI_STRING("Cancel", "Cancel");

Modified: trunk/Source/WebCore/platform/LocalizedStrings.h (276324 => 276325)


--- trunk/Source/WebCore/platform/LocalizedStrings.h	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebCore/platform/LocalizedStrings.h	2021-04-20 22:45:13 UTC (rev 276325)
@@ -265,6 +265,8 @@
     String fileButtonChooseMultipleMediaFilesLabel();
     String fileButtonNoMediaFileSelectedLabel();
     String fileButtonNoMediaFilesSelectedLabel();
+
+    WEBCORE_EXPORT String formControlDoneButtonTitle();
 #endif
 
     String imageTitle(const String& filename, const IntSize& size);
@@ -334,7 +336,6 @@
 #if PLATFORM(WATCHOS)
     WEBCORE_EXPORT String numberPadOKButtonTitle();
     WEBCORE_EXPORT String formControlCancelButtonTitle();
-    WEBCORE_EXPORT String formControlDoneButtonTitle();
     WEBCORE_EXPORT String formControlHideButtonTitle();
     WEBCORE_EXPORT String formControlGoButtonTitle();
     WEBCORE_EXPORT String formControlSearchButtonTitle();

Modified: trunk/Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm (276324 => 276325)


--- trunk/Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebCore/platform/cocoa/LocalizedStringsCocoa.mm	2021-04-20 22:45:13 UTC (rev 276325)
@@ -267,6 +267,12 @@
 {
     return WEB_UI_STRING("no media selected (multiple)", "Text to display in file button used in HTML forms for media files when no media files are selected and the button allows multiple files to be selected");
 }
+
+
+String formControlDoneButtonTitle()
+{
+    return WEB_UI_STRING("Done", "Title of the Done button for form controls.");
+}
 #endif
 
 String validationMessageTooLongText(int, int maxLength)

Modified: trunk/Source/WebKit/ChangeLog (276324 => 276325)


--- trunk/Source/WebKit/ChangeLog	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebKit/ChangeLog	2021-04-20 22:45:13 UTC (rev 276325)
@@ -1,3 +1,78 @@
+2021-04-20  Aditya Keerthi  <[email protected]>
+
+        [iOS][FCR] Update date/time picker appearance
+        https://bugs.webkit.org/show_bug.cgi?id=224794
+        <rdar://problem/76785859>
+
+        Reviewed by Wenson Hsieh.
+
+        Date/time pickers should have a system material background and should
+        avoid obscuring the associated element when possible.
+
+        * Platform/spi/ios/UIKitSPI.h:
+
+        Add new SPI declarations to support date/time picker modifications.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (createTargetedPreview):
+        (createFallbackTargetedPreview):
+        (-[WKContentView _createTargetedContextMenuHintPreviewForFocusedElement]):
+
+        Set the UITargetedPreview background color to clearColor when
+        presenting a date/time picker, so that the presented picker has a
+        visible material effect. Without this change, the picker would have a
+        solid white or black background.
+
+        * UIProcess/ios/forms/WKDateTimeInputControl.mm:
+        (-[WKDateTimePickerViewController initWithDelegate:]):
+        (-[WKDateTimePickerViewController viewDidLoad]):
+
+        Add a system material background to the date picker using
+        UIVisualEffectView.
+
+        (-[WKDateTimePickerViewController datePickerChanged:]):
+        (-[WKDateTimePickerViewController resetButtonPressed:]):
+        (-[WKDateTimePickerViewController doneButtonPressed:]):
+        (-[WKDateTimePickerViewController datePickerInsets]):
+        (-[WKDateTimePickerViewController preferredDatePickerSize]):
+        (-[WKDateTimePickerViewController preferredContentSize]):
+        (-[WKDateTimePickerViewController date]):
+        (-[WKDateTimePickerViewController setDate:]):
+        (-[WKDateTimePickerViewController setDatePickerMode:]):
+        (-[WKDateTimePickerViewController timeZone]):
+        (-[WKDateTimePickerViewController setTimeZone:]):
+        (-[WKDateTimePickerViewController calendar]):
+        (-[WKDateTimePicker initWithView:datePickerMode:]):
+        (-[WKDateTimePicker _preferredEdgeInsetsForDateTimePicker]):
+
+        Attempt to present the date picker in a way that does not obscure the
+        element.
+
+        (-[WKDateTimePicker _contextMenuInteraction:styleForMenuWithConfiguration:]):
+        (-[WKDateTimePicker contextMenuInteraction:configurationForMenuAtLocation:]):
+        (-[WKDateTimePicker dateTimePickerViewControllerDidChangeDate:]):
+        (-[WKDateTimePicker dateTimePickerViewControllerDidPressResetButton:]):
+        (-[WKDateTimePicker dateTimePickerViewControllerDidPressDoneButton:]):
+        (-[WKDateTimePicker shouldForceGregorianCalendar]):
+        (-[WKDateTimePicker dealloc]):
+        (-[WKDateTimePicker _timeZoneOffsetFromGMT:]):
+        (-[WKDateTimePicker _sanitizeInputValueForFormatter:]):
+        (-[WKDateTimePicker dateFormatterForPicker]):
+        (-[WKDateTimePicker _dateChangedSetAsNumber]):
+        (-[WKDateTimePicker _dateChangedSetAsString]):
+        (-[WKDateTimePicker setDateTimePickerToInitialValue]):
+        (-[WKDateTimePicker controlView]):
+
+        Updated this method to return nil, matching other form controls that
+        do not present a keyboard input view (example: <select>).
+
+        (-[WKDateTimePicker controlBeginEditing]):
+        (-[WKDateTimePicker controlEndEditing]):
+        (-[WKDateTimePicker calendarType]):
+        (-[WKDateTimePicker hour]):
+        (-[WKDateTimePicker minute]):
+        (-[WKDateTimePicker setHour:minute:]):
+
 2021-04-20  Keith Miller  <[email protected]>
 
         FullGCActivityCallback should use the percentage of pages uncompressed in RAM to determine deferral.

Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (276324 => 276325)


--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2021-04-20 22:45:13 UTC (rev 276325)
@@ -215,6 +215,7 @@
 #if HAVE(UIDATEPICKER_STYLE)
 @property (nonatomic, readwrite, assign) UIDatePickerStyle preferredDatePickerStyle;
 #endif
+- (UIEdgeInsets)_appliedInsetsToEdgeOfContent;
 @end
 
 @interface UIDevice ()
@@ -1197,6 +1198,7 @@
 
 typedef NS_ENUM(NSUInteger, _UIContextMenuLayout) {
     _UIContextMenuLayoutActionsOnly = 1,
+    _UIContextMenuLayoutPreviewOnly = 2,
     _UIContextMenuLayoutCompactMenu = 3,
     _UIContextMenuLayoutAutomatic = 100,
 };
@@ -1205,6 +1207,8 @@
 @property (nonatomic) _UIContextMenuLayout preferredLayout;
 @property (nonatomic) UIEdgeInsets preferredEdgeInsets;
 @property (nonatomic) BOOL hasInteractivePreview;
+@property (nonatomic) BOOL prefersCenteredPreviewWhenActionsAreAbsent;
+@property (nonatomic) BOOL ignoresDefaultSizingRules;
 @property (nonatomic, strong) NSArray *preferredBackgroundEffects;
 + (instancetype)defaultStyle;
 @end
@@ -1487,6 +1491,7 @@
 #endif
 
 UIEdgeInsets UIEdgeInsetsAdd(UIEdgeInsets lhs, UIEdgeInsets rhs, UIRectEdge);
+UIEdgeInsets UIEdgeInsetsSubtract(UIEdgeInsets lhs, UIEdgeInsets rhs, UIRectEdge);
 
 extern NSString *const UIBacklightLevelChangedNotification;
 

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (276324 => 276325)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-04-20 22:45:13 UTC (rev 276325)
@@ -8354,7 +8354,7 @@
     return adoptNS([[UITargetedPreview alloc] initWithView:imageView.get() parameters:parameters.get() target:target.get()]);
 }
 
-static RetainPtr<UITargetedPreview> createFallbackTargetedPreview(UIView *rootView, UIView *containerView, const WebCore::FloatRect& frameInRootViewCoordinates)
+static RetainPtr<UITargetedPreview> createFallbackTargetedPreview(UIView *rootView, UIView *containerView, const WebCore::FloatRect& frameInRootViewCoordinates, UIColor *backgroundColor)
 {
     if (!containerView.window)
         return nil;
@@ -8363,6 +8363,9 @@
         return nil;
 
     auto parameters = adoptNS([[UIPreviewParameters alloc] init]);
+    if (backgroundColor)
+        [parameters setBackgroundColor:backgroundColor];
+
     UIView *snapshotView = [rootView resizableSnapshotViewFromRect:frameInRootViewCoordinates afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
 
     CGRect frameInContainerViewCoordinates = [rootView convertRect:frameInRootViewCoordinates toView:containerView];
@@ -8380,8 +8383,20 @@
 
 - (UITargetedPreview *)_createTargetedContextMenuHintPreviewForFocusedElement
 {
-    RetainPtr<UITargetedPreview> targetedPreview = createFallbackTargetedPreview(self, self.containerForContextMenuHintPreviews, _focusedElementInformation.interactionRect);
+    auto backgroundColor = [&]() -> UIColor * {
+        switch (_focusedElementInformation.elementType) {
+        case WebKit::InputType::Date:
+        case WebKit::InputType::Month:
+        case WebKit::InputType::DateTimeLocal:
+        case WebKit::InputType::Time:
+            return UIColor.clearColor;
+        default:
+            return nil;
+        }
+    }();
 
+    auto targetedPreview = createFallbackTargetedPreview(self, self.containerForContextMenuHintPreviews, _focusedElementInformation.interactionRect, backgroundColor);
+
     [self _updateTargetedPreviewScrollViewUsingContainerScrollingNodeID:_focusedElementInformation.containerScrollingNodeID];
 
     _contextMenuInteractionTargetedPreview = WTFMove(targetedPreview);
@@ -8403,7 +8418,7 @@
     }
 
     if (!targetedPreview)
-        targetedPreview = createFallbackTargetedPreview(self, self.containerForContextMenuHintPreviews, _positionInformation.bounds);
+        targetedPreview = createFallbackTargetedPreview(self, self.containerForContextMenuHintPreviews, _positionInformation.bounds, nil);
 
     [self _updateTargetedPreviewScrollViewUsingContainerScrollingNodeID:_positionInformation.containerScrollingNodeID];
 

Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm (276324 => 276325)


--- trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm	2021-04-20 22:42:05 UTC (rev 276324)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm	2021-04-20 22:45:13 UTC (rev 276325)
@@ -33,61 +33,248 @@
 #import "WKContentViewInteraction.h"
 #import "WKWebViewPrivateForTesting.h"
 #import "WebPageProxy.h"
-#import <UIKit/UIBarButtonItem.h>
 #import <UIKit/UIDatePicker.h>
 #import <WebCore/LocalizedStrings.h>
 #import <algorithm>
 #import <wtf/RetainPtr.h>
 
-@interface WKDateTimeContextMenuViewController : UIViewController
+@class WKDateTimePickerViewController;
+
+@protocol WKDateTimePickerViewControllerDelegate <NSObject>
+- (void)dateTimePickerViewControllerDidChangeDate:(WKDateTimePickerViewController *)dateTimePickerViewController;
+- (void)dateTimePickerViewControllerDidPressResetButton:(WKDateTimePickerViewController *)dateTimePickerViewController;
+- (void)dateTimePickerViewControllerDidPressDoneButton:(WKDateTimePickerViewController *)dateTimePickerViewController;
+
+- (BOOL)shouldForceGregorianCalendar;
 @end
 
+@interface WKDateTimePickerViewController : UIViewController
+- (instancetype)initWithDelegate:(id<WKDateTimePickerViewControllerDelegate>)delegate;
+@end
+
+@implementation WKDateTimePickerViewController {
+    CGSize _contentSize;
+
+    RetainPtr<UIDatePicker> _datePicker;
+    WeakObjCPtr<id <WKDateTimePickerViewControllerDelegate>> _delegate;
+}
+
+static const CGFloat kDateTimePickerButtonFontSize = 17;
+static const CGFloat kDateTimePickerToolbarHeight = 44;
+static const CGFloat kDateTimePickerSeparatorHeight = 1;
+static const CGFloat kDateTimePickerViewMargin = 16;
+
+static const CGFloat kDateTimePickerDefaultWidth = 320;
+static const CGFloat kDateTimePickerTimeControlWidth = 218;
+static const CGFloat kDateTimePickerTimeControlHeight = 172;
+
+- (instancetype)initWithDelegate:(id <WKDateTimePickerViewControllerDelegate>)delegate
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _delegate = delegate;
+
+    _datePicker = adoptNS([[UIDatePicker alloc] init]);
+    [_datePicker addTarget:self action:@selector(datePickerChanged:) forControlEvents:UIControlEventValueChanged];
+    [_datePicker setTranslatesAutoresizingMaskIntoConstraints:NO];
+
+    if ([_delegate shouldForceGregorianCalendar])
+        [_datePicker setCalendar:[NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]];
+
+    return self;
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+
+    CGSize contentSize = self.preferredContentSize;
+
+    auto backgroundView = adoptNS([[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemMaterial]]);
+    [backgroundView setFrame:CGRectMake(0, 0, contentSize.width, contentSize.height)];
+    [self.view addSubview:backgroundView.get()];
+
+    [[backgroundView contentView] addSubview:_datePicker.get()];
+
+    CGSize datePickerSize = self.preferredDatePickerSize;
+    UIEdgeInsets datePickerInsets = [self datePickerInsets];
+
+    [NSLayoutConstraint activateConstraints:@[
+        [[_datePicker topAnchor] constraintEqualToAnchor:[backgroundView contentView].topAnchor constant:datePickerInsets.top],
+        [[_datePicker leadingAnchor] constraintEqualToAnchor:[backgroundView contentView].leadingAnchor constant:datePickerInsets.left],
+        [[_datePicker widthAnchor] constraintEqualToConstant:datePickerSize.width],
+        [[_datePicker heightAnchor] constraintEqualToConstant:datePickerSize.height],
+    ]];
+
+    auto toolbarView = adoptNS([[UIView alloc] init]);
+    [toolbarView setTranslatesAutoresizingMaskIntoConstraints:NO];
+    [[backgroundView contentView] addSubview:toolbarView.get()];
+
+    [NSLayoutConstraint activateConstraints:@[
+        [[toolbarView bottomAnchor] constraintEqualToAnchor:[backgroundView contentView].bottomAnchor],
+        [[toolbarView leadingAnchor] constraintEqualToAnchor:[backgroundView contentView].leadingAnchor],
+        [[toolbarView heightAnchor] constraintEqualToConstant:kDateTimePickerToolbarHeight],
+        [[toolbarView widthAnchor] constraintEqualToAnchor:[backgroundView contentView].widthAnchor],
+    ]];
+
+    auto separatorView = adoptNS([[UIView alloc] init]);
+    [separatorView setBackgroundColor:UIColor.separatorColor];
+
+    NSString *resetString = WEB_UI_STRING_KEY("Reset", "Reset Button Date/Time Context Menu", "Reset button in date input context menu");
+    UIButton *resetButton = [UIButton buttonWithType:UIButtonTypeSystem];
+    resetButton.titleLabel.font = [UIFont systemFontOfSize:kDateTimePickerButtonFontSize];
+    [resetButton setTitle:resetString forState:UIControlStateNormal];
+    [resetButton addTarget:self action:@selector(resetButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
+
+    NSString *doneString = WebCore::formControlDoneButtonTitle();
+    UIButton *doneButton = [UIButton buttonWithType:UIButtonTypeSystem];
+    doneButton.titleLabel.font = [UIFont boldSystemFontOfSize:kDateTimePickerButtonFontSize];
+    [doneButton setTitle:doneString forState:UIControlStateNormal];
+    [doneButton addTarget:self action:@selector(doneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
+
+    for (UIView *subview in @[separatorView.get(), resetButton, doneButton]) {
+        subview.translatesAutoresizingMaskIntoConstraints = NO;
+        [toolbarView addSubview:subview];
+    }
+
+    [NSLayoutConstraint activateConstraints:@[
+        [[separatorView topAnchor] constraintEqualToAnchor:[toolbarView topAnchor]],
+        [[separatorView leadingAnchor] constraintEqualToAnchor:[toolbarView leadingAnchor]],
+        [[separatorView heightAnchor] constraintEqualToConstant:kDateTimePickerSeparatorHeight],
+        [[separatorView widthAnchor] constraintEqualToAnchor:[toolbarView widthAnchor]],
+    ]];
+
+    [NSLayoutConstraint activateConstraints:@[
+        [resetButton.leadingAnchor constraintEqualToAnchor:[toolbarView leadingAnchor] constant:kDateTimePickerViewMargin],
+        [resetButton.topAnchor constraintEqualToAnchor:[toolbarView topAnchor]],
+        [resetButton.bottomAnchor constraintEqualToAnchor:[toolbarView bottomAnchor]],
+    ]];
+
+    [NSLayoutConstraint activateConstraints:@[
+        [doneButton.trailingAnchor constraintEqualToAnchor:[toolbarView trailingAnchor] constant:-kDateTimePickerViewMargin],
+        [doneButton.topAnchor constraintEqualToAnchor:[toolbarView topAnchor]],
+        [doneButton.bottomAnchor constraintEqualToAnchor:[toolbarView bottomAnchor]],
+    ]];
+}
+
+- (void)datePickerChanged:(id)sender
+{
+    [_delegate dateTimePickerViewControllerDidChangeDate:self];
+}
+
+- (void)resetButtonPressed:(id)sender
+{
+    [_delegate dateTimePickerViewControllerDidPressResetButton:self];
+}
+
+- (void)doneButtonPressed:(id)sender
+{
+    [_delegate dateTimePickerViewControllerDidPressDoneButton:self];
+}
+
+- (UIEdgeInsets)datePickerInsets
+{
+    UIEdgeInsets expectedInsets = UIEdgeInsetsMake(kDateTimePickerViewMargin, kDateTimePickerViewMargin, kDateTimePickerViewMargin, kDateTimePickerViewMargin);
+    UIEdgeInsets appliedInsets = [_datePicker _appliedInsetsToEdgeOfContent];
+    return UIEdgeInsetsSubtract(expectedInsets, appliedInsets, UIRectEdgeAll);
+}
+
+- (CGSize)preferredDatePickerSize
+{
+    CGSize fittingSize = UILayoutFittingCompressedSize;
+    UILayoutPriority horizontalPriority = UILayoutPriorityFittingSizeLevel;
+    UILayoutPriority verticalPriority = UILayoutPriorityFittingSizeLevel;
+    if ([_datePicker datePickerMode] != UIDatePickerModeTime)
+        fittingSize.width = kDateTimePickerDefaultWidth;
+    else {
+        fittingSize.width = kDateTimePickerTimeControlWidth;
+        fittingSize.height = kDateTimePickerTimeControlHeight;
+        horizontalPriority = UILayoutPriorityRequired;
+        verticalPriority = UILayoutPriorityRequired;
+    }
+
+    CGSize layoutSize = [_datePicker systemLayoutSizeFittingSize:fittingSize withHorizontalFittingPriority:horizontalPriority verticalFittingPriority:verticalPriority];
+    return layoutSize;
+}
+
+- (CGSize)preferredContentSize
+{
+    // Cache the content size to workaround rdar://74749942.
+    if (CGSizeEqualToSize(_contentSize, CGSizeZero)) {
+        CGSize datePickerSize = [self preferredDatePickerSize];
+        UIEdgeInsets datePickerInsets = [self datePickerInsets];
+
+        _contentSize = CGSizeMake(datePickerSize.width + datePickerInsets.left + datePickerInsets.right, datePickerSize.height + kDateTimePickerToolbarHeight + datePickerInsets.top + datePickerInsets.bottom);
+    }
+
+    return _contentSize;
+}
+
+- (NSDate *)date
+{
+    return [_datePicker date];
+}
+
+- (void)setDate:(NSDate *)date
+{
+    [_datePicker setDate:date];
+}
+
+- (void)setDatePickerMode:(UIDatePickerMode)mode
+{
+    [_datePicker setDatePickerMode:mode];
+
+#if HAVE(UIDATEPICKER_STYLE)
+    if (mode == UIDatePickerModeTime || mode == (UIDatePickerMode)UIDatePickerModeYearAndMonth)
+        [_datePicker setPreferredDatePickerStyle:UIDatePickerStyleWheels];
+    else
+        [_datePicker setPreferredDatePickerStyle:UIDatePickerStyleInline];
+#endif
+}
+
+- (NSTimeZone *)timeZone
+{
+    return [_datePicker timeZone];
+}
+
+- (void)setTimeZone:(NSTimeZone *)timeZone
+{
+    return [_datePicker setTimeZone:timeZone];
+}
+
+- (NSCalendar *)calendar
+{
+    return [_datePicker calendar];
+}
+
+@end
+
 @interface WKDateTimePicker : NSObject<WKFormControl
 #if USE(UICONTEXTMENU)
 , UIContextMenuInteractionDelegate
 #endif
+, WKDateTimePickerViewControllerDelegate
 > {
-    RetainPtr<UIDatePicker> _datePicker;
     NSString *_formatString;
     RetainPtr<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;
+    RetainPtr<WKDateTimePickerViewController> _dateTimePickerViewController;
 }
+
 - (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
 
-@implementation WKDateTimeContextMenuViewController
-
-- (CGSize)preferredContentSize
-{
-    // FIXME: Workaround, should be able to be readdressed after <rdar://problem/64143534>
-    UIView *view = self.view.subviews[0];
-    if (UIEdgeInsetsEqualToEdgeInsets(view.layoutMargins, UIEdgeInsetsZero)) {
-        view.translatesAutoresizingMaskIntoConstraints = NO;
-        [view layoutIfNeeded];
-        view.translatesAutoresizingMaskIntoConstraints = YES;
-        view.layoutMargins = UIEdgeInsetsMake(16, 16, 16, 16);
-    }
-    auto size = [view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
-    
-    size.width = std::max<CGFloat>(size.width, 250.0);
-    return size;
-}
-
 @end
 
 @implementation WKDateTimePicker
@@ -97,27 +284,17 @@
 static NSString * const kTimeFormatString = @"HH:mm"; // "13:45".
 static const NSTimeInterval kMillisecondsPerSecond = 1000;
 
-#if HAVE(UIDATEPICKER_STYLE)
-- (UIDatePickerStyle)datePickerStyle
-{
-    switch (_view.focusedElementInformation.elementType) {
-    case WebKit::InputType::Month:
-    case WebKit::InputType::Time:
-        return UIDatePickerStyleWheels;
-    default:
-        return UIDatePickerStyleInline;
-    }
-}
-#endif
+static const CGFloat kDateTimePickerControlMargin = 6;
 
 - (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 WebKit::InputType::Date:
         _formatString = kDateFormatString;
@@ -127,7 +304,6 @@
         break;
     case WebKit::InputType::Time:
         _formatString = kTimeFormatString;
-        _isTimeInput = YES;
         break;
     case WebKit::InputType::DateTimeLocal:
         _shouldRemoveTimeZoneInformation = YES;
@@ -135,25 +311,79 @@
     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];
-    
+    _dateTimePickerViewController = adoptNS([[WKDateTimePickerViewController alloc] initWithDelegate:self]);
+    [_dateTimePickerViewController setDatePickerMode:mode];
+
     return self;
 }
 
 #if USE(UICONTEXTMENU)
 
+- (UIEdgeInsets)_preferredEdgeInsetsForDateTimePicker
+{
+    CGSize pickerSize = [_dateTimePickerViewController preferredContentSize];
+    CGRect windowBounds = _view.textEffectsWindow.bounds;
+    CGRect elementFrameInWindowCoordinates = [_view convertRect:_view.focusedElementInformation.interactionRect toView:nil];
+
+    // Attempt to present the date picker in a way that does not obscure the element.
+
+    CGFloat topInsetForBottomAlignment = CGRectGetMaxY(elementFrameInWindowCoordinates) + kDateTimePickerControlMargin;
+    CGFloat rightInsetForRightAlignment = CGRectGetWidth(windowBounds) - CGRectGetMaxX(elementFrameInWindowCoordinates);
+
+    BOOL canPresentBelowElement = (topInsetForBottomAlignment + pickerSize.height) < CGRectGetHeight(windowBounds);
+    BOOL canAlignToElementRight = (rightInsetForRightAlignment + pickerSize.width) < CGRectGetWidth(windowBounds);
+
+    // Try to present the picker from the bottom right of the element.
+    if (canPresentBelowElement && canAlignToElementRight)
+        return UIEdgeInsetsMake(topInsetForBottomAlignment, 0, 0, rightInsetForRightAlignment);
+
+    CGFloat leftInsetForLeftAlignment = CGRectGetMinX(elementFrameInWindowCoordinates);
+
+    BOOL canAlignToElementLeft = (leftInsetForLeftAlignment + pickerSize.width) <= CGRectGetWidth(windowBounds);
+
+    // Try to present the picker from the bottom left of the element.
+    if (canPresentBelowElement && canAlignToElementLeft)
+        return UIEdgeInsetsMake(topInsetForBottomAlignment, leftInsetForLeftAlignment, 0, 0);
+
+    // Try to present the picker underneath the element.
+    if (canPresentBelowElement)
+        return UIEdgeInsetsMake(topInsetForBottomAlignment, 0, 0, 0);
+
+    CGFloat bottomInsetForTopAlignment = CGRectGetHeight(windowBounds) - CGRectGetMinY(elementFrameInWindowCoordinates) + kDateTimePickerControlMargin;
+
+    BOOL canPresentAboveElement = (bottomInsetForTopAlignment + pickerSize.height) < CGRectGetHeight(windowBounds);
+
+    // Try to present the picker from the top right of the element.
+    if (canPresentAboveElement && canAlignToElementRight)
+        return UIEdgeInsetsMake(0, 0, bottomInsetForTopAlignment, rightInsetForRightAlignment);
+
+    // Try to present the picker from the top left of the element.
+    if (canPresentAboveElement && canAlignToElementLeft)
+        return UIEdgeInsetsMake(0, leftInsetForLeftAlignment, bottomInsetForTopAlignment, 0);
+
+    // Try to present the picker above the element.
+    if (canPresentAboveElement)
+        return UIEdgeInsetsMake(0, 0, bottomInsetForTopAlignment, 0);
+
+    CGFloat rightInsetForPresentingBesideElementLeft = CGRectGetWidth(windowBounds) - CGRectGetMinX(elementFrameInWindowCoordinates) + kDateTimePickerControlMargin;
+    BOOL canPresentBesideElementLeft = (rightInsetForPresentingBesideElementLeft + pickerSize.width) < CGRectGetWidth(windowBounds);
+
+    // Try to present the picker to the left of the element.
+    if (canPresentBesideElementLeft)
+        return UIEdgeInsetsMake(0, 0, 0, rightInsetForPresentingBesideElementLeft);
+
+    CGFloat leftInsetForPresentingBesideElementRight = CGRectGetMaxX(elementFrameInWindowCoordinates) + kDateTimePickerControlMargin;
+    BOOL canPresentBesideElementRight = (leftInsetForPresentingBesideElementRight + pickerSize.width) < CGRectGetWidth(windowBounds);
+
+    // Try to present the picker to the right of the element.
+    if (canPresentBesideElementRight)
+        return UIEdgeInsetsMake(0, leftInsetForPresentingBesideElementRight, 0, 0);
+
+    // Present the picker from the center of the element.
+    return UIEdgeInsetsZero;
+}
+
 - (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForHighlightingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration
 {
     return [_view _createTargetedContextMenuHintPreviewForFocusedElement];
@@ -164,7 +394,10 @@
     _UIContextMenuStyle *style = [_UIContextMenuStyle defaultStyle];
     style.hasInteractivePreview = YES;
     style.preferredBackgroundEffects = @[ [UIVisualEffect emptyEffect] ];
-    style.preferredLayout = _UIContextMenuLayoutAutomatic;
+    style.preferredLayout = _UIContextMenuLayoutPreviewOnly;
+    style.prefersCenteredPreviewWhenActionsAreAbsent = NO;
+    style.ignoresDefaultSizingRules = YES;
+    style.preferredEdgeInsets = [self _preferredEdgeInsetsForDateTimePicker];
     return style;
 }
 
@@ -171,51 +404,7 @@
 - (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location
 {
     return [UIContextMenuConfiguration configurationWithIdentifier:@"_UIDatePickerCompactEditor" previewProvider:^{
-        [_viewController setView:nil];
-        _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");
-        NSString *okString = WEB_UI_STRING_KEY("OK", "OK (OK button title in date/time picker)", "Title of the OK button in date/time form controls.");
-
-        RetainPtr<UIBarButtonItem> okBarButton = adoptNS([[UIBarButtonItem alloc] initWithTitle:okString style:UIBarButtonItemStyleDone target:self action:@selector(ok:)]);
-        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:@[resetBarButton.get(), blankBarButton.get(), okBarButton.get()]];
-        [navigationController setToolbarHidden:NO];
-        
-        auto centeringView = adoptNS([[UIView alloc] init]);
-        
-        [centeringView addSubview:_datePicker.get()];
-        
-        _datePicker.get().translatesAutoresizingMaskIntoConstraints = NO;
-        auto widthConstraint = [[centeringView widthAnchor] constraintGreaterThanOrEqualToAnchor:[_datePicker widthAnchor]];
-        auto heightConstraint = [[centeringView heightAnchor] constraintEqualToAnchor:[_datePicker heightAnchor]];
-        auto horizontalConstraint = [[centeringView centerXAnchor] constraintEqualToAnchor:[_datePicker centerXAnchor]];
-        auto verticalConstraint = [[centeringView centerYAnchor] constraintEqualToAnchor:[_datePicker centerYAnchor]];
-
-        [NSLayoutConstraint activateConstraints:@[verticalConstraint, horizontalConstraint, widthConstraint, heightConstraint]];
-
-        [_viewController setView:centeringView.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].translucent = NO;
-        [navigationController navigationBar].barTintColor = [UIColor systemBackgroundColor];
-        [navigationController toolbar].translucent = NO;
-        [navigationController toolbar].barTintColor = [UIColor systemBackgroundColor];
-        return navigationController.get();
+        return _dateTimePickerViewController.get();
     } actionProvider:nil];
 }
 
@@ -267,13 +456,18 @@
 
 #endif
 
-- (void)reset:(id)sender
+- (void)dateTimePickerViewControllerDidChangeDate:(WKDateTimePickerViewController *)dateTimePickerViewController
 {
+    [self _dateChanged];
+}
+
+- (void)dateTimePickerViewControllerDidPressResetButton:(WKDateTimePickerViewController *)dateTimePickerViewController
+{
     [self setDateTimePickerToInitialValue];
     [_view page]->setFocusedElementValue(String());
 }
 
-- (void)ok:(id)sender
+- (void)dateTimePickerViewControllerDidPressDoneButton:(WKDateTimePickerViewController *)dateTimePickerViewController
 {
 #if USE(UICONTEXTMENU)
     [_dateTimeContextMenuInteraction dismissMenu];
@@ -280,30 +474,16 @@
 #endif
 }
 
-- (NSString *)calendarType
+- (BOOL)shouldForceGregorianCalendar
 {
-    return [_datePicker calendar].calendarIdentifier;
+    auto autofillFieldName = _view.focusedElementInformation.autofillFieldName;
+    return autofillFieldName == WebCore::AutofillFieldName::CcExpMonth
+        || autofillFieldName == WebCore::AutofillFieldName::CcExp
+        || autofillFieldName == WebCore::AutofillFieldName::CcExpYear;
 }
 
-- (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];
 #if USE(UICONTEXTMENU)
     [self removeContextMenuInteraction];
 #endif
@@ -310,24 +490,12 @@
     [super dealloc];
 }
 
-- (BOOL)shouldPresentGregorianCalendar:(const WebKit::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];
+    return [[_dateTimePickerViewController timeZone] secondsFromGMTForDate:date];
 }
 
 - (NSString *)_sanitizeInputValueForFormatter:(NSString *)value
@@ -334,33 +502,33 @@
 {
     // 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)
+    if (_view.focusedElementInformation.elementType == WebKit::InputType::Time)
         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 setTimeZone:[_dateTimePickerViewController timeZone]];
     [dateFormatter setDateFormat:_formatString];
     [dateFormatter setLocale:englishLocale.get()];
     return dateFormatter;
 }
 
+- (void)_dateChangedSetAsNumber
+{
+    NSDate *date = [_dateTimePickerViewController date];
+    [_view updateFocusedElementValueAsNumber:(date.timeIntervalSince1970 + [self _timeZoneOffsetFromGMT:date]) * kMillisecondsPerSecond];
+}
+
 - (void)_dateChangedSetAsString
 {
     // Force English locale because that is what HTML5 value parsing expects.
     RetainPtr<NSDateFormatter> dateFormatter = [self dateFormatterForPicker];
-    [_view updateFocusedElementValue:[dateFormatter stringFromDate:[_datePicker date]]];
+    [_view updateFocusedElementValue:[dateFormatter stringFromDate:[_dateTimePickerViewController date]]];
 }
 
 - (void)_dateChanged
@@ -375,43 +543,38 @@
         [self _dateChangedSetAsNumber];
 }
 
-- (void)_dateChangeHandler:(id)sender
-{
-    [self _dateChanged];
-}
-
 - (void)setDateTimePickerToInitialValue
 {
     if ([_initialValue isEqual: @""]) {
-        [_datePicker setDate:[NSDate date]];
+        [_dateTimePickerViewController 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.get()]];
-        [_datePicker setDate:parsedDate ? parsedDate : [NSDate date]];
+        [_dateTimePickerViewController 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]];
+        [_dateTimePickerViewController setDate:[NSDate dateWithTimeIntervalSince1970:adjustedSecondsSince1970]];
     }
 }
 
+- (UIView *)controlView
+{
+    return nil;
+}
+
 - (void)controlBeginEditing
 {
-    if (_presenting)
-        return;
-
-    _presenting = YES;
-
     auto elementType = _view.focusedElementInformation.elementType;
     if (elementType == WebKit::InputType::Time || elementType == WebKit::InputType::DateTimeLocal)
         [_view startRelinquishingFirstResponderToFocusedElement];
 
     // Set the time zone in case it changed.
-    _datePicker.get().timeZone = [NSTimeZone localTimeZone];
+    [_dateTimePickerViewController setTimeZone:NSTimeZone.localTimeZone];
 
     // Currently no value for the <input>. Start the picker with the current time.
     // Also, update the actual <input> value.
@@ -424,28 +587,43 @@
 #endif
 }
 
-- (void)setHour:(NSInteger)hour minute:(NSInteger)minute
+- (void)controlEndEditing
 {
-    NSString *timeString = [NSString stringWithFormat:@"%.2ld:%.2ld", (long)hour, (long)minute];
-    [_datePicker setDate:[[self dateFormatterForPicker] dateFromString:timeString]];
-    [self _dateChanged];
+    [_view stopRelinquishingFirstResponderToFocusedElement];
+
+#if USE(UICONTEXTMENU)
+    [self removeContextMenuInteraction];
+#endif
 }
 
-- (WKDateTimeContextMenuViewController *)viewController
+- (NSString *)calendarType
 {
-    return _viewController.get();
+    return [_dateTimePickerViewController calendar].calendarIdentifier;
 }
 
-- (void)controlEndEditing
+- (double)hour
 {
-    _presenting = NO;
+    NSCalendar *calendar = [NSCalendar currentCalendar];
+    NSDateComponents *components = [calendar components:NSCalendarUnitHour fromDate:[_dateTimePickerViewController date]];
 
-    [_view stopRelinquishingFirstResponderToFocusedElement];
+    return components.hour;
+}
 
-#if USE(UICONTEXTMENU)
-    [self removeContextMenuInteraction];
-#endif
+- (double)minute
+{
+    NSCalendar *calendar = [NSCalendar currentCalendar];
+    NSDateComponents *components = [calendar components:NSCalendarUnitMinute fromDate:[_dateTimePickerViewController date]];
+
+    return components.minute;
 }
+
+- (void)setHour:(NSInteger)hour minute:(NSInteger)minute
+{
+    NSString *timeString = [NSString stringWithFormat:@"%.2ld:%.2ld", (long)hour, (long)minute];
+    [_dateTimePickerViewController setDate:[[self dateFormatterForPicker] dateFromString:timeString]];
+    [self _dateChanged];
+}
+
 @end
 
 @implementation WKDateTimeInputControl
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to