Changeset 51159 in webkit


Ignore:
Timestamp:
Nov 18, 2009 5:48:52 PM (14 years ago)
Author:
eric@webkit.org
Message:

2009-11-18 Kent Tamura <tkent@chromium.org>

Reviewed by Darin Adler.

Add tests for ValidityState.stepMismatch.
https://bugs.webkit.org/show_bug.cgi?id=31331

  • fast/forms/ValidityState-stepMismatch-number-expected.txt: Added.
  • fast/forms/ValidityState-stepMismatch-number.html: Added.
  • fast/forms/ValidityState-stepMismatch-range-expected.txt: Added.
  • fast/forms/ValidityState-stepMismatch-range.html: Added.
  • fast/forms/ValidityState-stepMismatch-unsupported-expected.txt: Added.
  • fast/forms/ValidityState-stepMismatch-unsupported.html: Added.
  • fast/forms/input-step-expected.txt: Added.
  • fast/forms/input-step.html: Added.
  • fast/forms/script-tests/ValidityState-stepMismatch-number.js: Added.
  • fast/forms/script-tests/ValidityState-stepMismatch-range.js: Added.
  • fast/forms/script-tests/ValidityState-stepMismatch-unsupported.js: Added.
  • fast/forms/script-tests/input-step.js: Added.

2009-11-18 Kent Tamura <tkent@chromium.org>

Reviewed by Darin Adler.

Support for step attribute and ValidityStae.stepMismatch for
type=number and range. stepMismatch will be false if the
difference between the current value and a multiple of the step
value is very small.

Change the behavior of RenderSlider so that it always has a value
rounded to the step attribute value.

https://bugs.webkit.org/show_bug.cgi?id=31331

Tests: fast/forms/ValidityState-stepMismatch-number.html

fast/forms/ValidityState-stepMismatch-range.html
fast/forms/ValidityState-stepMismatch-unsupported.html
fast/forms/input-step.html

  • html/HTMLAttributeNames.in: Add "step".
  • html/HTMLInputElement.cpp: (WebCore::HTMLInputElement::stepMismatch): (WebCore::HTMLInputElement::getStepParameters): (WebCore::HTMLInputElement::getAllowedValueStep):
  • html/HTMLInputElement.h:
  • html/HTMLInputElement.idl: Add "step".
  • html/ValidityState.cpp: (WebCore::ValidityState::stepMismatch): Forward to HTMLInputElement::stepMismatch().
  • html/ValidityState.h:
  • rendering/RenderSlider.cpp: (WebCore::SliderRange::SliderRange): (WebCore::SliderRange::clampValue):
