Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / forms / MonthInputType.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "core/html/forms/MonthInputType.h"
33
34 #include "HTMLNames.h"
35 #include "InputTypeNames.h"
36 #include "core/html/HTMLInputElement.h"
37 #include "core/html/forms/DateTimeFieldsState.h"
38 #include "platform/DateComponents.h"
39 #include "platform/text/PlatformLocale.h"
40 #include "wtf/CurrentTime.h"
41 #include "wtf/DateMath.h"
42 #include "wtf/MathExtras.h"
43 #include "wtf/PassOwnPtr.h"
44 #include "wtf/text/WTFString.h"
45
46 namespace WebCore {
47
48 using namespace HTMLNames;
49
50 static const int monthDefaultStep = 1;
51 static const int monthDefaultStepBase = 0;
52 static const int monthStepScaleFactor = 1;
53
54 PassRefPtrWillBeRawPtr<InputType> MonthInputType::create(HTMLInputElement& element)
55 {
56     return adoptRefWillBeNoop(new MonthInputType(element));
57 }
58
59 void MonthInputType::countUsage()
60 {
61     countUsageIfVisible(UseCounter::InputTypeMonth);
62 }
63
64 const AtomicString& MonthInputType::formControlType() const
65 {
66     return InputTypeNames::month;
67 }
68
69 double MonthInputType::valueAsDate() const
70 {
71     DateComponents date;
72     if (!parseToDateComponents(element().value(), &date))
73         return DateComponents::invalidMilliseconds();
74     double msec = date.millisecondsSinceEpoch();
75     ASSERT(std::isfinite(msec));
76     return msec;
77 }
78
79 String MonthInputType::serializeWithMilliseconds(double value) const
80 {
81     DateComponents date;
82     if (!date.setMillisecondsSinceEpochForMonth(value))
83         return String();
84     return serializeWithComponents(date);
85 }
86
87 Decimal MonthInputType::defaultValueForStepUp() const
88 {
89     double current = currentTimeMS();
90     double utcOffset = calculateUTCOffset();
91     double dstOffset = calculateDSTOffset(current, utcOffset);
92     int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
93     current += offset * msPerMinute;
94
95     DateComponents date;
96     date.setMillisecondsSinceEpochForMonth(current);
97     double months = date.monthsSinceEpoch();
98     ASSERT(std::isfinite(months));
99     return Decimal::fromDouble(months);
100 }
101
102 StepRange MonthInputType::createStepRange(AnyStepHandling anyStepHandling) const
103 {
104     DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (monthDefaultStep, monthDefaultStepBase, monthStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
105
106     return InputType::createStepRange(anyStepHandling, Decimal::fromDouble(monthDefaultStepBase), Decimal::fromDouble(DateComponents::minimumMonth()), Decimal::fromDouble(DateComponents::maximumMonth()), stepDescription);
107 }
108
109 Decimal MonthInputType::parseToNumber(const String& src, const Decimal& defaultValue) const
110 {
111     DateComponents date;
112     if (!parseToDateComponents(src, &date))
113         return defaultValue;
114     double months = date.monthsSinceEpoch();
115     ASSERT(std::isfinite(months));
116     return Decimal::fromDouble(months);
117 }
118
119 bool MonthInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
120 {
121     ASSERT(out);
122     unsigned end;
123     return out->parseMonth(string, 0, end) && end == string.length();
124 }
125
126 bool MonthInputType::setMillisecondToDateComponents(double value, DateComponents* date) const
127 {
128     ASSERT(date);
129     return date->setMonthsSinceEpoch(value);
130 }
131
132 bool MonthInputType::isMonthField() const
133 {
134     return true;
135 }
136
137 bool MonthInputType::canSetSuggestedValue()
138 {
139     return true;
140 }
141
142 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
143 String MonthInputType::formatDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState) const
144 {
145     if (!dateTimeFieldsState.hasMonth() || !dateTimeFieldsState.hasYear())
146         return emptyString();
147     return String::format("%04u-%02u", dateTimeFieldsState.year(), dateTimeFieldsState.month());
148 }
149
150 void MonthInputType::setupLayoutParameters(DateTimeEditElement::LayoutParameters& layoutParameters, const DateComponents& date) const
151 {
152     layoutParameters.dateTimeFormat = layoutParameters.locale.monthFormat();
153     layoutParameters.fallbackDateTimeFormat = "yyyy-MM";
154     if (!parseToDateComponents(element().fastGetAttribute(minAttr), &layoutParameters.minimum))
155         layoutParameters.minimum = DateComponents();
156     if (!parseToDateComponents(element().fastGetAttribute(maxAttr), &layoutParameters.maximum))
157         layoutParameters.maximum = DateComponents();
158     layoutParameters.placeholderForMonth = "--";
159     layoutParameters.placeholderForYear = "----";
160 }
161
162 bool MonthInputType::isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const
163 {
164     return hasYear && hasMonth;
165 }
166 #endif
167 } // namespace WebCore