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
6 * are met:
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.
12 *
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
23 * SUCH DAMAGE.
24 */
25
26#include "config.h"
27#if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
28#include "web/ExternalDateTimeChooser.h"
29
30#include "core/InputTypeNames.h"
31#include "core/html/forms/DateTimeChooserClient.h"
32#include "public/web/WebDateTimeChooserCompletion.h"
33#include "public/web/WebDateTimeChooserParams.h"
34#include "public/web/WebViewClient.h"
35#include "web/ChromeClientImpl.h"
36#include "wtf/text/AtomicString.h"
37
38namespace blink {
39
40class WebDateTimeChooserCompletionImpl : public WebDateTimeChooserCompletion {
41public:
42    WebDateTimeChooserCompletionImpl(ExternalDateTimeChooser* chooser)
43        : m_chooser(chooser)
44    {
45    }
46
47private:
48    virtual void didChooseValue(const WebString& value) OVERRIDE
49    {
50        m_chooser->didChooseValue(value);
51        delete this;
52    }
53
54    virtual void didChooseValue(double value) OVERRIDE
55    {
56        m_chooser->didChooseValue(value);
57        delete this;
58    }
59
60    virtual void didCancelChooser() OVERRIDE
61    {
62        m_chooser->didCancelChooser();
63        delete this;
64    }
65
66    RefPtr<ExternalDateTimeChooser> m_chooser;
67};
68
69ExternalDateTimeChooser::~ExternalDateTimeChooser()
70{
71}
72
73ExternalDateTimeChooser::ExternalDateTimeChooser(DateTimeChooserClient* client)
74    : m_client(client)
75{
76    ASSERT(client);
77}
78
79PassRefPtr<ExternalDateTimeChooser> ExternalDateTimeChooser::create(ChromeClientImpl* chromeClient, WebViewClient* webViewClient, DateTimeChooserClient* client, const DateTimeChooserParameters& parameters)
80{
81    ASSERT(chromeClient);
82    RefPtr<ExternalDateTimeChooser> chooser = adoptRef(new ExternalDateTimeChooser(client));
83    if (!chooser->openDateTimeChooser(chromeClient, webViewClient, parameters))
84        chooser.clear();
85    return chooser.release();
86}
87
88
89static WebDateTimeInputType toWebDateTimeInputType(const AtomicString& source)
90{
91    if (source == InputTypeNames::date)
92        return WebDateTimeInputTypeDate;
93    if (source == InputTypeNames::datetime)
94        return WebDateTimeInputTypeDateTime;
95    if (source == InputTypeNames::datetime_local)
96        return WebDateTimeInputTypeDateTimeLocal;
97    if (source == InputTypeNames::month)
98        return WebDateTimeInputTypeMonth;
99    if (source == InputTypeNames::time)
100        return WebDateTimeInputTypeTime;
101    if (source == InputTypeNames::week)
102        return WebDateTimeInputTypeWeek;
103    return WebDateTimeInputTypeNone;
104}
105
106bool ExternalDateTimeChooser::openDateTimeChooser(ChromeClientImpl* chromeClient, WebViewClient* webViewClient, const DateTimeChooserParameters& parameters)
107{
108    if (!webViewClient)
109        return false;
110
111    WebDateTimeChooserParams webParams;
112    webParams.type = toWebDateTimeInputType(parameters.type);
113    webParams.anchorRectInScreen = chromeClient->rootViewToScreen(parameters.anchorRectInRootView);
114    webParams.currentValue = parameters.currentValue;
115    webParams.doubleValue = parameters.doubleValue;
116    webParams.suggestions = parameters.suggestions;
117    webParams.minimum = parameters.minimum;
118    webParams.maximum = parameters.maximum;
119    webParams.step = parameters.step;
120    webParams.stepBase = parameters.stepBase;
121    webParams.isRequired = parameters.required;
122    webParams.isAnchorElementRTL = parameters.isAnchorElementRTL;
123
124    WebDateTimeChooserCompletion* completion = new WebDateTimeChooserCompletionImpl(this);
125    if (webViewClient->openDateTimeChooser(webParams, completion))
126        return true;
127    // We can't open a chooser. Calling
128    // WebDateTimeChooserCompletionImpl::didCancelChooser to delete the
129    // WebDateTimeChooserCompletionImpl object and deref this.
130    completion->didCancelChooser();
131    return false;
132}
133
134void ExternalDateTimeChooser::didChooseValue(const WebString& value)
135{
136    if (m_client)
137        m_client->didChooseValue(value);
138    // didChooseValue might run JavaScript code, and endChooser() might be
139    // called. However DateTimeChooserCompletionImpl still has one reference to
140    // this object.
141    if (m_client)
142        m_client->didEndChooser();
143}
144
145void ExternalDateTimeChooser::didChooseValue(double value)
146{
147    if (m_client)
148        m_client->didChooseValue(value);
149    // didChooseValue might run JavaScript code, and endChooser() might be
150    // called. However DateTimeChooserCompletionImpl still has one reference to
151    // this object.
152    if (m_client)
153        m_client->didEndChooser();
154}
155
156void ExternalDateTimeChooser::didCancelChooser()
157{
158    if (m_client)
159        m_client->didEndChooser();
160}
161
162void ExternalDateTimeChooser::endChooser()
163{
164    DateTimeChooserClient* client = m_client;
165    m_client = 0;
166    client->didEndChooser();
167}
168
169AXObject* ExternalDateTimeChooser::rootAXObject()
170{
171    return 0;
172}
173
174} // namespace blink
175
176#endif
177