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/ModuleMap.h" | |
34 #include "core/dom/ScriptLoaderClient.h" | 36 #include "core/dom/ScriptLoaderClient.h" |
35 #include "core/dom/ScriptRunner.h" | 37 #include "core/dom/ScriptRunner.h" |
36 #include "core/dom/ScriptableDocumentParser.h" | 38 #include "core/dom/ScriptableDocumentParser.h" |
37 #include "core/dom/Text.h" | 39 #include "core/dom/Text.h" |
38 #include "core/events/Event.h" | 40 #include "core/events/Event.h" |
39 #include "core/fetch/AccessControlStatus.h" | 41 #include "core/fetch/AccessControlStatus.h" |
40 #include "core/fetch/FetchRequest.h" | 42 #include "core/fetch/FetchRequest.h" |
41 #include "core/fetch/MemoryCache.h" | 43 #include "core/fetch/MemoryCache.h" |
42 #include "core/fetch/ResourceFetcher.h" | 44 #include "core/fetch/ResourceFetcher.h" |
43 #include "core/frame/LocalFrame.h" | 45 #include "core/frame/LocalFrame.h" |
44 #include "core/frame/SubresourceIntegrity.h" | 46 #include "core/frame/SubresourceIntegrity.h" |
45 #include "core/frame/UseCounter.h" | 47 #include "core/frame/UseCounter.h" |
46 #include "core/frame/csp/ContentSecurityPolicy.h" | 48 #include "core/frame/csp/ContentSecurityPolicy.h" |
47 #include "core/html/CrossOriginAttribute.h" | 49 #include "core/html/CrossOriginAttribute.h" |
48 #include "core/html/HTMLScriptElement.h" | 50 #include "core/html/HTMLScriptElement.h" |
49 #include "core/html/imports/HTMLImport.h" | 51 #include "core/html/imports/HTMLImport.h" |
50 #include "core/html/parser/HTMLParserIdioms.h" | 52 #include "core/html/parser/HTMLParserIdioms.h" |
51 #include "core/inspector/ConsoleMessage.h" | 53 #include "core/inspector/ConsoleMessage.h" |
52 #include "core/svg/SVGScriptElement.h" | 54 #include "core/svg/SVGScriptElement.h" |
53 #include "platform/WebFrameScheduler.h" | 55 #include "platform/WebFrameScheduler.h" |
54 #include "platform/network/mime/MIMETypeRegistry.h" | 56 #include "platform/network/mime/MIMETypeRegistry.h" |
55 #include "platform/weborigin/SecurityOrigin.h" | 57 #include "platform/weborigin/SecurityOrigin.h" |
56 #include "public/platform/WebCachePolicy.h" | 58 #include "public/platform/WebCachePolicy.h" |
57 #include "wtf/StdLibExtras.h" | 59 #include "wtf/StdLibExtras.h" |
58 #include "wtf/text/StringBuilder.h" | 60 #include "wtf/text/StringBuilder.h" |
59 #include "wtf/text/StringHash.h" | 61 #include "wtf/text/StringHash.h" |
60 | 62 |
61 namespace blink { | 63 namespace blink { |
62 | 64 |
65 class ScriptElementModuleLoaderClient | |
66 : public GarbageCollectedFinalized<ScriptElementModuleLoaderClient>, | |
67 public ModuleLoaderClient { | |
68 USING_GARBAGE_COLLECTED_MIXIN(ScriptElementModuleLoaderClient); | |
69 | |
70 public: | |
71 static ScriptElementModuleLoaderClient* create(Element* element) { | |
72 return new ScriptElementModuleLoaderClient(element); | |
73 } | |
74 virtual ~ScriptElementModuleLoaderClient() {} | |
75 | |
76 DECLARE_VIRTUAL_TRACE(); | |
77 | |
78 private: | |
79 ScriptElementModuleLoaderClient(Element* element) : m_element(element) {} | |
80 | |
81 // Implements ModuleLoaderClient | |
82 void notifyFinished() override; | |
83 | |
84 Member<Element> m_element; | |
85 }; | |
86 | |
87 void ScriptElementModuleLoaderClient::notifyFinished() { | |
88 DCHECK(loader()); | |
89 DCHECK(loader()->hasFinished()); | |
90 | |
91 // The code below is entirely wrong o(`ω´*)o | |
92 // TODO(kouhei? dominicc?): Fix this as a part of implementing "fetch a module | |
93 // script graph" algorithm. | |
94 if (!loader()->hasFinishedSuccessfully()) { | |
95 printf( | |
96 "ScriptElementModuleLoaderClient::notifyFinished: load has failed\n"); | |
97 return; | |
98 } | |
99 printf("ScriptElementModuleLoaderClient::notifyFinished: load successful\n"); | |
100 | |
101 Document* contextDocument = m_element->document().contextDocument(); | |
102 DCHECK(contextDocument); | |
103 | |
104 // Below should belong to ScriptController.cpp | |
105 DCHECK(contextDocument->frame()); | |
dominicc (has gone to gerrit)
2016/12/13 07:45:29
Who guarantees this?
kouhei (in TOK)
2016/12/15 04:56:27
After this is moved to ScriptController, ScriptCon
| |
106 ScriptState* scriptState = | |
107 ScriptState::forMainWorld(contextDocument->frame()); | |
108 DCHECK(scriptState); | |
109 ScriptState::Scope scope(scriptState); | |
110 | |
111 ScriptModule module = loader()->scriptModule(); | |
112 CHECK(module.instantiate(scriptState)); | |
113 module.evaluate(scriptState); | |
114 | |
115 dispose(); | |
116 } | |
117 | |
118 DEFINE_TRACE(ScriptElementModuleLoaderClient) { | |
119 visitor->trace(m_element); | |
120 ModuleLoaderClient::trace(visitor); | |
121 } | |
122 | |
63 ScriptLoader::ScriptLoader(Element* element, | 123 ScriptLoader::ScriptLoader(Element* element, |
64 bool parserInserted, | 124 bool parserInserted, |
65 bool alreadyStarted, | 125 bool alreadyStarted, |
66 bool createdDuringDocumentWrite) | 126 bool createdDuringDocumentWrite) |
67 : m_element(element), | 127 : m_element(element), |
68 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), | 128 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), |
69 m_parserInserted(parserInserted), | 129 m_parserInserted(parserInserted), |
70 m_isExternalScript(false), | 130 m_isExternalScript(false), |
71 m_alreadyStarted(alreadyStarted), | 131 m_alreadyStarted(alreadyStarted), |
72 m_haveFiredLoad(false), | 132 m_haveFiredLoad(false), |
(...skipping 10 matching lines...) Expand all Loading... | |
83 !element->document().isInDocumentWrite()) | 143 !element->document().isInDocumentWrite()) |
84 m_startLineNumber = | 144 m_startLineNumber = |
85 element->document().scriptableDocumentParser()->lineNumber(); | 145 element->document().scriptableDocumentParser()->lineNumber(); |
86 } | 146 } |
87 | 147 |
88 ScriptLoader::~ScriptLoader() {} | 148 ScriptLoader::~ScriptLoader() {} |
89 | 149 |
90 DEFINE_TRACE(ScriptLoader) { | 150 DEFINE_TRACE(ScriptLoader) { |
91 visitor->trace(m_element); | 151 visitor->trace(m_element); |
92 visitor->trace(m_resource); | 152 visitor->trace(m_resource); |
153 visitor->trace(m_elementModuleClient); | |
93 visitor->trace(m_pendingScript); | 154 visitor->trace(m_pendingScript); |
94 ScriptResourceClient::trace(visitor); | 155 ScriptResourceClient::trace(visitor); |
95 } | 156 } |
96 | 157 |
97 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { | 158 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { |
98 DCHECK(!m_createdDuringDocumentWrite); | 159 DCHECK(!m_createdDuringDocumentWrite); |
99 m_documentWriteIntervention = | 160 m_documentWriteIntervention = |
100 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; | 161 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; |
101 } | 162 } |
102 | 163 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 m_characterEncoding = elementDocument.characterSet(); | 314 m_characterEncoding = elementDocument.characterSet(); |
254 | 315 |
255 if (client->hasSourceAttribute()) { | 316 if (client->hasSourceAttribute()) { |
256 FetchRequest::DeferOption defer = FetchRequest::NoDefer; | 317 FetchRequest::DeferOption defer = FetchRequest::NoDefer; |
257 if (!m_parserInserted || client->asyncAttributeValue() || | 318 if (!m_parserInserted || client->asyncAttributeValue() || |
258 client->deferAttributeValue()) | 319 client->deferAttributeValue()) |
259 defer = FetchRequest::LazyLoad; | 320 defer = FetchRequest::LazyLoad; |
260 if (m_documentWriteIntervention == | 321 if (m_documentWriteIntervention == |
261 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) | 322 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) |
262 defer = FetchRequest::IdleLoad; | 323 defer = FetchRequest::IdleLoad; |
324 | |
263 if (!fetchScript(client->sourceAttributeValue(), defer)) | 325 if (!fetchScript(client->sourceAttributeValue(), defer)) |
264 return false; | 326 return false; |
265 } | 327 } |
266 | 328 |
267 // Since the asynchronous, low priority fetch for doc.written blocked | 329 // Since the asynchronous, low priority fetch for doc.written blocked |
268 // script is not for execution, return early from here. Watch for its | 330 // script is not for execution, return early from here. Watch for its |
269 // completion to be able to remove it from the memory cache. | 331 // completion to be able to remove it from the memory cache. |
270 if (m_documentWriteIntervention == | 332 if (m_documentWriteIntervention == |
271 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 333 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
272 m_pendingScript = PendingScript::create(m_element, m_resource.get()); | 334 m_pendingScript = PendingScript::create(m_element, m_resource.get()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 | 390 |
329 bool ScriptLoader::fetchScript(const String& sourceUrl, | 391 bool ScriptLoader::fetchScript(const String& sourceUrl, |
330 FetchRequest::DeferOption defer) { | 392 FetchRequest::DeferOption defer) { |
331 DCHECK(m_element); | 393 DCHECK(m_element); |
332 | 394 |
333 Document* elementDocument = &(m_element->document()); | 395 Document* elementDocument = &(m_element->document()); |
334 if (!m_element->isConnected() || m_element->document() != elementDocument) | 396 if (!m_element->isConnected() || m_element->document() != elementDocument) |
335 return false; | 397 return false; |
336 | 398 |
337 DCHECK(!m_resource); | 399 DCHECK(!m_resource); |
400 | |
338 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 401 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
339 FetchRequest request( | 402 KURL url = elementDocument->completeURL(sourceUrl); |
340 ResourceRequest(elementDocument->completeURL(sourceUrl)), | 403 |
341 m_element->localName()); | 404 if (RuntimeEnabledFeatures::moduleScriptsEnabled() && |
405 client()->typeAttributeValue() == "module") { | |
406 m_elementModuleClient = | |
407 ScriptElementModuleLoaderClient::create(m_element); | |
408 | |
409 // TODO(kouhei,dominicc): Below should trigger "fetch a module script | |
410 // graph", not "fetch a single module script" algorithm. | |
411 elementDocument->ensureModuleMap()->fetchSingle(url, | |
412 m_elementModuleClient); | |
413 return true; | |
414 } | |
415 | |
416 FetchRequest request(ResourceRequest(url), m_element->localName()); | |
342 | 417 |
343 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( | 418 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( |
344 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); | 419 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); |
345 if (crossOrigin != CrossOriginAttributeNotSet) | 420 if (crossOrigin != CrossOriginAttributeNotSet) |
346 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), | 421 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), |
347 crossOrigin); | 422 crossOrigin); |
348 request.setCharset(scriptCharset()); | 423 request.setCharset(scriptCharset()); |
349 | 424 |
350 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) { | 425 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) { |
351 request.setContentSecurityPolicyNonce( | 426 request.setContentSecurityPolicyNonce( |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 if (isHTMLScriptLoader(element)) | 721 if (isHTMLScriptLoader(element)) |
647 return toHTMLScriptElement(element)->loader(); | 722 return toHTMLScriptElement(element)->loader(); |
648 | 723 |
649 if (isSVGScriptLoader(element)) | 724 if (isSVGScriptLoader(element)) |
650 return toSVGScriptElement(element)->loader(); | 725 return toSVGScriptElement(element)->loader(); |
651 | 726 |
652 return 0; | 727 return 0; |
653 } | 728 } |
654 | 729 |
655 } // namespace blink | 730 } // namespace blink |
OLD | NEW |