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

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

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

Powered by Google App Engine
This is Rietveld 408576698