REGRESSION(r231291): InputType should hold a WeakPtr to its HTMLInputElement
[WebKit-https.git] / Source / WebCore / html / BaseChooserOnlyDateAndTimeInputType.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  * Copyright (C) 2018 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "BaseChooserOnlyDateAndTimeInputType.h"
29
30 #if ENABLE(DATE_AND_TIME_INPUT_TYPES)
31
32 #include "HTMLDivElement.h"
33 #include "HTMLInputElement.h"
34 #include "Page.h"
35 #include "RenderElement.h"
36 #include "ShadowRoot.h"
37 #include "UserGestureIndicator.h"
38 #include <wtf/NeverDestroyed.h>
39
40 namespace WebCore {
41
42 BaseChooserOnlyDateAndTimeInputType::~BaseChooserOnlyDateAndTimeInputType()
43 {
44     closeDateTimeChooser();
45 }
46
47 void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event&)
48 {
49     if (element().isDisabledOrReadOnly() || !element().renderer() || !UserGestureIndicator::processingUserGesture())
50         return;
51
52     if (m_dateTimeChooser)
53         return;
54     if (!element().document().page())
55         return;
56     DateTimeChooserParameters parameters;
57     if (!element().setupDateTimeChooserParameters(parameters))
58         return;
59 }
60
61 void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree()
62 {
63     static NeverDestroyed<AtomicString> valueContainerPseudo("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral);
64
65     auto valueContainer = HTMLDivElement::create(element().document());
66     valueContainer->setPseudo(valueContainerPseudo);
67     element().userAgentShadowRoot()->appendChild(valueContainer);
68     updateInnerTextValue();
69 }
70
71 void BaseChooserOnlyDateAndTimeInputType::updateInnerTextValue()
72 {
73     RefPtr<Node> node = element().userAgentShadowRoot()->firstChild();
74     if (!is<HTMLElement>(node))
75         return;
76     String displayValue = visibleValue();
77     if (displayValue.isEmpty()) {
78         // Need to put something to keep text baseline.
79         displayValue = ASCIILiteral(" ");
80     }
81     downcast<HTMLElement>(*node).setInnerText(displayValue);
82 }
83
84 void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
85 {
86     BaseDateAndTimeInputType::setValue(value, valueChanged, eventBehavior);
87     if (valueChanged)
88         updateInnerTextValue();
89 }
90
91 void BaseChooserOnlyDateAndTimeInputType::detach()
92 {
93     closeDateTimeChooser();
94 }
95
96 void BaseChooserOnlyDateAndTimeInputType::didChooseValue(const String& value)
97 {
98     element().setValue(value, DispatchInputAndChangeEvent);
99 }
100
101 void BaseChooserOnlyDateAndTimeInputType::didEndChooser()
102 {
103     m_dateTimeChooser = nullptr;
104 }
105
106 void BaseChooserOnlyDateAndTimeInputType::closeDateTimeChooser()
107 {
108     if (m_dateTimeChooser)
109         m_dateTimeChooser->endChooser();
110 }
111
112 void BaseChooserOnlyDateAndTimeInputType::handleKeydownEvent(KeyboardEvent& event)
113 {
114     BaseClickableWithKeyInputType::handleKeydownEvent(element(), event);
115 }
116
117 void BaseChooserOnlyDateAndTimeInputType::handleKeypressEvent(KeyboardEvent& event)
118 {
119     BaseClickableWithKeyInputType::handleKeypressEvent(element(), event);
120 }
121
122 void BaseChooserOnlyDateAndTimeInputType::handleKeyupEvent(KeyboardEvent& event)
123 {
124     BaseClickableWithKeyInputType::handleKeyupEvent(*this, event);
125 }
126
127 void BaseChooserOnlyDateAndTimeInputType::accessKeyAction(bool sendMouseEvents)
128 {
129     BaseDateAndTimeInputType::accessKeyAction(sendMouseEvents);
130     BaseClickableWithKeyInputType::accessKeyAction(element(), sendMouseEvents);
131 }
132
133 bool BaseChooserOnlyDateAndTimeInputType::isMouseFocusable() const
134 {
135     return element().isTextFormControlFocusable();
136 }
137
138 void BaseChooserOnlyDateAndTimeInputType::attributeChanged(const QualifiedName& name)
139 {
140     if (name == valueAttr) {
141         if (auto* element = this->element()) {
142             if (!element->hasDirtyValue())
143                 updateInnerTextValue();
144         }
145     }
146     BaseDateAndTimeInputType::attributeChanged(name);
147 }
148
149 }
150
151 #endif