Fix bugs related to setting reflected floating point DOM attributes
[WebKit-https.git] / Source / WebCore / html / shadow / MediaControlElementTypes.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Google 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  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31
32 #if ENABLE(VIDEO)
33 #include "MediaControlElementTypes.h"
34
35 #include "CSSValueKeywords.h"
36 #include "EventNames.h"
37 #include "HTMLNames.h"
38 #include "MouseEvent.h"
39 #include "RenderMedia.h"
40 #include "RenderMediaControlElements.h"
41 #include "StyleProperties.h"
42
43 namespace WebCore {
44
45 using namespace HTMLNames;
46
47 class Event;
48
49 HTMLMediaElement* parentMediaElement(Node* node)
50 {
51     if (!node)
52         return nullptr;
53     Node* mediaNode = node->shadowHost();
54     if (!mediaNode)
55         mediaNode = node;
56     if (!is<HTMLMediaElement>(*mediaNode))
57         return nullptr;
58     return downcast<HTMLMediaElement>(mediaNode);
59 }
60
61 MediaControlElementType mediaControlElementType(Node* node)
62 {
63     ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
64     if (is<HTMLInputElement>(*node))
65         return static_cast<MediaControlInputElement*>(node)->displayType();
66     return static_cast<MediaControlDivElement*>(node)->displayType();
67 }
68
69 MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
70     : m_mediaController(0)
71     , m_displayType(displayType)
72     , m_element(element)
73 {
74 }
75
76 void MediaControlElement::hide()
77 {
78     m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
79 }
80
81 void MediaControlElement::show()
82 {
83     m_element->removeInlineStyleProperty(CSSPropertyDisplay);
84 }
85
86 bool MediaControlElement::isShowing() const
87 {
88     const StyleProperties* propertySet = m_element->inlineStyle();
89     // Following the code from show() and hide() above, we only have
90     // to check for the presense of inline display.
91     return (!propertySet || !propertySet->getPropertyCSSValue(CSSPropertyDisplay));
92 }
93
94 void MediaControlElement::setDisplayType(MediaControlElementType displayType)
95 {
96     if (displayType == m_displayType)
97         return;
98
99     m_displayType = displayType;
100     if (auto object = m_element->renderer())
101         object->repaint();
102 }
103
104 // ----------------------------
105
106 MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType)
107     : HTMLDivElement(divTag, document)
108     , MediaControlElement(displayType, this)
109 {
110 }
111
112 // ----------------------------
113
114 MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType)
115     : HTMLInputElement(inputTag, document, 0, false)
116     , MediaControlElement(displayType, this)
117 {
118 }
119
120 // ----------------------------
121
122 MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType)
123     : MediaControlDivElement(document, displayType)
124     , m_currentValue(0)
125 {
126 }
127
128 void MediaControlTimeDisplayElement::setCurrentValue(double time)
129 {
130     m_currentValue = time;
131 }
132
133 // ----------------------------
134
135 MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType)
136     : MediaControlInputElement(document, displayType)
137 {
138 }
139
140 void MediaControlMuteButtonElement::defaultEventHandler(Event& event)
141 {
142     if (event.type() == eventNames().clickEvent) {
143         mediaController()->setMuted(!mediaController()->muted());
144         event.setDefaultHandled();
145     }
146
147     HTMLInputElement::defaultEventHandler(event);
148 }
149
150 void MediaControlMuteButtonElement::changedMute()
151 {
152     updateDisplayType();
153 }
154
155 void MediaControlMuteButtonElement::updateDisplayType()
156 {
157     setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton);
158 }
159
160 // ----------------------------
161
162 MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document& document, MediaControlElementType displayType)
163     : MediaControlInputElement(document, displayType)
164 {
165 }
166
167 void MediaControlSeekButtonElement::defaultEventHandler(Event& event)
168 {
169     // Set the mousedown and mouseup events as defaultHandled so they
170     // do not trigger drag start or end actions in MediaControlPanelElement.
171     if (event.type() == eventNames().mousedownEvent || event.type() == eventNames().mouseupEvent)
172         event.setDefaultHandled();
173 }
174
175 void MediaControlSeekButtonElement::setActive(bool flag, bool pause)
176 {
177     if (flag == active())
178         return;
179
180     if (flag)
181         mediaController()->beginScanning(isForwardButton() ? MediaControllerInterface::Forward : MediaControllerInterface::Backward);
182     else
183         mediaController()->endScanning();
184
185     MediaControlInputElement::setActive(flag, pause);
186 }
187
188 // ----------------------------
189
190 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
191     : MediaControlInputElement(document, MediaVolumeSlider)
192     , m_clearMutedOnUserInteraction(false)
193 {
194 }
195
196 void MediaControlVolumeSliderElement::defaultEventHandler(Event& event)
197 {
198     // Left button is 0. Rejects mouse events not from left button.
199     if (is<MouseEvent>(event) && downcast<MouseEvent>(event).button())
200         return;
201
202     if (!renderer())
203         return;
204
205     MediaControlInputElement::defaultEventHandler(event);
206
207     if (event.type() == eventNames().mouseoverEvent || event.type() == eventNames().mouseoutEvent || event.type() == eventNames().mousemoveEvent)
208         return;
209
210     double volume = value().toDouble();
211     if (volume != mediaController()->volume())
212         mediaController()->setVolume(volume);
213     if (m_clearMutedOnUserInteraction)
214         mediaController()->setMuted(false);
215     event.setDefaultHandled();
216 }
217
218 bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
219 {
220     if (!renderer())
221         return false;
222
223     return MediaControlInputElement::willRespondToMouseMoveEvents();
224 }
225
226 bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
227 {
228     if (!renderer())
229         return false;
230
231     return MediaControlInputElement::willRespondToMouseClickEvents();
232 }
233
234 void MediaControlVolumeSliderElement::setVolume(double volume)
235 {
236     if (value().toDouble() != volume)
237         setValue(String::numberToStringECMAScript(volume));
238 }
239
240 void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
241 {
242     m_clearMutedOnUserInteraction = clearMute;
243 }
244
245 } // namespace WebCore
246
247 #endif // ENABLE(VIDEO)