summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLScriptRunner.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-07-08 12:51:48 +0100
committerSteve Block <steveblock@google.com>2010-07-09 15:33:40 +0100
commitca9cb53ed1119a3fd98fafa0972ffeb56dee1c24 (patch)
treebb45155550ec013adc0ad10f4d7d354c6469b022 /WebCore/html/HTMLScriptRunner.cpp
parentd4b24d9a829ed7de70381c8b99fb75a07ab40466 (diff)
downloadexternal_webkit-ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24.zip
external_webkit-ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24.tar.gz
external_webkit-ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24.tar.bz2
Merge WebKit at r62496: Initial merge by git
Change-Id: Ie3da0770eca22a70a632e3571f31cfabc80facb2
Diffstat (limited to 'WebCore/html/HTMLScriptRunner.cpp')
-rw-r--r--WebCore/html/HTMLScriptRunner.cpp93
1 files changed, 52 insertions, 41 deletions
diff --git a/WebCore/html/HTMLScriptRunner.cpp b/WebCore/html/HTMLScriptRunner.cpp
index ab35449..29790c0 100644
--- a/WebCore/html/HTMLScriptRunner.cpp
+++ b/WebCore/html/HTMLScriptRunner.cpp
@@ -74,7 +74,7 @@ HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* hos
HTMLScriptRunner::~HTMLScriptRunner()
{
// FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction?
- if (m_parsingBlockingScript.cachedScript && m_parsingBlockingScript.watchingForLoad())
+ if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parsingBlockingScript);
}
@@ -99,10 +99,10 @@ inline PassRefPtr<Event> createScriptErrorEvent()
ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred)
{
- if (script.cachedScript) {
- errorOccurred = script.cachedScript->errorOccurred();
- ASSERT(script.cachedScript->isLoaded());
- return ScriptSourceCode(script.cachedScript.get());
+ if (script.cachedScript()) {
+ errorOccurred = script.cachedScript()->errorOccurred();
+ ASSERT(script.cachedScript()->isLoaded());
+ return ScriptSourceCode(script.cachedScript());
}
errorOccurred = false;
return ScriptSourceCode(script.element->textContent(), documentURLForScriptExecution(m_document), script.startingLineNumber);
@@ -113,7 +113,7 @@ bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
m_hasScriptsWaitingForStylesheets = !m_document->haveStylesheetsLoaded();
if (m_hasScriptsWaitingForStylesheets)
return false;
- if (script.cachedScript && !script.cachedScript->isLoaded())
+ if (script.cachedScript() && !script.cachedScript()->isLoaded())
return false;
return true;
}
@@ -127,12 +127,11 @@ void HTMLScriptRunner::executePendingScript()
ScriptSourceCode sourceCode = sourceFromPendingScript(m_parsingBlockingScript, errorOccurred);
// Stop watching loads before executeScript to prevent recursion if the script reloads itself.
- if (m_parsingBlockingScript.cachedScript && m_parsingBlockingScript.watchingForLoad())
+ if (m_parsingBlockingScript.cachedScript() && m_parsingBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parsingBlockingScript);
// Clear the pending script before possible rentrancy from executeScript()
- RefPtr<Element> scriptElement = m_parsingBlockingScript.element.release();
- m_parsingBlockingScript = PendingScript();
+ RefPtr<Element> scriptElement = m_parsingBlockingScript.releaseElementAndClear();
{
NestScript nestingLevel(m_scriptNestingLevel, m_host->inputStream());
if (errorOccurred)
@@ -161,30 +160,18 @@ void HTMLScriptRunner::executeScript(Element* element, const ScriptSourceCode& s
m_document->frame()->script()->executeScript(sourceCode);
}
-bool HTMLScriptRunner::hasScriptsWaitingForLoad() const
-{
- // We're only actually waiting for a load. This allows us to ignore load
- // callbacks when CachedResource::addClient calls notifyFinished because
- // of a cache hit (not because of a load we were set up to wait for).
- return m_parsingBlockingScript.watchingForLoadState == PendingScript::WatchingForLoad;
-}
-
void HTMLScriptRunner::watchForLoad(PendingScript& pendingScript)
{
ASSERT(!pendingScript.watchingForLoad());
- // CachedResource::addClient will call notifyFinished if the load is already
- // complete. We set watchingForLoadState to RegisteringForWatch so that we
- // know to ignore any notifyFinished call during addClient.
- pendingScript.watchingForLoadState = PendingScript::RegisteringForWatch;
- m_host->watchForLoad(pendingScript.cachedScript.get());
- pendingScript.watchingForLoadState = PendingScript::WatchingForLoad;
+ m_host->watchForLoad(pendingScript.cachedScript());
+ pendingScript.setWatchingForLoad(true);
}
void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
{
ASSERT(pendingScript.watchingForLoad());
- m_host->stopWatchingForLoad(pendingScript.cachedScript.get());
- pendingScript.watchingForLoadState = PendingScript::NotWatchingForLoad;
+ m_host->stopWatchingForLoad(pendingScript.cachedScript());
+ pendingScript.setWatchingForLoad(false);
}
// This function should match 10.2.5.11 "An end tag whose tag name is 'script'"
@@ -224,14 +211,10 @@ bool HTMLScriptRunner::executeParsingBlockingScripts()
bool HTMLScriptRunner::executeScriptsWaitingForLoad(CachedResource* cachedScript)
{
- // Callers should check hasScriptsWaitingForLoad() before calling
- // to prevent parser or script re-entry during due to
- // CachedResource::addClient calling notifyFinished on cache-hits.
- ASSERT(hasScriptsWaitingForLoad());
ASSERT(!m_scriptNestingLevel);
ASSERT(haveParsingBlockingScript());
- ASSERT_UNUSED(cachedScript, m_parsingBlockingScript.cachedScript == cachedScript);
- ASSERT(m_parsingBlockingScript.cachedScript->isLoaded());
+ ASSERT_UNUSED(cachedScript, m_parsingBlockingScript.cachedScript() == cachedScript);
+ ASSERT(m_parsingBlockingScript.cachedScript()->isLoaded());
return executeParsingBlockingScripts();
}
@@ -262,16 +245,14 @@ void HTMLScriptRunner::requestScript(Element* script)
notImplemented(); // Dispatch error event.
return;
}
- m_parsingBlockingScript.cachedScript = cachedScript;
-
- // Always call watchForLoad, even if the script is already loaded.
- // CachedResource may purge its data if it has no clients, which would cause
- // later script execution to fail. watchForLoad sets m_parsingBlockingScript
- // to the RegisteringForWatch state so we know to ignore any
- // executeScriptsWaitingForLoad callbacks during the watchForLoad call.
- watchForLoad(m_parsingBlockingScript);
- // Callers will attempt to run the m_parsingBlockingScript if possible
- // before returning control to the parser.
+
+ m_parsingBlockingScript.setCachedScript(cachedScript);
+
+ // We only care about a load callback if cachedScript is not already
+ // in the cache. Callers will attempt to run the m_parsingBlockingScript
+ // if possible before returning control to the parser.
+ if (!m_parsingBlockingScript.cachedScript()->isLoaded())
+ watchForLoad(m_parsingBlockingScript);
}
// This method is meant to match the HTML5 definition of "running a script"
@@ -297,4 +278,34 @@ void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
}
}
+HTMLScriptRunner::PendingScript::~PendingScript()
+{
+ if (m_cachedScript)
+ m_cachedScript->removeClient(this);
+}
+
+PassRefPtr<Element> HTMLScriptRunner::PendingScript::releaseElementAndClear()
+{
+ setCachedScript(0);
+ startingLineNumber = 0;
+ m_watchingForLoad = false;
+ return element.release();
+}
+
+void HTMLScriptRunner::PendingScript::setCachedScript(CachedScript* cachedScript)
+{
+ if (m_cachedScript == cachedScript)
+ return;
+ if (m_cachedScript)
+ m_cachedScript->removeClient(this);
+ m_cachedScript = cachedScript;
+ if (m_cachedScript)
+ m_cachedScript->addClient(this);
+}
+
+CachedScript* HTMLScriptRunner::PendingScript::cachedScript() const
+{
+ return m_cachedScript.get();
+}
+
}