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 Computer, 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 #include "core/html/shadow/MediaControlElementTypes.h"
33
34 #include "CSSValueKeywords.h"
35 #include "HTMLNames.h"
36 #include "bindings/v8/ExceptionStatePlaceholder.h"
37 #include "core/css/StylePropertySet.h"
38 #include "core/events/MouseEvent.h"
39
40 namespace WebCore {
41
42 using namespace HTMLNames;
43
44 class Event;
45
toParentMediaElement(Node * node)46 HTMLMediaElement* toParentMediaElement(Node* node)
47 {
48 if (!node)
49 return 0;
50 Node* mediaNode = node->shadowHost();
51 if (!mediaNode)
52 mediaNode = node;
53 if (!mediaNode || !mediaNode->isElementNode() || !toElement(mediaNode)->isMediaElement())
54 return 0;
55
56 return toHTMLMediaElement(mediaNode);
57 }
58
mediaControlElementType(Node * node)59 MediaControlElementType mediaControlElementType(Node* node)
60 {
61 ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
62 HTMLElement* element = toHTMLElement(node);
63 if (element->hasTagName(inputTag))
64 return static_cast<MediaControlInputElement*>(element)->displayType();
65 return static_cast<MediaControlDivElement*>(element)->displayType();
66 }
67
MediaControlElement(MediaControlElementType displayType,HTMLElement * element)68 MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
69 : m_mediaController(0)
70 , m_displayType(displayType)
71 , m_element(element)
72 {
73 }
74
hide()75 void MediaControlElement::hide()
76 {
77 m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
78 }
79
show()80 void MediaControlElement::show()
81 {
82 m_element->removeInlineStyleProperty(CSSPropertyDisplay);
83 }
84
isShowing() const85 bool MediaControlElement::isShowing() const
86 {
87 const StylePropertySet* propertySet = m_element->inlineStyle();
88 // Following the code from show() and hide() above, we only have
89 // to check for the presense of inline display.
90 return (!propertySet || !propertySet->getPropertyCSSValue(CSSPropertyDisplay));
91 }
92
setDisplayType(MediaControlElementType displayType)93 void MediaControlElement::setDisplayType(MediaControlElementType displayType)
94 {
95 if (displayType == m_displayType)
96 return;
97
98 m_displayType = displayType;
99 if (RenderObject* object = m_element->renderer())
100 object->repaint();
101 }
102
103 // ----------------------------
104
MediaControlDivElement(Document & document,MediaControlElementType displayType)105 MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType)
106 : HTMLDivElement(document)
107 , MediaControlElement(displayType, this)
108 {
109 }
110
111 // ----------------------------
112
MediaControlInputElement(Document & document,MediaControlElementType displayType)113 MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType)
114 : HTMLInputElement(document, 0, false)
115 , MediaControlElement(displayType, this)
116 {
117 }
118
isMouseFocusable() const119 bool MediaControlInputElement::isMouseFocusable() const
120 {
121 return false;
122 }
123
124 // ----------------------------
125
MediaControlTimeDisplayElement(Document & document,MediaControlElementType displayType)126 MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType)
127 : MediaControlDivElement(document, displayType)
128 , m_currentValue(0)
129 {
130 }
131
setCurrentValue(double time)132 void MediaControlTimeDisplayElement::setCurrentValue(double time)
133 {
134 m_currentValue = time;
135 }
136
137 // ----------------------------
138
MediaControlMuteButtonElement(Document & document,MediaControlElementType displayType)139 MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType)
140 : MediaControlInputElement(document, displayType)
141 {
142 }
143
defaultEventHandler(Event * event)144 void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
145 {
146 if (event->type() == EventTypeNames::click) {
147 mediaController()->setMuted(!mediaController()->muted());
148 event->setDefaultHandled();
149 }
150
151 HTMLInputElement::defaultEventHandler(event);
152 }
153
changedMute()154 void MediaControlMuteButtonElement::changedMute()
155 {
156 updateDisplayType();
157 }
158
updateDisplayType()159 void MediaControlMuteButtonElement::updateDisplayType()
160 {
161 setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton);
162 }
163
164 // ----------------------------
165
MediaControlVolumeSliderElement(Document & document)166 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
167 : MediaControlInputElement(document, MediaVolumeSlider)
168 , m_clearMutedOnUserInteraction(false)
169 {
170 }
171
defaultEventHandler(Event * event)172 void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
173 {
174 // Left button is 0. Rejects mouse events not from left button.
175 if (event->isMouseEvent() && toMouseEvent(event)->button())
176 return;
177
178 if (!inDocument() || !document().isActive())
179 return;
180
181 MediaControlInputElement::defaultEventHandler(event);
182
183 if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
184 return;
185
186 double volume = value().toDouble();
187 if (volume != mediaController()->volume())
188 mediaController()->setVolume(volume, ASSERT_NO_EXCEPTION);
189 if (m_clearMutedOnUserInteraction)
190 mediaController()->setMuted(false);
191 }
192
willRespondToMouseMoveEvents()193 bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
194 {
195 if (!inDocument() || !document().isActive())
196 return false;
197
198 return MediaControlInputElement::willRespondToMouseMoveEvents();
199 }
200
willRespondToMouseClickEvents()201 bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
202 {
203 if (!inDocument() || !document().isActive())
204 return false;
205
206 return MediaControlInputElement::willRespondToMouseClickEvents();
207 }
208
setVolume(double volume)209 void MediaControlVolumeSliderElement::setVolume(double volume)
210 {
211 if (value().toDouble() != volume)
212 setValue(String::number(volume));
213 }
214
setClearMutedOnUserInteraction(bool clearMute)215 void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
216 {
217 m_clearMutedOnUserInteraction = clearMute;
218 }
219
220 } // namespace WebCore
221