Index: third_party/WebKit/Source/core/dom/PendingScript.cpp |
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.cpp b/third_party/WebKit/Source/core/dom/PendingScript.cpp |
index e9cd5ab012ca4d19f1cfbdbfd6a9001076ccb32c..20c822632920b32bb2a86bca59a8d52bf4b4d691 100644 |
--- a/third_party/WebKit/Source/core/dom/PendingScript.cpp |
+++ b/third_party/WebKit/Source/core/dom/PendingScript.cpp |
@@ -25,79 +25,37 @@ |
#include "core/dom/PendingScript.h" |
-#include "bindings/core/v8/ScriptSourceCode.h" |
-#include "bindings/core/v8/ScriptState.h" |
-#include "bindings/core/v8/V8Binding.h" |
-#include "core/dom/ClassicScript.h" |
-#include "core/dom/Document.h" |
#include "core/dom/ScriptElementBase.h" |
-#include "core/dom/TaskRunnerHelper.h" |
-#include "core/frame/LocalFrame.h" |
-#include "core/frame/SubresourceIntegrity.h" |
-#include "platform/SharedBuffer.h" |
#include "wtf/CurrentTime.h" |
namespace blink { |
-PendingScript* PendingScript::create(ScriptElementBase* element, |
- ScriptResource* resource) { |
- return new PendingScript(element, resource, TextPosition()); |
-} |
- |
-PendingScript* PendingScript::create(ScriptElementBase* element, |
- const TextPosition& startingPosition) { |
- return new PendingScript(element, nullptr, startingPosition); |
-} |
- |
-PendingScript* PendingScript::createForTesting(ScriptResource* resource) { |
- return new PendingScript(nullptr, resource, TextPosition(), true); |
-} |
- |
PendingScript::PendingScript(ScriptElementBase* element, |
- ScriptResource* resource, |
- const TextPosition& startingPosition, |
- bool isForTesting) |
+ const TextPosition& startingPosition) |
: m_watchingForLoad(false), |
m_element(element), |
m_startingPosition(startingPosition), |
- m_integrityFailure(false), |
m_parserBlockingLoadStartTime(0), |
- m_client(nullptr), |
- m_isForTesting(isForTesting) { |
- checkState(); |
- setResource(resource); |
- MemoryCoordinator::instance().registerClient(this); |
-} |
+ m_client(nullptr) {} |
PendingScript::~PendingScript() {} |
-NOINLINE void PendingScript::checkState() const { |
- // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta. |
- CHECK(m_isForTesting || m_element); |
- CHECK(resource() || !m_streamer); |
- CHECK(!m_streamer || m_streamer->resource() == resource()); |
-} |
- |
void PendingScript::dispose() { |
stopWatchingForLoad(); |
- DCHECK(!m_client); |
- DCHECK(!m_watchingForLoad); |
+ DCHECK(!client()); |
+ DCHECK(!isWatchingForLoad()); |
- MemoryCoordinator::instance().unregisterClient(this); |
- setResource(nullptr); |
m_startingPosition = TextPosition::belowRangePosition(); |
- m_integrityFailure = false; |
m_parserBlockingLoadStartTime = 0; |
- if (m_streamer) |
- m_streamer->cancel(); |
- m_streamer = nullptr; |
+ |
+ disposeInternal(); |
m_element = nullptr; |
} |
void PendingScript::watchForLoad(PendingScriptClient* client) { |
checkState(); |
- DCHECK(!m_watchingForLoad); |
+ DCHECK(!isWatchingForLoad()); |
// addClient() will call streamingFinished() if the load is complete. Callers |
// who do not expect to be re-entered from this call should not call |
// watchForLoad for a PendingScript which isReady. We also need to set |
@@ -110,10 +68,10 @@ void PendingScript::watchForLoad(PendingScriptClient* client) { |
} |
void PendingScript::stopWatchingForLoad() { |
- if (!m_watchingForLoad) |
+ if (!isWatchingForLoad()) |
return; |
checkState(); |
- DCHECK(resource()); |
+ DCHECK(isExternal()); |
m_client = nullptr; |
m_watchingForLoad = false; |
} |
@@ -126,172 +84,14 @@ ScriptElementBase* PendingScript::element() const { |
return m_element.get(); |
} |
-void PendingScript::streamingFinished() { |
- checkState(); |
- DCHECK(resource()); |
- if (m_client) |
- m_client->pendingScriptFinished(this); |
-} |
- |
void PendingScript::markParserBlockingLoadStartTime() { |
DCHECK_EQ(m_parserBlockingLoadStartTime, 0.0); |
m_parserBlockingLoadStartTime = monotonicallyIncreasingTime(); |
} |
-// Returns true if SRI check passed. |
-static bool checkScriptResourceIntegrity(Resource* resource, |
- ScriptElementBase* element) { |
- DCHECK_EQ(resource->getType(), Resource::Script); |
- ScriptResource* scriptResource = toScriptResource(resource); |
- String integrityAttr = element->integrityAttributeValue(); |
- |
- // It is possible to get back a script resource with integrity metadata |
- // for a request with an empty integrity attribute. In that case, the |
- // integrity check should be skipped, so this check ensures that the |
- // integrity attribute isn't empty in addition to checking if the |
- // resource has empty integrity metadata. |
- if (integrityAttr.isEmpty() || scriptResource->integrityMetadata().isEmpty()) |
- return true; |
- |
- switch (scriptResource->integrityDisposition()) { |
- case ResourceIntegrityDisposition::Passed: |
- return true; |
- |
- case ResourceIntegrityDisposition::Failed: |
- // TODO(jww): This should probably also generate a console |
- // message identical to the one produced by |
- // CheckSubresourceIntegrity below. See https://crbug.com/585267. |
- return false; |
- |
- case ResourceIntegrityDisposition::NotChecked: { |
- if (!resource->resourceBuffer()) |
- return true; |
- |
- bool passed = SubresourceIntegrity::CheckSubresourceIntegrity( |
- scriptResource->integrityMetadata(), element->document(), |
- resource->resourceBuffer()->data(), |
- resource->resourceBuffer()->size(), resource->url(), *resource); |
- scriptResource->setIntegrityDisposition( |
- passed ? ResourceIntegrityDisposition::Passed |
- : ResourceIntegrityDisposition::Failed); |
- return passed; |
- } |
- } |
- |
- NOTREACHED(); |
- return true; |
-} |
- |
-void PendingScript::notifyFinished(Resource* resource) { |
- // The following SRI checks need to be here because, unfortunately, fetches |
- // are not done purely according to the Fetch spec. In particular, |
- // different requests for the same resource do not have different |
- // responses; the memory cache can (and will) return the exact same |
- // Resource object. |
- // |
- // For different requests, the same Resource object will be returned and |
- // will not be associated with the particular request. Therefore, when the |
- // body of the response comes in, there's no way to validate the integrity |
- // of the Resource object against a particular request (since there may be |
- // several pending requests all tied to the identical object, and the |
- // actual requests are not stored). |
- // |
- // In order to simulate the correct behavior, Blink explicitly does the SRI |
- // checks here, when a PendingScript tied to a particular request is |
- // finished (and in the case of a StyleSheet, at the point of execution), |
- // while having proper Fetch checks in the fetch module for use in the |
- // fetch JavaScript API. In a future world where the ResourceFetcher uses |
- // the Fetch algorithm, this should be fixed by having separate Response |
- // objects (perhaps attached to identical Resource objects) per request. |
- // |
- // See https://crbug.com/500701 for more information. |
- checkState(); |
- if (m_element) { |
- m_integrityFailure = !checkScriptResourceIntegrity(resource, m_element); |
- } |
- |
- // If script streaming is in use, the client will be notified in |
- // streamingFinished. |
- if (m_streamer) |
- m_streamer->notifyFinished(resource); |
- else if (m_client) |
- m_client->pendingScriptFinished(this); |
-} |
- |
-void PendingScript::notifyAppendData(ScriptResource* resource) { |
- if (m_streamer) |
- m_streamer->notifyAppendData(resource); |
-} |
- |
DEFINE_TRACE(PendingScript) { |
visitor->trace(m_element); |
- visitor->trace(m_streamer); |
visitor->trace(m_client); |
- ResourceOwner<ScriptResource>::trace(visitor); |
- MemoryCoordinatorClient::trace(visitor); |
-} |
- |
-ClassicScript* PendingScript::getSource(const KURL& documentURL, |
- bool& errorOccurred) const { |
- checkState(); |
- |
- errorOccurred = this->errorOccurred(); |
- if (resource()) { |
- DCHECK(resource()->isLoaded()); |
- if (m_streamer && !m_streamer->streamingSuppressed()) |
- return ClassicScript::create(ScriptSourceCode(m_streamer, resource())); |
- return ClassicScript::create(ScriptSourceCode(resource())); |
- } |
- |
- return ClassicScript::create(ScriptSourceCode( |
- m_element->textContent(), documentURL, startingPosition())); |
-} |
- |
-void PendingScript::setStreamer(ScriptStreamer* streamer) { |
- DCHECK(!m_streamer); |
- DCHECK(!m_watchingForLoad); |
- m_streamer = streamer; |
- checkState(); |
-} |
- |
-bool PendingScript::isReady() const { |
- checkState(); |
- if (resource()) { |
- return resource()->isLoaded() && (!m_streamer || m_streamer->isFinished()); |
- } |
- |
- return true; |
-} |
- |
-bool PendingScript::errorOccurred() const { |
- checkState(); |
- if (resource()) |
- return resource()->errorOccurred() || m_integrityFailure; |
- |
- return false; |
-} |
- |
-void PendingScript::onPurgeMemory() { |
- checkState(); |
- if (!m_streamer) |
- return; |
- m_streamer->cancel(); |
- m_streamer = nullptr; |
-} |
- |
-void PendingScript::startStreamingIfPossible( |
- Document* document, |
- ScriptStreamer::Type streamerType) { |
- if (!document->frame()) |
- return; |
- |
- ScriptState* scriptState = toScriptStateForMainWorld(document->frame()); |
- if (!scriptState) |
- return; |
- |
- ScriptStreamer::startStreaming( |
- this, streamerType, document->frame()->settings(), scriptState, |
- TaskRunnerHelper::get(TaskType::Networking, document)); |
} |
} // namespace blink |