2010-10-07 Kent Tamura <tkent@chromium.org>
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Oct 2010 05:47:53 +0000 (05:47 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Oct 2010 05:47:53 +0000 (05:47 +0000)
        Reviewed by Dimitri Glazkov.

        Refactor HTMLInputElement: Move valueAsDate and valueAsNumber implementations
        https://bugs.webkit.org/show_bug.cgi?id=47327

        Move the content of HTMLInputElement::valueAsDate(), setValueAsDate(),
        valueAsNumber(), and setValueAsNumber() to InputType, and move
        serialize() and serializeForDateTimeTypes() too

        * html/BaseDateAndTimeInputType.cpp:
        (WebCore::BaseDateAndTimeInputType::valueAsDate):
        (WebCore::BaseDateAndTimeInputType::setValueAsDate):
        (WebCore::BaseDateAndTimeInputType::valueAsNumber):
        (WebCore::BaseDateAndTimeInputType::setValueAsNumber):
        (WebCore::BaseDateAndTimeInputType::serialize):
        * html/BaseDateAndTimeInputType.h:
        * html/DateInputType.cpp:
        (WebCore::DateInputType::setMillisecondToDateComponents):
        * html/DateInputType.h:
        * html/DateTimeInputType.cpp:
        (WebCore::DateTimeInputType::setMillisecondToDateComponents):
        * html/DateTimeInputType.h:
        * html/DateTimeLocalInputType.cpp:
        (WebCore::DateTimeLocalInputType::valueAsDate):
        (WebCore::DateTimeLocalInputType::setValueAsDate):
        (WebCore::DateTimeLocalInputType::setMillisecondToDateComponents):
        * html/DateTimeLocalInputType.h:
        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::valueAsDate):
        (WebCore::HTMLInputElement::setValueAsDate):
        (WebCore::HTMLInputElement::valueAsNumber):
        (WebCore::HTMLInputElement::setValueAsNumber):
        (WebCore::HTMLInputElement::stepUpFromRenderer):
        * html/HTMLInputElement.h:
        * html/InputType.cpp:
        (WebCore::InputType::valueAsDate):
        (WebCore::InputType::setValueAsDate):
        (WebCore::InputType::valueAsNumber):
        (WebCore::InputType::setValueAsNumber):
        (WebCore::InputType::serialize):
        * html/InputType.h:
        * html/MonthInputType.cpp:
        (WebCore::MonthInputType::valueAsDate):
        (WebCore::MonthInputType::setValueAsDate):
        (WebCore::MonthInputType::setMillisecondToDateComponents):
        * html/MonthInputType.h:
        * html/NumberInputType.cpp:
        (WebCore::NumberInputType::valueAsNumber):
        (WebCore::NumberInputType::setValueAsNumber):
        (WebCore::NumberInputType::serialize):
        * html/NumberInputType.h:
        * html/RangeInputType.cpp:
        (WebCore::RangeInputType::valueAsNumber):
        (WebCore::RangeInputType::setValueAsNumber):
        (WebCore::RangeInputType::serialize):
        * html/RangeInputType.h:
        * html/TimeInputType.cpp:
        (WebCore::TimeInputType::setMillisecondToDateComponents):
        * html/TimeInputType.h:
        * html/WeekInputType.cpp:
        (WebCore::WeekInputType::setMillisecondToDateComponents):
        * html/WeekInputType.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69378 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
WebCore/ChangeLog
WebCore/html/BaseDateAndTimeInputType.cpp
WebCore/html/BaseDateAndTimeInputType.h
WebCore/html/DateInputType.cpp
WebCore/html/DateInputType.h
WebCore/html/DateTimeInputType.cpp
WebCore/html/DateTimeInputType.h
WebCore/html/DateTimeLocalInputType.cpp
WebCore/html/DateTimeLocalInputType.h
WebCore/html/HTMLInputElement.cpp
WebCore/html/HTMLInputElement.h
WebCore/html/InputType.cpp
WebCore/html/InputType.h
WebCore/html/MonthInputType.cpp
WebCore/html/MonthInputType.h
WebCore/html/NumberInputType.cpp
WebCore/html/NumberInputType.h
WebCore/html/RangeInputType.cpp
WebCore/html/RangeInputType.h
WebCore/html/TimeInputType.cpp
WebCore/html/TimeInputType.h
WebCore/html/WeekInputType.cpp
WebCore/html/WeekInputType.h

