Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Unified Diff: Source/WebCore/html/HTMLMediaElement.cpp

Issue 9910031: Merge 111895 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1025/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/WebCore/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/WebCore/html/HTMLMediaElement.cpp
===================================================================
--- Source/WebCore/html/HTMLMediaElement.cpp (revision 112578)
+++ Source/WebCore/html/HTMLMediaElement.cpp (working copy)
@@ -190,8 +190,6 @@
, m_lastTimeUpdateEventWallTime(0)
, m_lastTimeUpdateEventMovieTime(numeric_limits<float>::max())
, m_loadState(WaitingForSource)
- , m_currentSourceNode(0)
- , m_nextChildNodeToConsider(0)
#if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
, m_proxyWidget(0)
#endif
@@ -548,6 +546,8 @@
void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
{
+ RefPtr<HTMLMediaElement> protect(this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
+
if (m_pendingLoadFlags & MediaResource) {
if (m_loadState == LoadingFromSourceElement)
loadNextSourceChild();
@@ -604,6 +604,8 @@
void HTMLMediaElement::load(ExceptionCode& ec)
{
+ RefPtr<HTMLMediaElement> protect(this); // loadInternal may result in a 'beforeload' event, which can make arbitrary DOM mutations.
+
LOG(Media, "HTMLMediaElement::load()");
if (userGestureRequiredForLoad() && !ScriptController::processingUserGesture())
@@ -757,7 +759,7 @@
// source element child in tree order.
if (node) {
mode = children;
- m_nextChildNodeToConsider = 0;
+ m_nextChildNodeToConsider = node;
m_currentSourceNode = 0;
} else {
// Otherwise the media element has neither a src attribute nor a source element
@@ -2451,8 +2453,8 @@
{
// Stash the current <source> node and next nodes so we can restore them after checking
// to see there is another potential.
- HTMLSourceElement* currentSourceNode = m_currentSourceNode;
- Node* nextNode = m_nextChildNodeToConsider;
+ RefPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNode;
+ RefPtr<Node> nextNode = m_nextChildNodeToConsider;
KURL nextURL = selectNextSourceChild(0, DoNothing);
@@ -2471,7 +2473,7 @@
LOG(Media, "HTMLMediaElement::selectNextSourceChild");
#endif
- if (m_nextChildNodeToConsider == sourceChildEndOfListValue()) {
+ if (!m_nextChildNodeToConsider) {
#if !LOG_DISABLED
if (shouldLog)
LOG(Media, "HTMLMediaElement::selectNextSourceChild -> 0x0000, \"\"");
@@ -2482,16 +2484,24 @@
KURL mediaURL;
Node* node;
HTMLSourceElement* source = 0;
+ String type;
bool lookingForStartNode = m_nextChildNodeToConsider;
- bool canUse = false;
+ bool canUseSourceElement = false;
+ bool okToLoadSourceURL;
- for (node = firstChild(); !canUse && node; node = node->nextSibling()) {
+ NodeVector potentialSourceNodes;
+ getChildNodes(this, potentialSourceNodes);
+
+ for (unsigned i = 0; !canUseSourceElement && i < potentialSourceNodes.size(); ++i) {
+ node = potentialSourceNodes[i].get();
if (lookingForStartNode && m_nextChildNodeToConsider != node)
continue;
lookingForStartNode = false;
-
+
if (!node->hasTagName(sourceTag))
continue;
+ if (node->parentNode() != this)
+ continue;
source = static_cast<HTMLSourceElement*>(node);
@@ -2525,34 +2535,41 @@
}
// Is it safe to load this url?
- if (!isSafeToLoadURL(mediaURL, actionIfInvalid) || !dispatchBeforeLoadEvent(mediaURL.string()))
+ okToLoadSourceURL = isSafeToLoadURL(mediaURL, actionIfInvalid) && dispatchBeforeLoadEvent(mediaURL.string());
+
+ // A 'beforeload' event handler can mutate the DOM, so check to see if the source element is still a child node.
+ if (node->parentNode() != this) {
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild : 'beforeload' removed current element");
+ source = 0;
goto check_again;
+ }
+ if (!okToLoadSourceURL)
+ goto check_again;
+
// Making it this far means the <source> looks reasonable.
- canUse = true;
+ canUseSourceElement = true;
check_again:
- if (!canUse && actionIfInvalid == Complain)
+ if (!canUseSourceElement && actionIfInvalid == Complain && source)
source->scheduleErrorEvent();
}
- if (canUse) {
+ if (canUseSourceElement) {
if (contentType)
*contentType = ContentType(source->type());
m_currentSourceNode = source;
m_nextChildNodeToConsider = source->nextSibling();
- if (!m_nextChildNodeToConsider)
- m_nextChildNodeToConsider = sourceChildEndOfListValue();
} else {
m_currentSourceNode = 0;
- m_nextChildNodeToConsider = sourceChildEndOfListValue();
+ m_nextChildNodeToConsider = 0;
}
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL).utf8().data() : "");
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode.get(), canUseSourceElement ? urlForLogging(mediaURL).utf8().data() : "");
#endif
- return canUse ? mediaURL : KURL();
+ return canUseSourceElement ? mediaURL : KURL();
}
void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
@@ -2584,20 +2601,20 @@
return;
}
- if (m_nextChildNodeToConsider != sourceChildEndOfListValue())
+ if (m_nextChildNodeToConsider)
return;
// 4.8.9.5, resource selection algorithm, source elements section:
- // 20 - Wait until the node after pointer is a node other than the end of the list. (This step might wait forever.)
- // 21 - Asynchronously await a stable state...
- // 22 - Set the element's delaying-the-load-event flag back to true (this delays the load event again, in case
+ // 21. Wait until the node after pointer is a node other than the end of the list. (This step might wait forever.)
+ // 22. Asynchronously await a stable state...
+ // 23. Set the element's delaying-the-load-event flag back to true (this delays the load event again, in case
// it hasn't been fired yet).
setShouldDelayLoadEvent(true);
- // 23 - Set the networkState back to NETWORK_LOADING.
+ // 24. Set the networkState back to NETWORK_LOADING.
m_networkState = NETWORK_LOADING;
- // 24 - Jump back to the find next candidate step above.
+ // 25. Jump back to the find next candidate step above.
m_nextChildNodeToConsider = source;
scheduleNextSourceChild();
}
@@ -2619,8 +2636,8 @@
if (source == m_nextChildNodeToConsider) {
m_nextChildNodeToConsider = m_nextChildNodeToConsider->nextSibling();
if (!m_nextChildNodeToConsider)
- m_nextChildNodeToConsider = sourceChildEndOfListValue();
- LOG(Media, "HTMLMediaElement::sourceRemoved - m_nextChildNodeToConsider set to %p", m_nextChildNodeToConsider);
+ m_nextChildNodeToConsider = 0;
+ LOG(Media, "HTMLMediaElement::sourceRemoved - m_nextChildNodeToConsider set to %p", m_nextChildNodeToConsider.get());
} else if (source == m_currentSourceNode) {
// Clear the current source node pointer, but don't change the movie as the spec says:
// 4.8.8 - Dynamically modifying a source element and its attribute when the element is already
@@ -3212,6 +3229,8 @@
void HTMLMediaElement::getPluginProxyParams(KURL& url, Vector<String>& names, Vector<String>& values)
{
+ RefPtr<HTMLMediaElement> protect(this); // selectNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
+
Frame* frame = document()->frame();
if (isVideo()) {
« no previous file with comments | « Source/WebCore/html/HTMLMediaElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698