WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-45491-20101129150009.patch (text/plain), 56.37 KB, created by
Dai Mikurube
on 2010-11-28 22:00:04 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dai Mikurube
Created:
2010-11-28 22:00:04 PST
Size:
56.37 KB
patch
obsolete
>diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog >index 7644cd76294e1ff3a20edfc0c3ce40df78bdc6f2..b639ff73368ab3cd021e9205cf03c341c9baf88b 100644 >--- a/JavaScriptCore/ChangeLog >+++ b/JavaScriptCore/ChangeLog >@@ -1,3 +1,26 @@ >+2010-11-24 Dai Mikurube <dmikurube@google.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ when empty, clicking "down" on outer-spin-button returns "max value" >+ https://bugs.webkit.org/show_bug.cgi?id=45491 >+ >+ It is required to calculate UTC/DST offsets to retrieve the current local milliseconds for >+ date/time type inputs. WTF::currentTimeMS() returns a UTC time, and WTF::getLocalTime() >+ returns a struct tm, not milliseconds. >+ >+ Calculating milliseconds from a struct tm is not clear. timegm() cannot be used in all >+ environments. This conversion is complicated and already done at calculateUTCOffset(). >+ Duplicating this complicated calculation is unreasonable because of maintainability. >+ To achieve this without duplication, we must call calculate{UTC|DST}Offset in some way. >+ >+ * JavaScriptCore.exp: >+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: >+ * wtf/DateMath.cpp: Changed calculateUTCOffset() and calculateDSTOffset() to external functions. >+ (WTF::calculateUTCOffset): >+ (WTF::calculateDSTOffset): >+ * wtf/DateMath.h: >+ > 2010-11-18 Gavin Barraclough <barraclough@apple.com> > > Reviewed by Oliver Hunt. >diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp >index 3715a43837dc910e8de70e433ed26feb154180d3..39bf52702b0b00bdd39b5a42cb4d88055e6ab2b9 100644 >--- a/JavaScriptCore/JavaScriptCore.exp >+++ b/JavaScriptCore/JavaScriptCore.exp >@@ -404,6 +404,8 @@ __ZN3WTF17charactersToFloatEPKtmPb > __ZN3WTF17equalIgnoringCaseEPKtPKcj > __ZN3WTF17equalIgnoringCaseEPNS_10StringImplEPKc > __ZN3WTF17equalIgnoringCaseEPNS_10StringImplES1_ >+__ZN3WTF18calculateDSTOffsetEdd >+__ZN3WTF18calculateUTCOffsetEv > __ZN3WTF18charactersToDoubleEPKtmPb > __ZN3WTF18dateToDaysFrom1970Eiii > __ZN3WTF18monthFromDayInYearEib >diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def >index 449c0bb841554cc27eac2f59a2425aa30a2dd08b..42ac7f11618d190b4f3a3fd8ecb17770ecf70488 100644 >--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def >+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def >@@ -59,6 +59,8 @@ EXPORTS > ?broadcast@ThreadCondition@WTF@@QAEXXZ > ?bufferLengthForStringDecimal@DecimalNumber@WTF@@QBEIXZ > ?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ >+ ?calculateUTCOffset@WTF@@YAHXZ >+ ?calculateDSTOffset@WTF@@YANNN@Z > ?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z > ?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z > ?callOnMainThreadAndWait@WTF@@YAXP6AXPAX@Z0@Z >diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp >index f3627e6b983e82b9aa3a40ac49db6d50be5f0814..675f093f01bb45f88b73c46069d52c0b8d09eab4 100644 >--- a/JavaScriptCore/wtf/DateMath.cpp >+++ b/JavaScriptCore/wtf/DateMath.cpp >@@ -379,7 +379,7 @@ int equivalentYearForDST(int year) > return year; > } > >-static int32_t calculateUTCOffset() >+int32_t calculateUTCOffset() > { > #if PLATFORM(BREWMP) > time_t localTime = static_cast<time_t>(currentTime()); >@@ -449,7 +449,7 @@ static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset > } > > // Get the DST offset, given a time in UTC >-static double calculateDSTOffset(double ms, double utcOffset) >+double calculateDSTOffset(double ms, double utcOffset) > { > // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate > // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript >diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h >index be51947f2a1bd91ba97af7e2b9b36a1515b9513f..cb84708118fa6a17b9aa8866657d4fa092312bb8 100644 >--- a/JavaScriptCore/wtf/DateMath.h >+++ b/JavaScriptCore/wtf/DateMath.h >@@ -84,6 +84,10 @@ int dayInYear(double ms, int year); > int monthFromDayInYear(int dayInYear, bool leapYear); > int dayInMonthFromDayInYear(int dayInYear, bool leapYear); > >+// Returns offset milliseconds for UTC and DST. >+int32_t calculateUTCOffset(); >+double calculateDSTOffset(double ms, double utcOffset); >+ > } // namespace WTF > > using WTF::dateToDaysFrom1970; >@@ -92,10 +96,13 @@ using WTF::dayInYear; > using WTF::minutesPerHour; > using WTF::monthFromDayInYear; > using WTF::msPerDay; >+using WTF::msPerMinute; > using WTF::msPerSecond; > using WTF::msToYear; > using WTF::secondsPerMinute; > using WTF::parseDateFromNullTerminatedCharacters; >+using WTF::calculateUTCOffset; >+using WTF::calculateDSTOffset; > > #if USE(JSC) > namespace JSC { >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index ae3047c2d056776d583c02e1800ed85cdb4458cc..e60df5a1c8c044b2efde1abc4043009d27a0718f 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,20 @@ >+2010-11-24 Dai Mikurube <dmikurube@google.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ when empty, clicking "down" on outer-spin-button returns "max value" >+ https://bugs.webkit.org/show_bug.cgi?id=45491 >+ >+ * fast/forms/input-stepup-stepdown-from-renderer-expected.txt: Added. >+ * fast/forms/input-stepup-stepdown-from-renderer.html: Added. >+ * fast/forms/script-tests/input-stepup-stepdown-from-renderer.js: Added. >+ (): >+ (setInputAttributes): >+ (stepUp): >+ (stepDown): >+ (stepUpExplicitBounds): >+ (stepDownExplicitBounds): >+ > 2010-11-18 David Levin <levin@chromium.org> > > [chromium] Misc test updates (most Ruby). >diff --git a/LayoutTests/fast/forms/input-stepup-stepdown-from-renderer-expected.txt b/LayoutTests/fast/forms/input-stepup-stepdown-from-renderer-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..62b2a63c013387a654d28f4332c4592e46f146fd >--- /dev/null >+++ b/LayoutTests/fast/forms/input-stepup-stepdown-from-renderer-expected.txt >@@ -0,0 +1,262 @@ >+Check stepUp() and stepDown() for from renderer. No cases of empty initial values for type=date, datetime, datetime-local, month, time, week. >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+Date type >+function arguments are (value, step, {min or max}, [stepCount]) >+Normal cases >+PASS stepUp("2010-02-10", null, null) is "2010-02-11" >+PASS stepDown("2010-02-10", null, null) is "2010-02-09" >+PASS stepUp("2010-02-10", null, null, 10) is "2010-02-20" >+PASS stepDown("2010-02-10", null, null, 11) is "2010-01-30" >+PASS stepUp("1970-01-01", "4", null, 2) is "1970-01-09" >+PASS stepDown("1970-01-01", "4", null, 3) is "1969-12-20" >+Step=any >+PASS stepUp("2010-02-10", "any", null) is "2010-02-10" >+PASS stepDown("2010-02-10", "any", null) is "2010-02-10" >+Overflow/underflow >+PASS stepUp("2010-02-10", "3.40282346e+38", null) is "275760-09-13" >+PASS stepDown("2010-02-10", "3.40282346e+38", null) is "1970-01-01" >+PASS stepUp("2010-02-10", "1", "2010-02-10") is "2010-02-10" >+PASS stepDown("2010-02-10", "1", "2010-02-10") is "2010-02-10" >+stepDown()/stepUp() for stepMismatch values >+PASS stepDown("2010-02-10", "3", "2010-02-06") is "2010-02-09" >+PASS stepUp("1970-01-02", "2", "") is "1970-01-03" >+ >+Datetime type >+function arguments are (value, step, {min or max}, [stepCount]) >+Normal cases >+PASS stepUp("2010-02-10T20:13Z", null, null) is "2010-02-10T20:14Z" >+PASS stepDown("2010-02-10T20:13Z", null, null) is "2010-02-10T20:12Z" >+PASS stepUp("2010-02-10T20:13Z", null, null, 10) is "2010-02-10T20:23Z" >+PASS stepDown("2010-02-10T20:13Z", null, null, 11) is "2010-02-10T20:02Z" >+PASS stepUp("1970-01-01T20:13Z", "4", null, 2) is "1970-01-01T20:13:08Z" >+PASS stepDown("1970-01-01T20:13Z", "4", null, 3) is "1970-01-01T20:12:48Z" >+Step=any >+PASS stepUp("2010-02-10T20:13Z", "any", null) is "2010-02-10T20:13Z" >+PASS stepDown("2010-02-10T20:13Z", "any", null) is "2010-02-10T20:13Z" >+Overflow/underflow >+PASS stepUp("2010-02-10T20:13Z", "3.40282346e+38", null) is "275760-09-13T00:00:00.000Z" >+PASS stepDown("2010-02-10T20:13Z", "3.40282346e+38", null) is "1970-01-01T00:00:00.000Z" >+PASS stepUp("2010-02-10T20:13Z", "1", "2010-02-10T20:13Z") is "2010-02-10T20:13Z" >+PASS stepDown("2010-02-10T20:13Z", "1", "2010-02-10T20:13Z") is "2010-02-10T20:13Z" >+stepDown()/stepUp() for stepMismatch values >+PASS stepDown("2010-02-10T20:13Z", "3", "2010-02-10T20:12:56Z") is "2010-02-10T20:12:59Z" >+PASS stepUp("1970-01-01T00:13Z", "7", "") is "1970-01-01T00:13:04Z" >+ >+Datetime-local type >+function arguments are (value, step, {min or max}, [stepCount]) >+Normal cases >+PASS stepUp("2010-02-10T20:13", null, null) is "2010-02-10T20:14" >+PASS stepDown("2010-02-10T20:13", null, null) is "2010-02-10T20:12" >+PASS stepUp("2010-02-10T20:13", null, null, 10) is "2010-02-10T20:23" >+PASS stepDown("2010-02-10T20:13", null, null, 11) is "2010-02-10T20:02" >+PASS stepUp("1970-01-01T20:13", "4", null, 2) is "1970-01-01T20:13:08" >+PASS stepDown("1970-01-01T20:13", "4", null, 3) is "1970-01-01T20:12:48" >+Step=any >+PASS stepUp("2010-02-10T20:13", "any", null) is "2010-02-10T20:13" >+PASS stepDown("2010-02-10T20:13", "any", null) is "2010-02-10T20:13" >+Overflow/underflow >+PASS stepUp("2010-02-10T20:13", "3.40282346e+38", null) is "275760-09-13T00:00:00.000" >+PASS stepDown("2010-02-10T20:13", "3.40282346e+38", null) is "1970-01-01T00:00:00.000" >+PASS stepUp("2010-02-10T20:13", "1", "2010-02-10T20:13") is "2010-02-10T20:13" >+PASS stepDown("2010-02-10T20:13", "1", "2010-02-10T20:13") is "2010-02-10T20:13" >+stepDown()/stepUp() for stepMismatch values >+PASS stepDown("2010-02-10T20:13", "3", "2010-02-10T20:12:56") is "2010-02-10T20:12:59" >+PASS stepUp("1970-01-01T00:13", "7", "") is "1970-01-01T00:13:04" >+ >+Month type >+function arguments are (value, step, {min or max}, [stepCount]) >+Normal cases >+PASS stepUp("2010-02", null, null) is "2010-03" >+PASS stepDown("2010-02", null, null) is "2010-01" >+PASS stepUp("2010-02", null, null, 10) is "2010-12" >+PASS stepDown("2010-02", null, null, 11) is "2009-03" >+PASS stepUp("1970-01", "4", null, 2) is "1970-09" >+PASS stepDown("1970-01", "4", null, 3) is "1969-01" >+Step=any >+PASS stepUp("2010-02", "any", null) is "2010-02" >+PASS stepDown("2010-02", "any", null) is "2010-02" >+Overflow/underflow >+PASS stepUp("2010-02", "3.40282346e+38", null) is "275760-09" >+PASS stepDown("2010-02", "3.40282346e+38", null) is "1970-01" >+PASS stepUp("2010-02", "1", "2010-02") is "2010-02" >+PASS stepDown("2010-02", "1", "2010-02") is "2010-02" >+stepDown()/stepUp() for stepMismatch values >+PASS stepDown("2010-02", "3", "2009-10") is "2010-01" >+PASS stepUp("1970-02", "4", "") is "1970-05" >+ >+Number type >+function arguments are (value, step, {min or max}, [stepCount]) >+Invalid value >+PASS stepUp("", null, null) is "1" >+PASS stepDown("", null, null) is "-1" >+PASS stepUp("", "any", null) is "0" >+PASS stepDown("", "any", null) is "0" >+PASS stepUp("", "foo", null) is "1" >+PASS stepDown("", "foo", null) is "-1" >+PASS stepUp("foo", null, null) is "1" >+PASS stepDown("foo", null, null) is "-1" >+PASS stepUp("foo", "any", null) is "0" >+PASS stepDown("foo", "any", null) is "0" >+PASS stepUp("foo", "foo", null) is "1" >+PASS stepDown("foo", "foo", null) is "-1" >+Normal cases >+PASS stepUp("0", null, null) is "1" >+PASS stepUp("1", null, null, 2) is "3" >+PASS stepUp("3", null, null, -1) is "2" >+PASS stepDown("2", null, null) is "1" >+PASS stepDown("1", null, null, 2) is "-1" >+PASS stepDown("-1", null, null, -1) is "0" >+Invalid step value >+PASS stepUp("0", "foo", null) is "1" >+PASS stepUp("1", "0", null) is "2" >+PASS stepUp("2", "-1", null) is "3" >+Step=any >+PASS stepUp("0", "any", null) is "0" >+PASS stepDown("0", "any", null) is "0" >+Overflow/underflow >+PASS stepDown("1", "1", "0") is "0" >+PASS stepDown("0", "1", "0") is "0" >+PASS stepDown("1", "1", "0", 2) is "0" >+PASS stepDown("1", "3.40282346e+38", "", 2) is "-3.40282346e+38" >+PASS stepUp("-1", "1", "0") is "0" >+PASS stepUp("0", "1", "0") is "0" >+PASS stepUp("-1", "1", "0", 2) is "0" >+PASS stepUp("1", "3.40282346e+38", "", 2) is "3.40282346e+38" >+stepDown()/stepUp() for stepMismatch values >+PASS stepUp("1", "2", "") is "2" >+PASS input.min = "0"; stepUp("9", "10", "") is "10" >+PASS stepDown("19", "10", "0") is "10" >+PASS stepUp("89", "10", "99") is "90" >+Huge value and small step >+PASS input.min = ""; stepUp("1e+38", "1", "", 999) is "1e+38" >+PASS input.max = ""; stepDown("1e+38", "1", "", 999) is "1e+38" >+Fractional numbers >+PASS input.min = ""; stepUp("0", "0.33333333333333333", "", 3) is "1" >+PASS stepUp("1", "0.1", "", 10) is "2" >+PASS input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255) is "1" >+Rounding >+PASS stepUp("5.005", "0.005", "", 2) is "5.015" >+PASS stepUp("5.005", "0.005", "", 11) is "5.06" >+PASS stepUp("5.005", "0.005", "", 12) is "5.065" >+PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 2) is "5.015" >+PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 11) is "5.06" >+PASS stepUpExplicitBounds("4", "9", "0.005", "5.005", 12) is "5.065" >+ >+Range type >+function arguments are (min, max, step, value, [stepCount]) >+Using the default values >+PASS stepUpExplicitBounds(null, null, null, "") is "51" >+PASS stepDownExplicitBounds(null, null, null, "") is "49" >+PASS stepUpExplicitBounds(null, null, "any", "") is "51" >+PASS stepDownExplicitBounds(null, null, "any", "") is "49" >+PASS stepUpExplicitBounds(null, null, "foo", "") is "51" >+PASS stepDownExplicitBounds(null, null, "foo", "") is "49" >+PASS stepUpExplicitBounds(null, null, null, "foo") is "51" >+PASS stepDownExplicitBounds(null, null, null, "foo") is "49" >+PASS stepUpExplicitBounds(null, null, "any", "foo") is "51" >+PASS stepDownExplicitBounds(null, null, "any", "foo") is "49" >+PASS stepUpExplicitBounds(null, null, "foo", "foo") is "51" >+PASS stepDownExplicitBounds(null, null, "foo", "foo") is "49" >+Normal cases >+PASS stepUpExplicitBounds(null, null, null, "0") is "1" >+PASS stepUpExplicitBounds(null, null, null, "1", 2) is "3" >+PASS stepUpExplicitBounds(null, null, null, "3", -1) is "2" >+PASS stepDownExplicitBounds("-100", null, null, "2") is "1" >+PASS stepDownExplicitBounds("-100", null, null, "1", 2) is "-1" >+PASS stepDownExplicitBounds("-100", null, null, "-1", -1) is "0" >+Invalid step value >+PASS stepUpExplicitBounds(null, null, "foo", "0") is "1" >+PASS stepUpExplicitBounds(null, null, "0", "1") is "2" >+PASS stepUpExplicitBounds(null, null, "-1", "2") is "3" >+PASS stepDownExplicitBounds(null, null, "foo", "1") is "0" >+PASS stepDownExplicitBounds(null, null, "0", "2") is "1" >+PASS stepDownExplicitBounds(null, null, "-1", "3") is "2" >+Step=any >+PASS stepUpExplicitBounds(null, null, "any", "1") is "2" >+PASS stepDownExplicitBounds(null, null, "any", "1") is "0" >+Overflow/underflow >+PASS stepUpExplicitBounds(null, "100", "1", "99") is "100" >+PASS stepUpExplicitBounds(null, "100", "1", "100") is "100" >+PASS input.value is "100" >+PASS stepUpExplicitBounds(null, "100", "1", "99", "2") is "100" >+PASS input.value is "100" >+PASS stepDownExplicitBounds("0", null, "1", "1") is "0" >+PASS stepDownExplicitBounds("0", null, "1", "0") is "0" >+PASS input.value is "0" >+PASS stepDownExplicitBounds("0", null, "1", "1", "2") is "0" >+PASS input.value is "0" >+PASS stepDownExplicitBounds(null, null, "3.40282346e+38", "1", "2") is "0" >+PASS stepUpExplicitBounds(-100, 0, 1, -1) is "0" >+PASS stepUpExplicitBounds(null, 0, 1, 0) is "0" >+PASS stepUpExplicitBounds(-100, 0, 1, -1, 2) is "0" >+PASS input.value is "0" >+PASS stepUpExplicitBounds(null, null, "3.40282346e+38", "1", "2") is "0" >+stepDown()/stepUp() for stepMismatch values >+PASS stepUpExplicitBounds(null, null, 2, 1) is "4" >+PASS stepUpExplicitBounds(0, null, 10, 9, 9) is "100" >+PASS stepDownExplicitBounds(0, null, 10, 19) is "10" >+value + step is <= max, but rounded result would be > max. >+PASS stepUpExplicitBounds(null, 99, 10, 89) is "90" >+Huge value and small step >+PASS stepUpExplicitBounds(0, 1e38, 1, 1e38, 999) is "1e+38" >+PASS stepDownExplicitBounds(0, 1e38, 1, 1e38, 999) is "1e+38" >+Fractional numbers >+PASS stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3) is "1" >+PASS stepUpExplicitBounds(null, null, 0.1, 1) is "1.1" >+PASS stepUpExplicitBounds(null, null, 0.1, 1, 8) is "1.8" >+PASS stepUpExplicitBounds(null, null, 0.1, 1, 10) is "2" >+PASS stepUpExplicitBounds(0, 1, 0.003921568627450980, 0, 255) is "1" >+PASS stepDownExplicitBounds(null, null, 0.1, 1, 8) is "0.2" >+PASS stepDownExplicitBounds(null, null, 0.1, 1) is "0.9" >+ >+Time type >+function arguments are (value, step, {min or max}, [stepCount]) >+Normal cases >+PASS stepUp("20:13", null, null) is "20:14" >+PASS stepDown("20:13", null, null) is "20:12" >+PASS stepUp("20:13", null, null, 10) is "20:23" >+PASS stepDown("20:13", null, null, 11) is "20:02" >+PASS stepUp("20:13", "4", null, 2) is "20:13:08" >+PASS stepDown("20:13", "4", null, 3) is "20:12:48" >+Step=any >+PASS stepUp("20:13", "any", null) is "20:13" >+PASS stepDown("20:13", "any", null) is "20:13" >+Overflow/underflow >+PASS stepUp("20:13", "3.40282346e+38", null) is "23:59:59.999" >+PASS stepDown("20:13", "3.40282346e+38", null) is "00:00:00.000" >+PASS stepUp("20:13", "1", "20:13") is "20:13" >+PASS stepDown("20:13", "1", "20:13") is "20:13" >+PASS stepUp("23:59", null, null) is "23:59" >+PASS stepDown("00:00", null, null) is "00:00" >+stepDown()/stepUp() for stepMismatch values >+PASS stepDown("20:13", "3", "20:12:56") is "20:12:59" >+PASS stepUp("00:13", "7", "") is "00:13:04" >+ >+Week type >+function arguments are (value, step, {min or max}, [stepCount]) >+Normal cases >+PASS stepUp("2010-W02", null, null) is "2010-W03" >+PASS stepDown("2010-W02", null, null) is "2010-W01" >+PASS stepUp("2010-W02", null, null, 10) is "2010-W12" >+PASS stepDown("2010-W02", null, null, 11) is "2009-W44" >+PASS stepUp("1970-W01", "4", null, 2) is "1970-W09" >+PASS stepDown("1970-W01", "4", null, 3) is "1969-W41" >+Step=any >+PASS stepUp("2010-W02", "any", null) is "2010-W02" >+PASS stepDown("2010-W02", "any", null) is "2010-W02" >+Overflow/underflow >+PASS stepUp("2010-W02", "3.40282346e+38", null) is "275760-W37" >+PASS stepDown("2010-W02", "3.40282346e+38", null) is "1970-W01" >+PASS stepUp("2010-W02", "1", "2010-W02") is "2010-W02" >+PASS stepDown("2010-W02", "1", "2010-W02") is "2010-W02" >+stepDown()/stepUp() for stepMismatch values >+PASS stepDown("2010-W02", "2", "2009-W52") is "2010-W01" >+PASS stepUp("1970-W02", "4", "") is "1970-W05" >+ >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/fast/forms/input-stepup-stepdown-from-renderer.html b/LayoutTests/fast/forms/input-stepup-stepdown-from-renderer.html >new file mode 100644 >index 0000000000000000000000000000000000000000..a4ffffdc8ee6002d53d7ab219f931e7089d5445d >--- /dev/null >+++ b/LayoutTests/fast/forms/input-stepup-stepdown-from-renderer.html >@@ -0,0 +1,13 @@ >+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> >+<html> >+<head> >+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css"> >+<script src="../../fast/js/resources/js-test-pre.js"></script> >+</head> >+<body> >+<p id="description"></p> >+<div id="console"></div> >+<script src="script-tests/input-stepup-stepdown-from-renderer.js"></script> >+<script src="../../fast/js/resources/js-test-post.js"></script> >+</body> >+</html> >diff --git a/LayoutTests/fast/forms/script-tests/input-stepup-stepdown-from-renderer.js b/LayoutTests/fast/forms/script-tests/input-stepup-stepdown-from-renderer.js >new file mode 100644 >index 0000000000000000000000000000000000000000..83407344d19699f8bc9f62727252ce22973c1ea2 >--- /dev/null >+++ b/LayoutTests/fast/forms/script-tests/input-stepup-stepdown-from-renderer.js >@@ -0,0 +1,356 @@ >+description('Check stepUp() and stepDown() for <input> from renderer. No cases of empty initial values for type=date, datetime, datetime-local, month, time, week.'); >+ >+var input = document.createElement('input'); >+var invalidStateErr = '"Error: INVALID_STATE_ERR: DOM Exception 11"'; >+ >+function sendKey(keyName) { >+ var event = document.createEvent('KeyboardEvent'); >+ event.initKeyboardEvent('keydown', true, true, document.defaultView, keyName); >+ input.dispatchEvent(event); >+} >+ >+function setInputAttributes(min, max, step, value) { >+ input.min = min; >+ input.max = max; >+ input.step = step; >+ input.value = value; >+} >+ >+function stepUp(value, step, max, optionalStepCount) { >+ setInputAttributes(null, max, step, value); >+ if (typeof optionalStepCount != "undefined") >+ if (optionalStepCount < 0) >+ for (var i = 0; i < -optionalStepCount; i++) >+ sendKey('Down'); >+ else >+ for (var i = 0; i < optionalStepCount; i++) >+ sendKey('Up'); >+ else >+ sendKey('Up'); >+ return input.value; >+} >+ >+function stepDown(value, step, min, optionalStepCount) { >+ setInputAttributes(min, null, step, value); >+ if (typeof optionalStepCount != "undefined") >+ if (optionalStepCount < 0) >+ for (var i = 0; i < -optionalStepCount; i++) >+ sendKey('Up'); >+ else >+ for (var i = 0; i < optionalStepCount; i++) >+ sendKey('Down'); >+ else >+ sendKey('Down'); >+ return input.value; >+} >+ >+// Range value gets automatically shifted based on bounds, >+// So always set the min and max first to get expected behavior >+ >+function stepUpExplicitBounds(min, max, step, value, stepCount) { >+ setInputAttributes(min, max, step, value); >+ if (typeof stepCount !== 'undefined') >+ if (stepCount < 0) { >+ for (var i = 0; i < -stepCount; i++) >+ sendKey('Down'); >+ } else { >+ for (var i = 0; i < stepCount; i++) >+ sendKey('Up'); >+ } >+ else >+ sendKey('Up'); >+ return input.value; >+} >+ >+function stepDownExplicitBounds(min, max, step, value, stepCount) { >+ setInputAttributes(min, max, step, value); >+ if (typeof stepCount !== 'undefined') >+ if (stepCount < 0) { >+ for (var i = 0; i < -stepCount; i++) >+ sendKey('Up'); >+ } else { >+ for (var i = 0; i < stepCount; i++) >+ sendKey('Down'); >+ } >+ else >+ sendKey('Down'); >+ return input.value; >+} >+ >+function stepMismatchFor(value, step, min) { >+ input.min = min; >+ input.step = step; >+ input.value = value; >+ return input.validity.stepMismatch; >+} >+ >+debug('Date type'); >+input.type = 'date'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Normal cases'); >+shouldBe('stepUp("2010-02-10", null, null)', '"2010-02-11"'); >+shouldBe('stepDown("2010-02-10", null, null)', '"2010-02-09"'); >+shouldBe('stepUp("2010-02-10", null, null, 10)', '"2010-02-20"'); >+shouldBe('stepDown("2010-02-10", null, null, 11)', '"2010-01-30"'); >+shouldBe('stepUp("1970-01-01", "4", null, 2)', '"1970-01-09"'); >+shouldBe('stepDown("1970-01-01", "4", null, 3)', '"1969-12-20"'); >+debug('Step=any'); >+shouldBe('stepUp("2010-02-10", "any", null)', '"2010-02-10"'); >+shouldBe('stepDown("2010-02-10", "any", null)', '"2010-02-10"'); >+debug('Overflow/underflow'); >+shouldBe('stepUp("2010-02-10", "3.40282346e+38", null)','"275760-09-13"'); >+shouldBe('stepDown("2010-02-10", "3.40282346e+38", null)', '"1970-01-01"'); >+shouldBe('stepUp("2010-02-10", "1", "2010-02-10")', '"2010-02-10"'); >+shouldBe('stepDown("2010-02-10", "1", "2010-02-10")', '"2010-02-10"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepDown("2010-02-10", "3", "2010-02-06")', '"2010-02-09"'); >+shouldBe('stepUp("1970-01-02", "2", "")', '"1970-01-03"'); >+ >+debug(''); >+debug('Datetime type'); >+input.type = 'datetime'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Normal cases'); >+shouldBe('stepUp("2010-02-10T20:13Z", null, null)', '"2010-02-10T20:14Z"'); >+shouldBe('stepDown("2010-02-10T20:13Z", null, null)', '"2010-02-10T20:12Z"'); >+shouldBe('stepUp("2010-02-10T20:13Z", null, null, 10)', '"2010-02-10T20:23Z"'); >+shouldBe('stepDown("2010-02-10T20:13Z", null, null, 11)', '"2010-02-10T20:02Z"'); >+shouldBe('stepUp("1970-01-01T20:13Z", "4", null, 2)', '"1970-01-01T20:13:08Z"'); >+shouldBe('stepDown("1970-01-01T20:13Z", "4", null, 3)', '"1970-01-01T20:12:48Z"'); >+debug('Step=any'); >+shouldBe('stepUp("2010-02-10T20:13Z", "any", null)', '"2010-02-10T20:13Z"'); >+shouldBe('stepDown("2010-02-10T20:13Z", "any", null)', '"2010-02-10T20:13Z"'); >+debug('Overflow/underflow'); >+shouldBe('stepUp("2010-02-10T20:13Z", "3.40282346e+38", null)', '"275760-09-13T00:00:00.000Z"'); >+shouldBe('stepDown("2010-02-10T20:13Z", "3.40282346e+38", null)', '"1970-01-01T00:00:00.000Z"'); >+shouldBe('stepUp("2010-02-10T20:13Z", "1", "2010-02-10T20:13Z")', '"2010-02-10T20:13Z"'); >+shouldBe('stepDown("2010-02-10T20:13Z", "1", "2010-02-10T20:13Z")', '"2010-02-10T20:13Z"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepDown("2010-02-10T20:13Z", "3", "2010-02-10T20:12:56Z")', '"2010-02-10T20:12:59Z"'); >+shouldBe('stepUp("1970-01-01T00:13Z", "7", "")', '"1970-01-01T00:13:04Z"'); >+ >+debug(''); >+debug('Datetime-local type'); >+input.type = 'datetime-local'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Normal cases'); >+shouldBe('stepUp("2010-02-10T20:13", null, null)', '"2010-02-10T20:14"'); >+shouldBe('stepDown("2010-02-10T20:13", null, null)', '"2010-02-10T20:12"'); >+shouldBe('stepUp("2010-02-10T20:13", null, null, 10)', '"2010-02-10T20:23"'); >+shouldBe('stepDown("2010-02-10T20:13", null, null, 11)', '"2010-02-10T20:02"'); >+shouldBe('stepUp("1970-01-01T20:13", "4", null, 2)', '"1970-01-01T20:13:08"'); >+shouldBe('stepDown("1970-01-01T20:13", "4", null, 3)', '"1970-01-01T20:12:48"'); >+debug('Step=any'); >+shouldBe('stepUp("2010-02-10T20:13", "any", null)', '"2010-02-10T20:13"'); >+shouldBe('stepDown("2010-02-10T20:13", "any", null)', '"2010-02-10T20:13"'); >+debug('Overflow/underflow'); >+shouldBe('stepUp("2010-02-10T20:13", "3.40282346e+38", null)', '"275760-09-13T00:00:00.000"'); >+shouldBe('stepDown("2010-02-10T20:13", "3.40282346e+38", null)', '"1970-01-01T00:00:00.000"'); >+shouldBe('stepUp("2010-02-10T20:13", "1", "2010-02-10T20:13")', '"2010-02-10T20:13"'); >+shouldBe('stepDown("2010-02-10T20:13", "1", "2010-02-10T20:13")', '"2010-02-10T20:13"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepDown("2010-02-10T20:13", "3", "2010-02-10T20:12:56")', '"2010-02-10T20:12:59"'); >+shouldBe('stepUp("1970-01-01T00:13", "7", "")', '"1970-01-01T00:13:04"'); >+ >+debug(''); >+debug('Month type'); >+input.type = 'month'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Normal cases'); >+shouldBe('stepUp("2010-02", null, null)', '"2010-03"'); >+shouldBe('stepDown("2010-02", null, null)', '"2010-01"'); >+shouldBe('stepUp("2010-02", null, null, 10)', '"2010-12"'); >+shouldBe('stepDown("2010-02", null, null, 11)', '"2009-03"'); >+shouldBe('stepUp("1970-01", "4", null, 2)', '"1970-09"'); >+shouldBe('stepDown("1970-01", "4", null, 3)', '"1969-01"'); >+debug('Step=any'); >+shouldBe('stepUp("2010-02", "any", null)', '"2010-02"'); >+shouldBe('stepDown("2010-02", "any", null)', '"2010-02"'); >+debug('Overflow/underflow'); >+shouldBe('stepUp("2010-02", "3.40282346e+38", null)', '"275760-09"'); >+shouldBe('stepDown("2010-02", "3.40282346e+38", null)', '"1970-01"'); >+shouldBe('stepUp("2010-02", "1", "2010-02")', '"2010-02"'); >+shouldBe('stepDown("2010-02", "1", "2010-02")', '"2010-02"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepDown("2010-02", "3", "2009-10")', '"2010-01"'); >+shouldBe('stepUp("1970-02", "4", "")', '"1970-05"'); >+ >+debug(''); >+debug('Number type'); >+input.type = 'number'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Invalid value'); >+shouldBe('stepUp("", null, null)', '"1"'); >+shouldBe('stepDown("", null, null)', '"-1"'); >+shouldBe('stepUp("", "any", null)', '"0"'); >+shouldBe('stepDown("", "any", null)', '"0"'); >+shouldBe('stepUp("", "foo", null)', '"1"'); >+shouldBe('stepDown("", "foo", null)', '"-1"'); >+shouldBe('stepUp("foo", null, null)', '"1"'); >+shouldBe('stepDown("foo", null, null)', '"-1"'); >+shouldBe('stepUp("foo", "any", null)', '"0"'); >+shouldBe('stepDown("foo", "any", null)', '"0"'); >+shouldBe('stepUp("foo", "foo", null)', '"1"'); >+shouldBe('stepDown("foo", "foo", null)', '"-1"'); >+debug('Normal cases'); >+shouldBe('stepUp("0", null, null)', '"1"'); >+shouldBe('stepUp("1", null, null, 2)', '"3"'); >+shouldBe('stepUp("3", null, null, -1)', '"2"'); >+shouldBe('stepDown("2", null, null)', '"1"'); >+shouldBe('stepDown("1", null, null, 2)', '"-1"'); >+shouldBe('stepDown("-1", null, null, -1)', '"0"'); >+debug('Invalid step value'); >+shouldBe('stepUp("0", "foo", null)', '"1"'); >+shouldBe('stepUp("1", "0", null)', '"2"'); >+shouldBe('stepUp("2", "-1", null)', '"3"'); >+debug('Step=any'); >+shouldBe('stepUp("0", "any", null)', '"0"'); >+shouldBe('stepDown("0", "any", null)', '"0"'); >+debug('Overflow/underflow'); >+shouldBe('stepDown("1", "1", "0")', '"0"'); >+shouldBe('stepDown("0", "1", "0")', '"0"'); >+shouldBe('stepDown("1", "1", "0", 2)', '"0"'); >+shouldBe('stepDown("1", "3.40282346e+38", "", 2)', '"-3.40282346e+38"'); >+shouldBe('stepUp("-1", "1", "0")', '"0"'); >+shouldBe('stepUp("0", "1", "0")', '"0"'); >+shouldBe('stepUp("-1", "1", "0", 2)', '"0"'); >+shouldBe('stepUp("1", "3.40282346e+38", "", 2)', '"3.40282346e+38"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepUp("1", "2", "")', '"2"'); >+shouldBe('input.min = "0"; stepUp("9", "10", "")', '"10"'); >+shouldBe('stepDown("19", "10", "0")', '"10"'); >+shouldBe('stepUp("89", "10", "99")', '"90"'); >+debug('Huge value and small step'); >+shouldBe('input.min = ""; stepUp("1e+38", "1", "", 999)', '"1e+38"'); >+shouldBe('input.max = ""; stepDown("1e+38", "1", "", 999)', '"1e+38"'); >+debug('Fractional numbers'); >+shouldBe('input.min = ""; stepUp("0", "0.33333333333333333", "", 3)', '"1"'); >+shouldBe('stepUp("1", "0.1", "", 10)', '"2"'); >+shouldBe('input.min = "0"; stepUp("0", "0.003921568627450980", "1", 255)', '"1"'); >+debug('Rounding'); >+shouldBe('stepUp("5.005", "0.005", "", 2)', '"5.015"'); >+shouldBe('stepUp("5.005", "0.005", "", 11)', '"5.06"'); >+shouldBe('stepUp("5.005", "0.005", "", 12)', '"5.065"'); >+shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 2)', '"5.015"'); >+shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 11)', '"5.06"'); >+shouldBe('stepUpExplicitBounds("4", "9", "0.005", "5.005", 12)', '"5.065"'); >+ >+debug(''); >+debug('Range type'); >+input.type = 'range'; >+debug('function arguments are (min, max, step, value, [stepCount])'); >+debug('Using the default values'); >+shouldBe('stepUpExplicitBounds(null, null, null, "")', '"51"'); >+shouldBe('stepDownExplicitBounds(null, null, null, "")', '"49"'); >+shouldBe('stepUpExplicitBounds(null, null, "any", "")', '"51"'); >+shouldBe('stepDownExplicitBounds(null, null, "any", "")', '"49"'); >+shouldBe('stepUpExplicitBounds(null, null, "foo", "")', '"51"'); >+shouldBe('stepDownExplicitBounds(null, null, "foo", "")', '"49"'); >+shouldBe('stepUpExplicitBounds(null, null, null, "foo")', '"51"'); >+shouldBe('stepDownExplicitBounds(null, null, null, "foo")', '"49"'); >+shouldBe('stepUpExplicitBounds(null, null, "any", "foo")', '"51"'); >+shouldBe('stepDownExplicitBounds(null, null, "any", "foo")', '"49"'); >+shouldBe('stepUpExplicitBounds(null, null, "foo", "foo")', '"51"'); >+shouldBe('stepDownExplicitBounds(null, null, "foo", "foo")', '"49"'); >+debug('Normal cases'); >+shouldBe('stepUpExplicitBounds(null, null, null, "0")', '"1"'); >+shouldBe('stepUpExplicitBounds(null, null, null, "1", 2)', '"3"'); >+shouldBe('stepUpExplicitBounds(null, null, null, "3", -1)', '"2"'); >+shouldBe('stepDownExplicitBounds("-100", null, null, "2")', '"1"'); >+shouldBe('stepDownExplicitBounds("-100", null, null, "1", 2)', '"-1"'); >+shouldBe('stepDownExplicitBounds("-100", null, null, "-1", -1)', '"0"'); >+debug('Invalid step value'); >+shouldBe('stepUpExplicitBounds(null, null, "foo", "0")', '"1"'); >+shouldBe('stepUpExplicitBounds(null, null, "0", "1")', '"2"'); >+shouldBe('stepUpExplicitBounds(null, null, "-1", "2")', '"3"'); >+shouldBe('stepDownExplicitBounds(null, null, "foo", "1")', '"0"'); >+shouldBe('stepDownExplicitBounds(null, null, "0", "2")', '"1"'); >+shouldBe('stepDownExplicitBounds(null, null, "-1", "3")', '"2"'); >+debug('Step=any'); >+shouldBe('stepUpExplicitBounds(null, null, "any", "1")', '"2"'); >+shouldBe('stepDownExplicitBounds(null, null, "any", "1")', '"0"'); >+debug('Overflow/underflow'); >+shouldBe('stepUpExplicitBounds(null, "100", "1", "99")', '"100"'); >+shouldBe('stepUpExplicitBounds(null, "100", "1", "100")', '"100"'); >+shouldBe('input.value', '"100"'); >+shouldBe('stepUpExplicitBounds(null, "100", "1", "99", "2")', '"100"'); >+shouldBe('input.value', '"100"'); >+shouldBe('stepDownExplicitBounds("0", null, "1", "1")', '"0"'); >+shouldBe('stepDownExplicitBounds("0", null, "1", "0")', '"0"'); >+shouldBe('input.value', '"0"'); >+shouldBe('stepDownExplicitBounds("0", null, "1", "1", "2")', '"0"'); >+shouldBe('input.value', '"0"'); >+shouldBe('stepDownExplicitBounds(null, null, "3.40282346e+38", "1", "2")', '"0"'); >+shouldBe('stepUpExplicitBounds(-100, 0, 1, -1)', '"0"'); >+shouldBe('stepUpExplicitBounds(null, 0, 1, 0)', '"0"'); >+shouldBe('stepUpExplicitBounds(-100, 0, 1, -1, 2)', '"0"'); >+shouldBe('input.value', '"0"'); >+shouldBe('stepUpExplicitBounds(null, null, "3.40282346e+38", "1", "2")', '"0"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepUpExplicitBounds(null, null, 2, 1)', '"4"'); >+shouldBe('stepUpExplicitBounds(0, null, 10, 9, 9)', '"100"'); >+shouldBe('stepDownExplicitBounds(0, null, 10, 19)', '"10"'); >+debug('value + step is <= max, but rounded result would be > max.'); >+shouldBe('stepUpExplicitBounds(null, 99, 10, 89)', '"90"'); >+debug('Huge value and small step'); >+shouldBe('stepUpExplicitBounds(0, 1e38, 1, 1e38, 999)', '"1e+38"'); >+shouldBe('stepDownExplicitBounds(0, 1e38, 1, 1e38, 999)', '"1e+38"'); >+debug('Fractional numbers'); >+shouldBe('stepUpExplicitBounds(null, null, 0.33333333333333333, 0, 3)', '"1"'); >+shouldBe('stepUpExplicitBounds(null, null, 0.1, 1)', '"1.1"'); >+shouldBe('stepUpExplicitBounds(null, null, 0.1, 1, 8)', '"1.8"'); >+shouldBe('stepUpExplicitBounds(null, null, 0.1, 1, 10)', '"2"'); >+shouldBe('stepUpExplicitBounds(0, 1, 0.003921568627450980, 0, 255)', '"1"'); >+shouldBe('stepDownExplicitBounds(null, null, 0.1, 1, 8)', '"0.2"'); >+shouldBe('stepDownExplicitBounds(null, null, 0.1, 1)', '"0.9"'); >+ >+debug(''); >+debug('Time type'); >+input.type = 'time'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Normal cases'); >+shouldBe('stepUp("20:13", null, null)', '"20:14"'); >+shouldBe('stepDown("20:13", null, null)', '"20:12"'); >+shouldBe('stepUp("20:13", null, null, 10)', '"20:23"'); >+shouldBe('stepDown("20:13", null, null, 11)', '"20:02"'); >+shouldBe('stepUp("20:13", "4", null, 2)', '"20:13:08"'); >+shouldBe('stepDown("20:13", "4", null, 3)', '"20:12:48"'); >+debug('Step=any'); >+shouldBe('stepUp("20:13", "any", null)', '"20:13"'); >+shouldBe('stepDown("20:13", "any", null)', '"20:13"'); >+debug('Overflow/underflow'); >+shouldBe('stepUp("20:13", "3.40282346e+38", null)', '"23:59:59.999"'); >+shouldBe('stepDown("20:13", "3.40282346e+38", null)', '"00:00:00.000"'); >+shouldBe('stepUp("20:13", "1", "20:13")', '"20:13"'); >+shouldBe('stepDown("20:13", "1", "20:13")', '"20:13"'); >+shouldBe('stepUp("23:59", null, null)', '"23:59"'); >+shouldBe('stepDown("00:00", null, null)', '"00:00"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepDown("20:13", "3", "20:12:56")', '"20:12:59"'); >+shouldBe('stepUp("00:13", "7", "")', '"00:13:04"'); >+ >+debug(''); >+debug('Week type'); >+input.type = 'week'; >+debug('function arguments are (value, step, {min or max}, [stepCount])'); >+debug('Normal cases'); >+shouldBe('stepUp("2010-W02", null, null)', '"2010-W03"'); >+shouldBe('stepDown("2010-W02", null, null)', '"2010-W01"'); >+shouldBe('stepUp("2010-W02", null, null, 10)', '"2010-W12"'); >+shouldBe('stepDown("2010-W02", null, null, 11)', '"2009-W44"'); >+shouldBe('stepUp("1970-W01", "4", null, 2)', '"1970-W09"'); >+shouldBe('stepDown("1970-W01", "4", null, 3)', '"1969-W41"'); >+debug('Step=any'); >+shouldBe('stepUp("2010-W02", "any", null)', '"2010-W02"'); >+shouldBe('stepDown("2010-W02", "any", null)', '"2010-W02"'); >+debug('Overflow/underflow'); >+shouldBe('stepUp("2010-W02", "3.40282346e+38", null)', '"275760-W37"'); >+shouldBe('stepDown("2010-W02", "3.40282346e+38", null)', '"1970-W01"'); >+shouldBe('stepUp("2010-W02", "1", "2010-W02")', '"2010-W02"'); >+shouldBe('stepDown("2010-W02", "1", "2010-W02")', '"2010-W02"'); >+debug('stepDown()/stepUp() for stepMismatch values'); >+shouldBe('stepDown("2010-W02", "2", "2009-W52")', '"2010-W01"'); >+shouldBe('stepUp("1970-W02", "4", "")', '"1970-W05"'); >+ >+debug(''); >+var successfullyParsed = true; >diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog >index 5d1c3c36156e27ef050fd5399a8c1ad27b125aa5..569ae3d238b175fb09e40b712f9a542a0981bbc3 100644 >--- a/WebCore/ChangeLog >+++ b/WebCore/ChangeLog >@@ -1,3 +1,66 @@ >+2010-11-24 Dai Mikurube <dmikurube@google.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ when empty, clicking "down" on outer-spin-button returns "max value" >+ https://bugs.webkit.org/show_bug.cgi?id=45491 >+ >+ Modified stepping-up/down from renderer >+ - to clamp steps, >+ - to handle empty values (described below), and >+ - to apply them for range type inputs. >+ >+ Stepping-up/down for empty values are handled "the empty as 0." >+ For example : >+ * If 0 is in-range, and matches to step value >+ "down" -> -step >+ "up" -> +step >+ If -step or +step is out of range, new value should be 0. >+ >+ * If 0 is smaller than the minimum value >+ "down" -> the minimum value >+ "up" -> the minimum value >+ >+ * If 0 is larger than the maximum value >+ "down" -> the maximum value >+ "up" -> the maximum value >+ >+ * If 0 is in-range, but not matched to step value >+ "down" -> smaler matched value nearest to 0. >+ e.g. <input type=number min=-100 step=3> -> -1 >+ "up" -> larger matched value nearest to 0. >+ e.g. <input type=number min=-100 step=3> -> 2 >+ >+ As for date/datetime/datetime-local/month/time/week types, the empty is assumed as "current date/time". >+ >+ As for range input types, changed stepping from renderer to use stepUpFromRenderer(). >+ It was calculated with stepUp() from RangeInputType::handleKeydownEvent(). >+ >+ Test: fast/forms/input-stepup-stepdown-from-renderer.html >+ >+ * html/BaseDateAndTimeInputType.cpp: >+ (WebCore::BaseDateAndTimeInputType::startingValue): Added startingValue() which returns the current local time >+ * html/BaseDateAndTimeInputType.h: >+ * html/DateTimeInputType.cpp: >+ (WebCore::DateTimeInputType::startingValue): Added startingValue() which returns the current UTC time >+ * html/DateTimeInputType.h: >+ * html/HTMLInputElement.cpp: >+ (WebCore::HTMLInputElement::stepUpFromRenderer): Modified it to clamp steps, support empty values and support range type inputs >+ * html/HTMLInputElement.h: >+ (WebCore::HTMLInputElement::isRangeControl): >+ * html/InputType.cpp: >+ (WebCore::InputType::startingValue): Added startingValue() which returns 0 >+ * html/InputType.h: >+ * html/MonthInputType.cpp: >+ (WebCore::MonthInputType::startingValue): Added startingValue() which returns the current month >+ * html/MonthInputType.h: >+ * html/RangeInputType.cpp: >+ (WebCore::RangeInputType::handleKeydownEvent): Added comments and modified it to use stepUpFromRenderer() >+ * html/TimeInputType.cpp: >+ (WebCore::TimeInputType::startingValue): Added startingValue() which returns the current time >+ * html/TimeInputType.h: >+ * manual-tests/input-type-datetime-default-value.html: Added manual tests for default values of date/time inputs >+ > 2010-11-18 Gavin Barraclough <barraclough@apple.com> > > Reviewed by Oliver Hunt. >diff --git a/WebCore/html/BaseDateAndTimeInputType.cpp b/WebCore/html/BaseDateAndTimeInputType.cpp >index e780ed6ba24d20fafbdb629e2836985f1a5a90cc..70243e59c4ef17dad130730e6e3864bf760670d7 100644 >--- a/WebCore/html/BaseDateAndTimeInputType.cpp >+++ b/WebCore/html/BaseDateAndTimeInputType.cpp >@@ -35,6 +35,8 @@ > #include "HTMLInputElement.h" > #include "HTMLNames.h" > #include <limits> >+#include <wtf/CurrentTime.h> >+#include <wtf/DateMath.h> > #include <wtf/MathExtras.h> > #include <wtf/PassOwnPtr.h> > #include <wtf/text/WTFString.h> >@@ -91,6 +93,15 @@ bool BaseDateAndTimeInputType::rangeOverflow(const String& value) const > return isfinite(doubleValue) && doubleValue > maximum(); > } > >+double BaseDateAndTimeInputType::defaultValueForStepUp() const >+{ >+ double ms = currentTimeMS(); >+ double utcOffset = calculateUTCOffset(); >+ double dstOffset = calculateDSTOffset(ms, utcOffset); >+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); >+ return ms + (offset * msPerMinute); >+} >+ > bool BaseDateAndTimeInputType::stepMismatch(const String& value, double step) const > { > const double nan = numeric_limits<double>::quiet_NaN(); >diff --git a/WebCore/html/BaseDateAndTimeInputType.h b/WebCore/html/BaseDateAndTimeInputType.h >index 11c60afca658c6b722fc027dde584cd67560d49a..ad7302a9e1badbcefca1938ef0ee24c77944ecfc 100644 >--- a/WebCore/html/BaseDateAndTimeInputType.h >+++ b/WebCore/html/BaseDateAndTimeInputType.h >@@ -55,6 +55,7 @@ private: > virtual bool typeMismatch() const; > virtual bool rangeUnderflow(const String&) const; > virtual bool rangeOverflow(const String&) const; >+ virtual double defaultValueForStepUp() const; > virtual bool stepMismatch(const String&, double) const; > virtual double stepBase() const; > virtual bool handleKeydownEvent(KeyboardEvent*); >diff --git a/WebCore/html/DateTimeInputType.cpp b/WebCore/html/DateTimeInputType.cpp >index c78a54056a15e10296dee82d063e46229c0836d7..c094ac70959e32054d251474beeb0bb66bab9252 100644 >--- a/WebCore/html/DateTimeInputType.cpp >+++ b/WebCore/html/DateTimeInputType.cpp >@@ -53,6 +53,11 @@ const AtomicString& DateTimeInputType::formControlType() const > return InputTypeNames::datetime(); > } > >+double DateTimeInputType::defaultValueForStepUp() const >+{ >+ return currentTimeMS(); >+} >+ > double DateTimeInputType::minimum() const > { > return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime()); >diff --git a/WebCore/html/DateTimeInputType.h b/WebCore/html/DateTimeInputType.h >index 140975b195184ae0b6d8f8ea4d563485e161ac3f..9a0efd1f3921900839e277a32554fe5fa237ed86 100644 >--- a/WebCore/html/DateTimeInputType.h >+++ b/WebCore/html/DateTimeInputType.h >@@ -42,6 +42,7 @@ public: > private: > DateTimeInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { } > virtual const AtomicString& formControlType() const; >+ virtual double defaultValueForStepUp() const; > virtual double minimum() const; > virtual double maximum() const; > virtual double defaultStep() const; >diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp >index af4e7d0548217110e397c3bc4a1fecf7767b5809..6651ceef844be3305e2d9d9b293e752fe686f350 100644 >--- a/WebCore/html/HTMLInputElement.cpp >+++ b/WebCore/html/HTMLInputElement.cpp >@@ -1849,37 +1849,100 @@ HTMLOptionElement* HTMLInputElement::selectedOption() const > void HTMLInputElement::stepUpFromRenderer(int n) > { > // The differences from stepUp()/stepDown(): >- // If the current value is not a number, the value will be >- // - The value should be the minimum value if n > 0 >- // - The value should be the maximum value if n < 0 >+ // >+ // Difference 1: the current value >+ // If the current value is not a number, including empty, the current value is assumed as 0. >+ // * If 0 is in-range, and matches to step value >+ // - The value should be the +step if n > 0 >+ // - The value should be the -step if n < 0 >+ // If -step or +step is out of range, new value should be 0. >+ // * If 0 is smaller than the minimum value >+ // - The value should be the minimum value for any n >+ // * If 0 is larger than the maximum value >+ // - The value should be the maximum value for any n >+ // * If 0 is in-range, but not matched to step value >+ // - The value should be the larger matched value nearest to 0 if n > 0 >+ // e.g. <input type=number min=-100 step=3> -> 2 >+ // - The value should be the smaler matched value nearest to 0 if n < 0 >+ // e.g. <input type=number min=-100 step=3> -> -1 >+ // As for date/datetime/datetime-local/month/time/week types, the current value is assumed as "the current date/time". > // If the current value is smaller than the minimum value: > // - The value should be the minimum value if n > 0 > // - Nothing should happen if n < 0 > // If the current value is larger than the maximum value: > // - The value should be the maximum value if n < 0 > // - Nothing should happen if n > 0 >- >- ASSERT(hasSpinButton()); >- if (!hasSpinButton()) >+ // >+ // Difference 2: clamping steps >+ // If the current value is not matched to step value: >+ // - The value should be the larger matched value nearest to 0 if n > 0 >+ // e.g. <input type=number value=3 min=-100 step=3> -> 5 >+ // - The value should be the smaler matched value nearest to 0 if n < 0 >+ // e.g. <input type=number value=3 min=-100 step=3> -> 2 >+ // >+ // n is assumed as -n if step < 0. >+ >+ ASSERT(hasSpinButton() || m_inputType->isRangeControl()); >+ if (!hasSpinButton() && !m_inputType->isRangeControl()) > return; > ASSERT(n); > if (!n) > return; > >+ unsigned stepDecimalPlaces, baseDecimalPlaces; >+ double step, base; >+ if (equalIgnoringCase(getAttribute(stepAttr), "any")) >+ step = 0; >+ else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) >+ return; >+ base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces); >+ baseDecimalPlaces = min(baseDecimalPlaces, 16u); >+ >+ int sign = n * (step < 0 ? (-1) : (1)); >+ > const double nan = numeric_limits<double>::quiet_NaN(); > String currentStringValue = value(); > double current = m_inputType->parseToDouble(currentStringValue, nan); >- if (!isfinite(current) || (n > 0 && current < m_inputType->minimum()) || (n < 0 && current > m_inputType->maximum())) >- setValue(m_inputType->serialize(n > 0 ? m_inputType->minimum() : m_inputType->maximum())); >+ if (!isfinite(current)) { >+ ExceptionCode ec; >+ current = m_inputType->defaultValueForStepUp(); >+ setValueAsNumber(current, ec); >+ } >+ if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum())) >+ setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum())); > else { > ExceptionCode ec; >- stepUp(n, ec); >+ if (stepMismatch(currentStringValue)) { >+ double newValue; >+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces))); >+ >+ if (sign < 0) >+ newValue = round((base + floor((current - base) / step) * step) * scale) / scale; >+ else >+ newValue = round((base + ceil((current - base) / step) * step) * scale) / scale; >+ >+ if (newValue < m_inputType->minimum()) >+ newValue = m_inputType->minimum(); >+ if (newValue > m_inputType->maximum()) >+ newValue = m_inputType->maximum(); >+ >+ setValueAsNumber(newValue, ec); >+ current = newValue; >+ if (n > 1) >+ applyStep(n - 1, ec); >+ else if (n < -1) >+ applyStep(n + 1, ec); >+ } else >+ applyStep(n, ec); > } > > if (currentStringValue != value()) { > if (renderer() && renderer()->isTextField()) > toRenderTextControl(renderer())->setChangedSinceLastChangeEvent(true); >- dispatchEvent(Event::create(eventNames().inputEvent, true, false)); >+ if (m_inputType->isRangeControl()) >+ dispatchFormControlChangeEvent(); >+ else >+ dispatchEvent(Event::create(eventNames().inputEvent, true, false)); > } > } > >diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h >index 9884117b811cca19ee0747b05d05b8fce022b51b..6761b578cfdd878c975915c73278270282fa0467 100644 >--- a/WebCore/html/HTMLInputElement.h >+++ b/WebCore/html/HTMLInputElement.h >@@ -27,6 +27,7 @@ > #include "HTMLFormControlElement.h" > #include "HTMLFormElement.h" > #include "InputElement.h" >+#include "InputType.h" > #include <wtf/OwnPtr.h> > > namespace WebCore { >diff --git a/WebCore/html/InputType.cpp b/WebCore/html/InputType.cpp >index 6dd002c4f2afd151ed42bb8e330e1f5224d832c2..ba9e87720b8cef14be8f286e4a417041c3768cf0 100644 >--- a/WebCore/html/InputType.cpp >+++ b/WebCore/html/InputType.cpp >@@ -125,6 +125,11 @@ bool InputType::isTextType() const > return false; > } > >+bool InputType::isRangeControl() const >+{ >+ return false; >+} >+ > bool InputType::saveFormControlState(String& result) const > { > String currentValue = element()->value(); >@@ -213,6 +218,11 @@ bool InputType::rangeOverflow(const String&) const > return false; > } > >+double InputType::defaultValueForStepUp() const >+{ >+ return 0; >+} >+ > double InputType::minimum() const > { > ASSERT_NOT_REACHED(); >diff --git a/WebCore/html/InputType.h b/WebCore/html/InputType.h >index f1a5b6dca0f7fae23029e8c26949daa222d73b1a..4dcff019327fff33c67225d38bf459d253714c0a 100644 >--- a/WebCore/html/InputType.h >+++ b/WebCore/html/InputType.h >@@ -60,6 +60,7 @@ public: > > virtual bool isTextField() const; > virtual bool isTextType() const; >+ virtual bool isRangeControl() const; > virtual const AtomicString& formControlType() const = 0; > > // Form value functions >@@ -89,6 +90,7 @@ public: > virtual bool patternMismatch(const String&) const; > virtual bool rangeUnderflow(const String&) const; > virtual bool rangeOverflow(const String&) const; >+ virtual double defaultValueForStepUp() const; > virtual double minimum() const; > virtual double maximum() const; > virtual bool stepMismatch(const String&, double) const; >diff --git a/WebCore/html/MonthInputType.cpp b/WebCore/html/MonthInputType.cpp >index cbde5cbad2941d4c581a83ba101e49adab23dd56..f56422cf1d7a5330038d31a595f82f387560ade9 100644 >--- a/WebCore/html/MonthInputType.cpp >+++ b/WebCore/html/MonthInputType.cpp >@@ -74,6 +74,21 @@ void MonthInputType::setValueAsDate(double value, ExceptionCode&) const > element()->setValue(date.toString()); > } > >+double MonthInputType::defaultValueForStepUp() const >+{ >+ double current = currentTimeMS(); >+ double utcOffset = calculateUTCOffset(); >+ double dstOffset = calculateDSTOffset(current, utcOffset); >+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); >+ current += offset * msPerMinute; >+ >+ DateComponents date; >+ date.setMillisecondsSinceEpochForMonth(current); >+ double months = date.monthsSinceEpoch(); >+ ASSERT(isfinite(months)); >+ return months; >+} >+ > double MonthInputType::minimum() const > { > return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth()); >diff --git a/WebCore/html/MonthInputType.h b/WebCore/html/MonthInputType.h >index 50cf7d50f94bf5068172e7b9955e63415064fd0a..23536e2d9424c39e4cf6169b30591c53d72d5273 100644 >--- a/WebCore/html/MonthInputType.h >+++ b/WebCore/html/MonthInputType.h >@@ -45,6 +45,7 @@ private: > virtual double valueAsDate() const; > virtual void setValueAsDate(double, ExceptionCode&) const; > virtual double parseToDouble(const String&, double) const; >+ virtual double defaultValueForStepUp() const; > virtual double minimum() const; > virtual double maximum() const; > virtual double defaultStep() const; >diff --git a/WebCore/html/RangeInputType.cpp b/WebCore/html/RangeInputType.cpp >index ad47f14cb14a9d88912fcda62c8f97f88ad3bc1c..30b53fe3e172d01f9bce6fe59cbd88549519b8e0 100644 >--- a/WebCore/html/RangeInputType.cpp >+++ b/WebCore/html/RangeInputType.cpp >@@ -55,6 +55,11 @@ PassOwnPtr<InputType> RangeInputType::create(HTMLInputElement* element) > return adoptPtr(new RangeInputType(element)); > } > >+bool RangeInputType::isRangeControl() const >+{ >+ return true; >+} >+ > const AtomicString& RangeInputType::formControlType() const > { > return InputTypeNames::range(); >@@ -143,6 +148,8 @@ bool RangeInputType::handleKeydownEvent(KeyboardEvent* event) > double step = (max - min) / 100; > double current = parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN()); > ASSERT(isfinite(current)); >+ // Not using stepUpFromRenderer() since it is not any kind of stepUp() >+ // No stepUp() for step="any" > double newValue; > if (key == "Up" || key == "Right") { > newValue = current + step; >@@ -159,10 +166,8 @@ bool RangeInputType::handleKeydownEvent(KeyboardEvent* event) > } > } else { > int stepMagnification = (key == "Up" || key == "Right") ? 1 : -1; >- String lastStringValue = element()->value(); >- element()->stepUp(stepMagnification, ec); >- if (lastStringValue != element()->value()) >- element()->dispatchFormControlChangeEvent(); >+ // Using stepUpFromRenderer() since it is a kind of stepUp() operation >+ element()->stepUpFromRenderer(stepMagnification); > } > event->setDefaultHandled(); > return true; >diff --git a/WebCore/html/RangeInputType.h b/WebCore/html/RangeInputType.h >index c2bbb0fc1d132b0f79b5d714cdb515dd9ce315a1..14280e86eabf39aea99461fe3b14ea192ba50fd5 100644 >--- a/WebCore/html/RangeInputType.h >+++ b/WebCore/html/RangeInputType.h >@@ -41,6 +41,7 @@ public: > > private: > RangeInputType(HTMLInputElement* element) : InputType(element) { } >+ virtual bool isRangeControl() const; > virtual const AtomicString& formControlType() const; > virtual double valueAsNumber() const; > virtual void setValueAsNumber(double, ExceptionCode&) const; >diff --git a/WebCore/html/TimeInputType.cpp b/WebCore/html/TimeInputType.cpp >index 27dce9057d3cb7dc92a1de000d73c727d6e38c3a..47df997adbd5634afcc429efe4b3b09e9b0d0822 100644 >--- a/WebCore/html/TimeInputType.cpp >+++ b/WebCore/html/TimeInputType.cpp >@@ -53,6 +53,21 @@ const AtomicString& TimeInputType::formControlType() const > return InputTypeNames::time(); > } > >+double TimeInputType::defaultValueForStepUp() const >+{ >+ double current = currentTimeMS(); >+ double utcOffset = calculateUTCOffset(); >+ double dstOffset = calculateDSTOffset(current, utcOffset); >+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); >+ current += offset * msPerMinute; >+ >+ DateComponents date; >+ date.setMillisecondsSinceMidnight(current); >+ double milliseconds = date.millisecondsSinceEpoch(); >+ ASSERT(isfinite(milliseconds)); >+ return milliseconds; >+} >+ > double TimeInputType::minimum() const > { > return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumTime()); >diff --git a/WebCore/html/TimeInputType.h b/WebCore/html/TimeInputType.h >index 6070fa07389a9ae728e9fa620aa3ee9af2670727..b50d987147a09de22152a4084dd91941cc6e2f4a 100644 >--- a/WebCore/html/TimeInputType.h >+++ b/WebCore/html/TimeInputType.h >@@ -42,6 +42,7 @@ public: > private: > TimeInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { } > virtual const AtomicString& formControlType() const; >+ virtual double defaultValueForStepUp() const; > virtual double minimum() const; > virtual double maximum() const; > virtual double defaultStep() const; >diff --git a/WebCore/manual-tests/input-type-datetime-default-value.html b/WebCore/manual-tests/input-type-datetime-default-value.html >new file mode 100644 >index 0000000000000000000000000000000000000000..1c7a81750eb45ddbcba3b4905249f873dee4a5dc >--- /dev/null >+++ b/WebCore/manual-tests/input-type-datetime-default-value.html >@@ -0,0 +1,37 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> >+<html> >+<head><title>Default values for date/time input (type= date, datetime, datetime-local, month, time, week)</title></head> >+ >+<p>Enter Up or Down, or click the spin buttons for each input field.</p> >+ >+ >+<!-- >+**** >+ We should add test cases with empty/invalid values and invalid/any step. >+*** >+--> >+ >+<form> >+ <ul> >+ <li>date: <input type="date" size="32" value="" /> >+ <li>datetime: <input type="datetime" size="32" value="" /> >+ <li>datetime-local: <input type="datetime-local" size="32" value="" /> >+ <li>month: <input type="month" size="32" value="" /> >+ <li>time: <input type="time" size="32" value="" /> >+ <li>week <input type="week" size="32" value="" /> >+ </ul> >+</form> >+ >+<p>The input fields should show the current date/time (with + or - a unit date/time described below).</p> >+ >+<p>Unit dates/times</p> >+<ul> >+ <li>date: 1 day >+ <li>datetime: 1 minute >+ <li>datetime-local: 1 minute >+ <li>month: 1 month >+ <li>time: 1 minute >+ <li>week: 1 week >+</ul> >+ >+</body></html>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 45491
:
74830
|
74835
|
74839
|
74984
|
74988
|
75003
|
75004
|
75099