Changeset 117738 in webkit


Ignore:
Timestamp:
May 21, 2012 12:15:38 AM (12 years ago)
Author:
yosin@chromium.org
Message:

[Forms] Move numeric related methods in HTMLInputElement class to another place
https://bugs.webkit.org/show_bug.cgi?id=82034

Reviewed by Kent Tamura.

This patch moves step and range related methods into StepRange class
for ease of using step calculation other than double floating point
number arithmetic, e.g. decimal, long double, and so on.

New class StepRange::StepDescription holds values for calculating
stepped value, defaultStep, defaultStepBase, integer rounding flags,
step scale factor instead of virtual methods in InputType class.

No new tests because of this patch doesn't change behavior.

  • WebCore.xcodeproj/project.pbxproj: Set attribute of StepRange.h to "Private" for including it in HTMLInputElement.cpp.
  • html/BaseDateAndTimeInputType.cpp:

(WebCore::InputType::rangeOverflow): Moved to use InputType class.
(WebCore::InputType::rangeUnderflow): Moved to use InputType class.
(WebCore::BaseDateAndTimeInputType::stepMismatch): Moved to use stepRange.

  • html/BaseDateAndTimeInputType.h:

(BaseDateAndTimeInputType): Removed method declaration for stepBase.

  • html/DateInputType.cpp:

(WebCore::DateInputType::setupStepRange): Added.

  • html/DateInputType.h:

(DateInputType): Removed method declarations.

  • html/DateTimeInputType.cpp:

(WebCore::DateTimeInputType::defaultStep): Removed.
(WebCore::DateTimeInputType::maximum): Removed.
(WebCore::DateTimeInputType::minimum): Removed.
(WebCore::DateTimeInputType::setupStepRange): Added
(WebCore::DateTimeInputType::stepScaleFactor): Removed.

  • html/DateTimeInputType.h:

(DateTimeInputType): Removed deprecated method declarations.

  • html/DateTimeLocalInputType.cpp:

(WebCore::DateTimeLocalInputType::defaultStep): Removed.
(WebCore::DateTimeLocalInputType::maximum): Removed.
(WebCore::DateTimeLocalInputType::minimum): Removed.
(WebCore::DateTimeLocalInputType::setupStepRange): Added.
(WebCore::DateTimeLocalInputType::stepScaleFactor): Removed.

  • html/DateTimeLocalInputType.h:

(DateTimeLocalInputType):

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::isInRange): Changed to call InputType::isInRange.
(WebCore::HTMLInputElement::isOutOfRange): Changed to call InputType::isOutOfRange.
(WebCore::HTMLInputElement::setupStepRange): Added.

  • html/HTMLInputElement.h:

(HTMLInputElement):

  • html/InputType.cpp:

(WebCore::InputType::acceptableError): Moved to StepRange class.
(WebCore::InputType::alignValueForStep): Moved to StepRange class.
(WebCore::InputType::minimum): Changed to use StepRange class.
(WebCore::InputType::maximum): Changed to use StepRange class.
(WebCore::InputType::parseToDouble): Changed to have ASSERT_NOT_REACHED.
(WebCore::InputType::stepBaseWithDecimalPlaces): Changed to use StepRange class.
(WebCore::InputType::validationMessage): Changed to use StepRange class.
(WebCore::InputType::applyStep): Changed to use StepRange class.
(WebCore::InputType::getAllowedValueStep): Changed to use StepRange class.
(WebCore::InputType::isInRange): Added.
(WebCore::InputType::isOutOfRange): Added.
(WebCore::InputType::rangeOverflow): Changed to use StepRange class.
(WebCore::InputType::rangeUnderflow): Changed to use StepRange class.
(WebCore::InputType::setupStepRange): Added.
(WebCore::InputType::stepUpFromRenderer): Changed to use StepRange class.
(WebCore::InputType::stepMismatch): Changed to use StepRange class.

  • html/InputType.h:

(InputType):

  • html/MonthInputType.cpp:

(WebCore::MonthInputType::defaultStep): Removed.
(WebCore::MonthInputType::maximum): Removed.
(WebCore::MonthInputType::minimum): Removed.
(WebCore::MonthInputType::setupStepRange): Added.
(WebCore::MonthInputType::stepScaleFactor): Removed.

  • html/MonthInputType.h:

(MonthInputType):

  • html/NumberInputType.cpp:

(WebCore):
(WebCore::NumberInputType::defaultStep): Removed.
(WebCore::NumberInputType::maximum): Removed.
(WebCore::NumberInputType::minimum): Removed.
(WebCore::NumberInputType::rangeOverflow): Moved to InputType class.
(WebCore::NumberInputType::rangeUnderflow): Moved to InputType class.
(WebCore::NumberInputType::setupStepRange): Added.
(WebCore::NumberInputType::stepMismatch): Moved to InputType class.
(WebCore::NumberInputType::stepBaseWithDecimalPlaces): Changed to use StepRange class.
(WebCore::NumberInputType::stepScaleFactor): Removed.

  • html/NumberInputType.h:

(NumberInputType):

  • html/RangeInputType.cpp:

(WebCore::RangeInputType::defaultStep): Removed.
(WebCore::RangeInputType::maximum): Removed.
(WebCore::RangeInputType::minimum): Removed.
(WebCore::RangeInputType::setupStepRange): Added.
(WebCore::RangeInputType::stepScaleFactor): Removed.
(WebCore::RangeInputType::handleKeydownEvent): Changed to use StepRange class.
(WebCore::RangeInputType::fallbackValue): Changed to use StepRange class.
(WebCore::RangeInputType::sanitizeValue): Changed to use StepRange class.

  • html/RangeInputType.h:

(RangeInputType):

  • html/StepRange.cpp:

(WebCore::StepRange::StepRange): Added.
(WebCore::StepRange::clampValue): Changed for member variable name changes.
(WebCore::StepRange::hasStep): Added.
(WebCore::StepRange::maximum): Added.
(WebCore::StepRange::minimum): Added.
(WebCore::StepRange::step): Added.
(WebCore::StepRange::stepBase): Added.
(WebCore::StepRange::stepDecimalPlaces): Added.
(WebCore::StepRange::stepScaleFactor): Added.
(WebCore::StepRange::setHasStep): Added.
(WebCore::StepRange::setup): Added.
(WebCore::StepRange::parse): Added.

  • html/StepRange.h:

(StepDescription): Added
(WebCore::StepRange::StepDescription::StepDescription):
(WebCore::StepRange::acceptableError): Moved from InputType class.
(WebCore::StepRange::alignValueForStep): Moved from InputType class.
(WebCore::StepRange::defaultValue): Changed for member variable name changes.
(WebCore::StepRange::proportionFromValue): Changed for member variable name changes.
(WebCore::StepRange::valueFromProportion): Changed for member variable name changes.

  • html/TimeInputType.cpp:

(WebCore::TimeInputType::defaultStep): Removed.
(WebCore::TimeInputType::maximum): Removed.
(WebCore::TimeInputType::minimum): Removed.
(WebCore::TimeInputType::setupStepRange): Added.
(WebCore::TimeInputType::stepScaleFactor): Removed.

  • html/TimeInputType.h:

(TimeInputType):

  • html/WeekInputType.cpp:

(WebCore):
(WebCore::WeekInputType::defaultStep): Removed.
(WebCore::WeekInputType::maximum): Removed.
(WebCore::WeekInputType::minimum): Removed.
(WebCore::WeekInputType::setupStepRange): Added.
(WebCore::WeekInputType::stepScaleFactor): Removed.

  • html/WeekInputType.h:

(WeekInputType):

  • html/shadow/SliderThumbElement.cpp:

(WebCore::sliderPosition): Changed to use StepRange class.
(WebCore::SliderThumbElement::setPositionFromPoint): Changed to use StepRange class.

