diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp | 308 |
1 files changed, 265 insertions, 43 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp index fc2790ca4e..74293e030a 100644 --- a/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp @@ -32,6 +32,7 @@ #include "MediaControlElements.h" +#include "LocalizedStrings.h" #include "EventNames.h" #include "FloatConversion.h" #include "Frame.h" @@ -40,6 +41,7 @@ #include "RenderMedia.h" #include "RenderSlider.h" #include "RenderTheme.h" +#include "CString.h" namespace WebCore { @@ -74,51 +76,165 @@ void MediaControlShadowRootElement::updateStyle() } // ---------------------------- + -MediaTextDisplayElement::MediaTextDisplayElement(Document* doc, PseudoId pseudo, HTMLMediaElement* mediaElement) +MediaControlElement::MediaControlElement(Document* doc, PseudoId pseudo, HTMLMediaElement* mediaElement) : HTMLDivElement(divTag, doc) , m_mediaElement(mediaElement) , m_pseudoStyleId(pseudo) { - RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); - RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style); - if (renderer) { - setRenderer(renderer); - renderer->setStyle(style); - } - setAttached(); setInDocument(true); } -void MediaTextDisplayElement::attachToParent(Element* parent) +void MediaControlElement::attachToParent(Element* parent) { parent->addChild(this); - if (renderer() && parent->renderer()) - parent->renderer()->addChild(renderer()); } -void MediaTextDisplayElement::update() +void MediaControlElement::update() { if (renderer()) renderer()->updateFromElement(); updateStyle(); } -void MediaTextDisplayElement::updateStyle() +PassRefPtr<RenderStyle> MediaControlElement::styleForElement() +{ + RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); + if (!style) + return 0; + + // text-decoration can't be overrided from CSS. So we do it here. + // See https://bugs.webkit.org/show_bug.cgi?id=27015 + style->setTextDecoration(TDNONE); + style->setTextDecorationsInEffect(TDNONE); + + return style; +} + +bool MediaControlElement::rendererIsNeeded(RenderStyle* style) +{ + return HTMLDivElement::rendererIsNeeded(style) && parent() && parent()->renderer(); +} + +void MediaControlElement::attach() { - if (renderer() && m_mediaElement->renderer()) { - RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); - renderer()->setStyle(style); + RefPtr<RenderStyle> style = styleForElement(); + if (!style) + return; + bool needsRenderer = rendererIsNeeded(style.get()); + if (!needsRenderer) + return; + RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style.get()); + if (!renderer) + return; + renderer->setStyle(style.get()); + setRenderer(renderer); + if (parent() && parent()->renderer()) { + // Find next sibling with a renderer to determine where to insert. + Node* sibling = nextSibling(); + while (sibling && !sibling->renderer()) + sibling = sibling->nextSibling(); + parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0); } + ContainerNode::attach(); } -MediaTimeDisplayElement::MediaTimeDisplayElement(Document* doc, HTMLMediaElement* element, bool currentTime) - : MediaTextDisplayElement(doc, currentTime ? MEDIA_CONTROLS_CURRENT_TIME_DISPLAY : MEDIA_CONTROLS_TIME_REMAINING_DISPLAY, element) +void MediaControlElement::updateStyle() { + if (!m_mediaElement || !m_mediaElement->renderer()) + return; + + RefPtr<RenderStyle> style = styleForElement(); + if (!style) + return; + + bool needsRenderer = rendererIsNeeded(style.get()) && parent() && parent()->renderer(); + if (renderer() && !needsRenderer) + detach(); + else if (!renderer() && needsRenderer) + attach(); + else if (renderer()) { + renderer()->setStyle(style.get()); + + // Make sure that if there is any innerText renderer, it is updated as well. + if (firstChild() && firstChild()->renderer()) + firstChild()->renderer()->setStyle(style.get()); + } } // ---------------------------- +MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document* doc, HTMLMediaElement* element) +: MediaControlElement(doc, MEDIA_CONTROLS_TIMELINE_CONTAINER, element) +{ +} + +bool MediaControlTimelineContainerElement::rendererIsNeeded(RenderStyle* style) +{ + if (!MediaControlElement::rendererIsNeeded(style)) + return false; + + // This is for MediaControllerThemeClassic: + // If there is no style for MediaControlStatusDisplayElement style, don't hide + // the timeline. + if (!m_mediaElement->renderer()->getCachedPseudoStyle(MEDIA_CONTROLS_STATUS_DISPLAY)) + return true; + + float duration = m_mediaElement->duration(); + return !isnan(duration) && !isinf(duration); +} + + +// ---------------------------- + +MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document* doc, HTMLMediaElement* element) +: MediaControlElement(doc, MEDIA_CONTROLS_STATUS_DISPLAY, element) +, m_stateBeingDisplayed(Nothing) +{ +} + +void MediaControlStatusDisplayElement::update() +{ + MediaControlElement::update(); + + // Get the new state that we'll have to display. + StateBeingDisplayed newStateToDisplay = Nothing; + + if (m_mediaElement->readyState() != HTMLMediaElement::HAVE_ENOUGH_DATA && !m_mediaElement->currentSrc().isEmpty()) + newStateToDisplay = Loading; + else if (m_mediaElement->movieLoadType() == MediaPlayer::LiveStream) + newStateToDisplay = LiveBroadcast; + + // Propagate only if needed. + if (newStateToDisplay == m_stateBeingDisplayed) + return; + m_stateBeingDisplayed = newStateToDisplay; + + ExceptionCode e; + switch (m_stateBeingDisplayed) { + case Nothing: + setInnerText("", e); + break; + case Loading: + setInnerText(mediaElementLoadingStateText(), e); + break; + case LiveBroadcast: + setInnerText(mediaElementLiveBroadcastStateText(), e); + break; + } +} + +bool MediaControlStatusDisplayElement::rendererIsNeeded(RenderStyle* style) +{ + if (!MediaControlElement::rendererIsNeeded(style)) + return false; + float duration = m_mediaElement->duration(); + return (isnan(duration) || isinf(duration)); +} + +// ---------------------------- + MediaControlInputElement::MediaControlInputElement(Document* doc, PseudoId pseudo, const String& type, HTMLMediaElement* mediaElement, MediaControlElementType displayType) : HTMLInputElement(inputTag, doc) , m_mediaElement(mediaElement) @@ -126,15 +242,12 @@ MediaControlInputElement::MediaControlInputElement(Document* doc, PseudoId pseud , m_displayType(displayType) { setInputType(type); - updateStyle(); setInDocument(true); } void MediaControlInputElement::attachToParent(Element* parent) { parent->addChild(this); - if (renderer() && parent->renderer()) - parent->renderer()->addChild(renderer()); } void MediaControlInputElement::update() @@ -145,34 +258,58 @@ void MediaControlInputElement::update() updateStyle(); } +PassRefPtr<RenderStyle> MediaControlInputElement::styleForElement() +{ + return m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); +} + +bool MediaControlInputElement::rendererIsNeeded(RenderStyle* style) +{ + return HTMLInputElement::rendererIsNeeded(style) && parent() && parent()->renderer(); +} + +void MediaControlInputElement::attach() +{ + RefPtr<RenderStyle> style = styleForElement(); + if (!style) + return; + + bool needsRenderer = rendererIsNeeded(style.get()); + if (!needsRenderer) + return; + RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style.get()); + if (!renderer) + return; + renderer->setStyle(style.get()); + setRenderer(renderer); + if (parent() && parent()->renderer()) { + // Find next sibling with a renderer to determine where to insert. + Node* sibling = nextSibling(); + while (sibling && !sibling->renderer()) + sibling = sibling->nextSibling(); + parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0); + } + ContainerNode::attach(); +} + void MediaControlInputElement::updateStyle() { if (!m_mediaElement || !m_mediaElement->renderer()) return; - RenderStyle* style = m_mediaElement->renderer()->getCachedPseudoStyle(m_pseudoStyleId); + RefPtr<RenderStyle> style = styleForElement(); + if (!style) + return; - bool needsRenderer = rendererIsNeeded(style); + bool needsRenderer = rendererIsNeeded(style.get()) && parent() && parent()->renderer(); if (renderer() && !needsRenderer) detach(); - else if (!renderer() && needsRenderer) { - RenderObject* renderer = createRenderer(m_mediaElement->renderer()->renderArena(), style); - if (!renderer) - return; - renderer->setStyle(style); - setRenderer(renderer); - setAttached(); - if (parent() && parent()->renderer()) { - // Find next sibling with a renderer to determine where to insert. - Node* sibling = nextSibling(); - while (sibling && !sibling->renderer()) - sibling = sibling->nextSibling(); - parent()->renderer()->addChild(renderer, sibling ? sibling->renderer() : 0); - } - } else if (renderer()) - renderer()->setStyle(style); + else if (!renderer() && needsRenderer) + attach(); + else if (renderer()) + renderer()->setStyle(style.get()); } - + bool MediaControlInputElement::hitTest(const IntPoint& absPoint) { if (renderer() && renderer()->style()->hasAppearance()) @@ -283,6 +420,59 @@ void MediaControlSeekButtonElement::seekTimerFired(Timer<MediaControlSeekButtonE m_mediaElement->setCurrentTime(m_mediaElement->currentTime() + seekTime, ec); } +void MediaControlSeekButtonElement::detach() +{ + if (m_capturing) { + if (Frame* frame = document()->frame()) + frame->eventHandler()->setCapturingMouseEventsNode(0); + } + MediaControlInputElement::detach(); +} + + +// ---------------------------- + +MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document* doc, HTMLMediaElement* element) +: MediaControlInputElement(doc, MEDIA_CONTROLS_REWIND_BUTTON, "button", element, MediaRewindButton) +{ +} + +void MediaControlRewindButtonElement::defaultEventHandler(Event* event) +{ + if (event->type() == eventNames().clickEvent) { + m_mediaElement->rewind(30); + event->setDefaultHandled(); + } + HTMLInputElement::defaultEventHandler(event); +} + +bool MediaControlRewindButtonElement::rendererIsNeeded(RenderStyle* style) +{ + return MediaControlInputElement::rendererIsNeeded(style) && m_mediaElement->movieLoadType() != MediaPlayer::LiveStream; +} + + +// ---------------------------- + +MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document* doc, HTMLMediaElement* element) +: MediaControlInputElement(doc, MEDIA_CONTROLS_RETURN_TO_REALTIME_BUTTON, "button", element, MediaReturnToRealtimeButton) +{ +} + +void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event* event) +{ + if (event->type() == eventNames().clickEvent) { + m_mediaElement->returnToRealtime(); + event->setDefaultHandled(); + } + HTMLInputElement::defaultEventHandler(event); +} + +bool MediaControlReturnToRealtimeButtonElement::rendererIsNeeded(RenderStyle* style) +{ + return MediaControlInputElement::rendererIsNeeded(style) && m_mediaElement->movieLoadType() == MediaPlayer::LiveStream; +} + // ---------------------------- MediaControlTimelineElement::MediaControlTimelineElement(Document* document, HTMLMediaElement* element) @@ -295,9 +485,9 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event) if (event->type() == eventNames().mousedownEvent) m_mediaElement->beginScrubbing(); - HTMLInputElement::defaultEventHandler(event); + MediaControlInputElement::defaultEventHandler(event); - if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent ) { + if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent || event->type() == eventNames().mousemoveEvent) { return; } @@ -322,6 +512,7 @@ void MediaControlTimelineElement::update(bool updateDuration) setAttribute(maxAttr, String::number(isfinite(dur) ? dur : 0)); } setValue(String::number(m_mediaElement->currentTime())); + MediaControlInputElement::update(); } // ---------------------------- @@ -341,11 +532,42 @@ void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event) bool MediaControlFullscreenButtonElement::rendererIsNeeded(RenderStyle* style) { - return m_mediaElement->supportsFullscreen() && MediaControlInputElement::rendererIsNeeded(style); + return MediaControlInputElement::rendererIsNeeded(style) && m_mediaElement->supportsFullscreen(); } // ---------------------------- +MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document* doc, PseudoId pseudo, HTMLMediaElement* element) + : MediaControlElement(doc, pseudo, element) + , m_isVisible(true) +{ +} + +PassRefPtr<RenderStyle> MediaControlTimeDisplayElement::styleForElement() +{ + RefPtr<RenderStyle> style = MediaControlElement::styleForElement(); + if (!m_isVisible) { + style = RenderStyle::clone(style.get()); + style->setWidth(Length(0, Fixed)); + } + return style; +} + +void MediaControlTimeDisplayElement::setVisible(bool visible) +{ + // This function is used during the RenderMedia::layout() + // call, where we cannot change the renderer at this time. + if (!renderer() || !renderer()->style()) + return; + + if (visible == m_isVisible) + return; + m_isVisible = visible; + RefPtr<RenderStyle> style = styleForElement(); + renderer()->setStyle(style.get()); +} + + } //namespace WebCore #endif // enable(video) |