summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2009-06-15 09:06:43 (GMT)
committerSimon Hausmann <simon.hausmann@nokia.com>2009-06-15 09:31:31 (GMT)
commitc411f16870f112c3407c28c22b617f613a82cff4 (patch)
tree29a1bcd590c8b31af2aab445bfe8a978dc5bf582 /src/3rdparty/webkit/WebCore/rendering/RenderMedia.cpp
parent3d77b56b32a0c53ec0bbfaa07236fedb900ff336 (diff)
downloadQt-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.cpp180
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