⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286560 in webkit


Ignore:
Timestamp:
Dec 6, 2021, 12:04:24 PM (5 years ago)
Author:
Devin Rousso
Message:

Change IDL Date to be backed by WallTime to avoid confusion when converting to native dates
https://bugs.webkit.org/show_bug.cgi?id=233781

Reviewed by Darin Adler.

JS Date is milliseconds-based, but some native dates (e.g. NSDate) are seconds-based.
WallTime will help avoid confusion since not a generic type (e.g. double) and instead
has explicitly defined conversion methods to seconds, milliseconds, etc..

Source/WebCore:

  • bindings/IDLTypes.h:

(WebCore::IDLDate::nullValue):
(WebCore::IDLDate::isNullValue):
(WebCore::IDLDate::extractValueFromNullable):

  • bindings/js/JSDOMConvertDate.h:

(WebCore::Converter<IDLDate>::convert):
(WebCore::JSConverter<IDLDate>::convert):

  • bindings/js/JSDOMConvertDate.cpp:

(WebCore::jsDate):
(WebCore::valueToDate):

  • Modules/applepay/ApplePayLineItem.h:

(WebCore::ApplePayLineItem::decode):

  • Modules/applepay/cocoa/PaymentSummaryItemsCocoa.mm:

(WebCore::toDate):

  • bindings/js/IDBBindingUtilities.cpp:

(WebCore::get):
(WebCore::toJS):
(WebCore::createIDBKeyFromValue):

  • html/BaseDateAndTimeInputType.h:
  • html/DateTimeLocalInputType.cpp:

(WebCore::DateTimeLocalInputType::valueAsDate const):
(WebCore::DateTimeLocalInputType::setValueAsDate const):

  • html/BaseDateAndTimeInputType.cpp:

(WebCore::BaseDateAndTimeInputType::valueAsDate const):
(WebCore::BaseDateAndTimeInputType::setValueAsDate const):

  • html/DateTimeLocalInputType.h:
  • html/HTMLInputElement.h:
  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::valueAsDate const):
(WebCore::HTMLInputElement::setValueAsDate):

  • html/InputType.h:
  • html/InputType.cpp:

(WebCore::InputType::valueAsDate const):
(WebCore::InputType::setValueAsDate const):

  • html/MonthInputType.h:
  • html/MonthInputType.cpp:

(WebCore::MonthInputType::valueAsDate const):

  • html/HTMLMediaElement.h:
  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::getStartDate const):
This also fixes an apparently longstanding bug in that MediaTime::toDouble is apparently a
seconds-based value, so this is the one case that doesn't need Seconds::fromMilliseconds.

Source/WebKitLegacy/mac:

  • DOM/DOMInternal.h:

(kit):
(core):

  • DOM/DOMHTMLMediaElement.mm:

(-[DOMHTMLMediaElement getStartDate]):