index 2d23498..42bfcf4 100644 (file)
@@ -1,3 +1,68 @@
+2010-10-07  Kent Tamura  <tkent@chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Refactor HTMLInputElement: Move valueAsDate and valueAsNumber implementations
+        https://bugs.webkit.org/show_bug.cgi?id=47327
+
+        Move the content of HTMLInputElement::valueAsDate(), setValueAsDate(),
+        valueAsNumber(), and setValueAsNumber() to InputType, and move
+        serialize() and serializeForDateTimeTypes() too
+
+        * html/BaseDateAndTimeInputType.cpp:
+        (WebCore::BaseDateAndTimeInputType::valueAsDate):
+        (WebCore::BaseDateAndTimeInputType::setValueAsDate):
+        (WebCore::BaseDateAndTimeInputType::valueAsNumber):
+        (WebCore::BaseDateAndTimeInputType::setValueAsNumber):
+        (WebCore::BaseDateAndTimeInputType::serialize):
+        * html/BaseDateAndTimeInputType.h:
+        * html/DateInputType.cpp:
+        (WebCore::DateInputType::setMillisecondToDateComponents):
+        * html/DateInputType.h:
+        * html/DateTimeInputType.cpp:
+        (WebCore::DateTimeInputType::setMillisecondToDateComponents):
+        * html/DateTimeInputType.h:
+        * html/DateTimeLocalInputType.cpp:
+        (WebCore::DateTimeLocalInputType::valueAsDate):
+        (WebCore::DateTimeLocalInputType::setValueAsDate):
+        (WebCore::DateTimeLocalInputType::setMillisecondToDateComponents):
+        * html/DateTimeLocalInputType.h:
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::valueAsDate):
+        (WebCore::HTMLInputElement::setValueAsDate):
+        (WebCore::HTMLInputElement::valueAsNumber):
+        (WebCore::HTMLInputElement::setValueAsNumber):
+        (WebCore::HTMLInputElement::stepUpFromRenderer):
+        * html/HTMLInputElement.h:
+        * html/InputType.cpp:
+        (WebCore::InputType::valueAsDate):
+        (WebCore::InputType::setValueAsDate):
+        (WebCore::InputType::valueAsNumber):
+        (WebCore::InputType::setValueAsNumber):
+        (WebCore::InputType::serialize):
+        * html/InputType.h:
+        * html/MonthInputType.cpp:
+        (WebCore::MonthInputType::valueAsDate):
+        (WebCore::MonthInputType::setValueAsDate):
+        (WebCore::MonthInputType::setMillisecondToDateComponents):
+        * html/MonthInputType.h:
+        * html/NumberInputType.cpp:
+        (WebCore::NumberInputType::valueAsNumber):
+        (WebCore::NumberInputType::setValueAsNumber):
+        (WebCore::NumberInputType::serialize):
+        * html/NumberInputType.h:
+        * html/RangeInputType.cpp:
+        (WebCore::RangeInputType::valueAsNumber):
+        (WebCore::RangeInputType::setValueAsNumber):
+        (WebCore::RangeInputType::serialize):
+        * html/RangeInputType.h:
+        * html/TimeInputType.cpp:
+        (WebCore::TimeInputType::setMillisecondToDateComponents):
+        * html/TimeInputType.h:
+        * html/WeekInputType.cpp:
+        (WebCore::WeekInputType::setMillisecondToDateComponents):
+        * html/WeekInputType.h:
+
 2010-10-07  No'am Rosenthal  <noam.rosenthal@nokia.com>
 
         Reviewed by Kenneth Rohde Christiansen.
