diff options
author | Iain Merrick <husky@google.com> | 2010-08-19 17:55:56 +0100 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-08-23 11:05:40 +0100 |
commit | f486d19d62f1bc33246748b14b14a9dfa617b57f (patch) | |
tree | 195485454c93125455a30e553a73981c3816144d /WebCore/html/HTMLScriptRunner.cpp | |
parent | 6ba0b43722d16bc295606bec39f396f596e4fef1 (diff) | |
download | external_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.cpp | 84 |
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); } |