3fa7e743154094a702a7f35296c66069295cdee8
[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 #include <wtf/IsoMallocInlines.h>
43
44 namespace WebCore {
45
46 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlDivElement);
47 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlInputElement);
48 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlTimeDisplayElement);
49 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlMuteButtonElement);
50 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlSeekButtonElement);
51 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlVolumeSliderElement);
52
53 using namespace HTMLNames;
54
55 class Event;
56
57 RefPtr<HTMLMediaElement> parentMediaElement(Node* node)
58 {
59     if (!node)
60         return nullptr;
61     RefPtr<Node> mediaNode = node->shadowHost();
62     if (!mediaNode)
63         mediaNode = node;
64     if (!is<HTMLMediaElement>(*mediaNode))
65         return nullptr;
66     return downcast<HTMLMediaElement>(mediaNode.get());
67 }
68
69 MediaControlElementType mediaControlElementType(Node* node)
70 {
71     ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
72     if (is<HTMLInputElement>(*node))
73         return static_cast<MediaControlInputElement*>(node)->displayType();
74     return static_cast<MediaControlDivElement*>(node)->displayType();
75 }
76
77 MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
78     : m_mediaController(0)
79     , m_displayType(displayType)
80     , m_element(element)
81 {
82 }
83
84 void MediaControlElement::hide()
85 {
86     m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
87 }
88
89 void MediaControlElement::show()
90 {
91     m_element->removeInlineStyleProperty(CSSPropertyDisplay);
92 }
93
94 bool MediaControlElement::isShowing() const
95 {
96     const StyleProperties* propertySet = m_element->inlineStyle();
97     // Following the code from show() and hide() above, we only have
98     // to check for the presense of inline display.
99     return (!propertySet || !propertySet->getPropertyCSSValue(CSSPropertyDisplay));
100 }
101
102 void MediaControlElement::setDisplayType(MediaControlElementType displayType)
103 {
104     if (displayType == m_displayType)
105         return;
106
107     m_displayType = displayType;
108     if (auto object = m_element->renderer())
109         object->repaint();
110 }
111
112 // ----------------------------
113
114 MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType)
115     : HTMLDivElement(divTag, document)
116     , MediaControlElement(displayType, this)
117 {
118 }
119
120 // ----------------------------
121
122 MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType)
123     : HTMLInputElement(inputTag, document, 0, false)
124     , MediaControlElement(displayType, this)
125 {
126 }
127
128 // ----------------------------
129
130 MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType)
131     : MediaControlDivElement(document, displayType)
132     , m_currentValue(0)
133 {
134 }
135
136 void MediaControlTimeDisplayElement::setCurrentValue(double time)
137 {
138     m_currentValue = time;
139 }
140
141 // ----------------------------
142
143 MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType)
144     : MediaControlInputElement(document, displayType)
145 {
146 }
147
148 void MediaControlMuteButtonElement::defaultEventHandler(Event& event)
149 {
150     if (event.type() == eventNames().clickEvent) {
151         mediaController()->setMuted(!mediaController()->muted());
152         event.setDefaultHandled();
153     }
154
155     HTMLInputElement::defaultEventHandler(event);
156 }
157
158 void MediaControlMuteButtonElement::changedMute()
159 {
160     updateDisplayType();
161 }
162
163 void MediaControlMuteButtonElement::updateDisplayType()
164 {
165     setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton);
166 }
167
168 // ----------------------------
169
170 MediaControlSeekButtonElement::MediaControlSeekButtonElement(Document& document, MediaControlElementType displayType)
171     : MediaControlInputElement(document, displayType)
172 {
173 }
174
175 void MediaControlSeekButtonElement::defaultEventHandler(Event& event)
176 {
177     // Set the mousedown and mouseup events as defaultHandled so they
178     // do not trigger drag start or end actions in MediaControlPanelElement.
179     if (event.type() == eventNames().mousedownEvent || event.type() == eventNames().mouseupEvent)
180         event.setDefaultHandled();
181 }
182
183 void MediaControlSeekButtonElement::setActive(bool flag, bool pause)
184 {
185     if (flag == active())
186         return;
187
188     if (flag)
189         mediaController()->beginScanning(isForwardButton() ? MediaControllerInterface::Forward : MediaControllerInterface::Backward);
190     else
191         mediaController()->endScanning();
192
193     MediaControlInputElement::setActive(flag, pause);
194 }
195
196 // ----------------------------
197
198 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
199     : MediaControlInputElement(document, MediaVolumeSlider)
200     , m_clearMutedOnUserInteraction(false)
201 {
202 }
203
204 void MediaControlVolumeSliderElement::defaultEventHandler(Event& event)
205 {
206     // Left button is 0. Rejects mouse events not from left button.
207     if (is<MouseEvent>(event) && downcast<MouseEvent>(event).button())
208         return;
209
210     if (!renderer())
211         return;
212
213     MediaControlInputElement::defaultEventHandler(event);
214
215     if (event.type() == eventNames().mouseoverEvent || event.type() == eventNames().mouseoutEvent || event.type() == eventNames().mousemoveEvent)
216         return;
217
218     double volume = value().toDouble();
219     if (volume != mediaController()->volume())
220         mediaController()->setVolume(volume);
221     if (m_clearMutedOnUserInteraction)
222         mediaController()->setMuted(false);
223     event.setDefaultHandled();
224 }
225
226 bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
227 {
228     if (!renderer())
229         return false;
230
231     return MediaControlInputElement::willRespondToMouseMoveEvents();
232 }
233
234 bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
235 {
236     if (!renderer())
237         return false;
238
239     return MediaControlInputElement::willRespondToMouseClickEvents();
240 }
241
242 void MediaControlVolumeSliderElement::setVolume(double volume)
243 {
244     if (value().toDouble() != volume)
245         setValue(String::numberToStringECMAScript(volume));
246 }
247
248 void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
249 {
250     m_clearMutedOnUserInteraction = clearMute;
251 }
252
253 } // namespace WebCore
254
255 #endif // ENABLE(VIDEO)