Location:
trunk/Source
Files:
22 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r286558 r286560  
     12021-12-06  Devin Rousso  <drousso@apple.com>
     2
     3        Change IDL `Date` to be backed by `WallTime` to avoid confusion when converting to native dates
     4        https://bugs.webkit.org/show_bug.cgi?id=233781
     5
     6        Reviewed by Darin Adler.
     7
     8        JS `Date` is milliseconds-based, but some native dates (e.g. `NSDate`) are seconds-based.
     9        `WallTime` will help avoid confusion since not a generic type (e.g. `double`) and instead
     10        has explicitly defined conversion methods to seconds, milliseconds, etc..
     11
     12        * bindings/IDLTypes.h:
     13        (WebCore::IDLDate::nullValue):
     14        (WebCore::IDLDate::isNullValue):
     15        (WebCore::IDLDate::extractValueFromNullable):
     16        * bindings/js/JSDOMConvertDate.h:
     17        (WebCore::Converter<IDLDate>::convert):
     18        (WebCore::JSConverter<IDLDate>::convert):
     19        * bindings/js/JSDOMConvertDate.cpp:
     20        (WebCore::jsDate):
     21        (WebCore::valueToDate):
     22
     23        * Modules/applepay/ApplePayLineItem.h:
     24        (WebCore::ApplePayLineItem::decode):
     25        * Modules/applepay/cocoa/PaymentSummaryItemsCocoa.mm:
     26        (WebCore::toDate):
     27        * bindings/js/IDBBindingUtilities.cpp:
     28        (WebCore::get):
     29        (WebCore::toJS):
     30        (WebCore::createIDBKeyFromValue):
     31        * html/BaseDateAndTimeInputType.h:
     32        * html/DateTimeLocalInputType.cpp:
     33        (WebCore::DateTimeLocalInputType::valueAsDate const):
     34        (WebCore::DateTimeLocalInputType::setValueAsDate const):
     35        * html/BaseDateAndTimeInputType.cpp:
     36        (WebCore::BaseDateAndTimeInputType::valueAsDate const):
     37        (WebCore::BaseDateAndTimeInputType::setValueAsDate const):
     38        * html/DateTimeLocalInputType.h:
     39        * html/HTMLInputElement.h:
     40        * html/HTMLInputElement.cpp:
     41        (WebCore::HTMLInputElement::valueAsDate const):
     42        (WebCore::HTMLInputElement::setValueAsDate):
     43        * html/InputType.h:
     44        * html/InputType.cpp:
     45        (WebCore::InputType::valueAsDate const):
     46        (WebCore::InputType::setValueAsDate const):
     47        * html/MonthInputType.h:
     48        * html/MonthInputType.cpp:
     49        (WebCore::MonthInputType::valueAsDate const):
     50
     51        * html/HTMLMediaElement.h:
     52        * html/HTMLMediaElement.cpp:
     53        (WebCore::HTMLMediaElement::getStartDate const):
     54        This also fixes an apparently longstanding bug in that `MediaTime::toDouble` is apparently a
     55        seconds-based value, so this is the one case that doesn't need `Seconds::fromMilliseconds`.
     56
    1572021-12-06  Patrick Angle  <pangle@apple.com>
    258
  • trunk/Source/WebCore/Modules/applepay/ApplePayLineItem.h

    r286344 r286560  
    3030#include "ApplePayPaymentTiming.h"
    3131#include "ApplePayRecurringPaymentDateUnit.h"
    32 #include <limits>
    3332#include <optional>
     33#include <wtf/WallTime.h>
    3434#include <wtf/text/WTFString.h>
    3535
     
    5353
    5454#if ENABLE(APPLE_PAY_RECURRING_LINE_ITEM)
    55     double recurringPaymentStartDate { std::numeric_limits<double>::quiet_NaN() };
     55    WallTime recurringPaymentStartDate { WallTime::nan() };
    5656    ApplePayRecurringPaymentDateUnit recurringPaymentIntervalUnit { ApplePayRecurringPaymentDateUnit::Month };
    5757    unsigned recurringPaymentIntervalCount = 1;
    58     double recurringPaymentEndDate { std::numeric_limits<double>::quiet_NaN() };
     58    WallTime recurringPaymentEndDate { WallTime::nan() };
    5959#endif
    6060
    6161#if ENABLE(APPLE_PAY_DEFERRED_LINE_ITEM)
    62     double deferredPaymentDate { std::numeric_limits<double>::quiet_NaN() };
     62    WallTime deferredPaymentDate { WallTime::nan() };
    6363#endif
    6464
     
    106106    DECODE(paymentTiming, ApplePayPaymentTiming)
    107107#if ENABLE(APPLE_PAY_RECURRING_LINE_ITEM)
    108     DECODE(recurringPaymentStartDate, double)
     108    DECODE(recurringPaymentStartDate, WallTime)
    109109    DECODE(recurringPaymentIntervalUnit, ApplePayRecurringPaymentDateUnit)
    110110    DECODE(recurringPaymentIntervalCount, unsigned)
    111     DECODE(recurringPaymentEndDate, double)
     111    DECODE(recurringPaymentEndDate, WallTime)
    112112#endif
    113113#if ENABLE(APPLE_PAY_DEFERRED_LINE_ITEM)
    114     DECODE(deferredPaymentDate, double)
     114    DECODE(deferredPaymentDate, WallTime)
    115115#endif
    116116#if defined(ApplePayLineItemAdditions_decode_members)
  • trunk/Source/WebCore/Modules/applepay/cocoa/PaymentSummaryItemsCocoa.mm

    r286454 r286560  
    6161#if HAVE(PASSKIT_RECURRING_SUMMARY_ITEM) || HAVE(PASSKIT_DEFERRED_SUMMARY_ITEM)
    6262
    63 static NSDate *toDate(double date)
     63static NSDate *toDate(WallTime date)
    6464{
    65     return [NSDate dateWithTimeIntervalSince1970:(date / 1000)];
     65    return [NSDate dateWithTimeIntervalSince1970:date.secondsSinceEpoch().value()];
    6666}
    6767
  • trunk/Source/WebCore/bindings/IDLTypes.h

    r284857 r286560  
    3333#include <wtf/StdLibExtras.h>
    3434#include <wtf/URL.h>
     35#include <wtf/WallTime.h>
    3536
    3637#if ENABLE(WEBGL)
     
    260261// Non-WebIDL extensions
    261262
    262 struct IDLDate : IDLType<double> {
    263     using NullableType = double;
    264     static double nullValue() { return std::numeric_limits<double>::quiet_NaN(); }
    265     static bool isNullValue(double value) { return std::isnan(value); }
    266     static double extractValueFromNullable(double value) { return value; }
     263struct IDLDate : IDLType<WallTime> {
     264    using NullableType = WallTime;
     265    static WallTime nullValue() { return WallTime::nan(); }
     266    static bool isNullValue(WallTime value) { return std::isnan(value); }
     267    static WallTime extractValueFromNullable(WallTime value) { return value; }
    267268};
    268269
  • trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp

    r284095 r286560  
    102102        }
    103103        if (keyPathElement == "lastModifiedDate") {
    104             result = jsDate(lexicalGlobalObject, jsCast<JSFile*>(obj)->wrapped().lastModified());
     104            result = jsDate(lexicalGlobalObject, WallTime::fromRawSeconds(Seconds::fromMilliseconds(jsCast<JSFile*>(obj)->wrapped().lastModified()).value()));
    105105            return true;
    106106        }
     
    178178        // FIXME: This should probably be toJS<IDLDate>(...) as per:
    179179        // http://w3c.github.io/IndexedDB/#request-convert-a-key-to-a-value
    180         RELEASE_AND_RETURN(scope, toJS<IDLNullable<IDLDate>>(lexicalGlobalObject, key->date()));
     180        RELEASE_AND_RETURN(scope, toJS<IDLNullable<IDLDate>>(lexicalGlobalObject, WallTime::fromRawSeconds(Seconds::fromMilliseconds(key->date()).value())));
    181181    case IndexedDB::KeyType::Number:
    182182        return jsNumber(key->number());
     
    212212        RETURN_IF_EXCEPTION(scope, { });
    213213        if (!std::isnan(dateValue))
    214             return IDBKey::createDate(dateValue);
     214            return IDBKey::createDate(dateValue.secondsSinceEpoch().milliseconds());
    215215    }
    216216
  • trunk/Source/WebCore/bindings/js/JSDOMConvertDate.cpp

    r274832 r286560  
    3131using namespace JSC;
    3232
    33 JSValue jsDate(JSGlobalObject& lexicalGlobalObject, double value)
     33JSValue jsDate(JSGlobalObject& lexicalGlobalObject, WallTime value)
    3434{
    35     return DateInstance::create(lexicalGlobalObject.vm(), lexicalGlobalObject.dateStructure(), value);
     35    return DateInstance::create(lexicalGlobalObject.vm(), lexicalGlobalObject.dateStructure(), value.secondsSinceEpoch().milliseconds());
    3636}
    3737
    38 double valueToDate(JSC::JSGlobalObject& lexicalGlobalObject, JSValue value)
     38WallTime valueToDate(JSC::JSGlobalObject& lexicalGlobalObject, JSValue value)
    3939{
     40    double milliseconds = std::numeric_limits<double>::quiet_NaN();
     41
    4042    auto& vm = lexicalGlobalObject.vm();
    4143    if (value.inherits<DateInstance>(vm))
    42         return jsCast<DateInstance*>(value)->internalNumber();
    43     if (value.isNumber())
    44         return value.asNumber();
    45     if (value.isString())
    46         return vm.dateCache.parseDate(&lexicalGlobalObject, vm, value.getString(&lexicalGlobalObject));
    47     return std::numeric_limits<double>::quiet_NaN();
     44        milliseconds = jsCast<DateInstance*>(value)->internalNumber();
     45    else if (value.isNumber())
     46        milliseconds = value.asNumber();
     47    else if (value.isString())
     48        milliseconds = vm.dateCache.parseDate(&lexicalGlobalObject, vm, value.getString(&lexicalGlobalObject));
     49
     50    return WallTime::fromRawSeconds(Seconds::fromMilliseconds(milliseconds).value());
    4851}
    4952
  • trunk/Source/WebCore/bindings/js/JSDOMConvertDate.h

    r273767 r286560  
    2929#include "JSDOMConvertBase.h"
    3030#include <JavaScriptCore/JSGlobalObject.h>
     31#include <wtf/WallTime.h>
    3132
    3233namespace WebCore {
    3334
    34 JSC::JSValue jsDate(JSC::JSGlobalObject&, double value);
    35 double valueToDate(JSC::JSGlobalObject&, JSC::JSValue); // NaN if the value can't be converted to a date.
     35JSC::JSValue jsDate(JSC::JSGlobalObject&, WallTime value);
     36WallTime valueToDate(JSC::JSGlobalObject&, JSC::JSValue); // NaN if the value can't be converted to a date.
    3637
    3738template<> struct Converter<IDLDate> : DefaultConverter<IDLDate> {
    38     static double convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value)
     39    static WallTime convert(JSC::JSGlobalObject& lexicalGlobalObject, JSC::JSValue value)
    3940    {
    4041        return valueToDate(lexicalGlobalObject, value);
     
    4748
    4849    // FIXME: This should be taking a JSDOMGlobalObject and passing it to jsDate.
    49     static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, double value)
     50    static JSC::JSValue convert(JSC::JSGlobalObject& lexicalGlobalObject, WallTime value)
    5051    {
    5152        return jsDate(lexicalGlobalObject, value);
  • trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp

    r286413 r286560  
    128128}
    129129
    130 double BaseDateAndTimeInputType::valueAsDate() const
    131 {
    132     return valueAsDouble();
    133 }
    134 
    135 ExceptionOr<void> BaseDateAndTimeInputType::setValueAsDate(double value) const
    136 {
    137     ASSERT(element());
    138     element()->setValue(serializeWithMilliseconds(value));
     130WallTime BaseDateAndTimeInputType::valueAsDate() const
     131{
     132    return WallTime::fromRawSeconds(Seconds::fromMilliseconds(valueAsDouble()).value());
     133}
     134
     135ExceptionOr<void> BaseDateAndTimeInputType::setValueAsDate(WallTime value) const
     136{
     137    ASSERT(element());
     138    element()->setValue(serializeWithMilliseconds(value.secondsSinceEpoch().milliseconds()));
    139139    return { };
    140140}
  • trunk/Source/WebCore/html/BaseDateAndTimeInputType.h

    r282242 r286560  
    103103    String sanitizeValue(const String&) const final;
    104104    void setValue(const String&, bool valueChanged, TextFieldEventBehavior) final;
    105     double valueAsDate() const override;
    106     ExceptionOr<void> setValueAsDate(double) const override;
     105    WallTime valueAsDate() const override;
     106    ExceptionOr<void> setValueAsDate(WallTime) const override;
    107107    double valueAsDouble() const final;
    108108    ExceptionOr<void> setValueAsDecimal(const Decimal&, TextFieldEventBehavior) const final;
  • trunk/Source/WebCore/html/DateTimeLocalInputType.cpp

    r283851 r286560  
    6363}
    6464
    65 double DateTimeLocalInputType::valueAsDate() const
     65WallTime DateTimeLocalInputType::valueAsDate() const
    6666{
    6767    // valueAsDate doesn't work for the datetime-local type according to the standard.
    68     return DateComponents::invalidMilliseconds();
     68    return WallTime::nan();
    6969}
    7070
    71 ExceptionOr<void> DateTimeLocalInputType::setValueAsDate(double value) const
     71ExceptionOr<void> DateTimeLocalInputType::setValueAsDate(WallTime value) const
    7272{
    7373    // valueAsDate doesn't work for the datetime-local type according to the standard.
  • trunk/Source/WebCore/html/DateTimeLocalInputType.h

    r282242 r286560  
    4848    const AtomString& formControlType() const final;
    4949    DateComponentsType dateType() const final;
    50     double valueAsDate() const final;
    51     ExceptionOr<void> setValueAsDate(double) const final;
     50    WallTime valueAsDate() const final;
     51    ExceptionOr<void> setValueAsDate(WallTime) const final;
    5252    StepRange createStepRange(AnyStepHandling) const final;
    5353    std::optional<DateComponents> parseToDateComponents(StringView) const final;
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r286482 r286560  
    11091109}
    11101110
    1111 double HTMLInputElement::valueAsDate() const
     1111WallTime HTMLInputElement::valueAsDate() const
    11121112{
    11131113    return m_inputType->valueAsDate();
    11141114}
    11151115
    1116 ExceptionOr<void> HTMLInputElement::setValueAsDate(double value)
     1116ExceptionOr<void> HTMLInputElement::setValueAsDate(WallTime value)
    11171117{
    11181118    return m_inputType->setValueAsDate(value);
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r286447 r286560  
    185185    String visibleValue() const;
    186186
    187     WEBCORE_EXPORT double valueAsDate() const;
    188     WEBCORE_EXPORT ExceptionOr<void> setValueAsDate(double);
     187    WEBCORE_EXPORT WallTime valueAsDate() const;
     188    WEBCORE_EXPORT ExceptionOr<void> setValueAsDate(WallTime);
    189189
    190190    WEBCORE_EXPORT double valueAsNumber() const;
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r285655 r286560  
    11121112}
    11131113
    1114 double HTMLMediaElement::getStartDate() const
     1114WallTime HTMLMediaElement::getStartDate() const
    11151115{
    11161116    if (!m_player)
    1117         return std::numeric_limits<double>::quiet_NaN();
    1118     return m_player->getStartDate().toDouble();
     1117        return WallTime::nan();
     1118
     1119    return WallTime::fromRawSeconds(m_player->getStartDate().toDouble());
    11191120}
    11201121
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r285993 r286560  
    4747#include <wtf/LoggerHelper.h>
    4848#include <wtf/Observer.h>
     49#include <wtf/WallTime.h>
    4950#include <wtf/WeakPtr.h>
    5051
     
    243244    double currentTimeForBindings() const { return currentTime(); }
    244245    WEBCORE_EXPORT ExceptionOr<void> setCurrentTimeForBindings(double);
    245     WEBCORE_EXPORT double getStartDate() const;
     246    WEBCORE_EXPORT WallTime getStartDate() const;
    246247    WEBCORE_EXPORT double duration() const override;
    247248    WEBCORE_EXPORT bool paused() const override;
  • trunk/Source/WebCore/html/InputType.cpp

    r286447 r286560  
    205205}
    206206
    207 double InputType::valueAsDate() const
    208 {
    209     return DateComponents::invalidMilliseconds();
    210 }
    211 
    212 ExceptionOr<void> InputType::setValueAsDate(double) const
     207WallTime InputType::valueAsDate() const
     208{
     209    return WallTime::nan();
     210}
     211
     212ExceptionOr<void> InputType::setValueAsDate(WallTime) const
    213213{
    214214    return Exception { InvalidStateError };
  • trunk/Source/WebCore/html/InputType.h

    r286447 r286560  
    221221    virtual String fallbackValue() const; // Checked last, if both internal storage and value attribute are missing.
    222222    virtual String defaultValue() const; // Checked after even fallbackValue, only when the valueWithDefault function is called.
    223     virtual double valueAsDate() const;
    224     virtual ExceptionOr<void> setValueAsDate(double) const;
     223    virtual WallTime valueAsDate() const;
     224    virtual ExceptionOr<void> setValueAsDate(WallTime) const;
    225225    virtual double valueAsDouble() const;
    226226    virtual ExceptionOr<void> setValueAsDouble(double, TextFieldEventBehavior) const;
  • trunk/Source/WebCore/html/MonthInputType.cpp

    r283851 r286560  
    6565}
    6666
    67 double MonthInputType::valueAsDate() const
     67WallTime MonthInputType::valueAsDate() const
    6868{
    6969    ASSERT(element());
    7070    auto date = parseToDateComponents(element()->value());
    7171    if (!date)
    72         return DateComponents::invalidMilliseconds();
     72        return WallTime::nan();
    7373    double msec = date->millisecondsSinceEpoch();
    7474    ASSERT(std::isfinite(msec));
    75     return msec;
     75    return WallTime::fromRawSeconds(Seconds::fromMilliseconds(msec).value());
    7676}
    7777
  • trunk/Source/WebCore/html/MonthInputType.h

    r282242 r286560  
    4848    const AtomString& formControlType() const override;
    4949    DateComponentsType dateType() const override;
    50     double valueAsDate() const override;
     50    WallTime valueAsDate() const override;
    5151    String serializeWithMilliseconds(double) const override;
    5252    Decimal parseToNumber(const String&, const Decimal&) const override;
  • trunk/Source/WebKitLegacy/mac/ChangeLog

    r286459 r286560  
     12021-12-06  Devin Rousso  <drousso@apple.com>
     2
     3        Change IDL `Date` to be backed by `WallTime` to avoid confusion when converting to native dates
     4        https://bugs.webkit.org/show_bug.cgi?id=233781
     5
     6        Reviewed by Darin Adler.
     7
     8        JS `Date` is milliseconds-based, but some native dates (e.g. `NSDate`) are seconds-based.
     9        `WallTime` will help avoid confusion since not a generic type (e.g. `double`) and instead
     10        has explicitly defined conversion methods to seconds, milliseconds, etc..
     11
     12        * DOM/DOMInternal.h:
     13        (kit):
     14        (core):
     15
     16        * DOM/DOMHTMLMediaElement.mm:
     17        (-[DOMHTMLMediaElement getStartDate]):
     18
    1192021-12-02  Myles C. Maxfield  <mmaxfield@apple.com>
    220
  • trunk/Source/WebKitLegacy/mac/DOM/DOMHTMLMediaElement.mm

    r260709 r286560  
    2929#import "DOMHTMLMediaElement.h"
    3030
     31#import "DOMInternal.h"
    3132#import "DOMMediaErrorInternal.h"
    3233#import "DOMNodeInternal.h"
     
    314315{
    315316    WebCore::JSMainThreadNullState state;
    316     return IMPL->getStartDate();
     317    return kit(IMPL->getStartDate());
    317318}
    318319
  • trunk/Source/WebKitLegacy/mac/DOM/DOMInternal.h

    r204717 r286560  
    3030#import "DOMXPathNSResolver.h"
    3131#import <wtf/Forward.h>
     32#import <wtf/WallTime.h>
    3233
    3334namespace JSC {
     
    7879WebCore::XPathNSResolver* core(DOMNativeXPathNSResolver *);
    7980
    80 inline NSTimeInterval kit(double msSinceEpoch)
     81inline NSTimeInterval kit(WallTime time)
    8182{
    82     return msSinceEpoch / 1000.0 - NSTimeIntervalSince1970;
     83    return time.secondsSinceEpoch().value() - NSTimeIntervalSince1970;
    8384}
    8485
    85 inline double core(NSTimeInterval sec)
     86inline WallTime core(NSTimeInterval sec)
    8687{
    87     return sec * 1000.0 + NSTimeIntervalSince1970;
     88    return WallTime::fromRawSeconds(sec + NSTimeIntervalSince1970);
    8889}
Note: See TracChangeset for help on using the changeset viewer.