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 |
(...skipping 24 matching lines...) Expand all Loading... | |
35 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" | 35 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" |
36 #include "core/dom/Script.h" | 36 #include "core/dom/Script.h" |
37 #include "core/dom/ScriptElementBase.h" | 37 #include "core/dom/ScriptElementBase.h" |
38 #include "core/dom/ScriptRunner.h" | 38 #include "core/dom/ScriptRunner.h" |
39 #include "core/dom/ScriptableDocumentParser.h" | 39 #include "core/dom/ScriptableDocumentParser.h" |
40 #include "core/dom/Text.h" | 40 #include "core/dom/Text.h" |
41 #include "core/events/Event.h" | 41 #include "core/events/Event.h" |
42 #include "core/frame/LocalFrame.h" | 42 #include "core/frame/LocalFrame.h" |
43 #include "core/frame/SubresourceIntegrity.h" | 43 #include "core/frame/SubresourceIntegrity.h" |
44 #include "core/frame/csp/ContentSecurityPolicy.h" | 44 #include "core/frame/csp/ContentSecurityPolicy.h" |
45 #include "core/html/CrossOriginAttribute.h" | |
46 #include "core/html/imports/HTMLImport.h" | 45 #include "core/html/imports/HTMLImport.h" |
47 #include "core/html/parser/HTMLParserIdioms.h" | 46 #include "core/html/parser/HTMLParserIdioms.h" |
47 #include "core/loader/resource/ScriptResource.h" | |
48 #include "platform/WebFrameScheduler.h" | 48 #include "platform/WebFrameScheduler.h" |
49 #include "platform/loader/fetch/AccessControlStatus.h" | 49 #include "platform/loader/fetch/AccessControlStatus.h" |
50 #include "platform/loader/fetch/FetchParameters.h" | 50 #include "platform/loader/fetch/FetchParameters.h" |
51 #include "platform/loader/fetch/ResourceFetcher.h" | 51 #include "platform/loader/fetch/ResourceFetcher.h" |
52 #include "platform/network/mime/MIMETypeRegistry.h" | 52 #include "platform/network/mime/MIMETypeRegistry.h" |
53 #include "platform/weborigin/SecurityOrigin.h" | 53 #include "platform/weborigin/SecurityOrigin.h" |
54 #include "platform/wtf/StdLibExtras.h" | 54 #include "platform/wtf/StdLibExtras.h" |
55 #include "platform/wtf/text/StringBuilder.h" | 55 #include "platform/wtf/text/StringBuilder.h" |
56 #include "platform/wtf/text/StringHash.h" | 56 #include "platform/wtf/text/StringHash.h" |
57 #include "public/platform/WebCachePolicy.h" | 57 #include "public/platform/WebCachePolicy.h" |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 | 260 |
261 // 10. "If scripting is disabled for the script element, then abort these | 261 // 10. "If scripting is disabled for the script element, then abort these |
262 // steps at this point. The script is not executed." | 262 // steps at this point. The script is not executed." |
263 if (!context_document->CanExecuteScripts(kAboutToExecuteScript)) | 263 if (!context_document->CanExecuteScripts(kAboutToExecuteScript)) |
264 return false; | 264 return false; |
265 | 265 |
266 // 13. | 266 // 13. |
267 if (!IsScriptForEventSupported()) | 267 if (!IsScriptForEventSupported()) |
268 return false; | 268 return false; |
269 | 269 |
270 // 14. "If the script element has a charset attribute, | 270 // 14. is handled below. |
hiroshige
2017/04/14 00:13:29
Step 14 is moved below.
| |
271 // then let encoding be the result of | |
272 // getting an encoding from the value of the charset attribute." | |
273 // "If the script element does not have a charset attribute, | |
274 // or if getting an encoding failed, let encoding | |
275 // be the same as the encoding of the script element's node document." | |
276 // TODO(hiroshige): Should we handle failure in getting an encoding? | |
277 String encoding; | |
278 if (!element_->CharsetAttributeValue().IsEmpty()) | |
279 encoding = element_->CharsetAttributeValue(); | |
280 else | |
281 encoding = element_document.characterSet(); | |
282 | 271 |
283 // Steps 15--20 are handled in fetchScript(). | 272 // 15. "Let CORS setting be the current state of the element's |
hiroshige
2017/04/14 00:13:29
Step 15 is moved from FetchScript().
| |
273 // crossorigin content attribute." | |
274 CrossOriginAttributeValue cross_origin = | |
275 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); | |
276 | |
277 // 16. will be handled below once module script support is implemented. | |
278 | |
279 // 17. "If the script element has a nonce attribute, | |
hiroshige
2017/04/14 00:13:29
Step 17 is moved from FetchScript().
| |
280 // then let cryptographic nonce be that attribute's value. | |
281 // Otherwise, let cryptographic nonce be the empty string." | |
282 String nonce; | |
283 if (element_->IsNonceableElement()) | |
284 nonce = element_->nonce(); | |
285 | |
286 // 18. is handled below. | |
287 | |
288 // 19. "Let parser state be "parser-inserted" | |
hiroshige
2017/04/14 00:13:29
Step 19 is moved from FetchScript().
| |
289 // if the script element has been flagged as "parser-inserted", | |
290 // and "not parser-inserted" otherwise." | |
291 ParserDisposition parser_state = | |
292 IsParserInserted() ? kParserInserted : kNotParserInserted; | |
284 | 293 |
285 // 21. "If the element has a src content attribute, run these substeps:" | 294 // 21. "If the element has a src content attribute, run these substeps:" |
286 if (element_->HasSourceAttribute()) { | 295 if (element_->HasSourceAttribute()) { |
287 FetchParameters::DeferOption defer = FetchParameters::kNoDefer; | 296 // 21.1. Let src be the value of the element's src attribute. |
288 if (!parser_inserted_ || element_->AsyncAttributeValue() || | 297 String src = |
289 element_->DeferAttributeValue()) | 298 StripLeadingAndTrailingHTMLSpaces(element_->SourceAttributeValue()); |
hiroshige
2017/04/14 00:13:29
Moved from Line 489.
| |
290 defer = FetchParameters::kLazyLoad; | 299 |
291 if (document_write_intervention_ == | 300 // 21.2. "If src is the empty string, queue a task to |
hiroshige
2017/04/14 00:13:29
Moved from Line 579.
| |
292 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) | 301 // fire an event named error at the element, and abort these steps." |
293 defer = FetchParameters::kIdleLoad; | 302 if (src.IsEmpty()) { |
294 if (!FetchScript(element_->SourceAttributeValue(), encoding, defer)) | 303 // TODO(hiroshige): Make this asynchronous. Currently we fire the error |
304 // event synchronously to keep the existing behavior. | |
305 DispatchErrorEvent(); | |
295 return false; | 306 return false; |
307 } | |
308 | |
309 // 21.3. "Set the element's from an external file flag." | |
hiroshige
2017/04/14 00:13:29
21.3 is moved from FetchScript().
Actually in this
| |
310 is_external_script_ = true; | |
311 | |
312 // 21.4. "Parse src relative to the element's node document." | |
313 KURL url = element_document.CompleteURL(src); | |
hiroshige
2017/04/14 00:13:29
This might cause slight behavior change: previousl
| |
314 | |
315 // 21.5. "If the previous step failed, queue a task to | |
hiroshige
2017/04/14 00:13:29
Moved from Line 579.
| |
316 // fire an event named error at the element, and abort these steps." | |
317 if (!url.IsValid()) { | |
318 // TODO(hiroshige): Make this asynchronous. Currently we fire the error | |
319 // event synchronously to keep the existing behavior. | |
320 DispatchErrorEvent(); | |
321 return false; | |
322 } | |
323 | |
324 DCHECK(!resource_); | |
325 | |
326 // 21.6. "Switch on the script's type:" | |
327 // - "classic": | |
328 | |
329 // 14. "If the script element has a charset attribute, | |
hiroshige
2017/04/14 00:13:29
Step 14 is moved from above.
| |
330 // then let encoding be the result of | |
331 // getting an encoding from the value of the charset attribute." | |
332 // "If the script element does not have a charset attribute, | |
333 // or if getting an encoding failed, let encoding | |
334 // be the same as the encoding of the script element's node | |
335 // document." | |
336 // TODO(hiroshige): Should we handle failure in getting an encoding? | |
337 String encoding; | |
338 if (!element_->CharsetAttributeValue().IsEmpty()) | |
339 encoding = element_->CharsetAttributeValue(); | |
340 else | |
341 encoding = element_document.characterSet(); | |
342 | |
343 // Step 16 is skipped because "module script credentials" is not used | |
344 // for classic scripts. | |
345 | |
346 // 18. "If the script element has an integrity attribute, | |
hiroshige
2017/04/14 00:13:29
Step 18 is moved from FetchScript().
| |
347 // then let integrity metadata be that attribute's value. | |
348 // Otherwise, let integrity metadata be the empty string." | |
349 String integrity_attr = element_->IntegrityAttributeValue(); | |
350 IntegrityMetadataSet integrity_metadata; | |
351 if (!integrity_attr.IsEmpty()) { | |
352 SubresourceIntegrity::ParseIntegrityAttribute( | |
353 integrity_attr, integrity_metadata, &element_document); | |
354 } | |
355 | |
356 if (!FetchClassicScript(url, element_document.Fetcher(), nonce, | |
357 integrity_metadata, parser_state, cross_origin, | |
358 element_document.GetSecurityOrigin(), encoding)) | |
359 return false; | |
hiroshige
2017/04/14 00:13:29
Moved from Line 579.
Oh, I should call DispatchErr
| |
360 | |
361 // - "module": | |
362 // TODO(hiroshige): Implement this. | |
363 | |
364 // "When the chosen algorithm asynchronously completes, set | |
365 // the script's script to the result. At that time, the script is ready." | |
366 // When the script is ready, PendingScriptClient::pendingScriptFinished() | |
367 // is used as the notification, and the action to take when | |
368 // the script is ready is specified later, in | |
369 // - ScriptLoader::PrepareScript(), or | |
370 // - HTMLParserScriptRunner, | |
371 // depending on the conditions in Step 23 of "prepare a script". | |
296 } | 372 } |
297 | 373 |
298 // 22. "If the element does not have a src content attribute, | 374 // 22. "If the element does not have a src content attribute, |
299 // run these substeps:" | 375 // run these substeps:" |
300 | 376 |
301 // 22.1. "Let source text be the value of the text IDL attribute." | 377 // 22.1. "Let source text be the value of the text IDL attribute." |
302 // This step is done later: | 378 // This step is done later: |
303 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), | 379 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), |
304 // as Element::textFromChildren() in ScriptLoader::scriptContent(), | 380 // as Element::textFromChildren() in ScriptLoader::scriptContent(), |
305 // - in HTMLParserScriptRunner::processScriptElementInternal() | 381 // - in HTMLParserScriptRunner::processScriptElementInternal() |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 | 545 |
470 if (!ExecuteScript(ClassicScript::Create( | 546 if (!ExecuteScript(ClassicScript::Create( |
471 ScriptSourceCode(ScriptContent(), script_url, position)))) { | 547 ScriptSourceCode(ScriptContent(), script_url, position)))) { |
472 DispatchErrorEvent(); | 548 DispatchErrorEvent(); |
473 return false; | 549 return false; |
474 } | 550 } |
475 | 551 |
476 return true; | 552 return true; |
477 } | 553 } |
478 | 554 |
479 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script | 555 bool ScriptLoader::FetchClassicScript( |
480 bool ScriptLoader::FetchScript(const String& source_url, | 556 const KURL& url, |
481 const String& encoding, | 557 ResourceFetcher* fetcher, |
482 FetchParameters::DeferOption defer) { | 558 const String& nonce, |
483 Document* element_document = &(element_->GetDocument()); | 559 const IntegrityMetadataSet& integrity_metadata, |
484 if (!element_->IsConnected() || element_->GetDocument() != element_document) | 560 ParserDisposition parser_state, |
485 return false; | 561 CrossOriginAttributeValue cross_origin, |
562 SecurityOrigin* security_origin, | |
563 const String& encoding) { | |
564 // https://html.spec.whatwg.org/#prepare-a-script | |
565 // 21.6, "classic": | |
566 // "Fetch a classic script given url, settings, ..." | |
567 ResourceRequest resource_request(url); | |
486 | 568 |
487 DCHECK(!resource_); | 569 // [Intervention] |
488 // 21. "If the element has a src content attribute, run these substeps:" | 570 if (document_write_intervention_ == |
489 if (!StripLeadingAndTrailingHTMLSpaces(source_url).IsEmpty()) { | 571 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) { |
490 // 21.4. "Parse src relative to the element's node document." | 572 resource_request.SetHTTPHeaderField( |
491 ResourceRequest resource_request(element_document->CompleteURL(source_url)); | 573 "Intervention", |
492 | 574 "<https://www.chromestatus.com/feature/5718547946799104>"); |
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 | |
503 // 15. "Let CORS setting be the current state of the element's | |
hiroshige
2017/04/14 00:13:29
Lines 503--544 (Steps 15, 17, 18, 19) are moved to
| |
504 // crossorigin content attribute." | |
505 CrossOriginAttributeValue cross_origin = | |
506 GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue()); | |
507 | |
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, | |
522 // then let cryptographic nonce be that attribute's value. | |
523 // Otherwise, let cryptographic nonce be the empty string." | |
524 if (element_->IsNonceableElement()) | |
525 params.SetContentSecurityPolicyNonce(element_->nonce()); | |
526 | |
527 // 19. "Let parser state be "parser-inserted" | |
528 // if the script element has been flagged as "parser-inserted", | |
529 // and "not parser-inserted" otherwise." | |
530 params.SetParserDisposition(IsParserInserted() ? kParserInserted | |
531 : 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 | |
546 // 21.6. "Switch on the script's type:" | |
547 | |
548 // - "classic": | |
549 // "Fetch a classic script given url, settings, cryptographic nonce, | |
550 // integrity metadata, parser state, CORS setting, and encoding." | |
551 resource_ = ScriptResource::Fetch(params, element_document->Fetcher()); | |
552 | |
553 // - "module": | |
554 // "Fetch a module script graph given url, settings, "script", | |
555 // cryptographic nonce, parser state, and | |
556 // module script credentials mode." | |
557 // TODO(kouhei, hiroshige): Implement this. | |
558 | |
559 // "When the chosen algorithm asynchronously completes, set | |
560 // the script's script to the result. At that time, the script is ready." | |
561 // When the script is ready, PendingScriptClient::pendingScriptFinished() | |
562 // is used as the notification, and the action to take when | |
563 // the script is ready is specified later, in | |
564 // - ScriptLoader::prepareScript(), or | |
565 // - HTMLParserScriptRunner, | |
566 // depending on the conditions in Step 23 of "prepare a script". | |
567 | |
568 // 21.3. "Set the element's from an external file flag." | |
569 is_external_script_ = true; | |
hiroshige
2017/04/14 00:13:29
Step 21.3 is moved to FetchScript().
| |
570 } | 575 } |
571 | 576 |
572 if (!resource_) { | 577 FetchParameters params(resource_request, element_->InitiatorName()); |
573 // 21.2. "If src is the empty string, queue a task to | 578 |
574 // fire an event named error at the element, and abort these steps." | 579 // "... cryptographic nonce, ..." |
575 // 21.5. "If the previous step failed, queue a task to | 580 params.SetContentSecurityPolicyNonce(nonce); |
576 // fire an event named error at the element, and abort these steps." | 581 |
577 // TODO(hiroshige): Make this asynchronous. | 582 // "... integrity metadata, ..." |
578 DispatchErrorEvent(); | 583 params.SetIntegrityMetadata(integrity_metadata); |
hiroshige
2017/04/14 00:13:29
This clause handles three different cases, and are
| |
584 | |
585 // "... parser state, ..." | |
586 params.SetParserDisposition(parser_state); | |
587 | |
588 // "... CORS setting, ..." | |
589 if (cross_origin != kCrossOriginAttributeNotSet) { | |
590 params.SetCrossOriginAccessControl(security_origin, cross_origin); | |
591 } | |
592 | |
593 // "... and encoding." | |
594 params.SetCharset(encoding); | |
595 | |
596 // This DeferOption logic is only for classic scripts, as we always set | |
hiroshige
2017/04/14 00:13:29
This logic is moved from PrepareScript() to clarif
| |
597 // |kLazyLoad| for module scripts in ModuleScriptLoader. | |
598 FetchParameters::DeferOption defer = FetchParameters::kNoDefer; | |
599 if (!parser_inserted_ || element_->AsyncAttributeValue() || | |
600 element_->DeferAttributeValue()) | |
601 defer = FetchParameters::kLazyLoad; | |
602 if (document_write_intervention_ == | |
603 DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) | |
604 defer = FetchParameters::kIdleLoad; | |
605 params.SetDefer(defer); | |
606 | |
607 resource_ = ScriptResource::Fetch(params, fetcher); | |
608 | |
609 if (!resource_) | |
579 return false; | 610 return false; |
580 } | |
581 | 611 |
582 // [Intervention] | 612 // [Intervention] |
583 if (created_during_document_write_ && | 613 if (created_during_document_write_ && |
584 resource_->GetResourceRequest().GetCachePolicy() == | 614 resource_->GetResourceRequest().GetCachePolicy() == |
585 WebCachePolicy::kReturnCacheDataDontLoad) { | 615 WebCachePolicy::kReturnCacheDataDontLoad) { |
586 document_write_intervention_ = | 616 document_write_intervention_ = |
587 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; | 617 DocumentWriteIntervention::kDoNotFetchDocWrittenScript; |
588 } | 618 } |
589 | 619 |
590 return true; | 620 return true; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
781 // then abort these steps at this point. The script is not executed. | 811 // then abort these steps at this point. The script is not executed. |
782 return DeprecatedEqualIgnoringCase(event_attribute, "onload") || | 812 return DeprecatedEqualIgnoringCase(event_attribute, "onload") || |
783 DeprecatedEqualIgnoringCase(event_attribute, "onload()"); | 813 DeprecatedEqualIgnoringCase(event_attribute, "onload()"); |
784 } | 814 } |
785 | 815 |
786 String ScriptLoader::ScriptContent() const { | 816 String ScriptLoader::ScriptContent() const { |
787 return element_->TextFromChildren(); | 817 return element_->TextFromChildren(); |
788 } | 818 } |
789 | 819 |
790 } // namespace blink | 820 } // namespace blink |
OLD | NEW |