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/ScriptState.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/Document.h" | 32 #include "core/dom/Document.h" |
32 #include "core/dom/DocumentParserTiming.h" | 33 #include "core/dom/DocumentParserTiming.h" |
33 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" | 34 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" |
| 35 #include "core/dom/Modulator.h" |
| 36 #include "core/dom/ModuleScript.h" |
34 #include "core/dom/ScriptLoaderClient.h" | 37 #include "core/dom/ScriptLoaderClient.h" |
35 #include "core/dom/ScriptRunner.h" | 38 #include "core/dom/ScriptRunner.h" |
36 #include "core/dom/ScriptableDocumentParser.h" | 39 #include "core/dom/ScriptableDocumentParser.h" |
37 #include "core/dom/Text.h" | 40 #include "core/dom/Text.h" |
38 #include "core/events/Event.h" | 41 #include "core/events/Event.h" |
39 #include "core/frame/LocalFrame.h" | 42 #include "core/frame/LocalFrame.h" |
40 #include "core/frame/SubresourceIntegrity.h" | 43 #include "core/frame/SubresourceIntegrity.h" |
41 #include "core/frame/UseCounter.h" | 44 #include "core/frame/UseCounter.h" |
42 #include "core/frame/csp/ContentSecurityPolicy.h" | 45 #include "core/frame/csp/ContentSecurityPolicy.h" |
43 #include "core/html/CrossOriginAttribute.h" | 46 #include "core/html/CrossOriginAttribute.h" |
44 #include "core/html/HTMLScriptElement.h" | 47 #include "core/html/HTMLScriptElement.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" |
47 #include "core/inspector/ConsoleMessage.h" | 50 #include "core/inspector/ConsoleMessage.h" |
| 51 #include "core/loader/modulescript/ModuleScriptFetchRequest.h" |
48 #include "core/svg/SVGScriptElement.h" | 52 #include "core/svg/SVGScriptElement.h" |
49 #include "platform/WebFrameScheduler.h" | 53 #include "platform/WebFrameScheduler.h" |
50 #include "platform/loader/fetch/AccessControlStatus.h" | 54 #include "platform/loader/fetch/AccessControlStatus.h" |
51 #include "platform/loader/fetch/FetchRequest.h" | 55 #include "platform/loader/fetch/FetchRequest.h" |
52 #include "platform/loader/fetch/MemoryCache.h" | 56 #include "platform/loader/fetch/MemoryCache.h" |
53 #include "platform/loader/fetch/ResourceFetcher.h" | 57 #include "platform/loader/fetch/ResourceFetcher.h" |
54 #include "platform/network/mime/MIMETypeRegistry.h" | 58 #include "platform/network/mime/MIMETypeRegistry.h" |
55 #include "platform/weborigin/SecurityOrigin.h" | 59 #include "platform/weborigin/SecurityOrigin.h" |
56 #include "public/platform/WebCachePolicy.h" | 60 #include "public/platform/WebCachePolicy.h" |
57 #include "wtf/StdLibExtras.h" | 61 #include "wtf/StdLibExtras.h" |
58 #include "wtf/text/StringBuilder.h" | 62 #include "wtf/text/StringBuilder.h" |
59 #include "wtf/text/StringHash.h" | 63 #include "wtf/text/StringHash.h" |
60 | 64 |
61 namespace blink { | 65 namespace blink { |
62 | 66 |
| 67 class ScriptElementModuleClient |
| 68 : public GarbageCollectedFinalized<ScriptElementModuleClient>, |
| 69 public ModuleTreeClient { |
| 70 USING_GARBAGE_COLLECTED_MIXIN(ScriptElementModuleClient); |
| 71 |
| 72 public: |
| 73 static ScriptElementModuleClient* create(Element* element) { |
| 74 return new ScriptElementModuleClient(element); |
| 75 } |
| 76 virtual ~ScriptElementModuleClient() = default; |
| 77 |
| 78 DECLARE_TRACE(); |
| 79 |
| 80 private: |
| 81 ScriptElementModuleClient(Element* element) : m_element(element) {} |
| 82 |
| 83 // Implements ModuleTreeClient |
| 84 void notifyModuleTreeLoadFinished(ModuleScript*) override; |
| 85 |
| 86 Member<Element> m_element; |
| 87 }; |
| 88 |
| 89 void ScriptElementModuleClient::notifyModuleTreeLoadFinished( |
| 90 ModuleScript* moduleScript) { |
| 91 printf("notifyFinishedModuleTree!!! moduleScript: %p\n", moduleScript); |
| 92 if (!moduleScript) |
| 93 return; |
| 94 DCHECK_EQ(moduleScript->instantiationState(), |
| 95 ModuleInstantiationState::Instantiated); |
| 96 |
| 97 LocalFrame* frame = m_element->document().frame(); |
| 98 |
| 99 // TODO(kouhei): Actually we should just return w/ the prepared script here. |
| 100 // In this prototype, we will execute the module immediately just for fun. :) |
| 101 Modulator::from(frame)->executeModule(moduleScript->record()); |
| 102 } |
| 103 |
| 104 DEFINE_TRACE(ScriptElementModuleClient) { |
| 105 visitor->trace(m_element); |
| 106 ModuleTreeClient::trace(visitor); |
| 107 } |
| 108 |
63 ScriptLoader::ScriptLoader(Element* element, | 109 ScriptLoader::ScriptLoader(Element* element, |
64 bool parserInserted, | 110 bool parserInserted, |
65 bool alreadyStarted, | 111 bool alreadyStarted, |
66 bool createdDuringDocumentWrite) | 112 bool createdDuringDocumentWrite) |
67 : m_element(element), | 113 : m_element(element), |
68 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), | 114 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), |
69 m_haveFiredLoad(false), | 115 m_haveFiredLoad(false), |
70 m_willBeParserExecuted(false), | 116 m_willBeParserExecuted(false), |
71 m_willExecuteWhenDocumentFinishedParsing(false), | 117 m_willExecuteWhenDocumentFinishedParsing(false), |
72 m_createdDuringDocumentWrite(createdDuringDocumentWrite), | 118 m_createdDuringDocumentWrite(createdDuringDocumentWrite), |
(...skipping 27 matching lines...) Expand all Loading... |
100 !element->document().isInDocumentWrite()) | 146 !element->document().isInDocumentWrite()) |
101 m_startLineNumber = | 147 m_startLineNumber = |
102 element->document().scriptableDocumentParser()->lineNumber(); | 148 element->document().scriptableDocumentParser()->lineNumber(); |
103 } | 149 } |
104 | 150 |
105 ScriptLoader::~ScriptLoader() {} | 151 ScriptLoader::~ScriptLoader() {} |
106 | 152 |
107 DEFINE_TRACE(ScriptLoader) { | 153 DEFINE_TRACE(ScriptLoader) { |
108 visitor->trace(m_element); | 154 visitor->trace(m_element); |
109 visitor->trace(m_resource); | 155 visitor->trace(m_resource); |
| 156 visitor->trace(m_elementModuleClient); |
110 visitor->trace(m_pendingScript); | 157 visitor->trace(m_pendingScript); |
111 PendingScriptClient::trace(visitor); | 158 PendingScriptClient::trace(visitor); |
112 } | 159 } |
113 | 160 |
114 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { | 161 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { |
115 DCHECK(!m_createdDuringDocumentWrite); | 162 DCHECK(!m_createdDuringDocumentWrite); |
116 m_documentWriteIntervention = | 163 m_documentWriteIntervention = |
117 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; | 164 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; |
118 } | 165 } |
119 | 166 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 | 359 |
313 // 21. "If the element has a src content attribute, run these substeps:" | 360 // 21. "If the element has a src content attribute, run these substeps:" |
314 if (client->hasSourceAttribute()) { | 361 if (client->hasSourceAttribute()) { |
315 FetchRequest::DeferOption defer = FetchRequest::NoDefer; | 362 FetchRequest::DeferOption defer = FetchRequest::NoDefer; |
316 if (!m_parserInserted || client->asyncAttributeValue() || | 363 if (!m_parserInserted || client->asyncAttributeValue() || |
317 client->deferAttributeValue()) | 364 client->deferAttributeValue()) |
318 defer = FetchRequest::LazyLoad; | 365 defer = FetchRequest::LazyLoad; |
319 if (m_documentWriteIntervention == | 366 if (m_documentWriteIntervention == |
320 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) | 367 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) |
321 defer = FetchRequest::IdleLoad; | 368 defer = FetchRequest::IdleLoad; |
| 369 |
322 if (!fetchScript(client->sourceAttributeValue(), encoding, defer)) | 370 if (!fetchScript(client->sourceAttributeValue(), encoding, defer)) |
323 return false; | 371 return false; |
324 } | 372 } |
325 | 373 |
326 // 22. "If the element does not have a src content attribute, | 374 // 22. "If the element does not have a src content attribute, |
327 // run these substeps:" | 375 // run these substeps:" |
328 | 376 |
329 // 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." |
330 // This step is done later: | 378 // This step is done later: |
331 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), | 379 // - in ScriptLoader::pendingScript() (Step 23, 6th Clause), |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 FetchRequest::DeferOption defer) { | 563 FetchRequest::DeferOption defer) { |
516 DCHECK(m_element); | 564 DCHECK(m_element); |
517 | 565 |
518 Document* elementDocument = &(m_element->document()); | 566 Document* elementDocument = &(m_element->document()); |
519 if (!m_element->isConnected() || m_element->document() != elementDocument) | 567 if (!m_element->isConnected() || m_element->document() != elementDocument) |
520 return false; | 568 return false; |
521 | 569 |
522 DCHECK(!m_resource); | 570 DCHECK(!m_resource); |
523 // 21. "If the element has a src content attribute, run these substeps:" | 571 // 21. "If the element has a src content attribute, run these substeps:" |
524 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 572 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
525 // 21.4. "Parse src relative to the element's node document." | 573 KURL url = elementDocument->completeURL(sourceUrl); |
526 FetchRequest request( | |
527 ResourceRequest(elementDocument->completeURL(sourceUrl)), | |
528 m_element->localName()); | |
529 | 574 |
530 // 15. "Let CORS setting be the current state of the element's | 575 // 15. "Let CORS setting be the current state of the element's |
531 // crossorigin content attribute." | 576 // crossorigin content attribute." |
532 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( | 577 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( |
533 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); | 578 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); |
534 | 579 |
535 // 16. "Let module script credentials mode be determined by switching | 580 if (RuntimeEnabledFeatures::moduleScriptsEnabled() && |
536 // on CORS setting:" | 581 client()->typeAttributeValue() == "module") { |
537 // TODO(hiroshige): Implement this step for "module". | 582 m_elementModuleClient = ScriptElementModuleClient::create(m_element); |
| 583 |
| 584 String nonce; |
| 585 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) { |
| 586 nonce = m_element->fastGetAttribute(HTMLNames::nonceAttr); |
| 587 } |
| 588 ParserDisposition parserState = |
| 589 isParserInserted() ? ParserInserted : NotParserInserted; |
| 590 |
| 591 // 16. "Let module script credentials mode be determined by switching |
| 592 // on CORS setting:" |
| 593 WebURLRequest::FetchCredentialsMode credentialsMode; |
| 594 switch (crossOrigin) { |
| 595 case CrossOriginAttributeNotSet: |
| 596 credentialsMode = WebURLRequest::FetchCredentialsModeOmit; |
| 597 break; |
| 598 case CrossOriginAttributeAnonymous: |
| 599 credentialsMode = WebURLRequest::FetchCredentialsModeSameOrigin; |
| 600 break; |
| 601 case CrossOriginAttributeUseCredentials: |
| 602 credentialsMode = WebURLRequest::FetchCredentialsModeInclude; |
| 603 break; |
| 604 default: |
| 605 NOTREACHED(); |
| 606 } |
| 607 |
| 608 ModuleScriptFetchRequest moduleRequest(url, nonce, parserState, |
| 609 credentialsMode); |
| 610 Modulator::from(elementDocument->frame()) |
| 611 ->fetchTree(moduleRequest, m_elementModuleClient); |
| 612 return true; |
| 613 } |
| 614 |
| 615 // 21.4. "Parse src relative to the element's node document." |
| 616 FetchRequest request( |
| 617 ResourceRequest(elementDocument->completeURL(sourceUrl)), |
| 618 m_element->localName()); |
538 | 619 |
539 // 21.6, "classic": "Fetch a classic script given ... CORS setting | 620 // 21.6, "classic": "Fetch a classic script given ... CORS setting |
540 // ... and encoding." | 621 // ... and encoding." |
541 if (crossOrigin != CrossOriginAttributeNotSet) | 622 if (crossOrigin != CrossOriginAttributeNotSet) |
542 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), | 623 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), |
543 crossOrigin); | 624 crossOrigin); |
544 | 625 |
545 request.setCharset(encoding); | 626 request.setCharset(encoding); |
546 | 627 |
547 // 17. "If the script element has a nonce attribute, | 628 // 17. "If the script element has a nonce attribute, |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 if (isHTMLScriptLoader(element)) | 971 if (isHTMLScriptLoader(element)) |
891 return toHTMLScriptElement(element)->loader(); | 972 return toHTMLScriptElement(element)->loader(); |
892 | 973 |
893 if (isSVGScriptLoader(element)) | 974 if (isSVGScriptLoader(element)) |
894 return toSVGScriptElement(element)->loader(); | 975 return toSVGScriptElement(element)->loader(); |
895 | 976 |
896 return 0; | 977 return 0; |
897 } | 978 } |
898 | 979 |
899 } // namespace blink | 980 } // namespace blink |
OLD | NEW |