Location:
trunk/Source/WebCore
Files:
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r117736 r117738  
     12012-05-21  Yoshifumi Inoue  <yosin@chromium.org>
     2
     3        [Forms] Move numeric related methods in HTMLInputElement class to another place
     4        https://bugs.webkit.org/show_bug.cgi?id=82034
     5
     6        Reviewed by Kent Tamura.
     7
     8        This patch moves step and range related methods into StepRange class
     9        for ease of using step calculation other than double floating point
     10        number arithmetic, e.g. decimal, long double, and so on.
     11
     12        New class StepRange::StepDescription holds values for calculating
     13        stepped value, defaultStep, defaultStepBase, integer rounding flags,
     14        step scale factor instead of virtual methods in InputType class.
     15
     16        No new tests because of this patch doesn't change behavior.
     17
     18        * WebCore.xcodeproj/project.pbxproj: Set attribute of StepRange.h to "Private" for including it in HTMLInputElement.cpp.
     19        * html/BaseDateAndTimeInputType.cpp:
     20        (WebCore::InputType::rangeOverflow): Moved to use InputType class.
     21        (WebCore::InputType::rangeUnderflow): Moved to use InputType class.
     22        (WebCore::BaseDateAndTimeInputType::stepMismatch): Moved to use stepRange.
     23        * html/BaseDateAndTimeInputType.h:
     24        (BaseDateAndTimeInputType): Removed method declaration for stepBase.
     25        * html/DateInputType.cpp:
     26        (WebCore::DateInputType::setupStepRange): Added.
     27        * html/DateInputType.h:
     28        (DateInputType): Removed method declarations.
     29        * html/DateTimeInputType.cpp:
     30        (WebCore::DateTimeInputType::defaultStep): Removed.
     31        (WebCore::DateTimeInputType::maximum): Removed.
     32        (WebCore::DateTimeInputType::minimum): Removed.
     33        (WebCore::DateTimeInputType::setupStepRange): Added
     34        (WebCore::DateTimeInputType::stepScaleFactor): Removed.
     35        * html/DateTimeInputType.h:
     36        (DateTimeInputType): Removed deprecated method declarations.
     37        * html/DateTimeLocalInputType.cpp:
     38        (WebCore::DateTimeLocalInputType::defaultStep): Removed.
     39        (WebCore::DateTimeLocalInputType::maximum): Removed.
     40        (WebCore::DateTimeLocalInputType::minimum): Removed.
     41        (WebCore::DateTimeLocalInputType::setupStepRange): Added.
     42        (WebCore::DateTimeLocalInputType::stepScaleFactor): Removed.
     43        * html/DateTimeLocalInputType.h:
     44        (DateTimeLocalInputType):
     45        * html/HTMLInputElement.cpp:
     46        (WebCore::HTMLInputElement::isInRange): Changed to call InputType::isInRange.
     47        (WebCore::HTMLInputElement::isOutOfRange): Changed to call InputType::isOutOfRange.
     48        (WebCore::HTMLInputElement::setupStepRange): Added.
     49        * html/HTMLInputElement.h:
     50        (HTMLInputElement):
     51        * html/InputType.cpp:
     52        (WebCore::InputType::acceptableError): Moved to StepRange class.
     53        (WebCore::InputType::alignValueForStep): Moved to StepRange class.
     54        (WebCore::InputType::minimum): Changed to use StepRange class.
     55        (WebCore::InputType::maximum): Changed to use StepRange class.
     56        (WebCore::InputType::parseToDouble): Changed to have ASSERT_NOT_REACHED.
     57        (WebCore::InputType::stepBaseWithDecimalPlaces): Changed to use StepRange class.
     58        (WebCore::InputType::validationMessage):  Changed to use StepRange class.
     59        (WebCore::InputType::applyStep):  Changed to use StepRange class.
     60        (WebCore::InputType::getAllowedValueStep):  Changed to use StepRange class.
     61        (WebCore::InputType::isInRange): Added.
     62        (WebCore::InputType::isOutOfRange): Added.
     63        (WebCore::InputType::rangeOverflow): Changed to use StepRange class.
     64        (WebCore::InputType::rangeUnderflow): Changed to use StepRange class.
     65        (WebCore::InputType::setupStepRange): Added.
     66        (WebCore::InputType::stepUpFromRenderer):  Changed to use StepRange class.
     67        (WebCore::InputType::stepMismatch): Changed to use StepRange class.
     68        * html/InputType.h:
     69        (InputType):
     70        * html/MonthInputType.cpp:
     71        (WebCore::MonthInputType::defaultStep): Removed.
     72        (WebCore::MonthInputType::maximum): Removed.
     73        (WebCore::MonthInputType::minimum): Removed.
     74        (WebCore::MonthInputType::setupStepRange): Added.
     75        (WebCore::MonthInputType::stepScaleFactor): Removed.
     76        * html/MonthInputType.h:
     77        (MonthInputType):
     78        * html/NumberInputType.cpp:
     79        (WebCore):
     80        (WebCore::NumberInputType::defaultStep): Removed.
     81        (WebCore::NumberInputType::maximum): Removed.
     82        (WebCore::NumberInputType::minimum): Removed.
     83        (WebCore::NumberInputType::rangeOverflow): Moved to InputType class.
     84        (WebCore::NumberInputType::rangeUnderflow): Moved to InputType class.
     85        (WebCore::NumberInputType::setupStepRange): Added.
     86        (WebCore::NumberInputType::stepMismatch): Moved to InputType class.
     87        (WebCore::NumberInputType::stepBaseWithDecimalPlaces): Changed to use StepRange class.
     88        (WebCore::NumberInputType::stepScaleFactor): Removed.
     89        * html/NumberInputType.h:
     90        (NumberInputType):
     91        * html/RangeInputType.cpp:
     92        (WebCore::RangeInputType::defaultStep): Removed.
     93        (WebCore::RangeInputType::maximum): Removed.
     94        (WebCore::RangeInputType::minimum): Removed.
     95        (WebCore::RangeInputType::setupStepRange): Added.
     96        (WebCore::RangeInputType::stepScaleFactor): Removed.
     97        (WebCore::RangeInputType::handleKeydownEvent): Changed to use StepRange class.
     98        (WebCore::RangeInputType::fallbackValue): Changed to use StepRange class.
     99        (WebCore::RangeInputType::sanitizeValue): Changed to use StepRange class.
     100        * html/RangeInputType.h:
     101        (RangeInputType):
     102        * html/StepRange.cpp:
     103        (WebCore::StepRange::StepRange): Added.
     104        (WebCore::StepRange::clampValue): Changed for member variable name changes.
     105        (WebCore::StepRange::hasStep): Added.
     106        (WebCore::StepRange::maximum): Added.
     107        (WebCore::StepRange::minimum): Added.
     108        (WebCore::StepRange::step): Added.
     109        (WebCore::StepRange::stepBase): Added.
     110        (WebCore::StepRange::stepDecimalPlaces): Added.
     111        (WebCore::StepRange::stepScaleFactor): Added.
     112        (WebCore::StepRange::setHasStep): Added.
     113        (WebCore::StepRange::setup): Added.
     114        (WebCore::StepRange::parse): Added.
     115        * html/StepRange.h:
     116        (StepDescription): Added
     117        (WebCore::StepRange::StepDescription::StepDescription):
     118        (WebCore::StepRange::acceptableError): Moved from InputType class.
     119        (WebCore::StepRange::alignValueForStep): Moved from InputType class.
     120        (WebCore::StepRange::defaultValue): Changed for member variable name changes.
     121        (WebCore::StepRange::proportionFromValue): Changed for member variable name changes.
     122        (WebCore::StepRange::valueFromProportion): Changed for member variable name changes.
     123        * html/TimeInputType.cpp:
     124        (WebCore::TimeInputType::defaultStep): Removed.
     125        (WebCore::TimeInputType::maximum): Removed.
     126        (WebCore::TimeInputType::minimum): Removed.
     127        (WebCore::TimeInputType::setupStepRange): Added.
     128        (WebCore::TimeInputType::stepScaleFactor): Removed.
     129        * html/TimeInputType.h:
     130        (TimeInputType):
     131        * html/WeekInputType.cpp:
     132        (WebCore):
     133        (WebCore::WeekInputType::defaultStep): Removed.
     134        (WebCore::WeekInputType::maximum): Removed.
     135        (WebCore::WeekInputType::minimum): Removed.
     136        (WebCore::WeekInputType::setupStepRange): Added.
     137        (WebCore::WeekInputType::stepScaleFactor): Removed.
     138        * html/WeekInputType.h:
     139        (WeekInputType):
     140        * html/shadow/SliderThumbElement.cpp:
     141        (WebCore::sliderPosition): Changed to use StepRange class.
     142        (WebCore::SliderThumbElement::setPositionFromPoint): Changed to use StepRange class.
     143
    11442012-05-21  Kentaro Hara  <haraken@chromium.org>
    2145
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r117607 r117738  
    37143714                A5ABB78713B904BC00F197E3 /* LineBreakIteratorPoolICU.h in Headers */ = {isa = PBXBuildFile; fileRef = A5ABB78613B904BC00F197E3 /* LineBreakIteratorPoolICU.h */; };
    37153715                A5AFB34F115151A700B045CB /* StepRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5AFB34D115151A700B045CB /* StepRange.cpp */; };
    3716                 A5AFB350115151A700B045CB /* StepRange.h in Headers */ = {isa = PBXBuildFile; fileRef = A5AFB34E115151A700B045CB /* StepRange.h */; };
     3716                A5AFB350115151A700B045CB /* StepRange.h in Headers */ = {isa = PBXBuildFile; fileRef = A5AFB34E115151A700B045CB /* StepRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
    37173717                A5D214B112E905510090F370 /* HTTPRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5D214AE12E905510090F370 /* HTTPRequest.cpp */; };
    37183718                A5D214B212E905510090F370 /* HTTPRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = A5D214AF12E905510090F370 /* HTTPRequest.h */; };
  • trunk/Source/WebCore/html/BaseDateAndTimeInputType.cpp

    r115155 r117738  
    8181}
    8282
    83 bool BaseDateAndTimeInputType::rangeUnderflow(const String& value) const
    84 {
    85     const double nan = numeric_limits<double>::quiet_NaN();
    86     double doubleValue = parseToDouble(value, nan);
    87     return isfinite(doubleValue) && doubleValue < minimum();
    88 }
    89 
    90 bool BaseDateAndTimeInputType::rangeOverflow(const String& value) const
    91 {
    92     const double nan = numeric_limits<double>::quiet_NaN();
    93     double doubleValue = parseToDouble(value, nan);
    94     return isfinite(doubleValue) && doubleValue > maximum();
    95 }
    96 
    97 bool BaseDateAndTimeInputType::supportsRangeLimitation() const
    98 {
    99     return true;
    100 }
    101 
    10283double BaseDateAndTimeInputType::defaultValueForStepUp() const
    10384{
     
    11293{
    11394    return true;
    114 }
    115 
    116 bool BaseDateAndTimeInputType::stepMismatch(const String& value, double step) const
    117 {
    118     const double nan = numeric_limits<double>::quiet_NaN();
    119     double doubleValue = parseToDouble(value, nan);
    120     doubleValue = fabs(doubleValue - stepBase());
    121     if (!isfinite(doubleValue))
    122         return false;
    123     ASSERT(round(doubleValue) == doubleValue);
    124     ASSERT(round(step) == step);
    125     return fmod(doubleValue, step);
    126 }
    127 
    128 double BaseDateAndTimeInputType::stepBase() const
    129 {
    130     return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase());
    13195}
    13296
  • trunk/Source/WebCore/html/BaseDateAndTimeInputType.h

    r115155 r117738  
    5757    virtual bool typeMismatchFor(const String&) const OVERRIDE;
    5858    virtual bool typeMismatch() const OVERRIDE;
    59     virtual bool rangeUnderflow(const String&) const OVERRIDE;
    60     virtual bool rangeOverflow(const String&) const OVERRIDE;
    61     virtual bool supportsRangeLimitation() const OVERRIDE;
    6259    virtual double defaultValueForStepUp() const OVERRIDE;
    6360    virtual bool isSteppable() const OVERRIDE;
    64     virtual bool stepMismatch(const String&, double) const OVERRIDE;
    65     virtual double stepBase() const OVERRIDE;
    6661    virtual void handleWheelEvent(WheelEvent*) OVERRIDE;
    6762    virtual String serialize(double) const OVERRIDE;
  • trunk/Source/WebCore/html/DateInputType.cpp

    r116499 r117738  
    4747
    4848static const double dateDefaultStep = 1.0;
     49static const double dateDefaultStepBase = 0.0;
    4950static const double dateStepScaleFactor = 86400000.0;
    5051
     
    6970}
    7071
    71 double DateInputType::minimum() const
     72StepRange DateInputType::createStepRange(AnyStepHandling anyStepHandling) const
    7273{
    73     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDate());
    74 }
     74    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateDefaultStep, dateDefaultStepBase, dateStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
    7575
    76 double DateInputType::maximum() const
    77 {
    78     return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDate());
    79 }
    80 
    81 double DateInputType::defaultStep() const
    82 {
    83     return dateDefaultStep;
    84 }
    85 
    86 double DateInputType::stepScaleFactor() const
    87 {
    88     return dateStepScaleFactor;
    89 }
    90 
    91 bool DateInputType::parsedStepValueShouldBeInteger() const
    92 {
    93     return true;
     76    double stepBase = parseToDouble(element()->fastGetAttribute(minAttr), 0);
     77    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDate());
     78    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDate());
     79    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     80    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    9481}
    9582
  • trunk/Source/WebCore/html/DateInputType.h

    r116499 r117738  
    4949    virtual const AtomicString& formControlType() const OVERRIDE;
    5050    virtual DateComponents::Type dateType() const OVERRIDE;
    51     virtual double minimum() const OVERRIDE;
    52     virtual double maximum() const OVERRIDE;
    53     virtual double defaultStep() const OVERRIDE;
    54     virtual double stepScaleFactor() const OVERRIDE;
    55     virtual bool parsedStepValueShouldBeInteger() const OVERRIDE;
     51    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    5652    virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const OVERRIDE;
    5753    virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
  • trunk/Source/WebCore/html/DateTimeInputType.cpp

    r116499 r117738  
    4545
    4646static const double dateTimeDefaultStep = 60.0;
     47static const double dateTimeDefaultStepBase = 0.0;
    4748static const double dateTimeStepScaleFactor = 1000.0;
    4849
     
    6768}
    6869
    69 double DateTimeInputType::minimum() const
     70StepRange DateTimeInputType::createStepRange(AnyStepHandling anyStepHandling) const
    7071{
    71     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
    72 }
     72    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeDefaultStep, dateTimeDefaultStepBase, dateTimeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
    7373
    74 double DateTimeInputType::maximum() const
    75 {
    76     return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDateTime());
    77 }
    78 
    79 double DateTimeInputType::defaultStep() const
    80 {
    81     return dateTimeDefaultStep;
    82 }
    83 
    84 double DateTimeInputType::stepScaleFactor() const
    85 {
    86     return dateTimeStepScaleFactor;
    87 }
    88 
    89 bool DateTimeInputType::scaledStepValueShouldBeInteger() const
    90 {
    91     return true;
     74    double stepBase = parseToDouble(element()->fastGetAttribute(minAttr), 0);
     75    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
     76    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDateTime());
     77    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     78    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    9279}
    9380
  • trunk/Source/WebCore/html/DateTimeInputType.h

    r116499 r117738  
    4646    virtual const AtomicString& formControlType() const OVERRIDE;
    4747    virtual DateComponents::Type dateType() const OVERRIDE;
     48    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    4849    virtual double defaultValueForStepUp() const OVERRIDE;
    49     virtual double minimum() const OVERRIDE;
    50     virtual double maximum() const OVERRIDE;
    51     virtual double defaultStep() const OVERRIDE;
    52     virtual double stepScaleFactor() const OVERRIDE;
    53     virtual bool scaledStepValueShouldBeInteger() const OVERRIDE;
    5450    virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const OVERRIDE;
    5551    virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
  • trunk/Source/WebCore/html/DateTimeLocalInputType.cpp

    r116499 r117738  
    4444
    4545static const double dateTimeLocalDefaultStep = 60.0;
     46static const double dateTimeLocalDefaultStepBase = 0.0;
    4647static const double dateTimeLocalStepScaleFactor = 1000.0;
    4748
     
    7374}
    7475
    75 double DateTimeLocalInputType::minimum() const
     76StepRange DateTimeLocalInputType::createStepRange(AnyStepHandling anyStepHandling) const
    7677{
    77     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
    78 }
     78    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeLocalDefaultStep, dateTimeLocalDefaultStepBase, dateTimeLocalStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
    7979
    80 double DateTimeLocalInputType::maximum() const
    81 {
    82     return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDateTime());
    83 }
    84 
    85 double DateTimeLocalInputType::defaultStep() const
    86 {
    87     return dateTimeLocalDefaultStep;
    88 }
    89 
    90 double DateTimeLocalInputType::stepScaleFactor() const
    91 {
    92     return dateTimeLocalStepScaleFactor;
    93 }
    94 
    95 bool DateTimeLocalInputType::scaledStepValueShouldBeInteger() const
    96 {
    97     return true;
     80    double stepBase = parseToDouble(element()->fastGetAttribute(minAttr), 0);
     81    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
     82    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumDateTime());
     83    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     84    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    9885}
    9986
  • trunk/Source/WebCore/html/DateTimeLocalInputType.h

    r116499 r117738  
    4848    virtual double valueAsDate() const OVERRIDE;
    4949    virtual void setValueAsDate(double, ExceptionCode&) const OVERRIDE;
    50     virtual double minimum() const OVERRIDE;
    51     virtual double maximum() const OVERRIDE;
    52     virtual double defaultStep() const OVERRIDE;
    53     virtual double stepScaleFactor() const OVERRIDE;
    54     virtual bool scaledStepValueShouldBeInteger() const OVERRIDE;
     50    virtual StepRange createStepRange(AnyStepHandling) const;
    5551    virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const OVERRIDE;
    5652    virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r117323 r117738  
    277277{
    278278    return m_inputType->getAllowedValueStep(step);
     279}
     280
     281StepRange HTMLInputElement::createStepRange(AnyStepHandling anyStepHandling) const
     282{
     283    return m_inputType->createStepRange(anyStepHandling);
    279284}
    280285
     
    12691274bool HTMLInputElement::isInRange() const
    12701275{
    1271     return m_inputType->supportsRangeLimitation() && !m_inputType->rangeUnderflow(value()) && !m_inputType->rangeOverflow(value());
     1276    return m_inputType->isInRange(value());
    12721277}
    12731278
    12741279bool HTMLInputElement::isOutOfRange() const
    12751280{
    1276     return m_inputType->supportsRangeLimitation() && (m_inputType->rangeUnderflow(value()) || m_inputType->rangeOverflow(value()));
     1281    return m_inputType->isOutOfRange(value());
    12771282}
    12781283
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r117323 r117738  
    2727
    2828#include "HTMLTextFormControlElement.h"
     29#include "StepRange.h"
    2930
    3031namespace WebCore {
     
    6667    // Returns false if there is no "allowed value step."
    6768    bool getAllowedValueStep(double*) const;
     69    StepRange createStepRange(AnyStepHandling) const;
    6870
    6971    // Implementations of HTMLInputElement::stepUp() and stepDown().
  • trunk/Source/WebCore/html/InputType.cpp

    r116915 r117738  
    246246}
    247247
    248 bool InputType::rangeUnderflow(const String&) const
    249 {
    250     return false;
    251 }
    252 
    253 bool InputType::rangeOverflow(const String&) const
    254 {
    255     return false;
    256 }
    257 
    258 bool InputType::supportsRangeLimitation() const
    259 {
    260     return false;
     248bool InputType::rangeUnderflow(const String& value) const
     249{
     250    if (!isSteppable())
     251        return false;
     252
     253    double doubleValue = parseToDouble(value, numeric_limits<double>::quiet_NaN());
     254    if (isnan(doubleValue))
     255        return false;
     256
     257    return doubleValue < createStepRange(RejectAny).minimum();
     258}
     259
     260bool InputType::rangeOverflow(const String& value) const
     261{
     262    if (!isSteppable())
     263        return false;
     264
     265    double doubleValue = parseToDouble(value, numeric_limits<double>::quiet_NaN());
     266    if (isnan(doubleValue))
     267        return false;
     268
     269    return doubleValue > createStepRange(RejectAny).maximum();
    261270}
    262271
     
    268277double InputType::minimum() const
    269278{
    270     ASSERT_NOT_REACHED();
    271     return 0;
     279    return createStepRange(RejectAny).minimum();
    272280}
    273281
    274282double InputType::maximum() const
    275283{
    276     ASSERT_NOT_REACHED();
    277     return 0;
     284    return createStepRange(RejectAny).maximum();
    278285}
    279286
     
    284291}
    285292
     293bool InputType::isInRange(const String& value) const
     294{
     295    if (!isSteppable())
     296        return false;
     297
     298    double doubleValue = parseToDouble(value, numeric_limits<double>::quiet_NaN());
     299    if (isnan(doubleValue))
     300        return true;
     301
     302    StepRange stepRange(createStepRange(RejectAny));
     303    return doubleValue >= stepRange.minimum() && doubleValue <= stepRange.maximum();
     304}
     305
     306bool InputType::isOutOfRange(const String& value) const
     307{
     308    if (!isSteppable())
     309        return false;
     310
     311    double doubleValue = parseToDouble(value, numeric_limits<double>::quiet_NaN());
     312    if (isnan(doubleValue))
     313        return true;
     314
     315    StepRange stepRange(createStepRange(RejectAny));
     316    return doubleValue < stepRange.minimum() || doubleValue > stepRange.maximum();
     317}
     318
    286319bool InputType::stepMismatch(const String& value) const
    287320{
    288     double step;
    289     if (!getAllowedValueStep(&step))
     321    if (!isSteppable())
    290322        return false;
    291     return stepMismatch(value, step);
    292 }
    293 
    294 bool InputType::stepMismatch(const String&, double) const
    295 {
    296     // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
    297     ASSERT_NOT_REACHED();
    298     return false;
    299 }
    300 
    301 double InputType::stepBase() const
    302 {
    303     ASSERT_NOT_REACHED();
    304     return 0;
    305 }
    306 
    307 double InputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
    308 {
    309     if (decimalPlaces)
    310         *decimalPlaces = 0;
    311     return stepBase();
    312 }
    313 
    314 double InputType::defaultStep() const
    315 {
    316     return numeric_limits<double>::quiet_NaN();
    317 }
    318 
    319 double InputType::stepScaleFactor() const
    320 {
    321     return numeric_limits<double>::quiet_NaN();
    322 }
    323 
    324 bool InputType::parsedStepValueShouldBeInteger() const
    325 {
    326     return false;
    327 }
    328 
    329 bool InputType::scaledStepValueShouldBeInteger() const
    330 {
    331     return false;
    332 }
    333 
    334 double InputType::acceptableError(double) const
    335 {
    336     return 0;
     323
     324    double doubleValue = parseToDouble(value, numeric_limits<double>::quiet_NaN());
     325    if (isnan(doubleValue))
     326        return false;
     327
     328    return createStepRange(RejectAny).stepMismatch(doubleValue);
    337329}
    338330
     
    365357        return validationMessageTooLongText(numGraphemeClusters(value), element()->maxLength());
    366358
    367     if (rangeUnderflow(value))
    368         return validationMessageRangeUnderflowText(serialize(minimum()));
    369 
    370     if (rangeOverflow(value))
    371         return validationMessageRangeOverflowText(serialize(maximum()));
    372 
    373     if (stepMismatch(value)) {
    374         String stepString;
    375         double step;
    376         if (getAllowedValueStep(&step))
    377             stepString = serializeForNumberType(step / stepScaleFactor());
    378         return validationMessageStepMismatchText(serialize(stepBase()), stepString);
     359    if (!isSteppable())
     360        return emptyString();
     361
     362    double doubleValue = parseToDouble(value, numeric_limits<double>::quiet_NaN());
     363    if (isnan(doubleValue))
     364        return emptyString();
     365
     366    StepRange stepRange(createStepRange(RejectAny));
     367
     368    if (doubleValue < stepRange.minimum())
     369        return validationMessageRangeUnderflowText(serialize(stepRange.minimum()));
     370
     371    if (doubleValue < stepRange.maximum())
     372        return validationMessageRangeOverflowText(serialize(stepRange.maximum()));
     373
     374    if (stepRange.stepMismatch(doubleValue)) {
     375        const String stepString = stepRange.hasStep() ? serializeForNumberType(stepRange.step() / stepRange.stepScaleFactor()) : emptyString();
     376        return validationMessageStepMismatchText(serialize(stepRange.stepBase()), stepString);
    379377    }
    380378
    381     return String();
     379    return emptyString();
    382380}
    383381
     
    457455double InputType::parseToDouble(const String&, double defaultValue) const
    458456{
     457    ASSERT_NOT_REACHED();
    459458    return defaultValue;
    460459}
     
    862861void InputType::applyStep(double count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
    863862{
    864     double step;
    865     unsigned stepDecimalPlaces, currentDecimalPlaces;
    866     if (!getAllowedValueStepWithDecimalPlaces(anyStepHandling, &step, &stepDecimalPlaces)) {
     863    StepRange stepRange(createStepRange(anyStepHandling));
     864    if (!stepRange.hasStep()) {
    867865        ec = INVALID_STATE_ERR;
    868866        return;
     
    870868
    871869    const double nan = numeric_limits<double>::quiet_NaN();
     870    unsigned currentDecimalPlaces;
    872871    double current = parseToDoubleWithDecimalPlaces(element()->value(), nan, &currentDecimalPlaces);
    873872    if (!isfinite(current)) {
     
    875874        return;
    876875    }
    877     double newValue = current + step * count;
     876    double newValue = current + stepRange.step() * count;
    878877    if (isinf(newValue)) {
    879878        ec = INVALID_STATE_ERR;
     
    881880    }
    882881
    883     double acceptableErrorValue = acceptableError(step);
    884     if (newValue - minimum() < -acceptableErrorValue) {
     882    double acceptableErrorValue = stepRange.acceptableError();
     883    if (newValue - stepRange.minimum() < -acceptableErrorValue) {
    885884        ec = INVALID_STATE_ERR;
    886885        return;
    887886    }
    888     if (newValue < minimum())
    889         newValue = minimum();
     887    if (newValue < stepRange.minimum())
     888        newValue = stepRange.minimum();
    890889
    891890    const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
    892891    if (!equalIgnoringCase(stepString, "any"))
    893         newValue = alignValueForStep(newValue, step, currentDecimalPlaces, stepDecimalPlaces);
    894 
    895     if (newValue - maximum() > acceptableErrorValue) {
     892        newValue = stepRange.alignValueForStep(current, currentDecimalPlaces, newValue);
     893
     894    if (newValue - stepRange.maximum() > acceptableErrorValue) {
    896895        ec = INVALID_STATE_ERR;
    897896        return;
    898897    }
    899     if (newValue > maximum())
    900         newValue = maximum();
     898    if (newValue > stepRange.maximum())
     899        newValue = stepRange.maximum();
    901900
    902901    element()->setValueAsNumber(newValue, ec, eventBehavior);
     
    906905}
    907906
    908 double InputType::alignValueForStep(double newValue, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces)
    909 {
    910     if (newValue >= pow(10.0, 21.0))
    911         return newValue;
    912 
    913     unsigned baseDecimalPlaces;
    914     double base = stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    915     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
    916     if (stepMismatch(element()->value())) {
    917         double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
    918         newValue = round(newValue * scale) / scale;
    919     } else {
    920         double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
    921         newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
     907bool InputType::getAllowedValueStep(double* step) const
     908{
     909    StepRange stepRange(createStepRange(RejectAny));
     910    *step = stepRange.step();
     911    return stepRange.hasStep();
     912}
     913
     914StepRange InputType::createStepRange(AnyStepHandling) const
     915{
     916    ASSERT_NOT_REACHED();
     917    return StepRange();
     918}
     919
     920void InputType::stepUp(int n, ExceptionCode& ec)
     921{
     922    if (!isSteppable()) {
     923        ec = INVALID_STATE_ERR;
     924        return;
    922925    }
    923 
    924     return newValue;
    925 }
    926 
    927 bool InputType::getAllowedValueStep(double* step) const
    928 {
    929     return getAllowedValueStepWithDecimalPlaces(RejectAny, step, 0);
    930 }
    931 
    932 bool InputType::getAllowedValueStepWithDecimalPlaces(AnyStepHandling anyStepHandling, double* step, unsigned* decimalPlaces) const
    933 {
    934     ASSERT(step);
    935     double defaultStepValue = defaultStep();
    936     double stepScaleFactorValue = stepScaleFactor();
    937     if (!isfinite(defaultStepValue) || !isfinite(stepScaleFactorValue))
    938         return false;
    939     const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
    940     if (stepString.isEmpty()) {
    941         *step = defaultStepValue * stepScaleFactorValue;
    942         if (decimalPlaces)
    943             *decimalPlaces = 0;
    944         return true;
    945     }
    946 
    947     if (equalIgnoringCase(stepString, "any")) {
    948         switch (anyStepHandling) {
    949         case RejectAny:
    950             return false;
    951         case AnyIsDefaultStep:
    952             *step = defaultStepValue * stepScaleFactorValue;
    953             if (decimalPlaces)
    954                 *decimalPlaces = 0;
    955             return true;
    956         default:
    957             ASSERT_NOT_REACHED();
    958         }
    959     }
    960 
    961     double parsed;
    962     if (!decimalPlaces) {
    963         if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
    964             *step = defaultStepValue * stepScaleFactorValue;
    965             return true;
    966         }
    967     } else {
    968         if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
    969             *step = defaultStepValue * stepScaleFactorValue;
    970             *decimalPlaces = 0;
    971             return true;
    972         }
    973     }
    974     // For date, month, week, the parsed value should be an integer for some types.
    975     if (parsedStepValueShouldBeInteger())
    976         parsed = max(round(parsed), 1.0);
    977     double result = parsed * stepScaleFactorValue;
    978     // For datetime, datetime-local, time, the result should be an integer.
    979     if (scaledStepValueShouldBeInteger())
    980         result = max(round(result), 1.0);
    981     ASSERT(result > 0);
    982     *step = result;
    983     return true;
    984 }
    985 
    986 void InputType::stepUp(int n, ExceptionCode& ec)
    987 {
    988926    applyStep(n, RejectAny, DispatchNoEvent, ec);
    989927}
     
    1033971        return;
    1034972
    1035     unsigned stepDecimalPlaces, baseDecimalPlaces;
    1036     double step, base;
     973    StepRange stepRange(createStepRange(AnyIsDefaultStep));
     974
    1037975    // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
    1038976    // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
    1039     if (!getAllowedValueStepWithDecimalPlaces(AnyIsDefaultStep, &step, &stepDecimalPlaces))
     977    if (!stepRange.hasStep())
    1040978      return;
    1041     base = stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    1042     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
     979
     980    double step = stepRange.step();
    1043981
    1044982    int sign;
     
    1057995        current = defaultValueForStepUp();
    1058996        double nextDiff = step * n;
    1059         if (current < minimum() - nextDiff)
    1060             current = minimum() - nextDiff;
    1061         if (current > maximum() - nextDiff)
    1062             current = maximum() - nextDiff;
     997        if (current < stepRange.minimum() - nextDiff)
     998            current = stepRange.minimum() - nextDiff;
     999        if (current > stepRange.maximum() - nextDiff)
     1000            current = stepRange.maximum() - nextDiff;
    10631001        element()->setValueAsNumber(current, ec, DispatchInputAndChangeEvent);
    10641002    }
    1065     if ((sign > 0 && current < minimum()) || (sign < 0 && current > maximum()))
    1066         element()->setValue(serialize(sign > 0 ? minimum() : maximum()), DispatchInputAndChangeEvent);
     1003    if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum()))
     1004        element()->setValue(serialize(sign > 0 ? stepRange.minimum() : stepRange.maximum()), DispatchInputAndChangeEvent);
    10671005    else {
    10681006        ExceptionCode ec;
     
    10701008            ASSERT(step);
    10711009            double newValue;
    1072             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
     1010            double scale = pow(10.0, static_cast<double>(max(stepRange.stepDecimalPlaces(), stepRange.stepBaseDecimalPlaces())));
     1011            double base = stepRange.stepBase();
    10731012
    10741013            if (sign < 0)
     
    10791018                newValue = current;
    10801019
    1081             if (newValue < minimum())
    1082                 newValue = minimum();
    1083             if (newValue > maximum())
    1084                 newValue = maximum();
     1020            if (newValue < stepRange.minimum())
     1021                newValue = stepRange.minimum();
     1022            if (newValue > stepRange.maximum())
     1023                newValue = stepRange.maximum();
    10851024
    10861025            element()->setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
  • trunk/Source/WebCore/html/InputType.h

    r116915 r117738  
    3535
    3636#include "HTMLTextFormControlElement.h"
     37#include "StepRange.h"
    3738#include <wtf/Forward.h>
    3839#include <wtf/FastAllocBase.h>
     
    151152    virtual bool valueMissing(const String&) const;
    152153    virtual bool patternMismatch(const String&) const;
    153     virtual bool rangeUnderflow(const String&) const;
    154     virtual bool rangeOverflow(const String&) const;
    155     virtual bool supportsRangeLimitation() const;
     154    bool rangeUnderflow(const String&) const;
     155    bool rangeOverflow(const String&) const;
     156    bool isInRange(const String&) const;
     157    bool isOutOfRange(const String&) const;
    156158    virtual double defaultValueForStepUp() const;
    157     virtual double minimum() const;
    158     virtual double maximum() const;
     159    double minimum() const;
     160    double maximum() const;
    159161    virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
    160162    bool stepMismatch(const String&) const;
    161     virtual bool stepMismatch(const String&, double step) const;
    162     virtual double stepBase() const;
    163     virtual double stepBaseWithDecimalPlaces(unsigned*) const;
    164163    virtual bool getAllowedValueStep(double*) const;
     164    virtual StepRange createStepRange(AnyStepHandling) const;
    165165    virtual void stepUp(int, ExceptionCode&);
    166166    virtual void stepUpFromRenderer(int);
    167     virtual double defaultStep() const;
    168     virtual double stepScaleFactor() const;
    169     virtual bool parsedStepValueShouldBeInteger() const;
    170     virtual bool scaledStepValueShouldBeInteger() const;
    171     virtual double acceptableError(double) const;
    172167    virtual String typeMismatchText() const;
    173168    virtual String valueMissingText() const;
     
    296291    HTMLInputElement* element() const { return m_element; }
    297292    void dispatchSimulatedClickIfActive(KeyboardEvent*) const;
    298     // We can't make this a static const data member because VC++ doesn't like it.
    299     static double defaultStepBase() { return 0.0; }
    300293    Chrome* chrome() const;
    301294
    302295private:
    303     enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
    304 
    305296    // Helper for stepUp()/stepDown(). Adds step value * count to the current value.
    306297    void applyStep(double count, AnyStepHandling, TextFieldEventBehavior, ExceptionCode&);
    307     double alignValueForStep(double value, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces);
    308     bool getAllowedValueStepWithDecimalPlaces(AnyStepHandling, double*, unsigned*) const;
    309298
    310299    // Raw pointer because the HTMLInputElement object owns this InputType object.
  • trunk/Source/WebCore/html/MonthInputType.cpp

    r116499 r117738  
    4747
    4848static const double monthDefaultStep = 1.0;
     49static const double monthDefaultStepBase = 0.0;
    4950static const double monthStepScaleFactor = 1.0;
    5051
     
    9798}
    9899
    99 double MonthInputType::minimum() const
     100StepRange MonthInputType::createStepRange(AnyStepHandling anyStepHandling) const
    100101{
    101     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth());
    102 }
     102    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (monthDefaultStep, monthDefaultStepBase, monthStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
    103103
    104 double MonthInputType::maximum() const
    105 {
    106     return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumMonth());
    107 }
    108 
    109 double MonthInputType::defaultStep() const
    110 {
    111     return monthDefaultStep;
    112 }
    113 
    114 double MonthInputType::stepScaleFactor() const
    115 {
    116     return monthStepScaleFactor;
    117 }
    118 
    119 bool MonthInputType::parsedStepValueShouldBeInteger() const
    120 {
    121     return true;
     104    double stepBase = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth());
     105    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth());
     106    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumMonth());
     107    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     108    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    122109}
    123110
  • trunk/Source/WebCore/html/MonthInputType.h

    r116499 r117738  
    5050    virtual double parseToDouble(const String&, double) const OVERRIDE;
    5151    virtual double defaultValueForStepUp() const OVERRIDE;
    52     virtual double minimum() const OVERRIDE;
    53     virtual double maximum() const OVERRIDE;
    54     virtual double defaultStep() const OVERRIDE;
    55     virtual double stepScaleFactor() const OVERRIDE;
    56     virtual bool parsedStepValueShouldBeInteger() const OVERRIDE;
     52    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    5753    virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const OVERRIDE;
    5854    virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
  • trunk/Source/WebCore/html/NumberInputType.cpp

    r107555 r117738  
    5252
    5353static const double numberDefaultStep = 1.0;
     54static const double numberDefaultStepBase = 0.0;
    5455static const double numberStepScaleFactor = 1.0;
    5556
     
    108109}
    109110
    110 bool NumberInputType::rangeUnderflow(const String& value) const
    111 {
    112     const double nan = numeric_limits<double>::quiet_NaN();
    113     double doubleValue = parseToDouble(value, nan);
    114     return isfinite(doubleValue) && doubleValue < minimum();
    115 }
    116 
    117 bool NumberInputType::rangeOverflow(const String& value) const
    118 {
    119     const double nan = numeric_limits<double>::quiet_NaN();
    120     double doubleValue = parseToDouble(value, nan);
    121     return isfinite(doubleValue) && doubleValue > maximum();
    122 }
    123 
    124 bool NumberInputType::supportsRangeLimitation() const
    125 {
    126     return true;
    127 }
    128 
    129 double NumberInputType::minimum() const
    130 {
    131     return parseToDouble(element()->fastGetAttribute(minAttr), -numeric_limits<float>::max());
    132 }
    133 
    134 double NumberInputType::maximum() const
    135 {
    136     return parseToDouble(element()->fastGetAttribute(maxAttr), numeric_limits<float>::max());
     111StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) const
     112{
     113    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor));
     114
     115    unsigned stepBaseDecimalPlaces;
     116    double stepBaseValue = parseToDoubleWithDecimalPlaces(element()->fastGetAttribute(minAttr), numberDefaultStepBase, &stepBaseDecimalPlaces);
     117    StepRange::DoubleWithDecimalPlaces stepBase(stepBaseValue, min(stepBaseDecimalPlaces, 16u));
     118    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), -numeric_limits<float>::max());
     119    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), numeric_limits<float>::max());
     120
     121    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     122    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    137123}
    138124
     
    189175}
    190176
    191 bool NumberInputType::stepMismatch(const String& value, double step) const
    192 {
    193     double doubleValue;
    194     if (!parseToDoubleForNumberType(value, &doubleValue))
    195         return false;
    196     doubleValue = fabs(doubleValue - stepBase());
    197     if (isinf(doubleValue))
    198         return false;
    199     // double's fractional part size is DBL_MAN_DIG-bit. If the current value
    200     // is greater than step*2^DBL_MANT_DIG, the following computation for
    201     // remainder makes no sense.
    202     if (doubleValue / pow(2.0, DBL_MANT_DIG) > step)
    203         return false;
    204     // The computation follows HTML5 4.10.7.2.10 `The step attribute' :
    205     // ... that number subtracted from the step base is not an integral multiple
    206     // of the allowed value step, the element is suffering from a step mismatch.
    207     double remainder = fabs(doubleValue - step * round(doubleValue / step));
    208     // Accepts erros in lower fractional part which IEEE 754 single-precision
    209     // can't represent.
    210     double computedAcceptableError = acceptableError(step);
    211     return computedAcceptableError < remainder && remainder < (step - computedAcceptableError);
    212 }
    213 
    214 double NumberInputType::stepBase() const
    215 {
    216     return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase());
    217 }
    218 
    219 double NumberInputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
    220 {
    221     return parseToDoubleWithDecimalPlaces(element()->fastGetAttribute(minAttr), defaultStepBase(), decimalPlaces);
    222 }
    223 
    224 double NumberInputType::defaultStep() const
    225 {
    226     return numberDefaultStep;
    227 }
    228 
    229 double NumberInputType::stepScaleFactor() const
    230 {
    231     return numberStepScaleFactor;
    232 }
    233 
    234177void NumberInputType::handleKeydownEvent(KeyboardEvent* event)
    235178{
     
    267210        return String();
    268211    return serializeForNumberType(value);
    269 }
    270 
    271 double NumberInputType::acceptableError(double step) const
    272 {
    273     return step / pow(2.0, FLT_MANT_DIG);
    274212}
    275213
  • trunk/Source/WebCore/html/NumberInputType.h

    r107555 r117738  
    4747    virtual bool typeMismatchFor(const String&) const OVERRIDE;
    4848    virtual bool typeMismatch() const OVERRIDE;
    49     virtual bool rangeUnderflow(const String&) const OVERRIDE;
    50     virtual bool rangeOverflow(const String&) const OVERRIDE;
    51     virtual bool supportsRangeLimitation() const OVERRIDE;
    52     virtual double minimum() const OVERRIDE;
    53     virtual double maximum() const OVERRIDE;
    5449    virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const OVERRIDE;
    5550    virtual bool isSteppable() const OVERRIDE;
    56     virtual bool stepMismatch(const String&, double) const OVERRIDE;
    57     virtual double stepBase() const OVERRIDE;
    58     virtual double stepBaseWithDecimalPlaces(unsigned*) const OVERRIDE;
    59     virtual double defaultStep() const OVERRIDE;
    60     virtual double stepScaleFactor() const OVERRIDE;
     51    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    6152    virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE;
    6253    virtual void handleWheelEvent(WheelEvent*) OVERRIDE;
     
    6455    virtual double parseToDoubleWithDecimalPlaces(const String&, double, unsigned*) const OVERRIDE;
    6556    virtual String serialize(double) const OVERRIDE;
    66     virtual double acceptableError(double) const OVERRIDE;
    6757    virtual void handleBlurEvent() OVERRIDE;
    6858    virtual String visibleValue() const OVERRIDE;
  • trunk/Source/WebCore/html/RangeInputType.cpp

    r116730 r117738  
    5858static const double rangeDefaultMaximum = 100.0;
    5959static const double rangeDefaultStep = 1.0;
     60static const double rangeDefaultStepBase = 0.0;
    6061static const double rangeStepScaleFactor = 1.0;
    6162
     
    9091}
    9192
    92 bool RangeInputType::rangeUnderflow(const String& value) const
    93 {
    94     // Guaranteed by sanitization.
    95     ASSERT_UNUSED(value, parseToDouble(value, numeric_limits<double>::quiet_NaN()) >= minimum());
    96     return false;
    97 }
    98 
    99 bool RangeInputType::rangeOverflow(const String& value) const
    100 {
    101     // Guaranteed by sanitization.
    102     ASSERT_UNUSED(value, parseToDouble(value, numeric_limits<double>::quiet_NaN()) <= maximum());
    103     return false;
    104 }
    105 
    106 bool RangeInputType::supportsRangeLimitation() const
     93StepRange RangeInputType::createStepRange(AnyStepHandling anyStepHandling) const
     94{
     95    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor));
     96
     97    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), rangeDefaultMinimum);
     98    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), rangeDefaultMaximum);
     99    if (maximum < minimum)
     100        maximum = max(minimum, rangeDefaultMaximum);
     101
     102    const AtomicString& precisionValue = element()->fastGetAttribute(precisionAttr);
     103    if (!precisionValue.isNull()) {
     104        StepRange::DoubleWithDecimalPlacesOrMissing step(1, !equalIgnoringCase(precisionValue, "float"));
     105        return StepRange(minimum, minimum, maximum, step, stepDescription);
     106    }
     107
     108    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     109    return StepRange(minimum, minimum, maximum, step, stepDescription);
     110}
     111
     112bool RangeInputType::isSteppable() const
    107113{
    108114    return true;
    109 }
    110 
    111 double RangeInputType::minimum() const
    112 {
    113     return parseToDouble(element()->fastGetAttribute(minAttr), rangeDefaultMinimum);
    114 }
    115 
    116 double RangeInputType::maximum() const
    117 {
    118     double max = parseToDouble(element()->fastGetAttribute(maxAttr), rangeDefaultMaximum);
    119     // A remedy for the inconsistent min/max values.
    120     // Sets the maximum to the default or the minimum value.
    121     double min = minimum();
    122     if (max < min)
    123         max = std::max(min, rangeDefaultMaximum);
    124     return max;
    125 }
    126 
    127 bool RangeInputType::isSteppable() const
    128 {
    129     return true;
    130 }
    131 
    132 bool RangeInputType::stepMismatch(const String&, double) const
    133 {
    134     // stepMismatch doesn't occur for type=range. RenderSlider guarantees the
    135     // value matches to step on user input, and sanitization takes care
    136     // of the general case.
    137     return false;
    138 }
    139 
    140 double RangeInputType::stepBase() const
    141 {
    142     return minimum();
    143 }
    144 
    145 double RangeInputType::defaultStep() const
    146 {
    147     return rangeDefaultStep;
    148 }
    149 
    150 double RangeInputType::stepScaleFactor() const
    151 {
    152     return rangeStepScaleFactor;
    153115}
    154116
     
    179141    double current = parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
    180142    ASSERT(isfinite(current));
     143
     144    StepRange stepRange(createStepRange(RejectAny));
    181145
    182146    double step, bigStep;
     
    184148        // FIXME: We can't use stepUp() for the step value "any". So, we increase
    185149        // or decrease the value by 1/100 of the value range. Is it reasonable?
    186         step = (maximum() - minimum()) / 100;
     150        step = (stepRange.maximum() - stepRange.minimum()) / 100;
    187151        bigStep = step * 10;
    188152    } else {
     
    190154            ASSERT_NOT_REACHED();
    191155
    192         bigStep = (maximum() - minimum()) / 10;
     156        bigStep = (stepRange.maximum() - stepRange.minimum()) / 10;
    193157        if (bigStep < step)
    194158            bigStep = step;
     
    215179        newValue = current - bigStep;
    216180    else if (key == "Home")
    217         newValue = isVertical ? maximum() : minimum();
     181        newValue = isVertical ? stepRange.maximum() : stepRange.minimum();
    218182    else if (key == "End")
    219         newValue = isVertical ? minimum() : maximum();
     183        newValue = isVertical ? stepRange.minimum() : stepRange.maximum();
    220184    else
    221185        return; // Did not match any key binding.
    222186
    223     newValue = StepRange(element()).clampValue(newValue);
     187    newValue = stepRange.clampValue(newValue);
    224188
    225189    if (newValue != current) {
     
    304268String RangeInputType::fallbackValue() const
    305269{
    306     return serializeForNumberType(StepRange(element()).defaultValue());
     270    return serializeForNumberType(createStepRange(RejectAny).defaultValue());
    307271}
    308272
    309273String RangeInputType::sanitizeValue(const String& proposedValue) const
    310274{
    311     return serializeForNumberType(StepRange(element()).clampValue(proposedValue));
     275    StepRange stepRange(createStepRange(RejectAny));
     276    double proposedDoubleValue = parseToDouble(proposedValue, stepRange.defaultValue());
     277    return serializeForNumberType(stepRange.clampValue(proposedDoubleValue));
    312278}
    313279
  • trunk/Source/WebCore/html/RangeInputType.h

    r107555 r117738  
    4949    virtual void setValueAsNumber(double, TextFieldEventBehavior, ExceptionCode&) const OVERRIDE;
    5050    virtual bool supportsRequired() const OVERRIDE;
    51     virtual bool rangeUnderflow(const String&) const OVERRIDE;
    52     virtual bool rangeOverflow(const String&) const OVERRIDE;
    53     virtual bool supportsRangeLimitation() const OVERRIDE;
    54     virtual double minimum() const OVERRIDE;
    55     virtual double maximum() const OVERRIDE;
     51    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    5652    virtual bool isSteppable() const OVERRIDE;
    57     virtual bool stepMismatch(const String&, double) const OVERRIDE;
    58     virtual double stepBase() const OVERRIDE;
    59     virtual double defaultStep() const OVERRIDE;
    60     virtual double stepScaleFactor() const OVERRIDE;
    6153    virtual void handleMouseDownEvent(MouseEvent*) OVERRIDE;
    6254    virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE;
  • trunk/Source/WebCore/html/StepRange.cpp

    r115434 r117738  
    2222#include "StepRange.h"
    2323
    24 #include "HTMLInputElement.h"
    2524#include "HTMLNames.h"
    2625#include "HTMLParserIdioms.h"
     
    3433using namespace HTMLNames;
    3534
    36 StepRange::StepRange(const HTMLInputElement* element)
     35StepRange::StepRange()
     36    : m_maximum(100)
     37    , m_minimum(0)
     38    , m_step(1)
     39    , m_stepBase(0)
     40    , m_stepBaseDecimalPlaces(0)
     41    , m_stepDecimalPlaces(0)
     42    , m_hasStep(false)
    3743{
    38     step = 1;
    39     const AtomicString& precisionValue = element->fastGetAttribute(precisionAttr);
    40     if (!precisionValue.isNull())
    41         hasStep = !equalIgnoringCase(precisionValue, "float");
    42     else
    43         hasStep = element->getAllowedValueStep(&step);
    44 
    45     maximum = element->maximum();
    46     minimum = element->minimum();
     44    ASSERT_NOT_REACHED();
    4745}
    4846
    49 double StepRange::clampValue(double value)
     47StepRange::StepRange(const StepRange& stepRange)
     48    : m_maximum(stepRange.m_maximum)
     49    , m_minimum(stepRange.m_minimum)
     50    , m_step(stepRange.m_step)
     51    , m_stepBase(stepRange.m_stepBase)
     52    , m_stepDescription(stepRange.m_stepDescription)
     53    , m_stepBaseDecimalPlaces(stepRange.m_stepBaseDecimalPlaces)
     54    , m_stepDecimalPlaces(stepRange.m_stepDecimalPlaces)
     55    , m_hasStep(stepRange.m_hasStep)
    5056{
    51     double clampedValue = max(minimum, min(value, maximum));
    52     if (!hasStep)
     57}
     58
     59StepRange::StepRange(const DoubleWithDecimalPlaces& stepBase, double minimum, double maximum, const DoubleWithDecimalPlacesOrMissing& step, const StepDescription& stepDescription)
     60    : m_maximum(maximum)
     61    , m_minimum(minimum)
     62    , m_step(step.value.value)
     63    , m_stepBase(stepBase.value)
     64    , m_stepDescription(stepDescription)
     65    , m_stepBaseDecimalPlaces(stepBase.decimalPlaces)
     66    , m_stepDecimalPlaces(step.value.decimalPlaces)
     67    , m_hasStep(step.hasValue)
     68{
     69    ASSERT(isfinite(m_maximum));
     70    ASSERT(isfinite(m_minimum));
     71    ASSERT(isfinite(m_step));
     72    ASSERT(isfinite(m_stepBase));
     73}
     74
     75double StepRange::acceptableError() const
     76{
     77    return m_step / pow(2.0, FLT_MANT_DIG);
     78}
     79
     80double StepRange::alignValueForStep(double currentValue, unsigned currentDecimalPlaces, double newValue) const
     81{
     82    if (newValue >= pow(10.0, 21.0))
     83        return newValue;
     84
     85    if (stepMismatch(currentValue)) {
     86        double scale = pow(10.0, static_cast<double>(max(m_stepDecimalPlaces, currentDecimalPlaces)));
     87        newValue = round(newValue * scale) / scale;
     88    } else {
     89        double scale = pow(10.0, static_cast<double>(max(m_stepDecimalPlaces, m_stepBaseDecimalPlaces)));
     90        newValue = round((m_stepBase + round((newValue - m_stepBase) / m_step) * m_step) * scale) / scale;
     91    }
     92
     93    return newValue;
     94}
     95double StepRange::clampValue(double value) const
     96{
     97    double clampedValue = max(m_minimum, min(value, m_maximum));
     98    if (!m_hasStep)
    5399        return clampedValue;
    54100    // Rounds clampedValue to minimum + N * step.
    55     clampedValue = minimum + round((clampedValue - minimum) / step) * step;
    56     if (clampedValue > maximum)
    57        clampedValue -= step;
    58     ASSERT(clampedValue >= minimum);
    59     ASSERT(clampedValue <= maximum);
     101    clampedValue = m_minimum + round((clampedValue - m_minimum) / m_step) * m_step;
     102    if (clampedValue > m_maximum)
     103       clampedValue -= m_step;
     104    ASSERT(clampedValue >= m_minimum);
     105    ASSERT(clampedValue <= m_maximum);
    60106    return clampedValue;
    61107}
    62108
    63 double StepRange::clampValue(const String& stringValue)
     109StepRange::DoubleWithDecimalPlacesOrMissing StepRange::parseStep(AnyStepHandling anyStepHandling, const StepDescription& stepDescription, const String& stepString)
    64110{
    65     double value;
    66     bool parseSuccess = parseToDoubleForNumberType(stringValue, &value);
    67     if (!parseSuccess)
    68         value = (minimum + maximum) / 2;
    69     return clampValue(value);
     111    ASSERT(isfinite(stepDescription.defaultStep));
     112    ASSERT(isfinite(stepDescription.stepScaleFactor));
     113
     114    if (stepString.isEmpty())
     115        return DoubleWithDecimalPlacesOrMissing(stepDescription.defaultValue());
     116
     117    if (equalIgnoringCase(stepString, "any")) {
     118        switch (anyStepHandling) {
     119        case RejectAny:
     120            return DoubleWithDecimalPlacesOrMissing(DoubleWithDecimalPlaces(1), false);
     121        case AnyIsDefaultStep:
     122            return DoubleWithDecimalPlacesOrMissing(stepDescription.defaultValue());
     123        default:
     124            ASSERT_NOT_REACHED();
     125        }
     126    }
     127
     128    DoubleWithDecimalPlacesOrMissing step(0);
     129    if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &step.value.value, &step.value.decimalPlaces) || step.value.value <= 0.0)
     130        return DoubleWithDecimalPlacesOrMissing(stepDescription.defaultValue());
     131
     132    switch (stepDescription.stepValueShouldBe) {
     133    case StepValueShouldBeReal:
     134        step.value.value *= stepDescription.stepScaleFactor;
     135        break;
     136    case ParsedStepValueShouldBeInteger:
     137        // For date, month, and week, the parsed value should be an integer for some types.
     138        step.value.value = max(round(step.value.value), 1.0);
     139        step.value.value *= stepDescription.stepScaleFactor;
     140        break;
     141    case ScaledStepValueShouldBeInteger:
     142        // For datetime, datetime-local, time, the result should be an integer.
     143        step.value.value *= stepDescription.stepScaleFactor;
     144        step.value.value = max(round(step.value.value), 1.0);
     145        break;
     146    default:
     147        ASSERT_NOT_REACHED();
     148    }
     149
     150    ASSERT(step.value.value > 0);
     151    return step;
    70152}
    71153
    72 double StepRange::valueFromElement(HTMLInputElement* element, bool* wasClamped)
     154bool StepRange::stepMismatch(double doubleValue) const
    73155{
    74     double oldValue;
    75     bool parseSuccess = parseToDoubleForNumberType(element->value(), &oldValue);
    76     if (!parseSuccess)
    77         oldValue = (minimum + maximum) / 2;
    78     double newValue = clampValue(oldValue);
    79 
    80     if (wasClamped)
    81         *wasClamped = !parseSuccess || newValue != oldValue;
    82 
    83     return newValue;
     156    if (!m_hasStep)
     157        return false;
     158    if (!isfinite(doubleValue))
     159        return false;
     160    doubleValue = fabs(doubleValue - m_stepBase);
     161    if (isinf(doubleValue))
     162        return false;
     163    // double's fractional part size is DBL_MAN_DIG-bit. If the current value
     164    // is greater than step*2^DBL_MANT_DIG, the following computation for
     165    // remainder makes no sense.
     166    if (doubleValue / pow(2.0, DBL_MANT_DIG) > m_step)
     167        return false;
     168    // The computation follows HTML5 4.10.7.2.10 `The step attribute' :
     169    // ... that number subtracted from the step base is not an integral multiple
     170    // of the allowed value step, the element is suffering from a step mismatch.
     171    double remainder = fabs(doubleValue - m_step * round(doubleValue / m_step));
     172    // Accepts erros in lower fractional part which IEEE 754 single-precision
     173    // can't represent.
     174    double computedAcceptableError = acceptableError();
     175    return computedAcceptableError < remainder && remainder < (m_step - computedAcceptableError);
    84176}
    85177
    86 }
     178} // namespace WebCore
  • trunk/Source/WebCore/html/StepRange.h

    r95901 r117738  
    2929class HTMLInputElement;
    3030
     31enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
     32
    3133class StepRange {
    32     WTF_MAKE_NONCOPYABLE(StepRange);
    3334public:
    34     bool hasStep;
    35     double step;
    36     double minimum;
    37     double maximum; // maximum must be >= minimum.
     35    struct DoubleWithDecimalPlaces {
     36        unsigned decimalPlaces;
     37        double value;
    3838
    39     explicit StepRange(const HTMLInputElement*);
    40     double clampValue(double value);
    41     double clampValue(const String& stringValue);
     39        DoubleWithDecimalPlaces(double value = 0, unsigned decimalPlaces = 0)
     40            : decimalPlaces(decimalPlaces)
     41            , value(value)
     42        {
     43        }
     44    };
     45
     46    struct DoubleWithDecimalPlacesOrMissing {
     47        bool hasValue;
     48        DoubleWithDecimalPlaces value;
     49
     50        DoubleWithDecimalPlacesOrMissing(DoubleWithDecimalPlaces value, bool hasValue = true)
     51            : hasValue(hasValue)
     52            , value(value)
     53        {
     54        }
     55    };
     56
     57    enum StepValueShouldBe {
     58        StepValueShouldBeReal,
     59        ParsedStepValueShouldBeInteger,
     60        ScaledStepValueShouldBeInteger,
     61    };
     62
     63    struct StepDescription {
     64        int defaultStep;
     65        int defaultStepBase;
     66        int stepScaleFactor;
     67        StepValueShouldBe stepValueShouldBe;
     68
     69        StepDescription(int defaultStep, int defaultStepBase, int stepScaleFactor, StepValueShouldBe stepValueShouldBe = StepValueShouldBeReal)
     70            : defaultStep(defaultStep)
     71            , defaultStepBase(defaultStepBase)
     72            , stepScaleFactor(stepScaleFactor)
     73            , stepValueShouldBe(stepValueShouldBe)
     74        {
     75        }
     76
     77        StepDescription()
     78            : defaultStep(1)
     79            , defaultStepBase(0)
     80            , stepScaleFactor(1)
     81            , stepValueShouldBe(StepValueShouldBeReal)
     82        {
     83            ASSERT_NOT_REACHED();
     84        }
     85
     86        double defaultValue() const
     87        {
     88            return defaultStep * stepScaleFactor;
     89        }
     90    };
     91
     92    StepRange();
     93    StepRange(const StepRange&);
     94    StepRange(const DoubleWithDecimalPlaces& stepBase, double minimum, double maximum, const DoubleWithDecimalPlacesOrMissing& step, const StepDescription&);
     95    double acceptableError() const;
     96    double alignValueForStep(double currentValue, unsigned currentDecimalPlaces, double newValue) const;
     97    double clampValue(double value) const;
     98    bool hasStep() const { return m_hasStep; }
     99    double maximum() const { return m_maximum; }
     100    double minimum() const { return m_minimum; }
     101    static DoubleWithDecimalPlacesOrMissing parseStep(AnyStepHandling, const StepDescription&, const String&);
     102    double step() const { return m_step; }
     103    double stepBase() const { return m_stepBase; }
     104    unsigned stepBaseDecimalPlaces() const { return m_stepBaseDecimalPlaces; }
     105    unsigned stepDecimalPlaces() const { return m_stepDecimalPlaces; }
     106    int stepScaleFactor() const { return m_stepDescription.stepScaleFactor; }
     107    bool stepMismatch(double) const;
    42108
    43109    // Clamp the middle value according to the step
    44110    double defaultValue()
    45111    {
    46         return clampValue((minimum + maximum) / 2);
     112        return clampValue((m_minimum + m_maximum) / 2);
    47113    }
    48114
     
    50116    double proportionFromValue(double value)
    51117    {
    52         if (minimum == maximum)
     118        if (m_minimum == m_maximum)
    53119            return 0;
    54120
    55         return (value - minimum) / (maximum - minimum);
     121        return (value - m_minimum) / (m_maximum - m_minimum);
    56122    }
    57123
     
    59125    double valueFromProportion(double proportion)
    60126    {
    61         return minimum + proportion * (maximum - minimum);
     127        return m_minimum + proportion * (m_maximum - m_minimum);
    62128    }
    63129
    64     double valueFromElement(HTMLInputElement*, bool* wasClamped = 0);
     130private:
     131    StepRange& operator =(const StepRange&);
     132
     133    const double m_maximum; // maximum must be >= minimum.
     134    const double m_minimum;
     135    const double m_step;
     136    const double m_stepBase;
     137    const StepDescription m_stepDescription;
     138    const unsigned m_stepBaseDecimalPlaces;
     139    const unsigned m_stepDecimalPlaces;
     140    const bool m_hasStep;
    65141};
    66142
  • trunk/Source/WebCore/html/TimeInputType.cpp

    r116499 r117738  
    4747
    4848static const double timeDefaultStep = 60.0;
     49static const double timeDefaultStepBase = 0.0;
    4950static const double timeStepScaleFactor = 1000.0;
    5051
     
    7980}
    8081
    81 double TimeInputType::minimum() const
     82StepRange TimeInputType::createStepRange(AnyStepHandling anyStepHandling) const
    8283{
    83     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumTime());
    84 }
     84    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (timeDefaultStep, timeDefaultStepBase, timeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
    8585
    86 double TimeInputType::maximum() const
    87 {
    88     return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumTime());
    89 }
    90 
    91 double TimeInputType::defaultStep() const
    92 {
    93     return timeDefaultStep;
    94 }
    95 
    96 double TimeInputType::stepScaleFactor() const
    97 {
    98     return timeStepScaleFactor;
    99 }
    100 
    101 bool TimeInputType::scaledStepValueShouldBeInteger() const
    102 {
    103     return true;
     86    double stepBase = parseToDouble(element()->fastGetAttribute(minAttr), 0);
     87    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumTime());
     88    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumTime());
     89    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     90    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    10491}
    10592
  • trunk/Source/WebCore/html/TimeInputType.h

    r116499 r117738  
    4747    virtual DateComponents::Type dateType() const OVERRIDE;
    4848    virtual double defaultValueForStepUp() const OVERRIDE;
    49     virtual double minimum() const OVERRIDE;
    50     virtual double maximum() const OVERRIDE;
    51     virtual double defaultStep() const OVERRIDE;
    52     virtual double stepScaleFactor() const OVERRIDE;
    53     virtual bool scaledStepValueShouldBeInteger() const OVERRIDE;
     49    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    5450    virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const OVERRIDE;
    5551    virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
  • trunk/Source/WebCore/html/WeekInputType.cpp

    r116499 r117738  
    6262}
    6363
    64 double WeekInputType::minimum() const
     64StepRange WeekInputType::createStepRange(AnyStepHandling anyStepHandling) const
    6565{
    66     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumWeek());
    67 }
     66    DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (weekDefaultStep, weekDefaultStepBase, weekStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
    6867
    69 double WeekInputType::maximum() const
    70 {
    71     return parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumWeek());
    72 }
    73 
    74 double WeekInputType::stepBase() const
    75 {
    76     return parseToDouble(element()->fastGetAttribute(minAttr), weekDefaultStepBase);
    77 }
    78 
    79 double WeekInputType::defaultStep() const
    80 {
    81     return weekDefaultStep;
    82 }
    83 
    84 double WeekInputType::stepScaleFactor() const
    85 {
    86     return weekStepScaleFactor;
    87 }
    88 
    89 bool WeekInputType::parsedStepValueShouldBeInteger() const
    90 {
    91     return true;
     68    double stepBase = parseToDouble(element()->fastGetAttribute(minAttr), weekDefaultStepBase);
     69    double minimum = parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumWeek());
     70    double maximum = parseToDouble(element()->fastGetAttribute(maxAttr), DateComponents::maximumWeek());
     71    StepRange::DoubleWithDecimalPlacesOrMissing step = StepRange::parseStep(anyStepHandling, stepDescription, element()->fastGetAttribute(stepAttr));
     72    return StepRange(stepBase, minimum, maximum, step, stepDescription);
    9273}
    9374
  • trunk/Source/WebCore/html/WeekInputType.h

    r116499 r117738  
    4646    virtual const AtomicString& formControlType() const OVERRIDE;
    4747    virtual DateComponents::Type dateType() const OVERRIDE;
    48     virtual double minimum() const OVERRIDE;
    49     virtual double maximum() const OVERRIDE;
    50     virtual double stepBase() const OVERRIDE;
    51     virtual double defaultStep() const OVERRIDE;
    52     virtual double stepScaleFactor() const OVERRIDE;
    53     virtual bool parsedStepValueShouldBeInteger() const OVERRIDE;
     48    virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
    5449    virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const OVERRIDE;
    5550    virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
  • trunk/Source/WebCore/html/shadow/SliderThumbElement.cpp

    r116730 r117738  
    5454inline static double sliderPosition(HTMLInputElement* element)
    5555{
    56     StepRange range(element);
    57     return range.proportionFromValue(range.valueFromElement(element));
     56    StepRange stepRange(element->createStepRange(RejectAny));
     57
     58    double oldValue;
     59    bool parseSuccess = parseToDoubleForNumberType(element->value(), &oldValue);
     60    if (!parseSuccess)
     61        oldValue = stepRange.defaultValue();
     62    double newValue = stepRange.clampValue(oldValue);
     63    return stepRange.proportionFromValue(newValue);
    5864}
    5965
     
    236242        return;
    237243
    238     StepRange range(input);
    239244    double fraction = static_cast<double>(position) / trackSize;
    240245    if (isVertical || !renderBox()->style()->isLeftToRightDirection())
    241246        fraction = 1 - fraction;
    242     double value = range.clampValue(range.valueFromProportion(fraction));
     247    StepRange stepRange(input->createStepRange(RejectAny));
     248    double value = stepRange.clampValue(stepRange.valueFromProportion(fraction));
    243249
    244250    // FIXME: This is no longer being set from renderer. Consider updating the method name.
Note: See TracChangeset for help on using the changeset viewer.