1 /*
2 * Copyright (C) 2012 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 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
33 #include "web/DateTimeChooserImpl.h"
34
35 #include "CalendarPicker.h"
36 #include "PickerCommon.h"
37 #include "core/InputTypeNames.h"
38 #include "core/frame/FrameView.h"
39 #include "core/rendering/RenderTheme.h"
40 #include "platform/DateComponents.h"
41 #include "platform/DateTimeChooserClient.h"
42 #include "platform/Language.h"
43 #include "platform/text/PlatformLocale.h"
44 #include "web/ChromeClientImpl.h"
45 #include "web/WebViewImpl.h"
46
47 using namespace WebCore;
48
49 namespace blink {
50
DateTimeChooserImpl(ChromeClientImpl * chromeClient,WebCore::DateTimeChooserClient * client,const WebCore::DateTimeChooserParameters & parameters)51 DateTimeChooserImpl::DateTimeChooserImpl(ChromeClientImpl* chromeClient, WebCore::DateTimeChooserClient* client, const WebCore::DateTimeChooserParameters& parameters)
52 : m_chromeClient(chromeClient)
53 , m_client(client)
54 , m_popup(0)
55 , m_parameters(parameters)
56 , m_locale(WebCore::Locale::create(parameters.locale))
57 {
58 ASSERT(m_chromeClient);
59 ASSERT(m_client);
60 m_popup = m_chromeClient->openPagePopup(this, m_parameters.anchorRectInRootView);
61 }
62
create(ChromeClientImpl * chromeClient,WebCore::DateTimeChooserClient * client,const WebCore::DateTimeChooserParameters & parameters)63 PassRefPtrWillBeRawPtr<DateTimeChooserImpl> DateTimeChooserImpl::create(ChromeClientImpl* chromeClient, WebCore::DateTimeChooserClient* client, const WebCore::DateTimeChooserParameters& parameters)
64 {
65 return adoptRefWillBeNoop(new DateTimeChooserImpl(chromeClient, client, parameters));
66 }
67
~DateTimeChooserImpl()68 DateTimeChooserImpl::~DateTimeChooserImpl()
69 {
70 }
71
endChooser()72 void DateTimeChooserImpl::endChooser()
73 {
74 if (!m_popup)
75 return;
76 m_chromeClient->closePagePopup(m_popup);
77 }
78
contentSize()79 WebCore::IntSize DateTimeChooserImpl::contentSize()
80 {
81 return WebCore::IntSize(0, 0);
82 }
83
valueToDateTimeString(double value,AtomicString type)84 static String valueToDateTimeString(double value, AtomicString type)
85 {
86 WebCore::DateComponents components;
87 if (type == WebCore::InputTypeNames::date)
88 components.setMillisecondsSinceEpochForDate(value);
89 else if (type == WebCore::InputTypeNames::datetime_local)
90 components.setMillisecondsSinceEpochForDateTimeLocal(value);
91 else if (type == WebCore::InputTypeNames::month)
92 components.setMonthsSinceEpoch(value);
93 else if (type == WebCore::InputTypeNames::time)
94 components.setMillisecondsSinceMidnight(value);
95 else if (type == WebCore::InputTypeNames::week)
96 components.setMillisecondsSinceEpochForWeek(value);
97 else
98 ASSERT_NOT_REACHED();
99 return components.type() == WebCore::DateComponents::Invalid ? String() : components.toString();
100 }
101
writeDocument(WebCore::SharedBuffer * data)102 void DateTimeChooserImpl::writeDocument(WebCore::SharedBuffer* data)
103 {
104 String stepString = String::number(m_parameters.step);
105 String stepBaseString = String::number(m_parameters.stepBase, 11, WTF::TruncateTrailingZeros);
106 IntRect anchorRectInScreen = m_chromeClient->rootViewToScreen(m_parameters.anchorRectInRootView);
107 String todayLabelString;
108 String otherDateLabelString;
109 if (m_parameters.type == WebCore::InputTypeNames::month) {
110 todayLabelString = locale().queryString(WebLocalizedString::ThisMonthButtonLabel);
111 otherDateLabelString = locale().queryString(WebLocalizedString::OtherMonthLabel);
112 } else if (m_parameters.type == WebCore::InputTypeNames::week) {
113 todayLabelString = locale().queryString(WebLocalizedString::ThisWeekButtonLabel);
114 otherDateLabelString = locale().queryString(WebLocalizedString::OtherWeekLabel);
115 } else {
116 todayLabelString = locale().queryString(WebLocalizedString::CalendarToday);
117 otherDateLabelString = locale().queryString(WebLocalizedString::OtherDateLabel);
118 }
119
120 addString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data);
121 data->append(pickerCommonCss, sizeof(pickerCommonCss));
122 data->append(pickerButtonCss, sizeof(pickerButtonCss));
123 data->append(suggestionPickerCss, sizeof(suggestionPickerCss));
124 data->append(calendarPickerCss, sizeof(calendarPickerCss));
125 addString("</style></head><body><div id=main>Loading...</div><script>\n"
126 "window.dialogArguments = {\n", data);
127 addProperty("anchorRectInScreen", anchorRectInScreen, data);
128 addProperty("min", valueToDateTimeString(m_parameters.minimum, m_parameters.type), data);
129 addProperty("max", valueToDateTimeString(m_parameters.maximum, m_parameters.type), data);
130 addProperty("step", stepString, data);
131 addProperty("stepBase", stepBaseString, data);
132 addProperty("required", m_parameters.required, data);
133 addProperty("currentValue", valueToDateTimeString(m_parameters.doubleValue, m_parameters.type), data);
134 addProperty("locale", m_parameters.locale.string(), data);
135 addProperty("todayLabel", todayLabelString, data);
136 addProperty("clearLabel", locale().queryString(WebLocalizedString::CalendarClear), data);
137 addProperty("weekLabel", locale().queryString(WebLocalizedString::WeekNumberLabel), data);
138 addProperty("weekStartDay", m_locale->firstDayOfWeek(), data);
139 addProperty("shortMonthLabels", m_locale->shortMonthLabels(), data);
140 addProperty("dayLabels", m_locale->weekDayShortLabels(), data);
141 addProperty("isLocaleRTL", m_locale->isRTL(), data);
142 addProperty("isRTL", m_parameters.isAnchorElementRTL, data);
143 addProperty("mode", m_parameters.type.string(), data);
144 if (m_parameters.suggestions.size()) {
145 Vector<String> suggestionValues;
146 Vector<String> localizedSuggestionValues;
147 Vector<String> suggestionLabels;
148 for (unsigned i = 0; i < m_parameters.suggestions.size(); i++) {
149 suggestionValues.append(valueToDateTimeString(m_parameters.suggestions[i].value, m_parameters.type));
150 localizedSuggestionValues.append(m_parameters.suggestions[i].localizedValue);
151 suggestionLabels.append(m_parameters.suggestions[i].label);
152 }
153 addProperty("suggestionValues", suggestionValues, data);
154 addProperty("localizedSuggestionValues", localizedSuggestionValues, data);
155 addProperty("suggestionLabels", suggestionLabels, data);
156 addProperty("inputWidth", static_cast<unsigned>(m_parameters.anchorRectInRootView.width()), data);
157 addProperty("showOtherDateEntry", WebCore::RenderTheme::theme().supportsCalendarPicker(m_parameters.type), data);
158 addProperty("otherDateLabel", otherDateLabelString, data);
159 addProperty("suggestionHighlightColor", WebCore::RenderTheme::theme().activeListBoxSelectionBackgroundColor().serialized(), data);
160 addProperty("suggestionHighlightTextColor", WebCore::RenderTheme::theme().activeListBoxSelectionForegroundColor().serialized(), data);
161 }
162 addString("}\n", data);
163
164 data->append(pickerCommonJs, sizeof(pickerCommonJs));
165 data->append(suggestionPickerJs, sizeof(suggestionPickerJs));
166 data->append(calendarPickerJs, sizeof(calendarPickerJs));
167 addString("</script></body>\n", data);
168 }
169
locale()170 WebCore::Locale& DateTimeChooserImpl::locale()
171 {
172 return *m_locale;
173 }
174
setValueAndClosePopup(int numValue,const String & stringValue)175 void DateTimeChooserImpl::setValueAndClosePopup(int numValue, const String& stringValue)
176 {
177 RefPtrWillBeRawPtr<DateTimeChooserImpl> protector(this);
178 if (numValue >= 0)
179 setValue(stringValue);
180 endChooser();
181 }
182
setValue(const String & value)183 void DateTimeChooserImpl::setValue(const String& value)
184 {
185 m_client->didChooseValue(value);
186 }
187
closePopup()188 void DateTimeChooserImpl::closePopup()
189 {
190 endChooser();
191 }
192
didClosePopup()193 void DateTimeChooserImpl::didClosePopup()
194 {
195 ASSERT(m_client);
196 m_popup = 0;
197 m_client->didEndChooser();
198 }
199
trace(Visitor * visitor)200 void DateTimeChooserImpl::trace(Visitor* visitor)
201 {
202 visitor->trace(m_client);
203 DateTimeChooser::trace(visitor);
204 }
205
206 } // namespace blink
207
208 #endif // ENABLE(INPUT_MULTIPLE_FIELDS_UI)
209