Chromium Code Reviews| 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/fetch/AccessControlStatus.h" | 42 #include "core/fetch/AccessControlStatus.h" |
| 40 #include "core/fetch/FetchRequest.h" | 43 #include "core/fetch/FetchRequest.h" |
| 41 #include "core/fetch/MemoryCache.h" | 44 #include "core/fetch/MemoryCache.h" |
| 42 #include "core/fetch/ResourceFetcher.h" | 45 #include "core/fetch/ResourceFetcher.h" |
| 43 #include "core/frame/LocalFrame.h" | 46 #include "core/frame/LocalFrame.h" |
| 44 #include "core/frame/SubresourceIntegrity.h" | 47 #include "core/frame/SubresourceIntegrity.h" |
| 45 #include "core/frame/UseCounter.h" | 48 #include "core/frame/UseCounter.h" |
| 46 #include "core/frame/csp/ContentSecurityPolicy.h" | 49 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 47 #include "core/html/CrossOriginAttribute.h" | 50 #include "core/html/CrossOriginAttribute.h" |
| 48 #include "core/html/HTMLScriptElement.h" | 51 #include "core/html/HTMLScriptElement.h" |
| 49 #include "core/html/imports/HTMLImport.h" | 52 #include "core/html/imports/HTMLImport.h" |
| 50 #include "core/html/parser/HTMLParserIdioms.h" | 53 #include "core/html/parser/HTMLParserIdioms.h" |
| 51 #include "core/inspector/ConsoleMessage.h" | 54 #include "core/inspector/ConsoleMessage.h" |
| 52 #include "core/svg/SVGScriptElement.h" | 55 #include "core/svg/SVGScriptElement.h" |
| 53 #include "platform/WebFrameScheduler.h" | 56 #include "platform/WebFrameScheduler.h" |
| 54 #include "platform/network/mime/MIMETypeRegistry.h" | 57 #include "platform/network/mime/MIMETypeRegistry.h" |
| 55 #include "platform/weborigin/SecurityOrigin.h" | 58 #include "platform/weborigin/SecurityOrigin.h" |
| 56 #include "public/platform/WebCachePolicy.h" | 59 #include "public/platform/WebCachePolicy.h" |
| 57 #include "wtf/StdLibExtras.h" | 60 #include "wtf/StdLibExtras.h" |
| 58 #include "wtf/text/StringBuilder.h" | 61 #include "wtf/text/StringBuilder.h" |
| 59 #include "wtf/text/StringHash.h" | 62 #include "wtf/text/StringHash.h" |
| 60 | 63 |
| 61 namespace blink { | 64 namespace blink { |
| 62 | 65 |
| 66 class ScriptElementModuleClient | |
| 67 : public GarbageCollectedFinalized<ScriptElementModuleClient>, | |
| 68 public ModuleTreeClient { | |
| 69 USING_GARBAGE_COLLECTED_MIXIN(ScriptElementModuleClient); | |
| 70 | |
| 71 public: | |
| 72 static ScriptElementModuleClient* create(Element* element) { | |
| 73 return new ScriptElementModuleClient(element); | |
| 74 } | |
| 75 virtual ~ScriptElementModuleClient() = default; | |
| 76 | |
| 77 DECLARE_TRACE(); | |
| 78 | |
| 79 private: | |
| 80 ScriptElementModuleClient(Element* element) : m_element(element) {} | |
| 81 | |
| 82 // Implements ModuleTreeClient | |
| 83 void notifyFinishedModuleTree(ModuleScript*) override; | |
| 84 | |
| 85 Member<Element> m_element; | |
| 86 }; | |
| 87 | |
| 88 void ScriptElementModuleClient::notifyFinishedModuleTree( | |
| 89 ModuleScript* moduleScript) { | |
| 90 printf("notifyFinishedModuleTree!!! moduleScript: %p\n", moduleScript); | |
| 91 if (!moduleScript) | |
| 92 return; | |
| 93 DCHECK(moduleScript->instantiationState() == | |
| 94 InstantiationState::Instantiated); | |
| 95 | |
| 96 LocalFrame* frame = m_element->document().frame(); | |
| 97 | |
| 98 // TODO(kouhei): Actually we should just return w/ the prepared script here. | |
| 99 // In this prototype, we will execute the module immediately just for fun. :) | |
| 100 Modulator::from(frame)->executeModule(moduleScript->record()); | |
| 101 } | |
| 102 | |
| 103 DEFINE_TRACE(ScriptElementModuleClient) { | |
| 104 visitor->trace(m_element); | |
| 105 ModuleTreeClient::trace(visitor); | |
| 106 } | |
| 107 | |
| 63 ScriptLoader::ScriptLoader(Element* element, | 108 ScriptLoader::ScriptLoader(Element* element, |
| 64 bool parserInserted, | 109 bool parserInserted, |
| 65 bool alreadyStarted, | 110 bool alreadyStarted, |
| 66 bool createdDuringDocumentWrite) | 111 bool createdDuringDocumentWrite) |
| 67 : m_element(element), | 112 : m_element(element), |
| 68 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), | 113 m_startLineNumber(WTF::OrdinalNumber::beforeFirst()), |
| 69 m_parserInserted(parserInserted), | 114 m_parserInserted(parserInserted), |
| 70 m_isExternalScript(false), | 115 m_isExternalScript(false), |
| 71 m_alreadyStarted(alreadyStarted), | 116 m_alreadyStarted(alreadyStarted), |
| 72 m_haveFiredLoad(false), | 117 m_haveFiredLoad(false), |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 83 !element->document().isInDocumentWrite()) | 128 !element->document().isInDocumentWrite()) |
| 84 m_startLineNumber = | 129 m_startLineNumber = |
| 85 element->document().scriptableDocumentParser()->lineNumber(); | 130 element->document().scriptableDocumentParser()->lineNumber(); |
| 86 } | 131 } |
| 87 | 132 |
| 88 ScriptLoader::~ScriptLoader() {} | 133 ScriptLoader::~ScriptLoader() {} |
| 89 | 134 |
| 90 DEFINE_TRACE(ScriptLoader) { | 135 DEFINE_TRACE(ScriptLoader) { |
| 91 visitor->trace(m_element); | 136 visitor->trace(m_element); |
| 92 visitor->trace(m_resource); | 137 visitor->trace(m_resource); |
| 138 visitor->trace(m_elementModuleClient); | |
| 93 visitor->trace(m_pendingScript); | 139 visitor->trace(m_pendingScript); |
| 94 PendingScriptClient::trace(visitor); | 140 PendingScriptClient::trace(visitor); |
| 95 } | 141 } |
| 96 | 142 |
| 97 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { | 143 void ScriptLoader::setFetchDocWrittenScriptDeferIdle() { |
| 98 DCHECK(!m_createdDuringDocumentWrite); | 144 DCHECK(!m_createdDuringDocumentWrite); |
| 99 m_documentWriteIntervention = | 145 m_documentWriteIntervention = |
| 100 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; | 146 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle; |
| 101 } | 147 } |
| 102 | 148 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 m_characterEncoding = elementDocument.characterSet(); | 299 m_characterEncoding = elementDocument.characterSet(); |
| 254 | 300 |
| 255 if (client->hasSourceAttribute()) { | 301 if (client->hasSourceAttribute()) { |
| 256 FetchRequest::DeferOption defer = FetchRequest::NoDefer; | 302 FetchRequest::DeferOption defer = FetchRequest::NoDefer; |
| 257 if (!m_parserInserted || client->asyncAttributeValue() || | 303 if (!m_parserInserted || client->asyncAttributeValue() || |
| 258 client->deferAttributeValue()) | 304 client->deferAttributeValue()) |
| 259 defer = FetchRequest::LazyLoad; | 305 defer = FetchRequest::LazyLoad; |
| 260 if (m_documentWriteIntervention == | 306 if (m_documentWriteIntervention == |
| 261 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) | 307 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) |
| 262 defer = FetchRequest::IdleLoad; | 308 defer = FetchRequest::IdleLoad; |
| 309 | |
| 263 if (!fetchScript(client->sourceAttributeValue(), defer)) | 310 if (!fetchScript(client->sourceAttributeValue(), defer)) |
| 264 return false; | 311 return false; |
| 265 } | 312 } |
| 266 | 313 |
| 267 // Since the asynchronous, low priority fetch for doc.written blocked | 314 // Since the asynchronous, low priority fetch for doc.written blocked |
| 268 // script is not for execution, return early from here. Watch for its | 315 // script is not for execution, return early from here. Watch for its |
| 269 // completion to be able to remove it from the memory cache. | 316 // completion to be able to remove it from the memory cache. |
| 270 if (m_documentWriteIntervention == | 317 if (m_documentWriteIntervention == |
| 271 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { | 318 DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
| 272 m_pendingScript = PendingScript::create(m_element, m_resource.get()); | 319 m_pendingScript = PendingScript::create(m_element, m_resource.get()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 | 375 |
| 329 bool ScriptLoader::fetchScript(const String& sourceUrl, | 376 bool ScriptLoader::fetchScript(const String& sourceUrl, |
| 330 FetchRequest::DeferOption defer) { | 377 FetchRequest::DeferOption defer) { |
| 331 DCHECK(m_element); | 378 DCHECK(m_element); |
| 332 | 379 |
| 333 Document* elementDocument = &(m_element->document()); | 380 Document* elementDocument = &(m_element->document()); |
| 334 if (!m_element->isConnected() || m_element->document() != elementDocument) | 381 if (!m_element->isConnected() || m_element->document() != elementDocument) |
| 335 return false; | 382 return false; |
| 336 | 383 |
| 337 DCHECK(!m_resource); | 384 DCHECK(!m_resource); |
| 385 | |
| 338 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { | 386 if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) { |
| 339 FetchRequest request( | 387 KURL url = elementDocument->completeURL(sourceUrl); |
| 340 ResourceRequest(elementDocument->completeURL(sourceUrl)), | 388 if (RuntimeEnabledFeatures::moduleScriptsEnabled() && |
| 341 m_element->localName()); | 389 client()->typeAttributeValue() == "module") { |
| 390 m_elementModuleClient = ScriptElementModuleClient::create(m_element); | |
| 391 | |
| 392 // TODO(kouhei): Per spec, we should actually pass in "settings object" | |
| 393 // which contains the baseURL. | |
| 394 KURL baseURL = elementDocument->baseURL(); | |
| 395 | |
| 396 Document* elementDocument = &(m_element->document()); | |
| 397 Modulator::from(elementDocument->frame()) | |
|
dominicc (has gone to gerrit)
2017/01/11 03:23:48
Feel like all these places need guards against shu
kouhei (in TOK)
2017/01/17 05:26:13
Is Line 381 isConnected check enough? Would you he
| |
| 398 ->fetchTree(url, baseURL, m_elementModuleClient); | |
| 399 return true; | |
| 400 } | |
| 401 | |
| 402 FetchRequest request(ResourceRequest(url), m_element->localName()); | |
| 342 | 403 |
| 343 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( | 404 CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( |
| 344 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); | 405 m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); |
| 345 if (crossOrigin != CrossOriginAttributeNotSet) | 406 if (crossOrigin != CrossOriginAttributeNotSet) |
| 346 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), | 407 request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), |
| 347 crossOrigin); | 408 crossOrigin); |
| 348 request.setCharset(scriptCharset()); | 409 request.setCharset(scriptCharset()); |
| 349 | 410 |
| 350 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) { | 411 if (ContentSecurityPolicy::isNonceableElement(m_element.get())) { |
| 351 request.setContentSecurityPolicyNonce( | 412 request.setContentSecurityPolicyNonce( |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 647 if (isHTMLScriptLoader(element)) | 708 if (isHTMLScriptLoader(element)) |
| 648 return toHTMLScriptElement(element)->loader(); | 709 return toHTMLScriptElement(element)->loader(); |
| 649 | 710 |
| 650 if (isSVGScriptLoader(element)) | 711 if (isSVGScriptLoader(element)) |
| 651 return toSVGScriptElement(element)->loader(); | 712 return toSVGScriptElement(element)->loader(); |
| 652 | 713 |
| 653 return 0; | 714 return 0; |
| 654 } | 715 } |
| 655 | 716 |
| 656 } // namespace blink | 717 } // namespace blink |
| OLD | NEW |