summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp')
-rw-r--r--src/3rdparty/webkit/WebCore/rendering/MediaControlElements.cpp308
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)