index 28dbbf0..5b91b01 100644 (file)
@@ -44,6 +44,29 @@ namespace WebCore {
 using namespace HTMLNames;
 using namespace std;
 
+static const double msecPerMinute = 60 * 1000;
+static const double msecPerSecond = 1000;
+
+double BaseDateAndTimeInputType::valueAsDate() const
+{
+    return parseToDouble(element()->value(), DateComponents::invalidMilliseconds());
+}
+
+void BaseDateAndTimeInputType::setValueAsDate(double value, ExceptionCode&) const
+{
+    element()->setValue(serialize(value));
+}
+
+double BaseDateAndTimeInputType::valueAsNumber() const
+{
+    return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+}
+
+void BaseDateAndTimeInputType::setValueAsNumber(double newValue, ExceptionCode&) const
+{
+    element()->setValue(serialize(newValue));
+}
+
 bool BaseDateAndTimeInputType::rangeUnderflow(const String& value) const
 {
     const double nan = numeric_limits<double>::quiet_NaN();
@@ -95,4 +118,21 @@ bool BaseDateAndTimeInputType::parseToDateComponents(const String& source, DateC
     return parseToDateComponentsInternal(source.characters(), source.length(), out);
 }
 
+String BaseDateAndTimeInputType::serialize(double value) const
+{
+    if (!isfinite(value))
+        return String();
+    DateComponents date;
+    if (!setMillisecondToDateComponents(value, &date))
+        return String();
+    double step;
+    if (!element()->getAllowedValueStep(&step))
+        return date.toString();
+    if (!fmod(step, msecPerMinute))
+        return date.toString(DateComponents::None);
+    if (!fmod(step, msecPerSecond))
+        return date.toString(DateComponents::Second);
+    return date.toString(DateComponents::Millisecond);
+}
+
 } // namespace WebCore
index 45b1edf..2214737 100644 (file)
@@ -44,12 +44,18 @@ protected:
     virtual bool parseToDateComponents(const String&, DateComponents*) const;
     // A helper for parseToDateComponents().
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const = 0;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const = 0;
 
 private:
+    virtual double valueAsDate() const;
+    virtual void setValueAsDate(double, ExceptionCode&) const;
+    virtual double valueAsNumber() const;
+    virtual void setValueAsNumber(double, ExceptionCode&) const;
     virtual bool rangeUnderflow(const String&) const;
     virtual bool rangeOverflow(const String&) const;
     virtual bool stepMismatch(const String&, double) const;
     virtual double stepBase() const;
+    virtual String serialize(double) const;
 };
 
 } // namespace WebCore
index 022b2e8..3409d3b 100644 (file)
@@ -85,4 +85,10 @@ bool DateInputType::parseToDateComponentsInternal(const UChar* characters, unsig
     return out->parseDate(characters, length, 0, end) && end == length;
 }
 
+bool DateInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+    ASSERT(date);
+    return date->setMillisecondsSinceEpochForDate(value);
+}
+
 } // namespace WebCore
index 58a078f..965d9ea 100644 (file)
@@ -48,6 +48,7 @@ private:
     virtual double stepScaleFactor() const;
     virtual bool parsedStepValueShouldBeInteger() const;
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
 };
 
 } // namespace WebCore
index 8b19076..c78a540 100644 (file)
@@ -85,4 +85,10 @@ bool DateTimeInputType::parseToDateComponentsInternal(const UChar* characters, u
     return out->parseDateTime(characters, length, 0, end) && end == length;
 }
 
+bool DateTimeInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+    ASSERT(date);
+    return date->setMillisecondsSinceEpochForDateTime(value);
+}
+
 } // namespace WebCore
index ef71f56..140975b 100644 (file)
@@ -48,6 +48,7 @@ private:
     virtual double stepScaleFactor() const;
     virtual bool scaledStepValeuShouldBeInteger() const;
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
 };
 
 } // namespace WebCore
