| OLD | NEW |
| 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/CrossOriginAttribute.h" | 48 #include "core/html/CrossOriginAttribute.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/loader/modulescript/ModuleScriptFetchRequest.h" |
| 52 #include "core/loader/resource/ScriptResource.h" |
| 48 #include "platform/WebFrameScheduler.h" | 53 #include "platform/WebFrameScheduler.h" |
| 49 #include "platform/loader/fetch/AccessControlStatus.h" | 54 #include "platform/loader/fetch/AccessControlStatus.h" |
| 50 #include "platform/loader/fetch/FetchParameters.h" | 55 #include "platform/loader/fetch/FetchParameters.h" |
| 51 #include "platform/loader/fetch/ResourceFetcher.h" | 56 #include "platform/loader/fetch/ResourceFetcher.h" |
| 52 #include "platform/network/mime/MIMETypeRegistry.h" | 57 #include "platform/network/mime/MIMETypeRegistry.h" |
| 53 #include "platform/weborigin/SecurityOrigin.h" | 58 #include "platform/weborigin/SecurityOrigin.h" |
| 54 #include "platform/wtf/StdLibExtras.h" | 59 #include "platform/wtf/StdLibExtras.h" |
| 55 #include "platform/wtf/text/StringBuilder.h" | 60 #include "platform/wtf/text/StringBuilder.h" |
| 56 #include "platform/wtf/text/StringHash.h" | 61 #include "platform/wtf/text/StringHash.h" |
| 57 #include "public/platform/WebCachePolicy.h" | 62 #include "public/platform/WebCachePolicy.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 element_->GetDocument().GetScriptableDocumentParser()->LineNumber(); | 104 element_->GetDocument().GetScriptableDocumentParser()->LineNumber(); |
| 100 } | 105 } |
| 101 } | 106 } |
| 102 | 107 |
| 103 ScriptLoader::~ScriptLoader() {} | 108 ScriptLoader::~ScriptLoader() {} |
| 104 | 109 |
| 105 DEFINE_TRACE(ScriptLoader) { | 110 DEFINE_TRACE(ScriptLoader) { |
| 106 visitor->Trace(element_); | 111 visitor->Trace(element_); |
| 107 visitor->Trace(resource_); | 112 visitor->Trace(resource_); |
| 108 visitor->Trace(pending_script_); | 113 visitor->Trace(pending_script_); |
| 114 visitor->Trace(module_tree_client_); |
| 109 PendingScriptClient::Trace(visitor); | 115 PendingScriptClient::Trace(visitor); |
| 110 } | 116 } |
| 111 | 117 |
| 112 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() { | 118 void ScriptLoader::SetFetchDocWrittenScriptDeferIdle() { |
| 113 DCHECK(!created_during_document_write_); | 119 DCHECK(!created_during_document_write_); |
| 114 document_write_intervention_ = | 120 document_write_intervention_ = |
| 115 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle; | 121 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle; |
| 116 } | 122 } |
| 117 | 123 |
| 118 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() { | 124 void ScriptLoader::DidNotifySubtreeInsertionsToDocument() { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 // 5. "If the element is not connected, then abort these steps. | 234 // 5. "If the element is not connected, then abort these steps. |
| 229 // The script is not executed." | 235 // The script is not executed." |
| 230 if (!element_->IsConnected()) | 236 if (!element_->IsConnected()) |
| 231 return false; | 237 return false; |
| 232 | 238 |
| 233 // 6. | 239 // 6. |
| 234 // TODO(hiroshige): Annotate and/or cleanup this step. | 240 // TODO(hiroshige): Annotate and/or cleanup this step. |
| 235 if (!IsScriptTypeSupported(support_legacy_types)) | 241 if (!IsScriptTypeSupported(support_legacy_types)) |
| 236 return false; | 242 return false; |
| 237 | 243 |
| 244 // TODO(hiroshige): Make the determination of script type spec-comformant. |
| 245 if (RuntimeEnabledFeatures::moduleScriptsEnabled() && |
| 246 element_->TypeAttributeValue() == "module") { |
| 247 script_type_ = ScriptType::kModule; |
| 248 } else { |
| 249 script_type_ = ScriptType::kClassic; |
| 250 } |
| 251 |
| 238 // 7. "If was-parser-inserted is true, | 252 // 7. "If was-parser-inserted is true, |
| 239 // then flag the element as "parser-inserted" again, | 253 // then flag the element as "parser-inserted" again, |
| 240 // and set the element's "non-blocking" flag to false." | 254 // and set the element's "non-blocking" flag to false." |
| 241 if (was_parser_inserted) { | 255 if (was_parser_inserted) { |
| 242 parser_inserted_ = true; | 256 parser_inserted_ = true; |
| 243 non_blocking_ = false; | 257 non_blocking_ = false; |
| 244 } | 258 } |
| 245 | 259 |
| 246 // 8. "Set the element's "already started" flag." | 260 // 8. "Set the element's "already started" flag." |
| 247 already_started_ = true; | 261 already_started_ = true; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 if (!parser_inserted_ || element_->AsyncAttributeValue() || | 302 if (!parser_inserted_ || element_->AsyncAttributeValue() || |
| 289 element_->DeferAttributeValue()) | 303 element_->DeferAttributeValue()) |
| 290 defer = FetchParameters::kLazyLoad; | 304 defer = FetchParameters::kLazyLoad; |
| 291 if (document_write_intervention_ == | 305 if (document_write_intervention_ == |
| 292 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) | 306 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) |
| 293 defer = FetchParameters::kIdleLoad; | 307 defer = FetchParameters::kIdleLoad; |
| 294 if (!FetchScript(element_->SourceAttributeValue(), encoding, defer)) | 308 if (!FetchScript(element_->SourceAttributeValue(), encoding, defer)) |
| 295 return false; | 309 return false; |
| 296 } | 310 } |
| 297 | 311 |
| 312 // Inline module script is not yet supported. |
| 313 if (GetScriptType() == ScriptType::kModule && !module_tree_client_) { |
| 314 fprintf(stderr, |
| 315 "Inline module script is not yet supported (Document URL: %s)\n", |
| 316 element_document.Url().GetString().Utf8().Data()); |
| 317 CHECK(false); |
| 318 } |
| 319 |
| 298 // 22. "If the element does not have a src content attribute, | 320 // 22. "If the element does not have a src content attribute, |
| 299 // run these substeps:" | 321 // run these substeps:" |
| 300 | 322 |
| 301 // 22.1. "Let source text be the value of the text IDL attribute." | 323 // 22.1. "Let source text be the value of the text IDL attribute." |
| 302 // This step is done later: | 324 // This step is done later: |
| 303 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), | 325 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), |
| 304 // as Element::textFromChildren() in ScriptLoader::scriptContent(), | 326 // as Element::textFromChildren() in ScriptLoader::scriptContent(), |
| 305 // - in HTMLParserScriptRunner::processScriptElementInternal() | 327 // - in HTMLParserScriptRunner::processScriptElementInternal() |
| 306 // (Duplicated code of Step 23, 6th Clause), | 328 // (Duplicated code of Step 23, 6th Clause), |
| 307 // as Element::textContent(), | 329 // as Element::textContent(), |
| 308 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause), | 330 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause), |
| 309 // as Element::textFromChildren() in ScriptLoader::scriptContent(), | 331 // as Element::textFromChildren() in ScriptLoader::scriptContent(), |
| 310 // - PendingScript::getSource() (Indirectly used via | 332 // - PendingScript::getSource() (Indirectly used via |
| 311 // HTMLParserScriptRunner::processScriptElementInternal(), | 333 // HTMLParserScriptRunner::processScriptElementInternal(), |
| 312 // Step 23, 5th Clause), | 334 // Step 23, 5th Clause), |
| 313 // as Element::textContent(). | 335 // as Element::textContent(). |
| 314 // TODO(hiroshige): Make them merged or consistent. | 336 // TODO(hiroshige): Make them merged or consistent. |
| 315 | 337 |
| 316 // 22.2. "Switch on the script's type:" | 338 // 22.2. "Switch on the script's type:" |
| 317 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". | 339 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". |
| 318 // TODO(hiroshige): Implement Step 22.2 for "module". | 340 // TODO(hiroshige): Implement Step 22.2 for "module". |
| 319 | 341 |
| 320 // [Intervention] | 342 // [Intervention] |
| 321 // Since the asynchronous, low priority fetch for doc.written blocked | 343 // Since the asynchronous, low priority fetch for doc.written blocked |
| 322 // script is not for execution, return early from here. Watch for its | 344 // script is not for execution, return early from here. Watch for its |
| 323 // completion to be able to remove it from the memory cache. | 345 // completion to be able to remove it from the memory cache. |
| 324 if (document_write_intervention_ == | 346 if (GetScriptType() == ScriptType::kClassic && |
| 325 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { | 347 document_write_intervention_ == |
| 348 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { |
| 326 pending_script_ = CreatePendingScript(); | 349 pending_script_ = CreatePendingScript(); |
| 327 pending_script_->WatchForLoad(this); | 350 pending_script_->WatchForLoad(this); |
| 328 return true; | 351 return true; |
| 329 } | 352 } |
| 330 | 353 |
| 331 // 23. "Then, follow the first of the following options that describes the | 354 // 23. "Then, follow the first of the following options that describes the |
| 332 // situation:" | 355 // situation:" |
| 333 | 356 |
| 334 // Three flags are used to instruct the caller of prepareScript() to execute | 357 // Three flags are used to instruct the caller of prepareScript() to execute |
| 335 // a part of Step 23, when |m_willBeParserExecuted| is true: | 358 // a part of Step 23, when |m_willBeParserExecuted| is true: |
| 336 // - |m_willBeParserExecuted| | 359 // - |m_willBeParserExecuted| |
| 337 // - |m_willExecuteWhenDocumentFinishedParsing| | 360 // - |m_willExecuteWhenDocumentFinishedParsing| |
| 338 // - |m_readyToBeParserExecuted| | 361 // - |m_readyToBeParserExecuted| |
| 339 // TODO(hiroshige): Clean up the dependency. | 362 // TODO(hiroshige): Clean up the dependency. |
| 340 | 363 |
| 341 // 1st Clause: | 364 // 1st Clause: |
| 342 // - "If the script's type is "classic", and | 365 // - "If the script's type is "classic", and |
| 343 // the element has a src attribute, and the element has a defer attribute, | 366 // the element has a src attribute, and the element has a defer attribute, |
| 344 // and the element has been flagged as "parser-inserted", | 367 // and the element has been flagged as "parser-inserted", |
| 345 // and the element does not have an async attribute" | 368 // and the element does not have an async attribute" |
| 346 // TODO(hiroshige): Check the script's type and implement "module" case. | 369 // - "If the script's type is "module", |
| 347 if (element_->HasSourceAttribute() && element_->DeferAttributeValue() && | 370 // and the element has been flagged as "parser-inserted", |
| 348 parser_inserted_ && !element_->AsyncAttributeValue()) { | 371 // and the element does not have an async attribute" |
| 372 if ((GetScriptType() == ScriptType::kClassic && |
| 373 element_->HasSourceAttribute() && element_->DeferAttributeValue() && |
| 374 parser_inserted_ && !element_->AsyncAttributeValue()) || |
| 375 (GetScriptType() == ScriptType::kModule && parser_inserted_ && |
| 376 !element_->AsyncAttributeValue())) { |
| 349 // This clause is implemented by the caller-side of prepareScript(): | 377 // This clause is implemented by the caller-side of prepareScript(): |
| 350 // - HTMLParserScriptRunner::requestDeferredScript(), and | 378 // - HTMLParserScriptRunner::requestDeferredScript(), and |
| 351 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() | 379 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() |
| 352 will_execute_when_document_finished_parsing_ = true; | 380 will_execute_when_document_finished_parsing_ = true; |
| 353 will_be_parser_executed_ = true; | 381 will_be_parser_executed_ = true; |
| 354 | 382 |
| 355 return true; | 383 return true; |
| 356 } | 384 } |
| 357 | 385 |
| 358 // 2nd Clause: | 386 // 2nd Clause: |
| 359 // - "If the script's type is "classic", | 387 // - "If the script's type is "classic", |
| 360 // and the element has a src attribute, | 388 // and the element has a src attribute, |
| 361 // and the element has been flagged as "parser-inserted", | 389 // and the element has been flagged as "parser-inserted", |
| 362 // and the element does not have an async attribute" | 390 // and the element does not have an async attribute" |
| 363 // TODO(hiroshige): Check the script's type. | 391 // TODO(hiroshige): Check the script's type. |
| 364 if (element_->HasSourceAttribute() && parser_inserted_ && | 392 if (GetScriptType() == ScriptType::kClassic && |
| 393 element_->HasSourceAttribute() && parser_inserted_ && |
| 365 !element_->AsyncAttributeValue()) { | 394 !element_->AsyncAttributeValue()) { |
| 366 // This clause is implemented by the caller-side of prepareScript(): | 395 // This clause is implemented by the caller-side of prepareScript(): |
| 367 // - HTMLParserScriptRunner::requestParsingBlockingScript() | 396 // - HTMLParserScriptRunner::requestParsingBlockingScript() |
| 368 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() | 397 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() |
| 369 will_be_parser_executed_ = true; | 398 will_be_parser_executed_ = true; |
| 370 | 399 |
| 371 return true; | 400 return true; |
| 372 } | 401 } |
| 373 | 402 |
| 374 // 5th Clause: | 403 // 5th Clause: |
| 375 // TODO(hiroshige): Reorder the clauses to match the spec. | 404 // TODO(hiroshige): Reorder the clauses to match the spec. |
| 376 // - "If the element does not have a src attribute, | 405 // - "If the element does not have a src attribute, |
| 377 // and the element has been flagged as "parser-inserted", | 406 // and the element has been flagged as "parser-inserted", |
| 378 // and either the parser that created the script is an XML parser | 407 // and either the parser that created the script is an XML parser |
| 379 // or it's an HTML parser whose script nesting level is not greater than | 408 // or it's an HTML parser whose script nesting level is not greater than |
| 380 // one, | 409 // one, |
| 381 // and the Document of the HTML parser or XML parser that created | 410 // and the Document of the HTML parser or XML parser that created |
| 382 // the script element has a style sheet that is blocking scripts" | 411 // the script element has a style sheet that is blocking scripts" |
| 383 // The last part "... has a style sheet that is blocking scripts" | 412 // The last part "... has a style sheet that is blocking scripts" |
| 384 // is implemented in Document::isScriptExecutionReady(). | 413 // is implemented in Document::isScriptExecutionReady(). |
| 385 // Part of the condition check is done in | 414 // Part of the condition check is done in |
| 386 // HTMLParserScriptRunner::processScriptElementInternal(). | 415 // HTMLParserScriptRunner::processScriptElementInternal(). |
| 387 // TODO(hiroshige): Clean up the split condition check. | 416 // TODO(hiroshige): Clean up the split condition check. |
| 388 if (!element_->HasSourceAttribute() && parser_inserted_ && | 417 // We check that the type is "classic" here, because according to the spec |
| 418 // a "module" script doesn't reach the 5th Clause because the 4th Clause |
| 419 // catches all "module" scripts. |
| 420 if (GetScriptType() == ScriptType::kClassic && |
| 421 !element_->HasSourceAttribute() && parser_inserted_ && |
| 389 !element_document.IsScriptExecutionReady()) { | 422 !element_document.IsScriptExecutionReady()) { |
| 390 // The former part of this clause is | 423 // The former part of this clause is |
| 391 // implemented by the caller-side of prepareScript(): | 424 // implemented by the caller-side of prepareScript(): |
| 392 // - HTMLParserScriptRunner::requestParsingBlockingScript() | 425 // - HTMLParserScriptRunner::requestParsingBlockingScript() |
| 393 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() | 426 // - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() |
| 394 will_be_parser_executed_ = true; | 427 will_be_parser_executed_ = true; |
| 395 // "Set the element's "ready to be parser-executed" flag." | 428 // "Set the element's "ready to be parser-executed" flag." |
| 396 ready_to_be_parser_executed_ = true; | 429 ready_to_be_parser_executed_ = true; |
| 397 | 430 |
| 398 return true; | 431 return true; |
| 399 } | 432 } |
| 400 | 433 |
| 401 // 3rd Clause: | 434 // 3rd Clause: |
| 402 // - "If the script's type is "classic", | 435 // - "If the script's type is "classic", |
| 403 // and the element has a src attribute, | 436 // and the element has a src attribute, |
| 404 // and the element does not have an async attribute, | 437 // and the element does not have an async attribute, |
| 405 // and the element does not have the "non-blocking" flag set" | 438 // and the element does not have the "non-blocking" flag set" |
| 439 // - "If the script's type is "module", |
| 440 // and the element does not have an async attribute, |
| 441 // and the element does not have the "non-blocking" flag set" |
| 406 // TODO(hiroshige): Check the script's type and implement "module" case. | 442 // TODO(hiroshige): Check the script's type and implement "module" case. |
| 407 if (element_->HasSourceAttribute() && !element_->AsyncAttributeValue() && | 443 if ((GetScriptType() == ScriptType::kClassic && |
| 408 !non_blocking_) { | 444 element_->HasSourceAttribute() && !element_->AsyncAttributeValue() && |
| 445 !non_blocking_) || |
| 446 (GetScriptType() == ScriptType::kModule && |
| 447 !element_->AsyncAttributeValue() && !non_blocking_)) { |
| 409 // "Add the element to the end of the list of scripts that will execute | 448 // "Add the element to the end of the list of scripts that will execute |
| 410 // in order as soon as possible associated with the node document of the | 449 // in order as soon as possible associated with the node document of the |
| 411 // script element at the time the prepare a script algorithm started." | 450 // script element at the time the prepare a script algorithm started." |
| 412 pending_script_ = CreatePendingScript(); | 451 pending_script_ = CreatePendingScript(); |
| 413 async_exec_type_ = ScriptRunner::kInOrder; | 452 async_exec_type_ = ScriptRunner::kInOrder; |
| 414 // TODO(hiroshige): Here |contextDocument| is used as "node document" | 453 // TODO(hiroshige): Here |contextDocument| is used as "node document" |
| 415 // while Step 14 uses |elementDocument| as "node document". Fix this. | 454 // while Step 14 uses |element_document| as "node document". Fix this. |
| 416 context_document->GetScriptRunner()->QueueScriptForExecution( | 455 context_document->GetScriptRunner()->QueueScriptForExecution( |
| 417 this, async_exec_type_); | 456 this, async_exec_type_); |
| 418 // Note that watchForLoad can immediately call pendingScriptFinished. | 457 // Note that watchForLoad can immediately call pendingScriptFinished. |
| 419 pending_script_->WatchForLoad(this); | 458 pending_script_->WatchForLoad(this); |
| 420 // The part "When the script is ready..." is implemented in | 459 // The part "When the script is ready..." is implemented in |
| 421 // ScriptRunner::notifyScriptReady(). | 460 // ScriptRunner::notifyScriptReady(). |
| 422 // TODO(hiroshige): Annotate it. | 461 // TODO(hiroshige): Annotate it. |
| 423 | 462 |
| 424 return true; | 463 return true; |
| 425 } | 464 } |
| 426 | 465 |
| 427 // 4th Clause: | 466 // 4th Clause: |
| 428 // - "If the script's type is "classic", and the element has a src attribute" | 467 // - "If the script's type is "classic", and the element has a src attribute" |
| 429 // TODO(hiroshige): Check the script's type and implement "module" case. | 468 // - "If the script's type is "module"" |
| 430 if (element_->HasSourceAttribute()) { | 469 if ((GetScriptType() == ScriptType::kClassic && |
| 470 element_->HasSourceAttribute()) || |
| 471 GetScriptType() == ScriptType::kModule) { |
| 431 // "The element must be added to the set of scripts that will execute | 472 // "The element must be added to the set of scripts that will execute |
| 432 // as soon as possible of the node document of the script element at the | 473 // as soon as possible of the node document of the script element at the |
| 433 // time the prepare a script algorithm started." | 474 // time the prepare a script algorithm started." |
| 434 pending_script_ = CreatePendingScript(); | 475 pending_script_ = CreatePendingScript(); |
| 435 async_exec_type_ = ScriptRunner::kAsync; | 476 async_exec_type_ = ScriptRunner::kAsync; |
| 436 pending_script_->StartStreamingIfPossible(&element_->GetDocument(), | 477 pending_script_->StartStreamingIfPossible(&element_->GetDocument(), |
| 437 ScriptStreamer::kAsync); | 478 ScriptStreamer::kAsync); |
| 479 |
| 438 // TODO(hiroshige): Here |contextDocument| is used as "node document" | 480 // TODO(hiroshige): Here |contextDocument| is used as "node document" |
| 439 // while Step 14 uses |elementDocument| as "node document". Fix this. | 481 // while Step 14 uses |element_document| as "node document". Fix this. |
| 440 context_document->GetScriptRunner()->QueueScriptForExecution( | 482 context_document->GetScriptRunner()->QueueScriptForExecution( |
| 441 this, async_exec_type_); | 483 this, async_exec_type_); |
| 442 // Note that watchForLoad can immediately call pendingScriptFinished. | 484 // Note that watchForLoad can immediately call pendingScriptFinished. |
| 443 pending_script_->WatchForLoad(this); | 485 pending_script_->WatchForLoad(this); |
| 444 // The part "When the script is ready..." is implemented in | 486 // The part "When the script is ready..." is implemented in |
| 445 // ScriptRunner::notifyScriptReady(). | 487 // ScriptRunner::notifyScriptReady(). |
| 446 // TODO(hiroshige): Annotate it. | 488 // TODO(hiroshige): Annotate it. |
| 447 | 489 |
| 448 return true; | 490 return true; |
| 449 } | 491 } |
| 450 | 492 |
| 451 // 6th Clause: | 493 // 6th Clause: |
| 452 // - "Otherwise" | 494 // - "Otherwise" |
| 453 // "Immediately execute the script block, | 495 // "Immediately execute the script block, |
| 454 // even if other scripts are already executing." | 496 // even if other scripts are already executing." |
| 455 // Note: this block is also duplicated in | 497 // Note: this block is also duplicated in |
| 456 // HTMLParserScriptRunner::processScriptElementInternal(). | 498 // HTMLParserScriptRunner::processScriptElementInternal(). |
| 457 // TODO(hiroshige): Merge the duplicated code. | 499 // TODO(hiroshige): Merge the duplicated code. |
| 458 | 500 |
| 459 // This clause is executed only if the script's type is "classic" | 501 // This clause is executed only if the script's type is "classic" |
| 460 // and the element doesn't have a src attribute. | 502 // and the element doesn't have a src attribute. |
| 503 DCHECK_EQ(GetScriptType(), ScriptType::kClassic); |
| 504 DCHECK(!is_external_script_); |
| 461 | 505 |
| 462 // Reset line numbering for nested writes. | 506 // Reset line numbering for nested writes. |
| 463 TextPosition position = element_document.IsInDocumentWrite() | 507 TextPosition position = element_document.IsInDocumentWrite() |
| 464 ? TextPosition() | 508 ? TextPosition() |
| 465 : script_start_position; | 509 : script_start_position; |
| 466 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_) | 510 KURL script_url = (!element_document.IsInDocumentWrite() && parser_inserted_) |
| 467 ? element_document.Url() | 511 ? element_document.Url() |
| 468 : KURL(); | 512 : KURL(); |
| 469 | 513 |
| 470 if (!ExecuteScript(ClassicScript::Create( | 514 if (!ExecuteScript(ClassicScript::Create( |
| 471 ScriptSourceCode(ScriptContent(), script_url, position)))) { | 515 ScriptSourceCode(ScriptContent(), script_url, position)))) { |
| 472 DispatchErrorEvent(); | 516 DispatchErrorEvent(); |
| 473 return false; | 517 return false; |
| 474 } | 518 } |
| 475 | 519 |
| 476 return true; | 520 return true; |
| 477 } | 521 } |
| 478 | 522 |
| 479 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script | 523 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script |
| 480 bool ScriptLoader::FetchScript(const String& source_url, | 524 bool ScriptLoader::FetchScript(const String& source_url, |
| 481 const String& encoding, | 525 const String& encoding, |
| 482 FetchParameters::DeferOption defer) { | 526 FetchParameters::DeferOption defer) { |
| 483 Document* element_document = &(element_->GetDocument()); | 527 Document* element_document = &(element_->GetDocument()); |
| 484 if (!element_->IsConnected() || element_->GetDocument() != element_document) | 528 if (!element_->IsConnected() || element_->GetDocument() != element_document) |
| 485 return false; | 529 return false; |
| 486 | 530 |
| 487 DCHECK(!resource_); | 531 DCHECK(!resource_); |
| 532 DCHECK(!module_tree_client_); |
| 533 |
| 488 // 21. "If the element has a src content attribute, run these substeps:" | 534 // 21. "If the element has a src content attribute, run these substeps:" |
| 489 if (!StripLeadingAndTrailingHTMLSpaces(source_url).IsEmpty()) { | 535 if (!StripLeadingAndTrailingHTMLSpaces(source_url).IsEmpty()) { |
| 490 // 21.4. "Parse src relative to the element's node document." | 536 // 21.4. "Parse src relative to the element's node document." |
| 491 ResourceRequest resource_request(element_document->CompleteURL(source_url)); | 537 KURL url = element_document->CompleteURL(source_url); |
| 492 | |
| 493 // [Intervention] | |
| 494 if (document_write_intervention_ == | |
| 495 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { | |
| 496 resource_request.SetHTTPHeaderField( | |
| 497 "Intervention", | |
| 498 "<https://www.chromestatus.com/feature/5718547946799104>"); | |
| 499 } | |
| 500 | |
| 501 FetchParameters params(resource_request, element_->InitiatorName()); | |
| 502 | 538 |
| 503 // 15. "Let CORS setting be the current state of the element's | 539 // 15. "Let CORS setting be the current state of the element's |
| 504 // crossorigin content attribute." | 540 // crossorigin content attribute." |
| 505 CrossOriginAttributeValue cross_origin = | 541 CrossOriginAttributeValue cross_origin = |
| 506 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); | 542 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); |
| 507 | 543 |
| 508 // 16. "Let module script credentials mode be determined by switching | |
| 509 // on CORS setting:" | |
| 510 // TODO(hiroshige): Implement this step for "module". | |
| 511 | |
| 512 // 21.6, "classic": "Fetch a classic script given ... CORS setting | |
| 513 // ... and encoding." | |
| 514 if (cross_origin != kCrossOriginAttributeNotSet) { | |
| 515 params.SetCrossOriginAccessControl(element_document->GetSecurityOrigin(), | |
| 516 cross_origin); | |
| 517 } | |
| 518 | |
| 519 params.SetCharset(encoding); | |
| 520 | |
| 521 // 17. "If the script element has a nonce attribute, | 544 // 17. "If the script element has a nonce attribute, |
| 522 // then let cryptographic nonce be that attribute's value. | 545 // then let cryptographic nonce be that attribute's value. |
| 523 // Otherwise, let cryptographic nonce be the empty string." | 546 // Otherwise, let cryptographic nonce be the empty string." |
| 547 String nonce; |
| 524 if (element_->IsNonceableElement()) | 548 if (element_->IsNonceableElement()) |
| 525 params.SetContentSecurityPolicyNonce(element_->nonce()); | 549 nonce = element_->nonce(); |
| 526 | 550 |
| 527 // 19. "Let parser state be "parser-inserted" | 551 // 19. "Let parser state be "parser-inserted" |
| 528 // if the script element has been flagged as "parser-inserted", | 552 // if the script element has been flagged as "parser-inserted", |
| 529 // and "not parser-inserted" otherwise." | 553 // and "not parser-inserted" otherwise." |
| 530 params.SetParserDisposition(IsParserInserted() ? kParserInserted | 554 ParserDisposition parser_state = |
| 531 : kNotParserInserted); | 555 IsParserInserted() ? kParserInserted : kNotParserInserted; |
| 532 | |
| 533 params.SetDefer(defer); | |
| 534 | |
| 535 // 18. "If the script element has an integrity attribute, | |
| 536 // then let integrity metadata be that attribute's value. | |
| 537 // Otherwise, let integrity metadata be the empty string." | |
| 538 String integrity_attr = element_->IntegrityAttributeValue(); | |
| 539 if (!integrity_attr.IsEmpty()) { | |
| 540 IntegrityMetadataSet metadata_set; | |
| 541 SubresourceIntegrity::ParseIntegrityAttribute( | |
| 542 integrity_attr, metadata_set, element_document); | |
| 543 params.SetIntegrityMetadata(metadata_set); | |
| 544 } | |
| 545 | 556 |
| 546 // 21.6. "Switch on the script's type:" | 557 // 21.6. "Switch on the script's type:" |
| 558 if (RuntimeEnabledFeatures::moduleScriptsEnabled() && |
| 559 GetScriptType() == ScriptType::kModule) { |
| 560 // - "module": |
| 547 | 561 |
| 548 // - "classic": | 562 // 16. "Let module script credentials mode be determined by switching |
| 549 // "Fetch a classic script given url, settings, cryptographic nonce, | 563 // on CORS setting:" |
| 550 // integrity metadata, parser state, CORS setting, and encoding." | 564 // FOXME |
| 551 resource_ = ScriptResource::Fetch(params, element_document->Fetcher()); | 565 WebURLRequest::FetchCredentialsMode credentials_mode = |
| 566 WebURLRequest::kFetchCredentialsModeOmit; |
| 567 switch (cross_origin) { |
| 568 case kCrossOriginAttributeNotSet: |
| 569 credentials_mode = WebURLRequest::kFetchCredentialsModeOmit; |
| 570 break; |
| 571 case kCrossOriginAttributeAnonymous: |
| 572 credentials_mode = WebURLRequest::kFetchCredentialsModeSameOrigin; |
| 573 break; |
| 574 case kCrossOriginAttributeUseCredentials: |
| 575 credentials_mode = WebURLRequest::kFetchCredentialsModeInclude; |
| 576 break; |
| 577 } |
| 552 | 578 |
| 553 // - "module": | 579 // Step 18 is skipped because "integrity metadata" is not used |
| 554 // "Fetch a module script graph given url, settings, "script", | 580 // for module scripts. |
| 555 // cryptographic nonce, parser state, and | 581 |
| 556 // module script credentials mode." | 582 // TODO(hiroshige): (How) should we reflect |defer|? |
| 557 // TODO(kouhei, hiroshige): Implement this. | 583 |
| 584 // "Fetch a module script graph given url, settings, "script", |
| 585 // cryptographic nonce, parser state, and |
| 586 // module script credentials mode." |
| 587 ModuleScriptFetchRequest module_request(url, nonce, parser_state, |
| 588 credentials_mode); |
| 589 module_tree_client_ = ModulePendingScriptTreeClient::Create(); |
| 590 Modulator::From(ToScriptStateForMainWorld(element_document->GetFrame())) |
| 591 ->FetchTree(module_request, module_tree_client_); |
| 592 } else { |
| 593 // - "classic": |
| 594 |
| 595 // Step 16 is skipped because "module script credentials" is not used |
| 596 // for classic scripts. |
| 597 |
| 598 // 18. "If the script element has an integrity attribute, |
| 599 // then let integrity metadata be that attribute's value. |
| 600 // Otherwise, let integrity metadata be the empty string." |
| 601 String integrity_attr = element_->IntegrityAttributeValue(); |
| 602 |
| 603 // "Fetch a classic script given url, settings, ..." |
| 604 ResourceRequest resource_request(url); |
| 605 |
| 606 // [Intervention] |
| 607 if (document_write_intervention_ == |
| 608 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { |
| 609 resource_request.SetHTTPHeaderField( |
| 610 "Intervention", |
| 611 "<https://www.chromestatus.com/feature/5718547946799104>"); |
| 612 } |
| 613 |
| 614 FetchParameters params(resource_request, element_->InitiatorName()); |
| 615 |
| 616 // "... cryptographic nonce, ..." |
| 617 params.SetContentSecurityPolicyNonce(nonce); |
| 618 |
| 619 // "... integrity metadata, ..." |
| 620 if (!integrity_attr.IsEmpty()) { |
| 621 IntegrityMetadataSet metadata_set; |
| 622 SubresourceIntegrity::ParseIntegrityAttribute( |
| 623 integrity_attr, metadata_set, element_document); |
| 624 params.SetIntegrityMetadata(metadata_set); |
| 625 } |
| 626 |
| 627 // "... parser state, ..." |
| 628 params.SetParserDisposition(parser_state); |
| 629 |
| 630 // "... CORS setting, ..." |
| 631 if (cross_origin != kCrossOriginAttributeNotSet) { |
| 632 params.SetCrossOriginAccessControl( |
| 633 element_document->GetSecurityOrigin(), cross_origin); |
| 634 } |
| 635 |
| 636 // "... and encoding." |
| 637 params.SetCharset(encoding); |
| 638 |
| 639 params.SetDefer(defer); |
| 640 |
| 641 resource_ = ScriptResource::Fetch(params, element_document->Fetcher()); |
| 642 } |
| 558 | 643 |
| 559 // "When the chosen algorithm asynchronously completes, set | 644 // "When the chosen algorithm asynchronously completes, set |
| 560 // the script's script to the result. At that time, the script is ready." | 645 // the script's script to the result. At that time, the script is ready." |
| 561 // When the script is ready, PendingScriptClient::pendingScriptFinished() | 646 // When the script is ready, PendingScriptClient::pendingScriptFinished() |
| 562 // is used as the notification, and the action to take when | 647 // is used as the notification, and the action to take when |
| 563 // the script is ready is specified later, in | 648 // the script is ready is specified later, in |
| 564 // - ScriptLoader::prepareScript(), or | 649 // - ScriptLoader::prepareScript(), or |
| 565 // - HTMLParserScriptRunner, | 650 // - HTMLParserScriptRunner, |
| 566 // depending on the conditions in Step 23 of "prepare a script". | 651 // depending on the conditions in Step 23 of "prepare a script". |
| 567 | 652 |
| 568 // 21.3. "Set the element's from an external file flag." | 653 // 21.3. "Set the element's from an external file flag." |
| 569 is_external_script_ = true; | 654 is_external_script_ = true; |
| 570 } | 655 } |
| 571 | 656 |
| 572 if (!resource_) { | 657 if (GetScriptType() == ScriptType::kClassic && !resource_) { |
| 573 // 21.2. "If src is the empty string, queue a task to | 658 // 21.2. "If src is the empty string, queue a task to |
| 574 // fire an event named error at the element, and abort these steps." | 659 // fire an event named error at the element, and abort these steps." |
| 575 // 21.5. "If the previous step failed, queue a task to | 660 // 21.5. "If the previous step failed, queue a task to |
| 576 // fire an event named error at the element, and abort these steps." | 661 // fire an event named error at the element, and abort these steps." |
| 577 // TODO(hiroshige): Make this asynchronous. | 662 // TODO(hiroshige): Make this asynchronous. |
| 578 DispatchErrorEvent(); | 663 DispatchErrorEvent(); |
| 579 return false; | 664 return false; |
| 580 } | 665 } |
| 581 | 666 |
| 582 // [Intervention] | 667 // [Intervention] |
| 583 if (created_during_document_write_ && | 668 if (GetScriptType() == ScriptType::kClassic && |
| 669 created_during_document_write_ && |
| 584 resource_->GetResourceRequest().GetCachePolicy() == | 670 resource_->GetResourceRequest().GetCachePolicy() == |
| 585 WebCachePolicy::kReturnCacheDataDontLoad) { | 671 WebCachePolicy::kReturnCacheDataDontLoad) { |
| 586 document_write_intervention_ = | 672 document_write_intervention_ = |
| 587 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; | 673 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; |
| 588 } | 674 } |
| 589 | 675 |
| 590 return true; | 676 return true; |
| 591 } | 677 } |
| 592 | 678 |
| 593 PendingScript* ScriptLoader::CreatePendingScript() { | 679 PendingScript* ScriptLoader::CreatePendingScript() { |
| 594 CHECK(resource_); | 680 switch (GetScriptType()) { |
| 595 return ClassicPendingScript::Create(element_, resource_); | 681 case ScriptType::kClassic: |
| 682 CHECK(resource_); |
| 683 return ClassicPendingScript::Create(element_, resource_); |
| 684 case ScriptType::kModule: |
| 685 CHECK(module_tree_client_); |
| 686 return ModulePendingScript::Create(element_, module_tree_client_); |
| 687 } |
| 688 NOTREACHED(); |
| 689 return nullptr; |
| 596 } | 690 } |
| 597 | 691 |
| 598 bool ScriptLoader::ExecuteScript(const Script* script) { | 692 bool ScriptLoader::ExecuteScript(const Script* script) { |
| 599 double script_exec_start_time = MonotonicallyIncreasingTime(); | 693 double script_exec_start_time = MonotonicallyIncreasingTime(); |
| 600 bool result = DoExecuteScript(script); | 694 bool result = DoExecuteScript(script); |
| 601 | 695 |
| 602 // NOTE: we do not check m_willBeParserExecuted here, since | 696 // NOTE: we do not check m_willBeParserExecuted here, since |
| 603 // m_willBeParserExecuted is false for inline scripts, and we want to | 697 // m_willBeParserExecuted is false for inline scripts, and we want to |
| 604 // include inline script execution time as part of parser blocked script | 698 // include inline script execution time as part of parser blocked script |
| 605 // execution time. | 699 // execution time. |
| 606 if (async_exec_type_ == ScriptRunner::kNone) | 700 if (async_exec_type_ == ScriptRunner::kNone) |
| 607 DocumentParserTiming::From(element_->GetDocument()) | 701 DocumentParserTiming::From(element_->GetDocument()) |
| 608 .RecordParserBlockedOnScriptExecutionDuration( | 702 .RecordParserBlockedOnScriptExecutionDuration( |
| 609 MonotonicallyIncreasingTime() - script_exec_start_time, | 703 MonotonicallyIncreasingTime() - script_exec_start_time, |
| 610 WasCreatedDuringDocumentWrite()); | 704 WasCreatedDuringDocumentWrite()); |
| 611 return result; | 705 return result; |
| 612 } | 706 } |
| 613 | 707 |
| 614 // https://html.spec.whatwg.org/#execute-the-script-block | 708 // https://html.spec.whatwg.org/#execute-the-script-block |
| 615 // with additional support for HTML imports. | 709 // with additional support for HTML imports. |
| 616 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), | 710 // Note that Steps 2 and 8 must be handled by the caller of doExecuteScript(), |
| 617 // i.e. load/error events are dispatched by the caller. | 711 // i.e. load/error events are dispatched by the caller. |
| 618 // Steps 3--7 are implemented here in doExecuteScript(). | 712 // Steps 3--7 are implemented here in doExecuteScript(). |
| 619 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). | 713 // TODO(hiroshige): Move event dispatching code to doExecuteScript(). |
| 620 bool ScriptLoader::DoExecuteScript(const Script* script) { | 714 bool ScriptLoader::DoExecuteScript(const Script* script) { |
| 621 DCHECK(already_started_); | 715 DCHECK(already_started_); |
| 716 CHECK_EQ(script->GetScriptType(), GetScriptType()); |
| 622 | 717 |
| 623 if (script->IsEmpty()) | 718 if (script->IsEmpty()) |
| 624 return true; | 719 return true; |
| 625 | 720 |
| 626 Document* element_document = &(element_->GetDocument()); | 721 Document* element_document = &(element_->GetDocument()); |
| 627 Document* context_document = element_document->ContextDocument(); | 722 Document* context_document = element_document->ContextDocument(); |
| 628 if (!context_document) | 723 if (!context_document) |
| 629 return true; | 724 return true; |
| 630 | 725 |
| 631 LocalFrame* frame = context_document->GetFrame(); | 726 LocalFrame* frame = context_document->GetFrame(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 647 script->InlineSourceTextForCSP())) { | 742 script->InlineSourceTextForCSP())) { |
| 648 return false; | 743 return false; |
| 649 } | 744 } |
| 650 } | 745 } |
| 651 | 746 |
| 652 if (is_external_script_) { | 747 if (is_external_script_) { |
| 653 if (!script->CheckMIMETypeBeforeRunScript( | 748 if (!script->CheckMIMETypeBeforeRunScript( |
| 654 context_document, element_->GetDocument().GetSecurityOrigin())) | 749 context_document, element_->GetDocument().GetSecurityOrigin())) |
| 655 return false; | 750 return false; |
| 656 } | 751 } |
| 752 // FOXME: In module cases, AccessControlStatus is not set or used here. |
| 753 // Instead, it is used when module script is fetched (and compiled). |
| 657 | 754 |
| 658 const bool is_imported_script = context_document != element_document; | 755 const bool is_imported_script = context_document != element_document; |
| 659 | 756 |
| 660 // 3. "If the script is from an external file, | 757 // 3. "If the script is from an external file, |
| 661 // or the script's type is module", | 758 // or the script's type is module", |
| 662 // then increment the ignore-destructive-writes counter of the | 759 // then increment the ignore-destructive-writes counter of the |
| 663 // script element's node document. Let neutralized doc be that Document." | 760 // script element's node document. Let neutralized doc be that Document." |
| 664 // TODO(hiroshige): Implement "module" case. | 761 // TODO(hiroshige): Implement "module" case. |
| 665 IgnoreDestructiveWriteCountIncrementer | 762 IgnoreDestructiveWriteCountIncrementer |
| 666 ignore_destructive_write_count_incrementer( | 763 ignore_destructive_write_count_incrementer( |
| 667 is_external_script_ || is_imported_script ? context_document : 0); | 764 is_external_script_ || |
| 765 script->GetScriptType() == ScriptType::kModule || |
| 766 is_imported_script |
| 767 ? context_document |
| 768 : 0); |
| 668 | 769 |
| 669 // 4. "Let old script element be the value to which the script element's | 770 // 4. "Let old script element be the value to which the script element's |
| 670 // node document's currentScript object was most recently set." | 771 // node document's currentScript object was most recently set." |
| 671 // This is implemented as push/popCurrentScript(). | 772 // This is implemented as push/popCurrentScript(). |
| 672 | 773 |
| 673 // 5. "Switch on the script's type:" | 774 // 5. "Switch on the script's type:" |
| 674 // - "classic": | 775 // - "classic": |
| 675 // 1. "If the script element's root is not a shadow root, | 776 // 1. "If the script element's root is not a shadow root, |
| 676 // then set the script element's node document's currentScript | 777 // then set the script element's node document's currentScript |
| 677 // attribute to the script element. Otherwise, set it to null." | 778 // attribute to the script element. Otherwise, set it to null." |
| 678 context_document->PushCurrentScript(element_.Get()); | 779 // - "module": |
| 780 // 1. "Set the script element's node document's currentScript attribute |
| 781 // to null." |
| 782 ScriptElementBase* current_script = nullptr; |
| 783 if (script->GetScriptType() == ScriptType::kClassic) |
| 784 current_script = element_; |
| 785 context_document->PushCurrentScript(current_script); |
| 679 | 786 |
| 787 // - "classic": |
| 680 // 2. "Run the classic script given by the script's script." | 788 // 2. "Run the classic script given by the script's script." |
| 681 // Note: This is where the script is compiled and actually executed. | 789 // Note: This is where the script is compiled and actually executed. |
| 790 // - "module": |
| 791 // 2. "Run the module script given by the script's script." |
| 682 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin()); | 792 script->RunScript(frame, element_->GetDocument().GetSecurityOrigin()); |
| 683 | 793 |
| 684 // - "module": | |
| 685 // TODO(hiroshige): Implement this. | |
| 686 | |
| 687 // 6. "Set the script element's node document's currentScript attribute | 794 // 6. "Set the script element's node document's currentScript attribute |
| 688 // to old script element." | 795 // to old script element." |
| 689 context_document->PopCurrentScript(element_.Get()); | 796 context_document->PopCurrentScript(current_script); |
| 690 | 797 |
| 691 return true; | 798 return true; |
| 692 | 799 |
| 693 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, | 800 // 7. "Decrement the ignore-destructive-writes counter of neutralized doc, |
| 694 // if it was incremented in the earlier step." | 801 // if it was incremented in the earlier step." |
| 695 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. | 802 // Implemented as the scope out of IgnoreDestructiveWriteCountIncrementer. |
| 696 } | 803 } |
| 697 | 804 |
| 698 void ScriptLoader::Execute() { | 805 void ScriptLoader::Execute() { |
| 699 DCHECK(!will_be_parser_executed_); | 806 DCHECK(!will_be_parser_executed_); |
| 700 DCHECK(async_exec_type_ != ScriptRunner::kNone); | 807 DCHECK(async_exec_type_ != ScriptRunner::kNone); |
| 701 DCHECK(pending_script_->IsExternal()); | 808 DCHECK(pending_script_->IsExternal()); |
| 702 bool error_occurred = false; | 809 bool error_occurred = false; |
| 703 Script* script = pending_script_->GetSource(KURL(), error_occurred); | 810 Script* script = pending_script_->GetSource(KURL(), error_occurred); |
| 704 const bool wasCanceled = pending_script_->WasCanceled(); | 811 const bool was_canceled = pending_script_->WasCanceled(); |
| 705 DetachPendingScript(); | 812 DetachPendingScript(); |
| 706 if (error_occurred) { | 813 if (error_occurred) { |
| 707 DispatchErrorEvent(); | 814 DispatchErrorEvent(); |
| 708 } else if (!wasCanceled) { | 815 } else if (!was_canceled) { |
| 709 if (ExecuteScript(script)) | 816 if (ExecuteScript(script)) |
| 710 DispatchLoadEvent(); | 817 DispatchLoadEvent(); |
| 711 else | 818 else |
| 712 DispatchErrorEvent(); | 819 DispatchErrorEvent(); |
| 713 } | 820 } |
| 714 resource_ = nullptr; | 821 resource_ = nullptr; |
| 822 module_tree_client_ = nullptr; |
| 715 } | 823 } |
| 716 | 824 |
| 717 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) { | 825 void ScriptLoader::PendingScriptFinished(PendingScript* pending_script) { |
| 718 DCHECK(!will_be_parser_executed_); | 826 DCHECK(!will_be_parser_executed_); |
| 719 DCHECK_EQ(pending_script_, pending_script); | 827 DCHECK_EQ(pending_script_, pending_script); |
| 828 DCHECK_EQ(pending_script_->GetScriptType(), GetScriptType()); |
| 720 | 829 |
| 721 // We do not need this script in the memory cache. The primary goals of | 830 // We do not need this script in the memory cache. The primary goals of |
| 722 // sending this fetch request are to let the third party server know | 831 // sending this fetch request are to let the third party server know |
| 723 // about the document.write scripts intervention and populate the http | 832 // about the document.write scripts intervention and populate the http |
| 724 // cache for subsequent uses. | 833 // cache for subsequent uses. |
| 725 if (document_write_intervention_ == | 834 if (document_write_intervention_ == |
| 726 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { | 835 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { |
| 727 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic); | 836 DCHECK_EQ(pending_script_->GetScriptType(), ScriptType::kClassic); |
| 728 pending_script_->RemoveFromMemoryCache(); | 837 pending_script_->RemoveFromMemoryCache(); |
| 729 pending_script_->StopWatchingForLoad(); | 838 pending_script_->StopWatchingForLoad(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 // then abort these steps at this point. The script is not executed. | 890 // then abort these steps at this point. The script is not executed. |
| 782 return DeprecatedEqualIgnoringCase(event_attribute, "onload") || | 891 return DeprecatedEqualIgnoringCase(event_attribute, "onload") || |
| 783 DeprecatedEqualIgnoringCase(event_attribute, "onload()"); | 892 DeprecatedEqualIgnoringCase(event_attribute, "onload()"); |
| 784 } | 893 } |
| 785 | 894 |
| 786 String ScriptLoader::ScriptContent() const { | 895 String ScriptLoader::ScriptContent() const { |
| 787 return element_->TextFromChildren(); | 896 return element_->TextFromChildren(); |
| 788 } | 897 } |
| 789 | 898 |
| 790 } // namespace blink | 899 } // namespace blink |
| OLD | NEW |