Diff
Modified: trunk/Source/WTF/ChangeLog (225554 => 225555)
--- trunk/Source/WTF/ChangeLog 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WTF/ChangeLog 2017-12-05 23:59:31 UTC (rev 225555)
@@ -1,3 +1,15 @@
+2017-12-05 Matt Lewis <[email protected]>
+
+ Unreviewed, rolling out r225430.
+
+ This caused an API failure on release.
+
+ Reverted changeset:
+
+ "Move DateComponents into WTF"
+ https://bugs.webkit.org/show_bug.cgi?id=180211
+ https://trac.webkit.org/changeset/225430
+
2017-12-05 Michael Saboff <[email protected]>
Make WebKit build for ARM64_32
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (225554 => 225555)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-12-05 23:59:31 UTC (rev 225555)
@@ -85,7 +85,6 @@
93F1993E19D7958D00C2390B /* StringView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F1993D19D7958D00C2390B /* StringView.cpp */; };
9BC70F05176C379D00101DEC /* AtomicStringTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9BC70F04176C379D00101DEC /* AtomicStringTable.cpp */; };
A3B725EC987446AD93F1A440 /* RandomDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C8F597CA2A57417FBAB92FD6 /* RandomDevice.cpp */; };
- A3CABA081FD095110007A4DE /* DateComponents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3CABA061FD095110007A4DE /* DateComponents.cpp */; };
A3E4DD931F3A803400DED0B4 /* TextStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A3E4DD911F3A803400DED0B4 /* TextStream.cpp */; };
A5BA15F3182433A900A82E69 /* StringMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5BA15F2182433A900A82E69 /* StringMac.mm */; };
A5BA15F51824348000A82E69 /* StringImplMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = A5BA15F41824348000A82E69 /* StringImplMac.mm */; };
@@ -400,8 +399,6 @@
A30D412C1F0DE0BA00B71954 /* SoftLinking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoftLinking.h; sourceTree = "<group>"; };
A30D412D1F0DE13F00B71954 /* SoftLinking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SoftLinking.h; sourceTree = "<group>"; };
A3AB6E6A1F3E1AD6009C14B1 /* ValueToString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueToString.h; sourceTree = "<group>"; };
- A3CABA061FD095110007A4DE /* DateComponents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DateComponents.cpp; sourceTree = "<group>"; };
- A3CABA071FD095110007A4DE /* DateComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateComponents.h; sourceTree = "<group>"; };
A3E4DD911F3A803400DED0B4 /* TextStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextStream.cpp; sourceTree = "<group>"; };
A3E4DD921F3A803400DED0B4 /* TextStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextStream.h; sourceTree = "<group>"; };
A5098AFF1C169E0700087797 /* SandboxSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SandboxSPI.h; sourceTree = "<group>"; };
@@ -830,8 +827,6 @@
A8A47276151A825A004123FF /* CurrentTime.h */,
A8A47277151A825A004123FF /* DataLog.cpp */,
A8A47278151A825A004123FF /* DataLog.h */,
- A3CABA061FD095110007A4DE /* DateComponents.cpp */,
- A3CABA071FD095110007A4DE /* DateComponents.h */,
A8A47279151A825A004123FF /* DateMath.cpp */,
A8A4727A151A825A004123FF /* DateMath.h */,
996B17841EBA441C007E10EB /* DebugUtilities.h */,
@@ -1413,7 +1408,6 @@
A8A47439151A825B004123FF /* CString.cpp in Sources */,
A8A4739C151A825B004123FF /* CurrentTime.cpp in Sources */,
A8A4739E151A825B004123FF /* DataLog.cpp in Sources */,
- A3CABA081FD095110007A4DE /* DateComponents.cpp in Sources */,
A8A473A0151A825B004123FF /* DateMath.cpp in Sources */,
A8A473A2151A825B004123FF /* DecimalNumber.cpp in Sources */,
1ACADD841884480100D8B71D /* DeprecatedSymbolsUsedBySafari.mm in Sources */,
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (225554 => 225555)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2017-12-05 23:59:31 UTC (rev 225555)
@@ -232,7 +232,6 @@
CryptographicallyRandomNumber.cpp
CurrentTime.cpp
DataLog.cpp
- DateComponents.cpp
DateMath.cpp
DecimalNumber.cpp
FastBitVector.cpp
Deleted: trunk/Source/WTF/wtf/DateComponents.cpp (225554 => 225555)
--- trunk/Source/WTF/wtf/DateComponents.cpp 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WTF/wtf/DateComponents.cpp 2017-12-05 23:59:31 UTC (rev 225555)
@@ -1,718 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DateComponents.h"
-
-#include <limits.h>
-#include <wtf/ASCIICType.h>
-#include <wtf/DateMath.h>
-#include <wtf/MathExtras.h>
-#include <wtf/text/WTFString.h>
-
-namespace WTF {
-
-// HTML5 specification defines minimum week of year is one.
-const int DateComponents::minimumWeekNumber = 1;
-
-// HTML5 specification defines maximum week of year is 53.
-const int DateComponents::maximumWeekNumber = 53;
-
-static const int maximumMonthInMaximumYear = 8; // This is September, since months are 0 based.
-static const int maximumDayInMaximumMonth = 13;
-static const int maximumWeekInMaximumYear = 37; // The week of 275760-09-13
-
-static const int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-// 'month' is 0-based.
-static int maxDayOfMonth(int year, int month)
-{
- if (month != 1) // February?
- return daysInMonth[month];
- return isLeapYear(year) ? 29 : 28;
-}
-
-// 'month' is 0-based.
-static int dayOfWeek(int year, int month, int day)
-{
- int shiftedMonth = month + 2;
- // 2:January, 3:Feburuary, 4:March, ...
-
- // Zeller's congruence
- if (shiftedMonth <= 3) {
- shiftedMonth += 12;
- year--;
- }
- // 4:March, ..., 14:January, 15:February
-
- int highYear = year / 100;
- int lowYear = year % 100;
- // We add 6 to make the result Sunday-origin.
- int result = (day + 13 * shiftedMonth / 5 + lowYear + lowYear / 4 + highYear / 4 + 5 * highYear + 6) % 7;
- return result;
-}
-
-int DateComponents::maxWeekNumberInYear() const
-{
- int day = dayOfWeek(m_year, 0, 1); // January 1.
- return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? maximumWeekNumber : maximumWeekNumber - 1;
-}
-
-static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
-{
- unsigned index = start;
- for (; index < length; ++index) {
- if (!isASCIIDigit(src[index]))
- break;
- }
- return index - start;
-}
-
-// 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)
-{
- if (parseStart + parseLength > length || parseLength <= 0)
- return false;
- int value = 0;
- const UChar* current = src + parseStart;
- const UChar* end = current + parseLength;
-
- // We don't need to handle negative numbers for ISO 8601.
- for (; current < end; ++current) {
- if (!isASCIIDigit(*current))
- return false;
- int digit = *current - '0';
- if (value > (INT_MAX - digit) / 10) // Check for overflow.
- return false;
- value = value * 10 + digit;
- }
- out = value;
- return true;
-}
-
-bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- unsigned digitsLength = countDigits(src, length, start);
- // Needs at least 4 digits according to the standard.
- if (digitsLength < 4)
- return false;
- int year;
- if (!toInt(src, length, start, digitsLength, year))
- return false;
- if (year < minimumYear() || year > maximumYear())
- return false;
- m_year = year;
- end = start + digitsLength;
- return true;
-}
-
-static bool withinHTMLDateLimits(int year, int month)
-{
- if (year < DateComponents::minimumYear())
- return false;
- if (year < DateComponents::maximumYear())
- return true;
- return month <= maximumMonthInMaximumYear;
-}
-
-static bool withinHTMLDateLimits(int year, int month, int monthDay)
-{
- if (year < DateComponents::minimumYear())
- return false;
- if (year < DateComponents::maximumYear())
- return true;
- if (month < maximumMonthInMaximumYear)
- return true;
- return monthDay <= maximumDayInMaximumMonth;
-}
-
-static bool withinHTMLDateLimits(int year, int month, int monthDay, int hour, int minute, int second, int millisecond)
-{
- if (year < DateComponents::minimumYear())
- return false;
- if (year < DateComponents::maximumYear())
- return true;
- if (month < maximumMonthInMaximumYear)
- return true;
- if (monthDay < maximumDayInMaximumMonth)
- return true;
- if (monthDay > maximumDayInMaximumMonth)
- return false;
- // (year, month, monthDay) = (maximumYear, maximumMonthInMaximumYear, maximumDayInMaximumMonth)
- return !hour && !minute && !second && !millisecond;
-}
-
-bool DateComponents::addDay(int dayDiff)
-{
- ASSERT(m_monthDay);
-
- int day = m_monthDay + dayDiff;
- if (day > maxDayOfMonth(m_year, m_month)) {
- day = m_monthDay;
- int year = m_year;
- int month = m_month;
- int maxDay = maxDayOfMonth(year, month);
- for (; dayDiff > 0; --dayDiff) {
- ++day;
- if (day > maxDay) {
- day = 1;
- ++month;
- // month is 0-origin.
- if (month >= 12) {
- month = 0;
- ++year;
- }
- maxDay = maxDayOfMonth(year, month);
- }
- }
- if (!withinHTMLDateLimits(year, month, day))
- return false;
- m_year = year;
- m_month = month;
- } else if (day < 1) {
- int month = m_month;
- int year = m_year;
- day = m_monthDay;
- for (; dayDiff < 0; ++dayDiff) {
- --day;
- if (day < 1) {
- --month;
- if (month < 0) {
- month = 11;
- --year;
- }
- day = maxDayOfMonth(year, month);
- }
- }
- if (!withinHTMLDateLimits(year, month, day))
- return false;
- m_year = year;
- m_month = month;
- } else {
- if (!withinHTMLDateLimits(m_year, m_month, day))
- return false;
- }
- m_monthDay = day;
- return true;
-}
-
-bool DateComponents::addMinute(int minute)
-{
- // This function is used to adjust timezone offset. So m_year, m_month,
- // m_monthDay have values between the lower and higher limits.
- ASSERT(withinHTMLDateLimits(m_year, m_month, m_monthDay));
-
- int carry;
- // minute can be negative or greater than 59.
- minute += m_minute;
- if (minute > 59) {
- carry = minute / 60;
- minute = minute % 60;
- } else if (minute < 0) {
- carry = (59 - minute) / 60;
- minute += carry * 60;
- carry = -carry;
- ASSERT(minute >= 0 && minute <= 59);
- } else {
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, minute, m_second, m_millisecond))
- return false;
- m_minute = minute;
- return true;
- }
-
- int hour = m_hour + carry;
- if (hour > 23) {
- carry = hour / 24;
- hour = hour % 24;
- } else if (hour < 0) {
- carry = (23 - hour) / 24;
- hour += carry * 24;
- carry = -carry;
- ASSERT(hour >= 0 && hour <= 23);
- } else {
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
- return false;
- m_minute = minute;
- m_hour = hour;
- return true;
- }
- if (!addDay(carry))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
- return false;
- m_minute = minute;
- m_hour = hour;
- return true;
-}
-
-// 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)
-{
- if (start >= length)
- return false;
- unsigned index = start;
- if (src[index] == 'Z') {
- end = index + 1;
- return true;
- }
-
- bool minus;
- if (src[index] == '+')
- minus = false;
- else if (src[index] == '-')
- minus = true;
- else
- return false;
- ++index;
-
- int hour;
- int minute;
- if (!toInt(src, length, index, 2, hour) || hour < 0 || hour > 23)
- return false;
- index += 2;
-
- if (index >= length || src[index] != ':')
- return false;
- ++index;
-
- if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
- return false;
- index += 2;
-
- if (minus) {
- hour = -hour;
- minute = -minute;
- }
-
- // Subtract the timezone offset.
- if (!addMinute(-(hour * 60 + minute)))
- return false;
- end = index;
- return true;
-}
-
-bool DateComponents::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- ASSERT(src);
- unsigned index;
- if (!parseYear(src, length, start, index))
- return false;
- if (index >= length || src[index] != '-')
- return false;
- ++index;
-
- int month;
- if (!toInt(src, length, index, 2, month) || month < 1 || month > 12)
- return false;
- --month;
- if (!withinHTMLDateLimits(m_year, month))
- return false;
- m_month = month;
- end = index + 2;
- m_type = Month;
- return true;
-}
-
-bool DateComponents::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- ASSERT(src);
- unsigned index;
- if (!parseMonth(src, length, start, index))
- return false;
- // '-' and 2-digits are needed.
- if (index + 2 >= length)
- return false;
- if (src[index] != '-')
- return false;
- ++index;
-
- int day;
- if (!toInt(src, length, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month, day))
- return false;
- m_monthDay = day;
- end = index + 2;
- m_type = Date;
- return true;
-}
-
-bool DateComponents::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- ASSERT(src);
- unsigned index;
- if (!parseYear(src, length, start, index))
- return false;
-
- // 4 characters ('-' 'W' digit digit) are needed.
- if (index + 3 >= length)
- return false;
- if (src[index] != '-')
- return false;
- ++index;
- if (src[index] != 'W')
- return false;
- ++index;
-
- int week;
- if (!toInt(src, length, index, 2, week) || week < minimumWeekNumber || week > maxWeekNumberInYear())
- return false;
- if (m_year == maximumYear() && week > maximumWeekInMaximumYear)
- return false;
- m_week = week;
- end = index + 2;
- m_type = Week;
- return true;
-}
-
-bool DateComponents::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- ASSERT(src);
- int hour;
- if (!toInt(src, length, start, 2, hour) || hour < 0 || hour > 23)
- return false;
- unsigned index = start + 2;
- if (index >= length)
- return false;
- if (src[index] != ':')
- return false;
- ++index;
-
- int minute;
- if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
- return false;
- index += 2;
-
- int second = 0;
- int millisecond = 0;
- // Optional second part.
- // Do not return with false because the part is optional.
- if (index + 2 < length && src[index] == ':') {
- if (toInt(src, length, index + 1, 2, second) && second >= 0 && second <= 59) {
- index += 3;
-
- // Optional fractional second part.
- if (index < length && src[index] == '.') {
- unsigned digitsLength = countDigits(src, length, index + 1);
- if (digitsLength > 0) {
- ++index;
- bool ok;
- if (digitsLength == 1) {
- ok = toInt(src, length, index, 1, millisecond);
- millisecond *= 100;
- } else if (digitsLength == 2) {
- ok = toInt(src, length, index, 2, millisecond);
- millisecond *= 10;
- } else // digitsLength >= 3
- ok = toInt(src, length, index, 3, millisecond);
- ASSERT_UNUSED(ok, ok);
- index += digitsLength;
- }
- }
- }
- }
- m_hour = hour;
- m_minute = minute;
- m_second = second;
- m_millisecond = millisecond;
- end = index;
- m_type = Time;
- return true;
-}
-
-bool DateComponents::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- ASSERT(src);
- unsigned index;
- if (!parseDate(src, length, start, index))
- return false;
- if (index >= length)
- return false;
- if (src[index] != 'T')
- return false;
- ++index;
- if (!parseTime(src, length, index, end))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
- return false;
- m_type = DateTimeLocal;
- return true;
-}
-
-bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
-{
- ASSERT(src);
- unsigned index;
- if (!parseDate(src, length, start, index))
- return false;
- if (index >= length)
- return false;
- if (src[index] != 'T')
- return false;
- ++index;
- if (!parseTime(src, length, index, index))
- return false;
- if (!parseTimeZone(src, length, index, end))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
- return false;
- m_type = DateTime;
- return true;
-}
-
-static inline double positiveFmod(double value, double divider)
-{
- double remainder = fmod(value, divider);
- return remainder < 0 ? remainder + divider : remainder;
-}
-
-void DateComponents::setMillisecondsSinceMidnightInternal(double msInDay)
-{
- ASSERT(msInDay >= 0 && msInDay < msPerDay);
- m_millisecond = static_cast<int>(fmod(msInDay, msPerSecond));
- double value = floor(msInDay / msPerSecond);
- m_second = static_cast<int>(fmod(value, secondsPerMinute));
- value = floor(value / secondsPerMinute);
- m_minute = static_cast<int>(fmod(value, minutesPerHour));
- m_hour = static_cast<int>(value / minutesPerHour);
-}
-
-bool DateComponents::setMillisecondsSinceEpochForDateInternal(double ms)
-{
- m_year = msToYear(ms);
- int yearDay = dayInYear(ms, m_year);
- m_month = monthFromDayInYear(yearDay, isLeapYear(m_year));
- m_monthDay = dayInMonthFromDayInYear(yearDay, isLeapYear(m_year));
- return true;
-}
-
-bool DateComponents::setMillisecondsSinceEpochForDate(double ms)
-{
- m_type = Invalid;
- if (!std::isfinite(ms))
- return false;
- if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay))
- return false;
- m_type = Date;
- return true;
-}
-
-bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms)
-{
- m_type = Invalid;
- if (!std::isfinite(ms))
- return false;
- ms = round(ms);
- setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay));
- if (!setMillisecondsSinceEpochForDateInternal(ms))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
- return false;
- m_type = DateTime;
- return true;
-}
-
-bool DateComponents::setMillisecondsSinceEpochForDateTimeLocal(double ms)
-{
- // Internal representation of DateTimeLocal is the same as DateTime except m_type.
- if (!setMillisecondsSinceEpochForDateTime(ms))
- return false;
- m_type = DateTimeLocal;
- return true;
-}
-
-bool DateComponents::setMillisecondsSinceEpochForMonth(double ms)
-{
- m_type = Invalid;
- if (!std::isfinite(ms))
- return false;
- if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
- return false;
- if (!withinHTMLDateLimits(m_year, m_month))
- return false;
- m_type = Month;
- return true;
-}
-
-bool DateComponents::setMillisecondsSinceMidnight(double ms)
-{
- m_type = Invalid;
- if (!std::isfinite(ms))
- return false;
- setMillisecondsSinceMidnightInternal(positiveFmod(round(ms), msPerDay));
- m_type = Time;
- return true;
-}
-
-bool DateComponents::setMonthsSinceEpoch(double months)
-{
- if (!std::isfinite(months))
- return false;
- months = round(months);
- double doubleMonth = positiveFmod(months, 12);
- double doubleYear = 1970 + (months - doubleMonth) / 12;
- if (doubleYear < minimumYear() || maximumYear() < doubleYear)
- return false;
- int year = static_cast<int>(doubleYear);
- int month = static_cast<int>(doubleMonth);
- if (!withinHTMLDateLimits(year, month))
- return false;
- m_year = year;
- m_month = month;
- m_type = Month;
- return true;
-}
-
-// Offset from January 1st to Monday of the ISO 8601's first week.
-// ex. If January 1st is Friday, such Monday is 3 days later. Returns 3.
-static int offsetTo1stWeekStart(int year)
-{
- int offsetTo1stWeekStart = 1 - dayOfWeek(year, 0, 1);
- if (offsetTo1stWeekStart <= -4)
- offsetTo1stWeekStart += 7;
- return offsetTo1stWeekStart;
-}
-
-bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
-{
- m_type = Invalid;
- if (!std::isfinite(ms))
- return false;
- ms = round(ms);
-
- m_year = msToYear(ms);
- if (m_year < minimumYear() || m_year > maximumYear())
- return false;
-
- int yearDay = dayInYear(ms, m_year);
- int offset = offsetTo1stWeekStart(m_year);
- if (yearDay < offset) {
- // The day belongs to the last week of the previous year.
- m_year--;
- if (m_year <= minimumYear())
- return false;
- m_week = maxWeekNumberInYear();
- } else {
- m_week = ((yearDay - offset) / 7) + 1;
- if (m_week > maxWeekNumberInYear()) {
- m_year++;
- m_week = 1;
- }
- if (m_year > maximumYear() || (m_year == maximumYear() && m_week > maximumWeekInMaximumYear))
- return false;
- }
- m_type = Week;
- return true;
-}
-
-double DateComponents::millisecondsSinceEpochForTime() const
-{
- ASSERT(m_type == Time || m_type == DateTime || m_type == DateTimeLocal);
- return ((m_hour * minutesPerHour + m_minute) * secondsPerMinute + m_second) * msPerSecond + m_millisecond;
-}
-
-double DateComponents::millisecondsSinceEpoch() const
-{
- switch (m_type) {
- case Date:
- return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay;
- case DateTime:
- case DateTimeLocal:
- return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay + millisecondsSinceEpochForTime();
- case Month:
- return dateToDaysFrom1970(m_year, m_month, 1) * msPerDay;
- case Time:
- return millisecondsSinceEpochForTime();
- case Week:
- return (dateToDaysFrom1970(m_year, 0, 1) + offsetTo1stWeekStart(m_year) + (m_week - 1) * 7) * msPerDay;
- case Invalid:
- break;
- }
- ASSERT_NOT_REACHED();
- return invalidMilliseconds();
-}
-
-double DateComponents::monthsSinceEpoch() const
-{
- ASSERT(m_type == Month);
- return (m_year - 1970) * 12 + m_month;
-}
-
-String DateComponents::toStringForTime(SecondFormat format) const
-{
- ASSERT(m_type == DateTime || m_type == DateTimeLocal || m_type == Time);
- SecondFormat effectiveFormat = format;
- if (m_millisecond)
- effectiveFormat = Millisecond;
- else if (format == None && m_second)
- effectiveFormat = Second;
-
- switch (effectiveFormat) {
- default:
- ASSERT_NOT_REACHED();
-#if ASSERT_DISABLED
- FALLTHROUGH; // To None.
-#endif
- case None:
- return String::format("%02d:%02d", m_hour, m_minute);
- case Second:
- return String::format("%02d:%02d:%02d", m_hour, m_minute, m_second);
- case Millisecond:
- return String::format("%02d:%02d:%02d.%03d", m_hour, m_minute, m_second, m_millisecond);
- }
-}
-
-String DateComponents::toString(SecondFormat format) const
-{
- switch (m_type) {
- case Date:
- return String::format("%04d-%02d-%02d", m_year, m_month + 1, m_monthDay);
- case DateTime:
- return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
- + toStringForTime(format) + String("Z");
- case DateTimeLocal:
- return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
- + toStringForTime(format);
- case Month:
- return String::format("%04d-%02d", m_year, m_month + 1);
- case Time:
- return toStringForTime(format);
- case Week:
- return String::format("%04d-W%02d", m_year, m_week);
- case Invalid:
- break;
- }
- ASSERT_NOT_REACHED();
- return String("(Invalid DateComponents)");
-}
-
-} // namespace WTF
Deleted: trunk/Source/WTF/wtf/DateComponents.h (225554 => 225555)
--- trunk/Source/WTF/wtf/DateComponents.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WTF/wtf/DateComponents.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <limits>
-#include <unicode/utypes.h>
-#include <wtf/Forward.h>
-
-namespace WTF {
-
-// A DateComponents instance represents one of the following date and time combinations:
-// * Month type: year-month
-// * Date type: year-month-day
-// * Week type: year-week
-// * Time type: hour-minute-second-millisecond
-// * DateTime or DateTimeLocal type: year-month-day hour-minute-second-millisecond
-class DateComponents {
-public:
- DateComponents()
- : m_millisecond(0)
- , m_second(0)
- , m_minute(0)
- , m_hour(0)
- , m_monthDay(0)
- , m_month(0)
- , m_year(0)
- , m_week(0)
- , m_type(Invalid)
- {
- }
-
- enum Type {
- Invalid,
- Date,
- DateTime,
- DateTimeLocal,
- Month,
- Time,
- Week,
- };
-
- int millisecond() const { return m_millisecond; }
- int second() const { return m_second; }
- int minute() const { return m_minute; }
- int hour() const { return m_hour; }
- int monthDay() const { return m_monthDay; }
- int month() const { return m_month; }
- int fullYear() const { return m_year; }
- int week() const { return m_week; }
- Type type() const { return m_type; }
-
- enum SecondFormat {
- None, // Suppress the second part and the millisecond part if they are 0.
- Second, // Always show the second part, and suppress the millisecond part if it is 0.
- Millisecond // Always show the second part and the millisecond part.
- };
-
- // Returns an ISO 8601 representation for this instance.
- // The format argument is valid for DateTime, DateTimeLocal, and Time types.
- WTF_EXPORT_PRIVATE 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.
- WTF_EXPORT_PRIVATE bool parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end);
- // Sets year, month and monthDay.
- WTF_EXPORT_PRIVATE bool parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end);
- // Sets year and week.
- WTF_EXPORT_PRIVATE bool parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end);
- // Sets hour, minute, second and millisecond.
- WTF_EXPORT_PRIVATE bool parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
- // Sets year, month, monthDay, hour, minute, second and millisecond.
- WTF_EXPORT_PRIVATE bool parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end);
- // Sets year, month, monthDay, hour, minute, second and millisecond, and adjusts timezone.
- WTF_EXPORT_PRIVATE bool parseDateTime(const UChar* 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.
-
- // For Date type. Updates m_year, m_month and m_monthDay.
- WTF_EXPORT_PRIVATE bool setMillisecondsSinceEpochForDate(double);
- // For DateTime type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
- WTF_EXPORT_PRIVATE bool setMillisecondsSinceEpochForDateTime(double);
- // For DateTimeLocal type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
- WTF_EXPORT_PRIVATE bool setMillisecondsSinceEpochForDateTimeLocal(double);
- // For Month type. Updates m_year and m_month.
- WTF_EXPORT_PRIVATE bool setMillisecondsSinceEpochForMonth(double);
- // For Week type. Updates m_year and m_week.
- WTF_EXPORT_PRIVATE bool setMillisecondsSinceEpochForWeek(double);
-
- // For Time type. Updates m_hour, m_minute, m_second and m_millisecond.
- WTF_EXPORT_PRIVATE bool setMillisecondsSinceMidnight(double);
-
- // Another initializer for Month type. Updates m_year and m_month.
- WTF_EXPORT_PRIVATE bool setMonthsSinceEpoch(double);
-
- // 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.
- WTF_EXPORT_PRIVATE double millisecondsSinceEpoch() const;
- // Returns the number of months from 1970-01.
- // Do not call this for types other than Month.
- WTF_EXPORT_PRIVATE 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.
-
- // 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:
- // 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);
- void setMillisecondsSinceMidnightInternal(double);
- // Helper for toString().
- String toStringForTime(SecondFormat) const;
-
- // m_weekDay values
- enum {
- Sunday = 0,
- Monday,
- Tuesday,
- Wednesday,
- Thursday,
- Friday,
- Saturday,
- };
-
- int m_millisecond; // 0 - 999
- int m_second;
- int m_minute;
- int m_hour;
- int m_monthDay; // 1 - 31
- int m_month; // 0:January - 11:December
- int m_year; // 1582 -
- int m_week; // 1 - 53
-
- Type m_type;
-};
-
-
-} // namespace WTF
-
-using WTF::DateComponents;
Modified: trunk/Source/WebCore/ChangeLog (225554 => 225555)
--- trunk/Source/WebCore/ChangeLog 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/ChangeLog 2017-12-05 23:59:31 UTC (rev 225555)
@@ -1,3 +1,15 @@
+2017-12-05 Matt Lewis <[email protected]>
+
+ Unreviewed, rolling out r225430.
+
+ This caused an API failure on release.
+
+ Reverted changeset:
+
+ "Move DateComponents into WTF"
+ https://bugs.webkit.org/show_bug.cgi?id=180211
+ https://trac.webkit.org/changeset/225430
+
2017-12-05 Simon Fraser <[email protected]>
Composited frames incorrectly get requestAnimationFrame throttled
Modified: trunk/Source/WebCore/Sources.txt (225554 => 225555)
--- trunk/Source/WebCore/Sources.txt 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/Sources.txt 2017-12-05 23:59:31 UTC (rev 225555)
@@ -1394,6 +1394,7 @@
platform/ContextMenu.cpp
platform/ContextMenuItem.cpp
platform/Cursor.cpp
+platform/DateComponents.cpp
platform/Decimal.cpp
platform/DragData.cpp
platform/DragImage.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (225554 => 225555)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2017-12-05 23:59:31 UTC (rev 225555)
@@ -2839,6 +2839,7 @@
A54A0C6C1DB831F90017A90B /* WorkerInspectorProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = A54A0C6A1DB831F20017A90B /* WorkerInspectorProxy.h */; };
A554B5F31E38393A001D4E03 /* PerformanceUserTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = A554B5F11E383936001D4E03 /* PerformanceUserTiming.h */; };
A55639D11C6F09E300806D8E /* WorkerConsoleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A55639D01C6EFD5900806D8E /* WorkerConsoleClient.h */; };
+ A5732B0B136A161D005C8D7C /* DateComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = A5732B09136A161D005C8D7C /* DateComponents.h */; settings = {ATTRIBUTES = (Private, ); }; };
A578F4351DE00EEB003DFC6A /* PromiseRejectionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A578F4331DE00ED6003DFC6A /* PromiseRejectionEvent.h */; };
A578F43C1DE01423003DFC6A /* JSPromiseRejectionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A578F43A1DE013FB003DFC6A /* JSPromiseRejectionEvent.h */; };
A578F43F1DE0B630003DFC6A /* RejectedPromiseTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = A578F43E1DE0B62B003DFC6A /* RejectedPromiseTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -10726,6 +10727,8 @@
A554B5F11E383936001D4E03 /* PerformanceUserTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceUserTiming.h; sourceTree = "<group>"; };
A55639CF1C6EFD5900806D8E /* WorkerConsoleClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerConsoleClient.cpp; sourceTree = "<group>"; };
A55639D01C6EFD5900806D8E /* WorkerConsoleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerConsoleClient.h; sourceTree = "<group>"; };
+ A5732B08136A161D005C8D7C /* DateComponents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DateComponents.cpp; sourceTree = "<group>"; };
+ A5732B09136A161D005C8D7C /* DateComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateComponents.h; sourceTree = "<group>"; };
A578F4321DE00ED6003DFC6A /* PromiseRejectionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PromiseRejectionEvent.cpp; sourceTree = "<group>"; };
A578F4331DE00ED6003DFC6A /* PromiseRejectionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromiseRejectionEvent.h; sourceTree = "<group>"; };
A578F4341DE00ED6003DFC6A /* PromiseRejectionEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PromiseRejectionEvent.idl; sourceTree = "<group>"; };
@@ -23485,6 +23488,8 @@
46C696C91E7205E400597937 /* CPUMonitor.h */,
E11AF15011B9A1A300805103 /* Cursor.cpp */,
F587868402DE3B8601EA4122 /* Cursor.h */,
+ A5732B08136A161D005C8D7C /* DateComponents.cpp */,
+ A5732B09136A161D005C8D7C /* DateComponents.h */,
37C738F11EDBDE87003F2B0B /* DateTimeChooser.h */,
37C738F21EDBDE87003F2B0B /* DateTimeChooserClient.h */,
45FEA5CD156DDE8C00654101 /* Decimal.cpp */,
@@ -26587,6 +26592,7 @@
81AC599A131636E60009A7E0 /* DataTransferItemList.h in Headers */,
E4A007831B820EC8002C5A6E /* DataURLDecoder.h in Headers */,
E4A007831B820EC8002C5A6E /* DataURLDecoder.h in Headers */,
+ A5732B0B136A161D005C8D7C /* DateComponents.h in Headers */,
F55B3DB61251F12D003EF269 /* DateInputType.h in Headers */,
37C738F31EDBDE8A003F2B0B /* DateTimeChooser.h in Headers */,
37C738F41EDBDE8D003F2B0B /* DateTimeChooserClient.h in Headers */,
Modified: trunk/Source/WebCore/dom/Document.cpp (225554 => 225555)
--- trunk/Source/WebCore/dom/Document.cpp 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-12-05 23:59:31 UTC (rev 225555)
@@ -53,6 +53,7 @@
#include "CustomEvent.h"
#include "DOMImplementation.h"
#include "DOMWindow.h"
+#include "DateComponents.h"
#include "DebugPageOverlays.h"
#include "DocumentLoader.h"
#include "DocumentMarkerController.h"
Modified: trunk/Source/WebCore/html/BaseDateAndTimeInputType.h (225554 => 225555)
--- trunk/Source/WebCore/html/BaseDateAndTimeInputType.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/html/BaseDateAndTimeInputType.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -33,8 +33,8 @@
#if ENABLE(DATE_AND_TIME_INPUT_TYPES)
+#include "DateComponents.h"
#include "InputType.h"
-#include <wtf/DateComponents.h>
namespace WebCore {
Modified: trunk/Source/WebCore/html/DateTimeInputType.h (225554 => 225555)
--- trunk/Source/WebCore/html/DateTimeInputType.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/html/DateTimeInputType.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -39,8 +39,7 @@
class DateTimeInputType final : public BaseChooserOnlyDateAndTimeInputType {
public:
- explicit DateTimeInputType(HTMLInputElement& element)
- : BaseChooserOnlyDateAndTimeInputType(element) { }
+ explicit DateTimeInputType(HTMLInputElement& element) : BaseDateTimeInputType(element) { }
private:
const AtomicString& formControlType() const override;
Modified: trunk/Source/WebCore/html/HTMLInputElement.h (225554 => 225555)
--- trunk/Source/WebCore/html/HTMLInputElement.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/html/HTMLInputElement.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -30,7 +30,7 @@
#include <memory>
#if PLATFORM(IOS)
-#include <wtf/DateComponents.h>
+#include "DateComponents.h"
#endif
namespace WebCore {
Modified: trunk/Source/WebCore/html/InputType.cpp (225554 => 225555)
--- trunk/Source/WebCore/html/InputType.cpp 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/html/InputType.cpp 2017-12-05 23:59:31 UTC (rev 225555)
@@ -34,6 +34,7 @@
#include "CheckboxInputType.h"
#include "ColorInputType.h"
#include "DOMFormData.h"
+#include "DateComponents.h"
#include "DateInputType.h"
#include "DateTimeInputType.h"
#include "DateTimeLocalInputType.h"
@@ -74,7 +75,6 @@
#include "WeekInputType.h"
#include <limits>
#include <wtf/Assertions.h>
-#include <wtf/DateComponents.h>
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
#include <wtf/text/TextBreakIterator.h>
Modified: trunk/Source/WebCore/html/InputType.h (225554 => 225555)
--- trunk/Source/WebCore/html/InputType.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/html/InputType.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -35,16 +35,20 @@
#include "HTMLTextFormControlElement.h"
#include "RenderPtr.h"
#include "StepRange.h"
-#include <wtf/DateComponents.h>
#include <wtf/FastMalloc.h>
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>
+#if PLATFORM(IOS)
+#include "DateComponents.h"
+#endif
+
namespace WebCore {
class BeforeTextInsertedEvent;
class Chrome;
class DOMFormData;
+class DateComponents;
class DragData;
class Event;
class FileList;
Copied: trunk/Source/WebCore/platform/DateComponents.cpp (from rev 225554, trunk/Source/WTF/wtf/DateComponents.cpp) (0 => 225555)
--- trunk/Source/WebCore/platform/DateComponents.cpp (rev 0)
+++ trunk/Source/WebCore/platform/DateComponents.cpp 2017-12-05 23:59:31 UTC (rev 225555)
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DateComponents.h"
+
+#include <limits.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+// HTML5 specification defines minimum week of year is one.
+const int DateComponents::minimumWeekNumber = 1;
+
+// HTML5 specification defines maximum week of year is 53.
+const int DateComponents::maximumWeekNumber = 53;
+
+static const int maximumMonthInMaximumYear = 8; // This is September, since months are 0 based.
+static const int maximumDayInMaximumMonth = 13;
+static const int maximumWeekInMaximumYear = 37; // The week of 275760-09-13
+
+static const int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+static bool isLeapYear(int year)
+{
+ if (year % 4)
+ return false;
+ if (!(year % 400))
+ return true;
+ if (!(year % 100))
+ return false;
+ return true;
+}
+
+// 'month' is 0-based.
+static int maxDayOfMonth(int year, int month)
+{
+ if (month != 1) // February?
+ return daysInMonth[month];
+ return isLeapYear(year) ? 29 : 28;
+}
+
+// 'month' is 0-based.
+static int dayOfWeek(int year, int month, int day)
+{
+ int shiftedMonth = month + 2;
+ // 2:January, 3:Feburuary, 4:March, ...
+
+ // Zeller's congruence
+ if (shiftedMonth <= 3) {
+ shiftedMonth += 12;
+ year--;
+ }
+ // 4:March, ..., 14:January, 15:February
+
+ int highYear = year / 100;
+ int lowYear = year % 100;
+ // We add 6 to make the result Sunday-origin.
+ int result = (day + 13 * shiftedMonth / 5 + lowYear + lowYear / 4 + highYear / 4 + 5 * highYear + 6) % 7;
+ return result;
+}
+
+int DateComponents::maxWeekNumberInYear() const
+{
+ int day = dayOfWeek(m_year, 0, 1); // January 1.
+ return day == Thursday || (day == Wednesday && isLeapYear(m_year)) ? maximumWeekNumber : maximumWeekNumber - 1;
+}
+
+static unsigned countDigits(const UChar* src, unsigned length, unsigned start)
+{
+ unsigned index = start;
+ for (; index < length; ++index) {
+ if (!isASCIIDigit(src[index]))
+ break;
+ }
+ return index - start;
+}
+
+// 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)
+{
+ if (parseStart + parseLength > length || parseLength <= 0)
+ return false;
+ int value = 0;
+ const UChar* current = src + parseStart;
+ const UChar* end = current + parseLength;
+
+ // We don't need to handle negative numbers for ISO 8601.
+ for (; current < end; ++current) {
+ if (!isASCIIDigit(*current))
+ return false;
+ int digit = *current - '0';
+ if (value > (INT_MAX - digit) / 10) // Check for overflow.
+ return false;
+ value = value * 10 + digit;
+ }
+ out = value;
+ return true;
+}
+
+bool DateComponents::parseYear(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ unsigned digitsLength = countDigits(src, length, start);
+ // Needs at least 4 digits according to the standard.
+ if (digitsLength < 4)
+ return false;
+ int year;
+ if (!toInt(src, length, start, digitsLength, year))
+ return false;
+ if (year < minimumYear() || year > maximumYear())
+ return false;
+ m_year = year;
+ end = start + digitsLength;
+ return true;
+}
+
+static bool withinHTMLDateLimits(int year, int month)
+{
+ if (year < DateComponents::minimumYear())
+ return false;
+ if (year < DateComponents::maximumYear())
+ return true;
+ return month <= maximumMonthInMaximumYear;
+}
+
+static bool withinHTMLDateLimits(int year, int month, int monthDay)
+{
+ if (year < DateComponents::minimumYear())
+ return false;
+ if (year < DateComponents::maximumYear())
+ return true;
+ if (month < maximumMonthInMaximumYear)
+ return true;
+ return monthDay <= maximumDayInMaximumMonth;
+}
+
+static bool withinHTMLDateLimits(int year, int month, int monthDay, int hour, int minute, int second, int millisecond)
+{
+ if (year < DateComponents::minimumYear())
+ return false;
+ if (year < DateComponents::maximumYear())
+ return true;
+ if (month < maximumMonthInMaximumYear)
+ return true;
+ if (monthDay < maximumDayInMaximumMonth)
+ return true;
+ if (monthDay > maximumDayInMaximumMonth)
+ return false;
+ // (year, month, monthDay) = (maximumYear, maximumMonthInMaximumYear, maximumDayInMaximumMonth)
+ return !hour && !minute && !second && !millisecond;
+}
+
+bool DateComponents::addDay(int dayDiff)
+{
+ ASSERT(m_monthDay);
+
+ int day = m_monthDay + dayDiff;
+ if (day > maxDayOfMonth(m_year, m_month)) {
+ day = m_monthDay;
+ int year = m_year;
+ int month = m_month;
+ int maxDay = maxDayOfMonth(year, month);
+ for (; dayDiff > 0; --dayDiff) {
+ ++day;
+ if (day > maxDay) {
+ day = 1;
+ ++month;
+ if (month >= 12) { // month is 0-origin.
+ month = 0;
+ ++year;
+ }
+ maxDay = maxDayOfMonth(year, month);
+ }
+ }
+ if (!withinHTMLDateLimits(year, month, day))
+ return false;
+ m_year = year;
+ m_month = month;
+ } else if (day < 1) {
+ int month = m_month;
+ int year = m_year;
+ day = m_monthDay;
+ for (; dayDiff < 0; ++dayDiff) {
+ --day;
+ if (day < 1) {
+ --month;
+ if (month < 0) {
+ month = 11;
+ --year;
+ }
+ day = maxDayOfMonth(year, month);
+ }
+ }
+ if (!withinHTMLDateLimits(year, month, day))
+ return false;
+ m_year = year;
+ m_month = month;
+ } else {
+ if (!withinHTMLDateLimits(m_year, m_month, day))
+ return false;
+ }
+ m_monthDay = day;
+ return true;
+}
+
+bool DateComponents::addMinute(int minute)
+{
+ // This function is used to adjust timezone offset. So m_year, m_month,
+ // m_monthDay have values between the lower and higher limits.
+ ASSERT(withinHTMLDateLimits(m_year, m_month, m_monthDay));
+
+ int carry;
+ // minute can be negative or greater than 59.
+ minute += m_minute;
+ if (minute > 59) {
+ carry = minute / 60;
+ minute = minute % 60;
+ } else if (minute < 0) {
+ carry = (59 - minute) / 60;
+ minute += carry * 60;
+ carry = -carry;
+ ASSERT(minute >= 0 && minute <= 59);
+ } else {
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, minute, m_second, m_millisecond))
+ return false;
+ m_minute = minute;
+ return true;
+ }
+
+ int hour = m_hour + carry;
+ if (hour > 23) {
+ carry = hour / 24;
+ hour = hour % 24;
+ } else if (hour < 0) {
+ carry = (23 - hour) / 24;
+ hour += carry * 24;
+ carry = -carry;
+ ASSERT(hour >= 0 && hour <= 23);
+ } else {
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
+ return false;
+ m_minute = minute;
+ m_hour = hour;
+ return true;
+ }
+ if (!addDay(carry))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, hour, minute, m_second, m_millisecond))
+ return false;
+ m_minute = minute;
+ m_hour = hour;
+ return true;
+}
+
+// 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)
+{
+ if (start >= length)
+ return false;
+ unsigned index = start;
+ if (src[index] == 'Z') {
+ end = index + 1;
+ return true;
+ }
+
+ bool minus;
+ if (src[index] == '+')
+ minus = false;
+ else if (src[index] == '-')
+ minus = true;
+ else
+ return false;
+ ++index;
+
+ int hour;
+ int minute;
+ if (!toInt(src, length, index, 2, hour) || hour < 0 || hour > 23)
+ return false;
+ index += 2;
+
+ if (index >= length || src[index] != ':')
+ return false;
+ ++index;
+
+ if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
+ return false;
+ index += 2;
+
+ if (minus) {
+ hour = -hour;
+ minute = -minute;
+ }
+
+ // Subtract the timezone offset.
+ if (!addMinute(-(hour * 60 + minute)))
+ return false;
+ end = index;
+ return true;
+}
+
+bool DateComponents::parseMonth(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseYear(src, length, start, index))
+ return false;
+ if (index >= length || src[index] != '-')
+ return false;
+ ++index;
+
+ int month;
+ if (!toInt(src, length, index, 2, month) || month < 1 || month > 12)
+ return false;
+ --month;
+ if (!withinHTMLDateLimits(m_year, month))
+ return false;
+ m_month = month;
+ end = index + 2;
+ m_type = Month;
+ return true;
+}
+
+bool DateComponents::parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseMonth(src, length, start, index))
+ return false;
+ // '-' and 2-digits are needed.
+ if (index + 2 >= length)
+ return false;
+ if (src[index] != '-')
+ return false;
+ ++index;
+
+ int day;
+ if (!toInt(src, length, index, 2, day) || day < 1 || day > maxDayOfMonth(m_year, m_month))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, day))
+ return false;
+ m_monthDay = day;
+ end = index + 2;
+ m_type = Date;
+ return true;
+}
+
+bool DateComponents::parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseYear(src, length, start, index))
+ return false;
+
+ // 4 characters ('-' 'W' digit digit) are needed.
+ if (index + 3 >= length)
+ return false;
+ if (src[index] != '-')
+ return false;
+ ++index;
+ if (src[index] != 'W')
+ return false;
+ ++index;
+
+ int week;
+ if (!toInt(src, length, index, 2, week) || week < minimumWeekNumber || week > maxWeekNumberInYear())
+ return false;
+ if (m_year == maximumYear() && week > maximumWeekInMaximumYear)
+ return false;
+ m_week = week;
+ end = index + 2;
+ m_type = Week;
+ return true;
+}
+
+bool DateComponents::parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ int hour;
+ if (!toInt(src, length, start, 2, hour) || hour < 0 || hour > 23)
+ return false;
+ unsigned index = start + 2;
+ if (index >= length)
+ return false;
+ if (src[index] != ':')
+ return false;
+ ++index;
+
+ int minute;
+ if (!toInt(src, length, index, 2, minute) || minute < 0 || minute > 59)
+ return false;
+ index += 2;
+
+ int second = 0;
+ int millisecond = 0;
+ // Optional second part.
+ // Do not return with false because the part is optional.
+ if (index + 2 < length && src[index] == ':') {
+ if (toInt(src, length, index + 1, 2, second) && second >= 0 && second <= 59) {
+ index += 3;
+
+ // Optional fractional second part.
+ if (index < length && src[index] == '.') {
+ unsigned digitsLength = countDigits(src, length, index + 1);
+ if (digitsLength > 0) {
+ ++index;
+ bool ok;
+ if (digitsLength == 1) {
+ ok = toInt(src, length, index, 1, millisecond);
+ millisecond *= 100;
+ } else if (digitsLength == 2) {
+ ok = toInt(src, length, index, 2, millisecond);
+ millisecond *= 10;
+ } else // digitsLength >= 3
+ ok = toInt(src, length, index, 3, millisecond);
+ ASSERT_UNUSED(ok, ok);
+ index += digitsLength;
+ }
+ }
+ }
+ }
+ m_hour = hour;
+ m_minute = minute;
+ m_second = second;
+ m_millisecond = millisecond;
+ end = index;
+ m_type = Time;
+ return true;
+}
+
+bool DateComponents::parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseDate(src, length, start, index))
+ return false;
+ if (index >= length)
+ return false;
+ if (src[index] != 'T')
+ return false;
+ ++index;
+ if (!parseTime(src, length, index, end))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
+ return false;
+ m_type = DateTimeLocal;
+ return true;
+}
+
+bool DateComponents::parseDateTime(const UChar* src, unsigned length, unsigned start, unsigned& end)
+{
+ ASSERT(src);
+ unsigned index;
+ if (!parseDate(src, length, start, index))
+ return false;
+ if (index >= length)
+ return false;
+ if (src[index] != 'T')
+ return false;
+ ++index;
+ if (!parseTime(src, length, index, index))
+ return false;
+ if (!parseTimeZone(src, length, index, end))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
+ return false;
+ m_type = DateTime;
+ return true;
+}
+
+static inline double positiveFmod(double value, double divider)
+{
+ double remainder = fmod(value, divider);
+ return remainder < 0 ? remainder + divider : remainder;
+}
+
+void DateComponents::setMillisecondsSinceMidnightInternal(double msInDay)
+{
+ ASSERT(msInDay >= 0 && msInDay < msPerDay);
+ m_millisecond = static_cast<int>(fmod(msInDay, msPerSecond));
+ double value = floor(msInDay / msPerSecond);
+ m_second = static_cast<int>(fmod(value, secondsPerMinute));
+ value = floor(value / secondsPerMinute);
+ m_minute = static_cast<int>(fmod(value, minutesPerHour));
+ m_hour = static_cast<int>(value / minutesPerHour);
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDateInternal(double ms)
+{
+ m_year = msToYear(ms);
+ int yearDay = dayInYear(ms, m_year);
+ m_month = monthFromDayInYear(yearDay, isLeapYear(m_year));
+ m_monthDay = dayInMonthFromDayInYear(yearDay, isLeapYear(m_year));
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDate(double ms)
+{
+ m_type = Invalid;
+ if (!std::isfinite(ms))
+ return false;
+ if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay))
+ return false;
+ m_type = Date;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDateTime(double ms)
+{
+ m_type = Invalid;
+ if (!std::isfinite(ms))
+ return false;
+ ms = round(ms);
+ setMillisecondsSinceMidnightInternal(positiveFmod(ms, msPerDay));
+ if (!setMillisecondsSinceEpochForDateInternal(ms))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month, m_monthDay, m_hour, m_minute, m_second, m_millisecond))
+ return false;
+ m_type = DateTime;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForDateTimeLocal(double ms)
+{
+ // Internal representation of DateTimeLocal is the same as DateTime except m_type.
+ if (!setMillisecondsSinceEpochForDateTime(ms))
+ return false;
+ m_type = DateTimeLocal;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForMonth(double ms)
+{
+ m_type = Invalid;
+ if (!std::isfinite(ms))
+ return false;
+ if (!setMillisecondsSinceEpochForDateInternal(round(ms)))
+ return false;
+ if (!withinHTMLDateLimits(m_year, m_month))
+ return false;
+ m_type = Month;
+ return true;
+}
+
+bool DateComponents::setMillisecondsSinceMidnight(double ms)
+{
+ m_type = Invalid;
+ if (!std::isfinite(ms))
+ return false;
+ setMillisecondsSinceMidnightInternal(positiveFmod(round(ms), msPerDay));
+ m_type = Time;
+ return true;
+}
+
+bool DateComponents::setMonthsSinceEpoch(double months)
+{
+ if (!std::isfinite(months))
+ return false;
+ months = round(months);
+ double doubleMonth = positiveFmod(months, 12);
+ double doubleYear = 1970 + (months - doubleMonth) / 12;
+ if (doubleYear < minimumYear() || maximumYear() < doubleYear)
+ return false;
+ int year = static_cast<int>(doubleYear);
+ int month = static_cast<int>(doubleMonth);
+ if (!withinHTMLDateLimits(year, month))
+ return false;
+ m_year = year;
+ m_month = month;
+ m_type = Month;
+ return true;
+}
+
+// Offset from January 1st to Monday of the ISO 8601's first week.
+// ex. If January 1st is Friday, such Monday is 3 days later. Returns 3.
+static int offsetTo1stWeekStart(int year)
+{
+ int offsetTo1stWeekStart = 1 - dayOfWeek(year, 0, 1);
+ if (offsetTo1stWeekStart <= -4)
+ offsetTo1stWeekStart += 7;
+ return offsetTo1stWeekStart;
+}
+
+bool DateComponents::setMillisecondsSinceEpochForWeek(double ms)
+{
+ m_type = Invalid;
+ if (!std::isfinite(ms))
+ return false;
+ ms = round(ms);
+
+ m_year = msToYear(ms);
+ if (m_year < minimumYear() || m_year > maximumYear())
+ return false;
+
+ int yearDay = dayInYear(ms, m_year);
+ int offset = offsetTo1stWeekStart(m_year);
+ if (yearDay < offset) {
+ // The day belongs to the last week of the previous year.
+ m_year--;
+ if (m_year <= minimumYear())
+ return false;
+ m_week = maxWeekNumberInYear();
+ } else {
+ m_week = ((yearDay - offset) / 7) + 1;
+ if (m_week > maxWeekNumberInYear()) {
+ m_year++;
+ m_week = 1;
+ }
+ if (m_year > maximumYear() || (m_year == maximumYear() && m_week > maximumWeekInMaximumYear))
+ return false;
+ }
+ m_type = Week;
+ return true;
+}
+
+double DateComponents::millisecondsSinceEpochForTime() const
+{
+ ASSERT(m_type == Time || m_type == DateTime || m_type == DateTimeLocal);
+ return ((m_hour * minutesPerHour + m_minute) * secondsPerMinute + m_second) * msPerSecond + m_millisecond;
+}
+
+double DateComponents::millisecondsSinceEpoch() const
+{
+ switch (m_type) {
+ case Date:
+ return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay;
+ case DateTime:
+ case DateTimeLocal:
+ return dateToDaysFrom1970(m_year, m_month, m_monthDay) * msPerDay + millisecondsSinceEpochForTime();
+ case Month:
+ return dateToDaysFrom1970(m_year, m_month, 1) * msPerDay;
+ case Time:
+ return millisecondsSinceEpochForTime();
+ case Week:
+ return (dateToDaysFrom1970(m_year, 0, 1) + offsetTo1stWeekStart(m_year) + (m_week - 1) * 7) * msPerDay;
+ case Invalid:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return invalidMilliseconds();
+}
+
+double DateComponents::monthsSinceEpoch() const
+{
+ ASSERT(m_type == Month);
+ return (m_year - 1970) * 12 + m_month;
+}
+
+String DateComponents::toStringForTime(SecondFormat format) const
+{
+ ASSERT(m_type == DateTime || m_type == DateTimeLocal || m_type == Time);
+ SecondFormat effectiveFormat = format;
+ if (m_millisecond)
+ effectiveFormat = Millisecond;
+ else if (format == None && m_second)
+ effectiveFormat = Second;
+
+ switch (effectiveFormat) {
+ default:
+ ASSERT_NOT_REACHED();
+#if ASSERT_DISABLED
+ FALLTHROUGH; // To None.
+#endif
+ case None:
+ return String::format("%02d:%02d", m_hour, m_minute);
+ case Second:
+ return String::format("%02d:%02d:%02d", m_hour, m_minute, m_second);
+ case Millisecond:
+ return String::format("%02d:%02d:%02d.%03d", m_hour, m_minute, m_second, m_millisecond);
+ }
+}
+
+String DateComponents::toString(SecondFormat format) const
+{
+ switch (m_type) {
+ case Date:
+ return String::format("%04d-%02d-%02d", m_year, m_month + 1, m_monthDay);
+ case DateTime:
+ return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
+ + toStringForTime(format) + String("Z");
+ case DateTimeLocal:
+ return String::format("%04d-%02d-%02dT", m_year, m_month + 1, m_monthDay)
+ + toStringForTime(format);
+ case Month:
+ return String::format("%04d-%02d", m_year, m_month + 1);
+ case Time:
+ return toStringForTime(format);
+ case Week:
+ return String::format("%04d-W%02d", m_year, m_week);
+ case Invalid:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return String("(Invalid DateComponents)");
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/platform/DateComponents.h (from rev 225554, trunk/Source/WTF/wtf/DateComponents.h) (0 => 225555)
--- trunk/Source/WebCore/platform/DateComponents.h (rev 0)
+++ trunk/Source/WebCore/platform/DateComponents.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DateComponents_h
+#define DateComponents_h
+
+#include <limits>
+#include <unicode/utypes.h>
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+// A DateComponents instance represents one of the following date and time combinations:
+// * Month type: year-month
+// * Date type: year-month-day
+// * Week type: year-week
+// * Time type: hour-minute-second-millisecond
+// * DateTime or DateTimeLocal type: year-month-day hour-minute-second-millisecond
+class DateComponents {
+public:
+ DateComponents()
+ : m_millisecond(0)
+ , m_second(0)
+ , m_minute(0)
+ , m_hour(0)
+ , m_monthDay(0)
+ , m_month(0)
+ , m_year(0)
+ , m_week(0)
+ , m_type(Invalid)
+ {
+ }
+
+ enum Type {
+ Invalid,
+ Date,
+ DateTime,
+ DateTimeLocal,
+ Month,
+ Time,
+ Week,
+ };
+
+ int millisecond() const { return m_millisecond; }
+ int second() const { return m_second; }
+ int minute() const { return m_minute; }
+ int hour() const { return m_hour; }
+ int monthDay() const { return m_monthDay; }
+ int month() const { return m_month; }
+ int fullYear() const { return m_year; }
+ int week() const { return m_week; }
+ Type type() const { return m_type; }
+
+ enum SecondFormat {
+ None, // Suppress the second part and the millisecond part if they are 0.
+ Second, // Always show the second part, and suppress the millisecond part if it is 0.
+ Millisecond // Always show the second part and the millisecond part.
+ };
+
+ // 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;
+
+ // 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);
+ // Sets year, month and monthDay.
+ bool parseDate(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year and week.
+ bool parseWeek(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets hour, minute, second and millisecond.
+ bool parseTime(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year, month, monthDay, hour, minute, second and millisecond.
+ bool parseDateTimeLocal(const UChar* src, unsigned length, unsigned start, unsigned& end);
+ // Sets year, month, monthDay, hour, minute, second and millisecond, and adjusts timezone.
+ bool parseDateTime(const UChar* 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.
+
+ // For Date type. Updates m_year, m_month and m_monthDay.
+ bool setMillisecondsSinceEpochForDate(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);
+ // For DateTimeLocal type. Updates m_year, m_month, m_monthDay, m_hour, m_minute, m_second and m_millisecond.
+ bool setMillisecondsSinceEpochForDateTimeLocal(double ms);
+ // For Month type. Updates m_year and m_month.
+ bool setMillisecondsSinceEpochForMonth(double ms);
+ // For Week type. Updates m_year and m_week.
+ bool setMillisecondsSinceEpochForWeek(double ms);
+
+ // For Time type. Updates m_hour, m_minute, m_second and m_millisecond.
+ bool setMillisecondsSinceMidnight(double ms);
+
+ // Another initializer for Month type. Updates m_year and m_month.
+ bool setMonthsSinceEpoch(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.
+
+ // 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:
+ // 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;
+
+ // m_weekDay values
+ enum {
+ Sunday = 0,
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday,
+ };
+
+ int m_millisecond; // 0 - 999
+ int m_second;
+ int m_minute;
+ int m_hour;
+ int m_monthDay; // 1 - 31
+ int m_month; // 0:January - 11:December
+ int m_year; // 1582 -
+ int m_week; // 1 - 53
+
+ Type m_type;
+};
+
+
+} // namespace WebCore
+
+#endif // DateComponents_h
Modified: trunk/Source/WebCore/platform/text/PlatformLocale.h (225554 => 225555)
--- trunk/Source/WebCore/platform/text/PlatformLocale.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/platform/text/PlatformLocale.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -23,9 +23,10 @@
* DAMAGE.
*/
-#pragma once
+#ifndef PlatformLocale_h
+#define PlatformLocale_h
-#include <wtf/DateComponents.h>
+#include "DateComponents.h"
#include <wtf/Language.h>
#include <wtf/text/WTFString.h>
@@ -154,3 +155,4 @@
}
}
+#endif
Modified: trunk/Source/WebCore/platform/text/ios/LocalizedDateCache.h (225554 => 225555)
--- trunk/Source/WebCore/platform/text/ios/LocalizedDateCache.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/platform/text/ios/LocalizedDateCache.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -28,8 +28,8 @@
// FIXME: Rename this file to LocalizedDataCacheIOS.h and remove this guard.
#if PLATFORM(IOS)
+#include "DateComponents.h"
#include "FontCascade.h"
-#include <wtf/DateComponents.h>
#include <wtf/HashMap.h>
#include <wtf/RetainPtr.h>
Modified: trunk/Source/WebCore/platform/text/mac/LocaleMac.h (225554 => 225555)
--- trunk/Source/WebCore/platform/text/mac/LocaleMac.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/platform/text/mac/LocaleMac.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -28,7 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
+#ifndef LocaleMac_h
+#define LocaleMac_h
#include "PlatformLocale.h"
#include <wtf/Forward.h>
@@ -40,12 +41,10 @@
OBJC_CLASS NSDateFormatter;
OBJC_CLASS NSLocale;
-namespace WTF {
+namespace WebCore {
+
class DateComponents;
-}
-namespace WebCore {
-
class LocaleMac : public Locale {
public:
explicit LocaleMac(NSLocale*);
@@ -99,3 +98,4 @@
};
} // namespace WebCore
+#endif
Modified: trunk/Source/WebCore/platform/text/win/LocaleWin.cpp (225554 => 225555)
--- trunk/Source/WebCore/platform/text/win/LocaleWin.cpp 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/platform/text/win/LocaleWin.cpp 2017-12-05 23:59:31 UTC (rev 225555)
@@ -31,6 +31,7 @@
#include "config.h"
#include "LocaleWin.h"
+#include "DateComponents.h"
#include "DateTimeFormat.h"
#include "LocalizedStrings.h"
#include <limits>
Modified: trunk/Source/WebCore/platform/text/win/LocaleWin.h (225554 => 225555)
--- trunk/Source/WebCore/platform/text/win/LocaleWin.h 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/platform/text/win/LocaleWin.h 2017-12-05 23:59:31 UTC (rev 225555)
@@ -28,7 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
+#ifndef LocaleWin_h
+#define LocaleWin_h
#include "PlatformLocale.h"
#include <windows.h>
@@ -38,6 +39,7 @@
namespace WebCore {
+class DateComponents;
struct DateFormatToken;
class LocaleWin : public Locale {
@@ -86,3 +88,4 @@
};
} // namespace WebCore
+#endif
Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (225554 => 225555)
--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2017-12-05 23:30:48 UTC (rev 225554)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm 2017-12-05 23:59:31 UTC (rev 225555)
@@ -32,6 +32,7 @@
#import "CSSPrimitiveValue.h"
#import "CSSToLengthConversionData.h"
#import "CSSValueKeywords.h"
+#import "DateComponents.h"
#import "Document.h"
#import "File.h"
#import "FloatRoundedRect.h"
@@ -69,7 +70,6 @@
#import <objc/runtime.h>
#import <pal/spi/cocoa/CoreTextSPI.h>
#import <pal/spi/ios/UIKitSPI.h>
-#import <wtf/DateComponents.h>
#import <wtf/NeverDestroyed.h>
#import <wtf/RefPtr.h>
#import <wtf/SoftLinking.h>