Diff
Modified: trunk/Source/WebCore/ChangeLog (116614 => 116615)
--- trunk/Source/WebCore/ChangeLog 2012-05-10 07:10:19 UTC (rev 116614)
+++ trunk/Source/WebCore/ChangeLog 2012-05-10 07:22:32 UTC (rev 116615)
@@ -1,3 +1,38 @@
+2012-05-10 Yoshifumi Inoue <yo...@chromium.org>
+
+ [Forms] Move step related methods to InputType class from HTMLInputElement class
+ https://bugs.webkit.org/show_bug.cgi?id=85978
+
+ 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):
+
2012-05-09 Kent Tamura <tk...@chromium.org>
Calendar Picker: Fix a crash by changing input type.
Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (116614 => 116615)
--- trunk/Source/WebCore/html/HTMLInputElement.cpp 2012-05-10 07:10:19 UTC (rev 116614)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp 2012-05-10 07:22:32 UTC (rev 116615)
@@ -298,136 +298,17 @@
bool HTMLInputElement::getAllowedValueStep(double* step) const
{
- return getAllowedValueStepWithDecimalPlaces(RejectAny, step, 0);
+ return m_inputType->getAllowedValueStep(step);
}
-bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(AnyStepHandling anyStepHandling, double* step, unsigned* decimalPlaces) const
-{
- ASSERT(step);
- double defaultStep = m_inputType->defaultStep();
- double stepScaleFactor = m_inputType->stepScaleFactor();
- if (!isfinite(defaultStep) || !isfinite(stepScaleFactor))
- return false;
- const AtomicString& stepString = fastGetAttribute(stepAttr);
- if (stepString.isEmpty()) {
- *step = defaultStep * stepScaleFactor;
- if (decimalPlaces)
- *decimalPlaces = 0;
- return true;
- }
-
- if (equalIgnoringCase(stepString, "any")) {
- switch (anyStepHandling) {
- case RejectAny:
- return false;
- case AnyIsDefaultStep:
- *step = defaultStep * stepScaleFactor;
- if (decimalPlaces)
- *decimalPlaces = 0;
- return true;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- double parsed;
- if (!decimalPlaces) {
- if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
- *step = defaultStep * stepScaleFactor;
- return true;
- }
- } else {
- if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
- *step = defaultStep * stepScaleFactor;
- *decimalPlaces = 0;
- return true;
- }
- }
- // For date, month, week, the parsed value should be an integer for some types.
- if (m_inputType->parsedStepValueShouldBeInteger())
- parsed = max(round(parsed), 1.0);
- double result = parsed * stepScaleFactor;
- // For datetime, datetime-local, time, the result should be an integer.
- if (m_inputType->scaledStepValueShouldBeInteger())
- result = max(round(result), 1.0);
- ASSERT(result > 0);
- *step = result;
- return true;
-}
-
-void HTMLInputElement::applyStep(double count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
-{
- double step;
- unsigned stepDecimalPlaces, currentDecimalPlaces;
- if (!getAllowedValueStepWithDecimalPlaces(anyStepHandling, &step, &stepDecimalPlaces)) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- const double nan = numeric_limits<double>::quiet_NaN();
- double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, ¤tDecimalPlaces);
- if (!isfinite(current)) {
- ec = INVALID_STATE_ERR;
- return;
- }
- double newValue = current + step * count;
- if (isinf(newValue)) {
- ec = INVALID_STATE_ERR;
- return;
- }
-
- double acceptableError = m_inputType->acceptableError(step);
- if (newValue - m_inputType->minimum() < -acceptableError) {
- ec = INVALID_STATE_ERR;
- return;
- }
- if (newValue < m_inputType->minimum())
- newValue = m_inputType->minimum();
-
- const AtomicString& stepString = fastGetAttribute(stepAttr);
- if (!equalIgnoringCase(stepString, "any"))
- newValue = alignValueForStep(newValue, step, currentDecimalPlaces, stepDecimalPlaces);
-
- if (newValue - m_inputType->maximum() > acceptableError) {
- ec = INVALID_STATE_ERR;
- return;
- }
- if (newValue > m_inputType->maximum())
- newValue = m_inputType->maximum();
-
- setValueAsNumber(newValue, ec, eventBehavior);
-
- if (AXObjectCache::accessibilityEnabled())
- document()->axObjectCache()->postNotification(renderer(), AXObjectCache::AXValueChanged, true);
-}
-
-double HTMLInputElement::alignValueForStep(double newValue, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces)
-{
- if (newValue >= pow(10.0, 21.0))
- return newValue;
-
- unsigned baseDecimalPlaces;
- double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
- baseDecimalPlaces = min(baseDecimalPlaces, 16u);
- if (stepMismatch(value())) {
- double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
- newValue = round(newValue * scale) / scale;
- } else {
- double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
- newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
- }
-
- return newValue;
-}
-
void HTMLInputElement::stepUp(int n, ExceptionCode& ec)
{
- applyStep(n, RejectAny, DispatchNoEvent, ec);
+ m_inputType->stepUp(n, ec);
}
void HTMLInputElement::stepDown(int n, ExceptionCode& ec)
{
- applyStep(-n, RejectAny, DispatchNoEvent, ec);
+ m_inputType->stepUp(-n, ec);
}
bool HTMLInputElement::isKeyboardFocusable(KeyboardEvent* event) const
@@ -1553,108 +1434,7 @@
void HTMLInputElement::stepUpFromRenderer(int n)
{
- // The differences from stepUp()/stepDown():
- //
- // Difference 1: the current value
- // If the current value is not a number, including empty, the current value is assumed as 0.
- // * If 0 is in-range, and matches to step value
- // - The value should be the +step if n > 0
- // - The value should be the -step if n < 0
- // If -step or +step is out of range, new value should be 0.
- // * If 0 is smaller than the minimum value
- // - The value should be the minimum value for any n
- // * If 0 is larger than the maximum value
- // - The value should be the maximum value for any n
- // * If 0 is in-range, but not matched to step value
- // - The value should be the larger matched value nearest to 0 if n > 0
- // e.g. <input type=number min=-100 step=3> -> 2
- // - The value should be the smaler matched value nearest to 0 if n < 0
- // e.g. <input type=number min=-100 step=3> -> -1
- // As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
- // As for datetime type, the current value is assumed as "the current date/time in UTC".
- // If the current value is smaller than the minimum value:
- // - The value should be the minimum value if n > 0
- // - Nothing should happen if n < 0
- // If the current value is larger than the maximum value:
- // - The value should be the maximum value if n < 0
- // - Nothing should happen if n > 0
- //
- // Difference 2: clamping steps
- // If the current value is not matched to step value:
- // - The value should be the larger matched value nearest to 0 if n > 0
- // e.g. <input type=number value=3 min=-100 step=3> -> 5
- // - The value should be the smaler matched value nearest to 0 if n < 0
- // e.g. <input type=number value=3 min=-100 step=3> -> 2
- //
- // n is assumed as -n if step < 0.
-
- ASSERT(isSteppable());
- if (!isSteppable())
- return;
- ASSERT(n);
- if (!n)
- return;
-
- unsigned stepDecimalPlaces, baseDecimalPlaces;
- double step, base;
- // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
- // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
- if (!getAllowedValueStepWithDecimalPlaces(AnyIsDefaultStep, &step, &stepDecimalPlaces))
- return;
- base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
- baseDecimalPlaces = min(baseDecimalPlaces, 16u);
-
- int sign;
- if (step > 0)
- sign = n;
- else if (step < 0)
- sign = -n;
- else
- sign = 0;
-
- const double nan = numeric_limits<double>::quiet_NaN();
- String currentStringValue = value();
- double current = m_inputType->parseToDouble(currentStringValue, nan);
- if (!isfinite(current)) {
- ExceptionCode ec;
- current = m_inputType->defaultValueForStepUp();
- double nextDiff = step * n;
- if (current < m_inputType->minimum() - nextDiff)
- current = m_inputType->minimum() - nextDiff;
- if (current > m_inputType->maximum() - nextDiff)
- current = m_inputType->maximum() - nextDiff;
- setValueAsNumber(current, ec, DispatchInputAndChangeEvent);
- }
- if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
- setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()), DispatchInputAndChangeEvent);
- else {
- ExceptionCode ec;
- if (stepMismatch(value())) {
- ASSERT(step);
- double newValue;
- double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
-
- if (sign < 0)
- newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
- else if (sign > 0)
- newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
- else
- newValue = current;
-
- if (newValue < m_inputType->minimum())
- newValue = m_inputType->minimum();
- if (newValue > m_inputType->maximum())
- newValue = m_inputType->maximum();
-
- setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
- current = newValue;
- if (n > 1)
- applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
- else if (n < -1)
- applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
- } else
- applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
- }
+ m_inputType->stepUpFromRenderer(n);
}
#if ENABLE(INPUT_SPEECH)
Modified: trunk/Source/WebCore/html/HTMLInputElement.h (116614 => 116615)
--- trunk/Source/WebCore/html/HTMLInputElement.h 2012-05-10 07:10:19 UTC (rev 116614)
+++ trunk/Source/WebCore/html/HTMLInputElement.h 2012-05-10 07:22:32 UTC (rev 116615)
@@ -260,7 +260,6 @@
private:
enum AutoCompleteSetting { Uninitialized, On, Off };
- enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
virtual void willChangeForm() OVERRIDE;
virtual void didChangeForm() OVERRIDE;
@@ -344,12 +343,7 @@
virtual void subtreeHasChanged();
- bool getAllowedValueStepWithDecimalPlaces(AnyStepHandling, double*, unsigned*) const;
- // Helper for stepUp()/stepDown(). Adds step value * count to the current value.
- void applyStep(double count, AnyStepHandling, TextFieldEventBehavior, ExceptionCode&);
- double alignValueForStep(double value, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces);
-
#if ENABLE(DATALIST)
HTMLDataListElement* dataList() const;
#endif
Modified: trunk/Source/WebCore/html/InputType.cpp (116614 => 116615)
--- trunk/Source/WebCore/html/InputType.cpp 2012-05-10 07:10:19 UTC (rev 116614)
+++ trunk/Source/WebCore/html/InputType.cpp 2012-05-10 07:22:32 UTC (rev 116615)
@@ -5,7 +5,7 @@
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
* (C) 2006 Alexey Proskuryakov (a...@nypop.com)
* Copyright (C) 2007 Samuel Weinig (s...@webkit.org)
- * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved.
* Copyright (C) 2012 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -28,6 +28,7 @@
#include "config.h"
#include "InputType.h"
+#include "AXObjectCache.h"
#include "BeforeTextInsertedEvent.h"
#include "ButtonInputType.h"
#include "CheckboxInputType.h"
@@ -815,6 +816,241 @@
return 0;
}
+void InputType::applyStep(double count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionCode& ec)
+{
+ double step;
+ unsigned stepDecimalPlaces, currentDecimalPlaces;
+ if (!getAllowedValueStepWithDecimalPlaces(anyStepHandling, &step, &stepDecimalPlaces)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ const double nan = numeric_limits<double>::quiet_NaN();
+ double current = parseToDoubleWithDecimalPlaces(element()->value(), nan, ¤tDecimalPlaces);
+ if (!isfinite(current)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ double newValue = current + step * count;
+ if (isinf(newValue)) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+
+ double acceptableErrorValue = acceptableError(step);
+ if (newValue - minimum() < -acceptableErrorValue) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ if (newValue < minimum())
+ newValue = minimum();
+
+ const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
+ if (!equalIgnoringCase(stepString, "any"))
+ newValue = alignValueForStep(newValue, step, currentDecimalPlaces, stepDecimalPlaces);
+
+ if (newValue - maximum() > acceptableErrorValue) {
+ ec = INVALID_STATE_ERR;
+ return;
+ }
+ if (newValue > maximum())
+ newValue = maximum();
+
+ element()->setValueAsNumber(newValue, ec, eventBehavior);
+
+ if (AXObjectCache::accessibilityEnabled())
+ element()->document()->axObjectCache()->postNotification(element()->renderer(), AXObjectCache::AXValueChanged, true);
+}
+
+double InputType::alignValueForStep(double newValue, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces)
+{
+ if (newValue >= pow(10.0, 21.0))
+ return newValue;
+
+ unsigned baseDecimalPlaces;
+ double base = stepBaseWithDecimalPlaces(&baseDecimalPlaces);
+ baseDecimalPlaces = min(baseDecimalPlaces, 16u);
+ if (element()->stepMismatch(element()->value())) {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
+ newValue = round(newValue * scale) / scale;
+ } else {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+ newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
+ }
+
+ return newValue;
+}
+
+bool InputType::getAllowedValueStep(double* step) const
+{
+ return getAllowedValueStepWithDecimalPlaces(RejectAny, step, 0);
+}
+
+bool InputType::getAllowedValueStepWithDecimalPlaces(AnyStepHandling anyStepHandling, double* step, unsigned* decimalPlaces) const
+{
+ ASSERT(step);
+ double defaultStepValue = defaultStep();
+ double stepScaleFactorValue = stepScaleFactor();
+ if (!isfinite(defaultStepValue) || !isfinite(stepScaleFactorValue))
+ return false;
+ const AtomicString& stepString = element()->fastGetAttribute(stepAttr);
+ if (stepString.isEmpty()) {
+ *step = defaultStepValue * stepScaleFactorValue;
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return true;
+ }
+
+ if (equalIgnoringCase(stepString, "any")) {
+ switch (anyStepHandling) {
+ case RejectAny:
+ return false;
+ case AnyIsDefaultStep:
+ *step = defaultStepValue * stepScaleFactorValue;
+ if (decimalPlaces)
+ *decimalPlaces = 0;
+ return true;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ double parsed;
+ if (!decimalPlaces) {
+ if (!parseToDoubleForNumberType(stepString, &parsed) || parsed <= 0.0) {
+ *step = defaultStepValue * stepScaleFactorValue;
+ return true;
+ }
+ } else {
+ if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepString, &parsed, decimalPlaces) || parsed <= 0.0) {
+ *step = defaultStepValue * stepScaleFactorValue;
+ *decimalPlaces = 0;
+ return true;
+ }
+ }
+ // For date, month, week, the parsed value should be an integer for some types.
+ if (parsedStepValueShouldBeInteger())
+ parsed = max(round(parsed), 1.0);
+ double result = parsed * stepScaleFactorValue;
+ // For datetime, datetime-local, time, the result should be an integer.
+ if (scaledStepValueShouldBeInteger())
+ result = max(round(result), 1.0);
+ ASSERT(result > 0);
+ *step = result;
+ return true;
+}
+
+void InputType::stepUp(int n, ExceptionCode& ec)
+{
+ applyStep(n, RejectAny, DispatchNoEvent, ec);
+}
+
+void InputType::stepUpFromRenderer(int n)
+{
+ // The differences from stepUp()/stepDown():
+ //
+ // Difference 1: the current value
+ // If the current value is not a number, including empty, the current value is assumed as 0.
+ // * If 0 is in-range, and matches to step value
+ // - The value should be the +step if n > 0
+ // - The value should be the -step if n < 0
+ // If -step or +step is out of range, new value should be 0.
+ // * If 0 is smaller than the minimum value
+ // - The value should be the minimum value for any n
+ // * If 0 is larger than the maximum value
+ // - The value should be the maximum value for any n
+ // * If 0 is in-range, but not matched to step value
+ // - The value should be the larger matched value nearest to 0 if n > 0
+ // e.g. <input type=number min=-100 step=3> -> 2
+ // - The value should be the smaler matched value nearest to 0 if n < 0
+ // e.g. <input type=number min=-100 step=3> -> -1
+ // As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
+ // As for datetime type, the current value is assumed as "the current date/time in UTC".
+ // If the current value is smaller than the minimum value:
+ // - The value should be the minimum value if n > 0
+ // - Nothing should happen if n < 0
+ // If the current value is larger than the maximum value:
+ // - The value should be the maximum value if n < 0
+ // - Nothing should happen if n > 0
+ //
+ // Difference 2: clamping steps
+ // If the current value is not matched to step value:
+ // - The value should be the larger matched value nearest to 0 if n > 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 5
+ // - The value should be the smaler matched value nearest to 0 if n < 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 2
+ //
+ // n is assumed as -n if step < 0.
+
+ ASSERT(isSteppable());
+ if (!isSteppable())
+ return;
+ ASSERT(n);
+ if (!n)
+ return;
+
+ unsigned stepDecimalPlaces, baseDecimalPlaces;
+ double step, base;
+ // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
+ // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
+ if (!getAllowedValueStepWithDecimalPlaces(AnyIsDefaultStep, &step, &stepDecimalPlaces))
+ return;
+ base = stepBaseWithDecimalPlaces(&baseDecimalPlaces);
+ baseDecimalPlaces = min(baseDecimalPlaces, 16u);
+
+ int sign;
+ if (step > 0)
+ sign = n;
+ else if (step < 0)
+ sign = -n;
+ else
+ sign = 0;
+
+ const double nan = numeric_limits<double>::quiet_NaN();
+ String currentStringValue = element()->value();
+ double current = parseToDouble(currentStringValue, nan);
+ if (!isfinite(current)) {
+ ExceptionCode ec;
+ current = defaultValueForStepUp();
+ double nextDiff = step * n;
+ if (current < minimum() - nextDiff)
+ current = minimum() - nextDiff;
+ if (current > maximum() - nextDiff)
+ current = maximum() - nextDiff;
+ element()->setValueAsNumber(current, ec, DispatchInputAndChangeEvent);
+ }
+ if ((sign > 0 && current < minimum()) || (sign < 0 && current > maximum()))
+ element()->setValue(serialize(sign > 0 ? minimum() : maximum()), DispatchInputAndChangeEvent);
+ else {
+ ExceptionCode ec;
+ if (element()->stepMismatch(element()->value())) {
+ ASSERT(step);
+ double newValue;
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+
+ if (sign < 0)
+ newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
+ else if (sign > 0)
+ newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
+ else
+ newValue = current;
+
+ if (newValue < minimum())
+ newValue = minimum();
+ if (newValue > maximum())
+ newValue = maximum();
+
+ element()->setValueAsNumber(newValue, ec, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent);
+ current = newValue;
+ if (n > 1)
+ applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
+ else if (n < -1)
+ applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
+ } else
+ applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, ec);
+ }
+}
+
namespace InputTypeNames {
// The type names must be lowercased because they will be the return values of
Modified: trunk/Source/WebCore/html/InputType.h (116614 => 116615)
--- trunk/Source/WebCore/html/InputType.h 2012-05-10 07:10:19 UTC (rev 116614)
+++ trunk/Source/WebCore/html/InputType.h 2012-05-10 07:22:32 UTC (rev 116615)
@@ -160,6 +160,9 @@
virtual bool stepMismatch(const String&, double step) const;
virtual double stepBase() const;
virtual double stepBaseWithDecimalPlaces(unsigned*) const;
+ virtual bool getAllowedValueStep(double*) const;
+ virtual void stepUp(int, ExceptionCode&);
+ virtual void stepUpFromRenderer(int);
virtual double defaultStep() const;
virtual double stepScaleFactor() const;
virtual bool parsedStepValueShouldBeInteger() const;
@@ -296,6 +299,13 @@
Chrome* chrome() const;
private:
+ enum AnyStepHandling { RejectAny, AnyIsDefaultStep };
+
+ // Helper for stepUp()/stepDown(). Adds step value * count to the current value.
+ void applyStep(double count, AnyStepHandling, TextFieldEventBehavior, ExceptionCode&);
+ double alignValueForStep(double value, double step, unsigned currentDecimalPlaces, unsigned stepDecimalPlaces);
+ bool getAllowedValueStepWithDecimalPlaces(AnyStepHandling, double*, unsigned*) const;
+
// Raw pointer because the HTMLInputElement object owns this InputType object.
HTMLInputElement* m_element;
};