Chromium Code Reviews| Index: Source/core/html/shadow/MediaControls.cpp |
| diff --git a/Source/core/html/shadow/MediaControls.cpp b/Source/core/html/shadow/MediaControls.cpp |
| index 5b521ce71d70c41027545b52b1a4ee1b72762158..91673a191cecc775a15c009963c8343ad39c7b7a 100644 |
| --- a/Source/core/html/shadow/MediaControls.cpp |
| +++ b/Source/core/html/shadow/MediaControls.cpp |
| @@ -28,17 +28,22 @@ |
| #include "core/html/shadow/MediaControls.h" |
| #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| +#include "bindings/core/v8/V8MediaControls.h" |
| +#include "bindings/core/v8/PrivateScriptRunner.h" |
| #include "core/events/MouseEvent.h" |
| #include "core/frame/Settings.h" |
| #include "core/html/HTMLMediaElement.h" |
| +#include "core/html/HTMLVideoElement.h" |
| #include "core/html/MediaController.h" |
| #include "core/rendering/RenderTheme.h" |
| +#include "core/rendering/RenderVideo.h" |
| +#include "wtf/text/Base64.h" |
| namespace blink { |
| // If you change this value, then also update the corresponding value in |
| // LayoutTests/media/media-controls.js. |
| -static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; |
| +//static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3; |
| static bool fullscreenIsSupported(const Document& document) |
| { |
| @@ -67,19 +72,26 @@ MediaControls::MediaControls(HTMLMediaElement& mediaElement) |
| , m_durationDisplay(nullptr) |
| , m_enclosure(nullptr) |
| , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired) |
| - , m_isMouseOverControls(false) |
| - , m_isPausedForScrubbing(false) |
| + //, m_isMouseOverControls(false) |
| + //, m_isPausedForScrubbing(false) |
| { |
| + ScriptWrappable::init(this); |
| + v8::Handle<v8::Value> classObject = PrivateScriptRunner::installClassIfNeeded(document().frame(), "MediaControls"); |
| + RELEASE_ASSERT(!classObject.IsEmpty()); |
| } |
| PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& mediaElement) |
| { |
| RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaControls(mediaElement)); |
| - if (controls->initializeControls()) |
| - return controls.release(); |
| + /*if (!controls->initializeControls()) |
| + return nullptr;*/ |
| - return nullptr; |
| + PassRefPtrWillBeRawPtr<HTMLMediaElement> media(&mediaElement); |
| + if (!V8MediaControls::PrivateScript::createdCallbackMethod(controls->document().frame(), controls.get(), media)) |
| + return nullptr; |
| + |
| + return controls.release(); |
| } |
| bool MediaControls::initializeControls() |
| @@ -169,7 +181,7 @@ bool MediaControls::initializeControls() |
| void MediaControls::reset() |
| { |
| - double duration = mediaElement().duration(); |
| + /*double duration = mediaElement().duration(); |
| m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION); |
| m_durationDisplay->setCurrentValue(duration); |
| @@ -188,50 +200,58 @@ void MediaControls::reset() |
| refreshClosedCaptionsButtonVisibility(); |
| - if (mediaElement().hasVideo() && fullscreenIsSupported(document())) |
| + if (mediaElement().hasVideo() && fullscreenIsSupported()) |
| m_fullScreenButton->show(); |
| else |
| m_fullScreenButton->hide(); |
| - makeOpaque(); |
| + makeOpaque();*/ |
| + |
| + V8MediaControls::PrivateScript::resetMethod(document().frame(), this); |
| } |
| void MediaControls::show() |
| { |
| - makeOpaque(); |
| + /*makeOpaque(); |
| m_panel->setIsDisplayed(true); |
| m_panel->show(); |
| if (m_overlayPlayButton) |
| - m_overlayPlayButton->updateDisplayType(); |
| + m_overlayPlayButton->updateDisplayType();*/ |
| + |
| + V8MediaControls::PrivateScript::showMethod(document().frame(), this); |
| } |
| void MediaControls::mediaElementFocused() |
| { |
| - show(); |
| - stopHideMediaControlsTimer(); |
| + /*show(); |
| + stopHideMediaControlsTimer();*/ |
| + |
| + V8MediaControls::PrivateScript::mediaElementFocusedMethod(document().frame(), this); |
| } |
| void MediaControls::hide() |
| { |
| - m_panel->setIsDisplayed(false); |
| + /*m_panel->setIsDisplayed(false); |
| m_panel->hide(); |
| if (m_overlayPlayButton) |
| - m_overlayPlayButton->hide(); |
| + m_overlayPlayButton->hide();*/ |
| + |
| + V8MediaControls::PrivateScript::hideMethod(document().frame(), this); |
| } |
| void MediaControls::makeOpaque() |
| { |
| - m_panel->makeOpaque(); |
| + //m_panel->makeOpaque(); |
| } |
| void MediaControls::makeTransparent() |
| { |
| - m_panel->makeTransparent(); |
| + //m_panel->makeTransparent(); |
| } |
| bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const |
| { |
| - // Never hide for a media element without visual representation. |
| + /*// Never hide for a media element without visual representation. |
| if (!mediaElement().hasVideo()) |
| return false; |
| // Don't hide if the mouse is over the controls. |
| @@ -248,70 +268,82 @@ bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const |
| const bool ignoreFocus = behaviorFlags & IgnoreFocus; |
| if (!ignoreFocus && (mediaElement().focused() || contains(document().focusedElement()))) |
| return false; |
| - return true; |
| + return true;*/ |
| + |
| + return false; |
| } |
| void MediaControls::playbackStarted() |
| { |
| - m_currentTimeDisplay->show(); |
| + /* m_currentTimeDisplay->show(); |
| m_durationDisplay->hide(); |
| updatePlayState(); |
| m_timeline->setPosition(mediaElement().currentTime()); |
| updateCurrentTimeDisplay(); |
| - startHideMediaControlsTimer(); |
| + startHideMediaControlsTimer();*/ |
| + |
| + V8MediaControls::PrivateScript::playbackStartedMethod(document().frame(), this); |
| } |
| void MediaControls::playbackProgressed() |
| { |
| - m_timeline->setPosition(mediaElement().currentTime()); |
| + /*m_timeline->setPosition(mediaElement().currentTime()); |
| updateCurrentTimeDisplay(); |
| if (shouldHideMediaControls()) |
| - makeTransparent(); |
| + makeTransparent();*/ |
| + |
| + V8MediaControls::PrivateScript::playbackProgressedMethod(document().frame(), this); |
| } |
| void MediaControls::playbackStopped() |
| { |
| - updatePlayState(); |
| + /*updatePlayState(); |
| m_timeline->setPosition(mediaElement().currentTime()); |
| updateCurrentTimeDisplay(); |
| makeOpaque(); |
| - stopHideMediaControlsTimer(); |
| + stopHideMediaControlsTimer();*/ |
| + |
| + V8MediaControls::PrivateScript::playbackStoppedMethod(document().frame(), this); |
| } |
| void MediaControls::updatePlayState() |
| { |
| - if (m_isPausedForScrubbing) |
| + /*if (m_isPausedForScrubbing) |
| return; |
| if (m_overlayPlayButton) |
| m_overlayPlayButton->updateDisplayType(); |
| - m_playButton->updateDisplayType(); |
| + m_playButton->updateDisplayType();*/ |
| } |
| void MediaControls::beginScrubbing() |
| { |
| - if (!mediaElement().togglePlayStateWillPlay()) { |
| + /*if (!mediaElement().togglePlayStateWillPlay()) { |
| m_isPausedForScrubbing = true; |
| mediaElement().togglePlayState(); |
| - } |
| + }*/ |
| + |
| + V8MediaControls::PrivateScript::beginScrubbingMethod(document().frame(), this); |
| } |
| void MediaControls::endScrubbing() |
| { |
| - if (m_isPausedForScrubbing) { |
| + /*if (m_isPausedForScrubbing) { |
| m_isPausedForScrubbing = false; |
| if (mediaElement().togglePlayStateWillPlay()) |
| mediaElement().togglePlayState(); |
| - } |
| + }*/ |
| + |
| + V8MediaControls::PrivateScript::endScrubbingMethod(document().frame(), this); |
| } |
| void MediaControls::updateCurrentTimeDisplay() |
| { |
| - double now = mediaElement().currentTime(); |
| + /*double now = mediaElement().currentTime(); |
| double duration = mediaElement().duration(); |
| // After seek, hide duration display and show current time. |
| @@ -322,56 +354,70 @@ void MediaControls::updateCurrentTimeDisplay() |
| // Allow the theme to format the time. |
| m_currentTimeDisplay->setInnerText(RenderTheme::theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION); |
| - m_currentTimeDisplay->setCurrentValue(now); |
| + m_currentTimeDisplay->setCurrentValue(now);*/ |
| + |
| + V8MediaControls::PrivateScript::updateCurrentTimeDisplayMethod(document().frame(), this); |
| } |
| void MediaControls::updateVolume() |
| { |
| - m_muteButton->updateDisplayType(); |
| + /*m_muteButton->updateDisplayType(); |
| if (m_muteButton->renderer()) |
| m_muteButton->renderer()->setShouldDoFullPaintInvalidation(true); |
| if (mediaElement().muted()) |
| m_volumeSlider->setVolume(0); |
| else |
| - m_volumeSlider->setVolume(mediaElement().volume()); |
| + m_volumeSlider->setVolume(mediaElement().volume());*/ |
| + |
| + V8MediaControls::PrivateScript::updateVolumeMethod(document().frame(), this); |
| } |
| void MediaControls::changedClosedCaptionsVisibility() |
| { |
| - m_toggleClosedCaptionsButton->updateDisplayType(); |
| + //m_toggleClosedCaptionsButton->updateDisplayType(); |
| + |
| + V8MediaControls::PrivateScript::changedClosedCaptionsVisibilityMethod(document().frame(), this); |
| } |
| void MediaControls::refreshClosedCaptionsButtonVisibility() |
| { |
| - if (mediaElement().hasClosedCaptions()) |
| + /*if (mediaElement().hasClosedCaptions()) |
| m_toggleClosedCaptionsButton->show(); |
| else |
| - m_toggleClosedCaptionsButton->hide(); |
| + m_toggleClosedCaptionsButton->hide();*/ |
| + |
| + V8MediaControls::PrivateScript::refreshClosedCaptionsButtonVisibilityMethod(document().frame(), this); |
| } |
| void MediaControls::closedCaptionTracksChanged() |
| { |
| - refreshClosedCaptionsButtonVisibility(); |
| + //refreshClosedCaptionsButtonVisibility(); |
| + |
| + V8MediaControls::PrivateScript::closedCaptionTracksChangedMethod(document().frame(), this); |
| } |
| void MediaControls::enteredFullscreen() |
| { |
| - m_fullScreenButton->setIsFullscreen(true); |
| + /*m_fullScreenButton->setIsFullscreen(true); |
| stopHideMediaControlsTimer(); |
| - startHideMediaControlsTimer(); |
| + startHideMediaControlsTimer();*/ |
| + |
| + V8MediaControls::PrivateScript::enteredFullscreenMethod(document().frame(), this); |
| } |
| void MediaControls::exitedFullscreen() |
| { |
| - m_fullScreenButton->setIsFullscreen(false); |
| + /*m_fullScreenButton->setIsFullscreen(false); |
| stopHideMediaControlsTimer(); |
| - startHideMediaControlsTimer(); |
| + startHideMediaControlsTimer();*/ |
| + |
| + V8MediaControls::PrivateScript::exitedFullscreenMethod(document().frame(), this); |
| } |
| void MediaControls::defaultEventHandler(Event* event) |
| { |
| - HTMLDivElement::defaultEventHandler(event); |
| + /*HTMLDivElement::defaultEventHandler(event); |
| if (event->type() == EventTypeNames::mouseover) { |
| if (!containsRelatedTarget(event)) { |
| @@ -400,12 +446,12 @@ void MediaControls::defaultEventHandler(Event* event) |
| if (shouldHideMediaControls(IgnoreVideoHover)) |
| startHideMediaControlsTimer(); |
| return; |
| - } |
| + }*/ |
| } |
| void MediaControls::hideMediaControlsTimerFired(Timer<MediaControls>*) |
| { |
| - if (mediaElement().togglePlayStateWillPlay()) |
| + /*if (mediaElement().togglePlayStateWillPlay()) |
| return; |
| unsigned behaviorFlags = IgnoreFocus | IgnoreVideoHover; |
| @@ -416,17 +462,17 @@ void MediaControls::hideMediaControlsTimerFired(Timer<MediaControls>*) |
| if (!shouldHideMediaControls(behaviorFlags)) |
| return; |
| - makeTransparent(); |
| + makeTransparent();*/ |
| } |
| void MediaControls::startHideMediaControlsTimer() |
| { |
| - m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMediaControls, FROM_HERE); |
| + //m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMediaControls, FROM_HERE); |
| } |
| void MediaControls::stopHideMediaControlsTimer() |
| { |
| - m_hideMediaControlsTimer.stop(); |
| + //m_hideMediaControlsTimer.stop(); |
| } |
| const AtomicString& MediaControls::shadowPseudoId() const |
| @@ -437,17 +483,19 @@ const AtomicString& MediaControls::shadowPseudoId() const |
| bool MediaControls::containsRelatedTarget(Event* event) |
| { |
| - if (!event->isMouseEvent()) |
| + /*if (!event->isMouseEvent()) |
| return false; |
| EventTarget* relatedTarget = toMouseEvent(event)->relatedTarget(); |
| if (!relatedTarget) |
| return false; |
| - return contains(relatedTarget->toNode()); |
| + return contains(relatedTarget->toNode());*/ |
| + |
| + return false; |
| } |
| void MediaControls::createTextTrackDisplay() |
| { |
| - if (m_textDisplayContainer) |
| + /*if (m_textDisplayContainer) |
| return; |
| RefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(*this); |
| @@ -457,29 +505,200 @@ void MediaControls::createTextTrackDisplay() |
| if (m_overlayEnclosure && m_overlayPlayButton) |
| m_overlayEnclosure->insertBefore(textDisplayContainer.release(), m_overlayPlayButton); |
| else |
| - insertBefore(textDisplayContainer.release(), m_enclosure); |
| + insertBefore(textDisplayContainer.release(), m_enclosure);*/ |
| } |
| void MediaControls::showTextTrackDisplay() |
| { |
| - if (!m_textDisplayContainer) |
| + /*if (!m_textDisplayContainer) |
| createTextTrackDisplay(); |
| - m_textDisplayContainer->show(); |
| + m_textDisplayContainer->show();*/ |
| } |
| void MediaControls::hideTextTrackDisplay() |
| { |
| - if (!m_textDisplayContainer) |
| + /*if (!m_textDisplayContainer) |
| createTextTrackDisplay(); |
| - m_textDisplayContainer->hide(); |
| + m_textDisplayContainer->hide();*/ |
| } |
| void MediaControls::updateTextTrackDisplay() |
| { |
| - if (!m_textDisplayContainer) |
| + /*if (!m_textDisplayContainer) |
| createTextTrackDisplay(); |
| - m_textDisplayContainer->updateDisplay(); |
| + m_textDisplayContainer->updateDisplay();*/ |
| +} |
| + |
| +String MediaControls::getResourceDataURL(String name) |
| +{ |
| + // FIXME: Use cache |
| + Image* image = Image::loadPlatformResource(name.utf8().data()).leakRef(); |
| + |
| + // FIXME: This depends on the fact the resource image is PNG. |
| + Vector<char> imageData; |
| + imageData.append(image->data()->data(), image->data()->size()); |
| + Vector<char> base64Data; |
| + WTF::base64Encode(imageData, base64Data); |
| + return "data:image/png;base64," + base64Data; |
| +} |
| + |
| +bool MediaControls::isOverlayPlayButtonEnabled() |
| +{ |
| + return document().settings() && document().settings()->mediaControlsOverlayPlayButtonEnabled(); |
| +} |
| + |
| +bool MediaControls::shouldShowControls() const |
| +{ |
| + return mediaElement().shouldShowControls(); |
| +} |
| + |
| +bool MediaControls::hasAudio() const |
| +{ |
| + return mediaElement().hasAudio(); |
| +} |
| + |
| +bool MediaControls::hasVideo() const |
| +{ |
| + return mediaElement().hasVideo(); |
| +} |
| + |
| +bool MediaControls::hasClosedCaptions() const |
| +{ |
| + return mediaElement().hasClosedCaptions(); |
| +} |
| + |
| +bool MediaControls::togglePlayStateWillPlay() const |
| +{ |
| + return mediaElement().togglePlayStateWillPlay(); |
| +} |
| + |
| +void MediaControls::togglePlayState() |
| +{ |
| + mediaElement().togglePlayState(); |
| +} |
| + |
| +void MediaControls::setCurrentTime(double time) |
|
philipj_slow
2014/08/25 09:53:27
I think this can be implemented in JS as (this.med
hajimehoshi
2014/08/26 04:33:51
Thanks! I didn't realize that MediaController was
|
| +{ |
| + if (mediaElement().controller()) |
| + mediaElement().controller()->setCurrentTime(time, IGNORE_EXCEPTION); |
| + else |
| + mediaElement().setCurrentTime(time, IGNORE_EXCEPTION); |
| +} |
| + |
| +bool MediaControls::isClosedCaptionsVisible() const |
| +{ |
| + return mediaElement().closedCaptionsVisible(); |
| +} |
| + |
| +void MediaControls::toggleClosedCaptionsVisible() |
| +{ |
| + mediaElement().setClosedCaptionsVisible(!mediaElement().closedCaptionsVisible()); |
| +} |
| + |
| +void MediaControls::toggleFullscreen() |
| +{ |
| + if (mediaElement().isFullscreen()) |
| + mediaElement().exitFullscreen(); |
| + else |
| + mediaElement().enterFullscreen(); |
| +} |
| + |
| +void MediaControls::setDivDisplayType(RefPtrWillBeRawPtr<HTMLElement> element, unsigned type) |
| +{ |
| + RefPtrWillBeRawPtr<MediaControlDivElement> mediaDivElement = static_pointer_cast<MediaControlDivElement>(element); |
| + mediaDivElement->setDisplayType(static_cast<MediaControlElementType>(type)); |
| +} |
| + |
| +void MediaControls::setInputDisplayType(RefPtrWillBeRawPtr<HTMLElement> element, unsigned type) |
| +{ |
| + //RefPtrWillBeRawPtr<MediaControlInputElement> mediaInputElement = static_pointer_cast<MediaControlInputElement>(element); |
| + // This doesn't work!!! |
| + //mediaInputElement->setDisplayType(static_cast<MediaControlElementType>(type)); |
| +} |
| + |
| +bool MediaControls::fullscreenIsSupported() const |
| +{ |
| + return blink::fullscreenIsSupported(document()); |
| +} |
| + |
| +double MediaControls::getTextTrackContainerFontSize() |
| +{ |
| + if (!document().isActive()) |
| + return 0; |
| + |
| + IntRect videoBox; |
| + |
| + if (!mediaElement().renderer() || !mediaElement().renderer()->isVideo()) |
| + return 0; |
| + videoBox = toRenderVideo(mediaElement().renderer())->videoBox(); |
| + |
| + m_videoDisplaySize = videoBox; |
| + |
| + float smallestDimension = std::min(videoBox.size().height(), videoBox.size().width()); |
| + |
| + return smallestDimension * 0.05f; |
| +} |
| + |
| +void MediaControls::updateTextTrackContainerDisplay(RefPtrWillBeRawPtr<HTMLElement> textTrackContainer) |
| +{ |
| + if (!mediaElement().closedCaptionsVisible()) { |
| + textTrackContainer->removeChildren(); |
| + return; |
| + } |
| + |
| + // 1. If the media element is an audio element, or is another playback |
| + // mechanism with no rendering area, abort these steps. There is nothing to |
| + // render. |
| + if (isHTMLAudioElement(mediaElement())) |
| + return; |
| + |
| + // 2. Let video be the media element or other playback mechanism. |
| + HTMLVideoElement& video = toHTMLVideoElement(mediaElement()); |
| + |
| + // 3. Let output be an empty list of absolutely positioned CSS block boxes. |
| + |
| + // 4. If the user agent is exposing a user interface for video, add to |
| + // output one or more completely transparent positioned CSS block boxes that |
| + // cover the same region as the user interface. |
| + |
| + // 5. If the last time these rules were run, the user agent was not exposing |
| + // a user interface for video, but now it is, let reset be true. Otherwise, |
| + // let reset be false. |
| + |
| + // There is nothing to be done explicitly for 4th and 5th steps, as |
| + // everything is handled through CSS. The caption box is on top of the |
| + // controls box, in a container set with the -webkit-box display property. |
| + |
| + // 6. Let tracks be the subset of video's list of text tracks that have as |
| + // their rules for updating the text track rendering these rules for |
| + // updating the display of WebVTT text tracks, and whose text track mode is |
| + // showing or showing by default. |
| + // 7. Let cues be an empty list of text track cues. |
| + // 8. For each track track in tracks, append to cues all the cues from |
| + // track's list of cues that have their text track cue active flag set. |
| + CueList activeCues = video.currentlyActiveCues(); |
| + |
| + // 9. If reset is false, then, for each text track cue cue in cues: if cue's |
| + // text track cue display state has a set of CSS boxes, then add those boxes |
| + // to output, and remove cue from cues. |
| + |
| + // There is nothing explicitly to be done here, as all the caching occurs |
| + // within the TextTrackCue instance itself. If parameters of the cue change, |
| + // the display tree is cleared. |
| + |
| + // 10. For each text track cue cue in cues that has not yet had |
| + // corresponding CSS boxes added to output, in text track cue order, run the |
| + // following substeps: |
| + for (size_t i = 0; i < activeCues.size(); ++i) { |
| + TextTrackCue* cue = activeCues[i].data(); |
| + |
| + ASSERT(cue->isActive()); |
| + if (!cue->track() || !cue->track()->isRendered() || !cue->isActive()) |
| + continue; |
| + |
| + cue->updateDisplay(m_videoDisplaySize.size(), *this); |
| + } |
| } |
| void MediaControls::trace(Visitor* visitor) |