summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLMediaElement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html/HTMLMediaElement.cpp')
-rw-r--r--WebCore/html/HTMLMediaElement.cpp161
1 files changed, 90 insertions, 71 deletions
diff --git a/WebCore/html/HTMLMediaElement.cpp b/WebCore/html/HTMLMediaElement.cpp
index cccf0fd..f86c44d 100644
--- a/WebCore/html/HTMLMediaElement.cpp
+++ b/WebCore/html/HTMLMediaElement.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,7 +53,6 @@ using namespace std;
namespace WebCore {
-using namespace EventNames;
using namespace HTMLNames;
HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
@@ -68,7 +67,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_loadedFirstFrame(false)
, m_autoplaying(true)
, m_currentLoop(0)
- , m_volume(0.5f)
+ , m_volume(1.0f)
, m_muted(false)
, m_paused(true)
, m_seeking(false)
@@ -80,15 +79,15 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* doc)
, m_loadNestingLevel(0)
, m_terminateLoadBelowNestingLevel(0)
, m_pausedInternal(false)
- , m_inPageCache(false)
+ , m_inActiveDocument(true)
, m_player(0)
{
- document()->registerForCacheCallbacks(this);
+ document()->registerForDocumentActivationCallbacks(this);
}
HTMLMediaElement::~HTMLMediaElement()
{
- document()->unregisterForCacheCallbacks(this);
+ document()->unregisterForDocumentActivationCallbacks(this);
}
bool HTMLMediaElement::checkDTD(const Node* newChild)
@@ -152,6 +151,14 @@ void HTMLMediaElement::attach()
renderer()->updateFromElement();
}
+void HTMLMediaElement::recalcStyle(StyleChange change)
+{
+ HTMLElement::recalcStyle(change);
+
+ if (renderer())
+ renderer()->updateFromElement();
+}
+
void HTMLMediaElement::scheduleLoad()
{
m_loadTimer.startOneShot(0);
@@ -186,7 +193,7 @@ void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
m_asyncEventsToDispatch.swap(asyncEventsToDispatch);
unsigned count = asyncEventsToDispatch.size();
for (unsigned n = 0; n < count; ++n)
- dispatchHTMLEvent(asyncEventsToDispatch[n], false, true);
+ dispatchEventForType(asyncEventsToDispatch[n], false, true);
}
String serializeTimeOffset(float time)
@@ -197,12 +204,16 @@ String serializeTimeOffset(float time)
return timeString;
}
-float parseTimeOffset(String timeString, bool* ok = 0)
+float parseTimeOffset(const String& timeString, bool* ok = 0)
{
- if (timeString.endsWith("s"))
- timeString = timeString.left(timeString.length() - 1);
+ const UChar* characters = timeString.characters();
+ unsigned length = timeString.length();
+
+ if (length && characters[length - 1] == 's')
+ length--;
+
// FIXME parse time offset values (format not specified yet)
- float val = (float)timeString.toDouble(ok);
+ float val = charactersToFloat(characters, length, ok);
return val;
}
@@ -226,7 +237,7 @@ PassRefPtr<MediaError> HTMLMediaElement::error() const
return m_error;
}
-String HTMLMediaElement::src() const
+KURL HTMLMediaElement::src() const
{
return document()->completeURL(getAttribute(srcAttr));
}
@@ -273,8 +284,8 @@ void HTMLMediaElement::load(ExceptionCode& ec)
// 2
if (m_begun) {
m_begun = false;
- m_error = new MediaError(MediaError::MEDIA_ERR_ABORTED);
- initAndDispatchProgressEvent(abortEvent);
+ m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
+ initAndDispatchProgressEvent(eventNames().abortEvent);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
goto end;
}
@@ -298,7 +309,7 @@ void HTMLMediaElement::load(ExceptionCode& ec)
m_player->seek(0);
}
m_currentLoop = 0;
- dispatchHTMLEvent(emptiedEvent, false, true);
+ dispatchEventForType(eventNames().emptiedEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
goto end;
}
@@ -318,7 +329,7 @@ void HTMLMediaElement::load(ExceptionCode& ec)
// 9
m_begun = true;
- dispatchProgressEvent(beginEvent, false, 0, 0); // progress event draft calls this loadstart
+ dispatchProgressEvent(eventNames().loadstartEvent, false, 0, 0);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
goto end;
@@ -359,12 +370,12 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
//delete m_player;
//m_player = 0;
// FIXME better error handling
- m_error = new MediaError(MediaError::MEDIA_ERR_NETWORK);
+ m_error = MediaError::create(MediaError::MEDIA_ERR_NETWORK);
m_begun = false;
m_progressEventTimer.stop();
m_bufferingRate = 0;
- initAndDispatchProgressEvent(errorEvent);
+ initAndDispatchProgressEvent(eventNames().errorEvent);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
@@ -373,7 +384,7 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
if (isVideo())
static_cast<HTMLVideoElement*>(this)->updatePosterImage();
- dispatchHTMLEvent(emptiedEvent, false, true);
+ dispatchEventForType(eventNames().emptiedEvent, false, true);
return;
}
@@ -384,11 +395,11 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
m_player->seek(effectiveStart());
m_networkState = LOADED_METADATA;
- dispatchHTMLEvent(durationchangeEvent, false, true);
+ dispatchEventForType(eventNames().durationchangeEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
- dispatchHTMLEvent(loadedmetadataEvent, false, true);
+ dispatchEventForType(eventNames().loadedmetadataEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
}
@@ -410,11 +421,11 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
static_cast<RenderVideo*>(renderer())->videoSizeChanged();
}
- dispatchHTMLEvent(loadedfirstframeEvent, false, true);
+ dispatchEventForType(eventNames().loadedfirstframeEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
- dispatchHTMLEvent(canshowcurrentframeEvent, false, true);
+ dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true);
if (m_loadNestingLevel < m_terminateLoadBelowNestingLevel)
return;
}
@@ -425,7 +436,7 @@ void HTMLMediaElement::mediaPlayerNetworkStateChanged(MediaPlayer*)
m_networkState = LOADED;
m_progressEventTimer.stop();
m_bufferingRate = 0;
- initAndDispatchProgressEvent(loadEvent);
+ initAndDispatchProgressEvent(eventNames().loadEvent);
}
}
@@ -451,25 +462,25 @@ void HTMLMediaElement::setReadyState(ReadyState state)
return;
if (state == DATA_UNAVAILABLE) {
- dispatchHTMLEvent(dataunavailableEvent, false, true);
+ dispatchEventForType(eventNames().dataunavailableEvent, false, true);
if (wasActivelyPlaying) {
- dispatchHTMLEvent(timeupdateEvent, false, true);
- dispatchHTMLEvent(waitingEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().waitingEvent, false, true);
}
} else if (state == CAN_SHOW_CURRENT_FRAME) {
if (m_loadedFirstFrame)
- dispatchHTMLEvent(canshowcurrentframeEvent, false, true);
+ dispatchEventForType(eventNames().canshowcurrentframeEvent, false, true);
if (wasActivelyPlaying) {
- dispatchHTMLEvent(timeupdateEvent, false, true);
- dispatchHTMLEvent(waitingEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().waitingEvent, false, true);
}
} else if (state == CAN_PLAY) {
- dispatchHTMLEvent(canplayEvent, false, true);
+ dispatchEventForType(eventNames().canplayEvent, false, true);
} else if (state == CAN_PLAY_THROUGH) {
- dispatchHTMLEvent(canplaythroughEvent, false, true);
+ dispatchEventForType(eventNames().canplaythroughEvent, false, true);
if (m_autoplaying && m_paused && autoplay()) {
m_paused = false;
- dispatchHTMLEvent(playEvent, false, true);
+ dispatchEventForType(eventNames().playEvent, false, true);
}
}
updatePlayState();
@@ -487,11 +498,11 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
if (progress == m_previousProgress) {
if (timedelta > 3.0 && !m_sentStalledEvent) {
m_bufferingRate = 0;
- initAndDispatchProgressEvent(stalledEvent);
+ initAndDispatchProgressEvent(eventNames().stalledEvent);
m_sentStalledEvent = true;
}
} else {
- initAndDispatchProgressEvent(progressEvent);
+ initAndDispatchProgressEvent(eventNames().progressEvent);
m_previousProgress = progress;
m_previousProgressTime = time;
m_sentStalledEvent = false;
@@ -537,7 +548,7 @@ void HTMLMediaElement::seek(float time, ExceptionCode& ec)
m_seeking = true;
// 9
- dispatchHTMLEvent(timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
// 10
// As soon as the user agent has established whether or not the media data for the new playback position is available,
@@ -596,7 +607,7 @@ void HTMLMediaElement::setDefaultPlaybackRate(float rate, ExceptionCode& ec)
}
if (m_defaultPlaybackRate != rate) {
m_defaultPlaybackRate = rate;
- dispatchEventAsync(ratechangeEvent);
+ dispatchEventAsync(eventNames().ratechangeEvent);
}
}
@@ -613,7 +624,7 @@ void HTMLMediaElement::setPlaybackRate(float rate, ExceptionCode& ec)
}
if (m_player && m_player->rate() != rate) {
m_player->setRate(rate);
- dispatchEventAsync(ratechangeEvent);
+ dispatchEventAsync(eventNames().ratechangeEvent);
}
}
@@ -650,7 +661,7 @@ void HTMLMediaElement::play(ExceptionCode& ec)
if (m_paused) {
m_paused = false;
- dispatchEventAsync(playEvent);
+ dispatchEventAsync(eventNames().playEvent);
}
m_autoplaying = false;
@@ -670,8 +681,8 @@ void HTMLMediaElement::pause(ExceptionCode& ec)
if (!m_paused) {
m_paused = true;
- dispatchEventAsync(timeupdateEvent);
- dispatchEventAsync(pauseEvent);
+ dispatchEventAsync(eventNames().timeupdateEvent);
+ dispatchEventAsync(eventNames().pauseEvent);
}
m_autoplaying = false;
@@ -681,9 +692,9 @@ void HTMLMediaElement::pause(ExceptionCode& ec)
unsigned HTMLMediaElement::playCount() const
{
- String val = getAttribute(playcountAttr);
- int count = val.toInt();
- return max(count, 1);
+ bool ok;
+ unsigned count = getAttribute(playcountAttr).string().toUInt(&ok);
+ return (count > 0 && ok) ? count : 1;
}
void HTMLMediaElement::setPlayCount(unsigned count, ExceptionCode& ec)
@@ -720,7 +731,7 @@ void HTMLMediaElement::setEnd(float time)
float HTMLMediaElement::loopStart() const
{
- return getTimeOffsetAttribute(loopstartAttr, 0);
+ return getTimeOffsetAttribute(loopstartAttr, start());
}
void HTMLMediaElement::setLoopStart(float time)
@@ -731,7 +742,7 @@ void HTMLMediaElement::setLoopStart(float time)
float HTMLMediaElement::loopEnd() const
{
- return getTimeOffsetAttribute(loopendAttr, std::numeric_limits<float>::infinity());
+ return getTimeOffsetAttribute(loopendAttr, end());
}
void HTMLMediaElement::setLoopEnd(float time)
@@ -775,7 +786,7 @@ void HTMLMediaElement::setVolume(float vol, ExceptionCode& ec)
if (m_volume != vol) {
m_volume = vol;
updateVolume();
- dispatchEventAsync(volumechangeEvent);
+ dispatchEventAsync(eventNames().volumechangeEvent);
}
}
@@ -789,7 +800,7 @@ void HTMLMediaElement::setMuted(bool muted)
if (m_muted != muted) {
m_muted = muted;
updateVolume();
- dispatchEventAsync(volumechangeEvent);
+ dispatchEventAsync(eventNames().volumechangeEvent);
}
}
@@ -809,23 +820,29 @@ String HTMLMediaElement::pickMedia()
if (!source->hasAttribute(srcAttr))
continue;
if (source->hasAttribute(mediaAttr)) {
- MediaQueryEvaluator screenEval("screen", document()->page(), renderer() ? renderer()->style() : 0);
- RefPtr<MediaList> media = new MediaList((CSSStyleSheet*)0, source->media(), true);
+ MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
+ RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(source->media());
if (!screenEval.eval(media.get()))
continue;
}
if (source->hasAttribute(typeAttr)) {
- String type = source->type();
+ String type = source->type().stripWhiteSpace();
+
+ // "type" can have parameters after a semi-colon, strip them before checking with the type registry
+ int semi = type.find(';');
+ if (semi != -1)
+ type = type.left(semi).stripWhiteSpace();
+
if (!MIMETypeRegistry::isSupportedMediaMIMEType(type))
continue;
}
- mediaSrc = source->src();
+ mediaSrc = source->src().string();
break;
}
}
}
if (!mediaSrc.isEmpty())
- mediaSrc = document()->completeURL(mediaSrc);
+ mediaSrc = document()->completeURL(mediaSrc).string();
return mediaSrc;
}
@@ -872,12 +889,12 @@ void HTMLMediaElement::mediaPlayerTimeChanged(MediaPlayer*)
ExceptionCode ec;
seek(effectiveLoopStart(), ec);
m_currentLoop++;
- dispatchHTMLEvent(timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
}
if (m_currentLoop == playCount() - 1 && currentTime() >= effectiveEnd()) {
- dispatchHTMLEvent(timeupdateEvent, false, true);
- dispatchHTMLEvent(endedEvent, false, true);
+ dispatchEventForType(eventNames().timeupdateEvent, false, true);
+ dispatchEventForType(eventNames().endedEvent, false, true);
}
updatePlayState();
@@ -893,22 +910,22 @@ PassRefPtr<TimeRanges> HTMLMediaElement::buffered() const
{
// FIXME real ranges support
if (!m_player || !m_player->maxTimeBuffered())
- return new TimeRanges;
- return new TimeRanges(0, m_player->maxTimeBuffered());
+ return TimeRanges::create();
+ return TimeRanges::create(0, m_player->maxTimeBuffered());
}
PassRefPtr<TimeRanges> HTMLMediaElement::played() const
{
// FIXME track played
- return new TimeRanges;
+ return TimeRanges::create();
}
PassRefPtr<TimeRanges> HTMLMediaElement::seekable() const
{
// FIXME real ranges support
if (!m_player || !m_player->maxTimeSeekable())
- return new TimeRanges;
- return new TimeRanges(0, m_player->maxTimeSeekable());
+ return TimeRanges::create();
+ return TimeRanges::create(0, m_player->maxTimeSeekable());
}
float HTMLMediaElement::effectiveStart() const
@@ -988,8 +1005,8 @@ void HTMLMediaElement::setPausedInternal(bool b)
m_pausedInternal = b;
updatePlayState();
}
-
-void HTMLMediaElement::willSaveToCache()
+
+void HTMLMediaElement::documentWillBecomeInactive()
{
// 3.14.9.4. Loading the media resource
// 14
@@ -998,26 +1015,26 @@ void HTMLMediaElement::willSaveToCache()
m_player.clear();
m_progressEventTimer.stop();
- m_error = new MediaError(MediaError::MEDIA_ERR_ABORTED);
+ m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
m_begun = false;
- initAndDispatchProgressEvent(abortEvent);
+ initAndDispatchProgressEvent(eventNames().abortEvent);
if (m_networkState >= LOADING) {
m_networkState = EMPTY;
- dispatchHTMLEvent(emptiedEvent, false, true);
+ m_readyState = DATA_UNAVAILABLE;
+ dispatchEventForType(eventNames().emptiedEvent, false, true);
}
}
- m_inPageCache = true;
+ m_inActiveDocument = false;
// Stop the playback without generating events
setPausedInternal(true);
- if (m_player)
- m_player->setVisible(false);
+
if (renderer())
renderer()->updateFromElement();
}
-void HTMLMediaElement::didRestoreFromCache()
+void HTMLMediaElement::documentDidBecomeActive()
{
- m_inPageCache = false;
+ m_inActiveDocument = true;
setPausedInternal(false);
if (m_error && m_error->code() == MediaError::MEDIA_ERR_ABORTED) {
@@ -1035,6 +1052,8 @@ void HTMLMediaElement::defaultEventHandler(Event* event)
{
if (renderer() && renderer()->isMedia())
static_cast<RenderMedia*>(renderer())->forwardEvent(event);
+ if (event->defaultHandled())
+ return;
HTMLElement::defaultEventHandler(event);
}