2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
28 #include "core/html/shadow/DateTimeFieldElements.h"
30 #include "core/html/forms/DateTimeFieldsState.h"
31 #include "platform/DateComponents.h"
32 #include "platform/text/PlatformLocale.h"
33 #include "wtf/CurrentTime.h"
34 #include "wtf/DateMath.h"
38 using blink::WebLocalizedString
;
40 static String
queryString(WebLocalizedString::Name name
)
42 return Locale::defaultLocale().queryString(name
);
45 DateTimeAMPMFieldElement::DateTimeAMPMFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Vector
<String
>& ampmLabels
)
46 : DateTimeSymbolicFieldElement(document
, fieldOwner
, ampmLabels
, 0, 1)
50 PassRefPtrWillBeRawPtr
<DateTimeAMPMFieldElement
> DateTimeAMPMFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Vector
<String
>& ampmLabels
)
52 DEFINE_STATIC_LOCAL(AtomicString
, ampmPseudoId
, ("-webkit-datetime-edit-ampm-field", AtomicString::ConstructFromLiteral
));
53 RefPtrWillBeRawPtr
<DateTimeAMPMFieldElement
> field
= adoptRefWillBeNoop(new DateTimeAMPMFieldElement(document
, fieldOwner
, ampmLabels
));
54 field
->initialize(ampmPseudoId
, queryString(WebLocalizedString::AXAMPMFieldText
));
55 return field
.release();
58 void DateTimeAMPMFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
61 dateTimeFieldsState
.setAMPM(valueAsInteger() ? DateTimeFieldsState::AMPMValuePM
: DateTimeFieldsState::AMPMValueAM
);
63 dateTimeFieldsState
.setAMPM(DateTimeFieldsState::AMPMValueEmpty
);
66 void DateTimeAMPMFieldElement::setValueAsDate(const DateComponents
& date
)
68 setValueAsInteger(date
.hour() >= 12 ? 1 : 0);
71 void DateTimeAMPMFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
73 if (dateTimeFieldsState
.hasAMPM())
74 setValueAsInteger(dateTimeFieldsState
.ampm());
79 // ----------------------------
81 DateTimeDayFieldElement::DateTimeDayFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const String
& placeholder
, const Range
& range
)
82 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, Range(1, 31), placeholder
)
86 PassRefPtrWillBeRawPtr
<DateTimeDayFieldElement
> DateTimeDayFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const String
& placeholder
, const Range
& range
)
88 DEFINE_STATIC_LOCAL(AtomicString
, dayPseudoId
, ("-webkit-datetime-edit-day-field", AtomicString::ConstructFromLiteral
));
89 RefPtrWillBeRawPtr
<DateTimeDayFieldElement
> field
= adoptRefWillBeNoop(new DateTimeDayFieldElement(document
, fieldOwner
, placeholder
.isEmpty() ? "--" : placeholder
, range
));
90 field
->initialize(dayPseudoId
, queryString(WebLocalizedString::AXDayOfMonthFieldText
));
91 return field
.release();
94 void DateTimeDayFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
96 dateTimeFieldsState
.setDayOfMonth(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
99 void DateTimeDayFieldElement::setValueAsDate(const DateComponents
& date
)
101 setValueAsInteger(date
.monthDay());
104 void DateTimeDayFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
106 if (!dateTimeFieldsState
.hasDayOfMonth()) {
111 const unsigned value
= dateTimeFieldsState
.dayOfMonth();
112 if (range().isInRange(static_cast<int>(value
))) {
113 setValueAsInteger(value
);
120 // ----------------------------
122 DateTimeHourFieldElementBase::DateTimeHourFieldElementBase(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Range
& hardLimits
, const Step
& step
)
123 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, hardLimits
, "--", step
)
127 void DateTimeHourFieldElementBase::initialize()
129 DEFINE_STATIC_LOCAL(AtomicString
, hourPseudoId
, ("-webkit-datetime-edit-hour-field", AtomicString::ConstructFromLiteral
));
130 DateTimeNumericFieldElement::initialize(hourPseudoId
, queryString(WebLocalizedString::AXHourFieldText
));
133 void DateTimeHourFieldElementBase::setValueAsDate(const DateComponents
& date
)
135 setValueAsInteger(date
.hour());
138 void DateTimeHourFieldElementBase::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
140 if (!dateTimeFieldsState
.hasHour()) {
145 const int hour12
= dateTimeFieldsState
.hour();
146 if (hour12
< 1 || hour12
> 12) {
151 const int hour11
= hour12
== 12 ? 0 : hour12
;
152 const int hour23
= dateTimeFieldsState
.ampm() == DateTimeFieldsState::AMPMValuePM
? hour11
+ 12 : hour11
;
153 setValueAsInteger(hour23
);
155 // ----------------------------
157 DateTimeHour11FieldElement::DateTimeHour11FieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
158 : DateTimeHourFieldElementBase(document
, fieldOwner
, range
, Range(0, 11), step
)
162 PassRefPtrWillBeRawPtr
<DateTimeHour11FieldElement
> DateTimeHour11FieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& hour23Range
, const Step
& step
)
164 ASSERT(hour23Range
.minimum
>= 0);
165 ASSERT(hour23Range
.maximum
<= 23);
166 ASSERT(hour23Range
.minimum
<= hour23Range
.maximum
);
168 if (hour23Range
.maximum
< 12)
170 else if (hour23Range
.minimum
>= 12) {
171 range
.minimum
= hour23Range
.minimum
- 12;
172 range
.maximum
= hour23Range
.maximum
- 12;
175 RefPtrWillBeRawPtr
<DateTimeHour11FieldElement
> field
= adoptRefWillBeNoop(new DateTimeHour11FieldElement(document
, fieldOwner
, range
, step
));
177 return field
.release();
180 void DateTimeHour11FieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
183 dateTimeFieldsState
.setHour(DateTimeFieldsState::emptyValue
);
186 const int value
= valueAsInteger();
187 dateTimeFieldsState
.setHour(value
? value
: 12);
190 void DateTimeHour11FieldElement::setValueAsInteger(int value
, EventBehavior eventBehavior
)
192 value
= Range(0, 23).clampValue(value
) % 12;
193 DateTimeNumericFieldElement::setValueAsInteger(value
, eventBehavior
);
196 // ----------------------------
198 DateTimeHour12FieldElement::DateTimeHour12FieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
199 : DateTimeHourFieldElementBase(document
, fieldOwner
, range
, Range(1, 12), step
)
203 PassRefPtrWillBeRawPtr
<DateTimeHour12FieldElement
> DateTimeHour12FieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& hour23Range
, const Step
& step
)
205 ASSERT(hour23Range
.minimum
>= 0);
206 ASSERT(hour23Range
.maximum
<= 23);
207 ASSERT(hour23Range
.minimum
<= hour23Range
.maximum
);
209 if (hour23Range
.maximum
< 12)
211 else if (hour23Range
.minimum
>= 12) {
212 range
.minimum
= hour23Range
.minimum
- 12;
213 range
.maximum
= hour23Range
.maximum
- 12;
219 if (range
.minimum
> range
.maximum
) {
223 RefPtrWillBeRawPtr
<DateTimeHour12FieldElement
> field
= adoptRefWillBeNoop(new DateTimeHour12FieldElement(document
, fieldOwner
, range
, step
));
225 return field
.release();
228 void DateTimeHour12FieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
230 dateTimeFieldsState
.setHour(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
233 void DateTimeHour12FieldElement::setValueAsInteger(int value
, EventBehavior eventBehavior
)
235 value
= Range(0, 24).clampValue(value
) % 12;
236 DateTimeNumericFieldElement::setValueAsInteger(value
? value
: 12, eventBehavior
);
239 // ----------------------------
241 DateTimeHour23FieldElement::DateTimeHour23FieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
242 : DateTimeHourFieldElementBase(document
, fieldOwner
, range
, Range(0, 23), step
)
246 PassRefPtrWillBeRawPtr
<DateTimeHour23FieldElement
> DateTimeHour23FieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& hour23Range
, const Step
& step
)
248 ASSERT(hour23Range
.minimum
>= 0);
249 ASSERT(hour23Range
.maximum
<= 23);
250 ASSERT(hour23Range
.minimum
<= hour23Range
.maximum
);
251 RefPtrWillBeRawPtr
<DateTimeHour23FieldElement
> field
= adoptRefWillBeNoop(new DateTimeHour23FieldElement(document
, fieldOwner
, hour23Range
, step
));
253 return field
.release();
256 void DateTimeHour23FieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
259 dateTimeFieldsState
.setHour(DateTimeFieldsState::emptyValue
);
263 const int value
= valueAsInteger();
265 dateTimeFieldsState
.setHour(value
% 12 ? value
% 12 : 12);
266 dateTimeFieldsState
.setAMPM(value
>= 12 ? DateTimeFieldsState::AMPMValuePM
: DateTimeFieldsState::AMPMValueAM
);
269 void DateTimeHour23FieldElement::setValueAsInteger(int value
, EventBehavior eventBehavior
)
271 value
= Range(0, 23).clampValue(value
);
272 DateTimeNumericFieldElement::setValueAsInteger(value
, eventBehavior
);
275 // ----------------------------
277 DateTimeHour24FieldElement::DateTimeHour24FieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
278 : DateTimeHourFieldElementBase(document
, fieldOwner
, range
, Range(1, 24), step
)
282 PassRefPtrWillBeRawPtr
<DateTimeHour24FieldElement
> DateTimeHour24FieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& hour23Range
, const Step
& step
)
284 ASSERT(hour23Range
.minimum
>= 0);
285 ASSERT(hour23Range
.maximum
<= 23);
286 ASSERT(hour23Range
.minimum
<= hour23Range
.maximum
);
287 Range
range(hour23Range
.minimum
? hour23Range
.minimum
: 24, hour23Range
.maximum
? hour23Range
.maximum
: 24);
288 if (range
.minimum
> range
.maximum
) {
293 RefPtrWillBeRawPtr
<DateTimeHour24FieldElement
> field
= adoptRefWillBeNoop(new DateTimeHour24FieldElement(document
, fieldOwner
, range
, step
));
295 return field
.release();
298 void DateTimeHour24FieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
301 dateTimeFieldsState
.setHour(DateTimeFieldsState::emptyValue
);
305 const int value
= valueAsInteger();
308 dateTimeFieldsState
.setHour(12);
309 dateTimeFieldsState
.setAMPM(DateTimeFieldsState::AMPMValueAM
);
311 dateTimeFieldsState
.setHour(value
== 12 ? 12 : value
% 12);
312 dateTimeFieldsState
.setAMPM(value
>= 12 ? DateTimeFieldsState::AMPMValuePM
: DateTimeFieldsState::AMPMValueAM
);
316 void DateTimeHour24FieldElement::setValueAsInteger(int value
, EventBehavior eventBehavior
)
318 value
= Range(0, 24).clampValue(value
);
319 DateTimeNumericFieldElement::setValueAsInteger(value
? value
: 24, eventBehavior
);
322 // ----------------------------
324 DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
325 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, Range(0, 999), "---", step
)
329 PassRefPtrWillBeRawPtr
<DateTimeMillisecondFieldElement
> DateTimeMillisecondFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
331 DEFINE_STATIC_LOCAL(AtomicString
, millisecondPseudoId
, ("-webkit-datetime-edit-millisecond-field", AtomicString::ConstructFromLiteral
));
332 RefPtrWillBeRawPtr
<DateTimeMillisecondFieldElement
> field
= adoptRefWillBeNoop(new DateTimeMillisecondFieldElement(document
, fieldOwner
, range
, step
));
333 field
->initialize(millisecondPseudoId
, queryString(WebLocalizedString::AXMillisecondFieldText
));
334 return field
.release();
337 void DateTimeMillisecondFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
339 dateTimeFieldsState
.setMillisecond(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
342 void DateTimeMillisecondFieldElement::setValueAsDate(const DateComponents
& date
)
344 setValueAsInteger(date
.millisecond());
347 void DateTimeMillisecondFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
349 if (!dateTimeFieldsState
.hasMillisecond()) {
354 const unsigned value
= dateTimeFieldsState
.millisecond();
355 if (value
> static_cast<unsigned>(maximum())) {
360 setValueAsInteger(value
);
363 // ----------------------------
365 DateTimeMinuteFieldElement::DateTimeMinuteFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
366 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, Range(0, 59), "--", step
)
370 PassRefPtrWillBeRawPtr
<DateTimeMinuteFieldElement
> DateTimeMinuteFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
372 DEFINE_STATIC_LOCAL(AtomicString
, minutePseudoId
, ("-webkit-datetime-edit-minute-field", AtomicString::ConstructFromLiteral
));
373 RefPtrWillBeRawPtr
<DateTimeMinuteFieldElement
> field
= adoptRefWillBeNoop(new DateTimeMinuteFieldElement(document
, fieldOwner
, range
, step
));
374 field
->initialize(minutePseudoId
, queryString(WebLocalizedString::AXMinuteFieldText
));
375 return field
.release();
378 void DateTimeMinuteFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
380 dateTimeFieldsState
.setMinute(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
383 void DateTimeMinuteFieldElement::setValueAsDate(const DateComponents
& date
)
385 setValueAsInteger(date
.minute());
388 void DateTimeMinuteFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
390 if (!dateTimeFieldsState
.hasMinute()) {
395 const unsigned value
= dateTimeFieldsState
.minute();
396 if (value
> static_cast<unsigned>(maximum())) {
401 setValueAsInteger(value
);
404 // ----------------------------
406 DateTimeMonthFieldElement::DateTimeMonthFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const String
& placeholder
, const Range
& range
)
407 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, Range(1, 12), placeholder
)
411 PassRefPtrWillBeRawPtr
<DateTimeMonthFieldElement
> DateTimeMonthFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const String
& placeholder
, const Range
& range
)
413 DEFINE_STATIC_LOCAL(AtomicString
, monthPseudoId
, ("-webkit-datetime-edit-month-field", AtomicString::ConstructFromLiteral
));
414 RefPtrWillBeRawPtr
<DateTimeMonthFieldElement
> field
= adoptRefWillBeNoop(new DateTimeMonthFieldElement(document
, fieldOwner
, placeholder
.isEmpty() ? "--" : placeholder
, range
));
415 field
->initialize(monthPseudoId
, queryString(WebLocalizedString::AXMonthFieldText
));
416 return field
.release();
419 void DateTimeMonthFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
421 dateTimeFieldsState
.setMonth(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
424 void DateTimeMonthFieldElement::setValueAsDate(const DateComponents
& date
)
426 setValueAsInteger(date
.month() + 1);
429 void DateTimeMonthFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
431 if (!dateTimeFieldsState
.hasMonth()) {
436 const unsigned value
= dateTimeFieldsState
.month();
437 if (range().isInRange(static_cast<int>(value
))) {
438 setValueAsInteger(value
);
445 // ----------------------------
447 DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
448 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, Range(0, 59), "--", step
)
452 PassRefPtrWillBeRawPtr
<DateTimeSecondFieldElement
> DateTimeSecondFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
, const Step
& step
)
454 DEFINE_STATIC_LOCAL(AtomicString
, secondPseudoId
, ("-webkit-datetime-edit-second-field", AtomicString::ConstructFromLiteral
));
455 RefPtrWillBeRawPtr
<DateTimeSecondFieldElement
> field
= adoptRefWillBeNoop(new DateTimeSecondFieldElement(document
, fieldOwner
, range
, step
));
456 field
->initialize(secondPseudoId
, queryString(WebLocalizedString::AXSecondFieldText
));
457 return field
.release();
460 void DateTimeSecondFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
462 dateTimeFieldsState
.setSecond(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
465 void DateTimeSecondFieldElement::setValueAsDate(const DateComponents
& date
)
467 setValueAsInteger(date
.second());
470 void DateTimeSecondFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
472 if (!dateTimeFieldsState
.hasSecond()) {
477 const unsigned value
= dateTimeFieldsState
.second();
478 if (value
> static_cast<unsigned>(maximum())) {
483 setValueAsInteger(value
);
486 // ----------------------------
488 DateTimeSymbolicMonthFieldElement::DateTimeSymbolicMonthFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Vector
<String
>& labels
, int minimum
, int maximum
)
489 : DateTimeSymbolicFieldElement(document
, fieldOwner
, labels
, minimum
, maximum
)
493 PassRefPtrWillBeRawPtr
<DateTimeSymbolicMonthFieldElement
> DateTimeSymbolicMonthFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Vector
<String
>& labels
, int minimum
, int maximum
)
495 DEFINE_STATIC_LOCAL(AtomicString
, monthPseudoId
, ("-webkit-datetime-edit-month-field", AtomicString::ConstructFromLiteral
));
496 RefPtrWillBeRawPtr
<DateTimeSymbolicMonthFieldElement
> field
= adoptRefWillBeNoop(new DateTimeSymbolicMonthFieldElement(document
, fieldOwner
, labels
, minimum
, maximum
));
497 field
->initialize(monthPseudoId
, queryString(WebLocalizedString::AXMonthFieldText
));
498 return field
.release();
501 void DateTimeSymbolicMonthFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
504 dateTimeFieldsState
.setMonth(DateTimeFieldsState::emptyValue
);
505 ASSERT(valueAsInteger() < static_cast<int>(symbolsSize()));
506 dateTimeFieldsState
.setMonth(valueAsInteger() + 1);
509 void DateTimeSymbolicMonthFieldElement::setValueAsDate(const DateComponents
& date
)
511 setValueAsInteger(date
.month());
514 void DateTimeSymbolicMonthFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
516 if (!dateTimeFieldsState
.hasMonth()) {
521 const unsigned value
= dateTimeFieldsState
.month() - 1;
522 if (value
>= symbolsSize()) {
527 setValueAsInteger(value
);
530 // ----------------------------
532 DateTimeWeekFieldElement::DateTimeWeekFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
)
533 : DateTimeNumericFieldElement(document
, fieldOwner
, range
, Range(DateComponents::minimumWeekNumber
, DateComponents::maximumWeekNumber
), "--")
537 PassRefPtrWillBeRawPtr
<DateTimeWeekFieldElement
> DateTimeWeekFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const Range
& range
)
539 DEFINE_STATIC_LOCAL(AtomicString
, weekPseudoId
, ("-webkit-datetime-edit-week-field", AtomicString::ConstructFromLiteral
));
540 RefPtrWillBeRawPtr
<DateTimeWeekFieldElement
> field
= adoptRefWillBeNoop(new DateTimeWeekFieldElement(document
, fieldOwner
, range
));
541 field
->initialize(weekPseudoId
, queryString(WebLocalizedString::AXWeekOfYearFieldText
));
542 return field
.release();
545 void DateTimeWeekFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
547 dateTimeFieldsState
.setWeekOfYear(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
550 void DateTimeWeekFieldElement::setValueAsDate(const DateComponents
& date
)
552 setValueAsInteger(date
.week());
555 void DateTimeWeekFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
557 if (!dateTimeFieldsState
.hasWeekOfYear()) {
562 const unsigned value
= dateTimeFieldsState
.weekOfYear();
563 if (range().isInRange(static_cast<int>(value
))) {
564 setValueAsInteger(value
);
571 // ----------------------------
573 DateTimeYearFieldElement::DateTimeYearFieldElement(Document
& document
, FieldOwner
& fieldOwner
, const DateTimeYearFieldElement::Parameters
& parameters
)
574 : DateTimeNumericFieldElement(document
, fieldOwner
, Range(parameters
.minimumYear
, parameters
.maximumYear
), Range(DateComponents::minimumYear(), DateComponents::maximumYear()), parameters
.placeholder
.isEmpty() ? "----" : parameters
.placeholder
)
575 , m_minIsSpecified(parameters
.minIsSpecified
)
576 , m_maxIsSpecified(parameters
.maxIsSpecified
)
578 ASSERT(parameters
.minimumYear
>= DateComponents::minimumYear());
579 ASSERT(parameters
.maximumYear
<= DateComponents::maximumYear());
582 PassRefPtrWillBeRawPtr
<DateTimeYearFieldElement
> DateTimeYearFieldElement::create(Document
& document
, FieldOwner
& fieldOwner
, const DateTimeYearFieldElement::Parameters
& parameters
)
584 DEFINE_STATIC_LOCAL(AtomicString
, yearPseudoId
, ("-webkit-datetime-edit-year-field", AtomicString::ConstructFromLiteral
));
585 RefPtrWillBeRawPtr
<DateTimeYearFieldElement
> field
= adoptRefWillBeNoop(new DateTimeYearFieldElement(document
, fieldOwner
, parameters
));
586 field
->initialize(yearPseudoId
, queryString(WebLocalizedString::AXYearFieldText
));
587 return field
.release();
590 static int currentFullYear()
593 date
.setMillisecondsSinceEpochForMonth(convertToLocalTime(currentTimeMS()));
594 return date
.fullYear();
597 int DateTimeYearFieldElement::defaultValueForStepDown() const
599 return m_maxIsSpecified
? DateTimeNumericFieldElement::defaultValueForStepDown() : currentFullYear();
602 int DateTimeYearFieldElement::defaultValueForStepUp() const
604 return m_minIsSpecified
? DateTimeNumericFieldElement::defaultValueForStepUp() : currentFullYear();
607 void DateTimeYearFieldElement::populateDateTimeFieldsState(DateTimeFieldsState
& dateTimeFieldsState
)
609 dateTimeFieldsState
.setYear(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue
);
612 void DateTimeYearFieldElement::setValueAsDate(const DateComponents
& date
)
614 setValueAsInteger(date
.fullYear());
617 void DateTimeYearFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState
& dateTimeFieldsState
)
619 if (!dateTimeFieldsState
.hasYear()) {
624 const unsigned value
= dateTimeFieldsState
.year();
625 if (range().isInRange(static_cast<int>(value
))) {
626 setValueAsInteger(value
);