index bf8f840..1ec2a47 100644 (file)
@@ -53,6 +53,18 @@ const AtomicString& DateTimeLocalInputType::formControlType() const
     return InputTypeNames::datetimelocal();
 }
 
+double DateTimeLocalInputType::valueAsDate() const
+{
+    // valueAsDate doesn't work for the datetime-local type according to the standard.
+    return DateComponents::invalidMilliseconds();
+}
+
+void DateTimeLocalInputType::setValueAsDate(double value, ExceptionCode& ec) const
+{
+    // valueAsDate doesn't work for the datetime-local type according to the standard.
+    InputType::setValueAsDate(value, ec);
+}
+
 double DateTimeLocalInputType::minimum() const
 {
     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
@@ -85,4 +97,10 @@ bool DateTimeLocalInputType::parseToDateComponentsInternal(const UChar* characte
     return out->parseDateTimeLocal(characters, length, 0, end) && end == length;
 }
 
+bool DateTimeLocalInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+    ASSERT(date);
+    return date->setMillisecondsSinceEpochForDateTimeLocal(value);
+}
+
 } // namespace WebCore
index 40d2e04..966e294 100644 (file)
@@ -42,12 +42,15 @@ public:
 private:
     DateTimeLocalInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
     virtual const AtomicString& formControlType() const;
+    virtual double valueAsDate() const;
+    virtual void setValueAsDate(double, ExceptionCode&) const;
     virtual double minimum() const;
     virtual double maximum() const;
     virtual double defaultStep() const;
     virtual double stepScaleFactor() const;
     virtual bool scaledStepValeuShouldBeInteger() const;
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
 };
 
 } // namespace WebCore
index 0d41821..4d5cd64 100644 (file)
@@ -82,9 +82,6 @@ using namespace HTMLNames;
 
 const int maxSavedResults = 256;
 
-static const double msecPerMinute = 60 * 1000;
-static const double msecPerSecond = 1000;
-
 static const char emailPattern[] =
     "[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part
     "@"
@@ -1337,123 +1334,17 @@ void HTMLInputElement::setValue(const String& value, bool sendChangeEvent)
 
 double HTMLInputElement::valueAsDate() const
 {
-    switch (deprecatedInputType()) {
-    case DATE:
-    case DATETIME:
-    case TIME:
-    case WEEK:
-        return m_inputType->parseToDouble(value(), DateComponents::invalidMilliseconds());
-    case MONTH: {
-        DateComponents date;
-        if (!m_inputType->parseToDateComponents(value(), &date))
-            return DateComponents::invalidMilliseconds();
-        double msec = date.millisecondsSinceEpoch();
-        ASSERT(isfinite(msec));
-        return msec;
-    }
-
-    case BUTTON:
-    case CHECKBOX:
-    case COLOR:
-    case DATETIMELOCAL: // valueAsDate doesn't work for the DATETIMELOCAL type according to the standard.
-    case EMAIL:
-    case FILE:
-    case HIDDEN:
-    case IMAGE:
-    case ISINDEX:
-    case NUMBER:
-    case PASSWORD:
-    case RADIO:
-    case RANGE:
-    case RESET:
-    case SEARCH:
-    case SUBMIT:
-    case TELEPHONE:
-    case TEXT:
-    case URL:
-        return DateComponents::invalidMilliseconds();
-    }
-    ASSERT_NOT_REACHED();
-    return DateComponents::invalidMilliseconds();
+    return m_inputType->valueAsDate();
 }
 
 void HTMLInputElement::setValueAsDate(double value, ExceptionCode& ec)
 {
-    switch (deprecatedInputType()) {
-    case DATE:
-    case DATETIME:
-    case TIME:
-    case WEEK:
-        setValue(serializeForDateTimeTypes(value));
-        return;
-    case MONTH: {
-        DateComponents date;
-        if (!date.setMillisecondsSinceEpochForMonth(value)) {
-            setValue(String());
-            return;
-        }
-        setValue(date.toString());
-        return;
-    }
-    case BUTTON:
-    case CHECKBOX:
-    case COLOR:
-    case DATETIMELOCAL: // valueAsDate doesn't work for the DATETIMELOCAL type according to the standard.
-    case EMAIL:
-    case FILE:
-    case HIDDEN:
-    case IMAGE:
-    case ISINDEX:
-    case NUMBER:
-    case PASSWORD:
-    case RADIO:
-    case RANGE:
-    case RESET:
-    case SEARCH:
-    case SUBMIT:
-    case TELEPHONE:
-    case TEXT:
-    case URL:
-        ec = INVALID_STATE_ERR;
-        return;
-    }
-    ASSERT_NOT_REACHED();
+    m_inputType->setValueAsDate(value, ec);
 }
 
 double HTMLInputElement::valueAsNumber() const
 {
-    const double nan = numeric_limits<double>::quiet_NaN();
-    switch (deprecatedInputType()) {
-    case DATE:
-    case DATETIME:
-    case DATETIMELOCAL:
-    case MONTH:
-    case NUMBER:
-    case RANGE:
-    case TIME:
-    case WEEK:
-        return m_inputType->parseToDouble(value(), nan);
-
-    case BUTTON:
-    case CHECKBOX:
-    case COLOR:
-    case EMAIL:
-    case FILE:
-    case HIDDEN:
-    case IMAGE:
-    case ISINDEX:
-    case PASSWORD:
-    case RADIO:
-    case RESET:
-    case SEARCH:
-    case SUBMIT:
-    case TELEPHONE:
-    case TEXT:
-    case URL:
-        return nan;
-    }
-    ASSERT_NOT_REACHED();
-    return nan;
+    return m_inputType->valueAsNumber();
 }
 
 void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
