Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Unified Diff: third_party/WebKit/Source/core/dom/ScriptLoader.cpp

Issue 2821553002: Refactor code around ScriptLoader::FetchScript() according to the spec (Closed)
Patch Set: refine Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/dom/ScriptLoader.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/dom/ScriptLoader.cpp
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index 77cc040f3400f0f5af8bc9f49e42ae0b41fe73e9..316051e3523c299f550f5ec3ded2c80df77478b4 100644
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -42,9 +42,9 @@
#include "core/frame/LocalFrame.h"
#include "core/frame/SubresourceIntegrity.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
-#include "core/html/CrossOriginAttribute.h"
#include "core/html/imports/HTMLImport.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/loader/resource/ScriptResource.h"
#include "platform/WebFrameScheduler.h"
#include "platform/loader/fetch/AccessControlStatus.h"
#include "platform/loader/fetch/FetchParameters.h"
@@ -267,32 +267,108 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
if (!IsScriptForEventSupported())
return false;
- // 14. "If the script element has a charset attribute,
hiroshige 2017/04/14 00:13:29 Step 14 is moved below.
- // then let encoding be the result of
- // getting an encoding from the value of the charset attribute."
- // "If the script element does not have a charset attribute,
- // or if getting an encoding failed, let encoding
- // be the same as the encoding of the script element's node document."
- // TODO(hiroshige): Should we handle failure in getting an encoding?
- String encoding;
- if (!element_->CharsetAttributeValue().IsEmpty())
- encoding = element_->CharsetAttributeValue();
- else
- encoding = element_document.characterSet();
-
- // Steps 15--20 are handled in fetchScript().
+ // 14. is handled below.
+
+ // 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().
+ // crossorigin content attribute."
+ CrossOriginAttributeValue cross_origin =
+ GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue());
+
+ // 16. will be handled below once module script support is implemented.
+
+ // 17. "If the script element has a nonce attribute,
hiroshige 2017/04/14 00:13:29 Step 17 is moved from FetchScript().
+ // then let cryptographic nonce be that attribute's value.
+ // Otherwise, let cryptographic nonce be the empty string."
+ String nonce;
+ if (element_->IsNonceableElement())
+ nonce = element_->nonce();
+
+ // 18. is handled below.
+
+ // 19. "Let parser state be "parser-inserted"
hiroshige 2017/04/14 00:13:29 Step 19 is moved from FetchScript().
+ // if the script element has been flagged as "parser-inserted",
+ // and "not parser-inserted" otherwise."
+ ParserDisposition parser_state =
+ IsParserInserted() ? kParserInserted : kNotParserInserted;
// 21. "If the element has a src content attribute, run these substeps:"
if (element_->HasSourceAttribute()) {
- FetchParameters::DeferOption defer = FetchParameters::kNoDefer;
- if (!parser_inserted_ || element_->AsyncAttributeValue() ||
- element_->DeferAttributeValue())
- defer = FetchParameters::kLazyLoad;
- if (document_write_intervention_ ==
- DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle)
- defer = FetchParameters::kIdleLoad;
- if (!FetchScript(element_->SourceAttributeValue(), encoding, defer))
+ // 21.1. Let src be the value of the element's src attribute.
+ String src =
+ StripLeadingAndTrailingHTMLSpaces(element_->SourceAttributeValue());
hiroshige 2017/04/14 00:13:29 Moved from Line 489.
+
+ // 21.2. "If src is the empty string, queue a task to
hiroshige 2017/04/14 00:13:29 Moved from Line 579.
+ // fire an event named error at the element, and abort these steps."
+ if (src.IsEmpty()) {
+ // TODO(hiroshige): Make this asynchronous. Currently we fire the error
+ // event synchronously to keep the existing behavior.
+ DispatchErrorEvent();
+ return false;
+ }
+
+ // 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
+ is_external_script_ = true;
+
+ // 21.4. "Parse src relative to the element's node document."
+ KURL url = element_document.CompleteURL(src);
hiroshige 2017/04/14 00:13:29 This might cause slight behavior change: previousl
+
+ // 21.5. "If the previous step failed, queue a task to
hiroshige 2017/04/14 00:13:29 Moved from Line 579.
+ // fire an event named error at the element, and abort these steps."
+ if (!url.IsValid()) {
+ // TODO(hiroshige): Make this asynchronous. Currently we fire the error
+ // event synchronously to keep the existing behavior.
+ DispatchErrorEvent();
+ return false;
+ }
+
+ DCHECK(!resource_);
+
+ // 21.6. "Switch on the script's type:"
+ // - "classic":
+
+ // 14. "If the script element has a charset attribute,
hiroshige 2017/04/14 00:13:29 Step 14 is moved from above.
+ // then let encoding be the result of
+ // getting an encoding from the value of the charset attribute."
+ // "If the script element does not have a charset attribute,
+ // or if getting an encoding failed, let encoding
+ // be the same as the encoding of the script element's node
+ // document."
+ // TODO(hiroshige): Should we handle failure in getting an encoding?
+ String encoding;
+ if (!element_->CharsetAttributeValue().IsEmpty())
+ encoding = element_->CharsetAttributeValue();
+ else
+ encoding = element_document.characterSet();
+
+ // Step 16 is skipped because "module script credentials" is not used
+ // for classic scripts.
+
+ // 18. "If the script element has an integrity attribute,
hiroshige 2017/04/14 00:13:29 Step 18 is moved from FetchScript().
+ // then let integrity metadata be that attribute's value.
+ // Otherwise, let integrity metadata be the empty string."
+ String integrity_attr = element_->IntegrityAttributeValue();
+ IntegrityMetadataSet integrity_metadata;
+ if (!integrity_attr.IsEmpty()) {
+ SubresourceIntegrity::ParseIntegrityAttribute(
+ integrity_attr, integrity_metadata, &element_document);
+ }
+
+ if (!FetchClassicScript(url, element_document.Fetcher(), nonce,
+ integrity_metadata, parser_state, cross_origin,
+ element_document.GetSecurityOrigin(), encoding))
return false;
hiroshige 2017/04/14 00:13:29 Moved from Line 579. Oh, I should call DispatchErr
+
+ // - "module":
+ // TODO(hiroshige): Implement this.
+
+ // "When the chosen algorithm asynchronously completes, set
+ // the script's script to the result. At that time, the script is ready."
+ // When the script is ready, PendingScriptClient::pendingScriptFinished()
+ // is used as the notification, and the action to take when
+ // the script is ready is specified later, in
+ // - ScriptLoader::PrepareScript(), or
+ // - HTMLParserScriptRunner,
+ // depending on the conditions in Step 23 of "prepare a script".
}
// 22. "If the element does not have a src content attribute,
@@ -476,108 +552,62 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position,
return true;
}
-// Steps 15--21 of https://html.spec.whatwg.org/#prepare-a-script
-bool ScriptLoader::FetchScript(const String& source_url,
- const String& encoding,
- FetchParameters::DeferOption defer) {
- Document* element_document = &(element_->GetDocument());
- if (!element_->IsConnected() || element_->GetDocument() != element_document)
- return false;
-
- DCHECK(!resource_);
- // 21. "If the element has a src content attribute, run these substeps:"
- if (!StripLeadingAndTrailingHTMLSpaces(source_url).IsEmpty()) {
- // 21.4. "Parse src relative to the element's node document."
- ResourceRequest resource_request(element_document->CompleteURL(source_url));
-
- // [Intervention]
- if (document_write_intervention_ ==
- DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
- resource_request.SetHTTPHeaderField(
- "Intervention",
- "<https://www.chromestatus.com/feature/5718547946799104>");
- }
-
- FetchParameters params(resource_request, element_->InitiatorName());
+bool ScriptLoader::FetchClassicScript(
+ const KURL& url,
+ ResourceFetcher* fetcher,
+ const String& nonce,
+ const IntegrityMetadataSet& integrity_metadata,
+ ParserDisposition parser_state,
+ CrossOriginAttributeValue cross_origin,
+ SecurityOrigin* security_origin,
+ const String& encoding) {
+ // https://html.spec.whatwg.org/#prepare-a-script
+ // 21.6, "classic":
+ // "Fetch a classic script given url, settings, ..."
+ ResourceRequest resource_request(url);
- // 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
- // crossorigin content attribute."
- CrossOriginAttributeValue cross_origin =
- GetCrossOriginAttributeValue(element_->CrossOriginAttributeValue());
-
- // 16. "Let module script credentials mode be determined by switching
- // on CORS setting:"
- // TODO(hiroshige): Implement this step for "module".
-
- // 21.6, "classic": "Fetch a classic script given ... CORS setting
- // ... and encoding."
- if (cross_origin != kCrossOriginAttributeNotSet) {
- params.SetCrossOriginAccessControl(element_document->GetSecurityOrigin(),
- cross_origin);
- }
-
- params.SetCharset(encoding);
-
- // 17. "If the script element has a nonce attribute,
- // then let cryptographic nonce be that attribute's value.
- // Otherwise, let cryptographic nonce be the empty string."
- if (element_->IsNonceableElement())
- params.SetContentSecurityPolicyNonce(element_->nonce());
+ // [Intervention]
+ if (document_write_intervention_ ==
+ DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle) {
+ resource_request.SetHTTPHeaderField(
+ "Intervention",
+ "<https://www.chromestatus.com/feature/5718547946799104>");
+ }
- // 19. "Let parser state be "parser-inserted"
- // if the script element has been flagged as "parser-inserted",
- // and "not parser-inserted" otherwise."
- params.SetParserDisposition(IsParserInserted() ? kParserInserted
- : kNotParserInserted);
+ FetchParameters params(resource_request, element_->InitiatorName());
- params.SetDefer(defer);
+ // "... cryptographic nonce, ..."
+ params.SetContentSecurityPolicyNonce(nonce);
- // 18. "If the script element has an integrity attribute,
- // then let integrity metadata be that attribute's value.
- // Otherwise, let integrity metadata be the empty string."
- String integrity_attr = element_->IntegrityAttributeValue();
- if (!integrity_attr.IsEmpty()) {
- IntegrityMetadataSet metadata_set;
- SubresourceIntegrity::ParseIntegrityAttribute(
- integrity_attr, metadata_set, element_document);
- params.SetIntegrityMetadata(metadata_set);
- }
+ // "... integrity metadata, ..."
+ params.SetIntegrityMetadata(integrity_metadata);
- // 21.6. "Switch on the script's type:"
+ // "... parser state, ..."
+ params.SetParserDisposition(parser_state);
- // - "classic":
- // "Fetch a classic script given url, settings, cryptographic nonce,
- // integrity metadata, parser state, CORS setting, and encoding."
- resource_ = ScriptResource::Fetch(params, element_document->Fetcher());
+ // "... CORS setting, ..."
+ if (cross_origin != kCrossOriginAttributeNotSet) {
+ params.SetCrossOriginAccessControl(security_origin, cross_origin);
+ }
- // - "module":
- // "Fetch a module script graph given url, settings, "script",
- // cryptographic nonce, parser state, and
- // module script credentials mode."
- // TODO(kouhei, hiroshige): Implement this.
+ // "... and encoding."
+ params.SetCharset(encoding);
- // "When the chosen algorithm asynchronously completes, set
- // the script's script to the result. At that time, the script is ready."
- // When the script is ready, PendingScriptClient::pendingScriptFinished()
- // is used as the notification, and the action to take when
- // the script is ready is specified later, in
- // - ScriptLoader::prepareScript(), or
- // - HTMLParserScriptRunner,
- // depending on the conditions in Step 23 of "prepare a script".
+ // 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
+ // |kLazyLoad| for module scripts in ModuleScriptLoader.
+ FetchParameters::DeferOption defer = FetchParameters::kNoDefer;
+ if (!parser_inserted_ || element_->AsyncAttributeValue() ||
+ element_->DeferAttributeValue())
+ defer = FetchParameters::kLazyLoad;
+ if (document_write_intervention_ ==
+ DocumentWriteIntervention::kFetchDocWrittenScriptDeferIdle)
+ defer = FetchParameters::kIdleLoad;
+ params.SetDefer(defer);
- // 21.3. "Set the element's from an external file flag."
- is_external_script_ = true;
hiroshige 2017/04/14 00:13:29 Step 21.3 is moved to FetchScript().
- }
+ resource_ = ScriptResource::Fetch(params, fetcher);
- if (!resource_) {
- // 21.2. "If src is the empty string, queue a task to
- // fire an event named error at the element, and abort these steps."
- // 21.5. "If the previous step failed, queue a task to
- // fire an event named error at the element, and abort these steps."
- // TODO(hiroshige): Make this asynchronous.
- DispatchErrorEvent();
hiroshige 2017/04/14 00:13:29 This clause handles three different cases, and are
+ if (!resource_)
return false;
- }
// [Intervention]
if (created_during_document_write_ &&
« no previous file with comments | « third_party/WebKit/Source/core/dom/ScriptLoader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698