Diff
Modified: trunk/Source/WebCore/ChangeLog (263899 => 263900)
--- trunk/Source/WebCore/ChangeLog 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/ChangeLog 2020-07-03 16:45:29 UTC (rev 263900)
@@ -1,5 +1,52 @@
2020-07-03 Sam Weinig <[email protected]>
+ Convert DateComponents parsing code to use Optional based return values rather than out-parameters
+ https://bugs.webkit.org/show_bug.cgi?id=213440
+
+ Reviewed by Darin Adler.
+
+ Rework DateComponents and Date/Time related InputTypes to use Optional based programming
+ for parsing results. Also take the opportunity to remove unicode upconversion from
+ DateComponent parsing and instead separate UChar and LChar variants via templates.
+
+ * html/BaseDateAndTimeInputType.cpp:
+ * html/BaseDateAndTimeInputType.h:
+ * html/DateInputType.cpp:
+ * html/DateInputType.h:
+ * html/DateTimeInputType.cpp:
+ * html/DateTimeInputType.h:
+ * html/DateTimeLocalInputType.cpp:
+ * html/DateTimeLocalInputType.h:
+ * html/HTMLInputElement.cpp:
+ * html/HTMLInputElement.h:
+ * html/InputType.cpp:
+ * html/InputType.h:
+ * html/MonthInputType.cpp:
+ * html/MonthInputType.h:
+ * html/TimeInputType.cpp:
+ * html/TimeInputType.h:
+ * html/WeekInputType.cpp:
+ * html/WeekInputType.h:
+ - Removes parseToDateComponentsInternal. No need it and parseToDateComponents.
+ - Makes parseToDateComponents pure virtual. The old code had a default implementations
+ down in InputType, but it had no callers.
+ - Remove iOS vs. non-iOS difference for dateType(). It is now available on InputType
+ on all platforms.
+ - Make setMillisecondToDateComponents and parseToDateComponents return an Optional.
+
+ * platform/DateComponents.cpp:
+ * platform/DateComponents.h:
+ - Replace member function based interfaces for parsing/setting explicit time offsets
+ with new factory functions that return Optional<DateComponents>.
+ - These factories are implemented using the existing member functions, which are
+ now private.
+ - Make max/min constants constexpr.
+ - Make parse* member functions templates to allow factory parse functions to
+ call them without upconverting.
+ - Replace header guard with #pragma once.
+
+2020-07-03 Sam Weinig <[email protected]>
+
Cleanup ApplicationCacheManifestParser.h/cpp
https://bugs.webkit.org/show_bug.cgi?id=213844
Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -78,7 +78,7 @@
bool BaseDateAndTimeInputType::typeMismatchFor(const String& value) const
{
- return !value.isEmpty() && !parseToDateComponents(value, 0);
+ return !value.isEmpty() && !parseToDateComponents(value);
}
bool BaseDateAndTimeInputType::typeMismatch() const
@@ -110,32 +110,22 @@
Decimal BaseDateAndTimeInputType::parseToNumber(const String& source, const Decimal& defaultValue) const
{
- DateComponents date;
- if (!parseToDateComponents(source, &date))
+ auto date = parseToDateComponents(source);
+ if (!date)
return defaultValue;
- double msec = date.millisecondsSinceEpoch();
+ double msec = date->millisecondsSinceEpoch();
ASSERT(std::isfinite(msec));
return Decimal::fromDouble(msec);
}
-bool BaseDateAndTimeInputType::parseToDateComponents(const String& source, DateComponents* out) const
-{
- if (source.isEmpty())
- return false;
- DateComponents ignoredResult;
- if (!out)
- out = &ignoredResult;
- return parseToDateComponentsInternal(StringView(source).upconvertedCharacters(), source.length(), out);
-}
-
String BaseDateAndTimeInputType::serialize(const Decimal& value) const
{
if (!value.isFinite())
- return String();
- DateComponents date;
- if (!setMillisecondToDateComponents(value.toDouble(), &date))
- return String();
- return serializeWithComponents(date);
+ return { };
+ auto date = setMillisecondToDateComponents(value.toDouble());
+ if (!date)
+ return { };
+ return serializeWithComponents(*date);
}
String BaseDateAndTimeInputType::serializeWithComponents(const DateComponents& date) const
@@ -158,12 +148,12 @@
String BaseDateAndTimeInputType::localizeValue(const String& proposedValue) const
{
- DateComponents date;
- if (!parseToDateComponents(proposedValue, &date))
+ auto date = parseToDateComponents(proposedValue);
+ if (!date)
return proposedValue;
ASSERT(element());
- String localized = element()->locale().formatDateTime(date);
+ String localized = element()->locale().formatDateTime(*date);
return localized.isEmpty() ? proposedValue : localized;
}
Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -44,11 +44,9 @@
BaseDateAndTimeInputType(HTMLInputElement& element) : InputType(element) { }
Decimal parseToNumber(const String&, const Decimal&) const override;
- bool parseToDateComponents(const String&, DateComponents*) const override;
String sanitizeValue(const String&) const override;
String serialize(const Decimal&) const override;
String serializeWithComponents(const DateComponents&) const;
- virtual bool setMillisecondToDateComponents(double, DateComponents*) const = 0;
String visibleValue() const override;
void attributeChanged(const QualifiedName&) override;
#if PLATFORM(IOS_FAMILY)
@@ -56,10 +54,9 @@
#endif
private:
- virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const = 0;
-#if !PLATFORM(IOS_FAMILY)
- virtual DateComponents::Type dateType() const = 0;
-#endif
+ virtual Optional<DateComponents> parseToDateComponents(const StringView&) const = 0;
+ virtual Optional<DateComponents> setMillisecondToDateComponents(double) const = 0;
+
double valueAsDate() const override;
ExceptionOr<void> setValueAsDate(double) const override;
double valueAsDouble() const override;
Modified: trunk/Source/WebCore/html/DateInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/DateInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/DateInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -70,17 +70,14 @@
return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, dateStepDescription);
}
-bool DateInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+Optional<DateComponents> DateInputType::parseToDateComponents(const StringView& source) const
{
- ASSERT(out);
- unsigned end;
- return out->parseDate(characters, length, 0, end) && end == length;
+ return DateComponents::fromParsingDate(source);
}
-bool DateInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+Optional<DateComponents> DateInputType::setMillisecondToDateComponents(double value) const
{
- ASSERT(date);
- return date->setMillisecondsSinceEpochForDate(value);
+ return DateComponents::fromMillisecondsSinceEpochForDate(value);
}
bool DateInputType::isDateField() const
Modified: trunk/Source/WebCore/html/DateInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/DateInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/DateInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -44,8 +44,8 @@
const AtomString& formControlType() const override;
DateComponents::Type dateType() const override;
StepRange createStepRange(AnyStepHandling) const override;
- bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const override;
- bool setMillisecondToDateComponents(double, DateComponents*) const override;
+ Optional<DateComponents> parseToDateComponents(const StringView&) const override;
+ Optional<DateComponents> setMillisecondToDateComponents(double) const override;
bool isDateField() const override;
};
Modified: trunk/Source/WebCore/html/DateTimeInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/DateTimeInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/DateTimeInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -69,17 +69,14 @@
return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, dateTimeStepDescription);
}
-bool DateTimeInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+Optional<DateComponents> DateTimeInputType::parseToDateComponents(const StringView& source) const
{
- ASSERT(out);
- unsigned end;
- return out->parseDateTime(characters, length, 0, end) && end == length;
+ return DateComponents::fromParsingDateTime(source);
}
-bool DateTimeInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+Optional<DateComponents> DateTimeInputType::setMillisecondToDateComponents(double value) const
{
- ASSERT(date);
- return date->setMillisecondsSinceEpochForDateTime(value);
+ return DateComponents::fromMillisecondsSinceEpochForDateTime(value);
}
bool DateTimeInputType::isDateTimeField() const
@@ -89,10 +86,10 @@
String DateTimeInputType::sanitizeValue(const String& proposedValue) const
{
- DateComponents date;
- if (!parseToDateComponents(proposedValue, &date))
- return String();
- return date.toString();
+ auto date = parseToDateComponents(proposedValue);
+ if (!date)
+ return { };
+ return date->toString();
}
} // namespace WebCore
Modified: trunk/Source/WebCore/html/DateTimeInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/DateTimeInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/DateTimeInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -46,8 +46,8 @@
DateComponents::Type dateType() const override;
StepRange createStepRange(AnyStepHandling) const override;
Decimal defaultValueForStepUp() const override;
- bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const override;
- bool setMillisecondToDateComponents(double, DateComponents*) const override;
+ Optional<DateComponents> parseToDateComponents(const StringView&) const override;
+ Optional<DateComponents> setMillisecondToDateComponents(double) const override;
bool isDateTimeField() const override;
String sanitizeValue(const String&) const override;
};
Modified: trunk/Source/WebCore/html/DateTimeLocalInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/DateTimeLocalInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/DateTimeLocalInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -78,17 +78,14 @@
return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, dateTimeLocalStepDescription);
}
-bool DateTimeLocalInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+Optional<DateComponents> DateTimeLocalInputType::parseToDateComponents(const StringView& source) const
{
- ASSERT(out);
- unsigned end;
- return out->parseDateTimeLocal(characters, length, 0, end) && end == length;
+ return DateComponents::fromParsingDateTimeLocal(source);
}
-bool DateTimeLocalInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+Optional<DateComponents> DateTimeLocalInputType::setMillisecondToDateComponents(double value) const
{
- ASSERT(date);
- return date->setMillisecondsSinceEpochForDateTimeLocal(value);
+ return DateComponents::fromMillisecondsSinceEpochForDateTimeLocal(value);
}
bool DateTimeLocalInputType::isDateTimeLocalField() const
Modified: trunk/Source/WebCore/html/DateTimeLocalInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/DateTimeLocalInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/DateTimeLocalInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -46,8 +46,8 @@
double valueAsDate() const final;
ExceptionOr<void> setValueAsDate(double) const final;
StepRange createStepRange(AnyStepHandling) const final;
- bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const final;
- bool setMillisecondToDateComponents(double, DateComponents*) const final;
+ Optional<DateComponents> parseToDateComponents(const StringView&) const final;
+ Optional<DateComponents> setMillisecondToDateComponents(double) const final;
bool isDateTimeLocalField() const final;
};
Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/HTMLInputElement.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -1674,12 +1674,10 @@
return m_inputType->isSteppable();
}
-#if PLATFORM(IOS_FAMILY)
DateComponents::Type HTMLInputElement::dateType() const
{
return m_inputType->dateType();
}
-#endif
bool HTMLInputElement::isTextButton() const
{
Modified: trunk/Source/WebCore/html/HTMLInputElement.h (263899 => 263900)
--- trunk/Source/WebCore/html/HTMLInputElement.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/HTMLInputElement.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -24,6 +24,7 @@
#pragma once
+#include "DateComponents.h"
#include "FileChooser.h"
#include "HTMLTextFormControlElement.h"
#include "StepRange.h"
@@ -30,10 +31,6 @@
#include <memory>
#include <wtf/WeakPtr.h>
-#if PLATFORM(IOS_FAMILY)
-#include "DateComponents.h"
-#endif
-
namespace WebCore {
class DragData;
@@ -131,9 +128,7 @@
WEBCORE_EXPORT bool isTimeField() const;
WEBCORE_EXPORT bool isWeekField() const;
-#if PLATFORM(IOS_FAMILY)
DateComponents::Type dateType() const;
-#endif
HTMLElement* containerElement() const;
Modified: trunk/Source/WebCore/html/InputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/InputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/InputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -522,12 +522,6 @@
return parseToNumber(string, Decimal::nan());
}
-bool InputType::parseToDateComponents(const String&, DateComponents*) const
-{
- ASSERT_NOT_REACHED();
- return false;
-}
-
String InputType::serialize(const Decimal&) const
{
ASSERT_NOT_REACHED();
@@ -534,12 +528,10 @@
return String();
}
-#if PLATFORM(IOS_FAMILY)
DateComponents::Type InputType::dateType() const
{
return DateComponents::Invalid;
}
-#endif
void InputType::dispatchSimulatedClickIfActive(KeyboardEvent& event) const
{
Modified: trunk/Source/WebCore/html/InputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/InputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/InputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -282,12 +282,6 @@
// return NaN or Infinity only if defaultValue is NaN or Infinity.
virtual Decimal parseToNumber(const String&, const Decimal& defaultValue) const;
- // Parses the specified string for this InputType, and returns true if it
- // is successfully parsed. An instance pointed by the DateComponents*
- // parameter will have parsed values and be modified even if the parsing
- // fails. The DateComponents* parameter may be null.
- virtual bool parseToDateComponents(const String&, DateComponents*) const;
-
// Create a string representation of the specified Decimal value for the
// input type. If NaN or Infinity is specified, this returns an empty
// string. This should not be called for types without valueAsNumber.
@@ -309,9 +303,8 @@
virtual bool receiveDroppedFiles(const DragData&);
#endif
-#if PLATFORM(IOS_FAMILY)
virtual DateComponents::Type dateType() const;
-#endif
+
virtual String displayString() const;
protected:
Modified: trunk/Source/WebCore/html/MonthInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/MonthInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/MonthInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -61,10 +61,10 @@
double MonthInputType::valueAsDate() const
{
ASSERT(element());
- DateComponents date;
- if (!parseToDateComponents(element()->value(), &date))
+ auto date = parseToDateComponents(element()->value());
+ if (!date)
return DateComponents::invalidMilliseconds();
- double msec = date.millisecondsSinceEpoch();
+ double msec = date->millisecondsSinceEpoch();
ASSERT(std::isfinite(msec));
return msec;
}
@@ -71,10 +71,10 @@
String MonthInputType::serializeWithMilliseconds(double value) const
{
- DateComponents date;
- if (!date.setMillisecondsSinceEpochForMonth(value))
- return String();
- return serializeWithComponents(date);
+ auto date = DateComponents::fromMillisecondsSinceEpochForMonth(value);
+ if (!date)
+ return { };
+ return serializeWithComponents(*date);
}
Decimal MonthInputType::defaultValueForStepUp() const
@@ -83,9 +83,11 @@
int offset = calculateLocalTimeOffset(current).offset / msPerMinute;
current += offset * msPerMinute;
- DateComponents date;
- date.setMillisecondsSinceEpochForMonth(current);
- double months = date.monthsSinceEpoch();
+ auto date = DateComponents::fromMillisecondsSinceEpochForMonth(current);
+ if (!date)
+ return { };
+
+ double months = date->monthsSinceEpoch();
ASSERT(std::isfinite(months));
return Decimal::fromDouble(months);
}
@@ -102,25 +104,22 @@
Decimal MonthInputType::parseToNumber(const String& src, const Decimal& defaultValue) const
{
- DateComponents date;
- if (!parseToDateComponents(src, &date))
+ auto date = parseToDateComponents(src);
+ if (!date)
return defaultValue;
- double months = date.monthsSinceEpoch();
+ double months = date->monthsSinceEpoch();
ASSERT(std::isfinite(months));
return Decimal::fromDouble(months);
}
-bool MonthInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+Optional<DateComponents> MonthInputType::parseToDateComponents(const StringView& source) const
{
- ASSERT(out);
- unsigned end;
- return out->parseMonth(characters, length, 0, end) && end == length;
+ return DateComponents::fromParsingMonth(source);
}
-bool MonthInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+Optional<DateComponents> MonthInputType::setMillisecondToDateComponents(double value) const
{
- ASSERT(date);
- return date->setMonthsSinceEpoch(value);
+ return DateComponents::fromMonthsSinceEpoch(value);
}
bool MonthInputType::isMonthField() const
Modified: trunk/Source/WebCore/html/MonthInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/MonthInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/MonthInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -48,8 +48,8 @@
Decimal parseToNumber(const String&, const Decimal&) const override;
Decimal defaultValueForStepUp() const override;
StepRange createStepRange(AnyStepHandling) const override;
- bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const override;
- bool setMillisecondToDateComponents(double, DateComponents*) const override;
+ Optional<DateComponents> parseToDateComponents(const StringView&) const override;
+ Optional<DateComponents> setMillisecondToDateComponents(double) const override;
bool isMonthField() const override;
};
Modified: trunk/Source/WebCore/html/TimeInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/TimeInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/TimeInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -68,9 +68,11 @@
int offset = calculateLocalTimeOffset(current).offset / msPerMinute;
current += offset * msPerMinute;
- DateComponents date;
- date.setMillisecondsSinceMidnight(current);
- double milliseconds = date.millisecondsSinceEpoch();
+ auto date = DateComponents::fromMillisecondsSinceMidnight(current);
+ if (!date)
+ return { };
+
+ double milliseconds = date->millisecondsSinceEpoch();
ASSERT(std::isfinite(milliseconds));
return Decimal::fromDouble(milliseconds);
}
@@ -85,17 +87,14 @@
return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, timeStepDescription);
}
-bool TimeInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+Optional<DateComponents> TimeInputType::parseToDateComponents(const StringView& source) const
{
- ASSERT(out);
- unsigned end;
- return out->parseTime(characters, length, 0, end) && end == length;
+ return DateComponents::fromParsingTime(source);
}
-bool TimeInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+Optional<DateComponents> TimeInputType::setMillisecondToDateComponents(double value) const
{
- ASSERT(date);
- return date->setMillisecondsSinceMidnight(value);
+ return DateComponents::fromMillisecondsSinceMidnight(value);
}
bool TimeInputType::isTimeField() const
Modified: trunk/Source/WebCore/html/TimeInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/TimeInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/TimeInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -45,8 +45,8 @@
DateComponents::Type dateType() const override;
Decimal defaultValueForStepUp() const override;
StepRange createStepRange(AnyStepHandling) const override;
- bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const override;
- bool setMillisecondToDateComponents(double, DateComponents*) const override;
+ Optional<DateComponents> parseToDateComponents(const StringView&) const override;
+ Optional<DateComponents> setMillisecondToDateComponents(double) const override;
bool isTimeField() const override;
};
Modified: trunk/Source/WebCore/html/WeekInputType.cpp (263899 => 263900)
--- trunk/Source/WebCore/html/WeekInputType.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/WeekInputType.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -65,17 +65,14 @@
return StepRange(stepBase, RangeLimitations::Valid, minimum, maximum, step, weekStepDescription);
}
-bool WeekInputType::parseToDateComponentsInternal(const UChar* characters, unsigned length, DateComponents* out) const
+Optional<DateComponents> WeekInputType::parseToDateComponents(const StringView& source) const
{
- ASSERT(out);
- unsigned end;
- return out->parseWeek(characters, length, 0, end) && end == length;
+ return DateComponents::fromParsingWeek(source);
}
-bool WeekInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+Optional<DateComponents> WeekInputType::setMillisecondToDateComponents(double value) const
{
- ASSERT(date);
- return date->setMillisecondsSinceEpochForWeek(value);
+ return DateComponents::fromMillisecondsSinceEpochForWeek(value);
}
bool WeekInputType::isWeekField() const
Modified: trunk/Source/WebCore/html/WeekInputType.h (263899 => 263900)
--- trunk/Source/WebCore/html/WeekInputType.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/html/WeekInputType.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -44,8 +44,8 @@
const AtomString& formControlType() const override;
DateComponents::Type dateType() const override;
StepRange createStepRange(AnyStepHandling) const override;
- bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const override;
- bool setMillisecondToDateComponents(double, DateComponents*) const override;
+ Optional<DateComponents> parseToDateComponents(const StringView&) const override;
+ Optional<DateComponents> setMillisecondToDateComponents(double) const override;
bool isWeekField() const override;
};
Modified: trunk/Source/WebCore/platform/DateComponents.cpp (263899 => 263900)
--- trunk/Source/WebCore/platform/DateComponents.cpp 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/platform/DateComponents.cpp 2020-07-03 16:45:29 UTC (rev 263900)
@@ -96,7 +96,7 @@
return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? maximumWeekNumber : maximumWeekNumber - 1;
}
-static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
+template<typename CharacterType> static unsigned countDigits(const CharacterType* src, unsigned length, unsigned start)
{
unsigned index = start;
for (; index < length; ++index) {
@@ -107,13 +107,13 @@
}
// Very strict integer parser. Do not allow leading or trailing whitespace unlike charactersToIntStrict().
-static bool toInt(const UChar* src, unsigned length, unsigned parseStart, unsigned parseLength, int& out)
+template<typename CharacterType> static bool toInt(const CharacterType* src, unsigned length, unsigned parseStart, unsigned parseLength, int& out)
{
if (parseStart + parseLength > length || parseLength <= 0)
return false;
int value = 0;
- const UChar* current = src + parseStart;
- const UChar* end = current + parseLength;
+ auto current = src + parseStart;
+ auto end = current + parseLength;
// We don't need to handle negative numbers for ISO 8601.
for (; current < end; ++current) {
@@ -128,7 +128,7 @@
return true;
}
-bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseYear(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
unsigned digitsLength = countDigits(src, length, start);
// Needs at least 4 digits according to the standard.
@@ -180,6 +180,67 @@
return !hour && !minute && !second && !millisecond;
}
+template<typename F> static Optional<DateComponents> createFromString(StringView source, F&& parseFunction)
+{
+ if (source.isEmpty())
+ return WTF::nullopt;
+
+ DateComponents result;
+ unsigned end;
+ if (source.is8Bit()) {
+ if (!parseFunction(result, source.characters8(), source.length(), end))
+ return WTF::nullopt;
+ } else {
+ if (!parseFunction(result, source.characters16(), source.length(), end))
+ return WTF::nullopt;
+ }
+ if (end != source.length())
+ return WTF::nullopt;
+ return result;
+}
+
+Optional<DateComponents> DateComponents::fromParsingMonth(StringView source)
+{
+ return createFromString(source, [] (auto& date, const auto* src, auto length, auto& end) {
+ return date.parseMonth(src, length, 0, end);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromParsingDate(StringView source)
+{
+ return createFromString(source, [] (auto& date, const auto* src, auto length, auto& end) {
+ return date.parseDate(src, length, 0, end);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromParsingWeek(StringView source)
+{
+ return createFromString(source, [] (auto& date, const auto* src, auto length, auto& end) {
+ return date.parseWeek(src, length, 0, end);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromParsingTime(StringView source)
+{
+ return createFromString(source, [] (auto& date, const auto* src, auto length, auto& end) {
+ return date.parseTime(src, length, 0, end);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromParsingDateTimeLocal(StringView source)
+{
+ return createFromString(source, [] (auto& date, const auto* src, auto length, auto& end) {
+ return date.parseDateTimeLocal(src, length, 0, end);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromParsingDateTime(StringView source)
+{
+ return createFromString(source, [] (auto& date, const auto* src, auto length, auto& end) {
+ return date.parseDateTime(src, length, 0, end);
+ });
+}
+
bool DateComponents::addDay(int dayDiff)
{
ASSERT(m_monthDay);
@@ -283,7 +344,7 @@
}
// Parses a timezone part, and adjust year, month, monthDay, hour, minute, second, millisecond.
-bool DateComponents::parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseTimeZone(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
if (start >= length)
return false;
@@ -328,7 +389,7 @@
return true;
}
-bool DateComponents::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseMonth(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
ASSERT(src);
unsigned index;
@@ -350,7 +411,7 @@
return true;
}
-bool DateComponents::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseDate(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
ASSERT(src);
unsigned index;
@@ -374,7 +435,7 @@
return true;
}
-bool DateComponents::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseWeek(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
ASSERT(src);
unsigned index;
@@ -402,7 +463,7 @@
return true;
}
-bool DateComponents::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseTime(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
ASSERT(src);
int hour;
@@ -457,7 +518,7 @@
return true;
}
-bool DateComponents::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseDateTimeLocal(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
ASSERT(src);
unsigned index;
@@ -476,7 +537,7 @@
return true;
}
-bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+template<typename CharacterType> bool DateComponents::parseDateTime(const CharacterType* src, unsigned length, unsigned start, unsigned& end)
{
ASSERT(src);
unsigned index;
@@ -503,6 +564,63 @@
return remainder < 0 ? remainder + divider : remainder;
}
+template<typename F> static Optional<DateComponents> createFromTimeOffset(double timeOffset, F&& function)
+{
+ DateComponents result;
+ if (!function(result, timeOffset))
+ return WTF::nullopt;
+ return result;
+}
+
+Optional<DateComponents> DateComponents::fromMillisecondsSinceEpochForDate(double ms)
+{
+ return createFromTimeOffset(ms, [] (auto& date, auto ms) {
+ return date.setMillisecondsSinceEpochForDate(ms);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromMillisecondsSinceEpochForDateTime(double ms)
+{
+ return createFromTimeOffset(ms, [] (auto& date, auto ms) {
+ return date.setMillisecondsSinceEpochForDateTime(ms);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromMillisecondsSinceEpochForDateTimeLocal(double ms)
+{
+ return createFromTimeOffset(ms, [] (auto& date, auto ms) {
+ return date.setMillisecondsSinceEpochForDateTimeLocal(ms);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromMillisecondsSinceEpochForMonth(double ms)
+{
+ return createFromTimeOffset(ms, [] (auto& date, auto ms) {
+ return date.setMillisecondsSinceEpochForMonth(ms);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromMillisecondsSinceEpochForWeek(double ms)
+{
+ return createFromTimeOffset(ms, [] (auto& date, auto ms) {
+ return date.setMillisecondsSinceEpochForWeek(ms);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromMillisecondsSinceMidnight(double ms)
+{
+ return createFromTimeOffset(ms, [] (auto& date, auto ms) {
+ return date.setMillisecondsSinceMidnight(ms);
+ });
+}
+
+Optional<DateComponents> DateComponents::fromMonthsSinceEpoch(double months)
+{
+ return createFromTimeOffset(months, [] (auto& date, auto months) {
+ return date.setMonthsSinceEpoch(months);
+ });
+}
+
void DateComponents::setMillisecondsSinceMidnightInternal(double msInDay)
{
ASSERT(msInDay >= 0 && msInDay < msPerDay);
Modified: trunk/Source/WebCore/platform/DateComponents.h (263899 => 263900)
--- trunk/Source/WebCore/platform/DateComponents.h 2020-07-03 15:09:38 UTC (rev 263899)
+++ trunk/Source/WebCore/platform/DateComponents.h 2020-07-03 16:45:29 UTC (rev 263900)
@@ -28,8 +28,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef DateComponents_h
-#define DateComponents_h
+#pragma once
#include <limits>
#include <unicode/utypes.h>
@@ -86,101 +85,109 @@
// Returns an ISO 8601 representation for this instance.
// The format argument is valid for DateTime, DateTimeLocal, and Time types.
- String toString(SecondFormat format = None) const;
+ String toString(SecondFormat = None) const;
- // parse*() and setMillisecondsSince*() functions are initializers for an
- // DateComponents instance. If these functions return false, the instance
- // might be invalid.
-
- // The following six functions parse the input 'src' whose length is
- // 'length', and updates some fields of this instance. The parsing starts at
- // src[start] and examines characters before src[length].
- // 'src' must be non-null. The 'src' string doesn't need to be
- // null-terminated.
- // The functions return true if the parsing succeeds, and set 'end' to the
- // next index after the last consumed. Extra leading characters cause parse
- // failures, and the trailing extra characters don't cause parse failures.
-
// Sets year and month.
- bool parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ static Optional<DateComponents> fromParsingMonth(StringView);
// Sets year, month and monthDay.
- bool parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ static Optional<DateComponents> fromParsingDate(StringView);
// Sets year and week.
- bool parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ static Optional<DateComponents> fromParsingWeek(StringView);
// Sets hour, minute, second and millisecond.
- bool parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ static Optional<DateComponents> fromParsingTime(StringView);
// Sets year, month, monthDay, hour, minute, second and millisecond.
- bool parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ static Optional<DateComponents> fromParsingDateTimeLocal(StringView);
// Sets year, month, monthDay, hour, minute, second and millisecond, and adjusts timezone.
- bool parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ static Optional<DateComponents> fromParsingDateTime(StringView);
- // The following setMillisecondsSinceEpochFor*() functions take
- // the number of milliseconds since 1970-01-01 00:00:00.000 UTC as
- // the argument, and update all fields for the corresponding
- // DateComponents type. The functions return true if it succeeds, and
- // false if they fail.
// For Date type. Updates m_year, m_month and m_monthDay.
- bool setMillisecondsSinceEpochForDate(double ms);
+ static Optional<DateComponents> fromMillisecondsSinceEpochForDate(double ms);
// For DateTime type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
- bool setMillisecondsSinceEpochForDateTime(double ms);
+ static Optional<DateComponents> fromMillisecondsSinceEpochForDateTime(double ms);
// For DateTimeLocal type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
- bool setMillisecondsSinceEpochForDateTimeLocal(double ms);
+ static Optional<DateComponents> fromMillisecondsSinceEpochForDateTimeLocal(double ms);
// For Month type. Updates m_year and m_month.
- bool setMillisecondsSinceEpochForMonth(double ms);
+ static Optional<DateComponents> fromMillisecondsSinceEpochForMonth(double ms);
// For Week type. Updates m_year and m_week.
- bool setMillisecondsSinceEpochForWeek(double ms);
+ static Optional<DateComponents> fromMillisecondsSinceEpochForWeek(double ms);
// For Time type. Updates m_hour, m_minute, m_second and m_millisecond.
- bool setMillisecondsSinceMidnight(double ms);
+ static Optional<DateComponents> fromMillisecondsSinceMidnight(double ms);
// Another initializer for Month type. Updates m_year and m_month.
- bool setMonthsSinceEpoch(double months);
+ static Optional<DateComponents> fromMonthsSinceEpoch(double months);
// Returns the number of milliseconds from 1970-01-01 00:00:00 UTC.
// For a DateComponents initialized with parseDateTimeLocal(),
// millisecondsSinceEpoch() returns a value for UTC timezone.
double millisecondsSinceEpoch() const;
+
// Returns the number of months from 1970-01.
// Do not call this for types other than Month.
double monthsSinceEpoch() const;
+
static inline double invalidMilliseconds() { return std::numeric_limits<double>::quiet_NaN(); }
// Minimum and maxmimum limits for setMillisecondsSince*(),
// setMonthsSinceEpoch(), millisecondsSinceEpoch(), and monthsSinceEpoch().
- static inline double minimumDate() { return -62135596800000.0; } // 0001-01-01T00:00Z
- static inline double minimumDateTime() { return -62135596800000.0; } // ditto.
- static inline double minimumMonth() { return (1 - 1970) * 12.0 + 1 - 1; } // 0001-01
- static inline double minimumTime() { return 0; } // 00:00:00.000
- static inline double minimumWeek() { return -62135596800000.0; } // 0001-01-01, the first Monday of 0001.
- static inline double maximumDate() { return 8640000000000000.0; } // 275760-09-13T00:00Z
- static inline double maximumDateTime() { return 8640000000000000.0; } // ditto.
- static inline double maximumMonth() { return (275760 - 1970) * 12.0 + 9 - 1; } // 275760-09
- static inline double maximumTime() { return 86399999; } // 23:59:59.999
- static inline double maximumWeek() { return 8639999568000000.0; } // 275760-09-08, the Monday of the week including 275760-09-13.
+ static constexpr inline double minimumDate() { return -62135596800000.0; } // 0001-01-01T00:00Z
+ static constexpr inline double minimumDateTime() { return -62135596800000.0; } // ditto.
+ static constexpr inline double minimumMonth() { return (1 - 1970) * 12.0 + 1 - 1; } // 0001-01
+ static constexpr inline double minimumTime() { return 0; } // 00:00:00.000
+ static constexpr inline double minimumWeek() { return -62135596800000.0; } // 0001-01-01, the first Monday of 0001.
+ static constexpr inline double maximumDate() { return 8640000000000000.0; } // 275760-09-13T00:00Z
+ static constexpr inline double maximumDateTime() { return 8640000000000000.0; } // ditto.
+ static constexpr inline double maximumMonth() { return (275760 - 1970) * 12.0 + 9 - 1; } // 275760-09
+ static constexpr inline double maximumTime() { return 86399999; } // 23:59:59.999
+ static constexpr inline double maximumWeek() { return 8639999568000000.0; } // 275760-09-08, the Monday of the week including 275760-09-13.
// HTML5 uses ISO-8601 format with year >= 1. Gregorian calendar started in
// 1582. However, we need to support 0001-01-01 in Gregorian calendar rule.
static inline int minimumYear() { return 1; }
+
// Date in ECMAScript can't represent dates later than 275760-09-13T00:00Z.
// So, we have the same upper limit in HTML5 date/time types.
static inline int maximumYear() { return 275760; }
+
static const int minimumWeekNumber;
static const int maximumWeekNumber;
private:
+ template<typename CharacterType> bool parseMonth(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseDate(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseWeek(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseTime(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseDateTimeLocal(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseDateTime(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseYear(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+ template<typename CharacterType> bool parseTimeZone(const CharacterType* src, unsigned length, unsigned start, unsigned& end);
+
+ // The following setMillisecondsSinceEpochFor*() functions take
+ // the number of milliseconds since 1970-01-01 00:00:00.000 UTC as
+ // the argument, and update all fields for the corresponding
+ // DateComponents type. The functions return true if it succeeds, and
+ // false if they fail.
+ bool setMillisecondsSinceEpochForDate(double);
+ bool setMillisecondsSinceEpochForDateTime(double);
+ bool setMillisecondsSinceEpochForDateTimeLocal(double);
+ bool setMillisecondsSinceEpochForMonth(double);
+ bool setMillisecondsSinceEpochForWeek(double);
+ bool setMillisecondsSinceMidnight(double);
+ bool setMonthsSinceEpoch(double);
+ bool setMillisecondsSinceEpochForDateInternal(double);
+ void setMillisecondsSinceMidnightInternal(double);
+
// Returns the maximum week number in this DateComponents's year.
// The result is either of 52 and 53.
int maxWeekNumberInYear() const;
- bool parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end);
+
bool addDay(int);
bool addMinute(int);
- bool parseTimeZone(const UChar* src, unsigned length, unsigned start, unsigned& end);
+
// Helper for millisecondsSinceEpoch().
double millisecondsSinceEpochForTime() const;
- // Helpers for setMillisecondsSinceEpochFor*().
- bool setMillisecondsSinceEpochForDateInternal(double ms);
- void setMillisecondsSinceMidnightInternal(double ms);
+
// Helper for toString().
String toStringForTime(SecondFormat) const;
@@ -207,7 +214,4 @@
Type m_type;
};
-
} // namespace WebCore
-
-#endif // DateComponents_h