LegacyNumberInputType.cpp [plain text]
#include "config.h"
#include "LegacyNumberInputType.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "KeyboardEvent.h"
#include "LocalizedNumber.h"
#include "RenderTextControl.h"
#include <limits>
#include <wtf/PassOwnPtr.h>
namespace WebCore {
using namespace HTMLNames;
using namespace std;
static const double numberDefaultStep = 1.0;
static const double numberStepScaleFactor = 1.0;
PassOwnPtr<InputType> LegacyNumberInputType::create(HTMLInputElement* element)
{
return adoptPtr(new LegacyNumberInputType(element));
}
const AtomicString& LegacyNumberInputType::formControlType() const
{
return InputTypeNames::number();
}
bool LegacyNumberInputType::shouldRespectSpeechAttribute()
{
return true;
}
double LegacyNumberInputType::valueAsNumber() const
{
return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
}
void LegacyNumberInputType::setValueAsNumber(double newValue, ExceptionCode& ec) const
{
if (newValue < -numeric_limits<float>::max()) {
ec = INVALID_STATE_ERR;
return;
}
if (newValue > numeric_limits<float>::max()) {
ec = INVALID_STATE_ERR;
return;
}
element()->setValue(serialize(newValue));
}
bool LegacyNumberInputType::rangeUnderflow(const String& value) const
{
const double nan = numeric_limits<double>::quiet_NaN();
double doubleValue = parseToDouble(value, nan);
return isfinite(doubleValue) && doubleValue < minimum();
}
bool LegacyNumberInputType::rangeOverflow(const String& value) const
{
const double nan = numeric_limits<double>::quiet_NaN();
double doubleValue = parseToDouble(value, nan);
return isfinite(doubleValue) && doubleValue > maximum();
}
bool LegacyNumberInputType::supportsRangeLimitation() const
{
return false;
}
double LegacyNumberInputType::minimum() const
{
return parseToDouble(element()->fastGetAttribute(minAttr), -numeric_limits<float>::max());
}
double LegacyNumberInputType::maximum() const
{
return parseToDouble(element()->fastGetAttribute(maxAttr), numeric_limits<float>::max());
}
bool LegacyNumberInputType::isSteppable() const
{
return true;
}
bool LegacyNumberInputType::stepMismatch(const String& value, double step) const
{
double doubleValue;
if (!parseToDoubleForNumberType(value, &doubleValue))
return false;
doubleValue = fabs(doubleValue - stepBase());
if (isinf(doubleValue))
return false;
if (doubleValue / pow(2.0, DBL_MANT_DIG) > step)
return false;
double remainder = fabs(doubleValue - step * round(doubleValue / step));
double computedAcceptableError = acceptableError(step);
return computedAcceptableError < remainder && remainder < (step - computedAcceptableError);
}
double LegacyNumberInputType::stepBase() const
{
return parseToDouble(element()->fastGetAttribute(minAttr), defaultStepBase());
}
double LegacyNumberInputType::stepBaseWithDecimalPlaces(unsigned* decimalPlaces) const
{
return parseToDoubleWithDecimalPlaces(element()->fastGetAttribute(minAttr), defaultStepBase(), decimalPlaces);
}
double LegacyNumberInputType::defaultStep() const
{
return numberDefaultStep;
}
double LegacyNumberInputType::stepScaleFactor() const
{
return numberStepScaleFactor;
}
void LegacyNumberInputType::handleKeydownEvent(KeyboardEvent* event)
{
handleKeydownEventForSpinButton(event);
if (!event->defaultHandled())
TextFieldInputType::handleKeydownEvent(event);
}
void LegacyNumberInputType::handleWheelEvent(WheelEvent* event)
{
handleWheelEventForSpinButton(event);
}
double LegacyNumberInputType::parseToDouble(const String& src, double defaultValue) const
{
double numberValue;
if (!parseToDoubleForNumberType(src, &numberValue))
return defaultValue;
ASSERT(isfinite(numberValue));
return numberValue;
}
double LegacyNumberInputType::parseToDoubleWithDecimalPlaces(const String& src, double defaultValue, unsigned *decimalPlaces) const
{
double numberValue;
if (!parseToDoubleForNumberTypeWithDecimalPlaces(src, &numberValue, decimalPlaces))
return defaultValue;
ASSERT(isfinite(numberValue));
return numberValue;
}
String LegacyNumberInputType::serialize(double value) const
{
if (!isfinite(value))
return String();
return serializeForNumberType(value);
}
double LegacyNumberInputType::acceptableError(double step) const
{
return step / pow(2.0, FLT_MANT_DIG);
}
void LegacyNumberInputType::handleBlurEvent()
{
element()->setFormControlValueMatchesRenderer(false);
if (element()->renderer())
element()->renderer()->updateFromElement();
}
bool LegacyNumberInputType::isNumberField() const
{
return true;
}
bool LegacyNumberInputType::isTextType() const
{
return true;
}
bool LegacyNumberInputType::supportsPlaceholder() const
{
return true;
}
}