Location:
trunk
Files:
12 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r51154 r51159  
     12009-11-18  Kent Tamura  <tkent@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Add tests for ValidityState.stepMismatch.
     6        https://bugs.webkit.org/show_bug.cgi?id=31331
     7
     8        * fast/forms/ValidityState-stepMismatch-number-expected.txt: Added.
     9        * fast/forms/ValidityState-stepMismatch-number.html: Added.
     10        * fast/forms/ValidityState-stepMismatch-range-expected.txt: Added.
     11        * fast/forms/ValidityState-stepMismatch-range.html: Added.
     12        * fast/forms/ValidityState-stepMismatch-unsupported-expected.txt: Added.
     13        * fast/forms/ValidityState-stepMismatch-unsupported.html: Added.
     14        * fast/forms/input-step-expected.txt: Added.
     15        * fast/forms/input-step.html: Added.
     16        * fast/forms/script-tests/ValidityState-stepMismatch-number.js: Added.
     17        * fast/forms/script-tests/ValidityState-stepMismatch-range.js: Added.
     18        * fast/forms/script-tests/ValidityState-stepMismatch-unsupported.js: Added.
     19        * fast/forms/script-tests/input-step.js: Added.
     20
    1212009-11-18  Shu Chang  <Chang.Shu@nokia.com>
    222
  • trunk/WebCore/ChangeLog

    r51158 r51159  
     12009-11-18  Kent Tamura  <tkent@chromium.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Support for step attribute and ValidityStae.stepMismatch for
     6        type=number and range.  stepMismatch will be false if the
     7        difference between the current value and a multiple of the step
     8        value is very small.
     9
     10        Change the behavior of RenderSlider so that it always has a value
     11        rounded to the step attribute value.
     12
     13        https://bugs.webkit.org/show_bug.cgi?id=31331
     14
     15        Tests: fast/forms/ValidityState-stepMismatch-number.html
     16               fast/forms/ValidityState-stepMismatch-range.html
     17               fast/forms/ValidityState-stepMismatch-unsupported.html
     18               fast/forms/input-step.html
     19
     20        * html/HTMLAttributeNames.in: Add "step".
     21        * html/HTMLInputElement.cpp:
     22        (WebCore::HTMLInputElement::stepMismatch):
     23        (WebCore::HTMLInputElement::getStepParameters):
     24        (WebCore::HTMLInputElement::getAllowedValueStep):
     25        * html/HTMLInputElement.h:
     26        * html/HTMLInputElement.idl: Add "step".
     27        * html/ValidityState.cpp:
     28        (WebCore::ValidityState::stepMismatch): Forward to HTMLInputElement::stepMismatch().
     29        * html/ValidityState.h:
     30        * rendering/RenderSlider.cpp:
     31        (WebCore::SliderRange::SliderRange):
     32        (WebCore::SliderRange::clampValue):
     33
    1342009-11-18  Dmitry Titov  <dimich@chromium.org>
    235
  • trunk/WebCore/html/HTMLAttributeNames.in

    r50893 r51159  
    236236standby
    237237start
     238step
    238239style
    239240summary
  • trunk/WebCore/html/HTMLInputElement.cpp

    r51148 r51159  
    7474const int maxSavedResults = 256;
    7575
     76// Constant values for getAllowedValueStep().
     77static const double numberDefaultStep = 1.0;
     78static const double numberStepScaleFactor = 1.0;
     79
    7680HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document* doc, HTMLFormElement* f)
    7781    : HTMLTextFormControlElement(tagName, doc, f)
     
    307311    }
    308312    return max;
     313}
     314
     315bool HTMLInputElement::stepMismatch() const
     316{
     317    double step;
     318    if (!getAllowedValueStep(&step))
     319        return false;
     320    if (inputType() == NUMBER) {
     321        double doubleValue;
     322        if (!formStringToDouble(value(), &doubleValue))
     323            return false;
     324        double stepBase = 0.0;
     325        formStringToDouble(getAttribute(minAttr), &stepBase);
     326        doubleValue = fabs(doubleValue - stepBase);
     327        if (isinf(doubleValue))
     328            return false;
     329        // double's fractional part size is DBL_MAN_DIG-bit.  If the current
     330        // value is greater than step*2^DBL_MANT_DIG, the following fmod() makes
     331        // no sense.
     332        if (doubleValue / pow(2, DBL_MANT_DIG) > step)
     333            return false;
     334        double remainder = fmod(doubleValue, step);
     335        // Accepts errors in lower 7-bit.
     336        double acceptableError = step / pow(2, DBL_MANT_DIG - 7);
     337        return acceptableError < remainder && remainder < (step - acceptableError);
     338    }
     339    // Non-RANGE types should be rejected by getAllowedValueStep().
     340    ASSERT(inputType() == RANGE);
     341    // stepMismatch doesn't occur for RANGE. RenderSlider guarantees the
     342    // value matches to step.
     343    return false;
     344}
     345
     346bool HTMLInputElement::getStepParameters(double* defaultStep, double* stepScaleFactor) const
     347{
     348    ASSERT(defaultStep);
     349    ASSERT(stepScaleFactor);
     350    switch (inputType()) {
     351    case NUMBER:
     352    case RANGE:
     353        *defaultStep = numberDefaultStep;
     354        *stepScaleFactor = numberStepScaleFactor;
     355        return true;
     356    case DATE:
     357    case DATETIME:
     358    case DATETIMELOCAL:
     359    case MONTH:
     360    case TIME:
     361    case WEEK:
     362        // FIXME: Implement for these types.
     363        return false;
     364    case BUTTON:
     365    case CHECKBOX:
     366    case COLOR:
     367    case EMAIL:
     368    case FILE:
     369    case HIDDEN:
     370    case IMAGE:
     371    case ISINDEX:
     372    case PASSWORD:
     373    case RADIO:
     374    case RESET:
     375    case SEARCH:
     376    case SUBMIT:
     377    case TELEPHONE:
     378    case TEXT:
     379    case URL:
     380        return false;
     381    }
     382    ASSERT_NOT_REACHED();
     383    return false;
     384}
     385
     386bool HTMLInputElement::getAllowedValueStep(double* step) const
     387{
     388    ASSERT(step);
     389    double defaultStep;
     390    double stepScaleFactor;
     391    if (!getStepParameters(&defaultStep, &stepScaleFactor))
     392        return false;
     393    const AtomicString& stepString = getAttribute(stepAttr);
     394    if (stepString.isEmpty()) {
     395        *step = defaultStep * stepScaleFactor;
     396        return true;
     397    }
     398    if (equalIgnoringCase(stepString, "any"))
     399        return false;
     400    double parsed;
     401    if (!formStringToDouble(stepString, &parsed) || parsed <= 0.0) {
     402        *step = defaultStep * stepScaleFactor;
     403        return true;
     404    }
     405    *step = parsed * stepScaleFactor;
     406    return true;
    309407}
    310408
  • trunk/WebCore/html/HTMLInputElement.h

    r50996 r51159  
    111111    // This always returns a value which is <= rangeMinimum().
    112112    double rangeMaximum() const;
     113    // Sets the "allowed value step" defined in the HTML spec to the specified double pointer.
     114    // Returns false if there is no "allowed value step."
     115    bool getAllowedValueStep(double*) const;
     116    // For ValidityState.
     117    bool stepMismatch() const;
    113118
    114119    bool isTextButton() const { return m_type == SUBMIT || m_type == RESET || m_type == BUTTON; }
     
    266271
    267272    PassRefPtr<HTMLFormElement> createTemporaryFormForIsIndex();
    268 
     273    // Helper for getAllowedValueStep();
     274    bool getStepParameters(double* defaultStep, double* stepScaleFactor) const;
    269275#if ENABLE(DATALIST)
    270276    HTMLDataListElement* dataList() const;
  • trunk/WebCore/html/HTMLInputElement.idl

    r49199 r51159  
    6464#endif
    6565                 attribute [ConvertNullToNullString] DOMString src;
     66                 attribute [Reflect] DOMString step;
    6667                 attribute [ConvertNullToNullString, JSCCustomGetter] DOMString type; // readonly dropped as part of DOM level 2
    6768                 attribute [ConvertNullToNullString] DOMString useMap;
     
    7071        readonly attribute HTMLOptionElement selectedOption;
    7172#endif
     73
    7274        readonly attribute boolean         willValidate;
    7375        boolean            checkValidity();
  • trunk/WebCore/html/ValidityState.cpp

    r49508 r51159  
    9494}
    9595
     96bool ValidityState::stepMismatch()
     97{
     98    if (!control()->hasTagName(inputTag))
     99        return false;
     100    return static_cast<HTMLInputElement*>(control())->stepMismatch();
     101}
     102
    96103bool ValidityState::valid()
    97104{
  • trunk/WebCore/html/ValidityState.h

    r49508 r51159  
    4747        bool rangeUnderflow();
    4848        bool rangeOverflow();
    49         bool stepMismatch() { return false; }
     49        bool stepMismatch();
    5050        bool customError() { return !m_customErrorMessage.isEmpty(); }
    5151        bool valid();
  • trunk/WebCore/rendering/RenderSlider.cpp

    r50417 r51159  
    4949// and could be put with HTMLInputElement (possibly with a new name) instead of here.
    5050struct SliderRange {
    51     bool isIntegral;
     51    bool hasStep;
     52    double step;
    5253    double minimum;
    5354    double maximum;  // maximum must be >= minimum.
     
    7677SliderRange::SliderRange(HTMLInputElement* element)
    7778{
    78     // FIXME: What's the right way to handle an integral range with non-integral minimum and maximum?
    79     // Currently values are guaranteed to be integral but could be outside the range in that case.
    80 
    81     isIntegral = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
     79    if (element->hasAttribute(precisionAttr)) {
     80        step = 1.0;
     81        hasStep = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
     82    } else
     83        hasStep = element->getAllowedValueStep(&step);
    8284
    8385    maximum = element->rangeMaximum();
     
    8890{
    8991    double clampedValue = max(minimum, min(value, maximum));
    90     return isIntegral ? round(clampedValue) : clampedValue;
     92    if (!hasStep)
     93        return clampedValue;
     94    // Rounds clampedValue to minimum + N * step.
     95    clampedValue = minimum + round((clampedValue - minimum) / step) * step;
     96    if (clampedValue > maximum)
     97       clampedValue -= step;
     98    ASSERT(clampedValue >= minimum);
     99    ASSERT(clampedValue <= maximum);
     100    return clampedValue;
    91101}
    92102
Note: See TracChangeset for help on using the changeset viewer.