Chromium Code Reviews| Index: Source/core/dom/ScriptLoader.cpp |
| diff --git a/Source/core/dom/ScriptLoader.cpp b/Source/core/dom/ScriptLoader.cpp |
| index e42b6c3a4a677732385876f272c720aae91400b7..5154b2e8c911d8d8e775360ea8a289c0703a835c 100644 |
| --- a/Source/core/dom/ScriptLoader.cpp |
| +++ b/Source/core/dom/ScriptLoader.cpp |
| @@ -35,6 +35,7 @@ |
| #include "core/dom/ScriptRunner.h" |
| #include "core/dom/ScriptableDocumentParser.h" |
| #include "core/dom/Text.h" |
| +#include "core/html/HTMLImportsController.h" |
| #include "core/html/HTMLScriptElement.h" |
| #include "core/html/parser/HTMLParserIdioms.h" |
| #include "core/loader/cache/CachedResourceLoader.h" |
| @@ -165,6 +166,14 @@ bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) c |
| return false; |
| } |
| +Document* ScriptLoader::executingDocument() const |
| +{ |
| + Document* document = m_element->document(); |
| + if (!document->import()) |
| + return document; |
| + return document->import()->master(); |
| +} |
| + |
| // http://dev.w3.org/html5/spec/Overview.html#prepare-a-script |
| bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, LegacyTypeSupport supportLegacyTypes) |
| { |
| @@ -202,15 +211,16 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy |
| m_alreadyStarted = true; |
| // FIXME: If script is parser inserted, verify it's still in the original document. |
| - Document* document = m_element->document(); |
| + Document* executingDocument = this->executingDocument(); |
| + Document* elementDocument = m_element->document(); |
| // FIXME: Eventually we'd like to evaluate scripts which are inserted into a |
| // viewless document but this'll do for now. |
| // See http://bugs.webkit.org/show_bug.cgi?id=5727 |
| - if (!document->frame()) |
| + if (!executingDocument->frame()) |
| return false; |
| - if (!document->frame()->script()->canExecuteScripts(AboutToExecuteScript)) |
| + if (!executingDocument->frame()->script()->canExecuteScripts(AboutToExecuteScript)) |
| return false; |
| if (!isScriptForEventSupported()) |
| @@ -219,7 +229,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy |
| if (!client->charsetAttributeValue().isEmpty()) |
| m_characterEncoding = client->charsetAttributeValue(); |
| else |
| - m_characterEncoding = document->charset(); |
| + m_characterEncoding = elementDocument->charset(); |
| if (client->hasSourceAttribute()) { |
| if (!requestScript(client->sourceAttributeValue())) |
| @@ -231,20 +241,20 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy |
| m_willBeParserExecuted = true; |
| } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) { |
| m_willBeParserExecuted = true; |
| - } else if (!client->hasSourceAttribute() && m_parserInserted && !document->haveStylesheetsAndImportsLoaded()) { |
| + } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument->haveStylesheetsAndImportsLoaded()) { |
| m_willBeParserExecuted = true; |
| m_readyToBeParserExecuted = true; |
| } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) { |
| m_willExecuteInOrder = true; |
| - document->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::IN_ORDER_EXECUTION); |
| + executingDocument->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::IN_ORDER_EXECUTION); |
| m_cachedScript->addClient(this); |
| } else if (client->hasSourceAttribute()) { |
| - document->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::ASYNC_EXECUTION); |
| + executingDocument->scriptRunner()->queueScriptForExecution(this, m_cachedScript, ScriptRunner::ASYNC_EXECUTION); |
| m_cachedScript->addClient(this); |
| } else { |
| // Reset line numbering for nested writes. |
| - TextPosition position = document->isInDocumentWrite() ? TextPosition() : scriptStartPosition; |
| - KURL scriptURL = (!document->isInDocumentWrite() && m_parserInserted) ? document->url() : KURL(); |
| + TextPosition position = elementDocument->isInDocumentWrite() ? TextPosition() : scriptStartPosition; |
| + KURL scriptURL = (!elementDocument->isInDocumentWrite() && m_parserInserted) ? elementDocument->url() : KURL(); |
| executeScript(ScriptSourceCode(scriptContent(), scriptURL, position)); |
| } |
| @@ -255,28 +265,28 @@ bool ScriptLoader::requestScript(const String& sourceUrl) |
| { |
| ASSERT(m_element); |
| - RefPtr<Document> originalDocument = m_element->document(); |
| + RefPtr<Document> elementDocument = m_element->document(); |
| if (!m_element->dispatchBeforeLoadEvent(sourceUrl)) |
| return false; |
| - if (!m_element->inDocument() || m_element->document() != originalDocument) |
| + if (!m_element->inDocument() || m_element->document() != elementDocument) |
| return false; |
| ASSERT(!m_cachedScript); |
| if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
| - CachedResourceRequest request(ResourceRequest(m_element->document()->completeURL(sourceUrl)), m_element->localName()); |
| + CachedResourceRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName()); |
| String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr); |
| if (!crossOriginMode.isNull()) { |
| StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; |
| - request.setPotentiallyCrossOriginEnabled(m_element->document()->securityOrigin(), allowCredentials); |
| + request.setPotentiallyCrossOriginEnabled(elementDocument->securityOrigin(), allowCredentials); |
| } |
| request.setCharset(scriptCharset()); |
| - bool isValidScriptNonce = m_element->document()->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
| + bool isValidScriptNonce = elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
| if (isValidScriptNonce) |
| request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy); |
| - m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(request); |
| + m_cachedScript = elementDocument->cachedResourceLoader()->requestScript(request); |
| m_isExternalScript = true; |
| } |
| @@ -305,24 +315,25 @@ void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) |
| if (sourceCode.isEmpty()) |
| return; |
| - RefPtr<Document> document = m_element->document(); |
| - Frame* frame = document->frame(); |
| + RefPtr<Document> executingDocument = this->executingDocument(); |
| + RefPtr<Document> elementDocument = m_element->document(); |
| + Frame* frame = executingDocument->frame(); |
| - bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()->shouldBypassMainWorldContentSecurityPolicy()) || document->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
| + bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script()->shouldBypassMainWorldContentSecurityPolicy()) || executingDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)); |
| - if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !document->contentSecurityPolicy()->allowInlineScript(document->url(), m_startLineNumber))) |
| + if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !executingDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url(), m_startLineNumber))) |
| return; |
|
abarth-chromium
2013/07/19 07:55:55
I'm not sure whether this check is right. I think
|
| if (m_isExternalScript && m_cachedScript && !m_cachedScript->mimeTypeAllowedByNosniff()) { |
| - document->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_cachedScript->url().elidedString() + "' because its MIME type ('" + m_cachedScript->mimeType() + "') is not executable, and strict MIME type checking is enabled."); |
| + executingDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_cachedScript->url().elidedString() + "' because its MIME type ('" + m_cachedScript->mimeType() + "') is not executable, and strict MIME type checking is enabled."); |
|
abarth-chromium
2013/07/19 07:55:55
Please add a test for this case as well.
|
| return; |
| } |
| if (frame) { |
| - IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? document.get() : 0); |
| + IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? executingDocument.get() : 0); |
| if (isHTMLScriptLoader(m_element)) |
| - document->pushCurrentScript(toHTMLScriptElement(m_element)); |
| + executingDocument->pushCurrentScript(toHTMLScriptElement(m_element)); |
| // Create a script from the script element node, using the script |
| // block's source and the script block's type. |
| @@ -330,8 +341,8 @@ void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode) |
| frame->script()->executeScriptInMainWorld(sourceCode); |
| if (isHTMLScriptLoader(m_element)) { |
| - ASSERT(document->currentScript() == m_element); |
| - document->popCurrentScript(); |
| + ASSERT(executingDocument->currentScript() == m_element); |
| + executingDocument->popCurrentScript(); |
| } |
| } |
| } |
| @@ -362,6 +373,9 @@ void ScriptLoader::notifyFinished(CachedResource* resource) |
| { |
| ASSERT(!m_willBeParserExecuted); |
| + RefPtr<Document> executingDocument = this->executingDocument(); |
| + RefPtr<Document> elementDocument = m_element->document(); |
| + |
| // CachedResource possibly invokes this notifyFinished() more than |
| // once because ScriptLoader doesn't unsubscribe itself from |
| // CachedResource here and does it in execute() instead. |
| @@ -369,15 +383,15 @@ void ScriptLoader::notifyFinished(CachedResource* resource) |
| ASSERT_UNUSED(resource, resource == m_cachedScript); |
| if (!m_cachedScript) |
| return; |
| - if (!m_element->document()->cachedResourceLoader()->canAccess(m_cachedScript.get())) { |
| + if (!elementDocument->cachedResourceLoader()->canAccess(m_cachedScript.get())) { |
| dispatchErrorEvent(); |
| return; |
| } |
| if (m_willExecuteInOrder) |
| - m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION); |
| + executingDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION); |
| else |
| - m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION); |
| + executingDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION); |
| m_cachedScript = 0; |
| } |