@@ -1462,133 +1353,7 @@ void HTMLInputElement::setValueAsNumber(double newValue, ExceptionCode& ec)
         ec = NOT_SUPPORTED_ERR;
         return;
     }
-    switch (deprecatedInputType()) {
-    case DATE:
-    case DATETIME:
-    case DATETIMELOCAL:
-    case MONTH:
-    case NUMBER:
-    case RANGE:
-    case TIME:
-    case WEEK:
-        setValue(serialize(newValue));
-        return;
-
-    case BUTTON:
-    case CHECKBOX:
-    case COLOR:
-    case EMAIL:
-    case FILE:
-    case HIDDEN:
-    case IMAGE:
-    case ISINDEX:
-    case PASSWORD:
-    case RADIO:
-    case RESET:
-    case SEARCH:
-    case SUBMIT:
-    case TELEPHONE:
-    case TEXT:
-    case URL:
-        ec = INVALID_STATE_ERR;
-        return;
-    }
-    ASSERT_NOT_REACHED();
-}
-
-String HTMLInputElement::serializeForDateTimeTypes(double value) const
-{
-    bool success = false;
-    DateComponents date;
-    switch (deprecatedInputType()) {
-    case DATE:
-        success = date.setMillisecondsSinceEpochForDate(value);
-        break;
-    case DATETIME:
-        success = date.setMillisecondsSinceEpochForDateTime(value);
-        break;
-    case DATETIMELOCAL:
-        success = date.setMillisecondsSinceEpochForDateTimeLocal(value);
-        break;
-    case MONTH:
-        success = date.setMonthsSinceEpoch(value);
-        break;
-    case TIME:
-        success = date.setMillisecondsSinceMidnight(value);
-        break;
-    case WEEK:
-        success = date.setMillisecondsSinceEpochForWeek(value);
-        break;
-    case NUMBER:
-    case RANGE:
-    case BUTTON:
-    case CHECKBOX:
-    case COLOR:
-    case EMAIL:
-    case FILE:
-    case HIDDEN:
-    case IMAGE:
-    case ISINDEX:
-    case PASSWORD:
-    case RADIO:
-    case RESET:
-    case SEARCH:
-    case SUBMIT:
-    case TELEPHONE:
-    case TEXT:
-    case URL:
-        ASSERT_NOT_REACHED();
-        return String();
-    }
-    if (!success)
-        return String();
-
-    double step;
-    if (!getAllowedValueStep(&step))
-        return date.toString();
-    if (!fmod(step, msecPerMinute))
-        return date.toString(DateComponents::None);
-    if (!fmod(step, msecPerSecond))
-        return date.toString(DateComponents::Second);
-    return date.toString(DateComponents::Millisecond);
-}
-
-String HTMLInputElement::serialize(double value) const
-{
-    if (!isfinite(value))
-        return String();
-    switch (deprecatedInputType()) {
-    case DATE:
-    case DATETIME:
-    case DATETIMELOCAL:
-    case MONTH:
-    case TIME:
-    case WEEK:
-        return serializeForDateTimeTypes(value);
-    case NUMBER:
-    case RANGE:
-        return serializeForNumberType(value);
-
-    case BUTTON:
-    case CHECKBOX:
-    case COLOR:
-    case EMAIL:
-    case FILE:
-    case HIDDEN:
-    case IMAGE:
-    case ISINDEX:
-    case PASSWORD:
-    case RADIO:
-    case RESET:
-    case SEARCH:
-    case SUBMIT:
-    case TELEPHONE:
-    case TEXT:
-    case URL:
-        break;
-    }
-    ASSERT_NOT_REACHED();
-    return String();
+    m_inputType->setValueAsNumber(newValue, ec);
 }
 
 String HTMLInputElement::placeholder() const
