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 54c374997963907b76b8fd1d7bd5b91d737fa1ba..a1b4db229982bafd0d9c0a4917fa2cd05fc70146 100644 |
--- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp |
+++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp |
@@ -31,7 +31,7 @@ |
#include "core/dom/Document.h" |
#include "core/dom/DocumentParserTiming.h" |
#include "core/dom/IgnoreDestructiveWriteCountIncrementer.h" |
-#include "core/dom/ScriptLoaderClient.h" |
+#include "core/dom/ScriptElementBase.h" |
#include "core/dom/ScriptRunner.h" |
#include "core/dom/ScriptableDocumentParser.h" |
#include "core/dom/Text.h" |
@@ -41,11 +41,9 @@ |
#include "core/frame/UseCounter.h" |
#include "core/frame/csp/ContentSecurityPolicy.h" |
#include "core/html/CrossOriginAttribute.h" |
-#include "core/html/HTMLScriptElement.h" |
#include "core/html/imports/HTMLImport.h" |
#include "core/html/parser/HTMLParserIdioms.h" |
#include "core/inspector/ConsoleMessage.h" |
-#include "core/svg/SVGScriptElement.h" |
#include "platform/WebFrameScheduler.h" |
#include "platform/loader/fetch/AccessControlStatus.h" |
#include "platform/loader/fetch/FetchRequest.h" |
@@ -60,7 +58,7 @@ |
namespace blink { |
-ScriptLoader::ScriptLoader(Element* element, |
+ScriptLoader::ScriptLoader(ScriptElementBase* element, |
bool parserInserted, |
bool alreadyStarted, |
bool createdDuringDocumentWrite) |
@@ -73,8 +71,6 @@ ScriptLoader::ScriptLoader(Element* element, |
m_asyncExecType(ScriptRunner::None), |
m_documentWriteIntervention( |
DocumentWriteIntervention::DocumentWriteInterventionNone) { |
- DCHECK(m_element); |
- |
// https://html.spec.whatwg.org/#already-started |
// "The cloning steps for script elements must set the "already started" |
// flag on the copy if it is set on the element being cloned." |
@@ -96,10 +92,11 @@ ScriptLoader::ScriptLoader(Element* element, |
m_nonBlocking = false; |
} |
- if (parserInserted && element->document().scriptableDocumentParser() && |
- !element->document().isInDocumentWrite()) |
+ if (parserInserted && m_element->document().scriptableDocumentParser() && |
+ !m_element->document().isInDocumentWrite()) { |
m_startLineNumber = |
- element->document().scriptableDocumentParser()->lineNumber(); |
+ m_element->document().scriptableDocumentParser()->lineNumber(); |
+ } |
} |
ScriptLoader::~ScriptLoader() {} |
@@ -175,12 +172,11 @@ static bool isLegacySupportedJavaScriptLanguage(const String& language) { |
} |
void ScriptLoader::dispatchErrorEvent() { |
- m_element->dispatchEvent(Event::create(EventTypeNames::error)); |
+ m_element->dispatchErrorEvent(); |
} |
void ScriptLoader::dispatchLoadEvent() { |
- if (ScriptLoaderClient* client = this->client()) |
- client->dispatchLoadEvent(); |
+ m_element->dispatchLoadEvent(); |
setHaveFiredLoadEvent(true); |
} |
@@ -215,8 +211,8 @@ bool ScriptLoader::isValidScriptTypeAndLanguage( |
bool ScriptLoader::isScriptTypeSupported( |
LegacyTypeSupport supportLegacyTypes) const { |
- return isValidScriptTypeAndLanguage(client()->typeAttributeValue(), |
- client()->languageAttributeValue(), |
+ return isValidScriptTypeAndLanguage(m_element->typeAttributeValue(), |
+ m_element->languageAttributeValue(), |
supportLegacyTypes); |
} |
@@ -228,8 +224,6 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
if (m_alreadyStarted) |
return false; |
- ScriptLoaderClient* client = this->client(); |
- |
// 2. "If the element has its "parser-inserted" flag set, then |
// set was-parser-inserted to true and unset the element's |
// "parser-inserted" flag. |
@@ -244,7 +238,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// 3. "If was-parser-inserted is true and the element does not have an |
// async attribute, then set the element's "non-blocking" flag to true." |
- if (wasParserInserted && !client->asyncAttributeValue()) |
+ if (wasParserInserted && !m_element->asyncAttributeValue()) |
m_nonBlocking = true; |
// 4. "If the element has no src attribute, and its child nodes, if any, |
@@ -252,7 +246,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// then abort these steps at this point. The script is not executed." |
// FIXME: HTML5 spec says we should check that all children are either |
// comments or empty text nodes. |
- if (!client->hasSourceAttribute() && !m_element->hasChildren()) |
+ if (!m_element->hasSourceAttribute() && !m_element->hasChildren()) |
return false; |
// 5. "If the element is not connected, then abort these steps. |
@@ -283,12 +277,14 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// document. |
Document& elementDocument = m_element->document(); |
Document* contextDocument = elementDocument.contextDocument(); |
- if (!contextDocument) |
+ if (!elementDocument.executingFrame()) |
+ return false; |
+ if (!contextDocument || !contextDocument->executingFrame()) |
return false; |
// 10. "If scripting is disabled for the script element, then abort these |
// steps at this point. The script is not executed." |
- if (!contextDocument->allowExecutingScripts(m_element)) |
+ if (!contextDocument->canExecuteScripts(AboutToExecuteScript)) |
return false; |
// 13. |
@@ -303,23 +299,23 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// 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 (!client->charsetAttributeValue().isEmpty()) |
- encoding = client->charsetAttributeValue(); |
+ if (!m_element->charsetAttributeValue().isEmpty()) |
+ encoding = m_element->charsetAttributeValue(); |
else |
encoding = elementDocument.characterSet(); |
// Steps 15--20 are handled in fetchScript(). |
// 21. "If the element has a src content attribute, run these substeps:" |
- if (client->hasSourceAttribute()) { |
+ if (m_element->hasSourceAttribute()) { |
FetchRequest::DeferOption defer = FetchRequest::NoDefer; |
- if (!m_parserInserted || client->asyncAttributeValue() || |
- client->deferAttributeValue()) |
+ if (!m_parserInserted || m_element->asyncAttributeValue() || |
+ m_element->deferAttributeValue()) |
defer = FetchRequest::LazyLoad; |
if (m_documentWriteIntervention == |
DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) |
defer = FetchRequest::IdleLoad; |
- if (!fetchScript(client->sourceAttributeValue(), encoding, defer)) |
+ if (!fetchScript(m_element->sourceAttributeValue(), encoding, defer)) |
return false; |
} |
@@ -351,7 +347,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// completion to be able to remove it from the memory cache. |
if (m_documentWriteIntervention == |
DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) { |
- m_pendingScript = PendingScript::create(m_element, m_resource.get()); |
+ m_pendingScript = PendingScript::create(m_element.get(), m_resource.get()); |
m_pendingScript->watchForLoad(this); |
return true; |
} |
@@ -372,8 +368,8 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// and the element has been flagged as "parser-inserted", |
// and the element does not have an async attribute" |
// TODO(hiroshige): Check the script's type and implement "module" case. |
- if (client->hasSourceAttribute() && client->deferAttributeValue() && |
- m_parserInserted && !client->asyncAttributeValue()) { |
+ if (m_element->hasSourceAttribute() && m_element->deferAttributeValue() && |
+ m_parserInserted && !m_element->asyncAttributeValue()) { |
// This clause is implemented by the caller-side of prepareScript(): |
// - HTMLParserScriptRunner::requestDeferredScript(), and |
// - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() |
@@ -389,8 +385,8 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// and the element has been flagged as "parser-inserted", |
// and the element does not have an async attribute" |
// TODO(hiroshige): Check the script's type. |
- if (client->hasSourceAttribute() && m_parserInserted && |
- !client->asyncAttributeValue()) { |
+ if (m_element->hasSourceAttribute() && m_parserInserted && |
+ !m_element->asyncAttributeValue()) { |
// This clause is implemented by the caller-side of prepareScript(): |
// - HTMLParserScriptRunner::requestParsingBlockingScript() |
// - TODO(hiroshige): Investigate XMLDocumentParser::endElementNs() |
@@ -413,7 +409,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// Part of the condition check is done in |
// HTMLParserScriptRunner::processScriptElementInternal(). |
// TODO(hiroshige): Clean up the split condition check. |
- if (!client->hasSourceAttribute() && m_parserInserted && |
+ if (!m_element->hasSourceAttribute() && m_parserInserted && |
!elementDocument.isScriptExecutionReady()) { |
// The former part of this clause is |
// implemented by the caller-side of prepareScript(): |
@@ -432,12 +428,12 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// and the element does not have an async attribute, |
// and the element does not have the "non-blocking" flag set" |
// TODO(hiroshige): Check the script's type and implement "module" case. |
- if (client->hasSourceAttribute() && !client->asyncAttributeValue() && |
+ if (m_element->hasSourceAttribute() && !m_element->asyncAttributeValue() && |
!m_nonBlocking) { |
// "Add the element to the end of the list of scripts that will execute |
// in order as soon as possible associated with the node document of the |
// script element at the time the prepare a script algorithm started." |
- m_pendingScript = PendingScript::create(m_element, m_resource.get()); |
+ m_pendingScript = PendingScript::create(m_element.get(), m_resource.get()); |
m_asyncExecType = ScriptRunner::InOrder; |
// TODO(hiroshige): Here |contextDocument| is used as "node document" |
// while Step 14 uses |elementDocument| as "node document". Fix this. |
@@ -455,11 +451,11 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
// 4th Clause: |
// - "If the script's type is "classic", and the element has a src attribute" |
// TODO(hiroshige): Check the script's type and implement "module" case. |
- if (client->hasSourceAttribute()) { |
+ if (m_element->hasSourceAttribute()) { |
// "The element must be added to the set of scripts that will execute |
// as soon as possible of the node document of the script element at the |
// time the prepare a script algorithm started." |
- m_pendingScript = PendingScript::create(m_element, m_resource.get()); |
+ m_pendingScript = PendingScript::create(m_element.get(), m_resource.get()); |
m_asyncExecType = ScriptRunner::Async; |
LocalFrame* frame = m_element->document().frame(); |
if (frame) { |
@@ -513,8 +509,6 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, |
bool ScriptLoader::fetchScript(const String& sourceUrl, |
const String& encoding, |
FetchRequest::DeferOption defer) { |
- DCHECK(m_element); |
- |
Document* elementDocument = &(m_element->document()); |
if (!m_element->isConnected() || m_element->document() != elementDocument) |
return false; |
@@ -533,12 +527,12 @@ bool ScriptLoader::fetchScript(const String& sourceUrl, |
"<https://www.chromestatus.com/feature/5718547946799104>"); |
} |
- FetchRequest request(resourceRequest, m_element->localName()); |
+ FetchRequest request(resourceRequest, m_element->initiatorName()); |
// 15. "Let CORS setting be the current state of the element's |
// crossorigin content attribute." |
- CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue( |
- m_element->fastGetAttribute(HTMLNames::crossoriginAttr)); |
+ CrossOriginAttributeValue crossOrigin = |
+ crossOriginAttributeValue(m_element->crossOriginAttributeValue()); |
// 16. "Let module script credentials mode be determined by switching |
// on CORS setting:" |
@@ -555,8 +549,8 @@ bool ScriptLoader::fetchScript(const String& sourceUrl, |
// 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 (ContentSecurityPolicy::isNonceableElement(m_element.get())) |
- request.setContentSecurityPolicyNonce(client()->nonce()); |
+ if (m_element->isNonceableElement()) |
+ request.setContentSecurityPolicyNonce(m_element->nonce()); |
// 19. "Let parser state be "parser-inserted" |
// if the script element has been flagged as "parser-inserted", |
@@ -569,8 +563,7 @@ bool ScriptLoader::fetchScript(const String& sourceUrl, |
// 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 integrityAttr = |
- m_element->fastGetAttribute(HTMLNames::integrityAttr); |
+ String integrityAttr = m_element->integrityAttributeValue(); |
if (!integrityAttr.isEmpty()) { |
IntegrityMetadataSet metadataSet; |
SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, |
@@ -625,16 +618,6 @@ bool ScriptLoader::fetchScript(const String& sourceUrl, |
return true; |
} |
-bool isHTMLScriptLoader(Element* element) { |
- DCHECK(element); |
- return isHTMLScriptElement(*element); |
-} |
- |
-bool isSVGScriptLoader(Element* element) { |
- DCHECK(element); |
- return isSVGScriptElement(*element); |
-} |
- |
void ScriptLoader::logScriptMIMEType(LocalFrame* frame, |
ScriptResource* resource, |
const String& mimeType) { |
@@ -704,13 +687,10 @@ bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode) { |
ContentSecurityPolicy::InlineType::Block); |
AtomicString nonce = |
- ContentSecurityPolicy::isNonceableElement(m_element.get()) |
- ? client()->nonce() |
- : nullAtom; |
- if (!m_isExternalScript && |
- (!shouldBypassMainWorldCSP && |
- !csp->allowInlineScript(m_element, elementDocument->url(), nonce, |
- m_startLineNumber, sourceCode.source()))) { |
+ m_element->isNonceableElement() ? m_element->nonce() : nullAtom; |
+ if (!m_isExternalScript && !shouldBypassMainWorldCSP && |
+ !m_element->allowInlineScriptForCSP(nonce, m_startLineNumber, |
+ sourceCode.source())) { |
return false; |
} |
@@ -786,8 +766,7 @@ bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode) { |
// 1. "If the script element's root is not a shadow root, |
// then set the script element's node document's currentScript |
// attribute to the script element. Otherwise, set it to null." |
- if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) |
- contextDocument->pushCurrentScript(m_element); |
+ contextDocument->pushCurrentScript(m_element.get()); |
// 2. "Run the classic script given by the script's script." |
// Note: This is where the script is compiled and actually executed. |
@@ -798,10 +777,7 @@ bool ScriptLoader::doExecuteScript(const ScriptSourceCode& sourceCode) { |
// 6. "Set the script element's node document's currentScript attribute |
// to old script element." |
- if (isHTMLScriptLoader(m_element) || isSVGScriptLoader(m_element)) { |
- DCHECK(contextDocument->currentScript() == m_element); |
- contextDocument->popCurrentScript(); |
- } |
+ contextDocument->popCurrentScript(m_element.get()); |
return true; |
@@ -865,15 +841,15 @@ void ScriptLoader::pendingScriptFinished(PendingScript* pendingScript) { |
bool ScriptLoader::ignoresLoadRequest() const { |
return m_alreadyStarted || m_isExternalScript || m_parserInserted || |
- !element() || !element()->isConnected(); |
+ !m_element->isConnected(); |
} |
// Step 13 of https://html.spec.whatwg.org/#prepare-a-script |
bool ScriptLoader::isScriptForEventSupported() const { |
// 1. "Let for be the value of the for attribute." |
- String eventAttribute = client()->eventAttributeValue(); |
+ String eventAttribute = m_element->eventAttributeValue(); |
// 2. "Let event be the value of the event attribute." |
- String forAttribute = client()->forAttributeValue(); |
+ String forAttribute = m_element->forAttributeValue(); |
// "If the script element has an event attribute and a for attribute, and |
// the script's type is "classic", then run these substeps:" |
@@ -900,25 +876,4 @@ String ScriptLoader::scriptContent() const { |
return m_element->textFromChildren(); |
} |
-ScriptLoaderClient* ScriptLoader::client() const { |
- if (isHTMLScriptLoader(m_element)) |
- return toHTMLScriptElement(m_element); |
- |
- if (isSVGScriptLoader(m_element)) |
- return toSVGScriptElement(m_element); |
- |
- NOTREACHED(); |
- return 0; |
-} |
- |
-ScriptLoader* toScriptLoaderIfPossible(Element* element) { |
- if (isHTMLScriptLoader(element)) |
- return toHTMLScriptElement(element)->loader(); |
- |
- if (isSVGScriptLoader(element)) |
- return toSVGScriptElement(element)->loader(); |
- |
- return 0; |
-} |
- |
} // namespace blink |