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 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 if (!m_parserInserted || client->asyncAttributeValue() || | 316 if (!m_parserInserted || client->asyncAttributeValue() || |
317 client->deferAttributeValue()) | 317 client->deferAttributeValue()) |
318 defer = FetchRequest::LazyLoad; | 318 defer = FetchRequest::LazyLoad; |
319 if (m_documentWriteIntervention == | 319 if (m_documentWriteIntervention == |
320 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) | 320 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) |
321 defer = FetchRequest::IdleLoad; | 321 defer = FetchRequest::IdleLoad; |
322 if (!fetchScript(client->sourceAttributeValue(), encoding, defer)) | 322 if (!fetchScript(client->sourceAttributeValue(), encoding, defer)) |
323 return false; | 323 return false; |
324 } | 324 } |
325 | 325 |
| 326 // 22. "If the element does not have a src content attribute, |
| 327 // run these substeps:" |
| 328 |
| 329 // 22.1. "Let source text be the value of the text IDL attribute." |
| 330 // This step is done later: |
| 331 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), |
| 332 // as Element::textFromChildren() in ScriptLoader::scriptContent(), |
| 333 // - in HTMLParserScriptRunner::processScriptElementInternal() |
| 334 // (Duplicated code of Step 23, 6th Clause), |
| 335 // as Element::textContent(), |
| 336 // - in XMLDocumentParser::endElementNs() (Step 23, 5th Clause), |
| 337 // as Element::textFromChildren() in ScriptLoader::scriptContent(), |
| 338 // - PendingScript::getSource() (Indirectly used via |
| 339 // HTMLParserScriptRunner::processScriptElementInternal(), |
| 340 // Step 23, 5th Clause), |
| 341 // as Element::textContent(). |
| 342 // TODO(hiroshige): Make them merged or consistent. |
| 343 |
| 344 // 22.2. "Switch on the script's type:" |
| 345 // TODO(hiroshige): Clarify how Step 22.2 is implemented for "classic". |
| 346 // TODO(hiroshige): Implement Step 22.2 for "module". |
| 347 |
326 // [Intervention] | 348 // [Intervention] |
327 // Since the asynchronous, low priority fetch for doc.written blocked | 349 // Since the asynchronous, low priority fetch for doc.written blocked |
328 // script is not for execution, return early from here. Watch for its | 350 // script is not for execution, return early from here. Watch for its |
329 // completion to be able to remove it from the memory cache. | 351 // completion to be able to remove it from the memory cache. |
330 if (m_documentWriteIntervention == | 352 if (m_documentWriteIntervention == |
331 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 353 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
332 m_pendingScript = PendingScript::create(m_element, m_resource.get()); | 354 m_pendingScript = PendingScript::create(m_element, m_resource.get()); |
333 m_pendingScript->watchForLoad(this); | 355 m_pendingScript->watchForLoad(this); |
334 return true; | 356 return true; |
335 } | 357 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 483 } |
462 | 484 |
463 // 6th Clause: | 485 // 6th Clause: |
464 // - "Otherwise" | 486 // - "Otherwise" |
465 // "Immediately execute the script block, | 487 // "Immediately execute the script block, |
466 // even if other scripts are already executing." | 488 // even if other scripts are already executing." |
467 // Note: this block is also duplicated in | 489 // Note: this block is also duplicated in |
468 // HTMLParserScriptRunner::processScriptElementInternal(). | 490 // HTMLParserScriptRunner::processScriptElementInternal(). |
469 // TODO(hiroshige): Merge the duplicated code. | 491 // TODO(hiroshige): Merge the duplicated code. |
470 | 492 |
| 493 // This clause is executed only if the script's type is "classic" |
| 494 // and the element doesn't have a src attribute. |
| 495 |
471 // Reset line numbering for nested writes. | 496 // Reset line numbering for nested writes. |
472 TextPosition position = elementDocument.isInDocumentWrite() | 497 TextPosition position = elementDocument.isInDocumentWrite() |
473 ? TextPosition() | 498 ? TextPosition() |
474 : scriptStartPosition; | 499 : scriptStartPosition; |
475 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) | 500 KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) |
476 ? elementDocument.url() | 501 ? elementDocument.url() |
477 : KURL(); | 502 : KURL(); |
| 503 |
478 if (!executeScript(ScriptSourceCode(scriptContent(), scriptURL, position))) { | 504 if (!executeScript(ScriptSourceCode(scriptContent(), scriptURL, position))) { |
479 dispatchErrorEvent(); | 505 dispatchErrorEvent(); |
480 return false; | 506 return false; |
481 } | 507 } |
482 | 508 |
483 return true; | 509 return true; |
484 } | 510 } |
485 | 511 |
486 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script | 512 // Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script |
487 bool ScriptLoader::fetchScript(const String& sourceUrl, | 513 bool ScriptLoader::fetchScript(const String& sourceUrl, |
488 const String& encoding, | 514 const String& encoding, |
489 FetchRequest::DeferOption defer) { | 515 FetchRequest::DeferOption defer) { |
490 DCHECK(m_element); | 516 DCHECK(m_element); |
491 | 517 |
492 Document* elementDocument = &(m_element->document()); | 518 Document* elementDocument = &(m_element->document()); |
493 if (!m_element->isConnected() || m_element->document() != elementDocument) | 519 if (!m_element->isConnected() || m_element->document() != elementDocument) |
494 return false; | 520 return false; |
495 | 521 |
496 DCHECK(!m_resource); | 522 DCHECK(!m_resource); |
| 523 // 21. "If the element has a src content attribute, run these substeps:" |
497 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 524 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
| 525 // 21.4. "Parse src relative to the element's node document." |
498 FetchRequest request( | 526 FetchRequest request( |
499 ResourceRequest(elementDocument->completeURL(sourceUrl)), | 527 ResourceRequest(elementDocument->completeURL(sourceUrl)), |
500 m_element->localName()); | 528 m_element->localName()); |
501 | 529 |
| 530 // 15. "Let CORS setting be the current state of the element's |
| 531 // crossorigin content attribute." |
502 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( | 532 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( |
503 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); | 533 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); |
| 534 |
| 535 // 16. "Let module script credentials mode be determined by switching |
| 536 // on CORS setting:" |
| 537 // TODO(hiroshige): Implement this step for "module". |
| 538 |
| 539 // 21.6, "classic": "Fetch a classic script given ... CORS setting |
| 540 // ... and encoding." |
504 if (crossOrigin != CrossOriginAttributeNotSet) | 541 if (crossOrigin != CrossOriginAttributeNotSet) |
505 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), | 542 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), |
506 crossOrigin); | 543 crossOrigin); |
| 544 |
507 request.setCharset(encoding); | 545 request.setCharset(encoding); |
508 | 546 |
| 547 // 17. "If the script element has a nonce attribute, |
| 548 // then let cryptographic nonce be that attribute's value. |
| 549 // Otherwise, let cryptographic nonce be the empty string." |
509 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) | 550 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) |
510 request.setContentSecurityPolicyNonce(client()->nonce()); | 551 request.setContentSecurityPolicyNonce(client()->nonce()); |
511 | 552 |
| 553 // 19. "Let parser state be "parser-inserted" |
| 554 // if the script element has been flagged as "parser-inserted", |
| 555 // and "not parser-inserted" otherwise." |
512 request.setParserDisposition(isParserInserted() ? ParserInserted | 556 request.setParserDisposition(isParserInserted() ? ParserInserted |
513 : NotParserInserted); | 557 : NotParserInserted); |
514 | 558 |
515 request.setDefer(defer); | 559 request.setDefer(defer); |
516 | 560 |
| 561 // 18. "If the script element has an integrity attribute, |
| 562 // then let integrity metadata be that attribute's value. |
| 563 // Otherwise, let integrity metadata be the empty string." |
517 String integrityAttr = | 564 String integrityAttr = |
518 m_element->fastGetAttribute(HTMLNames::integrityAttr); | 565 m_element->fastGetAttribute(HTMLNames::integrityAttr); |
519 if (!integrityAttr.isEmpty()) { | 566 if (!integrityAttr.isEmpty()) { |
520 IntegrityMetadataSet metadataSet; | 567 IntegrityMetadataSet metadataSet; |
521 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, | 568 SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, |
522 elementDocument); | 569 elementDocument); |
523 request.setIntegrityMetadata(metadataSet); | 570 request.setIntegrityMetadata(metadataSet); |
524 } | 571 } |
525 | 572 |
| 573 // [Intervention] |
526 if (m_documentWriteIntervention == | 574 if (m_documentWriteIntervention == |
527 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 575 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
528 request.mutableResourceRequest().setHTTPHeaderField( | 576 request.mutableResourceRequest().setHTTPHeaderField( |
529 "Intervention", | 577 "Intervention", |
530 "<https://www.chromestatus.com/feature/5718547946799104>"); | 578 "<https://www.chromestatus.com/feature/5718547946799104>"); |
531 } | 579 } |
532 | 580 |
| 581 // 21.6. "Switch on the script's type:" |
| 582 |
| 583 // - "classic": |
| 584 // "Fetch a classic script given url, settings, cryptographic nonce, |
| 585 // integrity metadata, parser state, CORS setting, and encoding." |
533 m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); | 586 m_resource = ScriptResource::fetch(request, elementDocument->fetcher()); |
534 | 587 |
| 588 // - "module": |
| 589 // "Fetch a module script graph given url, settings, "script", |
| 590 // cryptographic nonce, parser state, and |
| 591 // module script credentials mode." |
| 592 // TODO(kouhei, hiroshige): Implement this. |
| 593 |
| 594 // "When the chosen algorithm asynchronously completes, set |
| 595 // the script's script to the result. At that time, the script is ready." |
| 596 // When the script is ready, PendingScriptClient::pendingScriptFinished() |
| 597 // is used as the notification, and the action to take when |
| 598 // the script is ready is specified later, in |
| 599 // - ScriptLoader::prepareScript(), or |
| 600 // - HTMLParserScriptRunner, |
| 601 // depending on the conditions in Step 23 of "prepare a script". |
| 602 |
| 603 // 21.3. "Set the element's from an external file flag." |
535 m_isExternalScript = true; | 604 m_isExternalScript = true; |
536 } | 605 } |
537 | 606 |
538 if (!m_resource) { | 607 if (!m_resource) { |
| 608 // 21.2. "If src is the empty string, queue a task to |
| 609 // fire an event named error at the element, and abort these steps." |
| 610 // 21.5. "If the previous step failed, queue a task to |
| 611 // fire an event named error at the element, and abort these steps." |
| 612 // TODO(hiroshige): Make this asynchronous. |
539 dispatchErrorEvent(); | 613 dispatchErrorEvent(); |
540 return false; | 614 return false; |
541 } | 615 } |
542 | 616 |
| 617 // [Intervention] |
543 if (m_createdDuringDocumentWrite && | 618 if (m_createdDuringDocumentWrite && |
544 m_resource->resourceRequest().getCachePolicy() == | 619 m_resource->resourceRequest().getCachePolicy() == |
545 WebCachePolicy::ReturnCacheDataDontLoad) { | 620 WebCachePolicy::ReturnCacheDataDontLoad) { |
546 m_documentWriteIntervention = | 621 m_documentWriteIntervention = |
547 DocumentWriteIntervention::DoNotFetchDocWrittenScript; | 622 DocumentWriteIntervention::DoNotFetchDocWrittenScript; |
548 } | 623 } |
549 | 624 |
550 return true; | 625 return true; |
551 } | 626 } |
552 | 627 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 if (isHTMLScriptLoader(element)) | 890 if (isHTMLScriptLoader(element)) |
816 return toHTMLScriptElement(element)->loader(); | 891 return toHTMLScriptElement(element)->loader(); |
817 | 892 |
818 if (isSVGScriptLoader(element)) | 893 if (isSVGScriptLoader(element)) |
819 return toSVGScriptElement(element)->loader(); | 894 return toSVGScriptElement(element)->loader(); |
820 | 895 |
821 return 0; | 896 return 0; |
822 } | 897 } |
823 | 898 |
824 } // namespace blink | 899 } // namespace blink |
OLD | NEW |