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

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

Issue 2838933003: [not-for-commit] kitsune changes + pending kouhei changes (Closed)
Patch Set: Created 3 years, 7 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 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights
6 * reserved. 6 * reserved.
7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> 7 * Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org>
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 11 matching lines...) Expand all
22 * Boston, MA 02110-1301, USA. 22 * Boston, MA 02110-1301, USA.
23 */ 23 */
24 24
25 #include "core/dom/ScriptLoader.h" 25 #include "core/dom/ScriptLoader.h"
26 26
27 #include "bindings/core/v8/ScriptController.h" 27 #include "bindings/core/v8/ScriptController.h"
28 #include "bindings/core/v8/ScriptSourceCode.h" 28 #include "bindings/core/v8/ScriptSourceCode.h"
29 #include "bindings/core/v8/V8BindingForCore.h" 29 #include "bindings/core/v8/V8BindingForCore.h"
30 #include "core/HTMLNames.h" 30 #include "core/HTMLNames.h"
31 #include "core/SVGNames.h" 31 #include "core/SVGNames.h"
32 #include "core/dom/ClassicPendingScript.h"
32 #include "core/dom/ClassicScript.h" 33 #include "core/dom/ClassicScript.h"
33 #include "core/dom/Document.h" 34 #include "core/dom/Document.h"
34 #include "core/dom/DocumentParserTiming.h" 35 #include "core/dom/DocumentParserTiming.h"
35 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" 36 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
37 #include "core/dom/Modulator.h"
38 #include "core/dom/ModulePendingScript.h"
36 #include "core/dom/Script.h" 39 #include "core/dom/Script.h"
37 #include "core/dom/ScriptElementBase.h" 40 #include "core/dom/ScriptElementBase.h"
38 #include "core/dom/ScriptRunner.h" 41 #include "core/dom/ScriptRunner.h"
39 #include "core/dom/ScriptableDocumentParser.h" 42 #include "core/dom/ScriptableDocumentParser.h"
40 #include "core/dom/Text.h" 43 #include "core/dom/Text.h"
41 #include "core/events/Event.h" 44 #include "core/events/Event.h"
42 #include "core/frame/LocalFrame.h" 45 #include "core/frame/LocalFrame.h"
43 #include "core/frame/SubresourceIntegrity.h" 46 #include "core/frame/SubresourceIntegrity.h"
44 #include "core/frame/csp/ContentSecurityPolicy.h" 47 #include "core/frame/csp/ContentSecurityPolicy.h"
45 #include "core/html/imports/HTMLImport.h" 48 #include "core/html/imports/HTMLImport.h"
46 #include "core/html/parser/HTMLParserIdioms.h" 49 #include "core/html/parser/HTMLParserIdioms.h"
50 #include "core/loader/modulescript/ModuleScriptFetchRequest.h"
47 #include "core/loader/resource/ScriptResource.h" 51 #include "core/loader/resource/ScriptResource.h"
48 #include "platform/WebFrameScheduler.h" 52 #include "platform/WebFrameScheduler.h"
49 #include "platform/loader/fetch/AccessControlStatus.h" 53 #include "platform/loader/fetch/AccessControlStatus.h"
50 #include "platform/loader/fetch/FetchParameters.h" 54 #include "platform/loader/fetch/FetchParameters.h"
51 #include "platform/loader/fetch/MemoryCache.h"
52 #include "platform/loader/fetch/ResourceFetcher.h" 55 #include "platform/loader/fetch/ResourceFetcher.h"
53 #include "platform/network/mime/MIMETypeRegistry.h" 56 #include "platform/network/mime/MIMETypeRegistry.h"
54 #include "platform/weborigin/SecurityOrigin.h" 57 #include "platform/weborigin/SecurityOrigin.h"
55 #include "platform/wtf/StdLibExtras.h" 58 #include "platform/wtf/StdLibExtras.h"
56 #include "platform/wtf/text/StringBuilder.h" 59 #include "platform/wtf/text/StringBuilder.h"
57 #include "platform/wtf/text/StringHash.h" 60 #include "platform/wtf/text/StringHash.h"
58 #include "public/platform/WebCachePolicy.h" 61 #include "public/platform/WebCachePolicy.h"
59 62
60 namespace blink { 63 namespace blink {
61 64
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 element_->GetDocument().GetScriptableDocumentParser()->LineNumber(); 103 element_->GetDocument().GetScriptableDocumentParser()->LineNumber();
101 } 104 }
102 } 105 }
103 106
104 ScriptLoader::~ScriptLoader() {} 107 ScriptLoader::~ScriptLoader() {}
105 108
106 DEFINE_TRACE(ScriptLoader) { 109 DEFINE_TRACE(ScriptLoader) {
107 visitor->Trace(element_); 110 visitor->Trace(element_);
108 visitor->Trace(resource_); 111 visitor->Trace(resource_);
109 visitor->Trace(pending_script_); 112 visitor->Trace(pending_script_);
113 visitor->Trace(module_tree_client_);
110 PendingScriptClient::Trace(visitor); 114 PendingScriptClient::Trace(visitor);
111 } 115 }
112 116
113 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() { 117 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() {
114 DCHECK(!created_during_document_write_); 118 DCHECK(!created_during_document_write_);
115 document_write_intervention_ = 119 document_write_intervention_ =
116 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle; 120 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle;
117 } 121 }
118 122
119 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() { 123 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 if (!IsScriptForEventSupported()) 312 if (!IsScriptForEventSupported())
309 return false; 313 return false;
310 314
311 // 14. is handled below. 315 // 14. is handled below.
312 316
313 // 15. "Let CORS setting be the current state of the element's 317 // 15. "Let CORS setting be the current state of the element's
314 // crossorigin content attribute." 318 // crossorigin content attribute."
315 CrossOriginAttributeValue cross_origin = 319 CrossOriginAttributeValue cross_origin =
316 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); 320 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue());
317 321
318 // 16. will be handled below once module script support is implemented. 322 // 16. is handled below.
319 323
320 // 17. "If the script element has a nonce attribute, 324 // 17. "If the script element has a nonce attribute,
321 // then let cryptographic nonce be that attribute's value. 325 // then let cryptographic nonce be that attribute's value.
322 // Otherwise, let cryptographic nonce be the empty string." 326 // Otherwise, let cryptographic nonce be the empty string."
323 String nonce; 327 String nonce;
324 if (element_->IsNonceableElement()) 328 if (element_->IsNonceableElement())
325 nonce = element_->nonce(); 329 nonce = element_->nonce();
326 330
327 // 18. is handled below. 331 // 18. is handled below.
328 332
(...skipping 28 matching lines...) Expand all
357 // 21.5. "If the previous step failed, queue a task to 361 // 21.5. "If the previous step failed, queue a task to
358 // fire an event named error at the element, and abort these steps." 362 // fire an event named error at the element, and abort these steps."
359 if (!url.IsValid()) { 363 if (!url.IsValid()) {
360 // TODO(hiroshige): Make this asynchronous. Currently we fire the error 364 // TODO(hiroshige): Make this asynchronous. Currently we fire the error
361 // event synchronously to keep the existing behavior. 365 // event synchronously to keep the existing behavior.
362 DispatchErrorEvent(); 366 DispatchErrorEvent();
363 return false; 367 return false;
364 } 368 }
365 369
366 DCHECK(!resource_); 370 DCHECK(!resource_);
371 DCHECK(!module_tree_client_);
367 372
368 // 21.6. "Switch on the script's type:" 373 // 21.6. "Switch on the script's type:"
369 // - "classic": 374 if (GetScriptType() == ScriptType::kClassic) {
375 // - "classic":
370 376
371 // 14. "If the script element has a charset attribute, 377 // 14. "If the script element has a charset attribute,
372 // then let encoding be the result of 378 // then let encoding be the result of
373 // getting an encoding from the value of the charset attribute." 379 // getting an encoding from the value of the charset attribute."
374 // "If the script element does not have a charset attribute, 380 // "If the script element does not have a charset attribute,
375 // or if getting an encoding failed, let encoding 381 // or if getting an encoding failed, let encoding
376 // be the same as the encoding of the script element's node 382 // be the same as the encoding of the script element's node
377 // document." 383 // document."
378 // TODO(hiroshige): Should we handle failure in getting an encoding? 384 // TODO(hiroshige): Should we handle failure in getting an encoding?
379 String encoding; 385 String encoding;
380 if (!element_->CharsetAttributeValue().IsEmpty()) 386 if (!element_->CharsetAttributeValue().IsEmpty())
381 encoding = element_->CharsetAttributeValue(); 387 encoding = element_->CharsetAttributeValue();
382 else 388 else
383 encoding = element_document.characterSet(); 389 encoding = element_document.characterSet();
384 390
385 // Step 16 is skipped because "module script credentials" is not used 391 // Step 16 is skipped because "module script credentials" is not used
386 // for classic scripts. 392 // for classic scripts.
387 393
388 // 18. "If the script element has an integrity attribute, 394 // 18. "If the script element has an integrity attribute,
389 // then let integrity metadata be that attribute's value. 395 // then let integrity metadata be that attribute's value.
390 // Otherwise, let integrity metadata be the empty string." 396 // Otherwise, let integrity metadata be the empty string."
391 String integrity_attr = element_->IntegrityAttributeValue(); 397 String integrity_attr = element_->IntegrityAttributeValue();
392 IntegrityMetadataSet integrity_metadata; 398 IntegrityMetadataSet integrity_metadata;
393 if (!integrity_attr.IsEmpty()) { 399 if (!integrity_attr.IsEmpty()) {
394 SubresourceIntegrity::ParseIntegrityAttribute( 400 SubresourceIntegrity::ParseIntegrityAttribute(
395 integrity_attr, integrity_metadata, &element_document); 401 integrity_attr, integrity_metadata, &element_document);
402 }
403
404 if (!FetchClassicScript(url, element_document.Fetcher(), nonce,
405 integrity_metadata, parser_state, cross_origin,
406 element_document.GetSecurityOrigin(), encoding)) {
407 // TODO(hiroshige): Make this asynchronous. Currently we fire the error
408 // event synchronously to keep the existing behavior.
409 DispatchErrorEvent();
410 return false;
411 }
412
413 DCHECK(resource_);
414 DCHECK(!module_tree_client_);
415 } else {
416 // - "module":
417
418 // Steps 14 and 18 are skipped because they are not used in module
419 // scripts.
420
421 // 16. "Let module script credentials mode be determined by switching
422 // on CORS setting:"
423 WebURLRequest::FetchCredentialsMode credentials_mode =
424 WebURLRequest::kFetchCredentialsModeOmit;
425 switch (cross_origin) {
426 case kCrossOriginAttributeNotSet:
427 credentials_mode = WebURLRequest::kFetchCredentialsModeOmit;
428 break;
429 case kCrossOriginAttributeAnonymous:
430 credentials_mode = WebURLRequest::kFetchCredentialsModeSameOrigin;
431 break;
432 case kCrossOriginAttributeUseCredentials:
433 credentials_mode = WebURLRequest::kFetchCredentialsModeInclude;
434 break;
435 }
436
437 DCHECK(RuntimeEnabledFeatures::moduleScriptsEnabled());
438 Modulator* modulator = Modulator::From(
439 ToScriptStateForMainWorld(element_document.GetFrame()));
440 FetchModuleScriptTree(url, modulator, nonce, parser_state,
441 credentials_mode);
442
443 DCHECK(!resource_);
444 DCHECK(module_tree_client_);
396 } 445 }
397 446
398 if (!FetchClassicScript(url, element_document.Fetcher(), nonce,
399 integrity_metadata, parser_state, cross_origin,
400 element_document.GetSecurityOrigin(), encoding)) {
401 // TODO(hiroshige): Make this asynchronous. Currently we fire the error
402 // event synchronously to keep the existing behavior.
403 DispatchErrorEvent();
404 return false;
405 }
406
407 DCHECK(resource_);
408
409 // - "module":
410 // TODO(hiroshige): Implement this.
411
412 // "When the chosen algorithm asynchronously completes, set 447 // "When the chosen algorithm asynchronously completes, set
413 // the script's script to the result. At that time, the script is ready." 448 // the script's script to the result. At that time, the script is ready."
414 // When the script is ready, PendingScriptClient::pendingScriptFinished() 449 // When the script is ready, PendingScriptClient::pendingScriptFinished()
415 // is used as the notification, and the action to take when 450 // is used as the notification, and the action to take when
416 // the script is ready is specified later, in 451 // the script is ready is specified later, in
417 // - ScriptLoader::PrepareScript(), or 452 // - ScriptLoader::PrepareScript(), or
418 // - HTMLParserScriptRunner, 453 // - HTMLParserScriptRunner,
419 // depending on the conditions in Step 23 of "prepare a script". 454 // depending on the conditions in Step 23 of "prepare a script".
420 } 455 }
421 456
422 // 22. "If the element does not have a src content attribute, 457 // 22. "If the element does not have a src content attribute,
423 // run these substeps:" 458 // run these substeps:"
459 if (!element_->HasSourceAttribute()) {
460 // 22.1. "Let source text be the value of the text IDL attribute."
461 // This step is done later:
462 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause),
463 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
464 // - in HTMLParserScriptRunner::processScriptElementInternal()
465 // (Duplicated code of Step 23, 6th Clause),
466 // as Element::textContent(),
467 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause),
468 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
469 // - PendingScript::getSource() (Indirectly used via
470 // HTMLParserScriptRunner::processScriptElementInternal(),
471 // Step 23, 5th Clause),
472 // as Element::textContent().
473 // TODO(hiroshige): Make them merged or consistent.
424 474
425 // 22.1. "Let source text be the value of the text IDL attribute." 475 // 22.2. "Switch on the script's type:"
426 // This step is done later: 476 switch (GetScriptType()) {
427 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), 477 // - "classic":
428 // as Element::textFromChildren() in ScriptLoader::scriptContent(), 478 case ScriptType::kClassic:
429 // - in HTMLParserScriptRunner::processScriptElementInternal() 479 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic".
430 // (Duplicated code of Step 23, 6th Clause), 480 break;
431 // as Element::textContent(),
432 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause),
433 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
434 // - PendingScript::getSource() (Indirectly used via
435 // HTMLParserScriptRunner::processScriptElementInternal(),
436 // Step 23, 5th Clause),
437 // as Element::textContent().
438 // TODO(hiroshige): Make them merged or consistent.
439 481
440 // 22.2. "Switch on the script's type:" 482 // - "module":
441 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". 483 case ScriptType::kModule:
442 // TODO(hiroshige): Implement Step 22.2 for "module". 484 // Inline module scripts are not yet supported.
485 // FOXME: (how) should we handle this? Should we fail more gracefully?
486 fprintf(
487 stderr,
488 "Inline module script is not yet supported (Document URL: %s)\n",
489 element_document.Url().GetString().Utf8().data());
490 CHECK(false);
491 break;
492 }
493 }
443 494
444 // [Intervention] 495 // [Intervention]
445 // Since the asynchronous, low priority fetch for doc.written blocked 496 // Since the asynchronous, low priority fetch for doc.written blocked
446 // script is not for execution, return early from here. Watch for its 497 // script is not for execution, return early from here. Watch for its
447 // completion to be able to remove it from the memory cache. 498 // completion to be able to remove it from the memory cache.
448 if (document_write_intervention_ == 499 if (GetScriptType() == ScriptType::kClassic &&
449 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { 500 document_write_intervention_ ==
501 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
450 pending_script_ = CreatePendingScript(); 502 pending_script_ = CreatePendingScript();
451 pending_script_->WatchForLoad(this); 503 pending_script_->WatchForLoad(this);
452 return true; 504 return true;
453 } 505 }
454 506
455 // 23. "Then, follow the first of the following options that describes the 507 // 23. "Then, follow the first of the following options that describes the
456 // situation:" 508 // situation:"
457 509
458 // Three flags are used to instruct the caller of prepareScript() to execute 510 // Three flags are used to instruct the caller of prepareScript() to execute
459 // a part of Step 23, when |m_willBeParserExecuted| is true: 511 // a part of Step 23, when |m_willBeParserExecuted| is true:
460 // - |m_willBeParserExecuted| 512 // - |m_willBeParserExecuted|
461 // - |m_willExecuteWhenDocumentFinishedParsing| 513 // - |m_willExecuteWhenDocumentFinishedParsing|
462 // - |m_readyToBeParserExecuted| 514 // - |m_readyToBeParserExecuted|
463 // TODO(hiroshige): Clean up the dependency. 515 // TODO(hiroshige): Clean up the dependency.
464 516
465 // 1st Clause: 517 // 1st Clause:
466 // - "If the script's type is "classic", and 518 // - "If the script's type is "classic", and
467 // the element has a src attribute, and the element has a defer attribute, 519 // the element has a src attribute, and the element has a defer attribute,
468 // and the element has been flagged as "parser-inserted", 520 // and the element has been flagged as "parser-inserted",
469 // and the element does not have an async attribute" 521 // and the element does not have an async attribute"
470 // TODO(hiroshige): Check the script's type and implement "module" case. 522 // - "If the script's type is "module",
471 if (element_->HasSourceAttribute() && element_->DeferAttributeValue() && 523 // and the element has been flagged as "parser-inserted",
472 parser_inserted_ && !element_->AsyncAttributeValue()) { 524 // and the element does not have an async attribute"
525 if ((GetScriptType() == ScriptType::kClassic &&
526 element_->HasSourceAttribute() && element_->DeferAttributeValue() &&
527 parser_inserted_ && !element_->AsyncAttributeValue()) ||
528 (GetScriptType() == ScriptType::kModule && parser_inserted_ &&
529 !element_->AsyncAttributeValue())) {
473 // This clause is implemented by the caller-side of prepareScript(): 530 // This clause is implemented by the caller-side of prepareScript():
474 // - HTMLParserScriptRunner::requestDeferredScript(), and 531 // - HTMLParserScriptRunner::requestDeferredScript(), and
475 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 532 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
476 will_execute_when_document_finished_parsing_ = true; 533 will_execute_when_document_finished_parsing_ = true;
477 will_be_parser_executed_ = true; 534 will_be_parser_executed_ = true;
478 535
479 return true; 536 return true;
480 } 537 }
481 538
482 // 2nd Clause: 539 // 2nd Clause:
483 // - "If the script's type is "classic", 540 // - "If the script's type is "classic",
484 // and the element has a src attribute, 541 // and the element has a src attribute,
485 // and the element has been flagged as "parser-inserted", 542 // and the element has been flagged as "parser-inserted",
486 // and the element does not have an async attribute" 543 // and the element does not have an async attribute"
487 // TODO(hiroshige): Check the script's type. 544 // TODO(hiroshige): Check the script's type.
488 if (element_->HasSourceAttribute() && parser_inserted_ && 545 if (GetScriptType() == ScriptType::kClassic &&
546 element_->HasSourceAttribute() && parser_inserted_ &&
489 !element_->AsyncAttributeValue()) { 547 !element_->AsyncAttributeValue()) {
490 // This clause is implemented by the caller-side of prepareScript(): 548 // This clause is implemented by the caller-side of prepareScript():
491 // - HTMLParserScriptRunner::requestParsingBlockingScript() 549 // - HTMLParserScriptRunner::requestParsingBlockingScript()
492 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 550 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
493 will_be_parser_executed_ = true; 551 will_be_parser_executed_ = true;
494 552
495 return true; 553 return true;
496 } 554 }
497 555
498 // 5th Clause: 556 // 5th Clause:
499 // TODO(hiroshige): Reorder the clauses to match the spec. 557 // TODO(hiroshige): Reorder the clauses to match the spec.
500 // - "If the element does not have a src attribute, 558 // - "If the element does not have a src attribute,
501 // and the element has been flagged as "parser-inserted", 559 // and the element has been flagged as "parser-inserted",
502 // and either the parser that created the script is an XML parser 560 // and either the parser that created the script is an XML parser
503 // or it's an HTML parser whose script nesting level is not greater than 561 // or it's an HTML parser whose script nesting level is not greater than
504 // one, 562 // one,
505 // and the Document of the HTML parser or XML parser that created 563 // and the Document of the HTML parser or XML parser that created
506 // the script element has a style sheet that is blocking scripts" 564 // the script element has a style sheet that is blocking scripts"
507 // The last part "... has a style sheet that is blocking scripts" 565 // The last part "... has a style sheet that is blocking scripts"
508 // is implemented in Document::isScriptExecutionReady(). 566 // is implemented in Document::isScriptExecutionReady().
509 // Part of the condition check is done in 567 // Part of the condition check is done in
510 // HTMLParserScriptRunner::processScriptElementInternal(). 568 // HTMLParserScriptRunner::processScriptElementInternal().
511 // TODO(hiroshige): Clean up the split condition check. 569 // TODO(hiroshige): Clean up the split condition check.
512 if (!element_->HasSourceAttribute() && parser_inserted_ && 570 // We check that the type is "classic" here, because according to the spec
571 // a "module" script doesn't reach the 5th Clause because the 4th Clause
572 // catches all "module" scripts.
573 if (GetScriptType() == ScriptType::kClassic &&
574 !element_->HasSourceAttribute() && parser_inserted_ &&
513 !element_document.IsScriptExecutionReady()) { 575 !element_document.IsScriptExecutionReady()) {
514 // The former part of this clause is 576 // The former part of this clause is
515 // implemented by the caller-side of prepareScript(): 577 // implemented by the caller-side of prepareScript():
516 // - HTMLParserScriptRunner::requestParsingBlockingScript() 578 // - HTMLParserScriptRunner::requestParsingBlockingScript()
517 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 579 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
518 will_be_parser_executed_ = true; 580 will_be_parser_executed_ = true;
519 // "Set the element's "ready to be parser-executed" flag." 581 // "Set the element's "ready to be parser-executed" flag."
520 ready_to_be_parser_executed_ = true; 582 ready_to_be_parser_executed_ = true;
521 583
522 return true; 584 return true;
523 } 585 }
524 586
525 // 3rd Clause: 587 // 3rd Clause:
526 // - "If the script's type is "classic", 588 // - "If the script's type is "classic",
527 // and the element has a src attribute, 589 // and the element has a src attribute,
528 // and the element does not have an async attribute, 590 // and the element does not have an async attribute,
529 // and the element does not have the "non-blocking" flag set" 591 // and the element does not have the "non-blocking" flag set"
592 // - "If the script's type is "module",
593 // and the element does not have an async attribute,
594 // and the element does not have the "non-blocking" flag set"
530 // TODO(hiroshige): Check the script's type and implement "module" case. 595 // TODO(hiroshige): Check the script's type and implement "module" case.
531 if (element_->HasSourceAttribute() && !element_->AsyncAttributeValue() && 596 if ((GetScriptType() == ScriptType::kClassic &&
532 !non_blocking_) { 597 element_->HasSourceAttribute() && !element_->AsyncAttributeValue() &&
598 !non_blocking_) ||
599 (GetScriptType() == ScriptType::kModule &&
600 !element_->AsyncAttributeValue() && !non_blocking_)) {
533 // "Add the element to the end of the list of scripts that will execute 601 // "Add the element to the end of the list of scripts that will execute
534 // in order as soon as possible associated with the node document of the 602 // in order as soon as possible associated with the node document of the
535 // script element at the time the prepare a script algorithm started." 603 // script element at the time the prepare a script algorithm started."
536 pending_script_ = CreatePendingScript(); 604 pending_script_ = CreatePendingScript();
537 async_exec_type_ = ScriptRunner::kInOrder; 605 async_exec_type_ = ScriptRunner::kInOrder;
538 // TODO(hiroshige): Here |contextDocument| is used as "node document" 606 // TODO(hiroshige): Here |contextDocument| is used as "node document"
539 // while Step 14 uses |elementDocument| as "node document". Fix this. 607 // while Step 14 uses |elementDocument| as "node document". Fix this.
540 context_document->GetScriptRunner()->QueueScriptForExecution( 608 context_document->GetScriptRunner()->QueueScriptForExecution(
541 this, async_exec_type_); 609 this, async_exec_type_);
542 // Note that watchForLoad can immediately call pendingScriptFinished. 610 // Note that watchForLoad can immediately call pendingScriptFinished.
543 pending_script_->WatchForLoad(this); 611 pending_script_->WatchForLoad(this);
544 // The part "When the script is ready..." is implemented in 612 // The part "When the script is ready..." is implemented in
545 // ScriptRunner::notifyScriptReady(). 613 // ScriptRunner::notifyScriptReady().
546 // TODO(hiroshige): Annotate it. 614 // TODO(hiroshige): Annotate it.
547 615
548 return true; 616 return true;
549 } 617 }
550 618
551 // 4th Clause: 619 // 4th Clause:
552 // - "If the script's type is "classic", and the element has a src attribute" 620 // - "If the script's type is "classic", and the element has a src attribute"
553 // TODO(hiroshige): Check the script's type and implement "module" case. 621 // - "If the script's type is "module""
554 if (element_->HasSourceAttribute()) { 622 if ((GetScriptType() == ScriptType::kClassic &&
623 element_->HasSourceAttribute()) ||
624 GetScriptType() == ScriptType::kModule) {
555 // "The element must be added to the set of scripts that will execute 625 // "The element must be added to the set of scripts that will execute
556 // as soon as possible of the node document of the script element at the 626 // as soon as possible of the node document of the script element at the
557 // time the prepare a script algorithm started." 627 // time the prepare a script algorithm started."
558 pending_script_ = CreatePendingScript(); 628 pending_script_ = CreatePendingScript();
559 async_exec_type_ = ScriptRunner::kAsync; 629 async_exec_type_ = ScriptRunner::kAsync;
560 pending_script_->StartStreamingIfPossible(&element_->GetDocument(), 630 pending_script_->StartStreamingIfPossible(&element_->GetDocument(),
561 ScriptStreamer::kAsync); 631 ScriptStreamer::kAsync);
562 // TODO(hiroshige): Here |contextDocument| is used as "node document" 632 // TODO(hiroshige): Here |contextDocument| is used as "node document"
563 // while Step 14 uses |elementDocument| as "node document". Fix this. 633 // while Step 14 uses |elementDocument| as "node document". Fix this.
564 context_document->GetScriptRunner()->QueueScriptForExecution( 634 context_document->GetScriptRunner()->QueueScriptForExecution(
(...skipping 10 matching lines...) Expand all
575 // 6th Clause: 645 // 6th Clause:
576 // - "Otherwise" 646 // - "Otherwise"
577 // "Immediately execute the script block, 647 // "Immediately execute the script block,
578 // even if other scripts are already executing." 648 // even if other scripts are already executing."
579 // Note: this block is also duplicated in 649 // Note: this block is also duplicated in
580 // HTMLParserScriptRunner::processScriptElementInternal(). 650 // HTMLParserScriptRunner::processScriptElementInternal().
581 // TODO(hiroshige): Merge the duplicated code. 651 // TODO(hiroshige): Merge the duplicated code.
582 652
583 // This clause is executed only if the script's type is "classic" 653 // This clause is executed only if the script's type is "classic"
584 // and the element doesn't have a src attribute. 654 // and the element doesn't have a src attribute.
655 DCHECK_EQ(GetScriptType(), ScriptType::kClassic);
656 DCHECK(!is_external_script_);
585 657
586 // Reset line numbering for nested writes. 658 // Reset line numbering for nested writes.
587 TextPosition position = element_document.IsInDocumentWrite() 659 TextPosition position = element_document.IsInDocumentWrite()
588 ? TextPosition() 660 ? TextPosition()
589 : script_start_position; 661 : script_start_position;
590 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_) 662 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_)
591 ? element_document.Url() 663 ? element_document.Url()
592 : KURL(); 664 : KURL();
593 665
594 if (!ExecuteScript(ClassicScript::Create( 666 if (!ExecuteScript(ClassicScript::Create(
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 if (created_during_document_write_ && 733 if (created_during_document_write_ &&
662 resource_->GetResourceRequest().GetCachePolicy() == 734 resource_->GetResourceRequest().GetCachePolicy() ==
663 WebCachePolicy::kReturnCacheDataDontLoad) { 735 WebCachePolicy::kReturnCacheDataDontLoad) {
664 document_write_intervention_ = 736 document_write_intervention_ =
665 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; 737 DocumentWriteIntervention::kDoNotFetchDocWrittenScript;
666 } 738 }
667 739
668 return true; 740 return true;
669 } 741 }
670 742
743 void ScriptLoader::FetchModuleScriptTree(
744 const KURL& url,
745 Modulator* modulator,
746 const String& nonce,
747 ParserDisposition parser_state,
748 WebURLRequest::FetchCredentialsMode credentials_mode) {
749 // https://html.spec.whatwg.org/#prepare-a-script
750 // 21.6, "module":
751 // "Fetch a module script graph given url, settings, "script",
752 // cryptographic nonce, parser state, and
753 // module script credentials mode."
754 ModuleScriptFetchRequest module_request(url, nonce, parser_state,
755 credentials_mode);
756
757 module_tree_client_ = ModulePendingScriptTreeClient::Create();
758
759 modulator->FetchTree(module_request, module_tree_client_);
760 }
761
671 PendingScript* ScriptLoader::CreatePendingScript() { 762 PendingScript* ScriptLoader::CreatePendingScript() {
672 CHECK(resource_); 763 switch (GetScriptType()) {
673 return PendingScript::Create(element_, resource_); 764 case ScriptType::kClassic:
765 CHECK(resource_);
766 return ClassicPendingScript::Create(element_, resource_);
767 case ScriptType::kModule:
768 CHECK(module_tree_client_);
769 return ModulePendingScript::Create(element_, module_tree_client_);
770 }
771 NOTREACHED();
772 return nullptr;
674 } 773 }
675 774
676 bool ScriptLoader::ExecuteScript(const Script* script) { 775 bool ScriptLoader::ExecuteScript(const Script* script) {
677 double script_exec_start_time = MonotonicallyIncreasingTime(); 776 double script_exec_start_time = MonotonicallyIncreasingTime();
678 bool result = DoExecuteScript(script); 777 bool result = DoExecuteScript(script);
679 778
680 // NOTE: we do not check m_willBeParserExecuted here, since 779 // NOTE: we do not check m_willBeParserExecuted here, since
681 // m_willBeParserExecuted is false for inline scripts, and we want to 780 // m_willBeParserExecuted is false for inline scripts, and we want to
682 // include inline script execution time as part of parser blocked script 781 // include inline script execution time as part of parser blocked script
683 // execution time. 782 // execution time.
684 if (async_exec_type_ == ScriptRunner::kNone) 783 if (async_exec_type_ == ScriptRunner::kNone)
685 DocumentParserTiming::From(element_->GetDocument()) 784 DocumentParserTiming::From(element_->GetDocument())
686 .RecordParserBlockedOnScriptExecutionDuration( 785 .RecordParserBlockedOnScriptExecutionDuration(
687 MonotonicallyIncreasingTime() - script_exec_start_time, 786 MonotonicallyIncreasingTime() - script_exec_start_time,
688 WasCreatedDuringDocumentWrite()); 787 WasCreatedDuringDocumentWrite());
689 return result; 788 return result;
690 } 789 }
691 790
692 // https://html.spec.whatwg.org/#execute-the-script-block 791 // https://html.spec.whatwg.org/#execute-the-script-block
693 // with additional support for HTML imports. 792 // with additional support for HTML imports.
694 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), 793 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(),
695 // i.e. load/error events are dispatched by the caller. 794 // i.e. load/error events are dispatched by the caller.
696 // Steps 3--7 are implemented here in doExecuteScript(). 795 // Steps 3--7 are implemented here in doExecuteScript().
697 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). 796 // TODO(hiroshige): Move event dispatching code to doExecuteScript().
698 bool ScriptLoader::DoExecuteScript(const Script* script) { 797 bool ScriptLoader::DoExecuteScript(const Script* script) {
699 DCHECK(already_started_); 798 DCHECK(already_started_);
799 CHECK_EQ(script->GetScriptType(), GetScriptType());
700 800
701 if (script->IsEmpty()) 801 if (script->IsEmpty())
702 return true; 802 return true;
703 803
704 Document* element_document = &(element_->GetDocument()); 804 Document* element_document = &(element_->GetDocument());
705 Document* context_document = element_document->ContextDocument(); 805 Document* context_document = element_document->ContextDocument();
706 if (!context_document) 806 if (!context_document)
707 return true; 807 return true;
708 808
709 LocalFrame* frame = context_document->GetFrame(); 809 LocalFrame* frame = context_document->GetFrame();
(...skipping 22 matching lines...) Expand all
732 context_document, element_->GetDocument().GetSecurityOrigin())) 832 context_document, element_->GetDocument().GetSecurityOrigin()))
733 return false; 833 return false;
734 } 834 }
735 835
736 const bool is_imported_script = context_document != element_document; 836 const bool is_imported_script = context_document != element_document;
737 837
738 // 3. "If the script is from an external file, 838 // 3. "If the script is from an external file,
739 // or the script's type is module", 839 // or the script's type is module",
740 // then increment the ignore-destructive-writes counter of the 840 // then increment the ignore-destructive-writes counter of the
741 // script element's node document. Let neutralized doc be that Document." 841 // script element's node document. Let neutralized doc be that Document."
742 // TODO(hiroshige): Implement "module" case.
743 IgnoreDestructiveWriteCountIncrementer 842 IgnoreDestructiveWriteCountIncrementer
744 ignore_destructive_write_count_incrementer( 843 ignore_destructive_write_count_incrementer(
745 is_external_script_ || is_imported_script ? context_document : 0); 844 is_external_script_ ||
845 script->GetScriptType() == ScriptType::kModule ||
846 is_imported_script
847 ? context_document
848 : 0);
746 849
747 // 4. "Let old script element be the value to which the script element's 850 // 4. "Let old script element be the value to which the script element's
748 // node document's currentScript object was most recently set." 851 // node document's currentScript object was most recently set."
749 // This is implemented as push/popCurrentScript(). 852 // This is implemented as push/popCurrentScript().
750 853
751 // 5. "Switch on the script's type:" 854 // 5. "Switch on the script's type:"
752 // - "classic": 855 // - "classic":
753 // 1. "If the script element's root is not a shadow root, 856 // 1. "If the script element's root is not a shadow root,
754 // then set the script element's node document's currentScript 857 // then set the script element's node document's currentScript
755 // attribute to the script element. Otherwise, set it to null." 858 // attribute to the script element. Otherwise, set it to null."
756 context_document->PushCurrentScript(element_.Get()); 859 // - "module":
860 // 1. "Set the script element's node document's currentScript attribute
861 // to null."
862 ScriptElementBase* current_script = nullptr;
863 if (script->GetScriptType() == ScriptType::kClassic)
864 current_script = element_;
865 context_document->PushCurrentScript(current_script);
757 866
867 // - "classic":
758 // 2. "Run the classic script given by the script's script." 868 // 2. "Run the classic script given by the script's script."
759 // Note: This is where the script is compiled and actually executed. 869 // Note: This is where the script is compiled and actually executed.
870 // - "module":
871 // 2. "Run the module script given by the script's script."
760 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin()); 872 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin());
761 873
762 // - "module":
763 // TODO(hiroshige): Implement this.
764
765 // 6. "Set the script element's node document's currentScript attribute 874 // 6. "Set the script element's node document's currentScript attribute
766 // to old script element." 875 // to old script element."
767 context_document->PopCurrentScript(element_.Get()); 876 context_document->PopCurrentScript(current_script);
768 877
769 return true; 878 return true;
770 879
771 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, 880 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
772 // if it was incremented in the earlier step." 881 // if it was incremented in the earlier step."
773 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. 882 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
774 } 883 }
775 884
776 void ScriptLoader::Execute() { 885 void ScriptLoader::Execute() {
777 DCHECK(!will_be_parser_executed_); 886 DCHECK(!will_be_parser_executed_);
778 DCHECK(async_exec_type_ != ScriptRunner::kNone); 887 DCHECK(async_exec_type_ != ScriptRunner::kNone);
779 DCHECK(pending_script_->GetResource()); 888 DCHECK(pending_script_->IsExternal());
780 bool error_occurred = false; 889 bool error_occurred = false;
781 Script* script = pending_script_->GetSource(KURL(), error_occurred); 890 Script* script = pending_script_->GetSource(KURL(), error_occurred);
891 const bool wasCanceled = pending_script_->WasCanceled();
782 DetachPendingScript(); 892 DetachPendingScript();
783 if (error_occurred) { 893 if (error_occurred) {
784 DispatchErrorEvent(); 894 DispatchErrorEvent();
785 } else if (!resource_->WasCanceled()) { 895 } else if (!wasCanceled) {
786 if (ExecuteScript(script)) 896 if (ExecuteScript(script))
787 DispatchLoadEvent(); 897 DispatchLoadEvent();
788 else 898 else
789 DispatchErrorEvent(); 899 DispatchErrorEvent();
790 } 900 }
791 resource_ = nullptr; 901 resource_ = nullptr;
902 module_tree_client_ = nullptr;
792 } 903 }
793 904
794 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) { 905 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) {
795 DCHECK(!will_be_parser_executed_); 906 DCHECK(!will_be_parser_executed_);
796 DCHECK_EQ(pending_script_, pending_script); 907 DCHECK_EQ(pending_script_, pending_script);
797 DCHECK_EQ(pending_script->GetResource(), resource_); 908 DCHECK_EQ(pending_script_->GetScriptType(), GetScriptType());
798 909
799 // We do not need this script in the memory cache. The primary goals of 910 // We do not need this script in the memory cache. The primary goals of
800 // sending this fetch request are to let the third party server know 911 // sending this fetch request are to let the third party server know
801 // about the document.write scripts intervention and populate the http 912 // about the document.write scripts intervention and populate the http
802 // cache for subsequent uses. 913 // cache for subsequent uses.
803 if (document_write_intervention_ == 914 if (document_write_intervention_ ==
804 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { 915 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
805 GetMemoryCache()->Remove(pending_script_->GetResource()); 916 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic);
917 pending_script_->RemoveFromMemoryCache();
806 pending_script_->StopWatchingForLoad(); 918 pending_script_->StopWatchingForLoad();
807 return; 919 return;
808 } 920 }
809 921
810 DCHECK(async_exec_type_ != ScriptRunner::kNone); 922 DCHECK(async_exec_type_ != ScriptRunner::kNone);
811 923
812 Document* context_document = element_->GetDocument().ContextDocument(); 924 Document* context_document = element_->GetDocument().ContextDocument();
813 if (!context_document) { 925 if (!context_document) {
814 DetachPendingScript(); 926 DetachPendingScript();
815 return; 927 return;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 // then abort these steps at this point. The script is not executed. 970 // then abort these steps at this point. The script is not executed.
859 return DeprecatedEqualIgnoringCase(event_attribute, "onload") || 971 return DeprecatedEqualIgnoringCase(event_attribute, "onload") ||
860 DeprecatedEqualIgnoringCase(event_attribute, "onload()"); 972 DeprecatedEqualIgnoringCase(event_attribute, "onload()");
861 } 973 }
862 974
863 String ScriptLoader::ScriptContent() const { 975 String ScriptLoader::ScriptContent() const {
864 return element_->TextFromChildren(); 976 return element_->TextFromChildren();
865 } 977 }
866 978
867 } // namespace blink 979 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698