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

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

Issue 2781713003: Enable module scripts in ScriptLoader (Closed)
Patch Set: Rebase Created 3 years, 8 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/V8Binding.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/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/ResourceFetcher.h" 55 #include "platform/loader/fetch/ResourceFetcher.h"
52 #include "platform/network/mime/MIMETypeRegistry.h" 56 #include "platform/network/mime/MIMETypeRegistry.h"
53 #include "platform/weborigin/SecurityOrigin.h" 57 #include "platform/weborigin/SecurityOrigin.h"
54 #include "platform/wtf/StdLibExtras.h" 58 #include "platform/wtf/StdLibExtras.h"
55 #include "platform/wtf/text/StringBuilder.h" 59 #include "platform/wtf/text/StringBuilder.h"
56 #include "platform/wtf/text/StringHash.h" 60 #include "platform/wtf/text/StringHash.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 element_->GetDocument().GetScriptableDocumentParser()->LineNumber(); 103 element_->GetDocument().GetScriptableDocumentParser()->LineNumber();
100 } 104 }
101 } 105 }
102 106
103 ScriptLoader::~ScriptLoader() {} 107 ScriptLoader::~ScriptLoader() {}
104 108
105 DEFINE_TRACE(ScriptLoader) { 109 DEFINE_TRACE(ScriptLoader) {
106 visitor->Trace(element_); 110 visitor->Trace(element_);
107 visitor->Trace(resource_); 111 visitor->Trace(resource_);
108 visitor->Trace(pending_script_); 112 visitor->Trace(pending_script_);
113 visitor->Trace(module_tree_client_);
109 PendingScriptClient::Trace(visitor); 114 PendingScriptClient::Trace(visitor);
110 } 115 }
111 116
112 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() { 117 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() {
113 DCHECK(!created_during_document_write_); 118 DCHECK(!created_during_document_write_);
114 document_write_intervention_ = 119 document_write_intervention_ =
115 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle; 120 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle;
116 } 121 }
117 122
118 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() { 123 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 if (!IsScriptForEventSupported()) 312 if (!IsScriptForEventSupported())
308 return false; 313 return false;
309 314
310 // 14. is handled below. 315 // 14. is handled below.
311 316
312 // 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
313 // crossorigin content attribute." 318 // crossorigin content attribute."
314 CrossOriginAttributeValue cross_origin = 319 CrossOriginAttributeValue cross_origin =
315 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); 320 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue());
316 321
317 // 16. will be handled below once module script support is implemented. 322 // 16. is handled below.
318 323
319 // 17. "If the script element has a nonce attribute, 324 // 17. "If the script element has a nonce attribute,
320 // then let cryptographic nonce be that attribute's value. 325 // then let cryptographic nonce be that attribute's value.
321 // Otherwise, let cryptographic nonce be the empty string." 326 // Otherwise, let cryptographic nonce be the empty string."
322 String nonce; 327 String nonce;
323 if (element_->IsNonceableElement()) 328 if (element_->IsNonceableElement())
324 nonce = element_->nonce(); 329 nonce = element_->nonce();
325 330
326 // 18. is handled below. 331 // 18. is handled below.
327 332
(...skipping 28 matching lines...) Expand all
356 // 21.5. "If the previous step failed, queue a task to 361 // 21.5. "If the previous step failed, queue a task to
357 // 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."
358 if (!url.IsValid()) { 363 if (!url.IsValid()) {
359 // TODO(hiroshige): Make this asynchronous. Currently we fire the error 364 // TODO(hiroshige): Make this asynchronous. Currently we fire the error
360 // event synchronously to keep the existing behavior. 365 // event synchronously to keep the existing behavior.
361 DispatchErrorEvent(); 366 DispatchErrorEvent();
362 return false; 367 return false;
363 } 368 }
364 369
365 DCHECK(!resource_); 370 DCHECK(!resource_);
371 DCHECK(!module_tree_client_);
366 372
367 // 21.6. "Switch on the script's type:" 373 // 21.6. "Switch on the script's type:"
368 // - "classic": 374 if (GetScriptType() == ScriptType::kClassic) {
375 // - "classic":
369 376
370 // 14. "If the script element has a charset attribute, 377 // 14. "If the script element has a charset attribute,
371 // then let encoding be the result of 378 // then let encoding be the result of
372 // getting an encoding from the value of the charset attribute." 379 // getting an encoding from the value of the charset attribute."
373 // "If the script element does not have a charset attribute, 380 // "If the script element does not have a charset attribute,
374 // or if getting an encoding failed, let encoding 381 // or if getting an encoding failed, let encoding
375 // 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
376 // document." 383 // document."
377 // TODO(hiroshige): Should we handle failure in getting an encoding? 384 // TODO(hiroshige): Should we handle failure in getting an encoding?
378 String encoding; 385 String encoding;
379 if (!element_->CharsetAttributeValue().IsEmpty()) 386 if (!element_->CharsetAttributeValue().IsEmpty())
380 encoding = element_->CharsetAttributeValue(); 387 encoding = element_->CharsetAttributeValue();
381 else 388 else
382 encoding = element_document.characterSet(); 389 encoding = element_document.characterSet();
383 390
384 // Step 16 is skipped because "module script credentials" is not used 391 // Step 16 is skipped because "module script credentials" is not used
385 // for classic scripts. 392 // for classic scripts.
386 393
387 // 18. "If the script element has an integrity attribute, 394 // 18. "If the script element has an integrity attribute,
388 // then let integrity metadata be that attribute's value. 395 // then let integrity metadata be that attribute's value.
389 // Otherwise, let integrity metadata be the empty string." 396 // Otherwise, let integrity metadata be the empty string."
390 String integrity_attr = element_->IntegrityAttributeValue(); 397 String integrity_attr = element_->IntegrityAttributeValue();
391 IntegrityMetadataSet integrity_metadata; 398 IntegrityMetadataSet integrity_metadata;
392 if (!integrity_attr.IsEmpty()) { 399 if (!integrity_attr.IsEmpty()) {
393 SubresourceIntegrity::ParseIntegrityAttribute( 400 SubresourceIntegrity::ParseIntegrityAttribute(
394 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_);
395 } 445 }
396 446
397 if (!FetchClassicScript(url, element_document.Fetcher(), nonce,
398 integrity_metadata, parser_state, cross_origin,
399 element_document.GetSecurityOrigin(), encoding)) {
400 // TODO(hiroshige): Make this asynchronous. Currently we fire the error
401 // event synchronously to keep the existing behavior.
402 DispatchErrorEvent();
403 return false;
404 }
405
406 DCHECK(resource_);
407
408 // - "module":
409 // TODO(hiroshige): Implement this.
410
411 // "When the chosen algorithm asynchronously completes, set 447 // "When the chosen algorithm asynchronously completes, set
412 // 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."
413 // When the script is ready, PendingScriptClient::pendingScriptFinished() 449 // When the script is ready, PendingScriptClient::pendingScriptFinished()
414 // is used as the notification, and the action to take when 450 // is used as the notification, and the action to take when
415 // the script is ready is specified later, in 451 // the script is ready is specified later, in
416 // - ScriptLoader::PrepareScript(), or 452 // - ScriptLoader::PrepareScript(), or
417 // - HTMLParserScriptRunner, 453 // - HTMLParserScriptRunner,
418 // depending on the conditions in Step 23 of "prepare a script". 454 // depending on the conditions in Step 23 of "prepare a script".
419 } 455 }
420 456
421 // 22. "If the element does not have a src content attribute, 457 // 22. "If the element does not have a src content attribute,
422 // 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.
423 474
424 // 22.1. "Let source text be the value of the text IDL attribute." 475 // 22.2. "Switch on the script's type:"
425 // This step is done later: 476 switch (GetScriptType()) {
426 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), 477 // - "classic":
427 // as Element::textFromChildren() in ScriptLoader::scriptContent(), 478 case ScriptType::kClassic:
428 // - in HTMLParserScriptRunner::processScriptElementInternal() 479 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic".
429 // (Duplicated code of Step 23, 6th Clause), 480 break;
430 // as Element::textContent(),
431 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause),
432 // as Element::textFromChildren() in ScriptLoader::scriptContent(),
433 // - PendingScript::getSource() (Indirectly used via
434 // HTMLParserScriptRunner::processScriptElementInternal(),
435 // Step 23, 5th Clause),
436 // as Element::textContent().
437 // TODO(hiroshige): Make them merged or consistent.
438 481
439 // 22.2. "Switch on the script's type:" 482 // - "module":
440 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". 483 case ScriptType::kModule:
441 // 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?
kouhei (in TOK) 2017/04/24 01:24:03 just put NOTIMPLEMENTED() for now (for code which
hiroshige 2017/04/26 01:09:34 I put console logging in Patch Set 21.
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 }
442 494
443 // [Intervention] 495 // [Intervention]
444 // Since the asynchronous, low priority fetch for doc.written blocked 496 // Since the asynchronous, low priority fetch for doc.written blocked
445 // 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
446 // completion to be able to remove it from the memory cache. 498 // completion to be able to remove it from the memory cache.
447 if (document_write_intervention_ == 499 if (GetScriptType() == ScriptType::kClassic &&
448 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { 500 document_write_intervention_ ==
501 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
449 pending_script_ = CreatePendingScript(); 502 pending_script_ = CreatePendingScript();
450 pending_script_->WatchForLoad(this); 503 pending_script_->WatchForLoad(this);
451 return true; 504 return true;
452 } 505 }
453 506
454 // 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
455 // situation:" 508 // situation:"
456 509
457 // 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
458 // a part of Step 23, when |m_willBeParserExecuted| is true: 511 // a part of Step 23, when |m_willBeParserExecuted| is true:
459 // - |m_willBeParserExecuted| 512 // - |m_willBeParserExecuted|
460 // - |m_willExecuteWhenDocumentFinishedParsing| 513 // - |m_willExecuteWhenDocumentFinishedParsing|
461 // - |m_readyToBeParserExecuted| 514 // - |m_readyToBeParserExecuted|
462 // TODO(hiroshige): Clean up the dependency. 515 // TODO(hiroshige): Clean up the dependency.
463 516
464 // 1st Clause: 517 // 1st Clause:
465 // - "If the script's type is "classic", and 518 // - "If the script's type is "classic", and
466 // 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,
467 // and the element has been flagged as "parser-inserted", 520 // and the element has been flagged as "parser-inserted",
468 // and the element does not have an async attribute" 521 // and the element does not have an async attribute"
469 // TODO(hiroshige): Check the script's type and implement "module" case. 522 // - "If the script's type is "module",
470 if (element_->HasSourceAttribute() && element_->DeferAttributeValue() && 523 // and the element has been flagged as "parser-inserted",
471 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())) {
472 // This clause is implemented by the caller-side of prepareScript(): 530 // This clause is implemented by the caller-side of prepareScript():
473 // - HTMLParserScriptRunner::requestDeferredScript(), and 531 // - HTMLParserScriptRunner::requestDeferredScript(), and
474 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 532 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
475 will_execute_when_document_finished_parsing_ = true; 533 will_execute_when_document_finished_parsing_ = true;
476 will_be_parser_executed_ = true; 534 will_be_parser_executed_ = true;
477 535
478 return true; 536 return true;
479 } 537 }
480 538
481 // 2nd Clause: 539 // 2nd Clause:
482 // - "If the script's type is "classic", 540 // - "If the script's type is "classic",
483 // and the element has a src attribute, 541 // and the element has a src attribute,
484 // and the element has been flagged as "parser-inserted", 542 // and the element has been flagged as "parser-inserted",
485 // and the element does not have an async attribute" 543 // and the element does not have an async attribute"
486 // TODO(hiroshige): Check the script's type. 544 // TODO(hiroshige): Check the script's type.
487 if (element_->HasSourceAttribute() && parser_inserted_ && 545 if (GetScriptType() == ScriptType::kClassic &&
546 element_->HasSourceAttribute() && parser_inserted_ &&
488 !element_->AsyncAttributeValue()) { 547 !element_->AsyncAttributeValue()) {
489 // This clause is implemented by the caller-side of prepareScript(): 548 // This clause is implemented by the caller-side of prepareScript():
490 // - HTMLParserScriptRunner::requestParsingBlockingScript() 549 // - HTMLParserScriptRunner::requestParsingBlockingScript()
491 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 550 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
492 will_be_parser_executed_ = true; 551 will_be_parser_executed_ = true;
493 552
494 return true; 553 return true;
495 } 554 }
496 555
497 // 5th Clause: 556 // 5th Clause:
498 // TODO(hiroshige): Reorder the clauses to match the spec. 557 // TODO(hiroshige): Reorder the clauses to match the spec.
499 // - "If the element does not have a src attribute, 558 // - "If the element does not have a src attribute,
500 // and the element has been flagged as "parser-inserted", 559 // and the element has been flagged as "parser-inserted",
501 // 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
502 // 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
503 // one, 562 // one,
504 // 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
505 // the script element has a style sheet that is blocking scripts" 564 // the script element has a style sheet that is blocking scripts"
506 // The last part "... has a style sheet that is blocking scripts" 565 // The last part "... has a style sheet that is blocking scripts"
507 // is implemented in Document::isScriptExecutionReady(). 566 // is implemented in Document::isScriptExecutionReady().
508 // Part of the condition check is done in 567 // Part of the condition check is done in
509 // HTMLParserScriptRunner::processScriptElementInternal(). 568 // HTMLParserScriptRunner::processScriptElementInternal().
510 // TODO(hiroshige): Clean up the split condition check. 569 // TODO(hiroshige): Clean up the split condition check.
511 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_ &&
512 !element_document.IsScriptExecutionReady()) { 575 !element_document.IsScriptExecutionReady()) {
513 // The former part of this clause is 576 // The former part of this clause is
514 // implemented by the caller-side of prepareScript(): 577 // implemented by the caller-side of prepareScript():
515 // - HTMLParserScriptRunner::requestParsingBlockingScript() 578 // - HTMLParserScriptRunner::requestParsingBlockingScript()
516 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() 579 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs()
517 will_be_parser_executed_ = true; 580 will_be_parser_executed_ = true;
518 // "Set the element's "ready to be parser-executed" flag." 581 // "Set the element's "ready to be parser-executed" flag."
519 ready_to_be_parser_executed_ = true; 582 ready_to_be_parser_executed_ = true;
520 583
521 return true; 584 return true;
522 } 585 }
523 586
524 // 3rd Clause: 587 // 3rd Clause:
525 // - "If the script's type is "classic", 588 // - "If the script's type is "classic",
526 // and the element has a src attribute, 589 // and the element has a src attribute,
527 // and the element does not have an async attribute, 590 // and the element does not have an async attribute,
528 // 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"
529 // TODO(hiroshige): Check the script's type and implement "module" case. 595 // TODO(hiroshige): Check the script's type and implement "module" case.
530 if (element_->HasSourceAttribute() && !element_->AsyncAttributeValue() && 596 if ((GetScriptType() == ScriptType::kClassic &&
531 !non_blocking_) { 597 element_->HasSourceAttribute() && !element_->AsyncAttributeValue() &&
598 !non_blocking_) ||
599 (GetScriptType() == ScriptType::kModule &&
600 !element_->AsyncAttributeValue() && !non_blocking_)) {
532 // "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
533 // 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
534 // script element at the time the prepare a script algorithm started." 603 // script element at the time the prepare a script algorithm started."
535 pending_script_ = CreatePendingScript(); 604 pending_script_ = CreatePendingScript();
536 async_exec_type_ = ScriptRunner::kInOrder; 605 async_exec_type_ = ScriptRunner::kInOrder;
537 // TODO(hiroshige): Here |contextDocument| is used as "node document" 606 // TODO(hiroshige): Here |contextDocument| is used as "node document"
538 // while Step 14 uses |elementDocument| as "node document". Fix this. 607 // while Step 14 uses |elementDocument| as "node document". Fix this.
539 context_document->GetScriptRunner()->QueueScriptForExecution( 608 context_document->GetScriptRunner()->QueueScriptForExecution(
540 this, async_exec_type_); 609 this, async_exec_type_);
541 // Note that watchForLoad can immediately call pendingScriptFinished. 610 // Note that watchForLoad can immediately call pendingScriptFinished.
542 pending_script_->WatchForLoad(this); 611 pending_script_->WatchForLoad(this);
543 // The part "When the script is ready..." is implemented in 612 // The part "When the script is ready..." is implemented in
544 // ScriptRunner::notifyScriptReady(). 613 // ScriptRunner::notifyScriptReady().
545 // TODO(hiroshige): Annotate it. 614 // TODO(hiroshige): Annotate it.
546 615
547 return true; 616 return true;
548 } 617 }
549 618
550 // 4th Clause: 619 // 4th Clause:
551 // - "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"
552 // TODO(hiroshige): Check the script's type and implement "module" case. 621 // - "If the script's type is "module""
553 if (element_->HasSourceAttribute()) { 622 if ((GetScriptType() == ScriptType::kClassic &&
623 element_->HasSourceAttribute()) ||
624 GetScriptType() == ScriptType::kModule) {
554 // "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
555 // 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
556 // time the prepare a script algorithm started." 627 // time the prepare a script algorithm started."
557 pending_script_ = CreatePendingScript(); 628 pending_script_ = CreatePendingScript();
558 async_exec_type_ = ScriptRunner::kAsync; 629 async_exec_type_ = ScriptRunner::kAsync;
559 pending_script_->StartStreamingIfPossible(&element_->GetDocument(), 630 pending_script_->StartStreamingIfPossible(&element_->GetDocument(),
560 ScriptStreamer::kAsync); 631 ScriptStreamer::kAsync);
561 // TODO(hiroshige): Here |contextDocument| is used as "node document" 632 // TODO(hiroshige): Here |contextDocument| is used as "node document"
562 // while Step 14 uses |elementDocument| as "node document". Fix this. 633 // while Step 14 uses |elementDocument| as "node document". Fix this.
563 context_document->GetScriptRunner()->QueueScriptForExecution( 634 context_document->GetScriptRunner()->QueueScriptForExecution(
(...skipping 10 matching lines...) Expand all
574 // 6th Clause: 645 // 6th Clause:
575 // - "Otherwise" 646 // - "Otherwise"
576 // "Immediately execute the script block, 647 // "Immediately execute the script block,
577 // even if other scripts are already executing." 648 // even if other scripts are already executing."
578 // Note: this block is also duplicated in 649 // Note: this block is also duplicated in
579 // HTMLParserScriptRunner::processScriptElementInternal(). 650 // HTMLParserScriptRunner::processScriptElementInternal().
580 // TODO(hiroshige): Merge the duplicated code. 651 // TODO(hiroshige): Merge the duplicated code.
581 652
582 // 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"
583 // 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_);
584 657
585 // Reset line numbering for nested writes. 658 // Reset line numbering for nested writes.
586 TextPosition position = element_document.IsInDocumentWrite() 659 TextPosition position = element_document.IsInDocumentWrite()
587 ? TextPosition() 660 ? TextPosition()
588 : script_start_position; 661 : script_start_position;
589 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_) 662 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_)
590 ? element_document.Url() 663 ? element_document.Url()
591 : KURL(); 664 : KURL();
592 665
593 if (!ExecuteScript(ClassicScript::Create( 666 if (!ExecuteScript(ClassicScript::Create(
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 if (created_during_document_write_ && 733 if (created_during_document_write_ &&
661 resource_->GetResourceRequest().GetCachePolicy() == 734 resource_->GetResourceRequest().GetCachePolicy() ==
662 WebCachePolicy::kReturnCacheDataDontLoad) { 735 WebCachePolicy::kReturnCacheDataDontLoad) {
663 document_write_intervention_ = 736 document_write_intervention_ =
664 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; 737 DocumentWriteIntervention::kDoNotFetchDocWrittenScript;
665 } 738 }
666 739
667 return true; 740 return true;
668 } 741 }
669 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
670 PendingScript* ScriptLoader::CreatePendingScript() { 762 PendingScript* ScriptLoader::CreatePendingScript() {
671 CHECK(resource_); 763 switch (GetScriptType()) {
672 return ClassicPendingScript::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;
673 } 773 }
674 774
675 bool ScriptLoader::ExecuteScript(const Script* script) { 775 bool ScriptLoader::ExecuteScript(const Script* script) {
676 double script_exec_start_time = MonotonicallyIncreasingTime(); 776 double script_exec_start_time = MonotonicallyIncreasingTime();
677 bool result = DoExecuteScript(script); 777 bool result = DoExecuteScript(script);
678 778
679 // NOTE: we do not check m_willBeParserExecuted here, since 779 // NOTE: we do not check m_willBeParserExecuted here, since
680 // m_willBeParserExecuted is false for inline scripts, and we want to 780 // m_willBeParserExecuted is false for inline scripts, and we want to
681 // include inline script execution time as part of parser blocked script 781 // include inline script execution time as part of parser blocked script
682 // execution time. 782 // execution time.
683 if (async_exec_type_ == ScriptRunner::kNone) 783 if (async_exec_type_ == ScriptRunner::kNone)
684 DocumentParserTiming::From(element_->GetDocument()) 784 DocumentParserTiming::From(element_->GetDocument())
685 .RecordParserBlockedOnScriptExecutionDuration( 785 .RecordParserBlockedOnScriptExecutionDuration(
686 MonotonicallyIncreasingTime() - script_exec_start_time, 786 MonotonicallyIncreasingTime() - script_exec_start_time,
687 WasCreatedDuringDocumentWrite()); 787 WasCreatedDuringDocumentWrite());
688 return result; 788 return result;
689 } 789 }
690 790
691 // https://html.spec.whatwg.org/#execute-the-script-block 791 // https://html.spec.whatwg.org/#execute-the-script-block
692 // with additional support for HTML imports. 792 // with additional support for HTML imports.
693 // 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(),
694 // i.e. load/error events are dispatched by the caller. 794 // i.e. load/error events are dispatched by the caller.
695 // Steps 3--7 are implemented here in doExecuteScript(). 795 // Steps 3--7 are implemented here in doExecuteScript().
696 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). 796 // TODO(hiroshige): Move event dispatching code to doExecuteScript().
697 bool ScriptLoader::DoExecuteScript(const Script* script) { 797 bool ScriptLoader::DoExecuteScript(const Script* script) {
698 DCHECK(already_started_); 798 DCHECK(already_started_);
799 CHECK_EQ(script->GetScriptType(), GetScriptType());
699 800
700 if (script->IsEmpty()) 801 if (script->IsEmpty())
701 return true; 802 return true;
702 803
703 Document* element_document = &(element_->GetDocument()); 804 Document* element_document = &(element_->GetDocument());
704 Document* context_document = element_document->ContextDocument(); 805 Document* context_document = element_document->ContextDocument();
705 if (!context_document) 806 if (!context_document)
706 return true; 807 return true;
707 808
708 LocalFrame* frame = context_document->GetFrame(); 809 LocalFrame* frame = context_document->GetFrame();
(...skipping 22 matching lines...) Expand all
731 context_document, element_->GetDocument().GetSecurityOrigin())) 832 context_document, element_->GetDocument().GetSecurityOrigin()))
732 return false; 833 return false;
733 } 834 }
734 835
735 const bool is_imported_script = context_document != element_document; 836 const bool is_imported_script = context_document != element_document;
736 837
737 // 3. "If the script is from an external file, 838 // 3. "If the script is from an external file,
738 // or the script's type is module", 839 // or the script's type is module",
739 // then increment the ignore-destructive-writes counter of the 840 // then increment the ignore-destructive-writes counter of the
740 // script element's node document. Let neutralized doc be that Document." 841 // script element's node document. Let neutralized doc be that Document."
741 // TODO(hiroshige): Implement "module" case.
742 IgnoreDestructiveWriteCountIncrementer 842 IgnoreDestructiveWriteCountIncrementer
743 ignore_destructive_write_count_incrementer( 843 ignore_destructive_write_count_incrementer(
744 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);
745 849
746 // 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
747 // node document's currentScript object was most recently set." 851 // node document's currentScript object was most recently set."
748 // This is implemented as push/popCurrentScript(). 852 // This is implemented as push/popCurrentScript().
749 853
750 // 5. "Switch on the script's type:" 854 // 5. "Switch on the script's type:"
751 // - "classic": 855 // - "classic":
752 // 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,
753 // then set the script element's node document's currentScript 857 // then set the script element's node document's currentScript
754 // attribute to the script element. Otherwise, set it to null." 858 // attribute to the script element. Otherwise, set it to null."
755 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);
756 866
867 // - "classic":
757 // 2. "Run the classic script given by the script's script." 868 // 2. "Run the classic script given by the script's script."
758 // 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."
759 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin()); 872 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin());
760 873
761 // - "module":
762 // TODO(hiroshige): Implement this.
763
764 // 6. "Set the script element's node document's currentScript attribute 874 // 6. "Set the script element's node document's currentScript attribute
765 // to old script element." 875 // to old script element."
766 context_document->PopCurrentScript(element_.Get()); 876 context_document->PopCurrentScript(current_script);
767 877
768 return true; 878 return true;
769 879
770 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, 880 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc,
771 // if it was incremented in the earlier step." 881 // if it was incremented in the earlier step."
772 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. 882 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer.
773 } 883 }
774 884
775 void ScriptLoader::Execute() { 885 void ScriptLoader::Execute() {
776 DCHECK(!will_be_parser_executed_); 886 DCHECK(!will_be_parser_executed_);
777 DCHECK(async_exec_type_ != ScriptRunner::kNone); 887 DCHECK(async_exec_type_ != ScriptRunner::kNone);
778 DCHECK(pending_script_->IsExternal()); 888 DCHECK(pending_script_->IsExternal());
779 bool error_occurred = false; 889 bool error_occurred = false;
780 Script* script = pending_script_->GetSource(KURL(), error_occurred); 890 Script* script = pending_script_->GetSource(KURL(), error_occurred);
781 const bool wasCanceled = pending_script_->WasCanceled(); 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 (!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);
908 DCHECK_EQ(pending_script_->GetScriptType(), GetScriptType());
797 909
798 // 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
799 // 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
800 // about the document.write scripts intervention and populate the http 912 // about the document.write scripts intervention and populate the http
801 // cache for subsequent uses. 913 // cache for subsequent uses.
802 if (document_write_intervention_ == 914 if (document_write_intervention_ ==
803 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { 915 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
804 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic); 916 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic);
805 pending_script_->RemoveFromMemoryCache(); 917 pending_script_->RemoveFromMemoryCache();
806 pending_script_->StopWatchingForLoad(); 918 pending_script_->StopWatchingForLoad();
(...skipping 51 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