@@ -2525,7 +2290,7 @@ void HTMLInputElement::stepUpFromRenderer(int n)
     String currentStringValue = value();
     double current = m_inputType->parseToDouble(currentStringValue, nan);
     if (!isfinite(current) || (n > 0 && current < m_inputType->minimum()) || (n < 0 && current > m_inputType->maximum()))
-        setValue(serialize(n > 0 ? m_inputType->minimum() : m_inputType->maximum()));
+        setValue(m_inputType->serialize(n > 0 ? m_inputType->minimum() : m_inputType->maximum()));
     else {
         ExceptionCode ec;
         stepUp(n, ec);
index 21f4f0a..e4e0340 100644 (file)
@@ -329,15 +329,6 @@ private:
     // Helper for stepUp()/stepDown().  Adds step value * count to the current value.
     void applyStep(double count, ExceptionCode&);
 
-    // Create a string representation of the specified double value for the
-    // current input type. If NaN or Infinity is specified, this returns an
-    // emtpy string. This should not be called for types without valueAsNumber.
-    String serialize(double) const;
-    // Create a string representation of the specified double value for the
-    // current input type. The type must be one of DATE, DATETIME,
-    // DATETIMELOCAL, MONTH, TIME, and WEEK.
-    String serializeForDateTimeTypes(double) const;
-
 #if ENABLE(DATALIST)
     HTMLDataListElement* dataList() const;
 #endif
index ca58736..0619a15 100644 (file)
@@ -30,6 +30,7 @@
 #include "ButtonInputType.h"
 #include "CheckboxInputType.h"
 #include "ColorInputType.h"
+#include "DateComponents.h"
 #include "DateInputType.h"
 #include "DateTimeInputType.h"
 #include "DateTimeLocalInputType.h"
@@ -121,6 +122,26 @@ bool InputType::isTextType() const
     return false;
 }
 
+double InputType::valueAsDate() const
+{
+    return DateComponents::invalidMilliseconds();
+}
+
+void InputType::setValueAsDate(double, ExceptionCode& ec) const
+{
+    ec = INVALID_STATE_ERR;
+}
+
+double InputType::valueAsNumber() const
+{
+    return numeric_limits<double>::quiet_NaN();
+}
+
+void InputType::setValueAsNumber(double, ExceptionCode& ec) const
+{
+    ec = INVALID_STATE_ERR;
+}
+
 bool InputType::patternMismatch(const String&) const
 {
     return false;
@@ -192,6 +213,12 @@ bool InputType::parseToDateComponents(const String&, DateComponents*) const
     return false;
 }
 
