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 "core/html/forms/BaseChooserOnlyDateAndTimeInputType.h"
29
30#include "bindings/v8/ExceptionStatePlaceholder.h"
31#include "core/dom/shadow/ShadowRoot.h"
32#include "core/html/HTMLDivElement.h"
33#include "core/html/HTMLInputElement.h"
34#include "core/page/Chrome.h"
35#include "core/page/Page.h"
36#include "platform/UserGestureIndicator.h"
37
38namespace WebCore {
39
40BaseChooserOnlyDateAndTimeInputType::~BaseChooserOnlyDateAndTimeInputType()
41{
42    closeDateTimeChooser();
43}
44
45void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
46{
47    if (element().isDisabledOrReadOnly() || !element().renderer() || !UserGestureIndicator::processingUserGesture() || element().hasAuthorShadowRoot())
48        return;
49
50    if (m_dateTimeChooser)
51        return;
52    if (!element().document().isActive())
53        return;
54    DateTimeChooserParameters parameters;
55    if (!element().setupDateTimeChooserParameters(parameters))
56        return;
57    m_dateTimeChooser = element().document().page()->chrome().openDateTimeChooser(this, parameters);
58}
59
60void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree()
61{
62    DEFINE_STATIC_LOCAL(AtomicString, valueContainerPseudo, ("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral));
63
64    RefPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
65    valueContainer->setPseudo(valueContainerPseudo);
66    element().userAgentShadowRoot()->appendChild(valueContainer.get());
67    updateAppearance();
68}
69
70void BaseChooserOnlyDateAndTimeInputType::updateAppearance()
71{
72    Node* node = element().userAgentShadowRoot()->firstChild();
73    if (!node || !node->isHTMLElement())
74        return;
75    String displayValue = visibleValue();
76    if (displayValue.isEmpty()) {
77        // Need to put something to keep text baseline.
78        displayValue = " ";
79    }
80    toHTMLElement(node)->setInnerText(displayValue, ASSERT_NO_EXCEPTION);
81}
82
83void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
84{
85    BaseDateAndTimeInputType::setValue(value, valueChanged, eventBehavior);
86    if (valueChanged)
87        updateAppearance();
88}
89
90void BaseChooserOnlyDateAndTimeInputType::closePopupView()
91{
92    closeDateTimeChooser();
93}
94
95void BaseChooserOnlyDateAndTimeInputType::didChooseValue(const String& value)
96{
97    element().setValue(value, DispatchInputAndChangeEvent);
98}
99
100void BaseChooserOnlyDateAndTimeInputType::didChooseValue(double value)
101{
102    ASSERT(std::isfinite(value) || std::isnan(value));
103    if (std::isnan(value))
104        element().setValue(emptyString(), DispatchInputAndChangeEvent);
105    else
106        element().setValueAsNumber(value, ASSERT_NO_EXCEPTION, DispatchInputAndChangeEvent);
107}
108
109void BaseChooserOnlyDateAndTimeInputType::didEndChooser()
110{
111    m_dateTimeChooser.clear();
112}
113
114void BaseChooserOnlyDateAndTimeInputType::closeDateTimeChooser()
115{
116    if (m_dateTimeChooser)
117        m_dateTimeChooser->endChooser();
118}
119
120void BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent(KeyboardEvent* event)
121{
122    BaseClickableWithKeyInputType::handleKeydownEvent(element(), event);
123}
124
125void BaseChooserOnlyDateAndTimeInputType::handleKeypressEvent(KeyboardEvent* event)
126{
127    BaseClickableWithKeyInputType::handleKeypressEvent(element(), event);
128}
129
130void BaseChooserOnlyDateAndTimeInputType::handleKeyupEvent(KeyboardEvent* event)
131{
132    BaseClickableWithKeyInputType::handleKeyupEvent(*this, event);
133}
134
135void BaseChooserOnlyDateAndTimeInputType::accessKeyAction(bool sendMouseEvents)
136{
137    BaseDateAndTimeInputType::accessKeyAction(sendMouseEvents);
138    BaseClickableWithKeyInputType::accessKeyAction(element(), sendMouseEvents);
139}
140
141}
142#endif
143