summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--third_party/WebKit/Source/core/dom/Document.cpp6
-rw-r--r--third_party/WebKit/Source/core/dom/Document.h6
-rw-r--r--third_party/WebKit/Source/core/dom/DocumentParser.h5
-rw-r--r--third_party/WebKit/Source/core/fetch/RawResource.cpp3
-rw-r--r--third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp22
-rw-r--r--third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h5
-rw-r--r--third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp22
-rw-r--r--third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h19
-rw-r--r--third_party/WebKit/Source/core/loader/DocumentLoader.cpp78
-rw-r--r--third_party/WebKit/Source/core/loader/DocumentLoader.h5
-rw-r--r--third_party/WebKit/Source/core/loader/FrameLoader.cpp38
-rw-r--r--third_party/WebKit/Source/core/loader/FrameLoader.h2
-rw-r--r--third_party/WebKit/Source/core/loader/NavigationScheduler.cpp2
13 files changed, 171 insertions, 42 deletions
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 066b471..4049c86 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -396,6 +396,7 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
, m_frame(initializer.frame())
, m_domWindow(m_frame ? m_frame->localDOMWindow() : 0)
, m_importsController(initializer.importsController())
+ , m_activeParserCount(0)
, m_contextFeatures(ContextFeatures::defaultSwitch())
, m_wellFormed(false)
, m_printing(false)
@@ -5544,6 +5545,11 @@ bool Document::threadedParsingEnabledForTesting()
return s_threadedParsingEnabledForTesting;
}
+bool Document::hasActiveParser()
+{
+ return m_activeParserCount || (m_parser && m_parser->processingData());
+}
+
void Document::setContextFeatures(ContextFeatures& features)
{
m_contextFeatures = PassRefPtrWillBeRawPtr<ContextFeatures>(features);
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 5d7b140..960fd2d 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -954,6 +954,11 @@ public:
void adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>&, LayoutObject&);
void adjustFloatRectForScrollAndAbsoluteZoom(FloatRect&, LayoutObject&);
+ bool hasActiveParser();
+ unsigned activeParserCount() { return m_activeParserCount; }
+ void incrementActiveParserCount() { ++m_activeParserCount; }
+ void decrementActiveParserCount() { --m_activeParserCount; }
+
void setContextFeatures(ContextFeatures&);
ContextFeatures& contextFeatures() const { return *m_contextFeatures; }
@@ -1182,6 +1187,7 @@ private:
PersistentWillBeMember<ResourceFetcher> m_fetcher;
RefPtrWillBeMember<DocumentParser> m_parser;
+ unsigned m_activeParserCount;
RefPtrWillBeMember<ContextFeatures> m_contextFeatures;
bool m_wellFormed;
diff --git a/third_party/WebKit/Source/core/dom/DocumentParser.h b/third_party/WebKit/Source/core/dom/DocumentParser.h
index abbf48d..b5ff387 100644
--- a/third_party/WebKit/Source/core/dom/DocumentParser.h
+++ b/third_party/WebKit/Source/core/dom/DocumentParser.h
@@ -61,6 +61,11 @@ public:
virtual void finish() = 0;
+ // FIXME: processingData() is only used by DocumentLoader::isLoadingInAPISense
+ // and is very unclear as to what it actually means. The LegacyHTMLDocumentParser
+ // used to implement it.
+ virtual bool processingData() const { return false; }
+
// document() will return 0 after detach() is called.
Document* document() const { ASSERT(m_document); return m_document; }
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.cpp b/third_party/WebKit/Source/core/fetch/RawResource.cpp
index e885514..278fda7 100644
--- a/third_party/WebKit/Source/core/fetch/RawResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/RawResource.cpp
@@ -130,13 +130,12 @@ void RawResource::didAddClient(ResourceClient* c)
void RawResource::willFollowRedirect(ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
{
- Resource::willFollowRedirect(newRequest, redirectResponse);
-
RefPtrWillBeRawPtr<RawResource> protect(this);
ASSERT(!redirectResponse.isNull());
ResourceClientWalker<RawResourceClient> w(m_clients);
while (RawResourceClient* c = w.next())
c->redirectReceived(this, newRequest, redirectResponse);
+ Resource::willFollowRedirect(newRequest, redirectResponse);
}
void RawResource::responseReceived(const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle)
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index 3f1e195..0ed9b64 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -259,6 +259,11 @@ bool HTMLDocumentParser::isParsingFragment() const
return m_treeBuilder->isParsingFragment();
}
+bool HTMLDocumentParser::processingData() const
+{
+ return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser;
+}
+
void HTMLDocumentParser::pumpTokenizerIfPossible()
{
if (isStopped() || isWaitingForScripts())
@@ -429,8 +434,7 @@ size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par
TRACE_EVENT0("blink", "HTMLDocumentParser::processParsedChunkFromBackgroundParser");
TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true);
- ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1);
- ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession());
+ ASSERT_WITH_SECURITY_IMPLICATION(document()->activeParserCount() == 1);
ASSERT(!isParsingFragment());
ASSERT(!isWaitingForScripts());
ASSERT(!isStopped());
@@ -546,7 +550,7 @@ void HTMLDocumentParser::pumpPendingSpeculations()
// FIXME: Pass in current input length.
TRACE_EVENT_BEGIN1("devtools.timeline", "ParseHTML", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zeroBasedInt()));
- SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel);
+ SpeculationsPumpSession session(m_pumpSpeculationsSessionNestingLevel, contextForParsingSession());
while (!m_speculations.isEmpty()) {
ASSERT(!isScheduledForResume());
size_t elementTokenCount = processParsedChunkFromBackgroundParser(m_speculations.takeFirst().release());
@@ -580,6 +584,15 @@ void HTMLDocumentParser::forcePlaintextForTextDocument()
m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
}
+Document* HTMLDocumentParser::contextForParsingSession()
+{
+ // The parsing session should interact with the document only when parsing
+ // non-fragments. Otherwise, we might delay the load event mistakenly.
+ if (isParsingFragment())
+ return nullptr;
+ return document();
+}
+
void HTMLDocumentParser::pumpTokenizer()
{
ASSERT(!isStopped());
@@ -590,7 +603,7 @@ void HTMLDocumentParser::pumpTokenizer()
ASSERT(m_tokenizer);
ASSERT(m_token);
- PumpSession session(m_pumpSessionNestingLevel);
+ PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession());
// We tell the InspectorInstrumentation about every pump, even if we
// end up pumping nothing. It can filter out empty pumps itself.
@@ -1048,6 +1061,7 @@ void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFra
RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
parser->append(source);
parser->finish();
+ ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
}
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
index 8849292e..513e130 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -110,6 +110,8 @@ public:
void flush() final;
void setDecoder(PassOwnPtr<TextResourceDecoder>) final;
+ UseCounter* useCounter() { return UseCounter::getFrom(contextForParsingSession()); }
+
protected:
void insert(const SegmentedString&) final;
void append(const String&) override;
@@ -131,6 +133,7 @@ private:
// DocumentParser
void detach() final;
bool hasInsertionPoint() final;
+ bool processingData() const final;
void prepareToStopParsing() final;
void stopParsing() final;
bool isWaitingForScripts() const final;
@@ -150,6 +153,8 @@ private:
size_t processParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
void pumpPendingSpeculations();
+ Document* contextForParsingSession();
+
bool canTakeNextToken();
void pumpTokenizer();
void pumpTokenizerIfPossible();
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
index ae74514..70b70ad 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
@@ -35,8 +35,24 @@
namespace blink {
-PumpSession::PumpSession(unsigned& nestingLevel)
+ActiveParserSession::ActiveParserSession(unsigned& nestingLevel, Document* document)
: NestingLevelIncrementer(nestingLevel)
+ , m_document(document)
+{
+ if (!m_document)
+ return;
+ m_document->incrementActiveParserCount();
+}
+
+ActiveParserSession::~ActiveParserSession()
+{
+ if (!m_document)
+ return;
+ m_document->decrementActiveParserCount();
+}
+
+PumpSession::PumpSession(unsigned& nestingLevel, Document* document)
+ : ActiveParserSession(nestingLevel, document)
{
}
@@ -44,8 +60,8 @@ PumpSession::~PumpSession()
{
}
-SpeculationsPumpSession::SpeculationsPumpSession(unsigned& nestingLevel)
- : NestingLevelIncrementer(nestingLevel)
+SpeculationsPumpSession::SpeculationsPumpSession(unsigned& nestingLevel, Document* document)
+ : ActiveParserSession(nestingLevel, document)
, m_startTime(currentTime())
, m_processedElementTokens(0)
{
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
index 0445b84..da8cddc 100644
--- a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
+++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
@@ -34,20 +34,31 @@
namespace blink {
+class Document;
class HTMLDocumentParser;
class WebTaskRunner;
-class PumpSession : public NestingLevelIncrementer {
+class ActiveParserSession : public NestingLevelIncrementer {
STACK_ALLOCATED();
public:
- PumpSession(unsigned& nestingLevel);
+ ActiveParserSession(unsigned& nestingLevel, Document*);
+ ~ActiveParserSession();
+
+private:
+ RefPtrWillBeMember<Document> m_document;
+};
+
+class PumpSession : public ActiveParserSession {
+ STACK_ALLOCATED();
+public:
+ PumpSession(unsigned& nestingLevel, Document*);
~PumpSession();
};
-class SpeculationsPumpSession : public NestingLevelIncrementer {
+class SpeculationsPumpSession : public ActiveParserSession {
STACK_ALLOCATED();
public:
- SpeculationsPumpSession(unsigned& nestingLevel);
+ SpeculationsPumpSession(unsigned& nestingLevel, Document*);
~SpeculationsPumpSession();
double elapsedTime() const;
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index c10d6fc..c5b9083 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -128,7 +128,7 @@ ResourceLoader* DocumentLoader::mainResourceLoader() const
DocumentLoader::~DocumentLoader()
{
- ASSERT(!m_frame);
+ ASSERT(!m_frame || !isLoading());
ASSERT(!m_mainResource);
ASSERT(!m_applicationCacheHost);
}
@@ -149,6 +149,13 @@ unsigned long DocumentLoader::mainResourceIdentifier() const
return m_mainResource ? m_mainResource->identifier() : 0;
}
+Document* DocumentLoader::document() const
+{
+ if (m_frame && m_frame->loader().documentLoader() == this)
+ return m_frame->document();
+ return nullptr;
+}
+
const ResourceRequest& DocumentLoader::originalRequest() const
{
return m_originalRequest;
@@ -230,6 +237,33 @@ const KURL& DocumentLoader::urlForHistory() const
return unreachableURL().isEmpty() ? url() : unreachableURL();
}
+void DocumentLoader::mainReceivedError(const ResourceError& error)
+{
+ ASSERT(!error.isNull());
+ ASSERT(!m_frame || !m_frame->page()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame));
+ if (m_applicationCacheHost)
+ m_applicationCacheHost->failedLoadingMainResource();
+ if (!frameLoader())
+ return;
+ m_state = MainResourceDone;
+ frameLoader()->receivedMainResourceError(this, error);
+ clearMainResourceHandle();
+}
+
+// Cancels the data source's pending loads. Conceptually, a data source only loads
+// one document at a time, but one document may have many related resources.
+// stopLoading will stop all loads initiated by the data source,
+// but not loads initiated by child frames' data sources -- that's the WebFrame's job.
+void DocumentLoader::stopLoading()
+{
+ RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame.get());
+ RefPtrWillBeRawPtr<DocumentLoader> protectLoader(this);
+
+ if (isLoading())
+ cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
+ m_fetcher->stopFetching();
+}
+
void DocumentLoader::commitIfReady()
{
if (m_state < Committed) {
@@ -238,6 +272,14 @@ void DocumentLoader::commitIfReady()
}
}
+bool DocumentLoader::isLoading() const
+{
+ if (document() && document()->hasActiveParser())
+ return true;
+
+ return (m_state > NotStarted && m_state < MainResourceDone) || m_fetcher->isFetching();
+}
+
void DocumentLoader::notifyFinished(Resource* resource)
{
ASSERT_UNUSED(resource, m_mainResource == resource);
@@ -250,11 +292,7 @@ void DocumentLoader::notifyFinished(Resource* resource)
return;
}
- if (m_applicationCacheHost)
- m_applicationCacheHost->failedLoadingMainResource();
- m_state = MainResourceDone;
- frameLoader()->loadFailed(this, m_mainResource->resourceError());
- clearMainResourceHandle();
+ mainReceivedError(m_mainResource->resourceError());
}
void DocumentLoader::finishedLoading(double finishTime)
@@ -300,11 +338,11 @@ void DocumentLoader::redirectReceived(Resource* resource, ResourceRequest& reque
RefPtr<SecurityOrigin> redirectingOrigin = SecurityOrigin::create(redirectResponse.url());
if (!redirectingOrigin->canDisplay(requestURL)) {
FrameLoader::reportLocalLoadFailed(m_frame, requestURL.getString());
- m_fetcher->stopFetching();
+ cancelMainResourceLoad(ResourceError::cancelledError(requestURL));
return;
}
if (!frameLoader()->shouldContinueForNavigationPolicy(m_request, SubstituteData(), this, CheckContentSecurityPolicy, m_navigationType, NavigationPolicyCurrentTab, replacesCurrentHistoryItem(), isClientRedirect())) {
- m_fetcher->stopFetching();
+ cancelMainResourceLoad(ResourceError::cancelledError(requestURL));
return;
}
@@ -411,7 +449,7 @@ void DocumentLoader::responseReceived(Resource* resource, const ResourceResponse
if (!shouldContinueForResponse()) {
InspectorInstrumentation::continueWithPolicyIgnore(m_frame, this, m_mainResource->identifier(), m_response);
- m_fetcher->stopFetching();
+ cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
return;
}
@@ -469,8 +507,10 @@ void DocumentLoader::commitData(const char* bytes, size_t length)
// This can happen if document.close() is called by an event handler while
// there's still pending incoming data.
- if (m_frame && !m_frame->document()->parsing())
+ if (m_frame && !m_frame->document()->parsing()) {
+ cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
return;
+ }
if (length)
m_state = DataReceived;
@@ -534,7 +574,7 @@ void DocumentLoader::processData(const char* data, size_t length)
// If we are sending data to MediaDocument, we should stop here
// and cancel the request.
if (m_frame && m_frame->document()->isMediaDocument())
- m_fetcher->stopFetching();
+ cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
}
void DocumentLoader::clearRedirectChain()
@@ -555,7 +595,7 @@ void DocumentLoader::detachFromFrame()
// It never makes sense to have a document loader that is detached from its
// frame have any loads active, so go ahead and kill all the loads.
- m_fetcher->stopFetching();
+ stopLoading();
// If that load cancellation triggered another detach, leave.
// (fast/frames/detach-frame-nested-no-crash.html is an example of this.)
@@ -563,6 +603,7 @@ void DocumentLoader::detachFromFrame()
return;
m_fetcher->clearContext();
+
m_applicationCacheHost->detachFromDocumentLoader();
m_applicationCacheHost.clear();
WeakIdentifierMap<DocumentLoader>::notifyObjectDestroyed(this);
@@ -593,7 +634,7 @@ bool DocumentLoader::maybeCreateArchive()
ensureWriter(mainResource->mimeType(), mainResource->url());
// The Document has now been created.
- m_frame->document()->enforceSandboxFlags(SandboxAll);
+ document()->enforceSandboxFlags(SandboxAll);
commitData(mainResource->data()->data(), mainResource->data()->size());
return true;
@@ -664,6 +705,17 @@ void DocumentLoader::startLoadingMainResource()
m_mainResource->addClient(this);
}
+void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
+{
+ RefPtrWillBeRawPtr<DocumentLoader> protect(this);
+ ResourceError error = resourceError.isNull() ? ResourceError::cancelledError(m_request.url()) : resourceError;
+
+ if (mainResourceLoader())
+ mainResourceLoader()->cancel(error);
+
+ mainReceivedError(error);
+}
+
void DocumentLoader::endWriting(DocumentWriter* writer)
{
ASSERT_UNUSED(writer, m_writer == writer);
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h
index c1ea3ba..ec20778 100644
--- a/third_party/WebKit/Source/core/loader/DocumentLoader.h
+++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -93,6 +93,8 @@ public:
void didChangePerformanceTiming();
void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource);
+ void stopLoading();
+ bool isLoading() const;
const ResourceResponse& response() const { return m_response; }
bool isClientRedirect() const { return m_isClientRedirect; }
void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
@@ -108,6 +110,7 @@ public:
void setNavigationType(NavigationType navigationType) { m_navigationType = navigationType; }
void startLoadingMainResource();
+ void cancelMainResourceLoad(const ResourceError&);
void attachThreadedDataReceiver(PassRefPtrWillBeRawPtr<ThreadedDataReceiver>);
void acceptDataFromThreadedReceiver(const char* data, int dataLength, int encodedDataLength);
@@ -156,6 +159,7 @@ private:
void ensureWriter(const AtomicString& mimeType, const KURL& overridingURL = KURL());
void endWriting(DocumentWriter*);
+ Document* document() const;
FrameLoader* frameLoader() const;
void commitIfReady();
@@ -166,6 +170,7 @@ private:
bool maybeCreateArchive();
void finishedLoading(double finishTime);
+ void mainReceivedError(const ResourceError&);
void cancelLoadAfterXFrameOptionsOrCSPDenied(const ResourceResponse&);
void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) final;
void responseReceived(Resource*, const ResourceResponse&, PassOwnPtr<WebDataConsumerHandle>) final;
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index ad794a9..79fd956 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -701,9 +701,12 @@ void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip
ASSERT(!stateObject || frameLoadType == FrameLoadTypeBackForward);
// If we have a provisional request for a different document, a fragment scroll should cancel it.
- detachDocumentLoader(m_provisionalDocumentLoader);
- if (!m_frame->host())
- return;
+ if (m_provisionalDocumentLoader) {
+ m_provisionalDocumentLoader->stopLoading();
+ detachDocumentLoader(m_provisionalDocumentLoader);
+ if (!m_frame->host())
+ return;
+ }
TemporaryChange<FrameLoadType> loadTypeChange(m_loadType, frameLoadType);
saveScrollState();
@@ -983,7 +986,8 @@ void FrameLoader::stopAllLoaders()
if (m_inStopAllLoaders)
return;
- // Stopping a document loader can blow away the frame from underneath.
+ // Calling stopLoading() on the provisional document loader can blow away
+ // the frame from underneath.
RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get());
m_inStopAllLoaders = true;
@@ -994,21 +998,20 @@ void FrameLoader::stopAllLoaders()
}
m_frame->document()->suppressLoadEvent();
+ // Don't stop loading the provisional loader if it is being protected (i.e.
+ // it is about to be committed) See prepareForCommit() for more details.
+ if (m_provisionalDocumentLoader && !m_protectProvisionalLoader)
+ m_provisionalDocumentLoader->stopLoading();
if (m_documentLoader)
- m_documentLoader->fetcher()->stopFetching();
+ m_documentLoader->stopLoading();
m_frame->document()->cancelParsing();
+
if (!m_protectProvisionalLoader)
detachDocumentLoader(m_provisionalDocumentLoader);
m_checkTimer.stop();
m_frame->navigationScheduler().cancel();
- // It's possible that the above actions won't have stopped loading if load
- // completion had been blocked on parsing or if we were in the middle of
- // committing an empty document. In that case, emulate a failed navigation.
- if (!m_provisionalDocumentLoader && m_documentLoader && m_frame->isLoading())
- loadFailed(!m_documentLoader->sentDidFinishLoad() ? m_documentLoader.get() : nullptr, ResourceError::cancelledError(m_documentLoader->url()));
-
m_inStopAllLoaders = false;
}
@@ -1220,13 +1223,16 @@ void FrameLoader::detach()
}
}
-void FrameLoader::loadFailed(DocumentLoader* loader, const ResourceError& error)
+void FrameLoader::receivedMainResourceError(DocumentLoader* loader, const ResourceError& error)
{
// Retain because the stop may release the last reference to it.
RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get());
RefPtrWillBeRawPtr<DocumentLoader> protectDocumentLoader(loader);
- if (!error.isCancellation() && m_frame->owner()) {
+ // FIXME: We really ought to be able to just check for isCancellation() here, but there are some
+ // ResourceErrors that setIsCancellation() but aren't created by ResourceError::cancelledError().
+ ResourceError c(ResourceError::cancelledError(KURL()));
+ if ((error.errorCode() != c.errorCode() || error.domain() != c.domain()) && m_frame->owner()) {
// FIXME: For now, fallback content doesn't work cross process.
if (m_frame->owner()->isLocal())
m_frame->deprecatedLocalOwner()->renderFallbackContent();
@@ -1385,7 +1391,11 @@ void FrameLoader::startLoad(FrameLoadRequest& frameLoadRequest, FrameLoadType ty
return;
m_frame->document()->cancelParsing();
- detachDocumentLoader(m_provisionalDocumentLoader);
+
+ if (m_provisionalDocumentLoader) {
+ m_provisionalDocumentLoader->stopLoading();
+ detachDocumentLoader(m_provisionalDocumentLoader);
+ }
// beforeunload fired above, and detaching a DocumentLoader can fire
// events, which can detach this frame.
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.h b/third_party/WebKit/Source/core/loader/FrameLoader.h
index 3027655..b948aac 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.h
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.h
@@ -110,7 +110,7 @@ public:
DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
- void loadFailed(DocumentLoader*, const ResourceError&);
+ void receivedMainResourceError(DocumentLoader*, const ResourceError&);
bool isLoadingMainFrame() const;
diff --git a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
index 147c9a0..a5f2726 100644
--- a/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
+++ b/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
@@ -393,7 +393,7 @@ void NavigationScheduler::schedule(PassOwnPtrWillBeRawPtr<ScheduledNavigation> r
// FIXME: This check seems out of place.
if (!m_frame->loader().stateMachine()->committedFirstRealDocumentLoad() && m_frame->loader().provisionalDocumentLoader()) {
RefPtrWillBeRawPtr<LocalFrame> protect(m_frame.get());
- m_frame->loader().stopAllLoaders();
+ m_frame->loader().provisionalDocumentLoader()->stopLoading();
if (!m_frame->host())
return;
}