Changeset 54647 in webkit


Ignore:
Timestamp:
Feb 11, 2010 12:34:10 AM (14 years ago)
Author:
tkent@chromium.org
Message:

2010-02-11 Kent Tamura <tkent@chromium.org>

Reviewed by Darin Adler.

Step attribute support for date&time types.
https://bugs.webkit.org/show_bug.cgi?id=30847

Add tests for ValidityState.stepMismatch, stepUp() and stepDown()
for date, datetime, datetime-local, month, time, week types.
Update valueAsDate and valueAsNumber tests for a string representation
change.

  • fast/forms/ValidityState-stepMismatch-expected.txt: Added.
  • fast/forms/ValidityState-stepMismatch.html: Added.
  • fast/forms/input-stepup-stepdown-expected.txt: Added.
  • fast/forms/input-stepup-stepdown.html: Added.
  • fast/forms/input-valueasdate-datetime-expected.txt:
  • fast/forms/input-valueasdate-time-expected.txt:
  • fast/forms/input-valueasnumber-datetime-expected.txt:
  • fast/forms/input-valueasnumber-datetimelocal-expected.txt:
  • fast/forms/input-valueasnumber-time-expected.txt:
  • fast/forms/script-tests/ValidityState-stepMismatch.js: Added.
  • fast/forms/script-tests/input-stepup-stepdown.js: Added.
  • fast/forms/script-tests/input-valueasdate-datetime.js:
  • fast/forms/script-tests/input-valueasnumber-datetime.js:

2010-02-11 Kent Tamura <tkent@chromium.org>

Reviewed by Darin Adler.

Step attribute support for date&time types.
https://bugs.webkit.org/show_bug.cgi?id=30847

  • Add implementation for ValidityState.stepMismatch, stepUp() and stepDown() for date, datetime, datetime-local, month, time, week types.
  • Fix string representation of DateComponents.

Tests: fast/forms/ValidityState-stepMismatch.html

fast/forms/input-stepup-stepdown.html

  • html/HTMLInputElement.cpp:
    • Change monthDefaultMaximum so that DateComponents::m_year doesn't overflow.

(WebCore::HTMLInputElement::stepBase):
(WebCore::HTMLInputElement::stepMismatch):
(WebCore::HTMLInputElement::getStepParameters):
(WebCore::HTMLInputElement::getAllowedValueStep):
(WebCore::HTMLInputElement::applyStep):

Renamed from applyStepForNumberOrRange(), and add support for other types.

(WebCore::HTMLInputElement::stepUp): Rename applyStepForNumberOrRange().
(WebCore::HTMLInputElement::stepDown): Rename applyStepForNumberOrRange().
(WebCore::HTMLInputElement::setValueAsDate): Use setDateValue().
(WebCore::HTMLInputElement::setDateValue):

A helper function to make the best representation of DateComponents.

(WebCore::HTMLInputElement::setValueAsNumber): Use setDateValue().

  • html/HTMLInputElement.h:
