Changeset 116615 in webkit


Ignore:
Timestamp:
May 10, 2012 12:22:32 AM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[Forms] Move step related methods to InputType class from HTMLInputElement class
https://bugs.webkit.org/show_bug.cgi?id=85978

Patch by Yoshifumi Inoue <yosin@chromium.org> on 2012-05-10
Reviewed by Kent Tamura.

This patch is part of re-factoring of HTMLInputElement.cpp for numeric input type.
In this patch, we move implementation of getAllowedValueStep and stepUp/stepUpFromRenderer
to InputType class because of these are for DateTime/Number/Range.

Following patches will change implementation of getAllowedValueStep to use StepRange and
remove step related methods, defaultStep, stepScaleFactor, and so on.

No new tests. This patch should not change behavior.

  • html/HTMLInputElement.cpp:

(WebCore):
(WebCore::HTMLInputElement::getAllowedValueStep):
(WebCore::HTMLInputElement::stepUp):
(WebCore::HTMLInputElement::stepDown):
(WebCore::HTMLInputElement::stepUpFromRenderer):

  • html/HTMLInputElement.h:

(HTMLInputElement):

  • html/InputType.cpp:

(WebCore::InputType::applyStep):
(WebCore):
(WebCore::InputType::alignValueForStep):
(WebCore::InputType::getAllowedValueStep):
(WebCore::InputType::getAllowedValueStepWithDecimalPlaces):
(WebCore::InputType::stepUp):
(WebCore::InputType::stepUpFromRenderer):

  • html/InputType.h:

