Commit 31120af1 authored by marja@chromium.org's avatar marja@chromium.org

Refactor PendingScript / HTMLScriptRunner.

Goal: PendingScript should know how to watch for its resource to load, and upper
layers (such as HTMLScriptRunner) should delegate the "how to watch for load"
logic to PendingScript, instead of accessing its resource directly.

In addition, a function to extract source code from PendingScript should be in
PendingScript, not in HTMLScriptRunner.

The refactoring is split off from https://codereview.chromium.org/368283002
(script streaming), but it makes sense as standalone too.

BUG=

Review URL: https://codereview.chromium.org/551293002

git-svn-id: svn://svn.chromium.org/blink/trunk@181627 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent ceb12040
......@@ -35,6 +35,25 @@ PendingScript::~PendingScript()
{
}
void PendingScript::watchForLoad(ResourceClient* client)
{
ASSERT(!m_watchingForLoad);
ASSERT(!resource()->isLoaded());
// addClient() will call notifyFinished() if the load is complete. Callers
// do not expect to be re-entered from this call, so they should not become
// a client of an already-loaded Resource.
resource()->addClient(client);
m_watchingForLoad = true;
}
void PendingScript::stopWatchingForLoad(ResourceClient* client)
{
if (resource() && m_watchingForLoad) {
resource()->removeClient(client);
m_watchingForLoad = false;
}
}
PassRefPtrWillBeRawPtr<Element> PendingScript::releaseElementAndClear()
{
setScriptResource(0);
......@@ -57,4 +76,15 @@ void PendingScript::trace(Visitor* visitor)
visitor->trace(m_element);
}
ScriptSourceCode PendingScript::getSource(const KURL& documentURL, bool& errorOccurred) const
{
if (resource()) {
errorOccurred = resource()->errorOccurred();
ASSERT(resource()->isLoaded());
return ScriptSourceCode(resource());
}
errorOccurred = false;
return ScriptSourceCode(m_element->textContent(), documentURL, startingPosition());
}
}
......@@ -26,6 +26,7 @@
#ifndef PendingScript_h
#define PendingScript_h
#include "bindings/core/v8/ScriptSourceCode.h"
#include "core/dom/Element.h"
#include "core/fetch/ResourceClient.h"
#include "core/fetch/ResourceOwner.h"
......@@ -87,8 +88,8 @@ public:
TextPosition startingPosition() const { return m_startingPosition; }
void setStartingPosition(const TextPosition& position) { m_startingPosition = position; }
bool watchingForLoad() const { return m_watchingForLoad; }
void setWatchingForLoad(bool b) { m_watchingForLoad = b; }
void watchForLoad(ResourceClient*);
void stopWatchingForLoad(ResourceClient*);
Element* element() const { return m_element.get(); }
void setElement(Element* element) { m_element = element; }
......@@ -100,6 +101,8 @@ public:
void trace(Visitor*);
ScriptSourceCode getSource(const KURL& documentURL, bool& errorOccurred) const;
private:
bool m_watchingForLoad;
RefPtrWillBeMember<Element> m_element;
......
......@@ -72,13 +72,11 @@ void HTMLScriptRunner::detach()
if (!m_document)
return;
if (m_parserBlockingScript.resource() && m_parserBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parserBlockingScript);
m_parserBlockingScript.stopWatchingForLoad(this);
while (!m_scriptsToExecuteAfterParsing.isEmpty()) {
PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst();
if (pendingScript.resource() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
pendingScript.stopWatchingForLoad(this);
}
m_document = nullptr;
}
......@@ -103,17 +101,6 @@ inline PassRefPtrWillBeRawPtr<Event> createScriptLoadEvent()
return Event::create(EventTypeNames::load);
}
ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) const
{
if (script.resource()) {
errorOccurred = script.resource()->errorOccurred();
ASSERT(script.resource()->isLoaded());
return ScriptSourceCode(script.resource());
}
errorOccurred = false;
return ScriptSourceCode(script.element()->textContent(), documentURLForScriptExecution(m_document), script.startingPosition());
}
bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
{
m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady();
......@@ -138,11 +125,10 @@ void HTMLScriptRunner::executeParsingBlockingScript()
void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript, PendingScriptType pendingScriptType)
{
bool errorOccurred = false;
ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
ScriptSourceCode sourceCode = pendingScript.getSource(documentURLForScriptExecution(m_document), errorOccurred);
// Stop watching loads before executeScript to prevent recursion if the script reloads itself.
if (pendingScript.resource() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
pendingScript.stopWatchingForLoad(this);
if (!isExecutingScript()) {
Microtask::performCheckpoint();
......@@ -176,24 +162,6 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
ASSERT(!isExecutingScript());
}
void HTMLScriptRunner::watchForLoad(PendingScript& pendingScript)
{
ASSERT(!pendingScript.watchingForLoad());
ASSERT(!pendingScript.resource()->isLoaded());
// addClient() will call notifyFinished() if the load is complete.
// Callers do not expect to be re-entered from this call, so they
// should not become a client of an already-loaded Resource.
pendingScript.resource()->addClient(this);
pendingScript.setWatchingForLoad(true);
}
void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
{
ASSERT(pendingScript.watchingForLoad());
pendingScript.resource()->removeClient(this);
pendingScript.setWatchingForLoad(false);
}
void HTMLScriptRunner::notifyFinished(Resource* cachedResource)
{
m_host->notifyScriptLoaded(cachedResource);
......@@ -260,7 +228,7 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing()
ASSERT(!hasParserBlockingScript());
ASSERT(m_scriptsToExecuteAfterParsing.first().resource());
if (!m_scriptsToExecuteAfterParsing.first().resource()->isLoaded()) {
watchForLoad(m_scriptsToExecuteAfterParsing.first());
m_scriptsToExecuteAfterParsing.first().watchForLoad(this);
return false;
}
PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst();
......@@ -284,7 +252,7 @@ void HTMLScriptRunner::requestParsingBlockingScript(Element* element)
// in the cache. Callers will attempt to run the m_parserBlockingScript
// if possible before returning control to the parser.
if (!m_parserBlockingScript.resource()->isLoaded())
watchForLoad(m_parserBlockingScript);
m_parserBlockingScript.watchForLoad(this);
}
void HTMLScriptRunner::requestDeferredScript(Element* element)
......
......@@ -88,11 +88,7 @@ private:
void runScript(Element*, const TextPosition& scriptStartPosition);
// Helpers for dealing with HTMLScriptRunnerHost
void watchForLoad(PendingScript&);
void stopWatchingForLoad(PendingScript&);
bool isPendingScriptReady(const PendingScript&);
ScriptSourceCode sourceFromPendingScript(const PendingScript&, bool& errorOccurred) const;
RawPtrWillBeMember<Document> m_document;
RawPtrWillBeMember<HTMLScriptRunnerHost> m_host;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment