diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-15 09:06:43 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-06-15 09:31:31 (GMT) |
commit | c411f16870f112c3407c28c22b617f613a82cff4 (patch) | |
tree | 29a1bcd590c8b31af2aab445bfe8a978dc5bf582 /src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp | |
parent | 3d77b56b32a0c53ec0bbfaa07236fedb900ff336 (diff) | |
download | Qt-c411f16870f112c3407c28c22b617f613a82cff4.zip Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.gz Qt-c411f16870f112c3407c28c22b617f613a82cff4.tar.bz2 |
Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit-4.6-snapshot-15062009 ( 65232bf00dc494ebfd978f998c88f58d18ecce1e )
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp | 180 |
1 files changed, 113 insertions, 67 deletions
diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp index a224136..2ffa2f6 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,25 +28,20 @@ #if ENABLE(VIDEO) #include "RenderMedia.h" -#include "CSSStyleSelector.h" -#include "Event.h" #include "EventNames.h" #include "FloatConversion.h" -#include "FrameView.h" -#include "GraphicsContext.h" -#include "HTMLMediaElement.h" #include "HTMLNames.h" #include "MediaControlElements.h" #include "MouseEvent.h" -#include "MediaPlayer.h" -#include "RenderSlider.h" -#include "SystemTime.h" +#include <wtf/CurrentTime.h> #include <wtf/MathExtras.h> using namespace std; namespace WebCore { +using namespace HTMLNames; + static const double cTimeUpdateRepeatDelay = 0.2; static const double cOpacityAnimationRepeatDelay = 0.05; // FIXME get this from style @@ -82,8 +77,14 @@ RenderMedia::~RenderMedia() void RenderMedia::destroy() { if (m_controlsShadowRoot && m_controlsShadowRoot->renderer()) { + + // detach the panel before removing the shadow renderer to prevent a crash in m_controlsShadowRoot->detach() + // when display: style changes + m_panel->detach(); + removeChild(m_controlsShadowRoot->renderer()); m_controlsShadowRoot->detach(); + m_controlsShadowRoot = 0; } RenderReplaced::destroy(); } @@ -98,18 +99,40 @@ MediaPlayer* RenderMedia::player() const return mediaElement()->player(); } +void RenderMedia::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle) +{ + RenderReplaced::styleDidChange(diff, oldStyle); + + if (m_controlsShadowRoot) { + if (m_panel->renderer()) + m_panel->renderer()->setStyle(getCachedPseudoStyle(MEDIA_CONTROLS_PANEL)); + + if (m_timelineContainer->renderer()) + m_timelineContainer->renderer()->setStyle(getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER)); + + m_muteButton->updateStyle(); + m_playButton->updateStyle(); + m_seekBackButton->updateStyle(); + m_seekForwardButton->updateStyle(); + m_timeline->updateStyle(); + m_fullscreenButton->updateStyle(); + m_currentTimeDisplay->updateStyle(); + m_timeRemainingDisplay->updateStyle(); + } +} + void RenderMedia::layout() { - IntSize oldSize = contentBox().size(); + IntSize oldSize = contentBoxRect().size(); RenderReplaced::layout(); - RenderObject* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0; + RenderBox* controlsRenderer = m_controlsShadowRoot ? m_controlsShadowRoot->renderBox() : 0; if (!controlsRenderer) return; - IntSize newSize = contentBox().size(); + IntSize newSize = contentBoxRect().size(); if (newSize != oldSize || controlsRenderer->needsLayout()) { - controlsRenderer->setPos(borderLeft() + paddingLeft(), borderTop() + paddingTop()); + controlsRenderer->setLocation(borderLeft() + paddingLeft(), borderTop() + paddingTop()); controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed)); controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed)); controlsRenderer->setNeedsLayout(true, false); @@ -118,34 +141,17 @@ void RenderMedia::layout() } } -RenderObject* RenderMedia::firstChild() const -{ - return m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0; -} - -RenderObject* RenderMedia::lastChild() const -{ - return m_controlsShadowRoot ? m_controlsShadowRoot->renderer() : 0; -} - -void RenderMedia::removeChild(RenderObject* child) -{ - ASSERT(m_controlsShadowRoot); - ASSERT(child == m_controlsShadowRoot->renderer()); - child->removeLayers(enclosingLayer()); - static_cast<RenderMediaControlShadowRoot*>(child)->setParent(0); -} - void RenderMedia::createControlsShadowRoot() { ASSERT(!m_controlsShadowRoot); m_controlsShadowRoot = new MediaControlShadowRootElement(document(), mediaElement()); + addChild(m_controlsShadowRoot->renderer()); } void RenderMedia::createPanel() { ASSERT(!m_panel); - RenderStyle* style = getCachedPseudoStyle(RenderStyle::MEDIA_CONTROLS_PANEL); + RenderStyle* style = getCachedPseudoStyle(MEDIA_CONTROLS_PANEL); m_panel = new HTMLDivElement(HTMLNames::divTag, document()); RenderObject* renderer = m_panel->createRenderer(renderArena(), style); if (renderer) { @@ -186,27 +192,42 @@ void RenderMedia::createSeekForwardButton() m_seekForwardButton->attachToParent(m_panel.get()); } +void RenderMedia::createTimelineContainer() +{ + ASSERT(!m_timelineContainer); + RenderStyle* style = getCachedPseudoStyle(MEDIA_CONTROLS_TIMELINE_CONTAINER); + m_timelineContainer = new HTMLDivElement(HTMLNames::divTag, document()); + RenderObject* renderer = m_timelineContainer->createRenderer(renderArena(), style); + if (renderer) { + m_timelineContainer->setRenderer(renderer); + renderer->setStyle(style); + m_timelineContainer->setAttached(); + m_timelineContainer->setInDocument(true); + m_panel->addChild(m_timelineContainer); + m_panel->renderer()->addChild(renderer); + } +} + void RenderMedia::createTimeline() { ASSERT(!m_timeline); m_timeline = new MediaControlTimelineElement(document(), mediaElement()); - m_timeline->attachToParent(m_panel.get()); + m_timeline->setAttribute(precisionAttr, "float"); + m_timeline->attachToParent(m_timelineContainer.get()); } -void RenderMedia::createTimeDisplay() +void RenderMedia::createCurrentTimeDisplay() { - ASSERT(!m_timeDisplay); - RenderStyle* style = getCachedPseudoStyle(RenderStyle::MEDIA_CONTROLS_TIME_DISPLAY); - m_timeDisplay = new HTMLDivElement(HTMLNames::divTag, document()); - RenderObject* renderer = m_timeDisplay->createRenderer(renderArena(), style); - if (renderer) { - m_timeDisplay->setRenderer(renderer); - renderer->setStyle(style); - m_timeDisplay->setAttached(); - m_timeDisplay->setInDocument(true); - m_panel->addChild(m_timeDisplay); - m_panel->renderer()->addChild(renderer); - } + ASSERT(!m_currentTimeDisplay); + m_currentTimeDisplay = new MediaTimeDisplayElement(document(), mediaElement(), true); + m_currentTimeDisplay->attachToParent(m_timelineContainer.get()); +} + +void RenderMedia::createTimeRemainingDisplay() +{ + ASSERT(!m_timeRemainingDisplay); + m_timeRemainingDisplay = new MediaTimeDisplayElement(document(), mediaElement(), false); + m_timeRemainingDisplay->attachToParent(m_timelineContainer.get()); } void RenderMedia::createFullscreenButton() @@ -230,10 +251,12 @@ void RenderMedia::updateControls() m_panel = 0; m_muteButton = 0; m_playButton = 0; + m_timelineContainer = 0; m_timeline = 0; m_seekBackButton = 0; m_seekForwardButton = 0; - m_timeDisplay = 0; + m_currentTimeDisplay = 0; + m_timeRemainingDisplay = 0; m_fullscreenButton = 0; m_controlsShadowRoot = 0; } @@ -248,17 +271,23 @@ void RenderMedia::updateControls() createPanel(); createMuteButton(); createPlayButton(); + createTimelineContainer(); createTimeline(); createSeekBackButton(); createSeekForwardButton(); - createTimeDisplay(); + createCurrentTimeDisplay(); + createTimeRemainingDisplay(); createFullscreenButton(); } - - if (media->paused() || media->ended() || media->networkState() < HTMLMediaElement::LOADED_METADATA) - m_timeUpdateTimer.stop(); - else + + if (media->canPlay()) { + if (m_timeUpdateTimer.isActive()) + m_timeUpdateTimer.stop(); + } else if (style()->visibility() == VISIBLE && m_timeline && m_timeline->renderer() && m_timeline->renderer()->style()->display() != NONE ) { m_timeUpdateTimer.startRepeating(cTimeUpdateRepeatDelay); + } + + m_previousVisible = style()->visibility(); if (m_muteButton) m_muteButton->update(); @@ -287,32 +316,47 @@ String RenderMedia::formatTime(float time) { if (!isfinite(time)) time = 0; - int seconds = (int)time; + int seconds = (int)fabsf(time); int hours = seconds / (60 * 60); int minutes = (seconds / 60) % 60; seconds %= 60; - return String::format("%02d:%02d:%02d", hours, minutes, seconds); + if (hours) { + if (hours > 9) + return String::format("%s%02d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); + else + return String::format("%s%01d:%02d:%02d", (time < 0 ? "-" : ""), hours, minutes, seconds); + } + else + return String::format("%s%02d:%02d", (time < 0 ? "-" : ""), minutes, seconds); } void RenderMedia::updateTimeDisplay() { - if (!m_timeDisplay) + if (!m_currentTimeDisplay || !m_currentTimeDisplay->renderer() || m_currentTimeDisplay->renderer()->style()->display() == NONE || style()->visibility() != VISIBLE) return; - String timeString = formatTime(mediaElement()->currentTime()); + float now = mediaElement()->currentTime(); + float duration = mediaElement()->duration(); + + String timeString = formatTime(now); ExceptionCode ec; - m_timeDisplay->setInnerText(timeString, ec); -} + m_currentTimeDisplay->setInnerText(timeString, ec); + timeString = formatTime(now - duration); + m_timeRemainingDisplay->setInnerText(timeString, ec); +} + void RenderMedia::updateControlVisibility() { if (!m_panel || !m_panel->renderer()) return; + // Don't fade for audio controls. HTMLMediaElement* media = mediaElement(); - if (player() && !player()->hasVideo() || !media->isVideo()) + if (!media->hasVideo()) return; + // do fading manually, css animations don't work well with shadow trees - bool visible = style()->visibility() == VISIBLE && (m_mouseOver || media->paused() || media->ended() || media->networkState() < HTMLMediaElement::LOADED_METADATA); + bool visible = style()->visibility() == VISIBLE && (m_mouseOver || media->canPlay()); if (visible == (m_opacityAnimationTo > 0)) return; @@ -320,7 +364,7 @@ void RenderMedia::updateControlVisibility() // don't fade gradually if it the element has just changed visibility m_previousVisible = style()->visibility(); m_opacityAnimationTo = m_previousVisible == VISIBLE ? 1.0f : 0; - changeOpacity(m_panel.get(), 0); + changeOpacity(m_panel.get(), m_opacityAnimationTo); return; } @@ -361,7 +405,7 @@ void RenderMedia::forwardEvent(Event* event) { if (event->isMouseEvent() && m_controlsShadowRoot) { MouseEvent* mouseEvent = static_cast<MouseEvent*>(event); - IntPoint point(mouseEvent->pageX(), mouseEvent->pageY()); + IntPoint point(mouseEvent->absoluteLocation()); if (m_muteButton && m_muteButton->hitTest(point)) m_muteButton->defaultEventHandler(event); @@ -385,8 +429,10 @@ void RenderMedia::forwardEvent(Event* event) updateControlVisibility(); } if (event->type() == eventNames().mouseoutEvent) { - // FIXME: moving over scrollbar thumb generates mouseout for the ancestor media element for some reason - m_mouseOver = absoluteBoundingBoxRect().contains(point); + // When the scrollbar thumb captures mouse events, we should treat the mouse as still being over our renderer if the new target is a descendant + Node* mouseOverNode = mouseEvent->relatedTarget() ? mouseEvent->relatedTarget()->toNode() : 0; + RenderObject* mouseOverRenderer = mouseOverNode ? mouseOverNode->renderer() : 0; + m_mouseOver = mouseOverRenderer && mouseOverRenderer->isDescendantOf(this); updateControlVisibility(); } } @@ -398,7 +444,7 @@ int RenderMedia::lowestPosition(bool includeOverflowInterior, bool includeSelf) if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer()) return bottom; - return max(bottom, m_controlsShadowRoot->renderer()->yPos() + m_controlsShadowRoot->renderer()->lowestPosition(includeOverflowInterior, includeSelf)); + return max(bottom, m_controlsShadowRoot->renderBox()->y() + m_controlsShadowRoot->renderBox()->lowestPosition(includeOverflowInterior, includeSelf)); } int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSelf) const @@ -407,7 +453,7 @@ int RenderMedia::rightmostPosition(bool includeOverflowInterior, bool includeSel if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer()) return right; - return max(right, m_controlsShadowRoot->renderer()->xPos() + m_controlsShadowRoot->renderer()->rightmostPosition(includeOverflowInterior, includeSelf)); + return max(right, m_controlsShadowRoot->renderBox()->x() + m_controlsShadowRoot->renderBox()->rightmostPosition(includeOverflowInterior, includeSelf)); } int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf) const @@ -416,7 +462,7 @@ int RenderMedia::leftmostPosition(bool includeOverflowInterior, bool includeSelf if (!m_controlsShadowRoot || !m_controlsShadowRoot->renderer()) return left; - return min(left, m_controlsShadowRoot->renderer()->xPos() + m_controlsShadowRoot->renderer()->leftmostPosition(includeOverflowInterior, includeSelf)); + return min(left, m_controlsShadowRoot->renderBox()->x() + m_controlsShadowRoot->renderBox()->leftmostPosition(includeOverflowInterior, includeSelf)); } } // namespace WebCore |