(InputType):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r116611 r116615  
     12012-05-10  Yoshifumi Inoue  <yosin@chromium.org>
     2
     3        [Forms] Move step related methods to InputType class from HTMLInputElement class
     4        https://bugs.webkit.org/show_bug.cgi?id=85978
     5
     6        Reviewed by Kent Tamura.
     7
     8        This patch is part of re-factoring of HTMLInputElement.cpp for numeric input type.
     9        In this patch, we move implementation of getAllowedValueStep and stepUp/stepUpFromRenderer
     10        to InputType class because of these are for DateTime/Number/Range.
     11
     12        Following patches will change implementation of getAllowedValueStep to use StepRange and
     13        remove step related methods, defaultStep, stepScaleFactor, and so on.
     14
     15        No new tests. This patch should not change behavior.
     16
     17        * html/HTMLInputElement.cpp:
     18        (WebCore):
     19        (WebCore::HTMLInputElement::getAllowedValueStep):
     20        (WebCore::HTMLInputElement::stepUp):
     21        (WebCore::HTMLInputElement::stepDown):
     22        (WebCore::HTMLInputElement::stepUpFromRenderer):
     23        * html/HTMLInputElement.h:
     24        (HTMLInputElement):
     25        * html/InputType.cpp:
     26        (WebCore::InputType::applyStep):
     27        (WebCore):
     28        (WebCore::InputType::alignValueForStep):
     29        (WebCore::InputType::getAllowedValueStep):
     30        (WebCore::InputType::getAllowedValueStepWithDecimalPlaces):
     31        (WebCore::InputType::stepUp):
     32        (WebCore::InputType::stepUpFromRenderer):
     33        * html/InputType.h:
     34        (InputType):
     35
    1362012-05-09  Kent Tamura  <tkent@chromium.org>
    237
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r116592 r116615  
    299299bool HTMLInputElement::getAllowedValueStep(double* step) const
    300300{
    301     return getAllowedValueStepWithDecimalPlaces(RejectAny, step, 0);
    302 }
    303 
    304 bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(AnyStepHandling anyStepHandling, double* step, unsigned* decimalPlaces) const
    305 {
    306     ASSERT(step);
    307     double defaultStep = m_inputType->defaultStep();
    308     double stepScaleFactor = m_inputType->stepScaleFactor();
    309     if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
    310         return false;
    311     const AtomicString& stepString = fastGetAttribute(stepAttr);
    312     if (stepString.isEmpty()) {
    313         *step = defaultStep * stepScaleFactor;
    314         if (decimalPlaces)
    315             *decimalPlaces = 0;
    316         return true;
    317     }
    318 
    319     if (equalIgnoringCase(stepString, "any")) {
    320         switch (anyStepHandling) {
    321         case RejectAny:
    322             return false;
    323         case AnyIsDefaultStep:
    324             *step = defaultStep * stepScaleFactor;
    325             if (decimalPlaces)
    326                 *decimalPlaces = 0;
    327             return true;
    328         default:
    329             ASSERT_NOT_REACHED();
    330         }
    331     }
    332 
    333     double parsed;
    334     if (!decimalPlaces) {
    335         if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
    336             *step = defaultStep * stepScaleFactor;
    337             return true;
    338         }
    339     } else {
    340         if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
    341             *step = defaultStep * stepScaleFactor;
    342             *decimalPlaces = 0;
    343             return true;
    344         }
    345     }
    346     // For date, month, week, the parsed value should be an integer for some types.
    347     if (m_inputType->parsedStepValueShouldBeInteger())
    348         parsed = max(round(parsed), 1.0);
    349     double result = parsed * stepScaleFactor;
    350     // For datetime, datetime-local, time, the result should be an integer.
    351     if (m_inputType->scaledStepValueShouldBeInteger())
    352         result = max(round(result), 1.0);
    353     ASSERT(result > 0);
    354     *step = result;
    355     return true;
    356 }
    357 
    358 void HTMLInputElement::applyStep(double count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
    359 {
    360     double step;
    361     unsigned stepDecimalPlaces, currentDecimalPlaces;
    362     if (!getAllowedValueStepWithDecimalPlaces(anyStepHandling, &step, &stepDecimalPlaces)) {
    363         ec = INVALID_STATE_ERR;
    364         return;
    365     }
    366 
    367     const double nan = numeric_limits<double>::quiet_NaN();
    368     double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
    369     if (!isfinite(current)) {
    370         ec = INVALID_STATE_ERR;
    371         return;
    372     }
    373     double newValue = current + step * count;
    374     if (isinf(newValue)) {
    375         ec = INVALID_STATE_ERR;
    376         return;
    377     }
    378 
    379     double acceptableError = m_inputType->acceptableError(step);
    380     if (newValue - m_inputType->minimum() < -acceptableError) {
    381         ec = INVALID_STATE_ERR;
    382         return;
    383     }
    384     if (newValue < m_inputType->minimum())
    385         newValue = m_inputType->minimum();
    386 
    387     const AtomicString& stepString = fastGetAttribute(stepAttr);
    388     if (!equalIgnoringCase(stepString, "any"))
    389         newValue = alignValueForStep(newValue, step, currentDecimalPlaces, stepDecimalPlaces);
    390 
    391     if (newValue - m_inputType->maximum() > acceptableError) {
    392         ec = INVALID_STATE_ERR;
    393         return;
    394     }
    395     if (newValue > m_inputType->maximum())
    396         newValue = m_inputType->maximum();
    397 
    398     setValueAsNumber(newValue, ec, eventBehavior);
    399 
    400     if (AXObjectCache::accessibilityEnabled())
    401          document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
    402 }
    403 
    404 double HTMLInputElement::alignValueForStep(double newValue, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces)
    405 {
    406     if (newValue >= pow(10.0, 21.0))
    407         return newValue;
    408 
    409     unsigned baseDecimalPlaces;
    410     double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    411     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
    412     if (stepMismatch(value())) {
    413         double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
    414         newValue = round(newValue * scale) / scale;
    415     } else {
    416         double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
    417         newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
    418     }
    419 
    420     return newValue;
     301    return m_inputType->getAllowedValueStep(step);
    421302}
    422303
    423304void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
    424305{
    425     applyStep(n, RejectAny, DispatchNoEvent, ec);
     306    m_inputType->stepUp(n, ec);
    426307}
    427308
    428309void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
    429310{
    430     applyStep(-n, RejectAny, DispatchNoEvent, ec);
     311    m_inputType->stepUp(-n, ec);
    431312}
    432313
     
    15541435void HTMLInputElement::stepUpFromRenderer(int n)
    15551436{
    1556     // The differences from stepUp()/stepDown():
    1557     //
    1558     // Difference 1: the current value
    1559     // If the current value is not a number, including empty, the current value is assumed as 0.
    1560     //   * If 0 is in-range, and matches to step value
    1561     //     - The value should be the +step if n > 0
    1562     //     - The value should be the -step if n < 0
    1563     //     If -step or +step is out of range, new value should be 0.
    1564     //   * If 0 is smaller than the minimum value
    1565     //     - The value should be the minimum value for any n
    1566     //   * If 0 is larger than the maximum value
    1567     //     - The value should be the maximum value for any n
    1568     //   * If 0 is in-range, but not matched to step value
    1569     //     - The value should be the larger matched value nearest to 0 if n > 0
    1570     //       e.g. <input type=number min=-100 step=3> -> 2
    1571     //     - The value should be the smaler matched value nearest to 0 if n < 0
    1572     //       e.g. <input type=number min=-100 step=3> -> -1
    1573     //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
    1574     //   As for datetime type, the current value is assumed as "the current date/time in UTC".
    1575     // If the current value is smaller than the minimum value:
    1576     //  - The value should be the minimum value if n > 0
    1577     //  - Nothing should happen if n < 0
    1578     // If the current value is larger than the maximum value:
    1579     //  - The value should be the maximum value if n < 0
    1580     //  - Nothing should happen if n > 0
    1581     //
    1582     // Difference 2: clamping steps
    1583     // If the current value is not matched to step value:
    1584     // - The value should be the larger matched value nearest to 0 if n > 0
    1585     //   e.g. <input type=number value=3 min=-100 step=3> -> 5
    1586     // - The value should be the smaler matched value nearest to 0 if n < 0
    1587     //   e.g. <input type=number value=3 min=-100 step=3> -> 2
    1588     //
    1589     // n is assumed as -n if step < 0.
    1590 
    1591     ASSERT(isSteppable());
    1592     if (!isSteppable())
    1593         return;
    1594     ASSERT(n);
    1595     if (!n)
    1596         return;
    1597 
    1598     unsigned stepDecimalPlaces, baseDecimalPlaces;
    1599     double step, base;
    1600     // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
    1601     // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
    1602     if (!getAllowedValueStepWithDecimalPlaces(AnyIsDefaultStep, &step, &stepDecimalPlaces))
    1603       return;
    1604     base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
    1605     baseDecimalPlaces = min(baseDecimalPlaces, 16u);
    1606 
    1607     int sign;
    1608     if (step > 0)
    1609         sign = n;
    1610     else if (step < 0)
    1611         sign = -n;
    1612     else
    1613         sign = 0;
    1614 
    1615     const double nan = numeric_limits<double>::quiet_NaN();
    1616     String currentStringValue = value();
    1617     double current = m_inputType->parseToDouble(currentStringValue, nan);
    1618     if (!isfinite(current)) {
    1619         ExceptionCode ec;
    1620         current = m_inputType->defaultValueForStepUp();
    1621         double nextDiff = step * n;
    1622         if (current < m_inputType->minimum() - nextDiff)
    1623             current = m_inputType->minimum() - nextDiff;
    1624         if (current > m_inputType->maximum() - nextDiff)
    1625             current = m_inputType->maximum() - nextDiff;
    1626         setValueAsNumber(current, ec, DispatchInputAndChangeEvent);
    1627     }
    1628     if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
    1629         setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()), DispatchInputAndChangeEvent);
    1630     else {
    1631         ExceptionCode ec;
    1632         if (stepMismatch(value())) {
    1633             ASSERT(step);
    1634             double newValue;
    1635             double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
    1636 
    1637             if (sign < 0)
    1638                 newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
    1639             else if (sign > 0)
    1640                 newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
    1641             else
    1642                 newValue = current;
    1643 
    1644             if (newValue < m_inputType->minimum())
    1645                 newValue = m_inputType->minimum();
    1646             if (newValue > m_inputType->maximum())
    1647                 newValue = m_inputType->maximum();
    1648 
    1649             setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
    1650             current = newValue;
    1651             if (n > 1)
    1652                 applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
    1653             else if (n < -1)
    1654                 applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
    1655         } else
    1656             applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
    1657     }
     1437    m_inputType->stepUpFromRenderer(n);
    16581438}
    16591439
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r116592 r116615  
    261261private:
    262262    enum AutoCompleteSetting { Uninitialized, On, Off };
    263     enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
    264263
    265264    virtual void willChangeForm() OVERRIDE;
     
    345344    virtual void subtreeHasChanged();
    346345
    347     bool getAllowedValueStepWithDecimalPlaces(AnyStepHandling, double*, unsigned*) const;
    348 
    349     // Helper for stepUp()/stepDown().  Adds step value * count to the current value.
    350     void applyStep(double count, AnyStepHandling, TextFieldEventBehavior, ExceptionCode&);
    351     double alignValueForStep(double value, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces);
    352346
    353347#if ENABLE(DATALIST)
  • trunk/Source/WebCore/html/InputType.cpp

    r116499 r116615  
    66 *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
    77 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org)
    8  * Copyright (C) 2010 Google Inc. All rights reserved.
     8 * Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved.
    99 * Copyright (C) 2012 Samsung Electronics. All rights reserved.
    1010 *
     
    2929#include "InputType.h"
    3030
     31#include "AXObjectCache.h"
    3132#include "BeforeTextInsertedEvent.h"
    3233#include "ButtonInputType.h"
     
    816817}
    817818
     819void InputType::applyStep(double count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
     820{
     821    double step;
     822    unsigned stepDecimalPlaces, currentDecimalPlaces;
     823    if (!getAllowedValueStepWithDecimalPlaces(anyStepHandling, &step, &stepDecimalPlaces)) {
     824        ec = INVALID_STATE_ERR;
     825        return;
     826    }
     827
     828    const double nan = numeric_limits<double>::quiet_NaN();
     829    double current = parseToDoubleWithDecimalPlaces(element()->value(), nan, &currentDecimalPlaces);
     830    if (!isfinite(current)) {
     831        ec = INVALID_STATE_ERR;
     832        return;
     833    }
     834    double newValue = current + step * count;
     835    if (isinf(newValue)) {
     836        ec = INVALID_STATE_ERR;
     837        return;
     838    }
     839
     840    double acceptableErrorValue = acceptableError(step);
     841    if (newValue - minimum() < -acceptableErrorValue) {
     842        ec = INVALID_STATE_ERR;
     843        return;
     844    }
     845    if (newValue < minimum())
     846        newValue = minimum();
     847
     848    const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
     849    if (!equalIgnoringCase(stepString, "any"))
     850        newValue = alignValueForStep(newValue, step, currentDecimalPlaces, stepDecimalPlaces);
     851
     852    if (newValue - maximum() > acceptableErrorValue) {
     853        ec = INVALID_STATE_ERR;
     854        return;
     855    }
     856    if (newValue > maximum())
     857        newValue = maximum();
     858
     859    element()->setValueAsNumber(newValue, ec, eventBehavior);
     860
     861    if (AXObjectCache::accessibilityEnabled())
     862         element()->document()->axObjectCache()->postNotification(element()->renderer(), AXObjectCache::AXValueChanged, true);
     863}
     864
     865double InputType::alignValueForStep(double newValue, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces)
     866{
     867    if (newValue >= pow(10.0, 21.0))
     868        return newValue;
     869
     870    unsigned baseDecimalPlaces;
     871    double base = stepBaseWithDecimalPlaces(&baseDecimalPlaces);
     872    baseDecimalPlaces = min(baseDecimalPlaces, 16u);
     873    if (element()->stepMismatch(element()->value())) {
     874        double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
     875        newValue = round(newValue * scale) / scale;
     876    } else {
     877        double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
     878        newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
     879    }
     880
     881    return newValue;
     882}
     883
     884bool InputType::getAllowedValueStep(double* step) const
     885{
     886    return getAllowedValueStepWithDecimalPlaces(RejectAny, step, 0);
     887}
     888
     889bool InputType::getAllowedValueStepWithDecimalPlaces(AnyStepHandling anyStepHandling, double* step, unsigned* decimalPlaces) const
     890{
     891    ASSERT(step);
     892    double defaultStepValue = defaultStep();
     893    double stepScaleFactorValue = stepScaleFactor();
     894    if (!isfinite(defaultStepValue) || !isfinite(stepScaleFactorValue))
     895        return false;
     896    const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
     897    if (stepString.isEmpty()) {
     898        *step = defaultStepValue * stepScaleFactorValue;
     899        if (decimalPlaces)
     900            *decimalPlaces = 0;
     901        return true;
     902    }
     903
     904    if (equalIgnoringCase(stepString, "any")) {
     905        switch (anyStepHandling) {
     906        case RejectAny:
     907            return false;
     908        case AnyIsDefaultStep:
     909            *step = defaultStepValue * stepScaleFactorValue;
     910            if (decimalPlaces)
     911                *decimalPlaces = 0;
     912            return true;
     913        default:
     914            ASSERT_NOT_REACHED();
     915        }
     916    }
     917
     918    double parsed;
     919    if (!decimalPlaces) {
     920        if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
     921            *step = defaultStepValue * stepScaleFactorValue;
     922            return true;
     923        }
     924    } else {
     925        if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
     926            *step = defaultStepValue * stepScaleFactorValue;
     927            *decimalPlaces = 0;
     928            return true;
     929        }
     930    }
     931    // For date, month, week, the parsed value should be an integer for some types.
     932    if (parsedStepValueShouldBeInteger())
     933        parsed = max(round(parsed), 1.0);
     934    double result = parsed * stepScaleFactorValue;
     935    // For datetime, datetime-local, time, the result should be an integer.
     936    if (scaledStepValueShouldBeInteger())
     937        result = max(round(result), 1.0);
     938    ASSERT(result > 0);
     939    *step = result;
     940    return true;
     941}
     942
     943void InputType::stepUp(int n, ExceptionCode& ec)
     944{
     945    applyStep(n, RejectAny, DispatchNoEvent, ec);
     946}
     947
     948void InputType::stepUpFromRenderer(int n)
     949{
     950    // The differences from stepUp()/stepDown():
     951    //
     952    // Difference 1: the current value
     953    // If the current value is not a number, including empty, the current value is assumed as 0.
     954    //   * If 0 is in-range, and matches to step value
     955    //     - The value should be the +step if n > 0
     956    //     - The value should be the -step if n < 0
     957    //     If -step or +step is out of range, new value should be 0.
     958    //   * If 0 is smaller than the minimum value
     959    //     - The value should be the minimum value for any n
     960    //   * If 0 is larger than the maximum value
     961    //     - The value should be the maximum value for any n
     962    //   * If 0 is in-range, but not matched to step value
     963    //     - The value should be the larger matched value nearest to 0 if n > 0
     964    //       e.g. <input type=number min=-100 step=3> -> 2
     965    //     - The value should be the smaler matched value nearest to 0 if n < 0
     966    //       e.g. <input type=number min=-100 step=3> -> -1
     967    //   As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
     968    //   As for datetime type, the current value is assumed as "the current date/time in UTC".
     969    // If the current value is smaller than the minimum value:
     970    //  - The value should be the minimum value if n > 0
     971    //  - Nothing should happen if n < 0
     972    // If the current value is larger than the maximum value:
     973    //  - The value should be the maximum value if n < 0
     974    //  - Nothing should happen if n > 0
     975    //
     976    // Difference 2: clamping steps
     977    // If the current value is not matched to step value:
     978    // - The value should be the larger matched value nearest to 0 if n > 0
     979    //   e.g. <input type=number value=3 min=-100 step=3> -> 5
     980    // - The value should be the smaler matched value nearest to 0 if n < 0
     981    //   e.g. <input type=number value=3 min=-100 step=3> -> 2
     982    //
     983    // n is assumed as -n if step < 0.
     984
     985    ASSERT(isSteppable());
     986    if (!isSteppable())
     987        return;
     988    ASSERT(n);
     989    if (!n)
     990        return;
     991
     992    unsigned stepDecimalPlaces, baseDecimalPlaces;
     993    double step, base;
     994    // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
     995    // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
     996    if (!getAllowedValueStepWithDecimalPlaces(AnyIsDefaultStep, &step, &stepDecimalPlaces))
     997      return;
     998    base = stepBaseWithDecimalPlaces(&baseDecimalPlaces);
     999    baseDecimalPlaces = min(baseDecimalPlaces, 16u);
     1000
     1001    int sign;
     1002    if (step > 0)
     1003        sign = n;
     1004    else if (step < 0)
     1005        sign = -n;
     1006    else
     1007        sign = 0;
     1008
     1009    const double nan = numeric_limits<double>::quiet_NaN();
     1010    String currentStringValue = element()->value();
     1011    double current = parseToDouble(currentStringValue, nan);
     1012    if (!isfinite(current)) {
     1013        ExceptionCode ec;
     1014        current = defaultValueForStepUp();
     1015        double nextDiff = step * n;
     1016        if (current < minimum() - nextDiff)
     1017            current = minimum() - nextDiff;
     1018        if (current > maximum() - nextDiff)
     1019            current = maximum() - nextDiff;
     1020        element()->setValueAsNumber(current, ec, DispatchInputAndChangeEvent);
     1021    }
     1022    if ((sign > 0 && current < minimum()) || (sign < 0 && current > maximum()))
     1023        element()->setValue(serialize(sign > 0 ? minimum() : maximum()), DispatchInputAndChangeEvent);
     1024    else {
     1025        ExceptionCode ec;
     1026        if (element()->stepMismatch(element()->value())) {
     1027            ASSERT(step);
     1028            double newValue;
     1029            double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
     1030
     1031            if (sign < 0)
     1032                newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
     1033            else if (sign > 0)
     1034                newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
     1035            else
     1036                newValue = current;
     1037
     1038            if (newValue < minimum())
     1039                newValue = minimum();
     1040            if (newValue > maximum())
     1041                newValue = maximum();
     1042
     1043            element()->setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
     1044            current = newValue;
     1045            if (n > 1)
     1046                applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
     1047            else if (n < -1)
     1048                applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
     1049        } else
     1050            applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
     1051    }
     1052}
     1053
    8181054namespace InputTypeNames {
    8191055
  • trunk/Source/WebCore/html/InputType.h

    r116499 r116615  
    161161    virtual double stepBase() const;
    162162    virtual double stepBaseWithDecimalPlaces(unsigned*) const;
     163    virtual bool getAllowedValueStep(double*) const;
     164    virtual void stepUp(int, ExceptionCode&);
     165    virtual void stepUpFromRenderer(int);
    163166    virtual double defaultStep() const;
    164167    virtual double stepScaleFactor() const;
     
    297300
    298301private:
     302    enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
     303
     304    // Helper for stepUp()/stepDown(). Adds step value * count to the current value.
     305    void applyStep(double count, AnyStepHandling, TextFieldEventBehavior, ExceptionCode&);
     306    double alignValueForStep(double value, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces);
     307    bool getAllowedValueStepWithDecimalPlaces(AnyStepHandling, double*, unsigned*) const;
     308
    299309    // Raw pointer because the HTMLInputElement object owns this InputType object.
    300310    HTMLInputElement* m_element;
Note: See TracChangeset for help on using the changeset viewer.