+String InputType::serialize(double) const
+{
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
 
 namespace InputTypeNames {
 
index 22f3210..49b2ad0 100644 (file)
@@ -31,6 +31,7 @@
 #ifndef InputType_h
 #define InputType_h
 
+#include "ExceptionCode.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 
@@ -49,6 +50,11 @@ public:
     virtual bool isTextType() const;
     virtual const AtomicString& formControlType() const = 0;
 
+    virtual double valueAsDate() const;
+    virtual void setValueAsDate(double, ExceptionCode&) const;
+    virtual double valueAsNumber() const;
+    virtual void setValueAsNumber(double, ExceptionCode&) const;
+
     // Validation-related functions
 
     virtual bool patternMismatch(const String&) const;
@@ -73,6 +79,10 @@ public:
     // parameter will have parsed values and be modified even if the parsing
     // fails. The DateComponents* parameter may be 0.
     virtual bool parseToDateComponents(const String&, DateComponents*) const;
+    // Create a string representation of the specified double value for the
+    // input type. If NaN or Infinity is specified, this returns an empty
+    // string. This should not be called for types without valueAsNumber.
+    virtual String serialize(double) const;
 
 protected:
     InputType(HTMLInputElement* element) : m_element(element) { }
index e4970e0..cbde5cb 100644 (file)
@@ -54,6 +54,26 @@ const AtomicString& MonthInputType::formControlType() const
     return InputTypeNames::month();
 }
 
+double MonthInputType::valueAsDate() const
+{
+    DateComponents date;
+    if (!parseToDateComponents(element()->value(), &date))
+        return DateComponents::invalidMilliseconds();
+    double msec = date.millisecondsSinceEpoch();
+    ASSERT(isfinite(msec));
+    return msec;
+}
+
+void MonthInputType::setValueAsDate(double value, ExceptionCode&) const
+{
+    DateComponents date;
+    if (!date.setMillisecondsSinceEpochForMonth(value)) {
+        element()->setValue(String());
+        return;
+    }
+    element()->setValue(date.toString());
+}
+
 double MonthInputType::minimum() const
 {
     return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth());
@@ -96,4 +116,10 @@ bool MonthInputType::parseToDateComponentsInternal(const UChar* characters, unsi
     return out->parseMonth(characters, length, 0, end) && end == length;
 }
 
+bool MonthInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+    ASSERT(date);
+    return date->setMonthsSinceEpoch(value);
+}
+
 } // namespace WebCore
index d3e2ba1..50cf7d5 100644 (file)
@@ -42,6 +42,8 @@ public:
 private:
     MonthInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
     virtual const AtomicString& formControlType() const;
+    virtual double valueAsDate() const;
+    virtual void setValueAsDate(double, ExceptionCode&) const;
     virtual double parseToDouble(const String&, double) const;
     virtual double minimum() const;
     virtual double maximum() const;
@@ -49,6 +51,7 @@ private:
     virtual double stepScaleFactor() const;
     virtual bool parsedStepValueShouldBeInteger() const;
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
 };
 
 } // namespace WebCore
index 2f43ce9..4beda5a 100644 (file)
@@ -62,6 +62,16 @@ const AtomicString& NumberInputType::formControlType() const
     return InputTypeNames::number();
 }
 
+double NumberInputType::valueAsNumber() const
+{
+    return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+}
+
+void NumberInputType::setValueAsNumber(double newValue, ExceptionCode&) const
+{
+    element()->setValue(serialize(newValue));
+}
+
 bool NumberInputType::rangeUnderflow(const String& value) const
 {
     const double nan = numeric_limits<double>::quiet_NaN();
@@ -128,4 +138,11 @@ double NumberInputType::parseToDouble(const String& src, double defaultValue) co
     return numberValue;
 }
 
