summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/html/shadow/MediaControlElements.cpp
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/WebCore/html/shadow/MediaControlElements.cpp
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/WebCore/html/shadow/MediaControlElements.cpp')
-rw-r--r--Source/WebCore/html/shadow/MediaControlElements.cpp980
1 files changed, 980 insertions, 0 deletions
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp
new file mode 100644
index 0000000..68b301e
--- /dev/null
+++ b/Source/WebCore/html/shadow/MediaControlElements.cpp
@@ -0,0 +1,980 @@
+/*
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(VIDEO)
+
+#include "MediaControlElements.h"
+
+#include "CSSStyleSelector.h"
+#include "EventNames.h"
+#include "FloatConversion.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "LocalizedStrings.h"
+#include "MediaControls.h"
+#include "MouseEvent.h"
+#include "Page.h"
+#include "RenderFlexibleBox.h"
+#include "RenderMedia.h"
+#include "RenderSlider.h"
+#include "RenderTheme.h"
+#include "RenderView.h"
+#include "Settings.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+HTMLMediaElement* toParentMediaElement(RenderObject* o)
+{
+ Node* node = o->node();
+ Node* mediaNode = node ? node->shadowAncestorNode() : 0;
+ if (!mediaNode || (!mediaNode->hasTagName(HTMLNames::videoTag) && !mediaNode->hasTagName(HTMLNames::audioTag)))
+ return 0;
+
+ return static_cast<HTMLMediaElement*>(mediaNode);
+}
+
+// FIXME: These constants may need to be tweaked to better match the seeking in the QuickTime plug-in.
+static const float cSeekRepeatDelay = 0.1f;
+static const float cStepTime = 0.07f;
+static const float cSeekTime = 0.2f;
+
+// ----------------------------
+
+MediaControlElement::MediaControlElement(HTMLMediaElement* mediaElement)
+ : HTMLDivElement(divTag, mediaElement->document())
+ , m_mediaElement(mediaElement)
+{
+}
+
+static const String& displayString()
+{
+ DEFINE_STATIC_LOCAL(String, s, ("display"));
+ return s;
+}
+
+void MediaControlElement::show()
+{
+ ExceptionCode ec;
+ // FIXME: Make more efficient <http://webkit.org/b/58157>
+ style()->removeProperty(displayString(), ec);
+}
+
+void MediaControlElement::hide()
+{
+ ExceptionCode ec;
+ // FIXME: Make more efficient <http://webkit.org/b/58157>
+ DEFINE_STATIC_LOCAL(String, none, ("none"));
+ style()->setProperty(displayString(), none, ec);
+}
+
+// ----------------------------
+
+inline MediaControlPanelElement::MediaControlPanelElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlPanelElement(mediaElement));
+}
+
+MediaControlElementType MediaControlPanelElement::displayType() const
+{
+ return MediaControlsPanel;
+}
+
+const AtomicString& MediaControlPanelElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlTimelineContainerElement> element = adoptRef(new MediaControlTimelineContainerElement(mediaElement));
+ element->hide();
+ return element.release();
+}
+
+MediaControlElementType MediaControlTimelineContainerElement::displayType() const
+{
+ return MediaTimelineContainer;
+}
+
+const AtomicString& MediaControlTimelineContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline-container"));
+ return id;
+}
+
+// ----------------------------
+
+class RenderMediaVolumeSliderContainer : public RenderBlock {
+public:
+ RenderMediaVolumeSliderContainer(Node*);
+
+private:
+ virtual void layout();
+};
+
+RenderMediaVolumeSliderContainer::RenderMediaVolumeSliderContainer(Node* node)
+ : RenderBlock(node)
+{
+}
+
+void RenderMediaVolumeSliderContainer::layout()
+{
+ RenderBlock::layout();
+ if (style()->display() == NONE || !previousSibling() || !previousSibling()->isBox())
+ return;
+
+ RenderBox* buttonBox = toRenderBox(previousSibling());
+
+ if (view())
+ view()->disableLayoutState();
+
+ IntPoint offset = theme()->volumeSliderOffsetFromMuteButton(buttonBox, IntSize(width(), height()));
+ setX(offset.x() + buttonBox->offsetLeft());
+ setY(offset.y() + buttonBox->offsetTop());
+
+ if (view())
+ view()->enableLayoutState();
+}
+
+inline MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderContainerElement> element = adoptRef(new MediaControlVolumeSliderContainerElement(mediaElement));
+ element->hide();
+ return element.release();
+}
+
+RenderObject* MediaControlVolumeSliderContainerElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderMediaVolumeSliderContainer(this);
+}
+
+void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event* event)
+{
+ if (!event->isMouseEvent() || event->type() != eventNames().mouseoutEvent)
+ return;
+
+ // Poor man's mouseleave event detection.
+ MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
+ if (!mouseEvent->relatedTarget() || !mouseEvent->relatedTarget()->toNode())
+ return;
+
+ if (this->containsIncludingShadowDOM(mouseEvent->relatedTarget()->toNode()))
+ return;
+
+ hide();
+}
+
+
+MediaControlElementType MediaControlVolumeSliderContainerElement::displayType() const
+{
+ return MediaVolumeSliderContainer;
+}
+
+const AtomicString& MediaControlVolumeSliderContainerElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-container"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+ , m_stateBeingDisplayed(Nothing)
+{
+}
+
+PassRefPtr<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlStatusDisplayElement> element = adoptRef(new MediaControlStatusDisplayElement(mediaElement));
+ element->hide();
+ return element.release();
+}
+
+void MediaControlStatusDisplayElement::update()
+{
+ // Get the new state that we'll have to display.
+ StateBeingDisplayed newStateToDisplay = Nothing;
+
+ if (mediaElement()->readyState() != HTMLMediaElement::HAVE_ENOUGH_DATA && !mediaElement()->currentSrc().isEmpty())
+ newStateToDisplay = Loading;
+ else if (mediaElement()->movieLoadType() == MediaPlayer::LiveStream)
+ newStateToDisplay = LiveBroadcast;
+
+ if (newStateToDisplay == m_stateBeingDisplayed)
+ return;
+
+ ExceptionCode e;
+
+ if (m_stateBeingDisplayed == Nothing)
+ show();
+ else if (newStateToDisplay == Nothing)
+ hide();
+
+ m_stateBeingDisplayed = newStateToDisplay;
+
+ switch (m_stateBeingDisplayed) {
+ case Nothing:
+ setInnerText("", e);
+ break;
+ case Loading:
+ setInnerText(mediaElementLoadingStateText(), e);
+ break;
+ case LiveBroadcast:
+ setInnerText(mediaElementLiveBroadcastStateText(), e);
+ break;
+ }
+}
+
+MediaControlElementType MediaControlStatusDisplayElement::displayType() const
+{
+ return MediaStatusDisplay;
+}
+
+const AtomicString& MediaControlStatusDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-status-display"));
+ return id;
+}
+
+// ----------------------------
+
+MediaControlInputElement::MediaControlInputElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : HTMLInputElement(inputTag, mediaElement->document(), 0, false)
+ , m_mediaElement(mediaElement)
+ , m_displayType(displayType)
+{
+}
+
+void MediaControlInputElement::show()
+{
+ ExceptionCode ec;
+ style()->removeProperty(displayString(), ec);
+}
+
+void MediaControlInputElement::hide()
+{
+ ExceptionCode ec;
+ DEFINE_STATIC_LOCAL(String, none, ("none"));
+ style()->setProperty(displayString(), none, ec);
+}
+
+
+void MediaControlInputElement::setDisplayType(MediaControlElementType displayType)
+{
+ if (displayType == m_displayType)
+ return;
+
+ m_displayType = displayType;
+ if (RenderObject* object = renderer())
+ object->repaint();
+}
+
+// ----------------------------
+
+inline MediaControlMuteButtonElement::MediaControlMuteButtonElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : MediaControlInputElement(mediaElement, displayType)
+{
+}
+
+void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->setMuted(!mediaElement()->muted());
+ event->setDefaultHandled();
+ }
+
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlMuteButtonElement::changedMute()
+{
+ updateDisplayType();
+}
+
+void MediaControlMuteButtonElement::updateDisplayType()
+{
+ setDisplayType(mediaElement()->muted() ? MediaUnMuteButton : MediaMuteButton);
+}
+
+// ----------------------------
+
+inline MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
+ : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
+ , m_controls(controls)
+{
+}
+
+PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
+{
+ ASSERT(controls);
+
+ RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(mediaElement, controls));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().mouseoverEvent)
+ m_controls->showVolumeSlider();
+
+ MediaControlMuteButtonElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlMuteButtonElement(mediaElement, MediaMuteButton)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlVolumeSliderMuteButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlPlayButtonElement::MediaControlPlayButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaPlayButton)
+{
+}
+
+PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->togglePlayState();
+ updateDisplayType();
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlPlayButtonElement::updateDisplayType()
+{
+ setDisplayType(mediaElement()->canPlay() ? MediaPlayButton : MediaPauseButton);
+}
+
+const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlSeekButtonElement::MediaControlSeekButtonElement(HTMLMediaElement* mediaElement, MediaControlElementType displayType)
+ : MediaControlInputElement(mediaElement, displayType)
+ , m_seeking(false)
+ , m_capturing(false)
+ , m_seekTimer(this, &MediaControlSeekButtonElement::seekTimerFired)
+{
+}
+
+void MediaControlSeekButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().mousedownEvent) {
+ if (Frame* frame = document()->frame()) {
+ m_capturing = true;
+ frame->eventHandler()->setCapturingMouseEventsNode(this);
+ }
+ mediaElement()->pause(event->fromUserGesture());
+ m_seekTimer.startRepeating(cSeekRepeatDelay);
+ event->setDefaultHandled();
+ } else if (event->type() == eventNames().mouseupEvent) {
+ if (m_capturing)
+ if (Frame* frame = document()->frame()) {
+ m_capturing = false;
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ }
+ ExceptionCode ec;
+ if (m_seeking || m_seekTimer.isActive()) {
+ if (!m_seeking) {
+ float stepTime = isForwardButton() ? cStepTime : -cStepTime;
+ mediaElement()->setCurrentTime(mediaElement()->currentTime() + stepTime, ec);
+ }
+ m_seekTimer.stop();
+ m_seeking = false;
+ event->setDefaultHandled();
+ }
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonElement>*)
+{
+ ExceptionCode ec;
+ m_seeking = true;
+ float seekTime = isForwardButton() ? cSeekTime : -cSeekTime;
+ mediaElement()->setCurrentTime(mediaElement()->currentTime() + seekTime, ec);
+}
+
+void MediaControlSeekButtonElement::detach()
+{
+ if (m_capturing) {
+ if (Frame* frame = document()->frame())
+ frame->eventHandler()->setCapturingMouseEventsNode(0);
+ }
+ MediaControlInputElement::detach();
+}
+
+// ----------------------------
+
+inline MediaControlSeekForwardButtonElement::MediaControlSeekForwardButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlSeekButtonElement(mediaElement, MediaSeekForwardButton)
+{
+}
+
+PassRefPtr<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlSeekForwardButtonElement> button = adoptRef(new MediaControlSeekForwardButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekForwardButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-forward-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlSeekBackButtonElement::MediaControlSeekBackButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlSeekButtonElement(mediaElement, MediaSeekBackButton)
+{
+}
+
+PassRefPtr<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlSeekBackButtonElement> button = adoptRef(new MediaControlSeekBackButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+const AtomicString& MediaControlSeekBackButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-seek-back-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlRewindButtonElement::MediaControlRewindButtonElement(HTMLMediaElement* element)
+ : MediaControlInputElement(element, MediaRewindButton)
+{
+}
+
+PassRefPtr<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlRewindButtonElement> button = adoptRef(new MediaControlRewindButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlRewindButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->rewind(30);
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlRewindButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-rewind-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaReturnToRealtimeButton)
+{
+}
+
+PassRefPtr<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlReturnToRealtimeButtonElement> button = adoptRef(new MediaControlReturnToRealtimeButtonElement(mediaElement));
+ button->setType("button");
+ button->hide();
+ return button.release();
+}
+
+void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->returnToRealtime();
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlReturnToRealtimeButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-return-to-realtime-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaShowClosedCaptionsButton)
+{
+}
+
+PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(mediaElement));
+ button->setType("button");
+ button->hide();
+ return button.release();
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ mediaElement()->setClosedCaptionsVisible(!mediaElement()->closedCaptionsVisible());
+ setChecked(mediaElement()->closedCaptionsVisible());
+ updateDisplayType();
+ event->setDefaultHandled();
+ }
+
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
+{
+ setDisplayType(mediaElement()->closedCaptionsVisible() ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
+}
+
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button"));
+ return id;
+}
+
+// ----------------------------
+
+MediaControlTimelineElement::MediaControlTimelineElement(HTMLMediaElement* mediaElement, MediaControls* controls)
+ : MediaControlInputElement(mediaElement, MediaSlider)
+ , m_controls(controls)
+{
+}
+
+PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
+{
+ ASSERT(controls);
+
+ RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaElement, controls));
+ timeline->setType("range");
+ timeline->setAttribute(precisionAttr, "float");
+ return timeline.release();
+}
+
+void MediaControlTimelineElement::defaultEventHandler(Event* event)
+{
+ // Left button is 0. Rejects mouse events not from left button.
+ if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
+ return;
+
+ if (!attached())
+ return;
+
+ if (event->type() == eventNames().mousedownEvent)
+ mediaElement()->beginScrubbing();
+
+ MediaControlInputElement::defaultEventHandler(event);
+
+ if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
+ return;
+
+ float time = narrowPrecisionToFloat(value().toDouble());
+ if (time != mediaElement()->currentTime()) {
+ // FIXME: This is fired 3 times on every click. We should not be doing that <http:/webkit.org/b/58160>.
+ ExceptionCode ec;
+ mediaElement()->setCurrentTime(time, ec);
+ }
+
+ RenderSlider* slider = toRenderSlider(renderer());
+<<<<<<< HEAD:Source/WebCore/rendering/MediaControlElements.cpp
+ if (slider && slider->inDragMode()) {
+ toRenderMedia(mediaElement()->renderer())->controls()->updateTimeDisplay();
+#if PLATFORM(ANDROID)
+ toRenderMedia(mediaElement()->renderer())->controls()->updateLastTouch();
+#endif
+ }
+=======
+ if (slider && slider->inDragMode())
+ m_controls->updateTimeDisplay();
+>>>>>>> WebKit.org at r84325:Source/WebCore/html/shadow/MediaControlElements.cpp
+
+ if (event->type() == eventNames().mouseupEvent)
+ mediaElement()->endScrubbing();
+}
+
+void MediaControlTimelineElement::setPosition(float currentTime)
+{
+ setValue(String::number(currentTime));
+}
+
+void MediaControlTimelineElement::setDuration(float duration)
+{
+ setAttribute(maxAttr, String::number(isfinite(duration) ? duration : 0));
+}
+
+
+const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaVolumeSlider)
+{
+}
+
+PassRefPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlVolumeSliderElement> slider = adoptRef(new MediaControlVolumeSliderElement(mediaElement));
+ slider->setType("range");
+ slider->setAttribute(precisionAttr, "float");
+ slider->setAttribute(maxAttr, "1");
+ slider->setAttribute(valueAttr, String::number(mediaElement->volume()));
+ return slider.release();
+}
+
+void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
+{
+ // Left button is 0. Rejects mouse events not from left button.
+ if (event->isMouseEvent() && static_cast<MouseEvent*>(event)->button())
+ return;
+
+ if (!attached())
+ return;
+
+ MediaControlInputElement::defaultEventHandler(event);
+
+ if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent)
+ return;
+
+ float volume = narrowPrecisionToFloat(value().toDouble());
+ if (volume != mediaElement()->volume()) {
+ ExceptionCode ec = 0;
+ mediaElement()->setVolume(volume, ec);
+ ASSERT(!ec);
+ }
+}
+
+void MediaControlVolumeSliderElement::setVolume(float volume)
+{
+ if (value().toFloat() != volume)
+ setValue(String::number(volume));
+}
+
+const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenVolumeSliderElement::MediaControlFullscreenVolumeSliderElement(HTMLMediaElement* mediaElement)
+ : MediaControlVolumeSliderElement(mediaElement)
+{
+}
+
+PassRefPtr<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(new MediaControlFullscreenVolumeSliderElement(mediaElement));
+ slider->setType("range");
+ slider->setAttribute(precisionAttr, "float");
+ slider->setAttribute(maxAttr, "1");
+ slider->setAttribute(valueAttr, String::number(mediaElement->volume()));
+ return slider.release();
+}
+
+const AtomicString& MediaControlFullscreenVolumeSliderElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-slider"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(HTMLMediaElement* mediaElement, MediaControls* controls)
+ : MediaControlInputElement(mediaElement, MediaFullscreenButton)
+ , m_controls(controls)
+{
+}
+
+PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(HTMLMediaElement* mediaElement, MediaControls* controls)
+{
+ ASSERT(controls);
+
+ RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(mediaElement, controls));
+ button->setType("button");
+ button->hide();
+ return button.release();
+}
+
+void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+#if ENABLE(FULLSCREEN_API)
+ // Only use the new full screen API if the fullScreenEnabled setting has
+ // been explicitly enabled. Otherwise, use the old fullscreen API. This
+ // allows apps which embed a WebView to retain the existing full screen
+ // video implementation without requiring them to implement their own full
+ // screen behavior.
+ if (document()->settings() && document()->settings()->fullScreenEnabled()) {
+ if (document()->webkitIsFullScreen() && document()->webkitCurrentFullScreenElement() == mediaElement()) {
+ document()->webkitCancelFullScreen();
+ m_controls->exitedFullscreen();
+ } else {
+ mediaElement()->webkitRequestFullScreen(0);
+ m_controls->enteredFullscreen();
+ }
+ } else
+#endif
+ mediaElement()->enterFullscreen();
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenVolumeMinButtonElement::MediaControlFullscreenVolumeMinButtonElement(HTMLMediaElement* mediaElement)
+ : MediaControlInputElement(mediaElement, MediaUnMuteButton)
+{
+}
+
+PassRefPtr<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMinButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ ExceptionCode code = 0;
+ mediaElement()->setVolume(0, code);
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlFullscreenVolumeMinButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-min-button"));
+ return id;
+}
+
+// ----------------------------
+
+inline MediaControlFullscreenVolumeMaxButtonElement::MediaControlFullscreenVolumeMaxButtonElement(HTMLMediaElement* mediaElement)
+: MediaControlInputElement(mediaElement, MediaMuteButton)
+{
+}
+
+PassRefPtr<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(HTMLMediaElement* mediaElement)
+{
+ RefPtr<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(new MediaControlFullscreenVolumeMaxButtonElement(mediaElement));
+ button->setType("button");
+ return button.release();
+}
+
+void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == eventNames().clickEvent) {
+ ExceptionCode code = 0;
+ mediaElement()->setVolume(1, code);
+ event->setDefaultHandled();
+ }
+ HTMLInputElement::defaultEventHandler(event);
+}
+
+const AtomicString& MediaControlFullscreenVolumeMaxButtonElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-volume-max-button"));
+ return id;
+}
+
+// ----------------------------
+
+class RenderMediaControlTimeDisplay : public RenderFlexibleBox {
+public:
+ RenderMediaControlTimeDisplay(Node*);
+
+private:
+ virtual void layout();
+};
+
+RenderMediaControlTimeDisplay::RenderMediaControlTimeDisplay(Node* node)
+ : RenderFlexibleBox(node)
+{
+}
+
+// We want the timeline slider to be at least 100 pixels wide.
+// FIXME: Eliminate hard-coded widths altogether.
+static const int minWidthToDisplayTimeDisplays = 45 + 100 + 45;
+
+void RenderMediaControlTimeDisplay::layout()
+{
+ RenderFlexibleBox::layout();
+ RenderBox* timelineContainerBox = parentBox();
+ while (timelineContainerBox && timelineContainerBox->isAnonymous())
+ timelineContainerBox = timelineContainerBox->parentBox();
+
+ if (timelineContainerBox && timelineContainerBox->width() < minWidthToDisplayTimeDisplays)
+ setWidth(0);
+}
+
+inline MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlElement(mediaElement)
+ , m_currentValue(0)
+{
+}
+
+void MediaControlTimeDisplayElement::setCurrentValue(float time)
+{
+ m_currentValue = time;
+}
+
+RenderObject* MediaControlTimeDisplayElement::createRenderer(RenderArena* arena, RenderStyle*)
+{
+ return new (arena) RenderMediaControlTimeDisplay(this);
+}
+
+// ----------------------------
+
+PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlTimeRemainingDisplayElement(mediaElement));
+}
+
+MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlTimeDisplayElement(mediaElement)
+{
+}
+
+MediaControlElementType MediaControlTimeRemainingDisplayElement::displayType() const
+{
+ return MediaTimeRemainingDisplay;
+}
+
+const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-time-remaining-display"));
+ return id;
+}
+
+// ----------------------------
+
+PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(HTMLMediaElement* mediaElement)
+{
+ return adoptRef(new MediaControlCurrentTimeDisplayElement(mediaElement));
+}
+
+MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(HTMLMediaElement* mediaElement)
+ : MediaControlTimeDisplayElement(mediaElement)
+{
+}
+
+MediaControlElementType MediaControlCurrentTimeDisplayElement::displayType() const
+{
+ return MediaCurrentTimeDisplay;
+}
+
+const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const
+{
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-current-time-display"));
+ return id;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(VIDEO)