Title: [281955] trunk/Source
Revision
281955
Author
[email protected]
Date
2021-09-02 14:49:25 -0700 (Thu, 02 Sep 2021)

Log Message

[iOS] Simplify date picker logic for datetime-local inputs
https://bugs.webkit.org/show_bug.cgi?id=229773

Reviewed by Darin Adler.

Source/WebCore:

* platform/DateComponents.cpp:

Add comments pointing to the specification for parsing date/time information.

Source/WebKit:

Currently, the date picker logic for getting/setting the value of a
datetime-local input relies on the numeric value of input. This
logic differs from logic for date, time, and month inputs, where we use
the string value of the input. This patch simplifies the code by using
string values for all the date/time input types.

* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
* UIProcess/ios/WebPageProxyIOS.mm:
* UIProcess/ios/forms/WKDateTimeInputControl.mm:
(-[WKDateTimePicker initWithView:datePickerMode:]):

Set the format string for datetime-local inputs, matching the spec.

(-[WKDateTimePicker _sanitizeInputValueForFormatter:]):

Sanitize datetime-local values to remove seconds and milliseconds
information. UIKit does not support anything beyond minute granularity.

(-[WKDateTimePicker dateFormatterForPicker]):
(-[WKDateTimePicker _dateChanged]):

Always use setValueAsString, matching the other date/time inputs.

Time zone conversion before sending the date back to the web process
is no longer needed.

(-[WKDateTimePicker setDateTimePickerToInitialValue]):

Time zone conversion when retrieving the date from the web process is no
longer needed.

(-[WKDateTimePicker controlBeginEditing]):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281954 => 281955)


--- trunk/Source/WebCore/ChangeLog	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebCore/ChangeLog	2021-09-02 21:49:25 UTC (rev 281955)
@@ -1,3 +1,14 @@
+2021-09-02  Aditya Keerthi  <[email protected]>
+
+        [iOS] Simplify date picker logic for datetime-local inputs
+        https://bugs.webkit.org/show_bug.cgi?id=229773
+
+        Reviewed by Darin Adler.
+
+        * platform/DateComponents.cpp:
+
+        Add comments pointing to the specification for parsing date/time information.
+
 2021-09-02  Myles C. Maxfield  <[email protected]>
 
         FontFaceSet.add() needs to throw when called on a CSS-connected font

Modified: trunk/Source/WebCore/platform/DateComponents.cpp (281954 => 281955)