+String NumberInputType::serialize(double value) const
+{
+    if (!isfinite(value))
+        return String();
+    return serializeForNumberType(value);
+}
+
 } // namespace WebCore
index 0e82937..49e5e7c 100644 (file)
@@ -42,6 +42,8 @@ public:
 private:
     NumberInputType(HTMLInputElement* element) : TextFieldInputType(element) { }
     virtual const AtomicString& formControlType() const;
+    virtual double valueAsNumber() const;
+    virtual void setValueAsNumber(double, ExceptionCode&) const;
     virtual bool rangeUnderflow(const String&) const;
     virtual bool rangeOverflow(const String&) const;
     virtual double minimum() const;
@@ -51,6 +53,7 @@ private:
     virtual double defaultStep() const;
     virtual double stepScaleFactor() const;
     virtual double parseToDouble(const String&, double) const;
+    virtual String serialize(double) const;
 };
 
 } // namespace WebCore
index a73ca30..aa359cf 100644 (file)
@@ -58,6 +58,16 @@ const AtomicString& RangeInputType::formControlType() const
     return InputTypeNames::range();
 }
 
+double RangeInputType::valueAsNumber() const
+{
+    return parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
+}
+
+void RangeInputType::setValueAsNumber(double newValue, ExceptionCode&) const
+{
+    element()->setValue(serialize(newValue));
+}
+
 bool RangeInputType::rangeUnderflow(const String& value) const
 {
     // Guaranteed by sanitization.
@@ -120,4 +130,11 @@ double RangeInputType::parseToDouble(const String& src, double defaultValue) con
     return numberValue;
 }
 
+String RangeInputType::serialize(double value) const
+{
+    if (!isfinite(value))
+        return String();
+    return serializeForNumberType(value);
+}
+
 } // namespace WebCore
index 17d6334..00826af 100644 (file)
@@ -42,6 +42,8 @@ public:
 private:
     RangeInputType(HTMLInputElement* element) : InputType(element) { }
     virtual const AtomicString& formControlType() const;
+    virtual double valueAsNumber() const;
+    virtual void setValueAsNumber(double, ExceptionCode&) const;
     virtual bool rangeUnderflow(const String&) const;
     virtual bool rangeOverflow(const String&) const;
     virtual double minimum() const;
@@ -51,6 +53,7 @@ private:
     virtual double defaultStep() const;
     virtual double stepScaleFactor() const;
     virtual double parseToDouble(const String&, double) const;
+    virtual String serialize(double) const;
 };
 
 } // namespace WebCore
index 74b13cc..27dce90 100644 (file)
@@ -85,4 +85,10 @@ bool TimeInputType::parseToDateComponentsInternal(const UChar* characters, unsig
     return out->parseTime(characters, length, 0, end) && end == length;
 }
 
+bool TimeInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+    ASSERT(date);
+    return date->setMillisecondsSinceMidnight(value);
+}
+
 } // namespace WebCore
index 9e751ab..6070fa0 100644 (file)
@@ -48,6 +48,7 @@ private:
     virtual double stepScaleFactor() const;
     virtual bool scaledStepValeuShouldBeInteger() const;
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
 };
 
 } // namespace WebCore
index 947e631..a5836dc 100644 (file)
@@ -91,4 +91,10 @@ bool WeekInputType::parseToDateComponentsInternal(const UChar* characters, unsig
     return out->parseWeek(characters, length, 0, end) && end == length;
 }
 
+bool WeekInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
+{
+    ASSERT(date);
+    return date->setMillisecondsSinceEpochForWeek(value);
+}
+
 } // namespace WebCore
index 4aed6dd..437164b 100644 (file)
@@ -49,6 +49,7 @@ private:
     virtual double stepScaleFactor() const;
     virtual bool parsedStepValueShouldBeInteger() const;
     virtual bool parseToDateComponentsInternal(const UChar*, unsigned length, DateComponents*) const;
+    virtual bool setMillisecondToDateComponents(double, DateComponents*) const;
 };
 
 } // namespace WebCore