| Index: third_party/WebKit/Source/core/dom/ScriptLoader.cpp
|
| diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
|
| index 471a724b2edecac67d544a5c94e8991e2f113b74..db953339834b6d2b3d2d61822f5232d4827d7f97 100644
|
| --- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
|
| +++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
|
| @@ -36,6 +36,7 @@
|
| #include "core/events/Event.h"
|
| #include "core/fetch/AccessControlStatus.h"
|
| #include "core/fetch/FetchRequest.h"
|
| +#include "core/fetch/MemoryCache.h"
|
| #include "core/fetch/ResourceFetcher.h"
|
| #include "core/fetch/ScriptResource.h"
|
| #include "core/frame/LocalFrame.h"
|
| @@ -50,6 +51,7 @@
|
| #include "core/svg/SVGScriptElement.h"
|
| #include "platform/MIMETypeRegistry.h"
|
| #include "platform/weborigin/SecurityOrigin.h"
|
| +#include "public/platform/WebCachePolicy.h"
|
| #include "public/platform/WebFrameScheduler.h"
|
| #include "wtf/StdLibExtras.h"
|
| #include "wtf/text/StringBuilder.h"
|
| @@ -57,7 +59,7 @@
|
|
|
| namespace blink {
|
|
|
| -ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadyStarted, bool createdDuringDocumentWrite)
|
| +ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadyStarted, bool createdDuringDocumentWrite, bool blockedDocWriteScriptAsyncFetch)
|
| : m_element(element)
|
| , m_startLineNumber(WTF::OrdinalNumber::beforeFirst())
|
| , m_parserInserted(parserInserted)
|
| @@ -70,10 +72,14 @@ ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt
|
| , m_willExecuteWhenDocumentFinishedParsing(false)
|
| , m_forceAsync(!parserInserted)
|
| , m_createdDuringDocumentWrite(createdDuringDocumentWrite)
|
| + , m_disallowedFetchForDocWrittenScript(false)
|
| + , m_blockedDocWriteScriptAsyncFetch(blockedDocWriteScriptAsyncFetch)
|
| {
|
| DCHECK(m_element);
|
| if (parserInserted && element->document().scriptableDocumentParser() && !element->document().isInDocumentWrite())
|
| m_startLineNumber = element->document().scriptableDocumentParser()->lineNumber();
|
| + if (m_blockedDocWriteScriptAsyncFetch)
|
| + DCHECK(!m_createdDuringDocumentWrite);
|
| }
|
|
|
| ScriptLoader::~ScriptLoader()
|
| @@ -238,12 +244,21 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
|
|
|
| if (client->hasSourceAttribute()) {
|
| FetchRequest::DeferOption defer = FetchRequest::NoDefer;
|
| - if (!m_parserInserted || client->asyncAttributeValue() || client->deferAttributeValue())
|
| + if (!m_parserInserted || client->asyncAttributeValue() || client->deferAttributeValue() || m_blockedDocWriteScriptAsyncFetch)
|
| defer = FetchRequest::LazyLoad;
|
| if (!fetchScript(client->sourceAttributeValue(), defer))
|
| return false;
|
| }
|
|
|
| + // Since the asynchronous, low priority fetch for doc.written blocked
|
| + // script is not for execution, return early from here. Watch for its
|
| + // completion to be able to remove it from the memory cache.
|
| + if (m_blockedDocWriteScriptAsyncFetch) {
|
| + m_pendingScript = PendingScript::create(m_element, m_resource.get());
|
| + m_pendingScript->watchForLoad(this);
|
| + return true;
|
| + }
|
| +
|
| if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parserInserted && !client->asyncAttributeValue()) {
|
| m_willExecuteWhenDocumentFinishedParsing = true;
|
| m_willBeParserExecuted = true;
|
| @@ -317,16 +332,29 @@ bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOptio
|
| request.setIntegrityMetadata(metadataSet);
|
| }
|
|
|
| + if (m_blockedDocWriteScriptAsyncFetch) {
|
| + // Set interventions info in resourceRequest so that priority can
|
| + // be set accordingly.
|
| + request.mutableResourceRequest().setInterventionsInfo(InterventionsFlag::InterventionBlockedDocWriteScriptAsyncFetch);
|
| + request.mutableResourceRequest().setHTTPHeaderField("Intervention", "<https://www.chromestatus.com/feature/5718547946799104>");
|
| + }
|
| +
|
| m_resource = ScriptResource::fetch(request, elementDocument->fetcher());
|
|
|
| m_isExternalScript = true;
|
| }
|
|
|
| - if (m_resource)
|
| - return true;
|
| + if (!m_resource) {
|
| + dispatchErrorEvent();
|
| + return false;
|
| + }
|
|
|
| - dispatchErrorEvent();
|
| - return false;
|
| + if (m_createdDuringDocumentWrite && m_resource->resourceRequest().getCachePolicy() == WebCachePolicy::ReturnCacheDataDontLoad) {
|
| + DCHECK(!m_blockedDocWriteScriptAsyncFetch);
|
| + m_disallowedFetchForDocWrittenScript = true;
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
| bool isHTMLScriptLoader(Element* element)
|
| @@ -459,6 +487,16 @@ void ScriptLoader::notifyFinished(Resource* resource)
|
| {
|
| DCHECK(!m_willBeParserExecuted);
|
|
|
| + // We do not need this script in the memory cache. The primary goals of
|
| + // sending this fetch request is to let the third party server know
|
| + // about the document.write scripts intervention and populate the http
|
| + // cache for subsequent uses.
|
| + if (m_blockedDocWriteScriptAsyncFetch) {
|
| + memoryCache()->remove(resource);
|
| + m_pendingScript->stopWatchingForLoad();
|
| + return;
|
| + }
|
| +
|
| Document* contextDocument = m_element->document().contextDocument();
|
| if (!contextDocument) {
|
| detach();
|
|
|