diff options
Diffstat (limited to 'WebCore/html/HTMLMediaElement.cpp')
-rw-r--r-- | WebCore/html/HTMLMediaElement.cpp | 161 |
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); } |