Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: third_party/WebKit/Source/core/dom/ScriptLoader.cpp

Issue 2260303002: Sending an async GET request for doc.written blocked scripts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Windows compile error for GetResourcePriority return type fixed. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv ed. 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserv ed.
6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 6 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 19 matching lines...) Expand all
30 #include "core/dom/Document.h" 30 #include "core/dom/Document.h"
31 #include "core/dom/DocumentParserTiming.h" 31 #include "core/dom/DocumentParserTiming.h"
32 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" 32 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
33 #include "core/dom/ScriptLoaderClient.h" 33 #include "core/dom/ScriptLoaderClient.h"
34 #include "core/dom/ScriptRunner.h" 34 #include "core/dom/ScriptRunner.h"
35 #include "core/dom/ScriptableDocumentParser.h" 35 #include "core/dom/ScriptableDocumentParser.h"
36 #include "core/dom/Text.h" 36 #include "core/dom/Text.h"
37 #include "core/events/Event.h" 37 #include "core/events/Event.h"
38 #include "core/fetch/AccessControlStatus.h" 38 #include "core/fetch/AccessControlStatus.h"
39 #include "core/fetch/FetchRequest.h" 39 #include "core/fetch/FetchRequest.h"
40 #include "core/fetch/MemoryCache.h"
40 #include "core/fetch/ResourceFetcher.h" 41 #include "core/fetch/ResourceFetcher.h"
41 #include "core/fetch/ScriptResource.h" 42 #include "core/fetch/ScriptResource.h"
42 #include "core/frame/LocalFrame.h" 43 #include "core/frame/LocalFrame.h"
43 #include "core/frame/SubresourceIntegrity.h" 44 #include "core/frame/SubresourceIntegrity.h"
44 #include "core/frame/UseCounter.h" 45 #include "core/frame/UseCounter.h"
45 #include "core/frame/csp/ContentSecurityPolicy.h" 46 #include "core/frame/csp/ContentSecurityPolicy.h"
46 #include "core/html/CrossOriginAttribute.h" 47 #include "core/html/CrossOriginAttribute.h"
47 #include "core/html/HTMLScriptElement.h" 48 #include "core/html/HTMLScriptElement.h"
48 #include "core/html/imports/HTMLImport.h" 49 #include "core/html/imports/HTMLImport.h"
49 #include "core/html/parser/HTMLParserIdioms.h" 50 #include "core/html/parser/HTMLParserIdioms.h"
50 #include "core/inspector/ConsoleMessage.h" 51 #include "core/inspector/ConsoleMessage.h"
51 #include "core/svg/SVGScriptElement.h" 52 #include "core/svg/SVGScriptElement.h"
52 #include "platform/MIMETypeRegistry.h" 53 #include "platform/MIMETypeRegistry.h"
53 #include "platform/weborigin/SecurityOrigin.h" 54 #include "platform/weborigin/SecurityOrigin.h"
55 #include "public/platform/WebCachePolicy.h"
54 #include "public/platform/WebFrameScheduler.h" 56 #include "public/platform/WebFrameScheduler.h"
55 #include "wtf/StdLibExtras.h" 57 #include "wtf/StdLibExtras.h"
56 #include "wtf/text/StringBuilder.h" 58 #include "wtf/text/StringBuilder.h"
57 #include "wtf/text/StringHash.h" 59 #include "wtf/text/StringHash.h"
58 60
59 namespace blink { 61 namespace blink {
60 62
61 ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt arted, bool createdDuringDocumentWrite) 63 ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt arted, bool createdDuringDocumentWrite)
62 : m_element(element) 64 : m_element(element)
63 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst()) 65 , m_startLineNumber(WTF::OrdinalNumber::beforeFirst())
64 , m_parserInserted(parserInserted) 66 , m_parserInserted(parserInserted)
65 , m_isExternalScript(false) 67 , m_isExternalScript(false)
66 , m_alreadyStarted(alreadyStarted) 68 , m_alreadyStarted(alreadyStarted)
67 , m_haveFiredLoad(false) 69 , m_haveFiredLoad(false)
68 , m_willBeParserExecuted(false) 70 , m_willBeParserExecuted(false)
69 , m_readyToBeParserExecuted(false) 71 , m_readyToBeParserExecuted(false)
70 , m_willExecuteWhenDocumentFinishedParsing(false) 72 , m_willExecuteWhenDocumentFinishedParsing(false)
71 , m_forceAsync(!parserInserted) 73 , m_forceAsync(!parserInserted)
72 , m_createdDuringDocumentWrite(createdDuringDocumentWrite) 74 , m_createdDuringDocumentWrite(createdDuringDocumentWrite)
73 , m_asyncExecType(ScriptRunner::None) 75 , m_asyncExecType(ScriptRunner::None)
76 , m_documentWriteIntervention(DocumentWriteIntervention::DocumentWriteInterv entionNone)
74 { 77 {
75 DCHECK(m_element); 78 DCHECK(m_element);
76 if (parserInserted && element->document().scriptableDocumentParser() && !ele ment->document().isInDocumentWrite()) 79 if (parserInserted && element->document().scriptableDocumentParser() && !ele ment->document().isInDocumentWrite())
77 m_startLineNumber = element->document().scriptableDocumentParser()->line Number(); 80 m_startLineNumber = element->document().scriptableDocumentParser()->line Number();
78 } 81 }
79 82
80 ScriptLoader::~ScriptLoader() 83 ScriptLoader::~ScriptLoader()
81 { 84 {
82 } 85 }
83 86
84 DEFINE_TRACE(ScriptLoader) 87 DEFINE_TRACE(ScriptLoader)
85 { 88 {
86 visitor->trace(m_element); 89 visitor->trace(m_element);
87 visitor->trace(m_resource); 90 visitor->trace(m_resource);
88 visitor->trace(m_pendingScript); 91 visitor->trace(m_pendingScript);
89 ScriptResourceClient::trace(visitor); 92 ScriptResourceClient::trace(visitor);
90 } 93 }
91 94
95 void ScriptLoader::setFetchDocWrittenScriptDeferIdle()
96 {
97 DCHECK(!m_createdDuringDocumentWrite);
98 m_documentWriteIntervention = DocumentWriteIntervention::FetchDocWrittenScri ptDeferIdle;
99 }
100
92 void ScriptLoader::didNotifySubtreeInsertionsToDocument() 101 void ScriptLoader::didNotifySubtreeInsertionsToDocument()
93 { 102 {
94 if (!m_parserInserted) 103 if (!m_parserInserted)
95 prepareScript(); // FIXME: Provide a real starting line number here. 104 prepareScript(); // FIXME: Provide a real starting line number here.
96 } 105 }
97 106
98 void ScriptLoader::childrenChanged() 107 void ScriptLoader::childrenChanged()
99 { 108 {
100 if (!m_parserInserted && m_element->isConnected()) 109 if (!m_parserInserted && m_element->isConnected())
101 prepareScript(); // FIXME: Provide a real starting line number here. 110 prepareScript(); // FIXME: Provide a real starting line number here.
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 240
232 if (!client->charsetAttributeValue().isEmpty()) 241 if (!client->charsetAttributeValue().isEmpty())
233 m_characterEncoding = client->charsetAttributeValue(); 242 m_characterEncoding = client->charsetAttributeValue();
234 else 243 else
235 m_characterEncoding = elementDocument.characterSet(); 244 m_characterEncoding = elementDocument.characterSet();
236 245
237 if (client->hasSourceAttribute()) { 246 if (client->hasSourceAttribute()) {
238 FetchRequest::DeferOption defer = FetchRequest::NoDefer; 247 FetchRequest::DeferOption defer = FetchRequest::NoDefer;
239 if (!m_parserInserted || client->asyncAttributeValue() || client->deferA ttributeValue()) 248 if (!m_parserInserted || client->asyncAttributeValue() || client->deferA ttributeValue())
240 defer = FetchRequest::LazyLoad; 249 defer = FetchRequest::LazyLoad;
250 if (m_documentWriteIntervention == DocumentWriteIntervention::FetchDocWr ittenScriptDeferIdle)
251 defer = FetchRequest::IdleLoad;
241 if (!fetchScript(client->sourceAttributeValue(), defer)) 252 if (!fetchScript(client->sourceAttributeValue(), defer))
242 return false; 253 return false;
243 } 254 }
244 255
256 // Since the asynchronous, low priority fetch for doc.written blocked
257 // script is not for execution, return early from here. Watch for its
258 // completion to be able to remove it from the memory cache.
259 if (m_documentWriteIntervention == DocumentWriteIntervention::FetchDocWritte nScriptDeferIdle) {
260 m_pendingScript = PendingScript::create(m_element, m_resource.get());
261 m_pendingScript->watchForLoad(this);
262 return true;
263 }
264
245 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse rInserted && !client->asyncAttributeValue()) { 265 if (client->hasSourceAttribute() && client->deferAttributeValue() && m_parse rInserted && !client->asyncAttributeValue()) {
246 m_willExecuteWhenDocumentFinishedParsing = true; 266 m_willExecuteWhenDocumentFinishedParsing = true;
247 m_willBeParserExecuted = true; 267 m_willBeParserExecuted = true;
248 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn cAttributeValue()) { 268 } else if (client->hasSourceAttribute() && m_parserInserted && !client->asyn cAttributeValue()) {
249 m_willBeParserExecuted = true; 269 m_willBeParserExecuted = true;
250 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu ment.isScriptExecutionReady()) { 270 } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocu ment.isScriptExecutionReady()) {
251 m_willBeParserExecuted = true; 271 m_willBeParserExecuted = true;
252 m_readyToBeParserExecuted = true; 272 m_readyToBeParserExecuted = true;
253 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) { 273 } else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
254 m_pendingScript = PendingScript::create(m_element, m_resource.get()); 274 m_pendingScript = PendingScript::create(m_element, m_resource.get());
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 } 330 }
311 request.setDefer(defer); 331 request.setDefer(defer);
312 332
313 String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityA ttr); 333 String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityA ttr);
314 if (!integrityAttr.isEmpty()) { 334 if (!integrityAttr.isEmpty()) {
315 IntegrityMetadataSet metadataSet; 335 IntegrityMetadataSet metadataSet;
316 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadat aSet, elementDocument); 336 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadat aSet, elementDocument);
317 request.setIntegrityMetadata(metadataSet); 337 request.setIntegrityMetadata(metadataSet);
318 } 338 }
319 339
340 if (m_documentWriteIntervention == DocumentWriteIntervention::FetchDocWr ittenScriptDeferIdle) {
341 request.mutableResourceRequest().setHTTPHeaderField("Intervention", "<https://www.chromestatus.com/feature/5718547946799104>");
342 }
343
320 m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); 344 m_resource = ScriptResource::fetch(request, elementDocument->fetcher());
321 345
322 m_isExternalScript = true; 346 m_isExternalScript = true;
323 } 347 }
324 348
325 if (m_resource) 349 if (!m_resource) {
326 return true; 350 dispatchErrorEvent();
351 return false;
352 }
327 353
328 dispatchErrorEvent(); 354 if (m_createdDuringDocumentWrite && m_resource->resourceRequest().getCachePo licy() == WebCachePolicy::ReturnCacheDataDontLoad) {
329 return false; 355 m_documentWriteIntervention = DocumentWriteIntervention::DoNotFetchDocWr ittenScript;
356 }
357
358 return true;
330 } 359 }
331 360
332 bool isHTMLScriptLoader(Element* element) 361 bool isHTMLScriptLoader(Element* element)
333 { 362 {
334 DCHECK(element); 363 DCHECK(element);
335 return isHTMLScriptElement(*element); 364 return isHTMLScriptElement(*element);
336 } 365 }
337 366
338 bool isSVGScriptLoader(Element* element) 367 bool isSVGScriptLoader(Element* element)
339 { 368 {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 dispatchLoadEvent(); 504 dispatchLoadEvent();
476 else 505 else
477 dispatchErrorEvent(); 506 dispatchErrorEvent();
478 } 507 }
479 m_resource = nullptr; 508 m_resource = nullptr;
480 } 509 }
481 510
482 void ScriptLoader::notifyFinished(Resource* resource) 511 void ScriptLoader::notifyFinished(Resource* resource)
483 { 512 {
484 DCHECK(!m_willBeParserExecuted); 513 DCHECK(!m_willBeParserExecuted);
514
515 // We do not need this script in the memory cache. The primary goals of
516 // sending this fetch request are to let the third party server know
517 // about the document.write scripts intervention and populate the http
518 // cache for subsequent uses.
519 if (m_documentWriteIntervention == DocumentWriteIntervention::FetchDocWritte nScriptDeferIdle) {
520 memoryCache()->remove(resource);
521 m_pendingScript->stopWatchingForLoad();
522 return;
523 }
524
485 DCHECK(m_asyncExecType != ScriptRunner::None); 525 DCHECK(m_asyncExecType != ScriptRunner::None);
486 526
487 Document* contextDocument = m_element->document().contextDocument(); 527 Document* contextDocument = m_element->document().contextDocument();
488 if (!contextDocument) { 528 if (!contextDocument) {
489 detach(); 529 detach();
490 return; 530 return;
491 } 531 }
492 532
493 ASSERT_UNUSED(resource, resource == m_resource); 533 ASSERT_UNUSED(resource, resource == m_resource);
494 534
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 if (isHTMLScriptLoader(element)) 583 if (isHTMLScriptLoader(element))
544 return toHTMLScriptElement(element)->loader(); 584 return toHTMLScriptElement(element)->loader();
545 585
546 if (isSVGScriptLoader(element)) 586 if (isSVGScriptLoader(element))
547 return toSVGScriptElement(element)->loader(); 587 return toSVGScriptElement(element)->loader();
548 588
549 return 0; 589 return 0;
550 } 590 }
551 591
552 } // namespace blink 592 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698