Location:
trunk
Files:
6 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r54646 r54647  
     12010-02-11  Kent Tamura  <tkent@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Step attribute support for date&time types.
     6        https://bugs.webkit.org/show_bug.cgi?id=30847
     7
     8        Add tests for ValidityState.stepMismatch, stepUp() and stepDown()
     9        for date, datetime, datetime-local, month, time, week types.
     10        Update valueAsDate and valueAsNumber tests for a string representation
     11        change.
     12
     13        * fast/forms/ValidityState-stepMismatch-expected.txt: Added.
     14        * fast/forms/ValidityState-stepMismatch.html: Added.
     15        * fast/forms/input-stepup-stepdown-expected.txt: Added.
     16        * fast/forms/input-stepup-stepdown.html: Added.
     17        * fast/forms/input-valueasdate-datetime-expected.txt:
     18        * fast/forms/input-valueasdate-time-expected.txt:
     19        * fast/forms/input-valueasnumber-datetime-expected.txt:
     20        * fast/forms/input-valueasnumber-datetimelocal-expected.txt:
     21        * fast/forms/input-valueasnumber-time-expected.txt:
     22        * fast/forms/script-tests/ValidityState-stepMismatch.js: Added.
     23        * fast/forms/script-tests/input-stepup-stepdown.js: Added.
     24        * fast/forms/script-tests/input-valueasdate-datetime.js:
     25        * fast/forms/script-tests/input-valueasnumber-datetime.js:
     26
    1272010-02-10  Oliver Hunt  <oliver@apple.com>
    228
  • trunk/LayoutTests/fast/forms/input-valueasdate-datetime-expected.txt

    r53669 r54647  
    2121PASS input.value = "2010-01-01T00:00Z"; input.valueAsDate = null; input.value is ""
    2222Step attribute value and string representation:
    23 FAIL input.step = "1"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0) should be 2010-01-21T00:00:00. Was 2010-01-21T00:00Z.
    24 FAIL input.step = "0.001"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0) should be 2010-01-21T00:00:00.000. Was 2010-01-21T00:00Z.
     23PASS input.step = "1"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00Z"
     24PASS input.step = "0.001"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00.000Z"
    2525PASS successfullyParsed is true
    2626
  • trunk/LayoutTests/fast/forms/input-valueasdate-time-expected.txt

    r53551 r54647  
    2323PASS input.value = "00:00"; input.valueAsDate = null; input.value is ""
    2424Step attribute value and string representation:
    25 FAIL input.step = "1"; setValueAsDateAndGetValue(0, 0, 0, 0) should be 00:00:00. Was 00:00.
    26 FAIL input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0) should be 00:00:00.000. Was 00:00.
     25PASS input.step = "1"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00"
     26PASS input.step = "0.001"; setValueAsDateAndGetValue(0, 0, 0, 0) is "00:00:00.000"
    2727PASS successfullyParsed is true
    2828
  • trunk/LayoutTests/fast/forms/input-valueasnumber-datetime-expected.txt

    r54121 r54647  
    2626PASS input.valueAsNumber = Number.NEGATIVE_INFINITY threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
    2727Step attribute value and string representation:
    28 FAIL input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) should be 2010-01-21T00:00:00. Was 2010-01-21T00:00Z.
    29 FAIL input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) should be 2010-01-21T00:00:00.000. Was 2010-01-21T00:00Z.
     28PASS input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00Z"
     29PASS input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00.000Z"
    3030PASS successfullyParsed is true
    3131
  • trunk/LayoutTests/fast/forms/input-valueasnumber-datetimelocal-expected.txt

    r53991 r54647  
    2525PASS input.valueAsNumber = Number.NEGATIVE_INFINITY threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
    2626Step attribute value and string representation:
    27 FAIL input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) should be 2010-01-21T00:00:00. Was 2010-01-21T00:00.
    28 FAIL input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) should be 2010-01-21T00:00:00.000. Was 2010-01-21T00:00.
     27PASS input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00"
     28PASS input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0) is "2010-01-21T00:00:00.000"
    2929PASS successfullyParsed is true
    3030
  • trunk/LayoutTests/fast/forms/input-valueasnumber-time-expected.txt

    r53893 r54647  
    2626PASS input.valueAsNumber = Number.NEGATIVE_INFINITY threw exception Error: NOT_SUPPORTED_ERR: DOM Exception 9.
    2727Step attribute value and string representation:
    28 FAIL input.step = "1"; setValueAsNumberAndGetValue(0, 0, 0, 0) should be 00:00:00. Was 00:00.
    29 FAIL input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0) should be 00:00:00.000. Was 00:00.
     28PASS input.step = "1"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00"
     29PASS input.step = "0.001"; setValueAsNumberAndGetValue(0, 0, 0, 0) is "00:00:00.000"
    3030PASS successfullyParsed is true
    3131
  • trunk/LayoutTests/fast/forms/script-tests/input-valueasdate-datetime.js

    r53669 r54647  
    3838debug('Step attribute value and string representation:');
    3939// If the step attribute value is 1 second and the second part is 0, we should show the second part.
    40 shouldBe('input.step = "1"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00"');
     40shouldBe('input.step = "1"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00Z"');
    4141// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
    42 shouldBe('input.step = "0.001"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00.000"');
     42shouldBe('input.step = "0.001"; setValueAsDateAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00.000Z"');
    4343
    4444var successfullyParsed = true;
  • trunk/LayoutTests/fast/forms/script-tests/input-valueasnumber-datetime.js

    r54121 r54647  
    4343debug('Step attribute value and string representation:');
    4444// If the step attribute value is 1 second and the second part is 0, we should show the second part.
    45 shouldBe('input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00"');
     45shouldBe('input.step = "1"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00Z"');
    4646// If the step attribute value is 0.001 second and the millisecond part is 0, we should show the millisecond part.
    47 shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00.000"');
     47shouldBe('input.step = "0.001"; setValueAsNumberAndGetValue(2010, 0, 21, 0, 0, 0, 0)', '"2010-01-21T00:00:00.000Z"');
    4848
    4949var successfullyParsed = true;
  • trunk/WebCore/ChangeLog

    r54646 r54647  
     12010-02-11  Kent Tamura  <tkent@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Step attribute support for date&time types.
     6        https://bugs.webkit.org/show_bug.cgi?id=30847
     7
     8        - Add implementation for ValidityState.stepMismatch, stepUp() and
     9          stepDown() for date, datetime, datetime-local, month, time, week types.
     10        - Fix string representation of DateComponents.
     11
     12        Tests: fast/forms/ValidityState-stepMismatch.html
     13               fast/forms/input-stepup-stepdown.html
     14
     15        * html/HTMLInputElement.cpp:
     16          - Change monthDefaultMaximum so that DateComponents::m_year doesn't overflow.
     17        (WebCore::HTMLInputElement::stepBase):
     18        (WebCore::HTMLInputElement::stepMismatch):
     19        (WebCore::HTMLInputElement::getStepParameters):
     20        (WebCore::HTMLInputElement::getAllowedValueStep):
     21        (WebCore::HTMLInputElement::applyStep):
     22          Renamed from applyStepForNumberOrRange(), and add support for other types.
     23        (WebCore::HTMLInputElement::stepUp): Rename applyStepForNumberOrRange().
     24        (WebCore::HTMLInputElement::stepDown): Rename applyStepForNumberOrRange().
     25        (WebCore::HTMLInputElement::setValueAsDate): Use setDateValue().
     26        (WebCore::HTMLInputElement::setDateValue):
     27          A helper function to make the best representation of DateComponents.
     28        (WebCore::HTMLInputElement::setValueAsNumber):  Use setDateValue().
     29        * html/HTMLInputElement.h:
     30
    1312010-02-10  Oliver Hunt  <oliver@apple.com>
    232
  • trunk/WebCore/html/HTMLInputElement.cpp

    r54438 r54647  
    7777
    7878// Constant values for getAllowedValueStep().
     79static const double dateDefaultStep = 1.0;
     80static const double dateStepScaleFactor = 86400000.0;
     81static const double dateTimeDefaultStep = 60.0;
     82static const double dateTimeStepScaleFactor = 1000.0;
     83static const double monthDefaultStep = 1.0;
     84static const double monthStepScaleFactor = 1.0;
    7985static const double numberDefaultStep = 1.0;
    8086static const double numberStepScaleFactor = 1.0;
     87static const double timeDefaultStep = 60.0;
     88static const double timeStepScaleFactor = 1000.0;
     89static const double weekDefaultStep = 1.0;
     90static const double weekStepScaleFactor = 604800000.0;
     91
    8192// Constant values for minimum().
    8293static const double dateDefaultMinimum = -12219292800000.0; // This means 1582-10-15T00:00Z.
     
    8798static const double timeDefaultMinimum = 0.0; // 00:00:00.000
    8899static const double weekDefaultMinimum = -12212380800000.0; // 1583-01-03, the first Monday of 1583.
     100
    89101// Constant values for maximum().
    90102static const double dateDefaultMaximum = DBL_MAX;
    91103static const double dateTimeDefaultMaximum = DBL_MAX;
    92 static const double monthDefaultMaximum = DBL_MAX;
     104// DateComponents::m_year can't represent a year greater than INT_MAX.
     105static const double monthDefaultMaximum = (INT_MAX - 1970) * 12.0 + 12 - 1;
    93106static const double numberDefaultMaximum = DBL_MAX;
    94107static const double rangeDefaultMaximum = 100.0;
    95108static const double timeDefaultMaximum = 86399999.0; // 23:59:59.999
    96109static const double weekDefaultMaximum = DBL_MAX;
     110
     111static const double defaultStepBase = 0.0;
     112static const double weekDefaultStepBase = -259200000.0; // The first day of 1970-W01.
     113
     114static const double msecPerMinute = 60 * 1000;
     115static const double msecPerSecond = 1000;
    97116
    98117HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
     
    436455double HTMLInputElement::stepBase() const
    437456{
    438     if (inputType() == RANGE)
     457    switch (inputType()) {
     458    case RANGE:
    439459        return minimum();
    440     if (inputType() == NUMBER) {
    441         static const double defaultStepBase = 0.0;
    442         double min = defaultStepBase;
    443         formStringToDouble(getAttribute(minAttr), &min);
    444         return min;
     460    case DATE:
     461    case DATETIME:
     462    case DATETIMELOCAL:
     463    case MONTH:
     464    case NUMBER:
     465    case TIME:
     466        return parseToDouble(getAttribute(minAttr), defaultStepBase);
     467    case WEEK:
     468        return parseToDouble(getAttribute(minAttr), weekDefaultStepBase);
     469    case BUTTON:
     470    case CHECKBOX:
     471    case COLOR:
     472    case EMAIL:
     473    case FILE:
     474    case HIDDEN:
     475    case IMAGE:
     476    case ISINDEX:
     477    case PASSWORD:
     478    case RADIO:
     479    case RESET:
     480    case SEARCH:
     481    case SUBMIT:
     482    case TELEPHONE:
     483    case TEXT:
     484    case URL:
     485        break;
    445486    }
    446487    ASSERT_NOT_REACHED();
     
    453494    if (!getAllowedValueStep(&step))
    454495        return false;
    455     if (inputType() == NUMBER) {
     496    switch (inputType()) {
     497    case RANGE:
     498        // stepMismatch doesn't occur for RANGE. RenderSlider guarantees the
     499        // value matches to step.
     500        return false;
     501    case NUMBER: {
    456502        double doubleValue;
    457503        if (!formStringToDouble(value(), &doubleValue))
     
    470516        return acceptableError < remainder && remainder < (step - acceptableError);
    471517    }
    472     // Non-RANGE types should be rejected by getAllowedValueStep().
    473     ASSERT(inputType() == RANGE);
    474     // stepMismatch doesn't occur for RANGE. RenderSlider guarantees the
    475     // value matches to step.
     518    case DATE:
     519    case DATETIME:
     520    case DATETIMELOCAL:
     521    case MONTH:
     522    case TIME:
     523    case WEEK: {
     524        const double nan = numeric_limits<double>::quiet_NaN();
     525        double doubleValue = parseToDouble(value(), nan);
     526        doubleValue = fabs(doubleValue - stepBase());
     527        if (!isfinite(doubleValue))
     528            return false;
     529        ASSERT(round(doubleValue) == doubleValue);
     530        ASSERT(round(step) == step);
     531        return fmod(doubleValue, step);
     532    }
     533    case BUTTON:
     534    case CHECKBOX:
     535    case COLOR:
     536    case EMAIL:
     537    case FILE:
     538    case HIDDEN:
     539    case IMAGE:
     540    case ISINDEX:
     541    case PASSWORD:
     542    case RADIO:
     543    case RESET:
     544    case SEARCH:
     545    case SUBMIT:
     546    case TELEPHONE:
     547    case TEXT:
     548    case URL:
     549        break;
     550    }
     551    // Non-supported types should be rejected by getAllowedValueStep().
     552    ASSERT_NOT_REACHED();
    476553    return false;
    477554}
     
    488565        return true;
    489566    case DATE:
     567        *defaultStep = dateDefaultStep;
     568        *stepScaleFactor = dateStepScaleFactor;
     569        return true;
    490570    case DATETIME:
    491571    case DATETIMELOCAL:
     572        *defaultStep = dateTimeDefaultStep;
     573        *stepScaleFactor = dateTimeStepScaleFactor;
     574        return true;
    492575    case MONTH:
     576        *defaultStep = monthDefaultStep;
     577        *stepScaleFactor = monthStepScaleFactor;
     578        return true;
    493579    case TIME:
     580        *defaultStep = timeDefaultStep;
     581        *stepScaleFactor = timeStepScaleFactor;
     582        return true;
    494583    case WEEK:
    495         // FIXME: Implement for these types.
    496         return false;
     584        *defaultStep = weekDefaultStep;
     585        *stepScaleFactor = weekStepScaleFactor;
     586        return true;
    497587    case BUTTON:
    498588    case CHECKBOX:
     
    536626        return true;
    537627    }
    538     *step = parsed * stepScaleFactor;
    539     ASSERT(*step > 0);
     628    // For DATE, MONTH, WEEK, the parsed value should be an integer.
     629    if (inputType() == DATE || inputType() == MONTH || inputType() == WEEK)
     630        parsed = max(round(parsed), 1.0);
     631    double result = parsed * stepScaleFactor;
     632    // For DATETIME, DATETIMELOCAL, TIME, the result should be an integer.
     633    if (inputType() == DATETIME || inputType() == DATETIMELOCAL || inputType() == TIME)
     634        result = max(round(result), 1.0);
     635    ASSERT(result > 0);
     636    *step = result;
    540637    return true;
    541638}
    542639
    543 void HTMLInputElement::applyStepForNumberOrRange(double count, ExceptionCode& ec)
    544 {
    545     ASSERT(inputType() == NUMBER || inputType() == RANGE);
     640void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
     641{
    546642    double step;
    547643    if (!getAllowedValueStep(&step)) {
     
    549645        return;
    550646    }
    551     double current;
    552     if (!formStringToDouble(value(), &current)) {
     647    const double nan = numeric_limits<double>::quiet_NaN();
     648    double current = parseToDouble(value(), nan);
     649    if (!isfinite(current)) {
    553650        ec = INVALID_STATE_ERR;
    554651        return;
     
    569666        return;
    570667    }
    571     setValue(formStringFromDouble(newValue));
     668    setValueAsNumber(newValue, ec);
    572669}
    573670
    574671void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
    575672{
    576     if (inputType() != NUMBER && inputType() != RANGE) {
    577         ec = INVALID_STATE_ERR;
    578         return;
    579     }
    580     applyStepForNumberOrRange(n, ec);
     673    applyStep(n, ec);
    581674}
    582675
    583676void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
    584677{
    585     if (inputType() != NUMBER && inputType() != RANGE) {
    586         ec = INVALID_STATE_ERR;
    587         return;
    588     }
    589     applyStepForNumberOrRange(-n, ec);
     678    applyStep(-n, ec);
    590679}
    591680
     
    16551744        return;
    16561745    }
    1657     // FIXME: We should specify SecondFormat.
    1658     // e.g. If the step value is 60, use SecondFormat::None.
    1659     //      If the step value is 1, use SecondFormat::Second.
    1660     setValue(date.toString());
     1746    setDateValue(date);
     1747}
     1748
     1749void HTMLInputElement::setDateValue(const DateComponents& date)
     1750{
     1751    double step;
     1752    if (!getAllowedValueStep(&step)) {
     1753        setValue(date.toString());
     1754        return;
     1755    }
     1756    if (!fmod(step, msecPerMinute)) {
     1757        setValue(date.toString(DateComponents::None));
     1758        return;
     1759    }
     1760    if (!fmod(step, msecPerSecond)) {
     1761        setValue(date.toString(DateComponents::Second));
     1762        return;
     1763    }
     1764    setValue(date.toString(DateComponents::Millisecond));
    16611765}
    16621766
     
    17251829            return;
    17261830        }
    1727         // FIXME: We should specify SecondFormat.
    1728         // e.g. If the step value is 60, use SecondFormat::None.
    1729         //      If the step value is 1, use SecondFormat::Second.
    1730         setValue(date.toString());
     1831        setDateValue(date);
    17311832        return;
    17321833    }
  • trunk/WebCore/html/HTMLInputElement.h

    r54003 r54647  
    296296    // Helper for getAllowedValueStep();
    297297    bool getStepParameters(double* defaultStep, double* stepScaleFactor) const;
    298     // Helper for stepUp()/stepDown().  Adds step value * count to the current number/range value.
    299     void applyStepForNumberOrRange(double count, ExceptionCode&);
     298    // Helper for stepUp()/stepDown().  Adds step value * count to the current value.
     299    void applyStep(double count, ExceptionCode&);
    300300    // Helper for applyStepForNumberOrRange().
    301301    double stepBase() const;
     
    306306    // return NaN or Infinity only if defaultValue is NaN or Infinity.
    307307    double parseToDouble(const String&, double defaultValue) const;
     308
     309    // Generates a suitable string for the specified DateComponents and the
     310    // step value, and calls setValue() with it.
     311    void setDateValue(const DateComponents&);
     312
    308313
    309314#if ENABLE(DATALIST)
Note: See TracChangeset for help on using the changeset viewer.