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 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 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 68 MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element) 69 : m_mediaController(0) 70 , m_displayType(displayType) 71 , m_element(element) 72 { 73 } 74 75 void MediaControlElement::hide() 76 { 77 m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); 78 } 79 80 void MediaControlElement::show() 81 { 82 m_element->removeInlineStyleProperty(CSSPropertyDisplay); 83 } 84 85 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 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 105 MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType) 106 : HTMLDivElement(document) 107 , MediaControlElement(displayType, this) 108 { 109 } 110 111 // ---------------------------- 112 113 MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType) 114 : HTMLInputElement(document, 0, false) 115 , MediaControlElement(displayType, this) 116 { 117 } 118 119 bool MediaControlInputElement::isMouseFocusable() const 120 { 121 return false; 122 } 123 124 // ---------------------------- 125 126 MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType) 127 : MediaControlDivElement(document, displayType) 128 , m_currentValue(0) 129 { 130 } 131 132 void MediaControlTimeDisplayElement::setCurrentValue(double time) 133 { 134 m_currentValue = time; 135 } 136 137 // ---------------------------- 138 139 MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType) 140 : MediaControlInputElement(document, displayType) 141 { 142 } 143 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 154 void MediaControlMuteButtonElement::changedMute() 155 { 156 updateDisplayType(); 157 } 158 159 void MediaControlMuteButtonElement::updateDisplayType() 160 { 161 setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton); 162 } 163 164 // ---------------------------- 165 166 MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document) 167 : MediaControlInputElement(document, MediaVolumeSlider) 168 , m_clearMutedOnUserInteraction(false) 169 { 170 } 171 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 193 bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents() 194 { 195 if (!inDocument() || !document().isActive()) 196 return false; 197 198 return MediaControlInputElement::willRespondToMouseMoveEvents(); 199 } 200 201 bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents() 202 { 203 if (!inDocument() || !document().isActive()) 204 return false; 205 206 return MediaControlInputElement::willRespondToMouseClickEvents(); 207 } 208 209 void MediaControlVolumeSliderElement::setVolume(double volume) 210 { 211 if (value().toDouble() != volume) 212 setValue(String::number(volume)); 213 } 214 215 void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute) 216 { 217 m_clearMutedOnUserInteraction = clearMute; 218 } 219 220 } // namespace WebCore 221