diff options
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; } |