Home | History | Annotate | Download | only in web
      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 
     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 
     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 
     68 DateTimeChooserImpl::~DateTimeChooserImpl()
     69 {
     70 }
     71 
     72 void DateTimeChooserImpl::endChooser()
     73 {
     74     if (!m_popup)
     75         return;
     76     m_chromeClient->closePagePopup(m_popup);
     77 }
     78 
     79 WebCore::IntSize DateTimeChooserImpl::contentSize()
     80 {
     81     return WebCore::IntSize(0, 0);
     82 }
     83 
     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 
    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 
    170 WebCore::Locale& DateTimeChooserImpl::locale()
    171 {
    172     return *m_locale;
    173 }
    174 
    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 
    183 void DateTimeChooserImpl::setValue(const String& value)
    184 {
    185     m_client->didChooseValue(value);
    186 }
    187 
    188 void DateTimeChooserImpl::closePopup()
    189 {
    190     endChooser();
    191 }
    192 
    193 void DateTimeChooserImpl::didClosePopup()
    194 {
    195     ASSERT(m_client);
    196     m_popup = 0;
    197     m_client->didEndChooser();
    198 }
    199 
    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