summaryrefslogtreecommitdiffstats
path: root/WebCore/html/HTMLScriptRunner.cpp
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-08-19 17:55:56 +0100
committerIain Merrick <husky@google.com>2010-08-23 11:05:40 +0100
commitf486d19d62f1bc33246748b14b14a9dfa617b57f (patch)
tree195485454c93125455a30e553a73981c3816144d /WebCore/html/HTMLScriptRunner.cpp
parent6ba0b43722d16bc295606bec39f396f596e4fef1 (diff)
downloadexternal_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.zip
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.gz
external_webkit-f486d19d62f1bc33246748b14b14a9dfa617b57f.tar.bz2
Merge WebKit at r65615 : Initial merge by git.
Change-Id: Ifbf384f4531e3b58475a662e38195c2d9152ae79
Diffstat (limited to 'WebCore/html/HTMLScriptRunner.cpp')
-rw-r--r--WebCore/html/HTMLScriptRunner.cpp84
1 files changed, 49 insertions, 35 deletions
diff --git a/WebCore/html/HTMLScriptRunner.cpp b/WebCore/html/HTMLScriptRunner.cpp
index 4a9058f..0d603ed 100644
--- a/WebCore/html/HTMLScriptRunner.cpp
+++ b/WebCore/html/HTMLScriptRunner.cpp
@@ -43,23 +43,22 @@ namespace WebCore {
using namespace HTMLNames;
-class NestScript : public Noncopyable {
+// FIXME: Factor out to avoid duplication with HTMLDocumentParser.
+class NestingLevelIncrementer : public Noncopyable {
public:
- NestScript(unsigned& nestingLevel, HTMLInputStream& inputStream)
+ explicit NestingLevelIncrementer(unsigned& nestingLevel)
: m_nestingLevel(&nestingLevel)
- , m_savedInsertionPoint(inputStream)
{
++(*m_nestingLevel);
}
- ~NestScript()
+ ~NestingLevelIncrementer()
{
--(*m_nestingLevel);
}
private:
unsigned* m_nestingLevel;
- InsertionPointRecord m_savedInsertionPoint;
};
HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* host)
@@ -97,7 +96,7 @@ inline PassRefPtr<Event> createScriptErrorEvent()
return Event::create(eventNames().errorEvent, true, false);
}
-ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred)
+ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) const
{
if (script.cachedScript()) {
errorOccurred = script.cachedScript()->errorOccurred();
@@ -118,22 +117,29 @@ bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
return true;
}
-void HTMLScriptRunner::executePendingScript()
+void HTMLScriptRunner::executeParsingBlockingScript()
{
ASSERT(!m_scriptNestingLevel);
ASSERT(m_document->haveStylesheetsLoaded());
- bool errorOccurred = false;
ASSERT(isPendingScriptReady(m_parsingBlockingScript));
- 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())
stopWatchingForLoad(m_parsingBlockingScript);
+ InsertionPointRecord insertionPointRecord(m_host->inputStream());
+ executePendingScriptAndDispatchEvent(m_parsingBlockingScript);
+}
+
+void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript)
+{
+ bool errorOccurred = false;
+ ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
+
// Clear the pending script before possible rentrancy from executeScript()
- RefPtr<Element> scriptElement = m_parsingBlockingScript.releaseElementAndClear();
+ RefPtr<Element> scriptElement = pendingScript.releaseElementAndClear();
{
- NestScript nestingLevel(m_scriptNestingLevel, m_host->inputStream());
+ NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
if (errorOccurred)
scriptElement->dispatchEvent(createScriptErrorEvent());
else {
@@ -144,12 +150,8 @@ void HTMLScriptRunner::executePendingScript()
ASSERT(!m_scriptNestingLevel);
}
-void HTMLScriptRunner::executeScript(Element* element, const ScriptSourceCode& sourceCode)
+void HTMLScriptRunner::executeScript(Element* element, const ScriptSourceCode& sourceCode) const
{
- // FIXME: We do not block inline <script> tags on stylesheets for now.
- // When we do, || !element->hasAttribute(srcAttr) should be removed from
- // the ASSERT below. See https://bugs.webkit.org/show_bug.cgi?id=40047
- ASSERT(m_document->haveStylesheetsLoaded() || !element->hasAttribute(srcAttr));
ScriptElement* scriptElement = toScriptElement(element);
ASSERT(scriptElement);
if (!scriptElement->shouldExecuteAsJavaScript())
@@ -204,7 +206,7 @@ bool HTMLScriptRunner::executeParsingBlockingScripts()
// We only really need to check once.
if (!isPendingScriptReady(m_parsingBlockingScript))
return false;
- executePendingScript();
+ executeParsingBlockingScript();
}
return true;
}
@@ -228,31 +230,39 @@ bool HTMLScriptRunner::executeScriptsWaitingForStylesheets()
return executeParsingBlockingScripts();
}
-void HTMLScriptRunner::requestScript(Element* script)
+void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
{
- ASSERT(!m_parsingBlockingScript.element());
- AtomicString srcValue = script->getAttribute(srcAttr);
+ if (!requestPendingScript(m_parsingBlockingScript, element))
+ return;
+
+ ASSERT(m_parsingBlockingScript.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);
+}
+
+bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Element* script) const
+{
+ ASSERT(!pendingScript.element());
+ const AtomicString& srcValue = script->getAttribute(srcAttr);
// Allow the host to disllow script loads (using the XSSAuditor, etc.)
if (!m_host->shouldLoadExternalScriptFromSrc(srcValue))
- return;
+ return false;
// FIXME: We need to resolve the url relative to the element.
if (!script->dispatchBeforeLoadEvent(srcValue))
- return;
- m_parsingBlockingScript.adoptElement(script);
+ return false;
+ pendingScript.adoptElement(script);
// This should correctly return 0 for empty or invalid srcValues.
CachedScript* cachedScript = m_document->docLoader()->requestScript(srcValue, toScriptElement(script)->scriptCharset());
if (!cachedScript) {
notImplemented(); // Dispatch error event.
- return;
+ return false;
}
-
- 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);
+ pendingScript.setCachedScript(cachedScript);
+ return true;
}
// This method is meant to match the HTML5 definition of "running a script"
@@ -261,17 +271,21 @@ void HTMLScriptRunner::runScript(Element* script, int startingLineNumber)
{
ASSERT(!haveParsingBlockingScript());
{
- NestScript nestingLevel(m_scriptNestingLevel, m_host->inputStream());
+ InsertionPointRecord insertionPointRecord(m_host->inputStream());
+ NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
// Check script type and language, current code uses ScriptElement::shouldExecuteAsJavaScript(), but that may not be HTML5 compliant.
notImplemented(); // event for support
if (script->hasAttribute(srcAttr)) {
// FIXME: Handle defer and async
- requestScript(script);
+ requestParsingBlockingScript(script);
} else {
// FIXME: We do not block inline <script> tags on stylesheets to match the
- // old parser for now. See https://bugs.webkit.org/show_bug.cgi?id=40047
+ // old parser for now. When we do, the ASSERT below should be added.
+ // See https://bugs.webkit.org/show_bug.cgi?id=40047
+ // ASSERT(document()->haveStylesheetsLoaded());
+ ASSERT(isExecutingScript());
ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), startingLineNumber);
executeScript(script, sourceCode);
}