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

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

Issue 2723793002: De-Element ScriptLoader (Closed)
Patch Set: ScriptLoaderClient->ScriptElementBase, pure virtual interface, add fixme Created 3 years, 9 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
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
« no previous file with comments | « third_party/WebKit/Source/core/dom/ScriptLoader.h ('k') | third_party/WebKit/Source/core/dom/ScriptLoaderClient.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698