--- trunk/Source/WebCore/platform/DateComponents.cpp	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebCore/platform/DateComponents.cpp	2021-09-02 21:49:25 UTC (rev 281955)
@@ -136,6 +136,7 @@
     return value;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#months
 template<typename CharacterType> bool DateComponents::parseYear(StringParsingBuffer<CharacterType>& buffer)
 {
     unsigned digitsLength = countDigits(buffer);
@@ -337,6 +338,7 @@
     return true;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#time-zones
 // Parses a timezone part, and adjust year, month, monthDay, hour, minute, second, millisecond.
 template<typename CharacterType> bool DateComponents::parseTimeZone(StringParsingBuffer<CharacterType>& buffer)
 {
@@ -373,6 +375,7 @@
     return true;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#months
 template<typename CharacterType> bool DateComponents::parseMonth(StringParsingBuffer<CharacterType>& buffer)
 {
     if (!parseYear(buffer))
@@ -394,6 +397,7 @@
     return true;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#dates
 template<typename CharacterType> bool DateComponents::parseDate(StringParsingBuffer<CharacterType>& buffer)
 {
     if (!parseMonth(buffer))
@@ -414,6 +418,7 @@
     return true;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#weeks
 template<typename CharacterType> bool DateComponents::parseWeek(StringParsingBuffer<CharacterType>& buffer)
 {
     if (!parseYear(buffer))
@@ -436,6 +441,7 @@
     return true;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#times
 template<typename CharacterType> bool DateComponents::parseTime(StringParsingBuffer<CharacterType>& buffer)
 {
     auto hour = parseIntWithinLimits(buffer, 2, 0, 23);
@@ -496,6 +502,7 @@
     return true;
 }
 
+// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#local-dates-and-times
 template<typename CharacterType> bool DateComponents::parseDateTimeLocal(StringParsingBuffer<CharacterType>& buffer)
 {
     if (!parseDate(buffer))

Modified: trunk/Source/WebKit/ChangeLog (281954 => 281955)


--- trunk/Source/WebKit/ChangeLog	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/ChangeLog	2021-09-02 21:49:25 UTC (rev 281955)
@@ -1,3 +1,48 @@
+2021-09-02  Aditya Keerthi  <[email protected]>
+
+        [iOS] Simplify date picker logic for datetime-local inputs
+        https://bugs.webkit.org/show_bug.cgi?id=229773
+
+        Reviewed by Darin Adler.
+
+        Currently, the date picker logic for getting/setting the value of a
+        datetime-local input relies on the numeric value of input. This
+        logic differs from logic for date, time, and month inputs, where we use
+        the string value of the input. This patch simplifies the code by using
+        string values for all the date/time input types.
+
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        * UIProcess/ios/forms/WKDateTimeInputControl.mm:
+        (-[WKDateTimePicker initWithView:datePickerMode:]):
+
+        Set the format string for datetime-local inputs, matching the spec.
+
+        (-[WKDateTimePicker _sanitizeInputValueForFormatter:]):
+
+        Sanitize datetime-local values to remove seconds and milliseconds
+        information. UIKit does not support anything beyond minute granularity.
+
+        (-[WKDateTimePicker dateFormatterForPicker]):
+        (-[WKDateTimePicker _dateChanged]):
+
+        Always use setValueAsString, matching the other date/time inputs.
+
+        Time zone conversion before sending the date back to the web process
+        is no longer needed.
+
+        (-[WKDateTimePicker setDateTimePickerToInitialValue]):
+
+        Time zone conversion when retrieving the date from the web process is no
+        longer needed.
+
+        (-[WKDateTimePicker controlBeginEditing]):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+
 2021-09-02  Peng Liu  <[email protected]>
 
         [MSE][GPUP] SourceBufferPrivateAVFObjC does not work properly when audio and video exchange their track IDs

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (281954 => 281955)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2021-09-02 21:49:25 UTC (rev 281955)
@@ -840,7 +840,6 @@
     void saveImageToLibrary(const SharedMemory::IPCHandle& imageHandle);
     void focusNextFocusedElement(bool isForward, CompletionHandler<void()>&& = [] { });
     void setFocusedElementValue(const WebCore::ElementContext&, const String&);
-    void setFocusedElementValueAsNumber(const WebCore::ElementContext&, double);
     void setFocusedElementSelectedIndex(const WebCore::ElementContext&, uint32_t index, bool allowMultipleSelection = false);
     void applicationDidEnterBackground();
     void applicationDidFinishSnapshottingAfterEnteringBackground();

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h (281954 => 281955)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h	2021-09-02 21:49:25 UTC (rev 281955)
@@ -667,7 +667,6 @@
 - (void)accessoryOpen;
 
 - (void)updateFocusedElementValueAsColor:(UIColor *)value;
-- (void)updateFocusedElementValueAsNumber:(double)value;
 - (void)updateFocusedElementValue:(NSString *)value;
 - (void)updateFocusedElementSelectedIndex:(uint32_t)index allowsMultipleSelection:(bool)allowsMultipleSelection;
 - (void)updateFocusedElementFocusedWithDataListDropdown:(BOOL)value;

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (281954 => 281955)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2021-09-02 21:49:25 UTC (rev 281955)
@@ -4827,12 +4827,6 @@
     _page->setIsShowingInputViewForFocusedElement(false);
 }
 
-- (void)updateFocusedElementValueAsNumber:(double)value
-{
-    _page->setFocusedElementValueAsNumber(_focusedElementInformation.elementContext, value);
-    _focusedElementInformation.valueAsNumber = value;
-}
-
 - (void)updateFocusedElementValue:(NSString *)value
 {
     _page->setFocusedElementValue(_focusedElementInformation.elementContext, value);

Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (281954 => 281955)


--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm	2021-09-02 21:49:25 UTC (rev 281955)
@@ -967,11 +967,6 @@
     send(Messages::WebPage::SetFocusedElementValue(context, value));
 }
 
-void WebPageProxy::setFocusedElementValueAsNumber(const WebCore::ElementContext& context, double value)
-{
-    send(Messages::WebPage::SetFocusedElementValueAsNumber(context, value));
-}
-
 void WebPageProxy::setFocusedElementSelectedIndex(const WebCore::ElementContext& context, uint32_t index, bool allowMultipleSelection)
 {
     send(Messages::WebPage::SetFocusedElementSelectedIndex(context, index, allowMultipleSelection));

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


--- trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKDateTimeInputControl.mm	2021-09-02 21:49:25 UTC (rev 281955)
@@ -229,8 +229,6 @@
 > {
     NSString *_formatString;
     RetainPtr<NSString> _initialValue;
-    NSTimeInterval _initialValueAsNumber;
-    BOOL _shouldRemoveTimeZoneInformation;
     WKContentView *_view;
     CGPoint _interactionPoint;
     RetainPtr<UIDatePicker> _datePicker;
@@ -259,6 +257,7 @@
 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 NSString * const kDateTimeFormatString = @"yyyy-MM-dd'T'HH:mm"; // "2011-01-27T13:45"
 static const NSTimeInterval kMillisecondsPerSecond = 1000;
 
 static const CGFloat kDateTimePickerControlMargin = 6;
@@ -270,7 +269,6 @@
 
     _view = view;
     _interactionPoint = [_view lastInteractionLocation];
-    _shouldRemoveTimeZoneInformation = NO;
 
     switch (view.focusedElementInformation.elementType) {
     case WebKit::InputType::Date:
@@ -283,7 +281,7 @@
         _formatString = kTimeFormatString;
         break;
     case WebKit::InputType::DateTimeLocal:
-        _shouldRemoveTimeZoneInformation = YES;
+        _formatString = kDateTimeFormatString;
         break;
     default:
         break;
@@ -553,21 +551,22 @@
     [super dealloc];
 }
 
-- (NSInteger)_timeZoneOffsetFromGMT:(NSDate *)date
+- (NSString *)_sanitizeInputValueForFormatter:(NSString *)value
 {
-    if (!_shouldRemoveTimeZoneInformation)
-        return 0;
+    ASSERT([value length]);
 
-    return [[_datePicker timeZone] secondsFromGMTForDate:date];
-}
+    // Times may have seconds and milliseconds information which we just
+    // ignore. For example: "01:56:20.391" is shortened to just "01:56".
 
-- (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 (_view.focusedElementInformation.elementType == WebKit::InputType::Time)
         return [value substringToIndex:[kTimeFormatString length]];
 
+    if (_view.focusedElementInformation.elementType == WebKit::InputType::DateTimeLocal) {
+        NSString *timeString = [[value componentsSeparatedByString:@"T"] objectAtIndex:1];
+        NSString *sanitizedTimeString = [timeString substringToIndex:[kTimeFormatString length]];
+        return [value stringByReplacingOccurrencesOfString:timeString withString:sanitizedTimeString];
+    }
+
     return value;
 }
 
@@ -577,52 +576,27 @@
     RetainPtr<NSDateFormatter> dateFormatter = adoptNS([[NSDateFormatter alloc] init]);
     [dateFormatter setTimeZone:[_datePicker timeZone]];
     [dateFormatter setDateFormat:_formatString];
+    // Force English locale because that is what HTML5 value parsing expects.
     [dateFormatter setLocale:englishLocale.get()];
     return dateFormatter;
 }
 
-- (void)_dateChangedSetAsNumber
+- (void)_dateChanged
 {
-    NSDate *date = [_datePicker 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]]];
 }
 
-- (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)setDateTimePickerToInitialValue
 {
-    if ([_initialValue isEqual: @""]) {
+    if (![_initialValue length]) {
         [_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.get()]];
-        [_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]];
+        return;
     }
+
+    NSDate *parsedDate = [[self dateFormatterForPicker] dateFromString:[self _sanitizeInputValueForFormatter:_initialValue.get()]];
+    [_datePicker setDate:parsedDate ? parsedDate : [NSDate date]];
 }
 
 - (UIView *)controlView
@@ -642,7 +616,6 @@
     // 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];
 
     [self showDateTimePicker];

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (281954 => 281955)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h	2021-09-02 21:49:25 UTC (rev 281955)
@@ -793,7 +793,6 @@
     void focusNextFocusedElement(bool isForward, CompletionHandler<void()>&&);
     void autofillLoginCredentials(const String&, const String&);
     void setFocusedElementValue(const WebCore::ElementContext&, const String&);
-    void setFocusedElementValueAsNumber(const WebCore::ElementContext&, double);
     void setFocusedElementSelectedIndex(const WebCore::ElementContext&, uint32_t index, bool allowMultipleSelection);
     void setIsShowingInputViewForFocusedElement(bool);
     bool isShowingInputViewForFocusedElement() const { return m_isShowingInputViewForFocusedElement; }

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (281954 => 281955)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in	2021-09-02 21:49:25 UTC (rev 281955)
@@ -95,7 +95,6 @@
     FocusNextFocusedElement(bool isForward) -> () Async
     AutofillLoginCredentials(String username, String password)
     SetFocusedElementValue(struct WebCore::ElementContext context, String value)
-    SetFocusedElementValueAsNumber(struct WebCore::ElementContext context, double value)
     SetFocusedElementSelectedIndex(struct WebCore::ElementContext context, uint32_t index, bool allowMultipleSelection)
     ApplicationWillResignActive()
     ApplicationDidEnterBackground(bool isSuspendedUnderLock)

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (281954 => 281955)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2021-09-02 21:36:34 UTC (rev 281954)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2021-09-02 21:49:25 UTC (rev 281955)
@@ -1257,13 +1257,6 @@
         downcast<HTMLInputElement>(*element).setValue(value, DispatchInputAndChangeEvent);
 }
 
-void WebPage::setFocusedElementValueAsNumber(const WebCore::ElementContext& context, double value)
-{
-    RefPtr<Element> element = elementForContext(context);
-    if (is<HTMLInputElement>(element))
-        downcast<HTMLInputElement>(*element).setValueAsNumber(value, DispatchInputAndChangeEvent);
-}
-
 void WebPage::setFocusedElementSelectedIndex(const WebCore::ElementContext& context, uint32_t index, bool allowMultipleSelection)
 {
     RefPtr<Element> element = elementForContext(context);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to