diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/loader')
66 files changed, 1514 insertions, 3202 deletions
diff --git a/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp b/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp index 9d6821adf77..4ba0ca173d5 100644 --- a/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp @@ -33,8 +33,8 @@ #include "core/dom/Document.h" #include "core/loader/FrameLoaderClient.h" -#include "core/page/Frame.h" -#include "core/platform/Cookie.h" +#include "core/frame/Frame.h" +#include "platform/Cookie.h" #include "public/platform/Platform.h" #include "public/platform/WebCookie.h" #include "public/platform/WebCookieJar.h" @@ -43,21 +43,21 @@ namespace WebCore { -static WebKit::WebCookieJar* toCookieJar(const Document* document) +static blink::WebCookieJar* toCookieJar(const Document* document) { if (!document || !document->frame()) return 0; - WebKit::WebCookieJar* cookieJar = document->frame()->loader()->client()->cookieJar(); + blink::WebCookieJar* cookieJar = document->frame()->loader().client()->cookieJar(); // FIXME: DRT depends on being able to get a cookie jar from Platform rather than // FrameLoaderClient. Delete this when DRT is deleted. if (!cookieJar) - cookieJar = WebKit::Platform::current()->cookieJar(); + cookieJar = blink::Platform::current()->cookieJar(); return cookieJar; } String cookies(const Document* document, const KURL& url) { - WebKit::WebCookieJar* cookieJar = toCookieJar(document); + blink::WebCookieJar* cookieJar = toCookieJar(document); if (!cookieJar) return String(); return cookieJar->cookies(url, document->firstPartyForCookies()); @@ -65,7 +65,7 @@ String cookies(const Document* document, const KURL& url) void setCookies(Document* document, const KURL& url, const String& cookieString) { - WebKit::WebCookieJar* cookieJar = toCookieJar(document); + blink::WebCookieJar* cookieJar = toCookieJar(document); if (!cookieJar) return; cookieJar->setCookie(url, document->firstPartyForCookies(), cookieString); @@ -73,7 +73,7 @@ void setCookies(Document* document, const KURL& url, const String& cookieString) bool cookiesEnabled(const Document* document) { - WebKit::WebCookieJar* cookieJar = toCookieJar(document); + blink::WebCookieJar* cookieJar = toCookieJar(document); if (!cookieJar) return false; return cookieJar->cookiesEnabled(document->cookieURL(), document->firstPartyForCookies()); @@ -81,7 +81,7 @@ bool cookiesEnabled(const Document* document) String cookieRequestHeaderFieldValue(const Document* document, const KURL& url) { - WebKit::WebCookieJar* cookieJar = toCookieJar(document); + blink::WebCookieJar* cookieJar = toCookieJar(document); if (!cookieJar) return String(); return cookieJar->cookieRequestHeaderFieldValue(url, document->firstPartyForCookies()); @@ -90,13 +90,13 @@ String cookieRequestHeaderFieldValue(const Document* document, const KURL& url) bool getRawCookies(const Document* document, const KURL& url, Vector<Cookie>& cookies) { cookies.clear(); - WebKit::WebCookieJar* cookieJar = toCookieJar(document); + blink::WebCookieJar* cookieJar = toCookieJar(document); if (!cookieJar) return false; - WebKit::WebVector<WebKit::WebCookie> webCookies; + blink::WebVector<blink::WebCookie> webCookies; cookieJar->rawCookies(url, document->firstPartyForCookies(), webCookies); for (unsigned i = 0; i < webCookies.size(); ++i) { - const WebKit::WebCookie& webCookie = webCookies[i]; + const blink::WebCookie& webCookie = webCookies[i]; cookies.append(Cookie(webCookie.name, webCookie.value, webCookie.domain, webCookie.path, webCookie.expires, webCookie.httpOnly, webCookie.secure, webCookie.session)); } @@ -105,7 +105,7 @@ bool getRawCookies(const Document* document, const KURL& url, Vector<Cookie>& co void deleteCookie(const Document* document, const KURL& url, const String& cookieName) { - WebKit::WebCookieJar* cookieJar = toCookieJar(document); + blink::WebCookieJar* cookieJar = toCookieJar(document); if (!cookieJar) return; cookieJar->deleteCookie(url, cookieName); diff --git a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp index c3f82abc12e..460e2e9f826 100644 --- a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp @@ -28,7 +28,7 @@ #include "core/loader/CrossOriginPreflightResultCache.h" #include "core/fetch/CrossOriginAccessControl.h" -#include "core/platform/network/ResourceResponse.h" +#include "platform/network/ResourceResponse.h" #include "wtf/CurrentTime.h" #include "wtf/MainThread.h" #include "wtf/StdLibExtras.h" diff --git a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h index 3911a2c1373..1c65c968c22 100644 --- a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h +++ b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h @@ -28,7 +28,7 @@ #define CrossOriginPreflightResultCache_h #include "core/fetch/ResourceLoaderOptions.h" -#include "weborigin/KURLHash.h" +#include "platform/weborigin/KURLHash.h" #include "wtf/HashMap.h" #include "wtf/HashSet.h" #include "wtf/PassOwnPtr.h" diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp index a9115f00291..6204ca61357 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp @@ -26,8 +26,7 @@ #include "config.h" #include "core/loader/DocumentLoadTiming.h" -#include "weborigin/SecurityOrigin.h" -#include "wtf/CurrentTime.h" +#include "platform/weborigin/SecurityOrigin.h" #include "wtf/RefPtr.h" namespace WebCore { diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index 11f05e28e92..79122f88347 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp @@ -31,11 +31,9 @@ #include "core/loader/DocumentLoader.h" #include "FetchInitiatorTypeNames.h" -#include "bindings/v8/ScriptController.h" -#include "core/dom/DOMImplementation.h" #include "core/dom/Document.h" #include "core/dom/DocumentParser.h" -#include "core/dom/Event.h" +#include "core/events/Event.h" #include "core/fetch/FetchContext.h" #include "core/fetch/MemoryCache.h" #include "core/fetch/ResourceFetcher.h" @@ -43,25 +41,25 @@ #include "core/fetch/TextResourceDecoder.h" #include "core/html/HTMLFrameOwnerElement.h" #include "core/inspector/InspectorInstrumentation.h" -#include "core/loader/DocumentWriter.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" -#include "core/loader/SinkDocument.h" #include "core/loader/UniqueIdentifier.h" #include "core/loader/appcache/ApplicationCacheHost.h" -#include "core/loader/archive/ArchiveResourceCollection.h" -#include "core/loader/archive/MHTMLArchive.h" -#include "core/page/DOMWindow.h" -#include "core/page/Frame.h" +#include "core/frame/ContentSecurityPolicy.h" +#include "core/frame/DOMWindow.h" +#include "core/frame/Frame.h" #include "core/page/FrameTree.h" #include "core/page/Page.h" -#include "core/page/Settings.h" -#include "core/platform/Logging.h" -#include "core/plugins/PluginData.h" +#include "core/frame/Settings.h" +#include "platform/Logging.h" +#include "platform/UserGestureIndicator.h" +#include "platform/mhtml/ArchiveResourceCollection.h" +#include "platform/mhtml/MHTMLArchive.h" +#include "platform/plugins/PluginData.h" +#include "platform/weborigin/SchemeRegistry.h" +#include "platform/weborigin/SecurityPolicy.h" #include "public/platform/Platform.h" #include "public/platform/WebMimeRegistry.h" -#include "weborigin/SchemeRegistry.h" -#include "weborigin/SecurityPolicy.h" #include "wtf/Assertions.h" #include "wtf/text/WTFString.h" @@ -95,7 +93,7 @@ FrameLoader* DocumentLoader::frameLoader() const { if (!m_frame) return 0; - return m_frame->loader(); + return &m_frame->loader(); } ResourceLoader* DocumentLoader::mainResourceLoader() const @@ -127,7 +125,7 @@ unsigned long DocumentLoader::mainResourceIdentifier() const Document* DocumentLoader::document() const { - if (m_frame && m_frame->loader()->documentLoader() == this) + if (m_frame && m_frame->loader().documentLoader() == this) return m_frame->document(); return 0; } @@ -157,10 +155,20 @@ const KURL& DocumentLoader::url() const return request().url(); } -void DocumentLoader::replaceRequestURLForSameDocumentNavigation(const KURL& url) +void DocumentLoader::updateForSameDocumentNavigation(const KURL& newURL) { - m_originalRequestCopy.setURL(url); - m_request.setURL(url); + KURL oldURL = m_request.url(); + m_originalRequestCopy.setURL(newURL); + m_request.setURL(newURL); + clearRedirectChain(); + if (m_isClientRedirect) + appendRedirect(oldURL); + appendRedirect(newURL); +} + +bool DocumentLoader::isURLValidForNewHistoryEntry() const +{ + return !originalRequest().url().isEmpty() || !unreachableURL().isEmpty(); } void DocumentLoader::setRequest(const ResourceRequest& req) @@ -190,7 +198,7 @@ void DocumentLoader::setMainDocumentError(const ResourceError& error) void DocumentLoader::mainReceivedError(const ResourceError& error) { ASSERT(!error.isNull()); - ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading()); + ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame)); m_applicationCacheHost->failedLoadingMainResource(); if (!frameLoader()) return; @@ -220,7 +228,7 @@ void DocumentLoader::stopLoading() Document* doc = m_frame->document(); if (loading || doc->parsing()) - m_frame->loader()->stopLoading(); + m_frame->loader().stopLoading(); } clearArchiveResources(); @@ -337,7 +345,7 @@ bool DocumentLoader::isRedirectAfterPost(const ResourceRequest& newRequest, cons void DocumentLoader::handleSubstituteDataLoadNow(DocumentLoaderTimer*) { RefPtr<DocumentLoader> protect(this); - ResourceResponse response(m_request.url(), m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), ""); + ResourceResponse response(m_request.url(), m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), emptyString()); responseReceived(0, response); if (m_substituteData.content()->size()) dataReceived(0, m_substituteData.content()->data(), m_substituteData.content()->size()); @@ -373,15 +381,14 @@ bool DocumentLoader::shouldContinueForNavigationPolicy(const ResourceRequest& re if (m_frame->ownerElement() && !m_frame->ownerElement()->document().contentSecurityPolicy()->allowChildFrameFromSource(request.url())) return false; - NavigationPolicy policy = NavigationPolicyCurrentTab; - m_triggeringAction.specifiesNavigationPolicy(&policy); + NavigationPolicy policy = m_triggeringAction.policy(); if (policyCheckLoadType != PolicyCheckFragment) policy = frameLoader()->client()->decidePolicyForNavigation(request, this, policy); if (policy == NavigationPolicyCurrentTab) return true; if (policy == NavigationPolicyIgnore) return false; - if (!DOMWindow::allowPopUp(m_frame) && !ScriptController::processingUserGesture()) + if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture()) return false; frameLoader()->client()->loadURLExternally(request, policy); return false; @@ -434,9 +441,9 @@ void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource if (newRequest.cachePolicy() == UseProtocolCachePolicy && isRedirectAfterPost(newRequest, redirectResponse)) newRequest.setCachePolicy(ReloadIgnoringCacheData); - Frame* parent = m_frame->tree()->parent(); + Frame* parent = m_frame->tree().parent(); if (parent) { - if (!parent->loader()->mixedContentChecker()->canRunInsecureContent(parent->document()->securityOrigin(), newRequest.url())) { + if (!parent->loader().mixedContentChecker()->canRunInsecureContent(parent->document()->securityOrigin(), newRequest.url())) { cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url())); return; } @@ -455,7 +462,7 @@ void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource static bool canShowMIMEType(const String& mimeType, Page* page) { - if (WebKit::Platform::current()->mimeRegistry()->supportsMIMEType(mimeType) == WebKit::WebMimeRegistry::IsSupported) + if (blink::Platform::current()->mimeRegistry()->supportsMIMEType(mimeType) == blink::WebMimeRegistry::IsSupported) return true; PluginData* pluginData = page->pluginData(); return !mimeType.isEmpty() && pluginData && pluginData->supportsMimeType(mimeType); @@ -515,7 +522,7 @@ void DocumentLoader::responseReceived(Resource* resource, const ResourceResponse frame()->document()->addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, identifier); frame()->document()->enforceSandboxFlags(SandboxOrigin); if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement()) - ownerElement->dispatchEvent(Event::create(eventNames().loadEvent)); + ownerElement->dispatchEvent(Event::create(EventTypeNames::load)); // The load event might have detached this frame. In that case, the load will already have been cancelled during detach. if (frameLoader()) @@ -556,13 +563,12 @@ void DocumentLoader::ensureWriter() ensureWriter(m_response.mimeType()); } -void DocumentLoader::ensureWriter(const String& mimeType, const KURL& overridingURL) +void DocumentLoader::ensureWriter(const AtomicString& mimeType, const KURL& overridingURL) { if (m_writer) return; - String encoding = overrideEncoding().isNull() ? response().textEncodingName().impl() : overrideEncoding(); - bool userChosen = !overrideEncoding().isNull(); + const AtomicString& encoding = overrideEncoding().isNull() ? response().textEncodingName() : overrideEncoding(); m_writer = createWriterFor(m_frame, 0, requestURL(), mimeType, encoding, false, false); m_writer->setDocumentWasLoadedAsPartOfNavigation(); // This should be set before receivedFirstData(). @@ -682,6 +688,8 @@ bool DocumentLoader::isLoadingInAPISense() const return true; if (m_fetcher->requestCount()) return true; + if (doc->isDelayingLoadEvent() && !doc->loadEventFinished()) + return true; if (doc->processingLoadEvent()) return true; if (doc->hasActiveParser()) @@ -715,14 +723,14 @@ void DocumentLoader::addAllArchiveResources(MHTMLArchive* archive) void DocumentLoader::prepareSubframeArchiveLoadIfNeeded() { - if (!m_frame->tree()->parent()) + if (!m_frame->tree().parent()) return; - ArchiveResourceCollection* parentCollection = m_frame->tree()->parent()->loader()->documentLoader()->m_archiveResourceCollection.get(); + ArchiveResourceCollection* parentCollection = m_frame->tree().parent()->loader().documentLoader()->m_archiveResourceCollection.get(); if (!parentCollection) return; - m_archive = parentCollection->popSubframeArchive(m_frame->tree()->uniqueName(), m_request.url()); + m_archive = parentCollection->popSubframeArchive(m_frame->tree().uniqueName(), m_request.url()); if (!m_archive) return; @@ -758,17 +766,6 @@ bool DocumentLoader::scheduleArchiveLoad(Resource* cachedResource, const Resourc return true; } -KURL DocumentLoader::urlForHistory() const -{ - // Return the URL to be used for history and B/F list. - // Returns nil for WebDataProtocol URLs that aren't alternates - // for unreachable URLs, because these can't be stored in history. - if (m_substituteData.isValid()) - return unreachableURL(); - - return m_originalRequestCopy.url(); -} - const KURL& DocumentLoader::originalURL() const { return m_originalRequestCopy.url(); @@ -779,7 +776,7 @@ const KURL& DocumentLoader::requestURL() const return request().url(); } -const String& DocumentLoader::responseMIMEType() const +const AtomicString& DocumentLoader::responseMIMEType() const { return m_response.mimeType(); } @@ -808,7 +805,7 @@ bool DocumentLoader::maybeLoadEmpty() if (m_request.url().isEmpty() && !frameLoader()->stateMachine()->creatingInitialEmptyDocument()) m_request.setURL(blankURL()); - m_response = ResourceResponse(m_request.url(), "text/html", 0, String(), String()); + m_response = ResourceResponse(m_request.url(), "text/html", 0, nullAtom, String()); finishedLoading(monotonicallyIncreasingTime()); return true; } @@ -846,7 +843,7 @@ void DocumentLoader::startLoadingMainResource() ResourceRequest request(m_request); DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions, - (SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, UseDefaultOriginRestrictionsForType, DocumentContext)); + (SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, DocumentContext)); FetchRequest cachedResourceRequest(request, FetchInitiatorTypeNames::document, mainResourceLoadOptions); m_mainResource = m_fetcher->fetchMainResource(cachedResourceRequest); if (!m_mainResource) { @@ -882,7 +879,7 @@ void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError) mainReceivedError(error); } -DocumentWriter* DocumentLoader::beginWriting(const String& mimeType, const String& encoding, const KURL& url) +DocumentWriter* DocumentLoader::beginWriting(const AtomicString& mimeType, const AtomicString& encoding, const KURL& url) { m_writer = createWriterFor(m_frame, 0, url, mimeType, encoding, false, true); return m_writer.get(); @@ -895,53 +892,63 @@ void DocumentLoader::endWriting(DocumentWriter* writer) m_writer.clear(); } -PassRefPtr<DocumentWriter> DocumentLoader::createWriterFor(Frame* frame, const Document* ownerDocument, const KURL& url, const String& mimeType, const String& encoding, bool userChosen, bool dispatch) +PassRefPtr<DocumentWriter> DocumentLoader::createWriterFor(Frame* frame, const Document* ownerDocument, const KURL& url, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch) { // Create a new document before clearing the frame, because it may need to // inherit an aliased security context. - RefPtr<Document> document = DOMImplementation::createDocument(mimeType, frame, url, frame->inViewSourceMode()); - if (document->isPluginDocument() && document->isSandboxed(SandboxPlugins)) - document = SinkDocument::create(DocumentInit(url, frame)); - bool shouldReuseDefaultView = frame->loader()->stateMachine()->isDisplayingInitialEmptyDocument() && frame->document()->isSecureTransitionTo(url); + DocumentInit init(url, frame); + + // In some rare cases, we'll re-used a DOMWindow for a new Document. For example, + // when a script calls window.open("..."), the browser gives JavaScript a window + // synchronously but kicks off the load in the window asynchronously. Web sites + // expect that modifications that they make to the window object synchronously + // won't be blown away when the network load commits. To make that happen, we + // "securely transition" the existing DOMWindow to the Document that results from + // the network load. See also SecurityContext::isSecureTransitionTo. + bool shouldReuseDefaultView = frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && frame->document()->isSecureTransitionTo(url); ClearOptions options = 0; if (!shouldReuseDefaultView) options = ClearWindowProperties | ClearScriptObjects; - frame->loader()->clear(options); + frame->loader().clear(options); - if (frame->document() && frame->document()->attached()) + if (frame->document()) frame->document()->prepareForDestruction(); if (!shouldReuseDefaultView) frame->setDOMWindow(DOMWindow::create(frame)); - frame->loader()->setOutgoingReferrer(url); - frame->domWindow()->setDocument(document); - + RefPtr<Document> document = frame->domWindow()->installNewDocument(mimeType, init); if (ownerDocument) { document->setCookieURL(ownerDocument->cookieURL()); document->setSecurityOrigin(ownerDocument->securityOrigin()); } - frame->loader()->didBeginDocument(dispatch); + frame->loader().didBeginDocument(dispatch); return DocumentWriter::create(document.get(), mimeType, encoding, userChosen); } -String DocumentLoader::mimeType() const +const AtomicString& DocumentLoader::mimeType() const { if (m_writer) return m_writer->mimeType(); return m_response.mimeType(); } +void DocumentLoader::setUserChosenEncoding(const String& charset) +{ + if (m_writer) + m_writer->setUserChosenEncoding(charset); +} + // This is only called by ScriptController::executeScriptIfJavaScriptURL // and always contains the result of evaluating a javascript: url. // This is the <iframe src="javascript:'html'"> case. void DocumentLoader::replaceDocument(const String& source, Document* ownerDocument) { - m_frame->loader()->stopAllLoaders(); - m_writer = createWriterFor(m_frame, ownerDocument, m_frame->document()->url(), mimeType(), m_writer ? m_writer->encoding() : "", m_writer ? m_writer->encodingWasChosenByUser() : false, true); + m_frame->loader().stopAllLoaders(); + m_writer = createWriterFor(m_frame, ownerDocument, m_frame->document()->url(), mimeType(), m_writer ? m_writer->encoding() : emptyAtom, m_writer ? m_writer->encodingWasChosenByUser() : false, true); if (!source.isNull()) m_writer->appendReplacingData(source); endWriting(m_writer.get()); diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h index 7fe971f89c8..d9b30f80232 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h @@ -37,10 +37,10 @@ #include "core/loader/DocumentWriter.h" #include "core/loader/NavigationAction.h" #include "core/loader/SubstituteData.h" -#include "core/platform/Timer.h" -#include "core/platform/network/ResourceError.h" -#include "core/platform/network/ResourceRequest.h" -#include "core/platform/network/ResourceResponse.h" +#include "platform/Timer.h" +#include "platform/network/ResourceError.h" +#include "platform/network/ResourceRequest.h" +#include "platform/network/ResourceResponse.h" #include "wtf/HashSet.h" #include "wtf/RefPtr.h" @@ -81,10 +81,12 @@ namespace WebCore { unsigned long mainResourceIdentifier() const; void replaceDocument(const String& source, Document*); - DocumentWriter* beginWriting(const String& mimeType, const String& encoding, const KURL& = KURL()); + DocumentWriter* beginWriting(const AtomicString& mimeType, const AtomicString& encoding, const KURL& = KURL()); void endWriting(DocumentWriter*); - String mimeType() const; + const AtomicString& mimeType() const; + + void setUserChosenEncoding(const String& charset); const ResourceRequest& originalRequest() const; const ResourceRequest& originalRequestCopy() const; @@ -99,12 +101,13 @@ namespace WebCore { // FIXME: This is the same as requestURL(). We should remove one of them. const KURL& url() const; const KURL& unreachableURL() const; + bool isURLValidForNewHistoryEntry() const; const KURL& originalURL() const; const KURL& requestURL() const; - const String& responseMIMEType() const; + const AtomicString& responseMIMEType() const; - void replaceRequestURLForSameDocumentNavigation(const KURL&); + void updateForSameDocumentNavigation(const KURL&); void stopLoading(); void setCommitted(bool committed) { m_committed = committed; } bool isCommitted() const { return m_committed; } @@ -116,7 +119,7 @@ namespace WebCore { bool replacesCurrentHistoryItem() const { return m_replacesCurrentHistoryItem; } void setReplacesCurrentHistoryItem(bool replacesCurrentHistoryItem) { m_replacesCurrentHistoryItem = replacesCurrentHistoryItem; } bool isLoadingInAPISense() const; - const String& overrideEncoding() const { return m_overrideEncoding; } + const AtomicString& overrideEncoding() const { return m_overrideEncoding; } bool scheduleArchiveLoad(Resource*, const ResourceRequest&); void cancelPendingSubstituteLoad(ResourceLoader*); @@ -129,9 +132,7 @@ namespace WebCore { const NavigationAction& triggeringAction() const { return m_triggeringAction; } void setTriggeringAction(const NavigationAction& action) { m_triggeringAction = action; } - void setOverrideEncoding(const String& encoding) { m_overrideEncoding = encoding; } - - KURL urlForHistory() const; + void setOverrideEncoding(const AtomicString& encoding) { m_overrideEncoding = encoding; } void setDefersLoading(bool); @@ -164,10 +165,10 @@ namespace WebCore { Vector<KURL> m_redirectChain; private: - static PassRefPtr<DocumentWriter> createWriterFor(Frame*, const Document* ownerDocument, const KURL&, const String& mimeType, const String& encoding, bool userChosen, bool dispatch); + static PassRefPtr<DocumentWriter> createWriterFor(Frame*, const Document* ownerDocument, const KURL&, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch); void ensureWriter(); - void ensureWriter(const String& mimeType, const KURL& overridingURL = KURL()); + void ensureWriter(const AtomicString& mimeType, const KURL& overridingURL = KURL()); Document* document() const; @@ -239,7 +240,7 @@ namespace WebCore { bool m_isClientRedirect; bool m_replacesCurrentHistoryItem; - String m_overrideEncoding; + AtomicString m_overrideEncoding; // The action that triggered loading - we keep this around for the // benefit of the various policy handlers. diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp index c12ac96fafe..f34ee2e5b9e 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp @@ -35,21 +35,19 @@ #include "core/dom/Document.h" #include "core/fetch/CrossOriginAccessControl.h" #include "core/fetch/FetchRequest.h" -#include "core/fetch/RawResource.h" #include "core/fetch/Resource.h" #include "core/fetch/ResourceFetcher.h" +#include "core/frame/ContentSecurityPolicy.h" +#include "core/frame/Frame.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/loader/CrossOriginPreflightResultCache.h" #include "core/loader/DocumentThreadableLoaderClient.h" #include "core/loader/FrameLoader.h" #include "core/loader/ThreadableLoaderClient.h" -#include "core/page/ContentSecurityPolicy.h" -#include "core/page/Frame.h" -#include "core/platform/SharedBuffer.h" -#include "core/platform/network/ResourceError.h" -#include "core/platform/network/ResourceRequest.h" -#include "weborigin/SchemeRegistry.h" -#include "weborigin/SecurityOrigin.h" +#include "platform/SharedBuffer.h" +#include "platform/network/ResourceRequest.h" +#include "platform/weborigin/SchemeRegistry.h" +#include "platform/weborigin/SecurityOrigin.h" #include "wtf/Assertions.h" namespace WebCore { @@ -64,7 +62,7 @@ void DocumentThreadableLoader::loadResourceSynchronously(Document* document, con PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options) { RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options)); - if (!loader->m_resource) + if (!loader->resource()) loader = 0; return loader.release(); } @@ -89,7 +87,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document* document, Threadabl } if (m_options.crossOriginRequestPolicy == DenyCrossOriginRequests) { - m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.url().string(), "Cross origin requests are not supported.")); + m_client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are not supported.")); return; } @@ -125,7 +123,7 @@ void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const Resource // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied. if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) { - m_client->didFailAccessControlCheck(ResourceError(errorDomainWebKitInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP.")); + m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP.")); return; } @@ -140,8 +138,6 @@ void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const R DocumentThreadableLoader::~DocumentThreadableLoader() { - if (m_resource) - m_resource->removeClient(this); } void DocumentThreadableLoader::cancel() @@ -154,14 +150,14 @@ void DocumentThreadableLoader::cancelWithError(const ResourceError& error) RefPtr<DocumentThreadableLoader> protect(this); // Cancel can re-enter and m_resource might be null here as a result. - if (m_client && m_resource) { + if (m_client && resource()) { ResourceError errorForCallback = error; if (errorForCallback.isNull()) { // FIXME: This error is sent to the client in didFail(), so it should not be an internal one. Use FrameLoaderClient::cancelledError() instead. - errorForCallback = ResourceError(errorDomainWebKitInternal, 0, m_resource->url().string(), "Load cancelled"); + errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resource()->url().string(), "Load cancelled"); errorForCallback.setIsCancellation(true); } - didFail(m_resource->identifier(), errorForCallback); + didFail(resource()->identifier(), errorForCallback); } clearResource(); m_client = 0; @@ -169,26 +165,14 @@ void DocumentThreadableLoader::cancelWithError(const ResourceError& error) void DocumentThreadableLoader::setDefersLoading(bool value) { - if (m_resource) - m_resource->setDefersLoading(value); -} - -void DocumentThreadableLoader::clearResource() -{ - // Script can cancel and restart a request reentrantly within removeClient(), - // which could lead to calling Resource::removeClient() multiple times for - // this DocumentThreadableLoader. Save off a copy of m_resource and clear it to - // prevent the reentrancy. - if (ResourcePtr<RawResource> resource = m_resource) { - m_resource = 0; - resource->removeClient(this); - } + if (resource()) + resource()->setDefersLoading(value); } void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse) { ASSERT(m_client); - ASSERT_UNUSED(resource, resource == m_resource); + ASSERT_UNUSED(resource, resource == this->resource()); RefPtr<DocumentThreadableLoader> protect(this); if (!isAllowedByPolicy(request.url())) { @@ -209,7 +193,7 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ // original request was not same-origin. if (m_options.crossOriginRequestPolicy == UseAccessControl) { - InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document->frame(), resource->identifier(), m_document->frame()->loader()->documentLoader(), redirectResponse, 0); + InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document->frame(), resource->identifier(), m_document->frame()->loader().documentLoader(), redirectResponse, 0); bool allowRedirect = false; String accessControlErrorDescription; @@ -222,8 +206,7 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ } if (allowRedirect) { - if (m_resource) - clearResource(); + clearResource(); RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(redirectResponse.url()); RefPtr<SecurityOrigin> requestOrigin = SecurityOrigin::create(request.url()); @@ -250,7 +233,7 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ return; } - ResourceError error(errorDomainWebKitInternal, 0, redirectResponse.url().string(), accessControlErrorDescription); + ResourceError error(errorDomainBlinkInternal, 0, redirectResponse.url().string(), accessControlErrorDescription); m_client->didFailAccessControlCheck(error); } else { m_client->didFailRedirectCheck(); @@ -261,14 +244,14 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { ASSERT(m_client); - ASSERT_UNUSED(resource, resource == m_resource); + ASSERT_UNUSED(resource, resource == this->resource()); m_client->didSendData(bytesSent, totalBytesToBeSent); } void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength) { ASSERT(m_client); - ASSERT_UNUSED(resource, resource == m_resource); + ASSERT_UNUSED(resource, resource == this->resource()); ASSERT(!m_actualRequest); m_client->didDownloadData(dataLength); @@ -276,8 +259,8 @@ void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength void DocumentThreadableLoader::responseReceived(Resource* resource, const ResourceResponse& response) { - ASSERT_UNUSED(resource, resource == m_resource); - didReceiveResponse(m_resource->identifier(), response); + ASSERT_UNUSED(resource, resource == this->resource()); + didReceiveResponse(resource->identifier(), response); } void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response) @@ -286,9 +269,8 @@ void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, cons String accessControlErrorDescription; if (m_actualRequest) { - DocumentLoader* loader = m_document->frame()->loader()->documentLoader(); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(m_document->frame(), identifier, response); - InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, loader, response, m_resource ? m_resource->loader() : 0); + DocumentLoader* loader = m_document->frame()->loader().documentLoader(); + InspectorInstrumentation::didReceiveResourceResponse(m_document->frame(), identifier, loader, response, resource() ? resource()->loader() : 0); if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) { preflightFailure(identifier, response.url().string(), accessControlErrorDescription); @@ -312,7 +294,7 @@ void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, cons } else { if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessControl) { if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) { - m_client->didFailAccessControlCheck(ResourceError(errorDomainWebKitInternal, 0, response.url().string(), accessControlErrorDescription)); + m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, response.url().string(), accessControlErrorDescription)); return; } } @@ -323,8 +305,8 @@ void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, cons void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data, int dataLength) { - ASSERT_UNUSED(resource, resource == m_resource); - didReceiveData(m_resource->identifier(), data, dataLength); + ASSERT(resource == this->resource()); + didReceiveData(resource->identifier(), data, dataLength); } void DocumentThreadableLoader::didReceiveData(unsigned long identifier, const char* data, int dataLength) @@ -343,20 +325,20 @@ void DocumentThreadableLoader::didReceiveData(unsigned long identifier, const ch void DocumentThreadableLoader::notifyFinished(Resource* resource) { ASSERT(m_client); - ASSERT_UNUSED(resource, resource == m_resource); + ASSERT(resource == this->resource()); m_timeoutTimer.stop(); - if (m_resource->errorOccurred()) - didFail(m_resource->identifier(), m_resource->resourceError()); + if (resource->errorOccurred()) + didFail(resource->identifier(), resource->resourceError()); else - didFinishLoading(m_resource->identifier(), m_resource->loadFinishTime()); + didFinishLoading(resource->identifier(), resource->loadFinishTime()); } void DocumentThreadableLoader::didFinishLoading(unsigned long identifier, double finishTime) { if (m_actualRequest) { - InspectorInstrumentation::didFinishLoading(m_document->frame(), identifier, m_document->frame()->loader()->documentLoader(), finishTime); + InspectorInstrumentation::didFinishLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), finishTime); ASSERT(!m_sameOriginRequest); ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); preflightSuccess(); @@ -367,7 +349,7 @@ void DocumentThreadableLoader::didFinishLoading(unsigned long identifier, double void DocumentThreadableLoader::didFail(unsigned long identifier, const ResourceError& error) { if (m_actualRequest) - InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader()->documentLoader(), error); + InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), error); m_client->didFail(error); } @@ -379,7 +361,7 @@ void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer // Using values from net/base/net_error_list.h ERR_TIMED_OUT, // Same as existing FIXME above - this error should be coming from FrameLoaderClient to be identifiable. static const int timeoutError = -7; - ResourceError error("net", timeoutError, m_resource->url(), String()); + ResourceError error("net", timeoutError, resource()->url(), String()); error.setIsTimeout(true); cancelWithError(error); } @@ -399,9 +381,9 @@ void DocumentThreadableLoader::preflightSuccess() void DocumentThreadableLoader::preflightFailure(unsigned long identifier, const String& url, const String& errorDescription) { - ResourceError error(errorDomainWebKitInternal, 0, url, errorDescription); + ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription); if (m_actualRequest) - InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader()->documentLoader(), error); + InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), error); m_actualRequest = nullptr; // Prevent didFinishLoading() from bypassing access check. m_client->didFailAccessControlCheck(error); } @@ -429,14 +411,11 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0); FetchRequest newRequest(request, m_options.initiator, options); - ASSERT(!m_resource); - m_resource = m_document->fetcher()->fetchRawResource(newRequest); - if (m_resource) { - if (m_resource->loader()) { - unsigned long identifier = m_resource->identifier(); - InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); - } - m_resource->addClient(this); + ASSERT(!resource()); + setResource(m_document->fetcher()->fetchRawResource(newRequest)); + if (resource() && resource()->loader()) { + unsigned long identifier = resource()->identifier(); + InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client); } return; } diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h index df0e851f5aa..3eadc624f31 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h @@ -33,10 +33,10 @@ #define DocumentThreadableLoader_h #include "core/fetch/RawResource.h" -#include "core/fetch/ResourcePtr.h" +#include "core/fetch/ResourceOwner.h" #include "core/loader/ThreadableLoader.h" -#include "core/platform/Timer.h" -#include "core/platform/network/ResourceError.h" +#include "platform/Timer.h" +#include "platform/network/ResourceError.h" #include "wtf/Forward.h" #include "wtf/OwnPtr.h" #include "wtf/PassRefPtr.h" @@ -51,7 +51,7 @@ class ResourceRequest; class SecurityOrigin; class ThreadableLoaderClient; -class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, public ThreadableLoader, private RawResourceClient { +class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, public ThreadableLoader, private ResourceOwner<RawResource> { WTF_MAKE_FAST_ALLOCATED; public: static void loadResourceSynchronously(Document*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&); @@ -76,8 +76,6 @@ class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, pu DocumentThreadableLoader(Document*, ThreadableLoaderClient*, BlockingBehavior, const ResourceRequest&, const ThreadableLoaderOptions&); - void clearResource(); - // RawResourceClient virtual void dataSent(Resource*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent); virtual void responseReceived(Resource*, const ResourceResponse&); @@ -105,7 +103,6 @@ class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, pu SecurityOrigin* securityOrigin() const; bool checkCrossOriginAccessRedirectionUrl(const KURL&, String& errorDescription); - ResourcePtr<RawResource> m_resource; ThreadableLoaderClient* m_client; Document* m_document; ThreadableLoaderOptions m_options; diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp index 61e19f1f1ff..349da64347d 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp @@ -34,24 +34,23 @@ #include "core/fetch/TextResourceDecoder.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderStateMachine.h" -#include "core/page/DOMWindow.h" -#include "core/page/Frame.h" -#include "core/page/FrameView.h" -#include "core/page/Settings.h" -#include "weborigin/KURL.h" -#include "weborigin/SecurityOrigin.h" +#include "core/frame/DOMWindow.h" +#include "core/frame/Frame.h" +#include "core/frame/FrameView.h" +#include "core/frame/Settings.h" +#include "platform/weborigin/KURL.h" +#include "platform/weborigin/SecurityOrigin.h" #include "wtf/PassOwnPtr.h" namespace WebCore { -PassRefPtr<DocumentWriter> DocumentWriter::create(Document* document, const String& mimeType, const String& encoding, bool encodingUserChoosen) +PassRefPtr<DocumentWriter> DocumentWriter::create(Document* document, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen) { return adoptRef(new DocumentWriter(document, mimeType, encoding, encodingUserChoosen)); } -DocumentWriter::DocumentWriter(Document* document, const String& mimeType, const String& encoding, bool encodingUserChoosen) +DocumentWriter::DocumentWriter(Document* document, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen) : m_document(document) - , m_hasReceivedSomeData(false) , m_decoderBuilder(mimeType, encoding, encodingUserChoosen) // We grab a reference to the parser so that we'll always send data to the // original parser, even if the document acquires a new parser (e.g., via @@ -70,8 +69,6 @@ DocumentWriter::~DocumentWriter() void DocumentWriter::appendReplacingData(const String& source) { - ASSERT(!m_hasReceivedSomeData); - m_hasReceivedSomeData = true; m_document->setCompatibilityMode(Document::NoQuirksMode); // FIXME: This should call DocumentParser::appendBytes instead of append @@ -81,29 +78,20 @@ void DocumentWriter::appendReplacingData(const String& source) // Because we're pinned to the main thread we don't need to worry about // passing ownership of the source string. parser->append(source.impl()); + parser->setHasAppendedData(); } } -void DocumentWriter::reportDataReceived() -{ - ASSERT(m_decoder); - if (m_hasReceivedSomeData) - return; - m_hasReceivedSomeData = true; - if (m_decoder->encoding().usesVisualOrdering()) - m_document->setVisuallyOrdered(); -} - void DocumentWriter::addData(const char* bytes, size_t length) { ASSERT(m_parser); - if (!m_decoder && m_parser->needsDecoder() && 0 < length) - m_decoder = m_decoderBuilder.buildFor(m_document); + if (m_parser->needsDecoder() && 0 < length) { + OwnPtr<TextResourceDecoder> decoder = m_decoderBuilder.buildFor(m_document); + m_parser->setDecoder(decoder.release()); + } // appendBytes() can result replacing DocumentLoader::m_writer. RefPtr<DocumentWriter> protectingThis(this); - size_t consumedChars = m_parser->appendBytes(bytes, length); - if (consumedChars) - reportDataReceived(); + m_parser->appendBytes(bytes, length); } void DocumentWriter::end() @@ -118,13 +106,14 @@ void DocumentWriter::end() if (!m_parser) return; - if (!m_decoder && m_parser->needsDecoder()) - m_decoder = m_decoderBuilder.buildFor(m_document); + if (m_parser->needsDecoder()) { + OwnPtr<TextResourceDecoder> decoder = m_decoderBuilder.buildFor(m_document); + m_parser->setDecoder(decoder.release()); + } // flush() can result replacing DocumentLoader::m_writer. RefPtr<DocumentWriter> protectingThis(this); - size_t consumedChars = m_parser->flush(); - if (consumedChars) - reportDataReceived(); + m_parser->flush(); + if (!m_parser) return; @@ -133,6 +122,13 @@ void DocumentWriter::end() m_document = 0; } +void DocumentWriter::setUserChosenEncoding(const String& charset) +{ + TextResourceDecoder* decoder = m_parser->decoder(); + if (decoder) + decoder->setEncoding(charset, TextResourceDecoder::UserChosenEncoding); +} + void DocumentWriter::setDocumentWasLoadedAsPartOfNavigation() { ASSERT(m_parser && !m_parser->isStopped()); diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h index f3da31f112b..4e79045a1e9 100644 --- a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h +++ b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h @@ -45,7 +45,7 @@ class TextResourceDecoder; class DocumentWriter : public RefCounted<DocumentWriter> { WTF_MAKE_NONCOPYABLE(DocumentWriter); public: - static PassRefPtr<DocumentWriter> create(Document*, const String& mimeType = "", const String& encoding = "", bool encodingUserChoosen = false); + static PassRefPtr<DocumentWriter> create(Document*, const AtomicString& mimeType = emptyAtom, const AtomicString& encoding = emptyAtom, bool encodingUserChoosen = false); ~DocumentWriter(); @@ -57,27 +57,25 @@ public: void addData(const char* bytes, size_t length); - const String& mimeType() const { return m_decoderBuilder.mimeType(); } - const String& encoding() const { return m_decoderBuilder.encoding(); } + const AtomicString& mimeType() const { return m_decoderBuilder.mimeType(); } + const AtomicString& encoding() const { return m_decoderBuilder.encoding(); } bool encodingWasChosenByUser() const { return m_decoderBuilder.encodingWasChosenByUser(); } - // Exposed for DocumentParser::appendBytes. - void reportDataReceived(); // Exposed for DocumentLoader::replaceDocument. void appendReplacingData(const String&); + void setUserChosenEncoding(const String& charset); + void setDocumentWasLoadedAsPartOfNavigation(); private: - DocumentWriter(Document*, const String& mimeType, const String& encoding, bool encodingUserChoosen); + DocumentWriter(Document*, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen); PassRefPtr<Document> createDocument(const KURL&); Document* m_document; - bool m_hasReceivedSomeData; TextResourceDecoderBuilder m_decoderBuilder; - RefPtr<TextResourceDecoder> m_decoder; RefPtr<DocumentParser> m_parser; }; diff --git a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp index cacba5b8f1a..78fbce00c1d 100644 --- a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp @@ -31,10 +31,12 @@ #include "core/html/HTMLFormElement.h" #include "core/loader/DocumentLoader.h" #include "core/loader/FormState.h" -#include "core/page/Frame.h" -#include "core/platform/ColorChooser.h" -#include "core/platform/DateTimeChooser.h" -#include "core/platform/FileChooser.h" +#include "core/frame/Frame.h" +#include "platform/ColorChooser.h" +#include "platform/DateTimeChooser.h" +#include "platform/FileChooser.h" +#include "public/platform/WebServiceWorkerProvider.h" +#include "public/platform/WebServiceWorkerProviderClient.h" namespace WebCore { @@ -57,6 +59,9 @@ void fillWithEmptyClients(Page::PageClients& pageClients) static BackForwardClient* dummyBackForwardClient = adoptPtr(new EmptyBackForwardClient).leakPtr(); pageClients.backForwardClient = dummyBackForwardClient; + + static SpellCheckerClient* dummySpellCheckerClient = adoptPtr(new EmptySpellCheckerClient).leakPtr(); + pageClients.spellCheckerClient = dummySpellCheckerClient; } class EmptyPopupMenu : public PopupMenu { @@ -82,6 +87,10 @@ PassRefPtr<DateTimeChooser> EmptyChromeClient::openDateTimeChooser(DateTimeChoos return PassRefPtr<DateTimeChooser>(); } +void EmptyChromeClient::openTextDataListChooser(HTMLInputElement&) +{ +} + void EmptyChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser>) { } @@ -128,16 +137,13 @@ void EmptyTextCheckerClient::requestCheckingOfString(PassRefPtr<TextCheckingRequ { } -void EmptyEditorClient::registerUndoStep(PassRefPtr<UndoStep>) -{ -} - -void EmptyEditorClient::registerRedoStep(PassRefPtr<UndoStep>) +void EmptyFrameLoaderClient::didRequestAutocomplete(PassRefPtr<FormState>) { } -void EmptyFrameLoaderClient::didRequestAutocomplete(PassRefPtr<FormState>) +PassOwnPtr<blink::WebServiceWorkerProvider> EmptyFrameLoaderClient::createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) { + return nullptr; } } diff --git a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h index ed1cb5a3e18..ce31e022eaa 100644 --- a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h @@ -29,20 +29,21 @@ #ifndef EmptyClients_h #define EmptyClients_h -#include "core/dom/DeviceOrientationClient.h" -#include "core/history/BackForwardClient.h" +#include "core/editing/UndoStep.h" #include "core/inspector/InspectorClient.h" #include "core/loader/FrameLoaderClient.h" +#include "core/page/BackForwardClient.h" #include "core/page/ChromeClient.h" #include "core/page/ContextMenuClient.h" #include "core/page/DragClient.h" #include "core/page/EditorClient.h" #include "core/page/FocusDirection.h" #include "core/page/Page.h" +#include "core/page/SpellCheckerClient.h" #include "core/platform/DragImage.h" -#include "core/platform/graphics/FloatRect.h" -#include "core/platform/network/ResourceError.h" -#include "core/platform/text/TextCheckerClient.h" +#include "platform/geometry/FloatRect.h" +#include "platform/network/ResourceError.h" +#include "platform/text/TextCheckerClient.h" #include "public/platform/WebScreenInfo.h" #include "wtf/Forward.h" @@ -84,7 +85,7 @@ public: virtual void takeFocus(FocusDirection) OVERRIDE { } virtual void focusedNodeChanged(Node*) OVERRIDE { } - virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy) OVERRIDE { return 0; } + virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) OVERRIDE { return 0; } virtual void show(NavigationPolicy) OVERRIDE { } virtual bool canRunModal() OVERRIDE { return false; } @@ -134,9 +135,11 @@ public: virtual void scroll(const IntSize&, const IntRect&, const IntRect&) OVERRIDE { } virtual void scheduleAnimation() OVERRIDE { } + virtual bool isCompositorFramePending() const OVERRIDE { return false; } + virtual IntPoint screenToRootView(const IntPoint& p) const OVERRIDE { return p; } virtual IntRect rootViewToScreen(const IntRect& r) const OVERRIDE { return r; } - virtual WebKit::WebScreenInfo screenInfo() const OVERRIDE { return WebKit::WebScreenInfo(); } + virtual blink::WebScreenInfo screenInfo() const OVERRIDE { return blink::WebScreenInfo(); } virtual void contentsSizeChanged(Frame*, const IntSize&) const OVERRIDE { } virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned) OVERRIDE { } @@ -148,8 +151,8 @@ public: virtual void enumerateChosenDirectory(FileChooser*) OVERRIDE { } virtual PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color&) OVERRIDE; - virtual PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) OVERRIDE; + virtual void openTextDataListChooser(HTMLInputElement&) OVERRIDE; virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) OVERRIDE; @@ -161,6 +164,7 @@ public: virtual void scheduleCompositingLayerFlush() OVERRIDE { } virtual void needTouchEvents(bool) OVERRIDE { } + virtual void setTouchAction(TouchAction touchAction) OVERRIDE { }; virtual void numWheelEventHandlersChanged(unsigned) OVERRIDE { } @@ -201,12 +205,12 @@ public: virtual void dispatchDidStartProvisionalLoad() OVERRIDE { } virtual void dispatchDidReceiveTitle(const String&) OVERRIDE { } virtual void dispatchDidChangeIcons(IconType) OVERRIDE { } - virtual void dispatchDidCommitLoad() OVERRIDE { } + virtual void dispatchDidCommitLoad(Frame*, HistoryItem*, NavigationHistoryPolicy) OVERRIDE { } virtual void dispatchDidFailProvisionalLoad(const ResourceError&) OVERRIDE { } virtual void dispatchDidFailLoad(const ResourceError&) OVERRIDE { } virtual void dispatchDidFinishDocumentLoad() OVERRIDE { } virtual void dispatchDidFinishLoad() OVERRIDE { } - virtual void dispatchDidLayout(LayoutMilestones) OVERRIDE { } + virtual void dispatchDidFirstVisuallyNonEmptyLayout() OVERRIDE { } virtual NavigationPolicy decidePolicyForNavigation(const ResourceRequest&, DocumentLoader*, NavigationPolicy) OVERRIDE; @@ -227,11 +231,12 @@ public: virtual void transitionToCommittedForNewPage() OVERRIDE { } - virtual void navigateBackForward(int offset) const OVERRIDE { } + virtual bool navigateBackForward(int offset) const OVERRIDE { return false; } virtual void didDisplayInsecureContent() OVERRIDE { } virtual void didRunInsecureContent(SecurityOrigin*, const KURL&) OVERRIDE { } virtual void didDetectXSS(const KURL&, bool) OVERRIDE { } virtual void didDispatchPingLoader(const KURL&) OVERRIDE { } + virtual void selectorMatchChanged(const Vector<String>&, const Vector<String>&) OVERRIDE { } virtual PassRefPtr<Frame> createFrame(const KURL&, const String&, const String&, HTMLFrameOwnerElement*) OVERRIDE; virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) OVERRIDE; virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) OVERRIDE; @@ -245,10 +250,10 @@ public: virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) OVERRIDE { } virtual bool allowScriptExtension(const String& extensionName, int extensionGroup, int worldId) OVERRIDE { return false; } - virtual WebKit::WebCookieJar* cookieJar() const { return 0; } + virtual blink::WebCookieJar* cookieJar() const { return 0; } virtual void didRequestAutocomplete(PassRefPtr<FormState>) OVERRIDE; - virtual WebKit::WebServiceWorkerRegistry* serviceWorkerRegistry() OVERRIDE { return 0; } + virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) OVERRIDE; }; class EmptyTextCheckerClient : public TextCheckerClient { @@ -260,63 +265,42 @@ public: virtual void requestCheckingOfString(PassRefPtr<TextCheckingRequest>) OVERRIDE; }; -class EmptyEditorClient : public EditorClient { - WTF_MAKE_NONCOPYABLE(EmptyEditorClient); WTF_MAKE_FAST_ALLOCATED; +class EmptySpellCheckerClient : public SpellCheckerClient { + WTF_MAKE_NONCOPYABLE(EmptySpellCheckerClient); WTF_MAKE_FAST_ALLOCATED; public: - EmptyEditorClient() { } - virtual ~EmptyEditorClient() { } + EmptySpellCheckerClient() { } + virtual ~EmptySpellCheckerClient() { } - virtual bool shouldDeleteRange(Range*) OVERRIDE { return false; } - virtual bool smartInsertDeleteEnabled() OVERRIDE { return false; } - virtual bool isSelectTrailingWhitespaceEnabled() OVERRIDE { return false; } virtual bool isContinuousSpellCheckingEnabled() OVERRIDE { return false; } virtual void toggleContinuousSpellChecking() OVERRIDE { } virtual bool isGrammarCheckingEnabled() OVERRIDE { return false; } - virtual bool shouldBeginEditing(Range*) OVERRIDE { return false; } - virtual bool shouldEndEditing(Range*) OVERRIDE { return false; } - virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction) OVERRIDE { return false; } - virtual bool shouldInsertText(const String&, Range*, EditorInsertAction) OVERRIDE { return false; } - virtual bool shouldChangeSelectedRange(Range*, Range*, EAffinity, bool) OVERRIDE { return false; } - - virtual bool shouldApplyStyle(StylePropertySet*, Range*) OVERRIDE { return false; } - - virtual void didBeginEditing() OVERRIDE { } - virtual void respondToChangedContents() OVERRIDE { } - virtual void respondToChangedSelection(Frame*) OVERRIDE { } - virtual void didEndEditing() OVERRIDE { } - virtual void didCancelCompositionOnSelectionChange() OVERRIDE { } - - virtual void registerUndoStep(PassRefPtr<UndoStep>) OVERRIDE; - virtual void registerRedoStep(PassRefPtr<UndoStep>) OVERRIDE; - virtual void clearUndoRedoOperations() OVERRIDE { } - - virtual bool canCopyCut(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; } - virtual bool canPaste(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; } - virtual bool canUndo() const OVERRIDE { return false; } - virtual bool canRedo() const OVERRIDE { return false; } - - virtual void undo() OVERRIDE { } - virtual void redo() OVERRIDE { } - - virtual void handleKeyboardEvent(KeyboardEvent*) OVERRIDE { } - - virtual void textFieldDidEndEditing(Element*) OVERRIDE { } - virtual void textDidChangeInTextField(Element*) OVERRIDE { } - virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*) OVERRIDE { return false; } - TextCheckerClient& textChecker() { return m_textCheckerClient; } virtual void updateSpellingUIWithMisspelledWord(const String&) OVERRIDE { } virtual void showSpellingUI(bool) OVERRIDE { } virtual bool spellingUIIsShowing() OVERRIDE { return false; } - virtual void willSetInputMethodState() OVERRIDE { } - private: EmptyTextCheckerClient m_textCheckerClient; }; +class EmptyEditorClient : public EditorClient { + WTF_MAKE_NONCOPYABLE(EmptyEditorClient); WTF_MAKE_FAST_ALLOCATED; +public: + EmptyEditorClient() { } + virtual ~EmptyEditorClient() { } + + virtual void respondToChangedContents() OVERRIDE { } + virtual void respondToChangedSelection(SelectionType) OVERRIDE { } + + virtual bool canCopyCut(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; } + virtual bool canPaste(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; } + + virtual void didExecuteCommand(String) OVERRIDE { } + virtual bool handleKeyboardEvent() OVERRIDE { return false; } +}; + class EmptyContextMenuClient : public ContextMenuClient { WTF_MAKE_NONCOPYABLE(EmptyContextMenuClient); WTF_MAKE_FAST_ALLOCATED; public: @@ -345,24 +329,11 @@ public: virtual void hideHighlight() OVERRIDE { } }; -class EmptyDeviceClient : public DeviceClient { -public: - virtual void startUpdating() OVERRIDE { } - virtual void stopUpdating() OVERRIDE { } -}; - -class EmptyDeviceOrientationClient : public DeviceOrientationClient { -public: - virtual void setController(DeviceOrientationController*) OVERRIDE { } - virtual DeviceOrientationData* lastOrientation() const OVERRIDE { return 0; } - virtual void deviceOrientationControllerDestroyed() OVERRIDE { } -}; - class EmptyBackForwardClient : public BackForwardClient { public: - virtual void didAddItem() OVERRIDE { } virtual int backListCount() OVERRIDE { return 0; } virtual int forwardListCount() OVERRIDE { return 0; } + virtual int backForwardListCount() OVERRIDE { return 0; } }; void fillWithEmptyClients(Page::PageClients&); diff --git a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp index d427f0b1da6..178a996bc76 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp @@ -32,18 +32,18 @@ #include "core/loader/FormSubmission.h" #include "HTMLNames.h" +#include "RuntimeEnabledFeatures.h" #include "core/dom/Document.h" -#include "core/dom/Event.h" +#include "core/events/Event.h" #include "core/html/DOMFormData.h" #include "core/html/HTMLFormControlElement.h" #include "core/html/HTMLFormElement.h" #include "core/html/HTMLInputElement.h" #include "core/html/parser/HTMLParserIdioms.h" -#include "core/loader/FormState.h" #include "core/loader/FrameLoadRequest.h" #include "core/loader/FrameLoader.h" -#include "core/platform/network/FormData.h" -#include "core/platform/network/FormDataBuilder.h" +#include "platform/network/FormData.h" +#include "platform/network/FormDataBuilder.h" #include "wtf/CurrentTime.h" #include "wtf/text/TextEncoding.h" @@ -103,7 +103,11 @@ void FormSubmission::Attributes::updateEncodingType(const String& type) FormSubmission::Method FormSubmission::Attributes::parseMethodType(const String& type) { - return equalIgnoringCase(type, "post") ? FormSubmission::PostMethod : FormSubmission::GetMethod; + if (equalIgnoringCase(type, "post")) + return FormSubmission::PostMethod; + if (RuntimeEnabledFeatures::dialogElementEnabled() && equalIgnoringCase(type, "dialog")) + return FormSubmission::DialogMethod; + return FormSubmission::GetMethod; } void FormSubmission::Attributes::updateMethodType(const String& type) @@ -111,6 +115,20 @@ void FormSubmission::Attributes::updateMethodType(const String& type) m_method = parseMethodType(type); } +String FormSubmission::Attributes::methodString(Method method) +{ + switch (method) { + case GetMethod: + return "get"; + case PostMethod: + return "post"; + case DialogMethod: + return "dialog"; + } + ASSERT_NOT_REACHED(); + return emptyString(); +} + void FormSubmission::Attributes::copyFrom(const Attributes& other) { m_method = other.m_method; @@ -134,6 +152,12 @@ inline FormSubmission::FormSubmission(Method method, const KURL& action, const S { } +inline FormSubmission::FormSubmission(const String& result) + : m_method(DialogMethod) + , m_result(result) +{ +} + PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, FormSubmissionTrigger trigger) { ASSERT(form); @@ -152,16 +176,19 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A copiedAttributes.copyFrom(attributes); if (submitButton) { String attributeValue; - if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull()) + if (!(attributeValue = submitButton->fastGetAttribute(formactionAttr)).isNull()) copiedAttributes.parseAction(attributeValue); - if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull()) + if (!(attributeValue = submitButton->fastGetAttribute(formenctypeAttr)).isNull()) copiedAttributes.updateEncodingType(attributeValue); - if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull()) + if (!(attributeValue = submitButton->fastGetAttribute(formmethodAttr)).isNull()) copiedAttributes.updateMethodType(attributeValue); - if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull()) + if (!(attributeValue = submitButton->fastGetAttribute(formtargetAttr)).isNull()) copiedAttributes.setTarget(attributeValue); } + if (copiedAttributes.method() == DialogMethod) + return adoptRef(new FormSubmission(submitButton->resultForDialogSubmit())); + Document& document = form->document(); KURL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action()); bool isMailtoForm = actionURL.protocolIs("mailto"); @@ -175,8 +202,7 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A isMultiPartForm = false; } } - - WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), &document); + WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document.inputEncoding(), document.defaultCharset()); RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission()); Vector<pair<String, String> > formValues; @@ -199,10 +225,10 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A String boundary; if (isMultiPartForm) { - formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), &document); + formData = domFormData->createMultiPartFormData(domFormData->encoding()); boundary = formData->boundary().data(); } else { - formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType)); + formData = domFormData->createFormData(domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType)); if (copiedAttributes.method() == PostMethod && isMailtoForm) { // Convert the form data into a string that we put into the URL. appendMailtoPostFormDataToURL(actionURL, *formData, encodingType); diff --git a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h index 8731bac3ecb..d53b2e686ec 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h +++ b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h @@ -32,7 +32,7 @@ #define FormSubmission_h #include "core/loader/FormState.h" -#include "weborigin/KURL.h" +#include "platform/weborigin/KURL.h" namespace WTF{ class TextEncoding; @@ -48,7 +48,7 @@ class HTMLFormElement; class FormSubmission : public RefCounted<FormSubmission> { public: - enum Method { GetMethod, PostMethod }; + enum Method { GetMethod, PostMethod, DialogMethod }; class Attributes { WTF_MAKE_NONCOPYABLE(Attributes); @@ -63,7 +63,7 @@ public: Method method() const { return m_method; } static Method parseMethodType(const String&); void updateMethodType(const String&); - static String methodString(Method method) { return method == PostMethod ? "post" : "get"; } + static String methodString(Method); const String& action() const { return m_action; } void parseAction(const String&); @@ -112,8 +112,12 @@ public: const String& origin() const { return m_origin; } void setOrigin(const String& origin) { m_origin = origin; } + const String& result() const { return m_result; } + private: FormSubmission(Method, const KURL& action, const String& target, const String& contentType, PassRefPtr<FormState>, PassRefPtr<FormData>, const String& boundary, PassRefPtr<Event>); + // FormSubmission for DialogMethod + FormSubmission(const String& result); // FIXME: Hold an instance of Attributes instead of individual members. Method m_method; @@ -126,6 +130,7 @@ private: RefPtr<Event> m_event; String m_referrer; String m_origin; + String m_result; }; } diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 387f13a8a25..a74ad9be373 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp @@ -31,15 +31,16 @@ #include "config.h" #include "core/loader/FrameFetchContext.h" +#include "core/dom/Document.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/loader/DocumentLoader.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" #include "core/loader/ProgressTracker.h" -#include "core/page/Frame.h" +#include "core/frame/Frame.h" #include "core/page/Page.h" -#include "core/page/Settings.h" -#include "weborigin/SecurityPolicy.h" +#include "core/frame/Settings.h" +#include "platform/weborigin/SecurityPolicy.h" namespace WebCore { @@ -55,16 +56,12 @@ void FrameFetchContext::reportLocalLoadFailed(const KURL& url) void FrameFetchContext::addAdditionalRequestHeaders(Document& document, ResourceRequest& request, Resource::Type type) { - bool isMainResource = type == Resource::MainResource; - - FrameLoader* frameLoader = m_frame->loader(); - - if (!isMainResource) { + if (type != Resource::MainResource) { String outgoingReferrer; String outgoingOrigin; if (request.httpReferrer().isNull()) { - outgoingReferrer = frameLoader->outgoingReferrer(); - outgoingOrigin = frameLoader->outgoingOrigin(); + outgoingReferrer = document.outgoingReferrer(); + outgoingOrigin = document.outgoingOrigin(); } else { outgoingReferrer = request.httpReferrer(); outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString(); @@ -79,16 +76,30 @@ void FrameFetchContext::addAdditionalRequestHeaders(Document& document, Resource FrameLoader::addHTTPOriginIfNeeded(request, outgoingOrigin); } - frameLoader->addExtraFieldsToRequest(request); + m_frame->loader().addExtraFieldsToRequest(request); } -CachePolicy FrameFetchContext::cachePolicy(Resource::Type type) const +CachePolicy FrameFetchContext::cachePolicy(Document* document) const { - if (type != Resource::MainResource) - return m_frame->loader()->subresourceCachePolicy(); + if (document && document->loadEventFinished()) + return CachePolicyVerify; - if (m_frame->loader()->loadType() == FrameLoadTypeReloadFromOrigin || m_frame->loader()->loadType() == FrameLoadTypeReload) + FrameLoadType loadType = m_frame->loader().loadType(); + if (loadType == FrameLoadTypeReloadFromOrigin) return CachePolicyReload; + + if (Frame* parentFrame = m_frame->tree().parent()) { + CachePolicy parentCachePolicy = parentFrame->loader().fetchContext().cachePolicy(parentFrame->document()); + if (parentCachePolicy != CachePolicyVerify) + return parentCachePolicy; + } + + if (loadType == FrameLoadTypeReload) + return CachePolicyRevalidate; + + DocumentLoader* loader = document ? document->loader() : 0; + if (loader && loader->request().cachePolicy() == ReturnCacheDataElseLoad) + return CachePolicyHistoryBuffer; return CachePolicyVerify; } @@ -99,33 +110,32 @@ CachePolicy FrameFetchContext::cachePolicy(Resource::Type type) const // cannot see imported documents. inline DocumentLoader* FrameFetchContext::ensureLoader(DocumentLoader* loader) { - return loader ? loader : m_frame->loader()->activeDocumentLoader(); + return loader ? loader : m_frame->loader().activeDocumentLoader(); } void FrameFetchContext::dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority loadPriority) { - m_frame->loader()->client()->dispatchDidChangeResourcePriority(identifier, loadPriority); + m_frame->loader().client()->dispatchDidChangeResourcePriority(identifier, loadPriority); } void FrameFetchContext::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& initiatorInfo) { - m_frame->loader()->applyUserAgent(request); - m_frame->loader()->client()->dispatchWillSendRequest(loader, identifier, request, redirectResponse); + m_frame->loader().applyUserAgent(request); + m_frame->loader().client()->dispatchWillSendRequest(loader, identifier, request, redirectResponse); InspectorInstrumentation::willSendRequest(m_frame, identifier, ensureLoader(loader), request, redirectResponse, initiatorInfo); } void FrameFetchContext::dispatchDidLoadResourceFromMemoryCache(const ResourceRequest& request, const ResourceResponse& response) { - m_frame->loader()->client()->dispatchDidLoadResourceFromMemoryCache(request, response); + m_frame->loader().client()->dispatchDidLoadResourceFromMemoryCache(request, response); } void FrameFetchContext::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r, ResourceLoader* resourceLoader) { if (Page* page = m_frame->page()) page->progress().incrementProgress(identifier, r); - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceResponse(m_frame, identifier, r); - m_frame->loader()->client()->dispatchDidReceiveResponse(loader, identifier, r); - InspectorInstrumentation::didReceiveResourceResponse(cookie, identifier, ensureLoader(loader), r, resourceLoader); + m_frame->loader().client()->dispatchDidReceiveResponse(loader, identifier, r); + InspectorInstrumentation::didReceiveResourceResponse(m_frame, identifier, ensureLoader(loader), r, resourceLoader); } void FrameFetchContext::dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) @@ -135,11 +145,18 @@ void FrameFetchContext::dispatchDidReceiveData(DocumentLoader*, unsigned long id InspectorInstrumentation::didReceiveData(m_frame, identifier, data, dataLength, encodedDataLength); } +void FrameFetchContext::dispatchDidDownloadData(DocumentLoader*, unsigned long identifier, int dataLength, int encodedDataLength) +{ + if (Page* page = m_frame->page()) + page->progress().incrementProgress(identifier, 0, dataLength); + InspectorInstrumentation::didReceiveData(m_frame, identifier, 0, dataLength, encodedDataLength); +} + void FrameFetchContext::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, double finishTime) { if (Page* page = m_frame->page()) page->progress().completeProgress(identifier); - m_frame->loader()->client()->dispatchDidFinishLoading(loader, identifier); + m_frame->loader().client()->dispatchDidFinishLoading(loader, identifier); InspectorInstrumentation::didFinishLoading(m_frame, identifier, ensureLoader(loader), finishTime); } @@ -151,18 +168,15 @@ void FrameFetchContext::dispatchDidFail(DocumentLoader* loader, unsigned long id InspectorInstrumentation::didFailLoading(m_frame, identifier, ensureLoader(loader), error); } -void FrameFetchContext::sendRemainingDelegateMessages(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const char* data, int dataLength, int encodedDataLength, const ResourceError& error) +void FrameFetchContext::sendRemainingDelegateMessages(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, int dataLength) { if (!response.isNull()) dispatchDidReceiveResponse(ensureLoader(loader), identifier, response); if (dataLength > 0) - dispatchDidReceiveData(ensureLoader(loader), identifier, data, dataLength, encodedDataLength); + dispatchDidReceiveData(ensureLoader(loader), identifier, 0, dataLength, 0); - if (error.isNull()) - dispatchDidFinishLoading(ensureLoader(loader), identifier, 0); - else - dispatchDidFail(ensureLoader(loader), identifier, error); + dispatchDidFinishLoading(ensureLoader(loader), identifier, 0); } } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h index 77a92afb05a..f8a2050fd8d 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h +++ b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h @@ -32,11 +32,12 @@ #define FrameFetchContext_h #include "core/fetch/FetchContext.h" -#include "core/platform/network/ResourceRequest.h" +#include "platform/network/ResourceRequest.h" #include "wtf/PassOwnPtr.h" namespace WebCore { +class Document; class DocumentLoader; class Frame; class Page; @@ -51,15 +52,16 @@ public: virtual void reportLocalLoadFailed(const KURL&) OVERRIDE; virtual void addAdditionalRequestHeaders(Document&, ResourceRequest&, Resource::Type) OVERRIDE; - virtual CachePolicy cachePolicy(Resource::Type) const OVERRIDE; + virtual CachePolicy cachePolicy(Document*) const OVERRIDE; virtual void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority); virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& = FetchInitiatorInfo()) OVERRIDE; virtual void dispatchDidLoadResourceFromMemoryCache(const ResourceRequest&, const ResourceResponse&) OVERRIDE; virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, ResourceLoader* = 0) OVERRIDE; - virtual void dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) OVERRIDE; + virtual void dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) OVERRIDE; + virtual void dispatchDidDownloadData(DocumentLoader*, unsigned long identifier, int dataLength, int encodedDataLength) OVERRIDE; virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, double finishTime) OVERRIDE; virtual void dispatchDidFail(DocumentLoader*, unsigned long identifier, const ResourceError&) OVERRIDE; - virtual void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const char* data, int dataLength, int encodedDataLength, const ResourceError&) OVERRIDE; + virtual void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, int dataLength) OVERRIDE; private: explicit FrameFetchContext(Frame*); diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h index 7d3e4daaf79..5f854f83f6a 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h @@ -26,56 +26,56 @@ #ifndef FrameLoadRequest_h #define FrameLoadRequest_h -#include "core/dom/Event.h" +#include "core/dom/Document.h" +#include "core/events/Event.h" #include "core/html/HTMLFormElement.h" #include "core/loader/FrameLoaderTypes.h" #include "core/loader/SubstituteData.h" -#include "weborigin/SecurityOrigin.h" -#include "core/platform/network/ResourceRequest.h" +#include "platform/network/ResourceRequest.h" namespace WebCore { class Frame; struct FrameLoadRequest { public: - explicit FrameLoadRequest(SecurityOrigin* requester) - : m_requester(requester) + explicit FrameLoadRequest(Document* originDocument) + : m_originDocument(originDocument) , m_lockBackForwardList(false) - , m_clientRedirect(false) + , m_clientRedirect(NotClientRedirect) , m_shouldSendReferrer(MaybeSendReferrer) { } - FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest) - : m_requester(requester) + FrameLoadRequest(Document* originDocument, const ResourceRequest& resourceRequest) + : m_originDocument(originDocument) , m_resourceRequest(resourceRequest) , m_lockBackForwardList(false) - , m_clientRedirect(false) + , m_clientRedirect(NotClientRedirect) , m_shouldSendReferrer(MaybeSendReferrer) { } - FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest, const String& frameName) - : m_requester(requester) + FrameLoadRequest(Document* originDocument, const ResourceRequest& resourceRequest, const String& frameName) + : m_originDocument(originDocument) , m_resourceRequest(resourceRequest) , m_frameName(frameName) , m_lockBackForwardList(false) - , m_clientRedirect(false) + , m_clientRedirect(NotClientRedirect) , m_shouldSendReferrer(MaybeSendReferrer) { } - FrameLoadRequest(SecurityOrigin* requester, const ResourceRequest& resourceRequest, const SubstituteData& substituteData) - : m_requester(requester) + FrameLoadRequest(Document* originDocument, const ResourceRequest& resourceRequest, const SubstituteData& substituteData) + : m_originDocument(originDocument) , m_resourceRequest(resourceRequest) , m_substituteData(substituteData) , m_lockBackForwardList(false) - , m_clientRedirect(false) + , m_clientRedirect(NotClientRedirect) , m_shouldSendReferrer(MaybeSendReferrer) { } - const SecurityOrigin* requester() const { return m_requester.get(); } + Document* originDocument() const { return m_originDocument.get(); } ResourceRequest& resourceRequest() { return m_resourceRequest; } const ResourceRequest& resourceRequest() const { return m_resourceRequest; } @@ -88,8 +88,8 @@ public: bool lockBackForwardList() const { return m_lockBackForwardList; } void setLockBackForwardList(bool lockBackForwardList) { m_lockBackForwardList = lockBackForwardList; } - bool clientRedirect() const { return m_clientRedirect; } - void setClientRedirect(bool clientRedirect) { m_clientRedirect = clientRedirect; } + ClientRedirectPolicy clientRedirect() const { return m_clientRedirect; } + void setClientRedirect(ClientRedirectPolicy clientRedirect) { m_clientRedirect = clientRedirect; } Event* triggeringEvent() const { return m_triggeringEvent.get(); } void setTriggeringEvent(PassRefPtr<Event> triggeringEvent) { m_triggeringEvent = triggeringEvent; } @@ -101,12 +101,12 @@ public: void setShouldSendReferrer(ShouldSendReferrer shouldSendReferrer) { m_shouldSendReferrer = shouldSendReferrer; } private: - RefPtr<SecurityOrigin> m_requester; + RefPtr<Document> m_originDocument; ResourceRequest m_resourceRequest; String m_frameName; SubstituteData m_substituteData; bool m_lockBackForwardList; - bool m_clientRedirect; + ClientRedirectPolicy m_clientRedirect; RefPtr<Event> m_triggeringEvent; RefPtr<FormState> m_formState; ShouldSendReferrer m_shouldSendReferrer; diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 511588a8102..b32c0c08e3a 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp @@ -41,15 +41,19 @@ #include "bindings/v8/SerializedScriptValue.h" #include "core/dom/Document.h" #include "core/dom/Element.h" -#include "core/dom/Event.h" -#include "core/dom/EventNames.h" -#include "core/dom/PageTransitionEvent.h" #include "core/editing/Editor.h" +#include "core/editing/UndoStack.h" +#include "core/events/Event.h" +#include "core/events/PageTransitionEvent.h" +#include "core/events/ThreadLocalEventNames.h" #include "core/fetch/FetchContext.h" #include "core/fetch/ResourceFetcher.h" #include "core/fetch/ResourceLoader.h" -#include "core/history/BackForwardController.h" -#include "core/history/HistoryItem.h" +#include "core/frame/ContentSecurityPolicy.h" +#include "core/frame/ContentSecurityPolicyResponseHeaders.h" +#include "core/frame/DOMWindow.h" +#include "core/frame/Frame.h" +#include "core/frame/FrameView.h" #include "core/html/HTMLFormElement.h" #include "core/html/HTMLFrameOwnerElement.h" #include "core/html/parser/HTMLParserIdioms.h" @@ -62,31 +66,29 @@ #include "core/loader/FrameFetchContext.h" #include "core/loader/FrameLoadRequest.h" #include "core/loader/FrameLoaderClient.h" -#include "core/loader/IconController.h" #include "core/loader/ProgressTracker.h" #include "core/loader/UniqueIdentifier.h" #include "core/loader/appcache/ApplicationCacheHost.h" +#include "core/page/BackForwardClient.h" #include "core/page/Chrome.h" #include "core/page/ChromeClient.h" -#include "core/page/ContentSecurityPolicy.h" -#include "core/page/ContentSecurityPolicyResponseHeaders.h" -#include "core/page/DOMWindow.h" +#include "core/page/CreateWindow.h" #include "core/page/EventHandler.h" -#include "core/page/Frame.h" #include "core/page/FrameTree.h" -#include "core/page/FrameView.h" #include "core/page/Page.h" -#include "core/page/Settings.h" +#include "core/frame/Settings.h" #include "core/page/WindowFeatures.h" -#include "core/platform/Logging.h" -#include "core/platform/ScrollAnimator.h" -#include "core/platform/graphics/FloatRect.h" -#include "core/platform/network/HTTPParsers.h" -#include "core/platform/network/ResourceRequest.h" +#include "core/page/scrolling/ScrollingCoordinator.h" #include "core/xml/parser/XMLDocumentParser.h" #include "modules/webdatabase/DatabaseManager.h" -#include "weborigin/SecurityOrigin.h" -#include "weborigin/SecurityPolicy.h" +#include "platform/Logging.h" +#include "platform/UserGestureIndicator.h" +#include "platform/geometry/FloatRect.h" +#include "platform/network/HTTPParsers.h" +#include "platform/network/ResourceRequest.h" +#include "platform/scroll/ScrollAnimator.h" +#include "platform/weborigin/SecurityOrigin.h" +#include "platform/weborigin/SecurityPolicy.h" #include "wtf/TemporaryChange.h" #include "wtf/text/CString.h" #include "wtf/text/WTFString.h" @@ -102,17 +104,6 @@ bool isBackForwardLoadType(FrameLoadType type) return type == FrameLoadTypeBackForward; } -// This is not in the FrameLoader class to emphasize that it does not depend on -// private FrameLoader data, and to avoid increasing the number of public functions -// with access to private data. Since only this .cpp file needs it, making it -// non-member lets us exclude it from the header file, thus keeping core/loader/FrameLoader.h's -// API simpler. -// -static bool isDocumentSandboxed(Frame* frame, SandboxFlags mask) -{ - return frame->document() && frame->document()->isSandboxed(mask); -} - class FrameLoader::FrameProgressTracker { public: static PassOwnPtr<FrameProgressTracker> create(Frame* frame) { return adoptPtr(new FrameProgressTracker(frame)); } @@ -153,22 +144,17 @@ private: FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) : m_frame(frame) , m_client(client) - , m_history(frame) - , m_icon(adoptPtr(new IconController(frame))) - , m_fetchContext(FrameFetchContext::create(frame)) , m_mixedContentChecker(frame) , m_state(FrameStateProvisional) , m_loadType(FrameLoadTypeStandard) + , m_fetchContext(FrameFetchContext::create(frame)) , m_inStopAllLoaders(false) , m_isComplete(false) - , m_containsPlugins(false) , m_checkTimer(this, &FrameLoader::checkTimerFired) , m_shouldCallCheckCompleted(false) , m_opener(0) , m_didAccessInitialDocument(false) , m_didAccessInitialDocumentTimer(this, &FrameLoader::didAccessInitialDocumentTimerFired) - , m_suppressOpenerInNewFrame(false) - , m_startingClientRedirect(false) , m_forcedSandboxFlags(SandboxNone) { } @@ -179,7 +165,7 @@ FrameLoader::~FrameLoader() HashSet<Frame*>::iterator end = m_openedFrames.end(); for (HashSet<Frame*>::iterator it = m_openedFrames.begin(); it != end; ++it) - (*it)->loader()->m_opener = 0; + (*it)->loader().m_opener = 0; m_client->frameLoaderDestroyed(); } @@ -203,10 +189,9 @@ void FrameLoader::setDefersLoading(bool defers) m_provisionalDocumentLoader->setDefersLoading(defers); if (m_policyDocumentLoader) m_policyDocumentLoader->setDefersLoading(defers); - history()->setDefersLoading(defers); if (!defers) { - m_frame->navigationScheduler()->startTimer(); + m_frame->navigationScheduler().startTimer(); startCheckCompleteTimer(); } } @@ -230,19 +215,50 @@ void FrameLoader::stopLoading() } // FIXME: This will cancel redirection timer, which really needs to be restarted when restoring the frame from b/f cache. - m_frame->navigationScheduler()->cancel(); + m_frame->navigationScheduler().cancel(); +} + +void FrameLoader::saveDocumentAndScrollState() +{ + if (!m_currentItem) + return; + + Document* document = m_frame->document(); + if (m_currentItem->isCurrentDocument(document) && document->isActive()) + m_currentItem->setDocumentState(document->formElementsState()); + + if (!m_frame->view()) + return; + + m_currentItem->setScrollPoint(m_frame->view()->scrollPosition()); + if (m_frame->isMainFrame() && !m_frame->page()->inspectorController().deviceEmulationEnabled()) + m_currentItem->setPageScaleFactor(m_frame->page()->pageScaleFactor()); +} + +void FrameLoader::clearScrollPositionAndViewState() +{ + ASSERT(m_frame->isMainFrame()); + if (!m_currentItem) + return; + m_currentItem->clearScrollPoint(); + m_currentItem->setPageScaleFactor(0); } bool FrameLoader::closeURL() { - history()->saveDocumentState(); + // This is done when a back/forward navigation begins (and the current item + // changes) in loadHistoryItem(). Saving now will save the state will save + // to the wrong item if the navigation is back/forward. + if (m_loadType != FrameLoadTypeBackForward) + saveDocumentAndScrollState(); // Should only send the pagehide event here if the current document exists. if (m_frame->document()) m_frame->document()->dispatchUnloadEvents(); stopLoading(); - m_frame->editor().clearUndoRedoOperations(); + if (Page* page = m_frame->page()) + page->undoStack().didUnloadFrame(*m_frame); return true; } @@ -258,7 +274,7 @@ void FrameLoader::didExplicitOpen() // from a subsequent window.document.open / window.document.write call. // Canceling redirection here works for all cases because document.open // implicitly precedes document.write. - m_frame->navigationScheduler()->cancel(); + m_frame->navigationScheduler().cancel(); } void FrameLoader::clear(ClearOptions options) @@ -268,21 +284,18 @@ void FrameLoader::clear(ClearOptions options) m_frame->editor().clear(); m_frame->document()->cancelParsing(); - m_frame->document()->stopActiveDOMObjects(); - if (m_frame->document()->attached()) { - m_frame->document()->prepareForDestruction(); - m_frame->document()->removeFocusedElementOfSubtree(m_frame->document()); - } + m_frame->document()->prepareForDestruction(); + m_frame->document()->removeFocusedElementOfSubtree(m_frame->document()); // Do this after detaching the document so that the unload event works. if (options & ClearWindowProperties) { InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame->domWindow()); m_frame->domWindow()->reset(); - m_frame->script()->clearWindowShell(); + m_frame->script().clearWindowShell(); } m_frame->selection().prepareForDestruction(); - m_frame->eventHandler()->clear(); + m_frame->eventHandler().clear(); if (m_frame->view()) m_frame->view()->clear(); @@ -292,14 +305,12 @@ void FrameLoader::clear(ClearOptions options) m_frame->setDOMWindow(0); } - m_containsPlugins = false; - if (options & ClearScriptObjects) - m_frame->script()->clearScriptObjects(); + m_frame->script().clearScriptObjects(); - m_frame->script()->enableEval(); + m_frame->script().enableEval(); - m_frame->navigationScheduler()->clear(); + m_frame->navigationScheduler().clear(); m_checkTimer.stop(); m_shouldCallCheckCompleted = false; @@ -308,28 +319,53 @@ void FrameLoader::clear(ClearOptions options) m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad); } +void FrameLoader::setHistoryItemStateForCommit(HistoryItemPolicy historyItemPolicy) +{ + if (!m_currentItem || historyItemPolicy == CreateNewHistoryItem || m_currentItem->url() != m_documentLoader->url()) { + if (!m_currentItem || historyItemPolicy == CreateNewHistoryItem) + m_currentItem = HistoryItem::create(); + else + m_currentItem->reset(); + const KURL& unreachableURL = m_documentLoader->unreachableURL(); + const KURL& url = unreachableURL.isEmpty() ? m_documentLoader->requestURL() : unreachableURL; + const KURL& originalURL = unreachableURL.isEmpty() ? m_documentLoader->originalURL() : unreachableURL; + m_currentItem->setURL(url); + m_currentItem->setTarget(m_frame->tree().uniqueName()); + m_currentItem->setTargetFrameID(m_frame->frameID()); + m_currentItem->setOriginalURLString(originalURL.string()); + } + m_currentItem->setFormInfoFromRequest(m_documentLoader->request()); +} + void FrameLoader::receivedFirstData() { if (m_stateMachine.creatingInitialEmptyDocument()) return; - m_client->dispatchDidCommitLoad(); + NavigationHistoryPolicy navigationHistoryPolicy = NavigationReusedHistoryEntry; + if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isURLValidForNewHistoryEntry()) + navigationHistoryPolicy = NavigationCreatedHistoryEntry; + HistoryItemPolicy historyItemPolicy = DoNotCreateNewHistoryItem; + if (m_loadType == FrameLoadTypeInitialInChildFrame || navigationHistoryPolicy == NavigationCreatedHistoryEntry) + historyItemPolicy = CreateNewHistoryItem; + setHistoryItemStateForCommit(historyItemPolicy); + + if (!m_stateMachine.committedMultipleRealLoads() && navigationHistoryPolicy == NavigationCreatedHistoryEntry) + m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealLoads); + + m_client->dispatchDidCommitLoad(m_frame, m_currentItem.get(), navigationHistoryPolicy); + InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get()); m_frame->page()->didCommitLoad(m_frame); dispatchDidClearWindowObjectsInAllWorlds(); } -void FrameLoader::setOutgoingReferrer(const KURL& url) -{ - m_outgoingReferrer = url.strippedForUseAsReferrer(); -} - void FrameLoader::didBeginDocument(bool dispatch) { m_isComplete = false; m_frame->document()->setReadyState(Document::Loading); - if (history()->currentItem() && m_loadType == FrameLoadTypeBackForward) - m_frame->document()->statePopped(history()->currentItem()->stateObject()); + if (m_currentItem && m_loadType == FrameLoadTypeBackForward) + m_frame->domWindow()->statePopped(m_currentItem->stateObject()); if (dispatch) dispatchDidClearWindowObjectsInAllWorlds(); @@ -338,12 +374,12 @@ void FrameLoader::didBeginDocument(bool dispatch) Settings* settings = m_frame->document()->settings(); if (settings) { - m_frame->document()->fetcher()->setImagesEnabled(settings->areImagesEnabled()); + m_frame->document()->fetcher()->setImagesEnabled(settings->imagesEnabled()); m_frame->document()->fetcher()->setAutoLoadImages(settings->loadsImagesAutomatically()); } if (m_documentLoader) { - String dnsPrefetchControl = m_documentLoader->response().httpHeaderField("X-DNS-Prefetch-Control"); + const AtomicString& dnsPrefetchControl = m_documentLoader->response().httpHeaderField("X-DNS-Prefetch-Control"); if (!dnsPrefetchControl.isEmpty()) m_frame->document()->parseDNSPrefetchControlHeader(dnsPrefetchControl); @@ -353,11 +389,12 @@ void FrameLoader::didBeginDocument(bool dispatch) headerContentLanguage.truncate(commaIndex); // kNotFound == -1 == don't truncate headerContentLanguage = headerContentLanguage.stripWhiteSpace(isHTMLSpace<UChar>); if (!headerContentLanguage.isEmpty()) - m_frame->document()->setContentLanguage(headerContentLanguage); + m_frame->document()->setContentLanguage(AtomicString(headerContentLanguage)); } } - history()->restoreDocumentState(); + if (m_currentItem && m_loadType == FrameLoadTypeBackForward) + m_frame->document()->setStateForNewFormElements(m_currentItem->documentState()); } void FrameLoader::finishedParsing() @@ -390,8 +427,8 @@ void FrameLoader::loadDone() bool FrameLoader::allChildrenAreComplete() const { - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { - if (!child->loader()->m_isComplete) + for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) { + if (!child->loader().m_isComplete) return false; } return true; @@ -399,7 +436,7 @@ bool FrameLoader::allChildrenAreComplete() const bool FrameLoader::allAncestorsAreComplete() const { - for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree()->parent()) { + for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent()) { if (!ancestor->document()->loadEventFinished()) return false; } @@ -436,12 +473,11 @@ void FrameLoader::checkCompleted() // OK, completed. m_isComplete = true; - m_requestedHistoryItem = 0; m_frame->document()->setReadyState(Document::Complete); if (m_frame->document()->loadEventStillNeeded()) m_frame->document()->implicitClose(); - m_frame->navigationScheduler()->startTimer(); + m_frame->navigationScheduler().startTimer(); completed(); if (m_frame->page()) @@ -478,25 +514,6 @@ void FrameLoader::scheduleCheckCompleted() startCheckCompleteTimer(); } -String FrameLoader::outgoingReferrer() const -{ - // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources - // for why we walk the parent chain for srcdoc documents. - Frame* frame = m_frame; - while (frame->document()->isSrcdocDocument()) { - frame = frame->tree()->parent(); - // Srcdoc documents cannot be top-level documents, by definition, - // because they need to be contained in iframes with the srcdoc. - ASSERT(frame); - } - return frame->loader()->m_outgoingReferrer; -} - -String FrameLoader::outgoingOrigin() const -{ - return m_frame->document()->securityOrigin()->toString(); -} - Frame* FrameLoader::opener() { return m_opener; @@ -508,9 +525,9 @@ void FrameLoader::setOpener(Frame* opener) m_client->didDisownOpener(); if (m_opener) - m_opener->loader()->m_openedFrames.remove(m_frame); + m_opener->loader().m_openedFrames.remove(m_frame); if (opener) - opener->loader()->m_openedFrames.add(m_frame); + opener->loader().m_openedFrames.add(m_frame); m_opener = opener; if (m_frame->document()) @@ -520,34 +537,17 @@ void FrameLoader::setOpener(Frame* opener) bool FrameLoader::allowPlugins(ReasonForCallingAllowPlugins reason) { Settings* settings = m_frame->settings(); - bool allowed = m_client->allowPlugins(settings && settings->arePluginsEnabled()); + bool allowed = m_client->allowPlugins(settings && settings->pluginsEnabled()); if (!allowed && reason == AboutToInstantiatePlugin) m_client->didNotAllowPlugins(); return allowed; } -void FrameLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocumentNavigationSource sameDocumentNavigationSource, PassRefPtr<SerializedScriptValue> data, const String& title, UpdateBackForwardListPolicy updateBackForwardList) +void FrameLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocumentNavigationSource sameDocumentNavigationSource, PassRefPtr<SerializedScriptValue> data, UpdateBackForwardListPolicy updateBackForwardList) { // Update the data source's request with the new URL to fake the URL change - KURL oldURL = m_frame->document()->url(); m_frame->document()->setURL(newURL); - setOutgoingReferrer(newURL); - documentLoader()->replaceRequestURLForSameDocumentNavigation(newURL); - - // updateBackForwardListForFragmentScroll() must happen after - // replaceRequestURLForSameDocumentNavigation(), since we add based on - // the current request. - if (updateBackForwardList == UpdateBackForwardList) - history()->updateBackForwardListForFragmentScroll(); - - if (sameDocumentNavigationSource == SameDocumentNavigationDefault) - history()->updateForSameDocumentNavigation(); - else if (sameDocumentNavigationSource == SameDocumentNavigationPushState) - history()->pushState(data, title, newURL.string()); - else if (sameDocumentNavigationSource == SameDocumentNavigationReplaceState) - history()->replaceState(data, title, newURL.string()); - else - ASSERT_NOT_REACHED(); + documentLoader()->updateForSameDocumentNavigation(newURL); // Generate start and stop notifications only when loader is completed so that we // don't fire them for fragment redirection that happens in window.onload handler. @@ -555,19 +555,28 @@ void FrameLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocume if (m_frame->document()->loadEventFinished()) m_client->postProgressStartedNotification(); - m_documentLoader->clearRedirectChain(); - if (m_documentLoader->isClientRedirect()) - m_documentLoader->appendRedirect(oldURL); - m_documentLoader->appendRedirect(newURL); - - m_client->dispatchDidNavigateWithinPage(); + NavigationHistoryPolicy navigationHistoryPolicy = NavigationReusedHistoryEntry; + if (updateBackForwardList == UpdateBackForwardList || (sameDocumentNavigationSource == SameDocumentNavigationPushState && m_currentItem)) { + navigationHistoryPolicy = NavigationCreatedHistoryEntry; + setHistoryItemStateForCommit(CreateNewHistoryItem); + } + m_client->dispatchDidNavigateWithinPage(navigationHistoryPolicy, m_currentItem.get()); m_client->dispatchDidReceiveTitle(m_frame->document()->title()); + if (m_currentItem) { + m_currentItem->setURL(newURL); + if (sameDocumentNavigationSource != SameDocumentNavigationDefault) { + m_currentItem->setStateObject(data); + m_currentItem->setFormData(0); + m_currentItem->setFormContentType(nullAtom); + } + } + if (m_frame->document()->loadEventFinished()) m_client->postProgressFinishedNotification(); } -void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation) +void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation, ClientRedirectPolicy clientRedirect) { // If we have a state object, we cannot also be a new navigation. ASSERT(!stateObject || (stateObject && !isNewNavigation)); @@ -576,13 +585,13 @@ void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip // If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor bool hashChange = equalIgnoringFragmentIdentifier(url, oldURL) && url.fragmentIdentifier() != oldURL.fragmentIdentifier(); if (hashChange) { - m_frame->eventHandler()->stopAutoscrollTimer(); - m_frame->document()->enqueueHashchangeEvent(oldURL, url); + m_frame->eventHandler().stopAutoscroll(); + m_frame->domWindow()->enqueueHashchangeEvent(oldURL, url); } - m_documentLoader->setIsClientRedirect((m_startingClientRedirect && !isNewNavigation) || !UserGestureIndicator::processingUserGesture()); + m_documentLoader->setIsClientRedirect((clientRedirect == ClientRedirect && !isNewNavigation) || !UserGestureIndicator::processingUserGesture()); m_documentLoader->setReplacesCurrentHistoryItem(!isNewNavigation); UpdateBackForwardListPolicy updateBackForwardList = isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject ? UpdateBackForwardList : DoNotUpdateBackForwardList; - updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, 0, String(), updateBackForwardList); + updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, 0, updateBackForwardList); // It's important to model this as a load that starts and immediately finishes. // Otherwise, the parent frame may think we never finished loading. @@ -595,18 +604,18 @@ void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip m_isComplete = false; checkCompleted(); - m_frame->document()->statePopped(stateObject ? stateObject : SerializedScriptValue::nullValue()); + m_frame->domWindow()->statePopped(stateObject ? stateObject : SerializedScriptValue::nullValue()); } void FrameLoader::completed() { RefPtr<Frame> protect(m_frame); - for (Frame* descendant = m_frame->tree()->traverseNext(m_frame); descendant; descendant = descendant->tree()->traverseNext(m_frame)) - descendant->navigationScheduler()->startTimer(); + for (Frame* descendant = m_frame->tree().traverseNext(m_frame); descendant; descendant = descendant->tree().traverseNext(m_frame)) + descendant->navigationScheduler().startTimer(); - if (Frame* parent = m_frame->tree()->parent()) - parent->loader()->checkCompleted(); + if (Frame* parent = m_frame->tree().parent()) + parent->loader().checkCompleted(); if (m_frame->view()) m_frame->view()->maintainScrollPositionAtAnchor(0); @@ -614,35 +623,24 @@ void FrameLoader::completed() void FrameLoader::started() { - for (Frame* frame = m_frame; frame; frame = frame->tree()->parent()) - frame->loader()->m_isComplete = false; + for (Frame* frame = m_frame; frame; frame = frame->tree().parent()) + frame->loader().m_isComplete = false; } -void FrameLoader::prepareForHistoryNavigation() -{ - // If there is no currentItem, but we still want to engage in - // history navigation we need to manufacture one, and update - // the state machine of this frame to impersonate having - // loaded it. - RefPtr<HistoryItem> currentItem = history()->currentItem(); - if (!currentItem) { - insertDummyHistoryItem(); - ASSERT(stateMachine()->isDisplayingInitialEmptyDocument()); - stateMachine()->advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad); - } -} - -void FrameLoader::setReferrerForFrameRequest(ResourceRequest& request, ShouldSendReferrer shouldSendReferrer) +void FrameLoader::setReferrerForFrameRequest(ResourceRequest& request, ShouldSendReferrer shouldSendReferrer, Document* originDocument) { if (shouldSendReferrer == NeverSendReferrer) { request.clearHTTPReferrer(); return; } + // Always use the initiating document to generate the referrer. + // We need to generateReferrerHeader(), because we might not have enforced ReferrerPolicy or https->http + // referrer suppression yet. String argsReferrer(request.httpReferrer()); if (argsReferrer.isEmpty()) - argsReferrer = outgoingReferrer(); - String referrer = SecurityPolicy::generateReferrerHeader(m_frame->document()->referrerPolicy(), request.url(), argsReferrer); + argsReferrer = originDocument->outgoingReferrer(); + String referrer = SecurityPolicy::generateReferrerHeader(originDocument->referrerPolicy(), request.url(), argsReferrer); request.setHTTPReferrer(referrer); RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer); @@ -654,20 +652,22 @@ bool FrameLoader::isScriptTriggeredFormSubmissionInChildFrame(const FrameLoadReq // If this is a child frame and the form submission was triggered by a script, lock the back/forward list // to match IE and Opera. // See https://bugs.webkit.org/show_bug.cgi?id=32383 for the original motivation for this. - if (!m_frame->tree()->parent() || ScriptController::processingUserGesture()) + if (!m_frame->tree().parent() || UserGestureIndicator::processingUserGesture()) return false; return request.formState() && request.formState()->formSubmissionTrigger() == SubmittedByJavaScript; } FrameLoadType FrameLoader::determineFrameLoadType(const FrameLoadRequest& request) { - if (m_frame->tree()->parent() && !m_stateMachine.startedFirstRealLoad()) + if (m_frame->tree().parent() && !m_stateMachine.startedFirstRealLoad()) return FrameLoadTypeInitialInChildFrame; + if (!m_frame->tree().parent() && !m_frame->page()->backForward().backForwardListCount()) + return FrameLoadTypeStandard; if (request.resourceRequest().cachePolicy() == ReloadIgnoringCacheData) return FrameLoadTypeReload; if (request.lockBackForwardList() || isScriptTriggeredFormSubmissionInChildFrame(request)) return FrameLoadTypeRedirectWithLockedBackForwardList; - if (!request.requester() && shouldTreatURLAsSameAsCurrent(request.resourceRequest().url())) + if (!request.originDocument() && shouldTreatURLAsSameAsCurrent(request.resourceRequest().url())) return FrameLoadTypeSame; if (shouldTreatURLAsSameAsCurrent(request.substituteData().failingURL()) && m_loadType == FrameLoadTypeReload) return FrameLoadTypeReload; @@ -676,44 +676,28 @@ FrameLoadType FrameLoader::determineFrameLoadType(const FrameLoadRequest& reques bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request) { - // If no SecurityOrigin was specified, skip security checks and assume the caller has fully initialized the FrameLoadRequest. - if (!request.requester()) + // If no origin Document* was specified, skip security checks and assume the caller has fully initialized the FrameLoadRequest. + if (!request.originDocument()) return true; KURL url = request.resourceRequest().url(); - if (m_frame->script()->executeScriptIfJavaScriptURL(url)) + if (m_frame->script().executeScriptIfJavaScriptURL(url)) return false; - if (!request.requester()->canDisplay(url)) { + if (!request.originDocument()->securityOrigin()->canDisplay(url)) { reportLocalLoadFailed(m_frame, url.elidedString()); return false; } - if (request.requester() && !request.formState() && request.frameName().isEmpty()) + if (!request.formState() && request.frameName().isEmpty()) request.setFrameName(m_frame->document()->baseTarget()); - // If the requesting SecurityOrigin is not this Frame's SecurityOrigin, the request was initiated by a different frame that should - // have already set the referrer. - if (request.requester() == m_frame->document()->securityOrigin()) - setReferrerForFrameRequest(request.resourceRequest(), request.shouldSendReferrer()); + setReferrerForFrameRequest(request.resourceRequest(), request.shouldSendReferrer(), request.originDocument()); return true; } -static bool shouldOpenInNewWindow(Frame* targetFrame, const FrameLoadRequest& request, const NavigationAction& action) -{ - if (!targetFrame && !request.frameName().isEmpty()) - return true; - if (!request.formState()) - return false; - NavigationPolicy navigationPolicy = NavigationPolicyCurrentTab; - if (!action.specifiesNavigationPolicy(&navigationPolicy)) - return false; - return navigationPolicy != NavigationPolicyCurrentTab; -} - void FrameLoader::load(const FrameLoadRequest& passedRequest) { - ASSERT(!m_suppressOpenerInNewFrame); ASSERT(m_frame->document()); // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader. @@ -726,10 +710,10 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest) if (!prepareRequestForThisFrame(request)) return; - RefPtr<Frame> targetFrame = findFrameForNavigation(request.frameName(), request.formState() ? request.formState()->sourceDocument() : m_frame->document()); + RefPtr<Frame> targetFrame = request.formState() ? 0 : findFrameForNavigation(request.frameName(), request.formState() ? request.formState()->sourceDocument() : m_frame->document()); if (targetFrame && targetFrame != m_frame) { request.setFrameName("_self"); - targetFrame->loader()->load(request); + targetFrame->loader().load(request); if (Page* page = targetFrame->page()) page->chrome().focus(); return; @@ -737,19 +721,20 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest) FrameLoadType newLoadType = determineFrameLoadType(request); NavigationAction action(request.resourceRequest(), newLoadType, request.formState(), request.triggeringEvent()); - if (shouldOpenInNewWindow(targetFrame.get(), request, action)) { - TemporaryChange<bool> changeOpener(m_suppressOpenerInNewFrame, request.shouldSendReferrer() == NeverSendReferrer); - checkNewWindowPolicyAndContinue(request.formState(), request.frameName(), action); + if ((!targetFrame && !request.frameName().isEmpty()) || action.shouldOpenInNewWindow()) { + if (action.policy() == NavigationPolicyDownload) + m_client->loadURLExternally(action.resourceRequest(), NavigationPolicyDownload); + else + createWindowForRequest(request, m_frame, action.policy(), request.shouldSendReferrer()); return; } - TemporaryChange<bool> changeClientRedirect(m_startingClientRedirect, request.clientRedirect()); if (shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, request.resourceRequest().url())) { - checkNavigationPolicyAndContinueFragmentScroll(action, newLoadType != FrameLoadTypeRedirectWithLockedBackForwardList); + checkNavigationPolicyAndContinueFragmentScroll(action, newLoadType != FrameLoadTypeRedirectWithLockedBackForwardList, request.clientRedirect()); return; } bool sameURL = shouldTreatURLAsSameAsCurrent(request.resourceRequest().url()); - loadWithNavigationAction(request.resourceRequest(), action, newLoadType, request.formState(), request.substituteData()); + loadWithNavigationAction(action, newLoadType, request.formState(), request.substituteData(), request.clientRedirect()); // Example of this case are sites that reload the same URL with a different cookie // driving the generated content, or a master frame with links that drive a target // frame, where the user has clicked on the same link repeatedly. @@ -776,16 +761,12 @@ void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url) frame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Not allowed to load local resource: " + url); } -void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, const String& overrideEncoding) +void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, const AtomicString& overrideEncoding) { DocumentLoader* documentLoader = activeDocumentLoader(); if (!documentLoader) return; - if (m_state == FrameStateProvisional) - insertDummyHistoryItem(); - frame()->loader()->history()->saveDocumentAndScrollState(); - ResourceRequest request = documentLoader->request(); // FIXME: We need to reset cache policy to prevent it from being incorrectly propagted to the reload. // Do we need to propagate anything other than the url? @@ -797,10 +778,10 @@ void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, con FrameLoadType type = reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload; NavigationAction action(request, type, request.httpMethod() == "POST"); - loadWithNavigationAction(request, action, type, 0, SubstituteData(), overrideEncoding); + loadWithNavigationAction(action, type, 0, SubstituteData(), NotClientRedirect, overrideEncoding); } -void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy) +void FrameLoader::stopAllLoaders() { if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) return; @@ -815,13 +796,8 @@ void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem m_inStopAllLoaders = true; - // If no new load is in progress, we should clear the provisional item from history - // before we call stopLoading. - if (clearProvisionalItemPolicy == ShouldClearProvisionalItem) - history()->setProvisionalItem(0); - - for (RefPtr<Frame> child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->loader()->stopAllLoaders(clearProvisionalItemPolicy); + for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) + child->loader().stopAllLoaders(); if (m_provisionalDocumentLoader) m_provisionalDocumentLoader->stopLoading(); if (m_documentLoader) @@ -834,6 +810,8 @@ void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem m_checkTimer.stop(); m_inStopAllLoaders = false; + + m_client->didStopAllLoaders(); } DocumentLoader* FrameLoader::activeDocumentLoader() const @@ -906,10 +884,8 @@ void FrameLoader::commitProvisionalLoad() if (isLoadingMainFrame()) m_frame->page()->chrome().client().needTouchEvents(false); - history()->updateForCommit(); m_client->transitionToCommittedForNewPage(); - - m_frame->navigationScheduler()->cancel(); + m_frame->navigationScheduler().cancel(); m_frame->editor().clearLastEditCommand(); // If we are still in the process of initializing an empty document then @@ -928,8 +904,8 @@ void FrameLoader::closeOldDataSources() // FIXME: Is it important for this traversal to be postorder instead of preorder? // If so, add helpers for postorder traversal, and use them. If not, then lets not // use a recursive algorithm here. - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->loader()->closeOldDataSources(); + for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) + child->loader().closeOldDataSources(); if (m_documentLoader) m_client->dispatchWillClose(); @@ -937,22 +913,21 @@ void FrameLoader::closeOldDataSources() bool FrameLoader::isLoadingMainFrame() const { - Page* page = m_frame->page(); - return page && m_frame == page->mainFrame(); + return m_frame->isMainFrame(); } bool FrameLoader::subframeIsLoading() const { // It's most likely that the last added frame is the last to load so we walk backwards. - for (Frame* child = m_frame->tree()->lastChild(); child; child = child->tree()->previousSibling()) { - FrameLoader* childLoader = child->loader(); - DocumentLoader* documentLoader = childLoader->documentLoader(); + for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling()) { + const FrameLoader& childLoader = child->loader(); + DocumentLoader* documentLoader = childLoader.documentLoader(); if (documentLoader && documentLoader->isLoadingInAPISense()) return true; - documentLoader = childLoader->provisionalDocumentLoader(); + documentLoader = childLoader.provisionalDocumentLoader(); if (documentLoader && documentLoader->isLoadingInAPISense()) return true; - documentLoader = childLoader->policyDocumentLoader(); + documentLoader = childLoader.policyDocumentLoader(); if (documentLoader) return true; } @@ -964,31 +939,6 @@ FrameLoadType FrameLoader::loadType() const return m_loadType; } -CachePolicy FrameLoader::subresourceCachePolicy() const -{ - if (m_frame->document()->loadEventFinished()) - return CachePolicyVerify; - - if (m_loadType == FrameLoadTypeReloadFromOrigin) - return CachePolicyReload; - - if (Frame* parentFrame = m_frame->tree()->parent()) { - CachePolicy parentCachePolicy = parentFrame->loader()->subresourceCachePolicy(); - if (parentCachePolicy != CachePolicyVerify) - return parentCachePolicy; - } - - if (m_loadType == FrameLoadTypeReload) - return CachePolicyRevalidate; - - const ResourceRequest& request(documentLoader()->request()); - - if (request.cachePolicy() == ReturnCacheDataElseLoad) - return CachePolicyHistoryBuffer; - - return CachePolicyVerify; -} - void FrameLoader::checkLoadCompleteForThisFrame() { ASSERT(m_client->hasWebView()); @@ -1005,11 +955,6 @@ void FrameLoader::checkLoadCompleteForThisFrame() m_provisionalDocumentLoader = 0; m_progressTracker->progressCompleted(); m_state = FrameStateComplete; - - // Reset the back forward list to the last committed history item at the top level. - RefPtr<HistoryItem> item = m_frame->page()->mainFrame()->loader()->history()->currentItem(); - if (isBackForwardLoadType(loadType()) && !history()->provisionalItem() && item) - m_frame->page()->backForward().setCurrentItem(item.get()); } if (m_state != FrameStateCommittedPage) @@ -1025,19 +970,12 @@ void FrameLoader::checkLoadCompleteForThisFrame() // the new page is ready. // If the user had a scroll point, scroll to it, overriding the anchor point if any. - if (m_frame->page()) { - if (isBackForwardLoadType(m_loadType) || m_loadType == FrameLoadTypeReload || m_loadType == FrameLoadTypeReloadFromOrigin) - history()->restoreScrollPositionAndViewState(); - } + restoreScrollPositionAndViewState(); if (!m_stateMachine.committedFirstRealDocumentLoad()) return; m_progressTracker->progressCompleted(); - if (Page* page = m_frame->page()) { - if (m_frame == page->mainFrame()) - page->resetRelevantPaintedObjectCounter(); - } const ResourceError& error = m_documentLoader->mainDocumentError(); if (!error.isNull()) @@ -1047,32 +985,56 @@ void FrameLoader::checkLoadCompleteForThisFrame() m_loadType = FrameLoadTypeStandard; } -void FrameLoader::didLayout(LayoutMilestones milestones) +// There is a race condition between the layout and load completion that affects restoring the scroll position. +// We try to restore the scroll position at both the first layout and upon load completion. +// 1) If first layout happens before the load completes, we want to restore the scroll position then so that the +// first time we draw the page is already scrolled to the right place, instead of starting at the top and later +// jumping down. It is possible that the old scroll position is past the part of the doc laid out so far, in +// which case the restore silent fails and we will fix it in when we try to restore on doc completion. +// 2) If the layout happens after the load completes, the attempt to restore at load completion time silently +// fails. We then successfully restore it when the layout happens. +void FrameLoader::restoreScrollPositionAndViewState(RestorePolicy restorePolicy) { - m_client->dispatchDidLayout(milestones); + if (!isBackForwardLoadType(m_loadType) && m_loadType != FrameLoadTypeReload && m_loadType != FrameLoadTypeReloadFromOrigin && restorePolicy != ForcedRestoreForSameDocumentHistoryNavigation) + return; + if (!m_frame->page() || !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad()) + return; + + if (FrameView* view = m_frame->view()) { + if (m_frame->isMainFrame()) { + if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator()) + scrollingCoordinator->frameViewRootLayerDidChange(view); + } + + if (!view->wasScrolledByUser() || restorePolicy == ForcedRestoreForSameDocumentHistoryNavigation) { + if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor()) + m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint()); + else + view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint()); + } + } } void FrameLoader::didFirstLayout() { - if (m_frame->page() && isBackForwardLoadType(m_loadType)) - history()->restoreScrollPositionAndViewState(); + restoreScrollPositionAndViewState(); } void FrameLoader::detachChildren() { typedef Vector<RefPtr<Frame> > FrameVector; FrameVector childrenToDetach; - childrenToDetach.reserveCapacity(m_frame->tree()->childCount()); - for (Frame* child = m_frame->tree()->lastChild(); child; child = child->tree()->previousSibling()) + childrenToDetach.reserveCapacity(m_frame->tree().childCount()); + for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling()) childrenToDetach.append(child); FrameVector::iterator end = childrenToDetach.end(); for (FrameVector::iterator it = childrenToDetach.begin(); it != end; it++) - (*it)->loader()->detachFromParent(); + (*it)->loader().detachFromParent(); } void FrameLoader::closeAndRemoveChild(Frame* child) { - child->tree()->detachFromParent(); + child->tree().detachFromParent(); child->setView(0); if (child->ownerElement() && child->page()) @@ -1080,7 +1042,7 @@ void FrameLoader::closeAndRemoveChild(Frame* child) child->willDetachPage(); child->detachFromPage(); - m_frame->tree()->removeChild(child); + m_frame->tree().removeChild(child); } // Called every time a resource is completely loaded or an error is received. @@ -1092,11 +1054,11 @@ void FrameLoader::checkLoadComplete() // is currently needed in order to null out the previous history item for all frames. if (Page* page = m_frame->page()) { Vector<RefPtr<Frame>, 10> frames; - for (RefPtr<Frame> frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) + for (RefPtr<Frame> frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) frames.append(frame); // To process children before their parents, iterate the vector backwards. for (size_t i = frames.size(); i; --i) - frames[i - 1]->loader()->checkLoadCompleteForThisFrame(); + frames[i - 1]->loader().checkLoadCompleteForThisFrame(); } } @@ -1113,7 +1075,7 @@ int FrameLoader::numPendingOrLoadingRequests(bool recurse) const return m_frame->document()->fetcher()->requestCount(); int count = 0; - for (Frame* frame = m_frame; frame; frame = frame->tree()->traverseNext(m_frame)) + for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext(m_frame)) count += frame->document()->fetcher()->requestCount(); return count; } @@ -1130,7 +1092,6 @@ void FrameLoader::frameDetached() // stopAllLoaders can detach the Frame, so protect it. RefPtr<Frame> protect(m_frame); stopAllLoaders(); - m_frame->document()->stopActiveDOMObjects(); detachFromParent(); } @@ -1140,7 +1101,6 @@ void FrameLoader::detachFromParent() RefPtr<Frame> protect(m_frame); closeURL(); - history()->saveScrollPositionAndViewStateToItem(history()->currentItem()); detachChildren(); // stopAllLoaders() needs to be called after detachChildren(), because detachedChildren() // will trigger the unload event handlers of any child frames, and those event @@ -1156,9 +1116,9 @@ void FrameLoader::detachFromParent() m_progressTracker.clear(); - if (Frame* parent = m_frame->tree()->parent()) { - parent->loader()->closeAndRemoveChild(m_frame); - parent->loader()->scheduleCheckCompleted(); + if (Frame* parent = m_frame->tree().parent()) { + parent->loader().closeAndRemoveChild(m_frame); + parent->loader().scheduleCheckCompleted(); } else { m_frame->setView(0); m_frame->willDetachPage(); @@ -1194,10 +1154,10 @@ void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request) request.setHTTPAccept(defaultAcceptHeader); // Make sure we send the Origin header. - addHTTPOriginIfNeeded(request, String()); + addHTTPOriginIfNeeded(request, nullAtom); } -void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const String& origin) +void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const AtomicString& origin) { if (!request.httpOrigin().isEmpty()) return; // Request already has an Origin header. @@ -1249,7 +1209,7 @@ void FrameLoader::receivedMainResourceError(const ResourceError& error) checkLoadComplete(); } -void FrameLoader::checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction& action, bool isNewNavigation) +void FrameLoader::checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction& action, bool isNewNavigation, ClientRedirectPolicy clientRedirect) { m_documentLoader->setTriggeringAction(action); @@ -1264,7 +1224,8 @@ void FrameLoader::checkNavigationPolicyAndContinueFragmentScroll(const Navigatio m_provisionalDocumentLoader->detachFromFrame(); m_provisionalDocumentLoader = 0; } - loadInSameDocument(request.url(), 0, isNewNavigation); + saveDocumentAndScrollState(); + loadInSameDocument(request.url(), 0, isNewNavigation, clientRedirect); } bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType loadType, const KURL& url) @@ -1310,7 +1271,7 @@ bool FrameLoader::shouldClose() // Store all references to each subframe in advance since beforeunload's event handler may modify frame Vector<RefPtr<Frame> > targetFrames; targetFrames.append(m_frame); - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->traverseNext(m_frame)) + for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().traverseNext(m_frame)) targetFrames.append(child); bool shouldClose = false; @@ -1320,7 +1281,7 @@ bool FrameLoader::shouldClose() bool didAllowNavigation = false; for (i = 0; i < targetFrames.size(); i++) { - if (!targetFrames[i]->tree()->isDescendantOf(m_frame)) + if (!targetFrames[i]->tree().isDescendantOf(m_frame)) continue; if (!targetFrames[i]->document()->dispatchBeforeUnloadEvent(page->chrome(), didAllowNavigation)) break; @@ -1332,7 +1293,7 @@ bool FrameLoader::shouldClose() return shouldClose; } -void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const NavigationAction& action, FrameLoadType type, PassRefPtr<FormState> formState, const SubstituteData& substituteData, const String& overrideEncoding) +void FrameLoader::loadWithNavigationAction(const NavigationAction& action, FrameLoadType type, PassRefPtr<FormState> formState, const SubstituteData& substituteData, ClientRedirectPolicy clientRedirect, const AtomicString& overrideEncoding) { ASSERT(m_client->hasWebView()); if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) @@ -1342,20 +1303,29 @@ void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const // document load because the event would leak subsequent activity by the frame which the parent // frame isn't supposed to learn. For example, if the child frame navigated to a new URL, the // parent frame shouldn't learn the URL. + const ResourceRequest& request = action.resourceRequest(); if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame->ownerElement() && !m_frame->ownerElement()->dispatchBeforeLoadEvent(request.url().string())) return; if (!m_stateMachine.startedFirstRealLoad()) m_stateMachine.advanceTo(FrameLoaderStateMachine::StartedFirstRealLoad); + // The current load should replace the history item if it is the first real + // load of the frame. + bool replacesCurrentHistoryItem = false; + if (type == FrameLoadTypeRedirectWithLockedBackForwardList + || !m_stateMachine.committedFirstRealDocumentLoad()) { + replacesCurrentHistoryItem = true; + } + m_policyDocumentLoader = m_client->createDocumentLoader(request, substituteData.isValid() ? substituteData : defaultSubstituteDataForURL(request.url())); m_policyDocumentLoader->setFrame(m_frame); m_policyDocumentLoader->setTriggeringAction(action); - m_policyDocumentLoader->setReplacesCurrentHistoryItem(type == FrameLoadTypeRedirectWithLockedBackForwardList); - m_policyDocumentLoader->setIsClientRedirect(m_startingClientRedirect); + m_policyDocumentLoader->setReplacesCurrentHistoryItem(replacesCurrentHistoryItem); + m_policyDocumentLoader->setIsClientRedirect(clientRedirect == ClientRedirect); - if (Frame* parent = m_frame->tree()->parent()) - m_policyDocumentLoader->setOverrideEncoding(parent->loader()->documentLoader()->overrideEncoding()); + if (Frame* parent = m_frame->tree().parent()) + m_policyDocumentLoader->setOverrideEncoding(parent->loader().documentLoader()->overrideEncoding()); else if (!overrideEncoding.isEmpty()) m_policyDocumentLoader->setOverrideEncoding(overrideEncoding); else if (m_documentLoader) @@ -1370,7 +1340,7 @@ void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const } // A new navigation is in progress, so don't clear the history's provisional item. - stopAllLoaders(ShouldNotClearProvisionalItem); + stopAllLoaders(); // <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders() // might detach the current FrameLoader, in which case we should bail on this newly defunct load. @@ -1379,7 +1349,7 @@ void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const if (isLoadingMainFrame()) m_frame->page()->inspectorController().resume(); - m_frame->navigationScheduler()->cancel(); + m_frame->navigationScheduler().cancel(); m_provisionalDocumentLoader = m_policyDocumentLoader.release(); m_loadType = type; @@ -1397,54 +1367,6 @@ void FrameLoader::loadWithNavigationAction(const ResourceRequest& request, const m_provisionalDocumentLoader->startLoadingMainResource(); } -void FrameLoader::checkNewWindowPolicyAndContinue(PassRefPtr<FormState> formState, const String& frameName, const NavigationAction& action) -{ - if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) - return; - - if (m_frame->document() && m_frame->document()->isSandboxed(SandboxPopups)) - return; - - if (!DOMWindow::allowPopUp(m_frame)) - return; - - NavigationPolicy navigationPolicy = NavigationPolicyNewForegroundTab; - action.specifiesNavigationPolicy(&navigationPolicy); - - if (navigationPolicy == NavigationPolicyDownload) { - m_client->loadURLExternally(action.resourceRequest(), navigationPolicy); - return; - } - - RefPtr<Frame> frame = m_frame; - RefPtr<Frame> mainFrame = m_frame; - - if (!m_frame->settings() || m_frame->settings()->supportsMultipleWindows()) { - struct WindowFeatures features; - Page* newPage = m_frame->page()->chrome().client().createWindow(m_frame, FrameLoadRequest(m_frame->document()->securityOrigin(), action.resourceRequest()), - features, navigationPolicy); - - // createWindow can return null (e.g., popup blocker denies the window). - if (!newPage) - return; - mainFrame = newPage->mainFrame(); - } - - if (frameName != "_blank") - mainFrame->tree()->setName(frameName); - - mainFrame->page()->setOpenedByDOM(); - mainFrame->page()->chrome().show(navigationPolicy); - if (!m_suppressOpenerInNewFrame) { - mainFrame->loader()->setOpener(frame.get()); - mainFrame->document()->setReferrerPolicy(frame->document()->referrerPolicy()); - } - - // FIXME: We can't just send our NavigationAction to the new FrameLoader's loadWithNavigationAction(), we need to - // create a new one with a default NavigationType and no triggering event. We should figure out why. - mainFrame->loader()->loadWithNavigationAction(action.resourceRequest(), NavigationAction(action.resourceRequest()), FrameLoadTypeStandard, formState, SubstituteData()); -} - void FrameLoader::applyUserAgent(ResourceRequest& request) { String userAgent = this->userAgent(request.url()); @@ -1454,9 +1376,9 @@ void FrameLoader::applyUserAgent(ResourceRequest& request) bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, const KURL& url, unsigned long requestIdentifier) { - UseCounter::count(m_frame->document(), UseCounter::XFrameOptions); + UseCounter::count(m_frame->domWindow(), UseCounter::XFrameOptions); - Frame* topFrame = m_frame->tree()->top(); + Frame* topFrame = m_frame->tree().top(); if (m_frame == topFrame) return false; @@ -1464,13 +1386,13 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con switch (disposition) { case XFrameOptionsSameOrigin: { - UseCounter::count(m_frame->document(), UseCounter::XFrameOptionsSameOrigin); + UseCounter::count(m_frame->domWindow(), UseCounter::XFrameOptionsSameOrigin); RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url); if (!origin->isSameSchemeHostPort(topFrame->document()->securityOrigin())) return true; - for (Frame* frame = m_frame->tree()->parent(); frame; frame = frame->tree()->parent()) { + for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) { if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin())) { - UseCounter::count(m_frame->document(), UseCounter::XFrameOptionsSameOriginWithBadAncestorChain); + UseCounter::count(m_frame->domWindow(), UseCounter::XFrameOptionsSameOriginWithBadAncestorChain); break; } } @@ -1494,9 +1416,9 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con bool FrameLoader::shouldTreatURLAsSameAsCurrent(const KURL& url) const { - if (!history()->currentItem()) + if (!m_currentItem) return false; - return url == history()->currentItem()->url() || url == history()->currentItem()->originalURL(); + return url == m_currentItem->url() || url == m_currentItem->originalURL(); } bool FrameLoader::shouldTreatURLAsSrcdocDocument(const KURL& url) const @@ -1514,7 +1436,7 @@ bool FrameLoader::shouldTreatURLAsSrcdocDocument(const KURL& url) const Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* activeDocument) { ASSERT(activeDocument); - Frame* frame = m_frame->tree()->find(name); + Frame* frame = m_frame->tree().find(name); // From http://www.whatwg.org/specs/web-apps/current-work/#seamlessLinks: // @@ -1526,7 +1448,7 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* a // browsing context flag set, and continue these steps as if that // browsing context was the one that was going to be navigated instead. if (frame == m_frame && name != "_self" && m_frame->document()->shouldDisplaySeamlesslyWithParent()) { - for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree()->parent()) { + for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent()) { if (!ancestor->document()->shouldDisplaySeamlesslyWithParent()) { frame = ancestor; break; @@ -1540,20 +1462,16 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* a return frame; } -void FrameLoader::loadHistoryItem(HistoryItem* item) +void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoadType) { - m_requestedHistoryItem = item; - HistoryItem* currentItem = history()->currentItem(); - - if (currentItem && item->shouldDoSameDocumentNavigationTo(currentItem)) { - history()->setCurrentItem(item); - loadInSameDocument(item->url(), item->stateObject(), false); + saveDocumentAndScrollState(); + m_currentItem = item; + if (historyLoadType == HistorySameDocumentLoad) { + loadInSameDocument(item->url(), item->stateObject(), false, NotClientRedirect); + restoreScrollPositionAndViewState(ForcedRestoreForSameDocumentHistoryNavigation); return; } - // Remember this item so we can traverse any child items as child frames load - history()->setProvisionalItem(item); - RefPtr<FormData> formData = item->formData(); ResourceRequest request(item->url()); request.setHTTPReferrer(item->referrer()); @@ -1565,14 +1483,7 @@ void FrameLoader::loadHistoryItem(HistoryItem* item) addHTTPOriginIfNeeded(request, securityOrigin->toString()); } - loadWithNavigationAction(request, NavigationAction(request, FrameLoadTypeBackForward, formData), FrameLoadTypeBackForward, 0, SubstituteData()); -} - -void FrameLoader::insertDummyHistoryItem() -{ - RefPtr<HistoryItem> currentItem = HistoryItem::create(); - history()->setCurrentItem(currentItem.get()); - frame()->page()->backForward().setCurrentItem(currentItem.get()); + loadWithNavigationAction(NavigationAction(request, FrameLoadTypeBackForward, formData), FrameLoadTypeBackForward, 0, SubstituteData()); } void FrameLoader::dispatchDocumentElementAvailable() @@ -1582,7 +1493,7 @@ void FrameLoader::dispatchDocumentElementAvailable() void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() { - if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript)) + if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript)) return; Vector<RefPtr<DOMWrapperWorld> > worlds; @@ -1593,7 +1504,7 @@ void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) { - if (!m_frame->script()->canExecuteScripts(NotAboutToExecuteScript) || !m_frame->script()->existingWindowShell(world)) + if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame->script().existingWindowShell(world)) return; m_client->dispatchDidClearWindowObjectInWorld(world); @@ -1607,7 +1518,7 @@ void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) SandboxFlags FrameLoader::effectiveSandboxFlags() const { SandboxFlags flags = m_forcedSandboxFlags; - if (Frame* parentFrame = m_frame->tree()->parent()) + if (Frame* parentFrame = m_frame->tree().parent()) flags |= parentFrame->document()->sandboxFlags(); if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement()) flags |= ownerElement->sandboxFlags(); diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h index 98879429e78..7bdedd6c85e 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h @@ -33,15 +33,14 @@ #define FrameLoader_h #include "core/dom/IconURL.h" +#include "core/dom/SandboxFlags.h" #include "core/dom/SecurityContext.h" -#include "core/fetch/CachePolicy.h" #include "core/fetch/ResourceLoaderOptions.h" +#include "core/history/HistoryItem.h" #include "core/loader/FrameLoaderStateMachine.h" #include "core/loader/FrameLoaderTypes.h" -#include "core/loader/HistoryController.h" #include "core/loader/MixedContentChecker.h" -#include "core/page/LayoutMilestones.h" -#include "core/platform/Timer.h" +#include "platform/Timer.h" #include "wtf/Forward.h" #include "wtf/HashSet.h" #include "wtf/OwnPtr.h" @@ -82,26 +81,19 @@ public: Frame* frame() const { return m_frame; } - HistoryController* history() const { return &m_history; } - - IconController* icon() const { return m_icon.get(); } MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; } - void prepareForHistoryNavigation(); - // These functions start a load. All eventually call into loadWithNavigationAction() or loadInSameDocument(). void load(const FrameLoadRequest&); // The entry point for non-reload, non-history loads. - void reload(ReloadPolicy = NormalReload, const KURL& overrideURL = KURL(), const String& overrideEncoding = String()); - void loadHistoryItem(HistoryItem*); // The entry point for all back/forward loads - - HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); } + void reload(ReloadPolicy = NormalReload, const KURL& overrideURL = KURL(), const AtomicString& overrideEncoding = nullAtom); + void loadHistoryItem(HistoryItem*, HistoryLoadType = HistoryDifferentDocumentLoad); // The entry point for all back/forward loads static void reportLocalLoadFailed(Frame*, const String& url); // FIXME: These are all functions which stop loads. We have too many. // Warning: stopAllLoaders can and will detach the Frame out from under you. All callers need to either protect the Frame // or guarantee they won't in any way access the Frame after stopAllLoaders returns. - void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem); + void stopAllLoaders(); void stopLoading(); bool closeURL(); // FIXME: clear() is trying to do too many things. We should break it down into smaller functions. @@ -120,8 +112,6 @@ public: bool isLoading() const; int numPendingOrLoadingRequests(bool recurse) const; - String outgoingReferrer() const; - String outgoingOrigin() const; DocumentLoader* activeDocumentLoader() const; DocumentLoader* documentLoader() const { return m_documentLoader.get(); } @@ -137,14 +127,12 @@ public: bool subframeIsLoading() const; + bool shouldTreatURLAsSameAsCurrent(const KURL&) const; bool shouldTreatURLAsSrcdocDocument(const KURL&) const; FrameLoadType loadType() const; void setLoadType(FrameLoadType loadType) { m_loadType = loadType; } - CachePolicy subresourceCachePolicy() const; - - void didLayout(LayoutMilestones); void didFirstLayout(); void checkLoadComplete(DocumentLoader*); @@ -153,7 +141,7 @@ public: void addExtraFieldsToRequest(ResourceRequest&); - static void addHTTPOriginIfNeeded(ResourceRequest&, const String& origin); + static void addHTTPOriginIfNeeded(ResourceRequest&, const AtomicString& origin); FrameLoaderClient* client() const { return m_client; } @@ -182,8 +170,6 @@ public: void frameDetached(); - void setOutgoingReferrer(const KURL&); - void loadDone(); void finishedParsing(); void checkCompleted(); @@ -200,21 +186,27 @@ public: bool allAncestorsAreComplete() const; // including this - bool suppressOpenerInNewFrame() const { return m_suppressOpenerInNewFrame; } - bool shouldClose(); void started(); - void setContainsPlugins() { m_containsPlugins = true; } - bool containsPlugins() const { return m_containsPlugins; } bool allowPlugins(ReasonForCallingAllowPlugins); enum UpdateBackForwardListPolicy { UpdateBackForwardList, DoNotUpdateBackForwardList }; - void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource, PassRefPtr<SerializedScriptValue>, const String& title, UpdateBackForwardListPolicy); + void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource, PassRefPtr<SerializedScriptValue>, UpdateBackForwardListPolicy); + + HistoryItem* currentItem() const { return m_currentItem.get(); } + void saveDocumentAndScrollState(); + void clearScrollPositionAndViewState(); + + enum RestorePolicy { + StandardRestore, + ForcedRestoreForSameDocumentHistoryNavigation + }; + void restoreScrollPositionAndViewState(RestorePolicy = StandardRestore); private: bool allChildrenAreComplete() const; // immediate children, not all descendants @@ -224,17 +216,14 @@ private: void checkTimerFired(Timer<FrameLoader>*); void didAccessInitialDocumentTimerFired(Timer<FrameLoader>*); - void insertDummyHistoryItem(); - bool prepareRequestForThisFrame(FrameLoadRequest&); - void setReferrerForFrameRequest(ResourceRequest&, ShouldSendReferrer); + void setReferrerForFrameRequest(ResourceRequest&, ShouldSendReferrer, Document*); FrameLoadType determineFrameLoadType(const FrameLoadRequest&); bool isScriptTriggeredFormSubmissionInChildFrame(const FrameLoadRequest&) const; SubstituteData defaultSubstituteDataForURL(const KURL&); - void checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction&, bool isNewNavigation); - void checkNewWindowPolicyAndContinue(PassRefPtr<FormState>, const String& frameName, const NavigationAction&); + void checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction&, bool isNewNavigation, ClientRedirectPolicy); bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&); void scrollToFragmentWithParentBoundary(const KURL&); @@ -244,28 +233,30 @@ private: void closeOldDataSources(); // Calls continueLoadAfterNavigationPolicy - void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, - FrameLoadType, PassRefPtr<FormState>, const SubstituteData&, const String& overrideEncoding = String()); + void loadWithNavigationAction(const NavigationAction&, FrameLoadType, PassRefPtr<FormState>, + const SubstituteData&, ClientRedirectPolicy = NotClientRedirect, const AtomicString& overrideEncoding = nullAtom); void detachChildren(); void closeAndRemoveChild(Frame*); - void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation); + enum HistoryItemPolicy { + CreateNewHistoryItem, + DoNotCreateNewHistoryItem + }; + void setHistoryItemStateForCommit(HistoryItemPolicy); + + void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation, ClientRedirectPolicy); void scheduleCheckCompleted(); void startCheckCompleteTimer(); - bool shouldTreatURLAsSameAsCurrent(const KURL&) const; - Frame* m_frame; FrameLoaderClient* m_client; // FIXME: These should be OwnPtr<T> to reduce build times and simplify // header dependencies unless performance testing proves otherwise. // Some of these could be lazily created for memory savings on devices. - mutable HistoryController m_history; mutable FrameLoaderStateMachine m_stateMachine; - OwnPtr<IconController> m_icon; mutable MixedContentChecker m_mixedContentChecker; class FrameProgressTracker; @@ -283,15 +274,13 @@ private: RefPtr<DocumentLoader> m_policyDocumentLoader; OwnPtr<FetchContext> m_fetchContext; - bool m_inStopAllLoaders; + RefPtr<HistoryItem> m_currentItem; - String m_outgoingReferrer; + bool m_inStopAllLoaders; // FIXME: This is only used in checkCompleted(). Figure out a way to disentangle it. bool m_isComplete; - bool m_containsPlugins; - Timer<FrameLoader> m_checkTimer; bool m_shouldCallCheckCompleted; @@ -300,12 +289,8 @@ private: bool m_didAccessInitialDocument; Timer<FrameLoader> m_didAccessInitialDocumentTimer; - bool m_suppressOpenerInNewFrame; - bool m_startingClientRedirect; SandboxFlags m_forcedSandboxFlags; - - RefPtr<HistoryItem> m_requestedHistoryItem; }; } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h index bb75b830aa1..ec3ca3ccfc5 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h @@ -33,8 +33,7 @@ #include "core/dom/IconURL.h" #include "core/loader/FrameLoaderTypes.h" #include "core/loader/NavigationPolicy.h" -#include "core/page/LayoutMilestones.h" -#include "core/platform/network/ResourceLoadPriority.h" +#include "platform/network/ResourceLoadPriority.h" #include "wtf/Forward.h" #include "wtf/Vector.h" @@ -45,9 +44,10 @@ class Context; template<class T> class Handle; } -namespace WebKit { +namespace blink { class WebCookieJar; -class WebServiceWorkerRegistry; +class WebServiceWorkerProvider; +class WebServiceWorkerProviderClient; } namespace WebCore { @@ -83,6 +83,11 @@ class FetchRequest; class SubstituteData; class Widget; + enum NavigationHistoryPolicy { + NavigationCreatedHistoryEntry, + NavigationReusedHistoryEntry + }; + class FrameLoaderClient { public: virtual ~FrameLoaderClient() { } @@ -101,18 +106,17 @@ class FetchRequest; virtual void dispatchDidHandleOnloadEvents() = 0; virtual void dispatchDidReceiveServerRedirectForProvisionalLoad() = 0; - virtual void dispatchDidNavigateWithinPage() { } + virtual void dispatchDidNavigateWithinPage(NavigationHistoryPolicy, HistoryItem*) { } virtual void dispatchWillClose() = 0; virtual void dispatchDidStartProvisionalLoad() = 0; virtual void dispatchDidReceiveTitle(const String&) = 0; virtual void dispatchDidChangeIcons(IconType) = 0; - virtual void dispatchDidCommitLoad() = 0; + virtual void dispatchDidCommitLoad(Frame*, HistoryItem*, NavigationHistoryPolicy) = 0; virtual void dispatchDidFailProvisionalLoad(const ResourceError&) = 0; virtual void dispatchDidFailLoad(const ResourceError&) = 0; virtual void dispatchDidFinishDocumentLoad() = 0; virtual void dispatchDidFinishLoad() = 0; - - virtual void dispatchDidLayout(LayoutMilestones) { } + virtual void dispatchDidFirstVisuallyNonEmptyLayout() = 0; virtual NavigationPolicy decidePolicyForNavigation(const ResourceRequest&, DocumentLoader*, NavigationPolicy) = 0; @@ -128,7 +132,7 @@ class FetchRequest; virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& suggestedName = String()) = 0; - virtual void navigateBackForward(int offset) const = 0; + virtual bool navigateBackForward(int offset) const = 0; // Another page has accessed the initial empty document of this frame. // It is no longer safe to display a provisional URL, since a URL spoof @@ -151,6 +155,10 @@ class FetchRequest; virtual void didDetectXSS(const KURL&, bool didBlockEntirePage) = 0; virtual void didDispatchPingLoader(const KURL&) = 0; + // Transmits the change in the set of watched CSS selectors property + // that match any element on the frame. + virtual void selectorMatchChanged(const Vector<String>& addedSelectors, const Vector<String>& removedSelectors) = 0; + virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&) = 0; virtual String userAgent(const KURL&) = 0; @@ -193,7 +201,7 @@ class FetchRequest; // This callback is similar, but for plugins. virtual void didNotAllowPlugins() { } - virtual WebKit::WebCookieJar* cookieJar() const = 0; + virtual blink::WebCookieJar* cookieJar() const = 0; // Returns true if the embedder intercepted the postMessage call virtual bool willCheckAndDispatchMessageEvent(SecurityOrigin* /*target*/, MessageEvent*) const { return false; } @@ -219,7 +227,11 @@ class FetchRequest; virtual void dispatchDidChangeResourcePriority(unsigned long /*identifier*/, ResourceLoadPriority) { } - virtual WebKit::WebServiceWorkerRegistry* serviceWorkerRegistry() = 0; + virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) = 0; + + virtual void didStopAllLoaders() { } + + virtual bool isFrameLoaderClientImpl() const { return false; } }; } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp index 2ad0e231cb7..61db0ef4cce 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp @@ -46,7 +46,7 @@ bool FrameLoaderStateMachine::startedFirstRealLoad() const bool FrameLoaderStateMachine::committedFirstRealDocumentLoad() const { - return m_state == CommittedFirstRealLoad; + return m_state >= CommittedFirstRealLoad; } bool FrameLoaderStateMachine::creatingInitialEmptyDocument() const @@ -54,6 +54,11 @@ bool FrameLoaderStateMachine::creatingInitialEmptyDocument() const return m_state == CreatingInitialEmptyDocument; } +bool FrameLoaderStateMachine::committedMultipleRealLoads() const +{ + return m_state == CommittedMultipleRealLoads; +} + bool FrameLoaderStateMachine::isDisplayingInitialEmptyDocument() const { return m_state >= DisplayingInitialEmptyDocument && m_state < CommittedFirstRealLoad; diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h index e8d1a2aaddf..aa349a5d660 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h @@ -47,13 +47,15 @@ public: CreatingInitialEmptyDocument, DisplayingInitialEmptyDocument, StartedFirstRealLoad, - CommittedFirstRealLoad + CommittedFirstRealLoad, + CommittedMultipleRealLoads }; bool startedFirstRealLoad() const; bool committedFirstRealDocumentLoad() const; bool creatingInitialEmptyDocument() const; bool isDisplayingInitialEmptyDocument() const; + bool committedMultipleRealLoads() const; void advanceTo(State); private: diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h index 53c6f0d8a2d..5fe5d36da4f 100644 --- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h +++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h @@ -31,73 +31,79 @@ namespace WebCore { - enum FrameState { - FrameStateProvisional, - // This state indicates we are ready to commit to a page, - // which means the view will transition to use the new data source. - FrameStateCommittedPage, - FrameStateComplete - }; +enum FrameState { + FrameStateProvisional, + // This state indicates we are ready to commit to a page, + // which means the view will transition to use the new data source. + FrameStateCommittedPage, + FrameStateComplete +}; - enum FrameLoadType { - FrameLoadTypeStandard, - FrameLoadTypeBackForward, - FrameLoadTypeReload, - FrameLoadTypeSame, // user loads same URL again (but not reload button) - FrameLoadTypeRedirectWithLockedBackForwardList, - FrameLoadTypeInitialInChildFrame, - FrameLoadTypeReloadFromOrigin, - }; +enum FrameLoadType { + FrameLoadTypeStandard, + FrameLoadTypeBackForward, + FrameLoadTypeReload, + FrameLoadTypeSame, // user loads same URL again (but not reload button) + FrameLoadTypeRedirectWithLockedBackForwardList, + FrameLoadTypeInitialInChildFrame, + FrameLoadTypeReloadFromOrigin, +}; - enum NavigationType { - NavigationTypeLinkClicked, - NavigationTypeFormSubmitted, - NavigationTypeBackForward, - NavigationTypeReload, - NavigationTypeFormResubmitted, - NavigationTypeOther - }; +enum NavigationType { + NavigationTypeLinkClicked, + NavigationTypeFormSubmitted, + NavigationTypeBackForward, + NavigationTypeReload, + NavigationTypeFormResubmitted, + NavigationTypeOther +}; - enum ClearProvisionalItemPolicy { - ShouldClearProvisionalItem, - ShouldNotClearProvisionalItem - }; +enum ObjectContentType { + ObjectContentNone, + ObjectContentImage, + ObjectContentFrame, + ObjectContentNetscapePlugin, + ObjectContentOtherPlugin +}; - enum ObjectContentType { - ObjectContentNone, - ObjectContentImage, - ObjectContentFrame, - ObjectContentNetscapePlugin, - ObjectContentOtherPlugin - }; +enum ClearOption { + ClearWindowProperties = 1 << 0, + ClearScriptObjects = 1 << 1, + ClearWindowObject = 1 << 2, +}; +typedef int ClearOptions; - enum ClearOption { - ClearWindowProperties = 1 << 0, - ClearScriptObjects = 1 << 1, - ClearWindowObject = 1 << 2, - }; - typedef int ClearOptions; +enum ShouldSendReferrer { + MaybeSendReferrer, + NeverSendReferrer +}; - enum ShouldSendReferrer { - MaybeSendReferrer, - NeverSendReferrer - }; +enum ReasonForCallingAllowPlugins { + AboutToInstantiatePlugin, + NotAboutToInstantiatePlugin +}; - enum ReasonForCallingAllowPlugins { - AboutToInstantiatePlugin, - NotAboutToInstantiatePlugin - }; +enum ReloadPolicy { + NormalReload, + EndToEndReload +}; - enum ReloadPolicy { - NormalReload, - EndToEndReload - }; +enum SameDocumentNavigationSource { + SameDocumentNavigationDefault, + SameDocumentNavigationPushState, + SameDocumentNavigationReplaceState +}; + +enum ClientRedirectPolicy { + NotClientRedirect, + ClientRedirect +}; + +enum HistoryLoadType { + HistorySameDocumentLoad, + HistoryDifferentDocumentLoad +}; - enum SameDocumentNavigationSource { - SameDocumentNavigationDefault, - SameDocumentNavigationPushState, - SameDocumentNavigationReplaceState - }; } #endif diff --git a/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp b/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp index be314f56128..033c7348ec0 100644 --- a/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp @@ -31,686 +31,317 @@ #include "config.h" #include "core/loader/HistoryController.h" -#include "core/dom/Document.h" -#include "core/history/BackForwardController.h" -#include "core/history/HistoryItem.h" -#include "core/html/HTMLFrameOwnerElement.h" -#include "core/loader/DocumentLoader.h" #include "core/loader/FrameLoader.h" -#include "core/loader/FrameLoaderClient.h" -#include "core/loader/FrameLoaderStateMachine.h" -#include "core/page/Frame.h" +#include "core/frame/Frame.h" #include "core/page/FrameTree.h" -#include "core/page/FrameView.h" #include "core/page/Page.h" -#include "core/page/scrolling/ScrollingCoordinator.h" -#include "core/platform/Logging.h" -#include "wtf/text/CString.h" +#include "wtf/Deque.h" +#include "wtf/text/StringHash.h" namespace WebCore { -HistoryController::HistoryController(Frame* frame) - : m_frame(frame) - , m_defersLoading(false) +PassOwnPtr<HistoryNode> HistoryNode::create(HistoryEntry* entry, HistoryItem* value) { + return adoptPtr(new HistoryNode(entry, value)); } -HistoryController::~HistoryController() +HistoryNode* HistoryNode::addChild(PassRefPtr<HistoryItem> item) { + m_children.append(HistoryNode::create(m_entry, item.get())); + return m_children.last().get(); } -void HistoryController::saveScrollPositionAndViewStateToItem(HistoryItem* item) +PassOwnPtr<HistoryNode> HistoryNode::cloneAndReplace(HistoryEntry* newEntry, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame) { - if (!item || !m_frame->view()) - return; + bool isNodeBeingNavigated = targetFrame == currentFrame; + HistoryItem* itemForCreate = isNodeBeingNavigated ? newItem : m_value.get(); + OwnPtr<HistoryNode> newHistoryNode = create(newEntry, itemForCreate); - item->setScrollPoint(m_frame->view()->scrollPosition()); - - Page* page = m_frame->page(); - if (page && page->mainFrame() == m_frame) - item->setPageScaleFactor(page->pageScaleFactor()); + if (!clipAtTarget || !isNodeBeingNavigated) { + for (Frame* child = currentFrame->tree().firstChild(); child; child = child->tree().nextSibling()) { + HistoryNode* childHistoryNode = m_entry->historyNodeForFrame(child); + if (!childHistoryNode) + continue; + newHistoryNode->m_children.append(childHistoryNode->cloneAndReplace(newEntry, newItem, clipAtTarget, targetFrame, child)); + } + } + return newHistoryNode.release(); } -void HistoryController::clearScrollPositionAndViewState() +HistoryNode::HistoryNode(HistoryEntry* entry, HistoryItem* value) + : m_entry(entry) + , m_value(value) { - if (!m_currentItem) - return; - - m_currentItem->clearScrollPoint(); - m_currentItem->setPageScaleFactor(0); + m_entry->m_framesToItems.add(value->targetFrameID(), this); + String target = value->target(); + if (target.isNull()) + target = emptyString(); + m_entry->m_uniqueNamesToItems.add(target, this); } -/* - There is a race condition between the layout and load completion that affects restoring the scroll position. - We try to restore the scroll position at both the first layout and upon load completion. - - 1) If first layout happens before the load completes, we want to restore the scroll position then so that the - first time we draw the page is already scrolled to the right place, instead of starting at the top and later - jumping down. It is possible that the old scroll position is past the part of the doc laid out so far, in - which case the restore silent fails and we will fix it in when we try to restore on doc completion. - 2) If the layout happens after the load completes, the attempt to restore at load completion time silently - fails. We then successfully restore it when the layout happens. -*/ -void HistoryController::restoreScrollPositionAndViewState() +void HistoryNode::removeChildren() { - if (!m_frame->loader()->stateMachine()->committedFirstRealDocumentLoad()) - return; - - ASSERT(m_currentItem); + // FIXME: This is inefficient. Figure out a cleaner way to ensure this HistoryNode isn't cached anywhere. + for (unsigned i = 0; i < m_children.size(); i++) { + m_children[i]->removeChildren(); - // FIXME: As the ASSERT attests, it seems we should always have a currentItem here. - // One counterexample is <rdar://problem/4917290> - // For now, to cover this issue in release builds, there is no technical harm to returning - // early and from a user standpoint - as in the above radar - the previous page load failed - // so there *is* no scroll or view state to restore! - if (!m_currentItem) - return; - - if (FrameView* view = m_frame->view()) { - Page* page = m_frame->page(); - if (page && page->mainFrame() == m_frame) { - if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) - scrollingCoordinator->frameViewRootLayerDidChange(view); + HashMap<uint64_t, HistoryNode*>::iterator framesEnd = m_entry->m_framesToItems.end(); + HashMap<String, HistoryNode*>::iterator uniqueNamesEnd = m_entry->m_uniqueNamesToItems.end(); + for (HashMap<uint64_t, HistoryNode*>::iterator it = m_entry->m_framesToItems.begin(); it != framesEnd; ++it) { + if (it->value == m_children[i]) + m_entry->m_framesToItems.remove(it); } - - if (!view->wasScrolledByUser()) { - if (page && page->mainFrame() == m_frame && m_currentItem->pageScaleFactor()) - page->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint()); - else - view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint()); + for (HashMap<String, HistoryNode*>::iterator it = m_entry->m_uniqueNamesToItems.begin(); it != uniqueNamesEnd; ++it) { + if (it->value == m_children[i]) + m_entry->m_uniqueNamesToItems.remove(it); } } + m_children.clear(); } -void HistoryController::updateBackForwardListForFragmentScroll() +HistoryEntry::HistoryEntry(HistoryItem* root) { - updateBackForwardListClippedAtTarget(false); + m_root = HistoryNode::create(this, root); } -void HistoryController::saveDocumentState() +PassOwnPtr<HistoryEntry> HistoryEntry::create(HistoryItem* root) { - if (!m_currentItem) - return; - - Document* document = m_frame->document(); - ASSERT(document); - - if (m_currentItem->isCurrentDocument(document) && document->attached()) { - LOG(Loading, "WebCoreLoading %s: saving form state to %p", m_frame->tree()->uniqueName().string().utf8().data(), m_currentItem.get()); - m_currentItem->setDocumentState(document->formElementsState()); - } + return adoptPtr(new HistoryEntry(root)); } -// Walk the frame tree, telling all frames to save their form state into their current -// history item. -void HistoryController::saveDocumentAndScrollState() +PassOwnPtr<HistoryEntry> HistoryEntry::cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page* page) { - for (Frame* frame = m_frame; frame; frame = frame->tree()->traverseNext(m_frame)) { - frame->loader()->history()->saveDocumentState(); - frame->loader()->history()->saveScrollPositionAndViewStateToItem(frame->loader()->history()->currentItem()); - } + OwnPtr<HistoryEntry> newEntry = adoptPtr(new HistoryEntry()); + newEntry->m_root = m_root->cloneAndReplace(newEntry.get(), newItem, clipAtTarget, targetFrame, page->mainFrame()); + return newEntry.release(); } -static inline bool isAssociatedToRequestedHistoryItem(const HistoryItem* current, Frame* frame, const HistoryItem* requested) +HistoryNode* HistoryEntry::historyNodeForFrame(Frame* frame) { - if (requested == current) - return true; - if (requested) - return false; - while ((frame = frame->tree()->parent())) { - requested = frame->loader()->requestedHistoryItem(); - if (!requested) - continue; - if (requested->isAncestorOf(current)) - return true; - } - return false; + if (HistoryNode* historyNode = m_framesToItems.get(frame->frameID())) + return historyNode; + String target = frame->tree().uniqueName(); + if (target.isNull()) + target = emptyString(); + return m_uniqueNamesToItems.get(target); } -void HistoryController::restoreDocumentState() +HistoryItem* HistoryEntry::itemForFrame(Frame* frame) { - Document* doc = m_frame->document(); - - HistoryItem* itemToRestore = 0; - - switch (m_frame->loader()->loadType()) { - case FrameLoadTypeReload: - case FrameLoadTypeReloadFromOrigin: - case FrameLoadTypeSame: - break; - case FrameLoadTypeBackForward: - case FrameLoadTypeRedirectWithLockedBackForwardList: - case FrameLoadTypeInitialInChildFrame: - case FrameLoadTypeStandard: - itemToRestore = m_currentItem.get(); - } - - if (!itemToRestore) - return; - if (isAssociatedToRequestedHistoryItem(itemToRestore, m_frame, m_frame->loader()->requestedHistoryItem()) && !m_frame->loader()->documentLoader()->isClientRedirect()) { - LOG(Loading, "WebCoreLoading %s: restoring form state from %p", m_frame->tree()->uniqueName().string().utf8().data(), itemToRestore); - doc->setStateForNewFormElements(itemToRestore->documentState()); - } -} - -bool HistoryController::shouldStopLoadingForHistoryItem(HistoryItem* targetItem) const -{ - if (!m_currentItem) - return false; - // Don't abort the current load if we're navigating within the current document. - return !m_currentItem->shouldDoSameDocumentNavigationTo(targetItem); + if (HistoryNode* historyNode = historyNodeForFrame(frame)) + return historyNode->value(); + return 0; } -// Main funnel for navigating to a previous location (back/forward, non-search snap-back) -// This includes recursion to handle loading into framesets properly -void HistoryController::goToItem(HistoryItem* targetItem) +HistoryController::HistoryController(Page* page) + : m_page(page) + , m_defersLoading(false) { - ASSERT(!m_frame->tree()->parent()); - - // shouldGoToHistoryItem is a private delegate method. This is needed to fix: - // <rdar://problem/3951283> can view pages from the back/forward cache that should be disallowed by Parental Controls - // Ultimately, history item navigations should go through the policy delegate. That's covered in: - // <rdar://problem/3979539> back/forward cache navigations should consult policy delegate - Page* page = m_frame->page(); - if (!page) - return; - if (m_defersLoading) { - m_deferredItem = targetItem; - return; - } - - // Set the BF cursor before commit, which lets the user quickly click back/forward again. - // - plus, it only makes sense for the top level of the operation through the frametree, - // as opposed to happening for some/one of the page commits that might happen soon - RefPtr<HistoryItem> currentItem = page->backForward().currentItem(); - page->backForward().setCurrentItem(targetItem); - - // First set the provisional item of any frames that are not actually navigating. - // This must be done before trying to navigate the desired frame, because some - // navigations can commit immediately (such as about:blank). We must be sure that - // all frames have provisional items set before the commit. - recursiveSetProvisionalItem(targetItem, currentItem.get()); - // Now that all other frames have provisional items, do the actual navigation. - recursiveGoToItem(targetItem, currentItem.get()); } -void HistoryController::setDefersLoading(bool defer) -{ - m_defersLoading = defer; - if (!defer && m_deferredItem) { - goToItem(m_deferredItem.get()); - m_deferredItem = 0; - } -} - -void HistoryController::updateForBackForwardNavigation() +HistoryController::~HistoryController() { -#if !LOG_DISABLED - LOG(History, "WebCoreHistory: Updating History for back/forward navigation in frame %s", m_frame->document()->title().utf8().data()); -#endif - - saveScrollPositionAndViewStateToItem(m_previousItem.get()); - - // When traversing history, we may end up redirecting to a different URL - // this time (e.g., due to cookies). See http://webkit.org/b/49654. - updateCurrentItem(); } -void HistoryController::updateForReload() +void HistoryController::updateBackForwardListForFragmentScroll(Frame* frame, HistoryItem* item) { -#if !LOG_DISABLED - LOG(History, "WebCoreHistory: Updating History for reload in frame %s", m_frame->document()->title().utf8().data()); -#endif - - if (m_currentItem) { - if (m_frame->loader()->loadType() == FrameLoadTypeReload || m_frame->loader()->loadType() == FrameLoadTypeReloadFromOrigin) - saveScrollPositionAndViewStateToItem(m_currentItem.get()); - } - - // When reloading the page, we may end up redirecting to a different URL - // this time (e.g., due to cookies). See http://webkit.org/b/4072. - updateCurrentItem(); + m_provisionalEntry.clear(); + createNewBackForwardItem(frame, item, false); } -// There are 2 things you might think of as "history", all of which are handled by these functions. -// -// 1) Back/forward: The m_currentItem is part of this mechanism. -// 2) Global history: Handled by the client. -// -void HistoryController::updateForStandardLoad() +void HistoryController::goToEntry(PassOwnPtr<HistoryEntry> targetEntry) { - LOG(History, "WebCoreHistory: Updating History for Standard Load in frame %s", m_frame->loader()->documentLoader()->url().string().ascii().data()); + ASSERT(m_sameDocumentLoadsInProgress.isEmpty()); + ASSERT(m_differentDocumentLoadsInProgress.isEmpty()); - if (!m_frame->loader()->documentLoader()->urlForHistory().isEmpty()) - updateBackForwardListClippedAtTarget(true); -} + m_provisionalEntry = targetEntry; + if (m_currentEntry) + recursiveGoToEntry(m_page->mainFrame()); + else + m_differentDocumentLoadsInProgress.set(m_page->mainFrame(), m_provisionalEntry->root()); -void HistoryController::updateForRedirectWithLockedBackForwardList() -{ -#if !LOG_DISABLED - LOG(History, "WebCoreHistory: Updating History for redirect load in frame %s", m_frame->document()->title().utf8().data()); -#endif + if (m_sameDocumentLoadsInProgress.isEmpty() && m_differentDocumentLoadsInProgress.isEmpty()) + m_sameDocumentLoadsInProgress.set(m_page->mainFrame(), m_provisionalEntry->root()); - if (!m_currentItem && !m_frame->tree()->parent()) { - if (!m_frame->loader()->documentLoader()->urlForHistory().isEmpty()) - updateBackForwardListClippedAtTarget(true); + if (m_differentDocumentLoadsInProgress.isEmpty()) { + m_previousEntry = m_currentEntry.release(); + m_currentEntry = m_provisionalEntry.release(); + } else { + m_page->mainFrame()->loader().stopAllLoaders(); } - // The client redirect replaces the current history item. - updateCurrentItem(); -} -void HistoryController::updateForInitialLoadInChildFrame() -{ - Frame* parentFrame = m_frame->tree()->parent(); - if (parentFrame && parentFrame->loader()->history()->m_currentItem) - parentFrame->loader()->history()->m_currentItem->setChildItem(createItem()); + for (HistoryFrameLoadSet::iterator it = m_sameDocumentLoadsInProgress.begin(); it != m_sameDocumentLoadsInProgress.end(); ++it) + it->key->loader().loadHistoryItem(it->value.get(), HistorySameDocumentLoad); + for (HistoryFrameLoadSet::iterator it = m_differentDocumentLoadsInProgress.begin(); it != m_differentDocumentLoadsInProgress.end(); ++it) + it->key->loader().loadHistoryItem(it->value.get(), HistoryDifferentDocumentLoad); + m_sameDocumentLoadsInProgress.clear(); + m_differentDocumentLoadsInProgress.clear(); } -void HistoryController::updateForCommit() +void HistoryController::recursiveGoToEntry(Frame* frame) { - FrameLoader* frameLoader = m_frame->loader(); -#if !LOG_DISABLED - if (m_frame->document()) - LOG(History, "WebCoreHistory: Updating History for commit in frame %s", m_frame->document()->title().utf8().data()); -#endif - FrameLoadType type = frameLoader->loadType(); - if (isBackForwardLoadType(type) || (isReloadTypeWithProvisionalItem(type) && !frameLoader->documentLoader()->unreachableURL().isEmpty())) { - // Once committed, we want to use current item for saving DocState, and - // the provisional item for restoring state. - // Note previousItem must be set before we close the URL, which will - // happen when the data source is made non-provisional below - m_previousItem = m_currentItem; - ASSERT(m_provisionalItem); - m_currentItem = m_provisionalItem; - m_provisionalItem = 0; - - // Tell all other frames in the tree to commit their provisional items and - // restore their scroll position. We'll avoid this frame (which has already - // committed) and its children (which will be replaced). - Page* page = m_frame->page(); - ASSERT(page); - page->mainFrame()->loader()->history()->recursiveUpdateForCommit(); - } - - switch (type) { - case FrameLoadTypeBackForward: - updateForBackForwardNavigation(); + ASSERT(m_provisionalEntry); + ASSERT(m_currentEntry); + HistoryItem* newItem = m_provisionalEntry->itemForFrame(frame); + HistoryItem* oldItem = m_currentEntry->itemForFrame(frame); + if (!newItem) return; - case FrameLoadTypeReload: - case FrameLoadTypeReloadFromOrigin: - case FrameLoadTypeSame: - updateForReload(); - return; - case FrameLoadTypeStandard: - updateForStandardLoad(); - return; - case FrameLoadTypeRedirectWithLockedBackForwardList: - updateForRedirectWithLockedBackForwardList(); - return; - case FrameLoadTypeInitialInChildFrame: - updateForInitialLoadInChildFrame(); + + if (!oldItem || (newItem != oldItem && newItem->itemSequenceNumber() != oldItem->itemSequenceNumber())) { + if (oldItem && newItem->documentSequenceNumber() == oldItem->documentSequenceNumber()) + m_sameDocumentLoadsInProgress.set(frame, newItem); + else + m_differentDocumentLoadsInProgress.set(frame, newItem); return; - default: - ASSERT_NOT_REACHED(); } -} -bool HistoryController::isReloadTypeWithProvisionalItem(FrameLoadType type) -{ - return (type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin) && m_provisionalItem; + for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) + recursiveGoToEntry(child); } -void HistoryController::recursiveUpdateForCommit() +void HistoryController::goToItem(HistoryItem* targetItem) { - // The frame that navigated will now have a null provisional item. - // Ignore it and its children. - if (!m_provisionalItem) + if (m_defersLoading) { + m_deferredItem = targetItem; return; - - // For each frame that already had the content the item requested (based on - // (a matching URL and frame tree snapshot), just restore the scroll position. - // Save form state - if (m_currentItem && itemsAreClones(m_currentItem.get(), m_provisionalItem.get())) { - saveDocumentState(); - saveScrollPositionAndViewStateToItem(m_currentItem.get()); - - if (FrameView* view = m_frame->view()) - view->setWasScrolledByUser(false); - - // Now commit the provisional item - m_previousItem = m_currentItem; - m_currentItem = m_provisionalItem; - m_provisionalItem = 0; - - // Restore form state (works from currentItem) - restoreDocumentState(); - - // Restore the scroll position (we choose to do this rather than going back to the anchor point) - restoreScrollPositionAndViewState(); } - // Iterate over the rest of the tree - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->loader()->history()->recursiveUpdateForCommit(); + OwnPtr<HistoryEntry> newEntry = HistoryEntry::create(targetItem); + Deque<HistoryNode*> historyNodes; + historyNodes.append(newEntry->rootHistoryNode()); + while (!historyNodes.isEmpty()) { + // For each item, read the children (if any) off the HistoryItem, + // create a new HistoryNode for each child and attach it, + // then clear the children on the HistoryItem. + HistoryNode* historyNode = historyNodes.takeFirst(); + const HistoryItemVector& children = historyNode->value()->children(); + for (size_t i = 0; i < children.size(); i++) { + HistoryNode* childHistoryNode = historyNode->addChild(children[i].get()); + historyNodes.append(childHistoryNode); + } + historyNode->value()->clearChildren(); + } + goToEntry(newEntry.release()); } -void HistoryController::updateForSameDocumentNavigation() +void HistoryController::setDefersLoading(bool defer) { - if (m_frame->document()->url().isEmpty()) - return; - - Page* page = m_frame->page(); - if (!page) - return; - - page->mainFrame()->loader()->history()->recursiveUpdateForSameDocumentNavigation(); - - if (m_currentItem) - m_currentItem->setURL(m_frame->document()->url()); + m_defersLoading = defer; + if (!defer && m_deferredItem) { + goToItem(m_deferredItem.get()); + m_deferredItem = 0; + } } -void HistoryController::recursiveUpdateForSameDocumentNavigation() +void HistoryController::updateForInitialLoadInChildFrame(Frame* frame, HistoryItem* item) { - // The frame that navigated will now have a null provisional item. - // Ignore it and its children. - if (!m_provisionalItem) - return; - - // The provisional item may represent a different pending navigation. - // Don't commit it if it isn't a same document navigation. - if (m_currentItem && !m_currentItem->shouldDoSameDocumentNavigationTo(m_provisionalItem.get())) + ASSERT(frame->tree().parent()); + if (!m_currentEntry) return; - - // Commit the provisional item. - m_previousItem = m_currentItem; - m_currentItem = m_provisionalItem; - m_provisionalItem = 0; - - // Iterate over the rest of the tree. - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) - child->loader()->history()->recursiveUpdateForSameDocumentNavigation(); -} - -void HistoryController::setCurrentItem(HistoryItem* item) -{ - m_previousItem = m_currentItem; - m_currentItem = item; -} - -void HistoryController::setCurrentItemTitle(const String& title) -{ - if (m_currentItem) - m_currentItem->setTitle(title); -} - -bool HistoryController::currentItemShouldBeReplaced() const -{ - // From the HTML5 spec for location.assign(): - // "If the browsing context's session history contains only one Document, - // and that was the about:blank Document created when the browsing context - // was created, then the navigation must be done with replacement enabled." - return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->urlString(), blankURL()); -} - -void HistoryController::setProvisionalItem(HistoryItem* item) -{ - m_provisionalItem = item; + if (HistoryNode* existingChildHistoryNode = m_currentEntry->historyNodeForFrame(frame)) + existingChildHistoryNode->updateValue(item); + else if (HistoryNode* parentHistoryNode = m_currentEntry->historyNodeForFrame(frame->tree().parent())) + parentHistoryNode->addChild(item); +} + +// FIXME: This is a temporary hack designed to be mergeable to the 1750 branch. +// As trunk stands currently, we should never clear the provisional entry, since it's +// possible to clear based on a commit in an irrelevant frame. On trunk, the provisional entry is +// an implementation detail of HistoryController and only used when we know that we're in +// a back/forward navigation. Also, it is clobbered when a new history navigation begins, +// so we can be sure that a stale provisional entry won't be confused with a new one. +// On the branch, however, the provisional entry is observable because +// WebFrameImpl::currentHistoryItem() will return data based on the provisional entry preferentially +// over the current entry, so we can't leave a stale provisional entry around indefinitely. +// Therefore, search the frame tree for any back/forward navigations in progress, and only clear +// the provisional entry if none are found. +// Once the fix is merged to the branch, this can be removed, along with all places that we clear +// m_provisionalEntry. +static bool shouldClearProvisionalEntry(Page* page) +{ + for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { + if (frame->loader().loadType() == FrameLoadTypeBackForward) + return false; + } + return true; } -void HistoryController::initializeItem(HistoryItem* item) +void HistoryController::updateForCommit(Frame* frame, HistoryItem* item) { - DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); - ASSERT(documentLoader); - - KURL unreachableURL = documentLoader->unreachableURL(); - - KURL url; - KURL originalURL; - - if (!unreachableURL.isEmpty()) { - url = unreachableURL; - originalURL = unreachableURL; - } else { - url = documentLoader->url(); - originalURL = documentLoader->originalURL(); + FrameLoadType type = frame->loader().loadType(); + if (isBackForwardLoadType(type) && m_provisionalEntry) { + // Once committed, we want to use current item for saving DocState, and + // the provisional item for restoring state. + // Note previousItem must be set before we close the URL, which will + // happen when the data source is made non-provisional below + m_previousEntry = m_currentEntry.release(); + ASSERT(m_provisionalEntry); + m_currentEntry = m_provisionalEntry.release(); + } else if (type != FrameLoadTypeRedirectWithLockedBackForwardList && shouldClearProvisionalEntry(m_page)) { + m_provisionalEntry.clear(); } - // Frames that have never successfully loaded any content - // may have no URL at all. Currently our history code can't - // deal with such things, so we nip that in the bud here. - // Later we may want to learn to live with nil for URL. - // See bug 3368236 and related bugs for more information. - if (url.isEmpty()) - url = blankURL(); - if (originalURL.isEmpty()) - originalURL = blankURL(); - - Frame* parentFrame = m_frame->tree()->parent(); - String parent = parentFrame ? parentFrame->tree()->uniqueName() : ""; - - item->setURL(url); - item->setTarget(m_frame->tree()->uniqueName()); - item->setParent(parent); - // FIXME: should store title directionality in history as well. - item->setTitle(m_frame->document()->title()); - item->setOriginalURLString(originalURL.string()); - - // Save form state if this is a POST - item->setFormInfoFromRequest(documentLoader->request()); + if (type == FrameLoadTypeStandard) + createNewBackForwardItem(frame, item, true); + else if (type == FrameLoadTypeInitialInChildFrame) + updateForInitialLoadInChildFrame(frame, item); } -PassRefPtr<HistoryItem> HistoryController::createItem() +static PassRefPtr<HistoryItem> itemForExport(HistoryNode* historyNode) { - RefPtr<HistoryItem> item = HistoryItem::create(); - initializeItem(item.get()); - - // Set the item for which we will save document state - m_previousItem = m_currentItem; - m_currentItem = item; - - return item.release(); + RefPtr<HistoryItem> item = historyNode->value()->copy(); + const Vector<OwnPtr<HistoryNode> >& childEntries = historyNode->children(); + for (size_t i = 0; i < childEntries.size(); i++) + item->addChildItem(itemForExport(childEntries[i].get())); + return item; } -PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame* targetFrame, bool clipAtTarget) +PassRefPtr<HistoryItem> HistoryController::currentItemForExport() { - RefPtr<HistoryItem> bfItem = createItem(); - saveScrollPositionAndViewStateToItem(m_previousItem.get()); - - if (!clipAtTarget || m_frame != targetFrame) { - // save frame state for items that aren't loading (khtml doesn't save those) - saveDocumentState(); - - // clipAtTarget is false for navigations within the same document, so - // we should copy the documentSequenceNumber over to the newly create - // item. Non-target items are just clones, and they should therefore - // preserve the same itemSequenceNumber. - if (m_previousItem) { - if (m_frame != targetFrame) - bfItem->setItemSequenceNumber(m_previousItem->itemSequenceNumber()); - bfItem->setDocumentSequenceNumber(m_previousItem->documentSequenceNumber()); - } - - for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { - // If the child is a frame corresponding to an <object> element that never loaded, - // we don't want to create a history item, because that causes fallback content - // to be ignored on reload. - FrameLoader* childLoader = child->loader(); - if (childLoader->stateMachine()->startedFirstRealLoad() || !child->ownerElement()->isObjectElement()) - bfItem->addChildItem(childLoader->history()->createItemTree(targetFrame, clipAtTarget)); - } - } - // FIXME: Eliminate the isTargetItem flag in favor of itemSequenceNumber. - if (m_frame == targetFrame) - bfItem->setIsTargetItem(true); - return bfItem; + if (!m_currentEntry) + return 0; + return itemForExport(m_currentEntry->rootHistoryNode()); } -// The general idea here is to traverse the frame tree and the item tree in parallel, -// tracking whether each frame already has the content the item requests. If there is -// a match, we set the provisional item and recurse. Otherwise we will reload that -// frame and all its kids in recursiveGoToItem. -void HistoryController::recursiveSetProvisionalItem(HistoryItem* item, HistoryItem* fromItem) +PassRefPtr<HistoryItem> HistoryController::previousItemForExport() { - ASSERT(item); - - if (itemsAreClones(item, fromItem)) { - // Set provisional item, which will be committed in recursiveUpdateForCommit. - m_provisionalItem = item; - - const HistoryItemVector& childItems = item->children(); - - int size = childItems.size(); - - for (int i = 0; i < size; ++i) { - String childFrameName = childItems[i]->target(); - HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName); - ASSERT(fromChildItem); - Frame* childFrame = m_frame->tree()->child(childFrameName); - ASSERT(childFrame); - childFrame->loader()->history()->recursiveSetProvisionalItem(childItems[i].get(), fromChildItem); - } - } -} - -// We now traverse the frame tree and item tree a second time, loading frames that -// do have the content the item requests. -void HistoryController::recursiveGoToItem(HistoryItem* item, HistoryItem* fromItem) -{ - ASSERT(item); - - if (itemsAreClones(item, fromItem)) { - // Just iterate over the rest, looking for frames to navigate. - const HistoryItemVector& childItems = item->children(); - - int size = childItems.size(); - for (int i = 0; i < size; ++i) { - String childFrameName = childItems[i]->target(); - HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName); - ASSERT(fromChildItem); - Frame* childFrame = m_frame->tree()->child(childFrameName); - ASSERT(childFrame); - childFrame->loader()->history()->recursiveGoToItem(childItems[i].get(), fromChildItem); - } - } else { - m_frame->loader()->loadHistoryItem(item); - } + if (!m_previousEntry) + return 0; + return itemForExport(m_previousEntry->rootHistoryNode()); } -bool HistoryController::itemsAreClones(HistoryItem* item1, HistoryItem* item2) const +PassRefPtr<HistoryItem> HistoryController::provisionalItemForExport() { - // If the item we're going to is a clone of the item we're at, then we do - // not need to load it again. The current frame tree and the frame tree - // snapshot in the item have to match. - // Note: Some clients treat a navigation to the current history item as - // a reload. Thus, if item1 and item2 are the same, we need to create a - // new document and should not consider them clones. - // (See http://webkit.org/b/35532 for details.) - return item1 - && item2 - && item1 != item2 - && item1->itemSequenceNumber() == item2->itemSequenceNumber() - && currentFramesMatchItem(item1) - && item2->hasSameFrames(item1); + if (!m_provisionalEntry) + return 0; + return itemForExport(m_provisionalEntry->rootHistoryNode()); } -// Helper method that determines whether the current frame tree matches given history item's. -bool HistoryController::currentFramesMatchItem(HistoryItem* item) const +HistoryItem* HistoryController::itemForNewChildFrame(Frame* frame) const { - if ((!m_frame->tree()->uniqueName().isEmpty() || !item->target().isEmpty()) && m_frame->tree()->uniqueName() != item->target()) - return false; - - const HistoryItemVector& childItems = item->children(); - if (childItems.size() != m_frame->tree()->childCount()) - return false; - - unsigned size = childItems.size(); - for (unsigned i = 0; i < size; ++i) { - if (!m_frame->tree()->child(childItems[i]->target())) - return false; - } - - return true; + return m_currentEntry ? m_currentEntry->itemForFrame(frame) : 0; } -void HistoryController::updateBackForwardListClippedAtTarget(bool doClip) +void HistoryController::removeChildrenForRedirect(Frame* frame) { - // In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree. - // The item that was the target of the user's navigation is designated as the "targetItem". - // When this function is called with doClip=true we're able to create the whole tree except for the target's children, - // which will be loaded in the future. That part of the tree will be filled out as the child loads are committed. - - Page* page = m_frame->page(); - if (!page) - return; - - if (m_frame->loader()->documentLoader()->urlForHistory().isEmpty()) + if (!m_provisionalEntry) return; - - Frame* mainFrame = page->mainFrame(); - ASSERT(mainFrame); - - RefPtr<HistoryItem> topItem = mainFrame->loader()->history()->createItemTree(m_frame, doClip); - LOG(BackForward, "WebCoreBackForward - Adding backforward item %p for frame %s", topItem.get(), m_frame->loader()->documentLoader()->url().string().ascii().data()); - page->backForward().addItem(topItem.release()); + if (HistoryNode* node = m_provisionalEntry->historyNodeForFrame(frame)) + node->removeChildren(); } -void HistoryController::updateCurrentItem() +void HistoryController::createNewBackForwardItem(Frame* targetFrame, HistoryItem* item, bool clipAtTarget) { - if (!m_currentItem) - return; - - DocumentLoader* documentLoader = m_frame->loader()->documentLoader(); - - if (!documentLoader->unreachableURL().isEmpty()) - return; - - if (m_currentItem->url() != documentLoader->url()) { - // We ended up on a completely different URL this time, so the HistoryItem - // needs to be re-initialized. Preserve the isTargetItem flag as it is a - // property of how this HistoryItem was originally created and is not - // dependent on the document. - bool isTargetItem = m_currentItem->isTargetItem(); - m_currentItem->reset(); - initializeItem(m_currentItem.get()); - m_currentItem->setIsTargetItem(isTargetItem); + RefPtr<HistoryItem> newItem = item; + if (!m_currentEntry) { + m_currentEntry = HistoryEntry::create(newItem.get()); } else { - // Even if the final URL didn't change, the form data may have changed. - m_currentItem->setFormInfoFromRequest(documentLoader->request()); + HistoryItem* oldItem = m_currentEntry->itemForFrame(targetFrame); + if (!clipAtTarget && oldItem) + newItem->setDocumentSequenceNumber(oldItem->documentSequenceNumber()); + m_previousEntry = m_currentEntry.release(); + m_currentEntry = m_previousEntry->cloneAndReplace(newItem.get(), clipAtTarget, targetFrame, m_page); } } -void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) -{ - if (!m_currentItem) - return; - - Page* page = m_frame->page(); - ASSERT(page); - - // Get a HistoryItem tree for the current frame tree. - RefPtr<HistoryItem> topItem = page->mainFrame()->loader()->history()->createItemTree(m_frame, false); - - // Override data in the current item (created by createItemTree) to reflect - // the pushState() arguments. - m_currentItem->setTitle(title); - m_currentItem->setStateObject(stateObject); - m_currentItem->setURLString(urlString); - page->backForward().addItem(topItem.release()); -} - -void HistoryController::replaceState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) -{ - if (!m_currentItem) - return; - - if (!urlString.isEmpty()) - m_currentItem->setURLString(urlString); - m_currentItem->setTitle(title); - m_currentItem->setStateObject(stateObject); - m_currentItem->setFormData(0); - m_currentItem->setFormContentType(String()); - - ASSERT(m_frame->page()); -} - } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/HistoryController.h b/chromium/third_party/WebKit/Source/core/loader/HistoryController.h index a5f85b85547..d9478c37554 100644 --- a/chromium/third_party/WebKit/Source/core/loader/HistoryController.h +++ b/chromium/third_party/WebKit/Source/core/loader/HistoryController.h @@ -32,6 +32,7 @@ #include "core/history/HistoryItem.h" #include "core/loader/FrameLoaderTypes.h" +#include "wtf/HashMap.h" #include "wtf/Noncopyable.h" #include "wtf/RefPtr.h" #include "wtf/text/WTFString.h" @@ -39,72 +40,136 @@ namespace WebCore { class Frame; -class SerializedScriptValue; +class HistoryEntry; +class Page; + + +// A guide to history state in Blink: +// +// HistoryController: Owned by Page, is the entry point for interacting with history. +// Handles most of the operations to modify history state, navigate to an existing +// back/forward entry, etc. +// HistoryEntry: Represents a single entry in the back/forward list, encapsulating +// all frames in the page it represents. It provides access to each frame's +// state via lookups by frame id or frame name. +// HistoryNode: Represents a single frame in a HistoryEntry. Owned by a HistoryEntry. HistoryNodes +// form a tree that mirrors the FrameTree in the corresponding page. HistoryNodes represent +// the structure of the page, but don't hold any per-frame state except a list of child frames. +// HistoryItem (lives in a separate file): The state for a given frame. Can persist across +// navigations. HistoryItem is reference counted, and each HistoryNode holds a reference +// to its single corresponding HistoryItem. Can be referenced by multiple HistoryNodes and +// can therefore exist in multiple HistoryEntry instances. +// +// Suppose we have the following page, foo.com, which embeds foo.com/a in an iframe: +// +// HistoryEntry 0: +// HistoryNode 0_0 (HistoryItem A (url: foo.com)) +// HistoryNode 0_1: (HistoryItem B (url: foo.com/a)) +// +// Now we navigation the top frame to bar.com, which embeds bar.com/b and bar.com/c in iframes, +// and bar.com/b in turn embeds bar.com/d. We will create a new HistoryEntry with a tree +// containing 4 new HistoryNodes. The state will be: +// +// HistoryEntry 1: +// HistoryNode 1_0 (HistoryItem C (url: bar.com)) +// HistoryNode 1_1: (HistoryItem D (url: bar.com/b)) +// HistoryNode 1_3: (HistoryItem F (url: bar.com/d)) +// HistoryNode 1_2: (HistoryItem E (url: bar.com/c)) +// +// +// Finally, we navigate the first subframe from bar.com/b to bar.com/e, which embeds bar.com/f. +// We will create a new HistoryEntry and new HistoryNode for each frame. Any frame that +// navigates (bar.com/e and its child, bar.com/f) will receive a new HistoryItem. However, +// 2 frames were not navigated (bar.com and bar.com/c), so those two frames will reuse the +// existing HistoryItem: +// +// HistoryEntry 2: +// HistoryNode 2_0 (HistoryItem C (url: bar.com)) *REUSED* +// HistoryNode 2_1: (HistoryItem G (url: bar.com/e)) +// HistoryNode 2_3: (HistoryItem H (url: bar.com/f)) +// HistoryNode 2_2: (HistoryItem E (url: bar.com/c)) *REUSED* +// + +class HistoryNode { +public: + static PassOwnPtr<HistoryNode> create(HistoryEntry*, HistoryItem*); + ~HistoryNode() { } -class HistoryController { - WTF_MAKE_NONCOPYABLE(HistoryController); + HistoryNode* addChild(PassRefPtr<HistoryItem>); + PassOwnPtr<HistoryNode> cloneAndReplace(HistoryEntry*, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame); + HistoryItem* value() { return m_value.get(); } + void updateValue(PassRefPtr<HistoryItem> item) { m_value = item; } + const Vector<OwnPtr<HistoryNode> >& children() const { return m_children; } + void removeChildren(); + +private: + HistoryNode(HistoryEntry*, HistoryItem*); + + HistoryEntry* m_entry; + Vector<OwnPtr<HistoryNode> > m_children; + RefPtr<HistoryItem> m_value; +}; + +class HistoryEntry { public: - explicit HistoryController(Frame*); - ~HistoryController(); + static PassOwnPtr<HistoryEntry> create(HistoryItem* root); + PassOwnPtr<HistoryEntry> cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page*); - void saveScrollPositionAndViewStateToItem(HistoryItem*); - void clearScrollPositionAndViewState(); - void restoreScrollPositionAndViewState(); + HistoryNode* historyNodeForFrame(Frame*); + HistoryItem* itemForFrame(Frame*); + HistoryItem* root() const { return m_root->value(); } + HistoryNode* rootHistoryNode() const { return m_root.get(); } - void updateBackForwardListForFragmentScroll(); +private: + friend class HistoryNode; - void saveDocumentState(); - void saveDocumentAndScrollState(); - void restoreDocumentState(); + HistoryEntry() { } + explicit HistoryEntry(HistoryItem* root); - void updateForCommit(); - void updateForSameDocumentNavigation(); + OwnPtr<HistoryNode> m_root; + HashMap<uint64_t, HistoryNode*> m_framesToItems; + HashMap<String, HistoryNode*> m_uniqueNamesToItems; +}; - HistoryItem* currentItem() const { return m_currentItem.get(); } - void setCurrentItem(HistoryItem*); - void setCurrentItemTitle(const String&); - bool currentItemShouldBeReplaced() const; +class HistoryController { + WTF_MAKE_NONCOPYABLE(HistoryController); +public: + explicit HistoryController(Page*); + ~HistoryController(); + + // Should only be called by embedder. To request a back/forward + // navigation, call FrameLoaderClient::navigateBackForward(). + void goToItem(HistoryItem*); - HistoryItem* previousItem() const { return m_previousItem.get(); } + void updateBackForwardListForFragmentScroll(Frame*, HistoryItem*); + void updateForCommit(Frame*, HistoryItem*); - HistoryItem* provisionalItem() const { return m_provisionalItem.get(); } - void setProvisionalItem(HistoryItem*); + PassRefPtr<HistoryItem> currentItemForExport(); + PassRefPtr<HistoryItem> previousItemForExport(); + PassRefPtr<HistoryItem> provisionalItemForExport(); + HistoryItem* itemForNewChildFrame(Frame*) const; + void removeChildrenForRedirect(Frame*); - void pushState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url); - void replaceState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url); + bool inSameDocumentLoad() const { return !m_sameDocumentLoadsInProgress.isEmpty() && m_differentDocumentLoadsInProgress.isEmpty(); } void setDefersLoading(bool); private: - friend class Page; - bool shouldStopLoadingForHistoryItem(HistoryItem*) const; - void goToItem(HistoryItem*); + void goToEntry(PassOwnPtr<HistoryEntry>); + void recursiveGoToEntry(Frame*); + + void updateForInitialLoadInChildFrame(Frame*, HistoryItem*); + void createNewBackForwardItem(Frame*, HistoryItem*, bool doClip); + + Page* m_page; + + OwnPtr<HistoryEntry> m_currentEntry; + OwnPtr<HistoryEntry> m_previousEntry; + OwnPtr<HistoryEntry> m_provisionalEntry; - void initializeItem(HistoryItem*); - PassRefPtr<HistoryItem> createItem(); - PassRefPtr<HistoryItem> createItemTree(Frame* targetFrame, bool clipAtTarget); - - void updateForBackForwardNavigation(); - void updateForReload(); - void updateForStandardLoad(); - void updateForRedirectWithLockedBackForwardList(); - void updateForInitialLoadInChildFrame(); - - void recursiveSetProvisionalItem(HistoryItem*, HistoryItem*); - void recursiveGoToItem(HistoryItem*, HistoryItem*); - bool isReloadTypeWithProvisionalItem(FrameLoadType); - void recursiveUpdateForCommit(); - void recursiveUpdateForSameDocumentNavigation(); - bool itemsAreClones(HistoryItem*, HistoryItem*) const; - bool currentFramesMatchItem(HistoryItem*) const; - void updateBackForwardListClippedAtTarget(bool doClip); - void updateCurrentItem(); - - Frame* m_frame; - - RefPtr<HistoryItem> m_currentItem; - RefPtr<HistoryItem> m_previousItem; - RefPtr<HistoryItem> m_provisionalItem; + typedef HashMap<Frame*, RefPtr<HistoryItem> > HistoryFrameLoadSet; + HistoryFrameLoadSet m_sameDocumentLoadsInProgress; + HistoryFrameLoadSet m_differentDocumentLoadsInProgress; bool m_defersLoading; RefPtr<HistoryItem> m_deferredItem; diff --git a/chromium/third_party/WebKit/Source/core/loader/IconController.cpp b/chromium/third_party/WebKit/Source/core/loader/IconController.cpp deleted file mode 100644 index b112bc4cabb..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/IconController.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) - * Copyright (C) 2008 Alp Toker <alp@atoker.com> - * Copyright (C) Research In Motion Limited 2009. All rights reserved. - * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "core/loader/IconController.h" - -#include "core/dom/Document.h" -#include "core/dom/IconURL.h" -#include "core/page/Frame.h" - -namespace WebCore { - -IconController::IconController(Frame* frame) - : m_frame(frame) -{ -} - -IconController::~IconController() -{ -} - -KURL IconController::url() -{ - IconURLs iconURLs = urlsForTypes(Favicon); - return iconURLs.isEmpty() ? KURL() : iconURLs[0].m_iconURL; -} - -IconURL IconController::iconURL(IconType iconType) const -{ - IconURL result; - const Vector<IconURL>& iconURLs = m_frame->document()->iconURLs(iconType); - Vector<IconURL>::const_iterator iter(iconURLs.begin()); - for (; iter != iconURLs.end(); ++iter) { - if (result.m_iconURL.isEmpty() || !iter->m_mimeType.isEmpty()) - result = *iter; - } - - return result; -} - -IconURLs IconController::urlsForTypes(int iconTypesMask) -{ - IconURLs iconURLs; - if (m_frame->tree() && m_frame->tree()->parent()) - return iconURLs; - - if (iconTypesMask & Favicon && !appendToIconURLs(Favicon, &iconURLs)) - iconURLs.append(defaultURL(Favicon)); - -#if ENABLE(TOUCH_ICON_LOADING) - appendToIconURLs(TouchPrecomposedIcon, &iconURLs); - appendToIconURLs(TouchIcon, &iconURLs); -#endif - - // Finally, append all remaining icons of this type. - const Vector<IconURL>& allIconURLs = m_frame->document()->iconURLs(iconTypesMask); - for (Vector<IconURL>::const_iterator iter = allIconURLs.begin(); iter != allIconURLs.end(); ++iter) { - int i; - int iconCount = iconURLs.size(); - for (i = 0; i < iconCount; ++i) { - if (*iter == iconURLs.at(i)) - break; - } - if (i == iconCount) - iconURLs.append(*iter); - } - - return iconURLs; -} - -bool IconController::appendToIconURLs(IconType iconType, IconURLs* iconURLs) -{ - IconURL faviconURL = iconURL(iconType); - if (faviconURL.m_iconURL.isEmpty()) - return false; - - iconURLs->append(faviconURL); - return true; -} - -IconURL IconController::defaultURL(IconType iconType) -{ - // Don't return a favicon iconURL unless we're http or https - KURL documentURL = m_frame->document()->url(); - if (!documentURL.protocolIsInHTTPFamily()) - return IconURL(); - - KURL url; - bool couldSetProtocol = url.setProtocol(documentURL.protocol()); - ASSERT_UNUSED(couldSetProtocol, couldSetProtocol); - url.setHost(documentURL.host()); - if (documentURL.hasPort()) - url.setPort(documentURL.port()); - - if (iconType == Favicon) { - url.setPath("/favicon.ico"); - return IconURL::defaultIconURL(url, Favicon); - } - return IconURL(); -} - -} diff --git a/chromium/third_party/WebKit/Source/core/loader/IconController.h b/chromium/third_party/WebKit/Source/core/loader/IconController.h deleted file mode 100644 index 87aa799dcda..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/IconController.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved. - * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) - * Copyright (C) Research In Motion Limited 2009. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef IconController_h -#define IconController_h - -#include "core/dom/IconURL.h" - -namespace WebCore { - -class Frame; -class KURL; - -class IconController { - WTF_MAKE_NONCOPYABLE(IconController); - WTF_MAKE_FAST_ALLOCATED; -public: - explicit IconController(Frame*); - ~IconController(); - - KURL url(); - IconURLs urlsForTypes(int iconTypesMask); - IconURL iconURL(IconType) const; - -private: - bool appendToIconURLs(IconType, IconURLs*); - IconURL defaultURL(IconType); - - Frame* m_frame; -}; - -} // namespace WebCore - -#endif diff --git a/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp index 06482124c0c..a8177ba48d5 100644 --- a/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp @@ -25,36 +25,35 @@ #include "HTMLNames.h" #include "core/dom/Document.h" #include "core/dom/Element.h" -#include "core/dom/Event.h" -#include "core/dom/EventSender.h" +#include "core/events/Event.h" +#include "core/events/EventSender.h" #include "core/fetch/CrossOriginAccessControl.h" #include "core/fetch/FetchRequest.h" -#include "core/fetch/ImageResource.h" #include "core/fetch/ResourceFetcher.h" #include "core/html/HTMLObjectElement.h" #include "core/html/parser/HTMLParserIdioms.h" #include "core/rendering/RenderImage.h" #include "core/rendering/RenderVideo.h" #include "core/rendering/svg/RenderSVGImage.h" -#include "weborigin/SecurityOrigin.h" +#include "platform/weborigin/SecurityOrigin.h" namespace WebCore { static ImageEventSender& beforeLoadEventSender() { - DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().beforeloadEvent)); + DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::beforeload)); return sender; } static ImageEventSender& loadEventSender() { - DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().loadEvent)); + DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load)); return sender; } static ImageEventSender& errorEventSender() { - DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().errorEvent)); + DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::error)); return sender; } @@ -141,10 +140,10 @@ void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI void ImageLoader::updateFromElement() { - // If we're not making renderers for the page, then don't load images. We don't want to slow - // down the raw HTML parsing case by loading images we don't intend to display. + // Don't load images for inactive documents. We don't want to slow down the + // raw HTML parsing case by loading images we don't intend to display. Document& document = m_element->document(); - if (!document.renderer()) + if (!document.isActive()) return; AtomicString attr = m_element->imageSourceURL(); @@ -158,7 +157,7 @@ void ImageLoader::updateFromElement() if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) { FetchRequest request(ResourceRequest(document.completeURL(sourceURI(attr))), element()->localName()); - String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr); + AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr); if (!crossOriginMode.isNull()) { StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; updateRequestForAccessControl(request.mutableResourceRequest(), document.securityOrigin(), allowCredentials); @@ -363,11 +362,11 @@ void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) { ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventSender() || eventSender == &errorEventSender()); const AtomicString& eventType = eventSender->eventType(); - if (eventType == eventNames().beforeloadEvent) + if (eventType == EventTypeNames::beforeload) dispatchPendingBeforeLoadEvent(); - if (eventType == eventNames().loadEvent) + if (eventType == EventTypeNames::load) dispatchPendingLoadEvent(); - if (eventType == eventNames().errorEvent) + if (eventType == EventTypeNames::error) dispatchPendingErrorEvent(); } @@ -377,7 +376,7 @@ void ImageLoader::dispatchPendingBeforeLoadEvent() return; if (!m_image) return; - if (!m_element->document().attached()) + if (!m_element->document().frame()) return; m_hasPendingBeforeLoadEvent = false; if (m_element->dispatchBeforeLoadEvent(m_image->url().string())) { @@ -407,7 +406,7 @@ void ImageLoader::dispatchPendingLoadEvent() if (!m_image) return; m_hasPendingLoadEvent = false; - if (element()->document().attached()) + if (element()->document().frame()) dispatchLoadEvent(); // Only consider updating the protection ref-count of the Element immediately before returning @@ -420,8 +419,8 @@ void ImageLoader::dispatchPendingErrorEvent() if (!m_hasPendingErrorEvent) return; m_hasPendingErrorEvent = false; - if (element()->document().attached()) - element()->dispatchEvent(Event::create(eventNames().errorEvent)); + if (element()->document().frame()) + element()->dispatchEvent(Event::create(EventTypeNames::error)); // Only consider updating the protection ref-count of the Element immediately before returning // from this function as doing so might result in the destruction of this ImageLoader. diff --git a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp index 2e49672fdfd..25c23488f04 100644 --- a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp @@ -37,10 +37,9 @@ #include "core/fetch/FetchRequest.h" #include "core/fetch/ResourceFetcher.h" #include "core/html/LinkRelAttribute.h" -#include "core/loader/Prerenderer.h" -#include "core/page/Settings.h" -#include "core/platform/PrerenderHandle.h" -#include "core/platform/network/DNS.h" +#include "core/loader/PrerenderHandle.h" +#include "core/frame/Settings.h" +#include "platform/network/DNS.h" namespace WebCore { @@ -53,10 +52,6 @@ LinkLoader::LinkLoader(LinkLoaderClient* client) LinkLoader::~LinkLoader() { - if (m_cachedLinkResource) - m_cachedLinkResource->removeClient(this); - if (m_prerenderHandle) - m_prerenderHandle->removeClient(); } void LinkLoader::linkLoadTimerFired(Timer<LinkLoader>* timer) @@ -73,15 +68,14 @@ void LinkLoader::linkLoadingErrorTimerFired(Timer<LinkLoader>* timer) void LinkLoader::notifyFinished(Resource* resource) { - ASSERT_UNUSED(resource, m_cachedLinkResource.get() == resource); + ASSERT(this->resource() == resource); - if (m_cachedLinkResource->errorOccurred()) + if (resource->errorOccurred()) m_linkLoadingErrorTimer.startOneShot(0); else m_linkLoadTimer.startOneShot(0); - m_cachedLinkResource->removeClient(this); - m_cachedLinkResource = 0; + clearResource(); } void LinkLoader::didStartPrerender() @@ -114,30 +108,25 @@ bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const String& ty prefetchDNS(href.host()); } + // FIXME(crbug.com/323096): Should take care of import. if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource()) && href.isValid() && document.frame()) { if (!m_client->shouldLoadLink()) return false; Resource::Type type = relAttribute.isLinkSubresource() ? Resource::LinkSubresource : Resource::LinkPrefetch; FetchRequest linkRequest(ResourceRequest(document.completeURL(href)), FetchInitiatorTypeNames::link); - if (m_cachedLinkResource) { - m_cachedLinkResource->removeClient(this); - m_cachedLinkResource = 0; - } - m_cachedLinkResource = document.fetcher()->fetchLinkResource(type, linkRequest); - if (m_cachedLinkResource) - m_cachedLinkResource->addClient(this); + setResource(document.fetcher()->fetchLinkResource(type, linkRequest)); } if (relAttribute.isLinkPrerender()) { - if (!m_prerenderHandle) { - m_prerenderHandle = document.prerenderer()->render(this, href); - } else if (m_prerenderHandle->url() != href) { - m_prerenderHandle->cancel(); - m_prerenderHandle = document.prerenderer()->render(this, href); + if (!m_prerender) { + m_prerender = PrerenderHandle::create(document, this, href); + } else if (m_prerender->url() != href) { + m_prerender->cancel(); + m_prerender = PrerenderHandle::create(document, this, href); } - } else if (m_prerenderHandle) { - m_prerenderHandle->cancel(); - m_prerenderHandle = 0; + } else if (m_prerender) { + m_prerender->cancel(); + m_prerender.clear(); } return true; } @@ -146,10 +135,9 @@ void LinkLoader::released() { // Only prerenders need treatment here; other links either use the Resource interface, or are notionally // atomic (dns prefetch). - if (m_prerenderHandle) { - m_prerenderHandle->cancel(); - m_prerenderHandle->removeClient(); - m_prerenderHandle.clear(); + if (m_prerender) { + m_prerender->cancel(); + m_prerender.clear(); } } diff --git a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h index b0208609a20..4d1f72d7c95 100644 --- a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h @@ -33,19 +33,20 @@ #define LinkLoader_h #include "core/fetch/ResourceClient.h" -#include "core/fetch/ResourcePtr.h" +#include "core/fetch/ResourceOwner.h" #include "core/loader/LinkLoaderClient.h" -#include "core/platform/PrerenderClient.h" -#include "core/platform/Timer.h" -#include "wtf/RefPtr.h" +#include "platform/PrerenderClient.h" +#include "platform/Timer.h" +#include "wtf/OwnPtr.h" namespace WebCore { +class Document; class LinkRelAttribute; class PrerenderHandle; // The LinkLoader can load link rel types icon, dns-prefetch, subresource, prefetch and prerender. -class LinkLoader : public ResourceClient, public PrerenderClient { +class LinkLoader : public ResourceOwner<Resource, ResourceClient>, public PrerenderClient { public: explicit LinkLoader(LinkLoaderClient*); @@ -69,11 +70,10 @@ private: LinkLoaderClient* m_client; - ResourcePtr<Resource> m_cachedLinkResource; Timer<LinkLoader> m_linkLoadTimer; Timer<LinkLoader> m_linkLoadingErrorTimer; - RefPtr<PrerenderHandle> m_prerenderHandle; + OwnPtr<PrerenderHandle> m_prerender; }; } diff --git a/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp b/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp index ac812e0edf8..750f1308afc 100644 --- a/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp @@ -32,10 +32,9 @@ #include "core/dom/Document.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" -#include "core/page/Frame.h" -#include "core/page/Settings.h" -#include "weborigin/SecurityOrigin.h" -#include "wtf/text/WTFString.h" +#include "core/frame/Frame.h" +#include "core/frame/Settings.h" +#include "platform/weborigin/SecurityOrigin.h" namespace WebCore { @@ -46,7 +45,7 @@ MixedContentChecker::MixedContentChecker(Frame* frame) FrameLoaderClient* MixedContentChecker::client() const { - return m_frame->loader()->client(); + return m_frame->loader().client(); } // static @@ -92,7 +91,8 @@ bool MixedContentChecker::canRunInsecureContent(SecurityOrigin* securityOrigin, void MixedContentChecker::logWarning(bool allowed, const String& action, const KURL& target) const { String message = String(allowed ? "" : "[blocked] ") + "The page at '" + m_frame->document()->url().elidedString() + "' was loaded over HTTPS, but " + action + " insecure content from '" + target.elidedString() + "': this content should also be loaded over HTTPS.\n"; - m_frame->document()->addConsoleMessage(SecurityMessageSource, WarningMessageLevel, message); + MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel; + m_frame->document()->addConsoleMessage(SecurityMessageSource, messageLevel, message); } } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp index ffabc57d84a..b0cffda86eb 100644 --- a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp @@ -29,7 +29,7 @@ #include "config.h" #include "core/loader/NavigationAction.h" -#include "core/dom/MouseEvent.h" +#include "core/events/MouseEvent.h" #include "core/loader/FrameLoader.h" namespace WebCore { @@ -60,19 +60,14 @@ NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, Frame , m_type(navigationType(frameLoadType, isFormSubmission, event)) , m_event(event) { -} - -bool NavigationAction::specifiesNavigationPolicy(NavigationPolicy* policy) const -{ - const MouseEvent* event = 0; + const MouseEvent* mouseEvent = 0; if (m_type == NavigationTypeLinkClicked && m_event->isMouseEvent()) - event = toMouseEvent(m_event.get()); + mouseEvent = toMouseEvent(m_event.get()); else if (m_type == NavigationTypeFormSubmitted && m_event && m_event->underlyingEvent() && m_event->underlyingEvent()->isMouseEvent()) - event = toMouseEvent(m_event->underlyingEvent()); + mouseEvent = toMouseEvent(m_event->underlyingEvent()); - if (!event) - return false; - return navigationPolicyFromMouseEvent(event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(), event->metaKey(), policy); + if (!mouseEvent || !navigationPolicyFromMouseEvent(mouseEvent->button(), mouseEvent->ctrlKey(), mouseEvent->shiftKey(), mouseEvent->altKey(), mouseEvent->metaKey(), &m_policy)) + m_policy = NavigationPolicyCurrentTab; } } diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h index 5ba25f33219..e50716bfe9c 100644 --- a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h +++ b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h @@ -29,11 +29,11 @@ #ifndef NavigationAction_h #define NavigationAction_h -#include "core/dom/Event.h" +#include "core/events/Event.h" #include "core/loader/FrameLoaderTypes.h" #include "core/loader/NavigationPolicy.h" -#include "core/platform/network/ResourceRequest.h" -#include "weborigin/KURL.h" +#include "platform/network/ResourceRequest.h" +#include "platform/weborigin/KURL.h" #include "wtf/Forward.h" namespace WebCore { @@ -46,13 +46,14 @@ namespace WebCore { const ResourceRequest& resourceRequest() const { return m_resourceRequest; } NavigationType type() const { return m_type; } Event* event() const { return m_event.get(); } - - bool specifiesNavigationPolicy(NavigationPolicy*) const; + NavigationPolicy policy() const { return m_policy; } + bool shouldOpenInNewWindow() const { return m_policy != NavigationPolicyCurrentTab; } private: ResourceRequest m_resourceRequest; NavigationType m_type; RefPtr<Event> m_event; + NavigationPolicy m_policy; }; } diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp index 594667a6a91..e47437cc842 100644 --- a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp @@ -33,9 +33,7 @@ #include "core/loader/NavigationScheduler.h" #include "bindings/v8/ScriptController.h" -#include "core/dom/Event.h" -#include "core/dom/UserGestureIndicator.h" -#include "core/history/BackForwardController.h" +#include "core/events/Event.h" #include "core/html/HTMLFormElement.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/loader/DocumentLoader.h" @@ -43,9 +41,12 @@ #include "core/loader/FormSubmission.h" #include "core/loader/FrameLoadRequest.h" #include "core/loader/FrameLoader.h" +#include "core/loader/FrameLoaderClient.h" #include "core/loader/FrameLoaderStateMachine.h" -#include "core/page/Frame.h" +#include "core/frame/Frame.h" +#include "core/page/BackForwardClient.h" #include "core/page/Page.h" +#include "platform/UserGestureIndicator.h" #include "wtf/CurrentTime.h" namespace WebCore { @@ -59,7 +60,7 @@ public: : m_delay(delay) , m_lockBackForwardList(lockBackForwardList) , m_isLocationChange(isLocationChange) - , m_wasUserGesture(ScriptController::processingUserGesture()) + , m_wasUserGesture(UserGestureIndicator::processingUserGesture()) { if (m_wasUserGesture) m_userGestureToken = UserGestureIndicator::currentToken(); @@ -69,11 +70,9 @@ public: virtual void fire(Frame*) = 0; virtual bool shouldStartTimer(Frame*) { return true; } - virtual void didStartTimer(Frame*, Timer<NavigationScheduler>*) { } double delay() const { return m_delay; } bool lockBackForwardList() const { return m_lockBackForwardList; } - void setLockBackForwardList(bool lockBackForwardList) { m_lockBackForwardList = lockBackForwardList; } bool isLocationChange() const { return m_isLocationChange; } PassOwnPtr<UserGestureIndicator> createUserGestureIndicator() { @@ -97,88 +96,75 @@ private: class ScheduledURLNavigation : public ScheduledNavigation { protected: - ScheduledURLNavigation(double delay, SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockBackForwardList, bool isLocationChange) + ScheduledURLNavigation(double delay, Document* originDocument, const String& url, const String& referrer, bool lockBackForwardList, bool isLocationChange) : ScheduledNavigation(delay, lockBackForwardList, isLocationChange) - , m_securityOrigin(securityOrigin) + , m_originDocument(originDocument) , m_url(url) , m_referrer(referrer) - , m_haveToldClient(false) { } virtual void fire(Frame* frame) { OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); - FrameLoadRequest request(m_securityOrigin.get(), ResourceRequest(KURL(ParsedURLString, m_url), m_referrer), "_self"); + FrameLoadRequest request(m_originDocument.get(), ResourceRequest(KURL(ParsedURLString, m_url), m_referrer), "_self"); request.setLockBackForwardList(lockBackForwardList()); - request.setClientRedirect(true); - frame->loader()->load(request); + request.setClientRedirect(ClientRedirect); + frame->loader().load(request); } - virtual void didStartTimer(Frame* frame, Timer<NavigationScheduler>* timer) - { - if (m_haveToldClient) - return; - m_haveToldClient = true; - - OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); - if (frame->loader()->history()->currentItemShouldBeReplaced()) - setLockBackForwardList(true); - } - - SecurityOrigin* securityOrigin() const { return m_securityOrigin.get(); } + Document* originDocument() const { return m_originDocument.get(); } String url() const { return m_url; } String referrer() const { return m_referrer; } private: - RefPtr<SecurityOrigin> m_securityOrigin; + RefPtr<Document> m_originDocument; String m_url; String m_referrer; - bool m_haveToldClient; }; class ScheduledRedirect : public ScheduledURLNavigation { public: - ScheduledRedirect(double delay, SecurityOrigin* securityOrigin, const String& url, bool lockBackForwardList) - : ScheduledURLNavigation(delay, securityOrigin, url, String(), lockBackForwardList, false) + ScheduledRedirect(double delay, Document* originDocument, const String& url, bool lockBackForwardList) + : ScheduledURLNavigation(delay, originDocument, url, String(), lockBackForwardList, false) { clearUserGesture(); } - virtual bool shouldStartTimer(Frame* frame) { return frame->loader()->allAncestorsAreComplete(); } + virtual bool shouldStartTimer(Frame* frame) { return frame->loader().allAncestorsAreComplete(); } virtual void fire(Frame* frame) { OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); - FrameLoadRequest request(securityOrigin(), ResourceRequest(KURL(ParsedURLString, url()), referrer()), "_self"); + FrameLoadRequest request(originDocument(), ResourceRequest(KURL(ParsedURLString, url()), referrer()), "_self"); request.setLockBackForwardList(lockBackForwardList()); if (equalIgnoringFragmentIdentifier(frame->document()->url(), request.resourceRequest().url())) request.resourceRequest().setCachePolicy(ReloadIgnoringCacheData); - request.setClientRedirect(true); - frame->loader()->load(request); + request.setClientRedirect(ClientRedirect); + frame->loader().load(request); } }; class ScheduledLocationChange : public ScheduledURLNavigation { public: - ScheduledLocationChange(SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockBackForwardList) - : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, lockBackForwardList, true) { } + ScheduledLocationChange(Document* originDocument, const String& url, const String& referrer, bool lockBackForwardList) + : ScheduledURLNavigation(0.0, originDocument, url, referrer, lockBackForwardList, true) { } }; class ScheduledRefresh : public ScheduledURLNavigation { public: - ScheduledRefresh(SecurityOrigin* securityOrigin, const String& url, const String& referrer) - : ScheduledURLNavigation(0.0, securityOrigin, url, referrer, true, true) + ScheduledRefresh(Document* originDocument, const String& url, const String& referrer) + : ScheduledURLNavigation(0.0, originDocument, url, referrer, true, true) { } virtual void fire(Frame* frame) { OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); - FrameLoadRequest request(securityOrigin(), ResourceRequest(KURL(ParsedURLString, url()), referrer(), ReloadIgnoringCacheData), "_self"); + FrameLoadRequest request(originDocument(), ResourceRequest(KURL(ParsedURLString, url()), referrer(), ReloadIgnoringCacheData), "_self"); request.setLockBackForwardList(lockBackForwardList()); - request.setClientRedirect(true); - frame->loader()->load(request); + request.setClientRedirect(ClientRedirect); + frame->loader().load(request); } }; @@ -195,16 +181,16 @@ public: OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); if (!m_historySteps) { - FrameLoadRequest frameRequest(frame->document()->securityOrigin(), ResourceRequest(frame->document()->url())); + FrameLoadRequest frameRequest(frame->document(), ResourceRequest(frame->document()->url())); frameRequest.setLockBackForwardList(lockBackForwardList()); // Special case for go(0) from a frame -> reload only the frame // To follow Firefox and IE's behavior, history reload can only navigate the self frame. - frame->loader()->load(frameRequest); + frame->loader().load(frameRequest); return; } // go(i!=0) from a frame navigates into the history of the frame only, // in both IE and NS (but not in Mozilla). We can't easily do that. - frame->page()->backForward().goBackOrForward(m_historySteps); + frame->page()->mainFrame()->loader().client()->navigateBackForward(m_historySteps); } private: @@ -214,9 +200,8 @@ private: class ScheduledFormSubmission : public ScheduledNavigation { public: ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBackForwardList) - : ScheduledNavigation(0, lockBackForwardList, submission->target().isNull()) + : ScheduledNavigation(0, lockBackForwardList, true) , m_submission(submission) - , m_haveToldClient(false) { ASSERT(m_submission->state()); } @@ -224,23 +209,12 @@ public: virtual void fire(Frame* frame) { OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); - FrameLoadRequest frameRequest(m_submission->state()->sourceDocument()->securityOrigin()); + FrameLoadRequest frameRequest(m_submission->state()->sourceDocument()); m_submission->populateFrameLoadRequest(frameRequest); frameRequest.setLockBackForwardList(lockBackForwardList()); frameRequest.setTriggeringEvent(m_submission->event()); frameRequest.setFormState(m_submission->state()); - frame->loader()->load(frameRequest); - } - - virtual void didStartTimer(Frame* frame, Timer<NavigationScheduler>* timer) - { - if (m_haveToldClient) - return; - m_haveToldClient = true; - - OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator(); - if (frame->loader()->history()->currentItemShouldBeReplaced()) - setLockBackForwardList(true); + frame->loader().load(frameRequest); } virtual bool isForm() const { return true; } @@ -248,7 +222,6 @@ public: private: RefPtr<FormSubmission> m_submission; - bool m_haveToldClient; }; NavigationScheduler::NavigationScheduler(Frame* frame) @@ -272,7 +245,6 @@ void NavigationScheduler::clear() InspectorInstrumentation::frameClearedScheduledNavigation(m_frame); m_timer.stop(); m_redirect.clear(); - m_additionalFormSubmissions.clear(); } inline bool NavigationScheduler::shouldScheduleNavigation() const @@ -296,23 +268,31 @@ void NavigationScheduler::scheduleRedirect(double delay, const String& url) // We want a new back/forward list item if the refresh timeout is > 1 second. if (!m_redirect || delay <= m_redirect->delay()) - schedule(adoptPtr(new ScheduledRedirect(delay, m_frame->document()->securityOrigin(), url, delay <= 1))); + schedule(adoptPtr(new ScheduledRedirect(delay, m_frame->document(), url, delay <= 1))); } bool NavigationScheduler::mustLockBackForwardList(Frame* targetFrame) { // Non-user navigation before the page has finished firing onload should not create a new back/forward item. // See https://webkit.org/b/42861 for the original motivation for this. - if (!ScriptController::processingUserGesture() && !targetFrame->document()->loadEventFinished()) + if (!UserGestureIndicator::processingUserGesture() && !targetFrame->document()->loadEventFinished()) + return true; + + // From the HTML5 spec for location.assign(): + // "If the browsing context's session history contains only one Document, + // and that was the about:blank Document created when the browsing context + // was created, then the navigation must be done with replacement enabled." + if (!targetFrame->loader().stateMachine()->committedMultipleRealLoads() + && equalIgnoringCase(targetFrame->document()->url(), blankURL())) return true; // Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item. // The definition of "during load" is any time before all handlers for the load event have been run. // See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this. - return targetFrame->tree()->parent() && !targetFrame->tree()->parent()->loader()->allAncestorsAreComplete(); + return targetFrame->tree().parent() && !targetFrame->tree().parent()->loader().allAncestorsAreComplete(); } -void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, const String& url, const String& referrer, bool lockBackForwardList) +void NavigationScheduler::scheduleLocationChange(Document* originDocument, const String& url, const String& referrer, bool lockBackForwardList) { if (!shouldScheduleNavigation(url)) return; @@ -321,36 +301,27 @@ void NavigationScheduler::scheduleLocationChange(SecurityOrigin* securityOrigin, lockBackForwardList = lockBackForwardList || mustLockBackForwardList(m_frame); - FrameLoader* loader = m_frame->loader(); - // If the URL we're going to navigate to is the same as the current one, except for the // fragment part, we don't need to schedule the location change. We'll skip this // optimization for cross-origin navigations to minimize the navigator's ability to // execute timing attacks. - if (securityOrigin->canAccess(m_frame->document()->securityOrigin())) { + if (originDocument->securityOrigin()->canAccess(m_frame->document()->securityOrigin())) { KURL parsedURL(ParsedURLString, url); if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame->document()->url(), parsedURL)) { - FrameLoadRequest request(securityOrigin, ResourceRequest(m_frame->document()->completeURL(url), referrer), "_self"); + FrameLoadRequest request(originDocument, ResourceRequest(m_frame->document()->completeURL(url), referrer), "_self"); request.setLockBackForwardList(lockBackForwardList); - request.setClientRedirect(true); - loader->load(request); + request.setClientRedirect(ClientRedirect); + m_frame->loader().load(request); return; } } - schedule(adoptPtr(new ScheduledLocationChange(securityOrigin, url, referrer, lockBackForwardList))); + schedule(adoptPtr(new ScheduledLocationChange(originDocument, url, referrer, lockBackForwardList))); } void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission) { ASSERT(m_frame->page()); - if (m_redirect && m_redirect->isForm()) { - if (submission->target() != static_cast<ScheduledFormSubmission*>(m_redirect.get())->submission()->target()) { - const String& target = submission->target().isNull() ? "" : submission->target(); - m_additionalFormSubmissions.add(target, adoptPtr(new ScheduledFormSubmission(submission, mustLockBackForwardList(m_frame)))); - return; - } - } schedule(adoptPtr(new ScheduledFormSubmission(submission, mustLockBackForwardList(m_frame)))); } @@ -362,7 +333,7 @@ void NavigationScheduler::scheduleRefresh() if (url.isEmpty()) return; - schedule(adoptPtr(new ScheduledRefresh(m_frame->document()->securityOrigin(), url.string(), m_frame->loader()->outgoingReferrer()))); + schedule(adoptPtr(new ScheduledRefresh(m_frame->document(), url.string(), m_frame->document()->outgoingReferrer()))); } void NavigationScheduler::scheduleHistoryNavigation(int steps) @@ -372,8 +343,8 @@ void NavigationScheduler::scheduleHistoryNavigation(int steps) // Invalid history navigations (such as history.forward() during a new load) have the side effect of cancelling any scheduled // redirects. We also avoid the possibility of cancelling the current load by avoiding the scheduled redirection altogether. - BackForwardController& backForward = m_frame->page()->backForward(); - if (steps > backForward.forwardCount() || -steps > backForward.backCount()) { + BackForwardClient& backForward = m_frame->page()->backForward(); + if (steps > backForward.forwardListCount() || -steps > backForward.backListCount()) { cancel(); return; } @@ -394,15 +365,7 @@ void NavigationScheduler::timerFired(Timer<NavigationScheduler>*) RefPtr<Frame> protect(m_frame); OwnPtr<ScheduledNavigation> redirect(m_redirect.release()); - HashMap<String, OwnPtr<ScheduledNavigation> > additionalFormSubmissions; - additionalFormSubmissions.swap(m_additionalFormSubmissions); redirect->fire(m_frame); - while (!additionalFormSubmissions.isEmpty()) { - HashMap<String, OwnPtr<ScheduledNavigation> >::iterator it = additionalFormSubmissions.begin(); - OwnPtr<ScheduledNavigation> formSubmission = it->value.release(); - additionalFormSubmissions.remove(it); - formSubmission->fire(m_frame); - } InspectorInstrumentation::frameClearedScheduledNavigation(m_frame); } @@ -426,7 +389,6 @@ void NavigationScheduler::startTimer() return; m_timer.startOneShot(m_redirect->delay()); - m_redirect->didStartTimer(m_frame, &m_timer); InspectorInstrumentation::frameScheduledNavigation(m_frame, m_redirect->delay()); } @@ -436,7 +398,6 @@ void NavigationScheduler::cancel() InspectorInstrumentation::frameClearedScheduledNavigation(m_frame); m_timer.stop(); m_redirect.clear(); - m_additionalFormSubmissions.clear(); } } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h index 07b610d0a7b..b10031e427c 100644 --- a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h +++ b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h @@ -31,7 +31,7 @@ #ifndef NavigationScheduler_h #define NavigationScheduler_h -#include "core/platform/Timer.h" +#include "platform/Timer.h" #include "wtf/Forward.h" #include "wtf/HashMap.h" #include "wtf/Noncopyable.h" @@ -42,10 +42,10 @@ namespace WebCore { +class Document; class FormSubmission; class Frame; class ScheduledNavigation; -class SecurityOrigin; class NavigationDisablerForBeforeUnload { WTF_MAKE_NONCOPYABLE(NavigationDisablerForBeforeUnload); @@ -76,7 +76,7 @@ public: bool locationChangePending(); void scheduleRedirect(double delay, const String& url); - void scheduleLocationChange(SecurityOrigin*, const String& url, const String& referrer, bool lockBackForwardList = true); + void scheduleLocationChange(Document*, const String& url, const String& referrer, bool lockBackForwardList = true); void scheduleFormSubmission(PassRefPtr<FormSubmission>); void scheduleRefresh(); void scheduleHistoryNavigation(int steps); @@ -98,7 +98,6 @@ private: Frame* m_frame; Timer<NavigationScheduler> m_timer; OwnPtr<ScheduledNavigation> m_redirect; - HashMap<String, OwnPtr<ScheduledNavigation> > m_additionalFormSubmissions; }; } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp index b9253d1a197..410143d86a4 100644 --- a/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp @@ -33,21 +33,20 @@ #include "core/loader/PingLoader.h" #include "core/dom/Document.h" +#include "core/frame/Frame.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" #include "core/loader/UniqueIdentifier.h" -#include "core/page/Frame.h" -#include "core/platform/chromium/support/WrappedResourceRequest.h" -#include "core/platform/network/FormData.h" -#include "core/platform/network/ResourceRequest.h" -#include "core/platform/network/ResourceResponse.h" +#include "platform/exported/WrappedResourceRequest.h" +#include "platform/network/FormData.h" +#include "platform/network/ResourceRequest.h" +#include "platform/network/ResourceResponse.h" +#include "platform/weborigin/SecurityOrigin.h" +#include "platform/weborigin/SecurityPolicy.h" #include "public/platform/Platform.h" #include "public/platform/WebURLLoader.h" -#include "weborigin/SecurityOrigin.h" -#include "weborigin/SecurityPolicy.h" #include "wtf/OwnPtr.h" -#include "wtf/UnusedParam.h" namespace WebCore { @@ -59,38 +58,37 @@ void PingLoader::loadImage(Frame* frame, const KURL& url) } ResourceRequest request(url); - request.setTargetType(ResourceRequest::TargetIsImage); + request.setTargetType(ResourceRequest::TargetIsPing); request.setHTTPHeaderField("Cache-Control", "max-age=0"); - String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), request.url(), frame->loader()->outgoingReferrer()); + String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), request.url(), frame->document()->outgoingReferrer()); if (!referrer.isEmpty()) request.setHTTPReferrer(referrer); - frame->loader()->addExtraFieldsToRequest(request); + frame->loader().addExtraFieldsToRequest(request); OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request)); // Leak the ping loader, since it will kill itself as soon as it receives a response. - PingLoader* leakedPingLoader = pingLoader.leakPtr(); - UNUSED_PARAM(leakedPingLoader); + PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr(); } // http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing void PingLoader::sendPing(Frame* frame, const KURL& pingURL, const KURL& destinationURL) { ResourceRequest request(pingURL); - request.setTargetType(ResourceRequest::TargetIsSubresource); + request.setTargetType(ResourceRequest::TargetIsPing); request.setHTTPMethod("POST"); request.setHTTPContentType("text/ping"); request.setHTTPBody(FormData::create("PING")); request.setHTTPHeaderField("Cache-Control", "max-age=0"); - frame->loader()->addExtraFieldsToRequest(request); + frame->loader().addExtraFieldsToRequest(request); SecurityOrigin* sourceOrigin = frame->document()->securityOrigin(); RefPtr<SecurityOrigin> pingOrigin = SecurityOrigin::create(pingURL); FrameLoader::addHTTPOriginIfNeeded(request, sourceOrigin->toString()); request.setHTTPHeaderField("Ping-To", destinationURL.string()); - if (!SecurityPolicy::shouldHideReferrer(pingURL, frame->loader()->outgoingReferrer())) { + if (!SecurityPolicy::shouldHideReferrer(pingURL, frame->document()->outgoingReferrer())) { request.setHTTPHeaderField("Ping-From", frame->document()->url().string()); if (!sourceOrigin->isSameSchemeHostPort(pingOrigin.get())) { - String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), pingURL, frame->loader()->outgoingReferrer()); + String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), pingURL, frame->document()->outgoingReferrer()); if (!referrer.isEmpty()) request.setHTTPReferrer(referrer); } @@ -98,8 +96,7 @@ void PingLoader::sendPing(Frame* frame, const KURL& pingURL, const KURL& destina OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request)); // Leak the ping loader, since it will kill itself as soon as it receives a response. - PingLoader* leakedPingLoader = pingLoader.leakPtr(); - UNUSED_PARAM(leakedPingLoader); + PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr(); } void PingLoader::sendViolationReport(Frame* frame, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType type) @@ -109,31 +106,30 @@ void PingLoader::sendViolationReport(Frame* frame, const KURL& reportURL, PassRe request.setHTTPMethod("POST"); request.setHTTPContentType(type == ContentSecurityPolicyViolationReport ? "application/csp-report" : "application/json"); request.setHTTPBody(report); - frame->loader()->addExtraFieldsToRequest(request); + frame->loader().addExtraFieldsToRequest(request); - String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), reportURL, frame->loader()->outgoingReferrer()); + String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), reportURL, frame->document()->outgoingReferrer()); if (!referrer.isEmpty()) request.setHTTPReferrer(referrer); OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request, SecurityOrigin::create(reportURL)->isSameSchemeHostPort(frame->document()->securityOrigin()) ? AllowStoredCredentials : DoNotAllowStoredCredentials)); // Leak the ping loader, since it will kill itself as soon as it receives a response. - PingLoader* leakedPingLoader = pingLoader.leakPtr(); - UNUSED_PARAM(leakedPingLoader); + PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr(); } PingLoader::PingLoader(Frame* frame, ResourceRequest& request, StoredCredentials credentialsAllowed) : m_timeout(this, &PingLoader::timeout) { - frame->loader()->client()->didDispatchPingLoader(request.url()); + frame->loader().client()->didDispatchPingLoader(request.url()); unsigned long identifier = createUniqueIdentifier(); - m_loader = adoptPtr(WebKit::Platform::current()->createURLLoader()); + m_loader = adoptPtr(blink::Platform::current()->createURLLoader()); ASSERT(m_loader); - WebKit::WrappedResourceRequest wrappedRequest(request); + blink::WrappedResourceRequest wrappedRequest(request); wrappedRequest.setAllowStoredCredentials(credentialsAllowed == AllowStoredCredentials); m_loader->loadAsynchronously(wrappedRequest, this); - InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame->loader()->activeDocumentLoader(), request, ResourceResponse()); + InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame->loader().activeDocumentLoader(), request, ResourceResponse()); // If the server never responds, FrameLoader won't be able to cancel this load and // we'll sit here waiting forever. Set a very generous timeout, just in case. diff --git a/chromium/third_party/WebKit/Source/core/loader/PingLoader.h b/chromium/third_party/WebKit/Source/core/loader/PingLoader.h index 80f7070aef7..e22f84caaf4 100644 --- a/chromium/third_party/WebKit/Source/core/loader/PingLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/PingLoader.h @@ -33,7 +33,7 @@ #define PingLoader_h #include "core/fetch/ResourceLoaderOptions.h" -#include "core/platform/Timer.h" +#include "platform/Timer.h" #include "public/platform/WebURLLoaderClient.h" #include "wtf/Noncopyable.h" #include "wtf/RefPtr.h" @@ -53,7 +53,7 @@ class ResourceResponse; // to allow the load to live long enough to ensure the message was actually sent. // Therefore, as soon as a callback is received from the ResourceHandle, this class // will cancel the load and delete itself. -class PingLoader : private WebKit::WebURLLoaderClient { +class PingLoader : private blink::WebURLLoaderClient { WTF_MAKE_NONCOPYABLE(PingLoader); WTF_MAKE_FAST_ALLOCATED; public: enum ViolationReportType { @@ -70,13 +70,13 @@ public: private: PingLoader(Frame*, ResourceRequest&, StoredCredentials = AllowStoredCredentials); - virtual void didReceiveResponse(WebKit::WebURLLoader*, const WebKit::WebURLResponse&) OVERRIDE { delete this; } - virtual void didReceiveData(WebKit::WebURLLoader*, const char*, int, int) OVERRIDE { delete this; } - virtual void didFinishLoading(WebKit::WebURLLoader*, double) OVERRIDE { delete this; } - virtual void didFail(WebKit::WebURLLoader*, const WebKit::WebURLError&) OVERRIDE { delete this; } + virtual void didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse&) OVERRIDE { delete this; } + virtual void didReceiveData(blink::WebURLLoader*, const char*, int, int) OVERRIDE { delete this; } + virtual void didFinishLoading(blink::WebURLLoader*, double) OVERRIDE { delete this; } + virtual void didFail(blink::WebURLLoader*, const blink::WebURLError&) OVERRIDE { delete this; } void timeout(Timer<PingLoader>*) { delete this; } - OwnPtr<WebKit::WebURLLoader> m_loader; + OwnPtr<blink::WebURLLoader> m_loader; Timer<PingLoader> m_timeout; }; diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp new file mode 100644 index 00000000000..763506ab77a --- /dev/null +++ b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "core/loader/PrerenderHandle.h" + +#include "core/dom/Document.h" +#include "core/frame/Frame.h" +#include "core/loader/FrameLoader.h" +#include "core/loader/PrerendererClient.h" +#include "platform/Prerender.h" +#include "platform/weborigin/ReferrerPolicy.h" +#include "platform/weborigin/SecurityPolicy.h" + +namespace WebCore { + +// static +PassOwnPtr<PrerenderHandle> PrerenderHandle::create(Document& document, PrerenderClient* client, const KURL& url) +{ + // Prerenders are unlike requests in most ways (for instance, they pass down fragments, and they don't return data), + // but they do have referrers. + const ReferrerPolicy referrerPolicy = document.referrerPolicy(); + + if (!document.frame()) + return PassOwnPtr<PrerenderHandle>(); + + const String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, document.outgoingReferrer()); + + RefPtr<Prerender> prerender = Prerender::create(client, url, referrer, referrerPolicy); + + PrerendererClient* prerendererClient = PrerendererClient::from(document.page()); + if (prerendererClient) + prerendererClient->willAddPrerender(prerender.get()); + prerender->add(); + + return adoptPtr(new PrerenderHandle(document, prerender.release())); +} + +PrerenderHandle::PrerenderHandle(Document& document, PassRefPtr<Prerender> prerender) + : DocumentLifecycleObserver(&document) + , m_prerender(prerender) +{ +} + +PrerenderHandle::~PrerenderHandle() +{ + if (m_prerender) + detach(); +} + +void PrerenderHandle::cancel() +{ + // Avoid both abandoning and canceling the same prerender. In the abandon case, the LinkLoader cancels the + // PrerenderHandle as the Document is destroyed, even through the DocumentLifecycleObserver has already abandoned + // it. + if (!m_prerender) + return; + m_prerender->cancel(); + detach(); +} + +const KURL& PrerenderHandle::url() const +{ + return m_prerender->url(); +} + +void PrerenderHandle::documentWasDetached() +{ + ASSERT(m_prerender); + m_prerender->abandon(); + detach(); +} + + +void PrerenderHandle::detach() +{ + m_prerender->removeClient(); + m_prerender.clear(); +} + +} diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLParser.h b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h index dda8bd34018..2adc058b85b 100644 --- a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLParser.h +++ b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Google Inc. All rights reserved. + * Copyright (C) 2013 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -28,45 +28,41 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MHTMLParser_h -#define MHTMLParser_h +#ifndef PrerenderHandle_h +#define PrerenderHandle_h -#include "core/platform/SharedBufferChunkReader.h" -#include "wtf/RefPtr.h" -#include "wtf/Vector.h" -#include "wtf/text/WTFString.h" +#include "core/dom/DocumentLifecycleObserver.h" +#include "platform/weborigin/KURL.h" +#include "wtf/Noncopyable.h" +#include "wtf/PassOwnPtr.h" +#include "wtf/PassRefPtr.h" namespace WebCore { -class ArchiveResource; -class MHTMLArchive; -class MIMEHeader; -class SharedBuffer; +class Document; +class Prerender; +class PrerenderClient; -class MHTMLParser { +class PrerenderHandle : public DocumentLifecycleObserver { + WTF_MAKE_NONCOPYABLE(PrerenderHandle); public: - explicit MHTMLParser(SharedBuffer*); + static PassOwnPtr<PrerenderHandle> create(Document&, PrerenderClient*, const KURL&); - PassRefPtr<MHTMLArchive> parseArchive(); + virtual ~PrerenderHandle(); - size_t frameCount() const; - MHTMLArchive* frameAt(size_t) const; - - size_t subResourceCount() const; - ArchiveResource* subResourceAt(size_t) const; + void cancel(); + const KURL& url() const; + // From DocumentLifecycleObserver: + virtual void documentWasDetached() OVERRIDE; private: - PassRefPtr<MHTMLArchive> parseArchiveWithHeader(MIMEHeader*); - PassRefPtr<ArchiveResource> parseNextPart(const MIMEHeader&, const String& endOfPartBoundary, const String& endOfDocumentBoundary, bool& endOfArchiveReached); + PrerenderHandle(Document&, PassRefPtr<Prerender>); - void addResourceToArchive(ArchiveResource*, MHTMLArchive*); + void detach(); - SharedBufferChunkReader m_lineReader; - Vector<RefPtr<ArchiveResource> > m_resources; - Vector<RefPtr<MHTMLArchive> > m_frames; + RefPtr<Prerender> m_prerender; }; } -#endif - +#endif // PrerenderHandle_h diff --git a/chromium/third_party/WebKit/Source/core/loader/Prerenderer.cpp b/chromium/third_party/WebKit/Source/core/loader/Prerenderer.cpp deleted file mode 100644 index 75f454d2319..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/Prerenderer.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "config.h" -#include "core/loader/Prerenderer.h" - -#include "core/dom/Document.h" -#include "core/loader/FrameLoader.h" -#include "core/loader/PrerendererClient.h" -#include "core/page/Frame.h" -#include "core/platform/PrerenderHandle.h" -#include "weborigin/ReferrerPolicy.h" -#include "weborigin/SecurityPolicy.h" - -#include "wtf/PassOwnPtr.h" -#include "wtf/PassRefPtr.h" -#include "wtf/RefPtr.h" -#include "wtf/text/WTFString.h" - -namespace WebCore { - -// static -PassOwnPtr<Prerenderer> Prerenderer::create(Document* document) -{ - Prerenderer* prerenderer = new Prerenderer(document); - prerenderer->suspendIfNeeded(); - return adoptPtr(prerenderer); -} - -Prerenderer::Prerenderer(Document* document) - : ActiveDOMObject(document) - , m_initializedClient(false) - , m_client(0) -{ -} - -Prerenderer::~Prerenderer() -{ -} - -PassRefPtr<PrerenderHandle> Prerenderer::render(PrerenderClient* prerenderClient, const KURL& url) -{ - // Prerenders are unlike requests in most ways (for instance, they pass down fragments, and they don't return data), - // but they do have referrers. - const ReferrerPolicy referrerPolicy = document()->referrerPolicy(); - - if (!document()->frame()) - return 0; - - const String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, document()->frame()->loader()->outgoingReferrer()); - - RefPtr<PrerenderHandle> prerenderHandle = PrerenderHandle::create(prerenderClient, url, referrer, referrerPolicy); - - if (client()) - client()->willAddPrerender(prerenderHandle.get()); - prerenderHandle->add(); - - // FIXME: This handle isn't released until page unload, but it may be canceled before then. It should be released in that case. - m_activeHandles.append(prerenderHandle); - return prerenderHandle; -} - -void Prerenderer::stop() -{ - while (!m_activeHandles.isEmpty()) { - RefPtr<PrerenderHandle> handle = m_activeHandles[0].release(); - m_activeHandles.remove(0); - handle->abandon(); - } - while (!m_suspendedHandles.isEmpty()) { - RefPtr<PrerenderHandle> handle = m_suspendedHandles[0].release(); - m_suspendedHandles.remove(0); - handle->abandon(); - } -} - -void Prerenderer::suspend(ReasonForSuspension reason) -{ - if (reason == DocumentWillBecomeInactive) { - while (!m_activeHandles.isEmpty()) { - RefPtr<PrerenderHandle> handle = m_activeHandles[0].release(); - m_activeHandles.remove(0); - handle->suspend(); - m_suspendedHandles.append(handle); - } - } -} - -void Prerenderer::resume() -{ - while (!m_suspendedHandles.isEmpty()) { - RefPtr<PrerenderHandle> handle = m_suspendedHandles[0].release(); - m_suspendedHandles.remove(0); - handle->resume(); - m_activeHandles.append(handle); - } -} - -Document* Prerenderer::document() -{ - ASSERT(scriptExecutionContext()->isDocument()); - return toDocument(scriptExecutionContext()); -} - -PrerendererClient* Prerenderer::client() -{ - if (!m_initializedClient) { - // We can't initialize the client in our contructor, because the platform might not have - // provided our supplement by then. - m_initializedClient = true; - m_client = PrerendererClient::from(document()->page()); - } - return m_client; -} - -} diff --git a/chromium/third_party/WebKit/Source/core/loader/Prerenderer.h b/chromium/third_party/WebKit/Source/core/loader/Prerenderer.h deleted file mode 100644 index a7545652f2a..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/Prerenderer.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef Prerenderer_h -#define Prerenderer_h - -#include "core/dom/ActiveDOMObject.h" -#include "weborigin/KURL.h" -#include "wtf/PassOwnPtr.h" -#include "wtf/PassRefPtr.h" -#include "wtf/RefPtr.h" -#include "wtf/Vector.h" - -namespace WebCore { - -class Document; -class PrerenderClient; -class PrerenderHandle; -class PrerendererClient; -class Page; - -class Prerenderer : public ActiveDOMObject { - WTF_MAKE_NONCOPYABLE(Prerenderer); -public: - virtual ~Prerenderer(); - - PassRefPtr<PrerenderHandle> render(PrerenderClient*, const KURL&); - - static PassOwnPtr<Prerenderer> create(Document*); - - // From ActiveDOMObject: - virtual bool canSuspend() const OVERRIDE { return true; } - virtual void stop() OVERRIDE; - virtual void suspend(ReasonForSuspension) OVERRIDE; - virtual void resume() OVERRIDE; - -private: - typedef Vector<RefPtr<PrerenderHandle> > HandleVector; - typedef Vector<KURL> KURLVector; - - explicit Prerenderer(Document*); - - Document* document(); - PrerendererClient* client(); - - bool m_initializedClient; - PrerendererClient* m_client; - HandleVector m_activeHandles; - HandleVector m_suspendedHandles; -}; - -} - -#endif // Prerenderer_h diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp index e7149fbfab7..3db482676ec 100644 --- a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp @@ -33,7 +33,6 @@ #include "core/loader/PrerendererClient.h" #include "core/page/Page.h" -#include "core/platform/Supplementable.h" namespace WebCore { diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h index 4a9eafeca2f..4c6a1952cc7 100644 --- a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h +++ b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h @@ -32,19 +32,19 @@ #ifndef PrerendererClient_h #define PrerendererClient_h -#include "core/platform/Supplementable.h" +#include "platform/Supplementable.h" namespace WebCore { class Document; class Page; -class PrerenderHandle; +class Prerender; class PrerendererClient : public Supplement<Page> { public: virtual ~PrerendererClient() { } - virtual void willAddPrerender(PrerenderHandle*) = 0; + virtual void willAddPrerender(Prerender*) = 0; static const char* supplementName(); static PrerendererClient* from(Page*); diff --git a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp index 2daa653e1b7..df7477cb71f 100644 --- a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp @@ -26,13 +26,13 @@ #include "config.h" #include "core/loader/ProgressTracker.h" +#include "core/frame/Frame.h" +#include "core/frame/FrameView.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" -#include "core/page/Frame.h" -#include "core/page/FrameView.h" -#include "core/platform/Logging.h" -#include "core/platform/network/ResourceResponse.h" +#include "platform/Logging.h" +#include "platform/network/ResourceResponse.h" #include "wtf/CurrentTime.h" #include "wtf/text/CString.h" @@ -104,14 +104,14 @@ void ProgressTracker::reset() void ProgressTracker::progressStarted(Frame* frame) { - LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); + WTF_LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree().uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); if (m_numProgressTrackedFrames == 0 || m_originatingProgressFrame == frame) { reset(); m_progressValue = initialProgressValue; m_originatingProgressFrame = frame; - m_originatingProgressFrame->loader()->client()->postProgressStartedNotification(); + m_originatingProgressFrame->loader().client()->postProgressStartedNotification(); } m_numProgressTrackedFrames++; InspectorInstrumentation::frameStartedLoading(frame); @@ -119,7 +119,7 @@ void ProgressTracker::progressStarted(Frame* frame) void ProgressTracker::progressCompleted(Frame* frame) { - LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree()->uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); + WTF_LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree().uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); if (m_numProgressTrackedFrames <= 0) return; @@ -130,7 +130,7 @@ void ProgressTracker::progressCompleted(Frame* frame) void ProgressTracker::finalProgressComplete() { - LOG(Progress, "Final progress complete (%p)", this); + WTF_LOG(Progress, "Final progress complete (%p)", this); RefPtr<Frame> frame = m_originatingProgressFrame.release(); @@ -138,17 +138,17 @@ void ProgressTracker::finalProgressComplete() // with final progress value. if (!m_finalProgressChangedSent) { m_progressValue = 1; - frame->loader()->client()->postProgressEstimateChangedNotification(); + frame->loader().client()->postProgressEstimateChangedNotification(); } reset(); - frame->loader()->client()->postProgressFinishedNotification(); + frame->loader().client()->postProgressFinishedNotification(); InspectorInstrumentation::frameStoppedLoading(frame.get()); } void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response) { - LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d, originating frame %p", this, m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); + WTF_LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d, originating frame %p", this, m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get()); if (m_numProgressTrackedFrames <= 0) return; @@ -186,7 +186,7 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i item->estimatedLength = item->bytesReceived * 2; } - int numPendingOrLoadingRequests = frame->loader()->numPendingOrLoadingRequests(true); + int numPendingOrLoadingRequests = frame->loader().numPendingOrLoadingRequests(true); estimatedBytesForPendingRequests = progressItemDefaultEstimatedLength * numPendingOrLoadingRequests; remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived); if (remainingBytes > 0) // Prevent divide by 0. @@ -207,7 +207,7 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i double now = currentTime(); double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime; - LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d", this, m_progressValue, m_numProgressTrackedFrames); + WTF_LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d", this, m_progressValue, m_numProgressTrackedFrames); double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue; if ((notificationProgressDelta >= m_progressNotificationInterval || notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) && @@ -216,7 +216,7 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i if (m_progressValue == 1) m_finalProgressChangedSent = true; - frame->loader()->client()->postProgressEstimateChangedNotification(); + frame->loader().client()->postProgressEstimateChangedNotification(); m_lastNotifiedProgressValue = m_progressValue; m_lastNotifiedProgressTime = now; diff --git a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h index f7516c70e74..fa7612f9dab 100644 --- a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h +++ b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h @@ -38,6 +38,9 @@ class Frame; class ResourceResponse; struct ProgressItem; +// FIXME: This is only used on Android. Android is the only Chrome +// browser which shows a progress bar during loading. +// We should find a better way for Android to get this data and remove this! class ProgressTracker { WTF_MAKE_NONCOPYABLE(ProgressTracker); WTF_MAKE_FAST_ALLOCATED; public: diff --git a/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp b/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp index 11839f7318b..990b71af0f4 100644 --- a/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp @@ -44,7 +44,7 @@ private: } // Ignore all data. - virtual size_t appendBytes(const char*, size_t) OVERRIDE { return 0; } + virtual void appendBytes(const char*, size_t) OVERRIDE { } }; SinkDocument::SinkDocument(const DocumentInit& initializer) diff --git a/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h b/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h index ad6f2b7bab6..48f19283a24 100644 --- a/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h +++ b/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h @@ -26,8 +26,8 @@ #ifndef SubstituteData_h #define SubstituteData_h -#include "core/platform/SharedBuffer.h" -#include "weborigin/KURL.h" +#include "platform/SharedBuffer.h" +#include "platform/weborigin/KURL.h" #include "wtf/PassRefPtr.h" #include "wtf/RefPtr.h" @@ -37,7 +37,7 @@ namespace WebCore { public: SubstituteData() { } - SubstituteData(PassRefPtr<SharedBuffer> content, const String& mimeType, const String& textEncoding, const KURL& failingURL) + SubstituteData(PassRefPtr<SharedBuffer> content, const AtomicString& mimeType, const AtomicString& textEncoding, const KURL& failingURL) : m_content(content) , m_mimeType(mimeType) , m_textEncoding(textEncoding) @@ -48,14 +48,14 @@ namespace WebCore { bool isValid() const { return m_content != 0; } const SharedBuffer* content() const { return m_content.get(); } - const String& mimeType() const { return m_mimeType; } - const String& textEncoding() const { return m_textEncoding; } + const AtomicString& mimeType() const { return m_mimeType; } + const AtomicString& textEncoding() const { return m_textEncoding; } const KURL& failingURL() const { return m_failingURL; } private: RefPtr<SharedBuffer> m_content; - String m_mimeType; - String m_textEncoding; + AtomicString m_mimeType; + AtomicString m_textEncoding; KURL m_failingURL; KURL m_responseURL; }; diff --git a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp index 1ad37828d03..ff4002adb3a 100644 --- a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp @@ -32,9 +32,9 @@ #include "core/loader/TextResourceDecoderBuilder.h" #include "core/dom/Document.h" -#include "core/page/Frame.h" -#include "core/page/Settings.h" -#include "weborigin/SecurityOrigin.h" +#include "core/frame/Frame.h" +#include "core/frame/Settings.h" +#include "platform/weborigin/SecurityOrigin.h" namespace WebCore { @@ -44,7 +44,7 @@ static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame } -TextResourceDecoderBuilder::TextResourceDecoderBuilder(const String& mimeType, const String& encoding, bool encodingUserChoosen) +TextResourceDecoderBuilder::TextResourceDecoderBuilder(const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen) : m_mimeType(mimeType) , m_encoding(encoding) , m_encodingWasChosenByUser(encodingUserChoosen) @@ -56,7 +56,7 @@ TextResourceDecoderBuilder::~TextResourceDecoderBuilder() } -inline PassRefPtr<TextResourceDecoder> TextResourceDecoderBuilder::createDecoderInstance(Document* document) +inline PassOwnPtr<TextResourceDecoder> TextResourceDecoderBuilder::createDecoderInstance(Document* document) { if (Frame* frame = document->frame()) { if (Settings* settings = frame->settings()) @@ -69,10 +69,10 @@ inline PassRefPtr<TextResourceDecoder> TextResourceDecoderBuilder::createDecoder inline void TextResourceDecoderBuilder::setupEncoding(TextResourceDecoder* decoder, Document* document) { Frame* frame = document->frame(); - Frame* parentFrame = frame ? frame->tree()->parent() : 0; + Frame* parentFrame = frame ? frame->tree().parent() : 0; if (!m_encoding.isEmpty()) - decoder->setEncoding(m_encoding, m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader); + decoder->setEncoding(m_encoding.string(), m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader); // Set the hint encoding to the parent frame encoding only if // the parent and the current frames share the security origin. @@ -84,24 +84,25 @@ inline void TextResourceDecoderBuilder::setupEncoding(TextResourceDecoder* decod // FIXME: This might be too cautious for non-7bit-encodings and // we may consider relaxing this later after testing. if (frame && canReferToParentFrameEncoding(frame, parentFrame)) { - decoder->setHintEncoding(parentFrame->document()->decoder()); + if (parentFrame->document()->encodingWasDetectedHeuristically()) + decoder->setHintEncoding(parentFrame->document()->encoding()); + if (m_encoding.isEmpty()) - decoder->setEncoding(parentFrame->document()->inputEncoding(), TextResourceDecoder::EncodingFromParentFrame); + decoder->setEncoding(parentFrame->document()->inputEncoding().string(), TextResourceDecoder::EncodingFromParentFrame); } } -PassRefPtr<TextResourceDecoder> TextResourceDecoderBuilder::buildFor(Document* document) +PassOwnPtr<TextResourceDecoder> TextResourceDecoderBuilder::buildFor(Document* document) { - RefPtr<TextResourceDecoder> decoder = createDecoderInstance(document); + OwnPtr<TextResourceDecoder> decoder = createDecoderInstance(document); setupEncoding(decoder.get(), document); - document->setDecoder(decoder); return decoder.release(); } void TextResourceDecoderBuilder::clear() { if (!m_encodingWasChosenByUser) - m_encoding = String(); + m_encoding = nullAtom; } } diff --git a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h index c2a57b9f4da..b6c27c77464 100644 --- a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h +++ b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h @@ -42,23 +42,23 @@ class TextResourceDecoder; class TextResourceDecoderBuilder { public: - TextResourceDecoderBuilder(const String& mimeType, const String& encoding, bool encodingUserChoosen); + TextResourceDecoderBuilder(const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen); ~TextResourceDecoderBuilder(); - PassRefPtr<TextResourceDecoder> buildFor(Document*); + PassOwnPtr<TextResourceDecoder> buildFor(Document*); - const String& mimeType() const { return m_mimeType; } - const String& encoding() const { return m_encoding; } + const AtomicString& mimeType() const { return m_mimeType; } + const AtomicString& encoding() const { return m_encoding; } bool encodingWasChosenByUser() const { return m_encodingWasChosenByUser; } void clear(); private: - PassRefPtr<TextResourceDecoder> createDecoderInstance(Document*); + PassOwnPtr<TextResourceDecoder> createDecoderInstance(Document*); void setupEncoding(TextResourceDecoder*, Document*); - String m_mimeType; - String m_encoding; + AtomicString m_mimeType; + AtomicString m_encoding; bool m_encodingWasChosenByUser; }; diff --git a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp index 7e6fd8612a5..121a2b5c163 100644 --- a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp @@ -32,28 +32,23 @@ #include "core/fetch/CrossOriginAccessControl.h" #include "core/fetch/FetchRequest.h" #include "core/fetch/ResourceFetcher.h" -#include "core/fetch/TextTrackResource.h" -#include "core/html/track/WebVTTParser.h" -#include "core/platform/Logging.h" -#include "core/platform/SharedBuffer.h" -#include "weborigin/SecurityOrigin.h" +#include "platform/Logging.h" +#include "platform/SharedBuffer.h" +#include "platform/weborigin/SecurityOrigin.h" namespace WebCore { -TextTrackLoader::TextTrackLoader(TextTrackLoaderClient* client, ScriptExecutionContext* context) +TextTrackLoader::TextTrackLoader(TextTrackLoaderClient& client, Document& document) : m_client(client) - , m_scriptExecutionContext(context) + , m_document(document) , m_cueLoadTimer(this, &TextTrackLoader::cueLoadTimerFired) , m_state(Idle) - , m_parseOffset(0) , m_newCuesAvailable(false) { } TextTrackLoader::~TextTrackLoader() { - if (m_cachedCueData) - m_cachedCueData->removeClient(this); } void TextTrackLoader::cueLoadTimerFired(Timer<TextTrackLoader>* timer) @@ -62,80 +57,54 @@ void TextTrackLoader::cueLoadTimerFired(Timer<TextTrackLoader>* timer) if (m_newCuesAvailable) { m_newCuesAvailable = false; - m_client->newCuesAvailable(this); + m_client.newCuesAvailable(this); } if (m_state >= Finished) - m_client->cueLoadingCompleted(this, m_state == Failed); + m_client.cueLoadingCompleted(this, m_state == Failed); } void TextTrackLoader::cancelLoad() { - if (m_cachedCueData) { - m_cachedCueData->removeClient(this); - m_cachedCueData = 0; - } + clearResource(); } -void TextTrackLoader::processNewCueData(Resource* resource) +void TextTrackLoader::dataReceived(Resource* resource, const char* data, int length) { - ASSERT(m_cachedCueData == resource); - - if (m_state == Failed || !resource->resourceBuffer()) - return; + ASSERT(this->resource() == resource); - SharedBuffer* buffer = resource->resourceBuffer(); - if (m_parseOffset == buffer->size()) + if (m_state == Failed) return; if (!m_cueParser) - m_cueParser = WebVTTParser::create(this, m_scriptExecutionContext); - - const char* data; - unsigned length; - - while ((length = buffer->getSomeData(data, m_parseOffset))) { - m_cueParser->parseBytes(data, length); - m_parseOffset += length; - } -} - -// FIXME: This is a very unusual pattern, no other ResourceClient does this. Refactor to use notifyFinished() instead. -void TextTrackLoader::deprecatedDidReceiveResource(Resource* resource) -{ - ASSERT(m_cachedCueData == resource); + m_cueParser = VTTParser::create(this, m_document); - if (!resource->resourceBuffer()) - return; - - processNewCueData(resource); + m_cueParser->parseBytes(data, length); } void TextTrackLoader::corsPolicyPreventedLoad() { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin text track load denied by Cross-Origin Resource Sharing policy.")); - Document* document = toDocument(m_scriptExecutionContext); - document->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage); + m_document.addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage); m_state = Failed; } void TextTrackLoader::notifyFinished(Resource* resource) { - ASSERT(m_cachedCueData == resource); + ASSERT(this->resource() == resource); - Document* document = toDocument(m_scriptExecutionContext); if (!m_crossOriginMode.isNull() - && !document->securityOrigin()->canRequest(resource->response().url()) - && !resource->passesAccessControlCheck(document->securityOrigin())) { + && !m_document.securityOrigin()->canRequest(resource->response().url()) + && !resource->passesAccessControlCheck(m_document.securityOrigin())) { corsPolicyPreventedLoad(); } - if (m_state != Failed) { - processNewCueData(resource); - if (m_state != Failed) - m_state = resource->errorOccurred() ? Failed : Finished; - } + if (m_state != Failed) + m_state = resource->errorOccurred() ? Failed : Finished; + + if (m_state == Finished && m_cueParser) + m_cueParser->flush(); if (!m_cueLoadTimer.isActive()) m_cueLoadTimer.startOneShot(0); @@ -147,33 +116,23 @@ bool TextTrackLoader::load(const KURL& url, const String& crossOriginMode) { cancelLoad(); - if (!m_client->shouldLoadCues(this)) - return false; - - ASSERT(m_scriptExecutionContext->isDocument()); - Document* document = toDocument(m_scriptExecutionContext); - FetchRequest cueRequest(ResourceRequest(document->completeURL(url)), FetchInitiatorTypeNames::texttrack); + FetchRequest cueRequest(ResourceRequest(m_document.completeURL(url)), FetchInitiatorTypeNames::texttrack); if (!crossOriginMode.isNull()) { m_crossOriginMode = crossOriginMode; StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials; - updateRequestForAccessControl(cueRequest.mutableResourceRequest(), document->securityOrigin(), allowCredentials); + updateRequestForAccessControl(cueRequest.mutableResourceRequest(), m_document.securityOrigin(), allowCredentials); } else { // Cross-origin resources that are not suitably CORS-enabled may not load. - if (!document->securityOrigin()->canRequest(url)) { + if (!m_document.securityOrigin()->canRequest(url)) { corsPolicyPreventedLoad(); return false; } } - ResourceFetcher* fetcher = document->fetcher(); - m_cachedCueData = fetcher->fetchTextTrack(cueRequest); - if (m_cachedCueData) - m_cachedCueData->addClient(this); - - m_client->cueLoadingStarted(this); - - return true; + ResourceFetcher* fetcher = m_document.fetcher(); + setResource(fetcher->fetchRawResource(cueRequest)); + return resource(); } void TextTrackLoader::newCuesParsed() @@ -185,16 +144,14 @@ void TextTrackLoader::newCuesParsed() m_cueLoadTimer.startOneShot(0); } -#if ENABLE(WEBVTT_REGIONS) void TextTrackLoader::newRegionsParsed() { - m_client->newRegionsAvailable(this); + m_client.newRegionsAvailable(this); } -#endif void TextTrackLoader::fileFailedToParse() { - LOG(Media, "TextTrackLoader::fileFailedToParse"); + WTF_LOG(Media, "TextTrackLoader::fileFailedToParse"); m_state = Failed; @@ -204,20 +161,18 @@ void TextTrackLoader::fileFailedToParse() cancelLoad(); } -void TextTrackLoader::getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues) +void TextTrackLoader::getNewCues(Vector<RefPtr<VTTCue> >& outputCues) { ASSERT(m_cueParser); if (m_cueParser) m_cueParser->getNewCues(outputCues); } -#if ENABLE(WEBVTT_REGIONS) -void TextTrackLoader::getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions) +void TextTrackLoader::getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions) { ASSERT(m_cueParser); if (m_cueParser) m_cueParser->getNewRegions(outputRegions); } -#endif -} +} diff --git a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h index 4eb68a81aa6..4ab8e95fd38 100644 --- a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h @@ -26,39 +26,33 @@ #ifndef TextTrackLoader_h #define TextTrackLoader_h -#include "core/fetch/ResourceClient.h" -#include "core/fetch/ResourcePtr.h" -#include "core/fetch/TextTrackResource.h" -#include "core/html/track/WebVTTParser.h" -#include "core/platform/Timer.h" +#include "core/fetch/RawResource.h" +#include "core/fetch/ResourceOwner.h" +#include "core/html/track/vtt/VTTParser.h" +#include "platform/Timer.h" #include "wtf/OwnPtr.h" namespace WebCore { class Document; class TextTrackLoader; -class ScriptExecutionContext; -class TextTrackLoaderClient { +class TextTrackLoaderClient : public ResourceOwner<RawResource> { public: virtual ~TextTrackLoaderClient() { } - virtual bool shouldLoadCues(TextTrackLoader*) = 0; virtual void newCuesAvailable(TextTrackLoader*) = 0; - virtual void cueLoadingStarted(TextTrackLoader*) = 0; virtual void cueLoadingCompleted(TextTrackLoader*, bool loadingFailed) = 0; -#if ENABLE(WEBVTT_REGIONS) virtual void newRegionsAvailable(TextTrackLoader*) = 0; -#endif }; -class TextTrackLoader : public ResourceClient, private WebVTTParserClient { +class TextTrackLoader : public ResourceOwner<RawResource>, private VTTParserClient { WTF_MAKE_NONCOPYABLE(TextTrackLoader); WTF_MAKE_FAST_ALLOCATED; public: - static PassOwnPtr<TextTrackLoader> create(TextTrackLoaderClient* client, ScriptExecutionContext* context) + static PassOwnPtr<TextTrackLoader> create(TextTrackLoaderClient& client, Document& document) { - return adoptPtr(new TextTrackLoader(client, context)); + return adoptPtr(new TextTrackLoader(client, document)); } virtual ~TextTrackLoader(); @@ -68,37 +62,31 @@ public: enum State { Idle, Loading, Finished, Failed }; State loadState() { return m_state; } - void getNewCues(Vector<RefPtr<TextTrackCue> >& outputCues); -#if ENABLE(WEBVTT_REGIONS) - void getNewRegions(Vector<RefPtr<TextTrackRegion> >& outputRegions); -#endif + void getNewCues(Vector<RefPtr<VTTCue> >& outputCues); + void getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions); private: - // ResourceClient - virtual void notifyFinished(Resource*); - virtual void deprecatedDidReceiveResource(Resource*); + // RawResourceClient + virtual void dataReceived(Resource*, const char* data, int length) OVERRIDE; + virtual void notifyFinished(Resource*) OVERRIDE; - // WebVTTParserClient - virtual void newCuesParsed(); -#if ENABLE(WEBVTT_REGIONS) - virtual void newRegionsParsed(); -#endif - virtual void fileFailedToParse(); + // VTTParserClient + virtual void newCuesParsed() OVERRIDE; + virtual void newRegionsParsed() OVERRIDE; + virtual void fileFailedToParse() OVERRIDE; - TextTrackLoader(TextTrackLoaderClient*, ScriptExecutionContext*); + TextTrackLoader(TextTrackLoaderClient&, Document&); - void processNewCueData(Resource*); void cueLoadTimerFired(Timer<TextTrackLoader>*); void corsPolicyPreventedLoad(); - TextTrackLoaderClient* m_client; - OwnPtr<WebVTTParser> m_cueParser; - ResourcePtr<TextTrackResource> m_cachedCueData; - ScriptExecutionContext* m_scriptExecutionContext; + TextTrackLoaderClient& m_client; + OwnPtr<VTTParser> m_cueParser; + // FIXME: Remove this pointer and get the Document from m_client. + Document& m_document; Timer<TextTrackLoader> m_cueLoadTimer; String m_crossOriginMode; State m_state; - unsigned m_parseOffset; bool m_newCuesAvailable; }; diff --git a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp index 50279cb2ae7..476f915fe9e 100644 --- a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp @@ -32,7 +32,7 @@ #include "core/loader/ThreadableLoader.h" #include "core/dom/Document.h" -#include "core/dom/ScriptExecutionContext.h" +#include "core/dom/ExecutionContext.h" #include "core/loader/DocumentThreadableLoader.h" #include "core/loader/WorkerThreadableLoader.h" #include "core/workers/WorkerGlobalScope.h" @@ -40,7 +40,7 @@ namespace WebCore { -PassRefPtr<ThreadableLoader> ThreadableLoader::create(ScriptExecutionContext* context, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options) +PassRefPtr<ThreadableLoader> ThreadableLoader::create(ExecutionContext* context, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options) { ASSERT(client); ASSERT(context); @@ -51,7 +51,7 @@ PassRefPtr<ThreadableLoader> ThreadableLoader::create(ScriptExecutionContext* co return DocumentThreadableLoader::create(toDocument(context), client, request, options); } -void ThreadableLoader::loadResourceSynchronously(ScriptExecutionContext* context, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options) +void ThreadableLoader::loadResourceSynchronously(ExecutionContext* context, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options) { ASSERT(context); diff --git a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h index a2afdd11b6b..a1092d24400 100644 --- a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h @@ -32,7 +32,6 @@ #define ThreadableLoader_h #include "core/fetch/ResourceLoaderOptions.h" -#include "weborigin/SecurityOrigin.h" #include "wtf/Noncopyable.h" #include "wtf/PassRefPtr.h" #include "wtf/RefPtr.h" @@ -42,7 +41,7 @@ namespace WebCore { class ResourceError; class ResourceRequest; class ResourceResponse; - class ScriptExecutionContext; + class ExecutionContext; class ThreadableLoaderClient; enum CrossOriginRequestPolicy { @@ -71,7 +70,6 @@ namespace WebCore { PreflightPolicy preflightPolicy; // If AccessControl is used, how to determine if a preflight is needed. CrossOriginRequestPolicy crossOriginRequestPolicy; - RefPtr<SecurityOrigin> securityOrigin; AtomicString initiator; ContentSecurityPolicyEnforcement contentSecurityPolicyEnforcement; unsigned long timeoutMilliseconds; @@ -82,8 +80,8 @@ namespace WebCore { class ThreadableLoader { WTF_MAKE_NONCOPYABLE(ThreadableLoader); public: - static void loadResourceSynchronously(ScriptExecutionContext*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&); - static PassRefPtr<ThreadableLoader> create(ScriptExecutionContext*, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&); + static void loadResourceSynchronously(ExecutionContext*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&); + static PassRefPtr<ThreadableLoader> create(ExecutionContext*, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&); virtual void cancel() = 0; void ref() { refThreadableLoader(); } diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp index d76b7244e99..ad16a0f36d0 100644 --- a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp @@ -35,13 +35,12 @@ #include "core/dom/CrossThreadTask.h" #include "core/dom/Document.h" #include "core/loader/DocumentThreadableLoader.h" -#include "core/loader/ThreadableLoader.h" -#include "core/platform/network/ResourceError.h" -#include "core/platform/network/ResourceRequest.h" -#include "core/platform/network/ResourceResponse.h" #include "core/workers/WorkerGlobalScope.h" #include "core/workers/WorkerLoaderProxy.h" #include "core/workers/WorkerThread.h" +#include "platform/network/ResourceError.h" +#include "platform/network/ResourceRequest.h" +#include "platform/network/ResourceResponse.h" #include "wtf/MainThread.h" #include "wtf/OwnPtr.h" #include "wtf/Vector.h" @@ -102,7 +101,7 @@ WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge() { } -void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options, const String& outgoingReferrer) +void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options, const String& outgoingReferrer) { ASSERT(isMainThread()); Document* document = toDocument(context); @@ -110,14 +109,14 @@ void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ScriptExec OwnPtr<ResourceRequest> request(ResourceRequest::adopt(requestData)); request->setHTTPReferrer(outgoingReferrer); options.requestInitiatorContext = WorkerContext; - // FIXME: If the a site requests a local resource, then this will return a non-zero value but the sync path - // will return a 0 value. Either this should return 0 or the other code path should do a callback with - // a failure. thisPtr->m_mainThreadLoader = DocumentThreadableLoader::create(document, thisPtr, *request, options); - ASSERT(thisPtr->m_mainThreadLoader); + if (!thisPtr->m_mainThreadLoader) { + // DocumentThreadableLoader::create may return 0 when the document loader has been already changed. + thisPtr->didFail(ResourceError(errorDomainBlinkInternal, 0, request->url().string(), "Can't create DocumentThreadableLoader")); + } } -void WorkerThreadableLoader::MainThreadBridge::mainThreadDestroy(ScriptExecutionContext* context, MainThreadBridge* thisPtr) +void WorkerThreadableLoader::MainThreadBridge::mainThreadDestroy(ExecutionContext* context, MainThreadBridge* thisPtr) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context->isDocument()); @@ -134,7 +133,7 @@ void WorkerThreadableLoader::MainThreadBridge::destroy() createCallbackTask(&MainThreadBridge::mainThreadDestroy, AllowCrossThreadAccess(this))); } -void WorkerThreadableLoader::MainThreadBridge::mainThreadCancel(ScriptExecutionContext* context, MainThreadBridge* thisPtr) +void WorkerThreadableLoader::MainThreadBridge::mainThreadCancel(ExecutionContext* context, MainThreadBridge* thisPtr) { ASSERT(isMainThread()); ASSERT_UNUSED(context, context->isDocument()); @@ -165,7 +164,7 @@ void WorkerThreadableLoader::MainThreadBridge::clearClientWrapper() m_workerClientWrapper->clearClient(); } -static void workerGlobalScopeDidSendData(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) +static void workerGlobalScopeDidSendData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didSendData(bytesSent, totalBytesToBeSent); @@ -176,7 +175,7 @@ void WorkerThreadableLoader::MainThreadBridge::didSendData(unsigned long long by m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent), m_taskMode); } -static void workerGlobalScopeDidReceiveResponse(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, PassOwnPtr<CrossThreadResourceResponseData> responseData) +static void workerGlobalScopeDidReceiveResponse(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, PassOwnPtr<CrossThreadResourceResponseData> responseData) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData)); @@ -188,7 +187,7 @@ void WorkerThreadableLoader::MainThreadBridge::didReceiveResponse(unsigned long m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveResponse, m_workerClientWrapper, identifier, response), m_taskMode); } -static void workerGlobalScopeDidReceiveData(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData) +static void workerGlobalScopeDidReceiveData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didReceiveData(vectorData->data(), vectorData->size()); @@ -201,7 +200,18 @@ void WorkerThreadableLoader::MainThreadBridge::didReceiveData(const char* data, m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveData, m_workerClientWrapper, vector.release()), m_taskMode); } -static void workerGlobalScopeDidReceiveCachedMetadata(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData) +static void workerGlobalScopeDidDownloadData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, int dataLength) +{ + ASSERT_UNUSED(context, context->isWorkerGlobalScope()); + workerClientWrapper->didDownloadData(dataLength); +} + +void WorkerThreadableLoader::MainThreadBridge::didDownloadData(int dataLength) +{ + m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidDownloadData, m_workerClientWrapper, dataLength), m_taskMode); +} + +static void workerGlobalScopeDidReceiveCachedMetadata(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didReceiveCachedMetadata(vectorData->data(), vectorData->size()); @@ -214,7 +224,7 @@ void WorkerThreadableLoader::MainThreadBridge::didReceiveCachedMetadata(const ch m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveCachedMetadata, m_workerClientWrapper, vector.release()), m_taskMode); } -static void workerGlobalScopeDidFinishLoading(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, double finishTime) +static void workerGlobalScopeDidFinishLoading(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, double finishTime) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didFinishLoading(identifier, finishTime); @@ -225,7 +235,7 @@ void WorkerThreadableLoader::MainThreadBridge::didFinishLoading(unsigned long id m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFinishLoading, m_workerClientWrapper, identifier, finishTime), m_taskMode); } -static void workerGlobalScopeDidFail(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error) +static void workerGlobalScopeDidFail(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didFail(error); @@ -236,7 +246,7 @@ void WorkerThreadableLoader::MainThreadBridge::didFail(const ResourceError& erro m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFail, m_workerClientWrapper, error), m_taskMode); } -static void workerGlobalScopeDidFailAccessControlCheck(ScriptExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error) +static void workerGlobalScopeDidFailAccessControlCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didFailAccessControlCheck(error); @@ -247,7 +257,7 @@ void WorkerThreadableLoader::MainThreadBridge::didFailAccessControlCheck(const R m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFailAccessControlCheck, m_workerClientWrapper, error), m_taskMode); } -static void workerGlobalScopeDidFailRedirectCheck(ScriptExecutionContext* context, RefPtr<ThreadableLoaderClientWrapper> workerClientWrapper) +static void workerGlobalScopeDidFailRedirectCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper) { ASSERT_UNUSED(context, context->isWorkerGlobalScope()); workerClientWrapper->didFailRedirectCheck(); diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h index 911bf6ea786..369babe30cc 100644 --- a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h +++ b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h @@ -104,14 +104,15 @@ namespace WebCore { void clearClientWrapper(); // All executed on the main thread. - static void mainThreadDestroy(ScriptExecutionContext*, MainThreadBridge*); + static void mainThreadDestroy(ExecutionContext*, MainThreadBridge*); ~MainThreadBridge(); - static void mainThreadCreateLoader(ScriptExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions, const String& outgoingReferrer); - static void mainThreadCancel(ScriptExecutionContext*, MainThreadBridge*); + static void mainThreadCreateLoader(ExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions, const String& outgoingReferrer); + static void mainThreadCancel(ExecutionContext*, MainThreadBridge*); virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE; virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE; virtual void didReceiveData(const char*, int dataLength) OVERRIDE; + virtual void didDownloadData(int dataLength) OVERRIDE; virtual void didReceiveCachedMetadata(const char*, int dataLength) OVERRIDE; virtual void didFinishLoading(unsigned long identifier, double finishTime) OVERRIDE; virtual void didFail(const ResourceError&) OVERRIDE; diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp index 786c8fdd3b9..862f37a668e 100644 --- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp +++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp @@ -26,16 +26,13 @@ #include "config.h" #include "core/loader/appcache/ApplicationCache.h" -#include "bindings/v8/ExceptionMessages.h" #include "bindings/v8/ExceptionState.h" #include "core/dom/Document.h" -#include "core/dom/EventListener.h" -#include "core/dom/EventNames.h" #include "core/dom/ExceptionCode.h" +#include "core/events/EventListener.h" #include "core/loader/DocumentLoader.h" #include "core/loader/FrameLoader.h" -#include "core/loader/appcache/ApplicationCacheHost.h" -#include "core/page/Frame.h" +#include "core/frame/Frame.h" namespace WebCore { @@ -57,9 +54,9 @@ void ApplicationCache::willDestroyGlobalObjectInFrame() ApplicationCacheHost* ApplicationCache::applicationCacheHost() const { - if (!m_frame || !m_frame->loader()->documentLoader()) + if (!m_frame || !m_frame->loader().documentLoader()) return 0; - return m_frame->loader()->documentLoader()->applicationCacheHost(); + return m_frame->loader().documentLoader()->applicationCacheHost(); } unsigned short ApplicationCache::status() const @@ -70,18 +67,18 @@ unsigned short ApplicationCache::status() const return cacheHost->status(); } -void ApplicationCache::update(ExceptionState& es) +void ApplicationCache::update(ExceptionState& exceptionState) { ApplicationCacheHost* cacheHost = applicationCacheHost(); if (!cacheHost || !cacheHost->update()) - es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecute("update", "ApplicationCache", "there is no application cache to update.")); + exceptionState.throwDOMException(InvalidStateError, "there is no application cache to update."); } -void ApplicationCache::swapCache(ExceptionState& es) +void ApplicationCache::swapCache(ExceptionState& exceptionState) { ApplicationCacheHost* cacheHost = applicationCacheHost(); if (!cacheHost || !cacheHost->swapCache()) - es.throwDOMException(InvalidStateError, ExceptionMessages::failedToExecute("swapCache", "ApplicationCache", "there is no newer application cache to swap to.")); + exceptionState.throwDOMException(InvalidStateError, "there is no newer application cache to swap to."); } void ApplicationCache::abort() @@ -93,10 +90,10 @@ void ApplicationCache::abort() const AtomicString& ApplicationCache::interfaceName() const { - return eventNames().interfaceForApplicationCache; + return EventTargetNames::ApplicationCache; } -ScriptExecutionContext* ApplicationCache::scriptExecutionContext() const +ExecutionContext* ApplicationCache::executionContext() const { if (m_frame) return m_frame->document(); @@ -107,34 +104,24 @@ const AtomicString& ApplicationCache::toEventType(ApplicationCacheHost::EventID { switch (id) { case ApplicationCacheHost::CHECKING_EVENT: - return eventNames().checkingEvent; + return EventTypeNames::checking; case ApplicationCacheHost::ERROR_EVENT: - return eventNames().errorEvent; + return EventTypeNames::error; case ApplicationCacheHost::NOUPDATE_EVENT: - return eventNames().noupdateEvent; + return EventTypeNames::noupdate; case ApplicationCacheHost::DOWNLOADING_EVENT: - return eventNames().downloadingEvent; + return EventTypeNames::downloading; case ApplicationCacheHost::PROGRESS_EVENT: - return eventNames().progressEvent; + return EventTypeNames::progress; case ApplicationCacheHost::UPDATEREADY_EVENT: - return eventNames().updatereadyEvent; + return EventTypeNames::updateready; case ApplicationCacheHost::CACHED_EVENT: - return eventNames().cachedEvent; + return EventTypeNames::cached; case ApplicationCacheHost::OBSOLETE_EVENT: - return eventNames().obsoleteEvent; + return EventTypeNames::obsolete; } ASSERT_NOT_REACHED(); - return eventNames().errorEvent; -} - -EventTargetData* ApplicationCache::eventTargetData() -{ - return &m_eventTargetData; -} - -EventTargetData* ApplicationCache::ensureEventTargetData() -{ - return &m_eventTargetData; + return EventTypeNames::error; } } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h index 680f9c4145d..405ad35b75e 100644 --- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h +++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h @@ -27,10 +27,10 @@ #define ApplicationCache_h #include "bindings/v8/ScriptWrappable.h" -#include "core/dom/EventNames.h" -#include "core/dom/EventTarget.h" +#include "core/events/EventTarget.h" +#include "core/events/ThreadLocalEventNames.h" #include "core/loader/appcache/ApplicationCacheHost.h" -#include "core/page/DOMWindowProperty.h" +#include "core/frame/DOMWindowProperty.h" #include "wtf/Forward.h" #include "wtf/PassRefPtr.h" #include "wtf/RefCounted.h" @@ -41,7 +41,8 @@ class ExceptionState; class Frame; class KURL; -class ApplicationCache : public ScriptWrappable, public RefCounted<ApplicationCache>, public EventTarget, public DOMWindowProperty { +class ApplicationCache : public ScriptWrappable, public RefCounted<ApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty { + REFCOUNTED_EVENT_TARGET(ApplicationCache); public: static PassRefPtr<ApplicationCache> create(Frame* frame) { return adoptRef(new ApplicationCache(frame)); } ~ApplicationCache() { ASSERT(!m_frame); } @@ -53,11 +54,6 @@ public: void swapCache(ExceptionState&); void abort(); - // EventTarget impl - - using RefCounted<ApplicationCache>::ref; - using RefCounted<ApplicationCache>::deref; - // Explicitly named attribute event listener helpers DEFINE_ATTRIBUTE_EVENT_LISTENER(checking); @@ -69,22 +65,15 @@ public: DEFINE_ATTRIBUTE_EVENT_LISTENER(cached); DEFINE_ATTRIBUTE_EVENT_LISTENER(obsolete); - virtual const AtomicString& interfaceName() const; - virtual ScriptExecutionContext* scriptExecutionContext() const; + virtual const AtomicString& interfaceName() const OVERRIDE; + virtual ExecutionContext* executionContext() const OVERRIDE; static const AtomicString& toEventType(ApplicationCacheHost::EventID); private: explicit ApplicationCache(Frame*); - virtual void refEventTarget() { ref(); } - virtual void derefEventTarget() { deref(); } - virtual EventTargetData* eventTargetData(); - virtual EventTargetData* ensureEventTargetData(); - ApplicationCacheHost* applicationCacheHost() const; - - EventTargetData m_eventTargetData; }; } // namespace WebCore diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h index 8530fc15721..140558900e3 100644 --- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h +++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h @@ -31,7 +31,7 @@ #ifndef ApplicationCacheHost_h #define ApplicationCacheHost_h -#include "weborigin/KURL.h" +#include "platform/weborigin/KURL.h" #include "wtf/Deque.h" #include "wtf/OwnPtr.h" #include "wtf/PassRefPtr.h" diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResource.cpp b/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResource.cpp deleted file mode 100644 index ebcbadca24b..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResource.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "core/loader/archive/ArchiveResource.h" - -#include "core/platform/SharedBuffer.h" - -namespace WebCore { - -inline ArchiveResource::ArchiveResource(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse& response) - : m_url(url) - , m_response(response) - , m_data(data) - , m_mimeType(mimeType) - , m_textEncoding(textEncoding) - , m_frameName(frameName) -{ - ASSERT(m_data); -} - -PassRefPtr<ArchiveResource> ArchiveResource::create(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse& response) -{ - if (!data) - return 0; - if (response.isNull()) { - unsigned dataSize = data->size(); - return adoptRef(new ArchiveResource(data, url, mimeType, textEncoding, frameName, - ResourceResponse(url, mimeType, dataSize, textEncoding, String()))); - } - return adoptRef(new ArchiveResource(data, url, mimeType, textEncoding, frameName, response)); -} - -PassRefPtr<ArchiveResource> ArchiveResource::create(PassRefPtr<SharedBuffer> data, const KURL& url, const ResourceResponse& response) -{ - return create(data, url, response.mimeType(), response.textEncodingName(), String(), response); -} - -} diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResource.h b/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResource.h deleted file mode 100644 index df6a949b0af..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResource.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArchiveResource_h -#define ArchiveResource_h - -#include "core/platform/SharedBuffer.h" -#include "core/platform/network/ResourceResponse.h" -#include "weborigin/KURL.h" -#include "wtf/RefCounted.h" -#include "wtf/RefPtr.h" - -namespace WebCore { - -class ArchiveResource : public RefCounted<ArchiveResource> { -public: - static PassRefPtr<ArchiveResource> create(PassRefPtr<SharedBuffer>, const KURL&, const ResourceResponse&); - static PassRefPtr<ArchiveResource> create(PassRefPtr<SharedBuffer>, const KURL&, - const String& mimeType, const String& textEncoding, const String& frameName, - const ResourceResponse& = ResourceResponse()); - - const KURL& url() const { return m_url; } - const ResourceResponse& response() const { return m_response; } - SharedBuffer* data() const { return m_data.get(); } - const String& mimeType() const { return m_mimeType; } - const String& textEncoding() const { return m_textEncoding; } - const String& frameName() const { return m_frameName; } - -private: - ArchiveResource(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse&); - - KURL m_url; - ResourceResponse m_response; - RefPtr<SharedBuffer> m_data; - String m_mimeType; - String m_textEncoding; - String m_frameName; -}; - -} - -#endif // ArchiveResource_h diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResourceCollection.cpp b/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResourceCollection.cpp deleted file mode 100644 index 06b24301ef4..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResourceCollection.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "core/loader/archive/ArchiveResourceCollection.h" - -#include "weborigin/KURL.h" - -namespace WebCore { - -ArchiveResourceCollection::ArchiveResourceCollection() -{ -} - -void ArchiveResourceCollection::addAllResources(MHTMLArchive* archive) -{ - ASSERT(archive); - if (!archive) - return; - - const Vector<RefPtr<ArchiveResource> >& subresources = archive->subresources(); - for (Vector<RefPtr<ArchiveResource> >::const_iterator iterator = subresources.begin(); iterator != subresources.end(); ++iterator) - m_subresources.set((*iterator)->url(), iterator->get()); - - const Vector<RefPtr<MHTMLArchive> >& subframes = archive->subframeArchives(); - for (Vector<RefPtr<MHTMLArchive> >::const_iterator iterator = subframes.begin(); iterator != subframes.end(); ++iterator) { - RefPtr<MHTMLArchive> archive = *iterator; - ASSERT(archive->mainResource()); - - const String& frameName = archive->mainResource()->frameName(); - if (!frameName.isNull()) - m_subframes.set(frameName, archive.get()); - else { - // In the MHTML case, frames don't have a name so we use the URL instead. - m_subframes.set(archive->mainResource()->url().string(), archive.get()); - } - } -} - -// FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on. -// Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps? -void ArchiveResourceCollection::addResource(PassRefPtr<ArchiveResource> resource) -{ - ASSERT(resource); - if (!resource) - return; - - const KURL& url = resource->url(); // get before passing PassRefPtr (which sets it to 0) - m_subresources.set(url, resource); -} - -ArchiveResource* ArchiveResourceCollection::archiveResourceForURL(const KURL& url) -{ - ArchiveResource* resource = m_subresources.get(url); - if (!resource) - return 0; - - return resource; -} - -PassRefPtr<MHTMLArchive> ArchiveResourceCollection::popSubframeArchive(const String& frameName, const KURL& url) -{ - RefPtr<MHTMLArchive> archive = m_subframes.take(frameName); - if (archive) - return archive.release(); - - return m_subframes.take(url.string()); -} - -} diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResourceCollection.h b/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResourceCollection.h deleted file mode 100644 index 4b66573f69e..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/ArchiveResourceCollection.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ArchiveResourceCollection_h -#define ArchiveResourceCollection_h - -#include "core/loader/archive/ArchiveResource.h" -#include "core/loader/archive/MHTMLArchive.h" -#include "wtf/HashMap.h" -#include "wtf/text/WTFString.h" - -namespace WebCore { - -class KURL; - -class ArchiveResourceCollection { - WTF_MAKE_NONCOPYABLE(ArchiveResourceCollection); WTF_MAKE_FAST_ALLOCATED; -public: - ArchiveResourceCollection(); - - void addResource(PassRefPtr<ArchiveResource>); - void addAllResources(MHTMLArchive*); - - ArchiveResource* archiveResourceForURL(const KURL&); - PassRefPtr<MHTMLArchive> popSubframeArchive(const String& frameName, const KURL&); - -private: - HashMap<String, RefPtr<ArchiveResource> > m_subresources; - HashMap<String, RefPtr<MHTMLArchive> > m_subframes; -}; - -} - -#endif diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/DEPS b/chromium/third_party/WebKit/Source/core/loader/archive/DEPS deleted file mode 100644 index f91aaec8510..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/DEPS +++ /dev/null @@ -1,9 +0,0 @@ -# Please run Tools/Scripts/check-blink-deps after modifying this file. - -include_rules = [ - # core/loader/archive should not depend on anything in core, - # except for itself and core/platform. - "-core", - "+core/loader/archive", - "+core/platform", -] diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLArchive.cpp b/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLArchive.cpp deleted file mode 100644 index 90cdb2cebcd..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLArchive.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include "core/loader/archive/MHTMLArchive.h" - -#include "core/loader/archive/MHTMLParser.h" -#include "core/platform/MIMETypeRegistry.h" -#include "core/platform/SerializedResource.h" -#include "core/platform/SharedBuffer.h" -#include "core/platform/text/QuotedPrintable.h" -#include "weborigin/SchemeRegistry.h" -#include "wtf/CryptographicallyRandomNumber.h" -#include "wtf/DateMath.h" -#include "wtf/GregorianDateTime.h" -#include "wtf/text/Base64.h" -#include "wtf/text/StringBuilder.h" - -namespace WebCore { - -const char* const quotedPrintable = "quoted-printable"; -const char* const base64 = "base64"; -const char* const binary = "binary"; - -static String generateRandomBoundary() -{ - // Trying to generate random boundaries similar to IE/UnMHT (ex: ----=_NextPart_000_001B_01CC157B.96F808A0). - const size_t randomValuesLength = 10; - char randomValues[randomValuesLength]; - cryptographicallyRandomValues(&randomValues, randomValuesLength); - StringBuilder stringBuilder; - stringBuilder.append("----=_NextPart_000_"); - for (size_t i = 0; i < randomValuesLength; ++i) { - if (i == 2) - stringBuilder.append('_'); - else if (i == 6) - stringBuilder.append('.'); - stringBuilder.append(lowerNibbleToASCIIHexDigit(randomValues[i])); - stringBuilder.append(upperNibbleToASCIIHexDigit(randomValues[i])); - } - return stringBuilder.toString(); -} - -static String replaceNonPrintableCharacters(const String& text) -{ - StringBuilder stringBuilder; - for (size_t i = 0; i < text.length(); ++i) { - if (isASCIIPrintable(text[i])) - stringBuilder.append(text[i]); - else - stringBuilder.append('?'); - } - return stringBuilder.toString(); -} - -MHTMLArchive::MHTMLArchive() -{ -} - -MHTMLArchive::~MHTMLArchive() -{ - // Because all frames know about each other we need to perform a deep clearing of the archives graph. - clearAllSubframeArchives(); -} - -PassRefPtr<MHTMLArchive> MHTMLArchive::create() -{ - return adoptRef(new MHTMLArchive); -} - -PassRefPtr<MHTMLArchive> MHTMLArchive::create(const KURL& url, SharedBuffer* data) -{ - // For security reasons we only load MHTML pages from local URLs. - if (!SchemeRegistry::shouldTreatURLSchemeAsLocal(url.protocol())) - return 0; - - MHTMLParser parser(data); - RefPtr<MHTMLArchive> mainArchive = parser.parseArchive(); - if (!mainArchive) - return 0; // Invalid MHTML file. - - // Since MHTML is a flat format, we need to make all frames aware of all resources. - for (size_t i = 0; i < parser.frameCount(); ++i) { - RefPtr<MHTMLArchive> archive = parser.frameAt(i); - for (size_t j = 1; j < parser.frameCount(); ++j) { - if (i != j) - archive->addSubframeArchive(parser.frameAt(j)); - } - for (size_t j = 0; j < parser.subResourceCount(); ++j) - archive->addSubresource(parser.subResourceAt(j)); - } - return mainArchive.release(); -} - -PassRefPtr<SharedBuffer> MHTMLArchive::generateMHTMLData(const Vector<SerializedResource>& resources, EncodingPolicy encodingPolicy, const String& title, const String& mimeType) -{ - String boundary = generateRandomBoundary(); - String endOfResourceBoundary = "--" + boundary + "\r\n"; - - GregorianDateTime now; - now.setToCurrentLocalTime(); - String dateString = makeRFC2822DateString(now.weekDay(), now.monthDay(), now.month(), now.year(), now.hour(), now.minute(), now.second(), now.utcOffset() / 60); - - StringBuilder stringBuilder; - stringBuilder.append("From: <Saved by WebKit>\r\n"); - stringBuilder.append("Subject: "); - // We replace non ASCII characters with '?' characters to match IE's behavior. - stringBuilder.append(replaceNonPrintableCharacters(title)); - stringBuilder.append("\r\nDate: "); - stringBuilder.append(dateString); - stringBuilder.append("\r\nMIME-Version: 1.0\r\n"); - stringBuilder.append("Content-Type: multipart/related;\r\n"); - stringBuilder.append("\ttype=\""); - stringBuilder.append(mimeType); - stringBuilder.append("\";\r\n"); - stringBuilder.append("\tboundary=\""); - stringBuilder.append(boundary); - stringBuilder.append("\"\r\n\r\n"); - - // We use utf8() below instead of ascii() as ascii() replaces CRLFs with ?? (we still only have put ASCII characters in it). - ASSERT(stringBuilder.toString().containsOnlyASCII()); - CString asciiString = stringBuilder.toString().utf8(); - RefPtr<SharedBuffer> mhtmlData = SharedBuffer::create(); - mhtmlData->append(asciiString.data(), asciiString.length()); - - for (size_t i = 0; i < resources.size(); ++i) { - const SerializedResource& resource = resources[i]; - - stringBuilder.clear(); - stringBuilder.append(endOfResourceBoundary); - stringBuilder.append("Content-Type: "); - stringBuilder.append(resource.mimeType); - - const char* contentEncoding = 0; - if (encodingPolicy == UseBinaryEncoding) - contentEncoding = binary; - else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(resource.mimeType) || MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType)) - contentEncoding = quotedPrintable; - else - contentEncoding = base64; - - stringBuilder.append("\r\nContent-Transfer-Encoding: "); - stringBuilder.append(contentEncoding); - stringBuilder.append("\r\nContent-Location: "); - stringBuilder.append(resource.url); - stringBuilder.append("\r\n\r\n"); - - asciiString = stringBuilder.toString().utf8(); - mhtmlData->append(asciiString.data(), asciiString.length()); - - if (!strcmp(contentEncoding, binary)) { - const char* data; - size_t position = 0; - while (size_t length = resource.data->getSomeData(data, position)) { - mhtmlData->append(data, length); - position += length; - } - } else { - // FIXME: ideally we would encode the content as a stream without having to fetch it all. - const char* data = resource.data->data(); - size_t dataLength = resource.data->size(); - Vector<char> encodedData; - if (!strcmp(contentEncoding, quotedPrintable)) { - quotedPrintableEncode(data, dataLength, encodedData); - mhtmlData->append(encodedData.data(), encodedData.size()); - mhtmlData->append("\r\n", 2); - } else { - ASSERT(!strcmp(contentEncoding, base64)); - // We are not specifying insertLFs = true below as it would cut the lines with LFs and MHTML requires CRLFs. - base64Encode(data, dataLength, encodedData); - const size_t maximumLineLength = 76; - size_t index = 0; - size_t encodedDataLength = encodedData.size(); - do { - size_t lineLength = std::min(encodedDataLength - index, maximumLineLength); - mhtmlData->append(encodedData.data() + index, lineLength); - mhtmlData->append("\r\n", 2); - index += maximumLineLength; - } while (index < encodedDataLength); - } - } - } - - asciiString = String("--" + boundary + "--\r\n").utf8(); - mhtmlData->append(asciiString.data(), asciiString.length()); - - return mhtmlData.release(); -} - -void MHTMLArchive::clearAllSubframeArchives() -{ - Vector<RefPtr<MHTMLArchive> > clearedArchives; - clearAllSubframeArchivesImpl(&clearedArchives); -} - -void MHTMLArchive::clearAllSubframeArchivesImpl(Vector<RefPtr<MHTMLArchive> >* clearedArchives) -{ - for (Vector<RefPtr<MHTMLArchive> >::iterator it = m_subframeArchives.begin(); it != m_subframeArchives.end(); ++it) { - if (!clearedArchives->contains(*it)) { - clearedArchives->append(*it); - (*it)->clearAllSubframeArchivesImpl(clearedArchives); - } - } - m_subframeArchives.clear(); -} - -} diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLArchive.h b/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLArchive.h deleted file mode 100644 index d102afdb81f..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLArchive.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MHTMLArchive_h -#define MHTMLArchive_h - -#include "core/loader/archive/ArchiveResource.h" -#include "wtf/PassRefPtr.h" -#include "wtf/RefCounted.h" -#include "wtf/RefPtr.h" -#include "wtf/Vector.h" - -namespace WebCore { - -class KURL; -class MHTMLParser; -class SharedBuffer; - -struct SerializedResource; - -class MHTMLArchive : public RefCounted<MHTMLArchive> { -public: - static PassRefPtr<MHTMLArchive> create(); - static PassRefPtr<MHTMLArchive> create(const KURL&, SharedBuffer*); - - enum EncodingPolicy { - UseDefaultEncoding, - UseBinaryEncoding - }; - - // Binary encoding results in smaller MHTML files but they might not work in other browsers. - static PassRefPtr<SharedBuffer> generateMHTMLData(const Vector<SerializedResource>&, EncodingPolicy, const String& title, const String& mimeType); - - virtual ~MHTMLArchive(); - ArchiveResource* mainResource() { return m_mainResource.get(); } - const Vector<RefPtr<ArchiveResource> >& subresources() const { return m_subresources; } - const Vector<RefPtr<MHTMLArchive> >& subframeArchives() const { return m_subframeArchives; } - -private: - friend class MHTMLParser; - MHTMLArchive(); - - void setMainResource(PassRefPtr<ArchiveResource> mainResource) { m_mainResource = mainResource; } - void addSubresource(PassRefPtr<ArchiveResource> subResource) { m_subresources.append(subResource); } - void addSubframeArchive(PassRefPtr<MHTMLArchive> subframeArchive) { m_subframeArchives.append(subframeArchive); } - - void clearAllSubframeArchives(); - void clearAllSubframeArchivesImpl(Vector<RefPtr<MHTMLArchive> >* clearedArchives); - - RefPtr<ArchiveResource> m_mainResource; - Vector<RefPtr<ArchiveResource> > m_subresources; - Vector<RefPtr<MHTMLArchive> > m_subframeArchives; -}; - -} - -#endif diff --git a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLParser.cpp b/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLParser.cpp deleted file mode 100644 index 6bab361df34..00000000000 --- a/chromium/third_party/WebKit/Source/core/loader/archive/MHTMLParser.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "core/loader/archive/MHTMLParser.h" - -#include "core/loader/archive/MHTMLArchive.h" -#include "core/platform/MIMETypeRegistry.h" -#include "core/platform/network/MIMEHeader.h" -#include "core/platform/text/QuotedPrintable.h" -#include "wtf/text/Base64.h" - -namespace WebCore { - -static bool skipLinesUntilBoundaryFound(SharedBufferChunkReader& lineReader, const String& boundary) -{ - String line; - while (!(line = lineReader.nextChunkAsUTF8StringWithLatin1Fallback()).isNull()) { - if (line == boundary) - return true; - } - return false; -} - -MHTMLParser::MHTMLParser(SharedBuffer* data) - : m_lineReader(data, "\r\n") -{ -} - -PassRefPtr<MHTMLArchive> MHTMLParser::parseArchive() -{ - RefPtr<MIMEHeader> header = MIMEHeader::parseHeader(&m_lineReader); - return parseArchiveWithHeader(header.get()); -} - -PassRefPtr<MHTMLArchive> MHTMLParser::parseArchiveWithHeader(MIMEHeader* header) -{ - if (!header) { - LOG_ERROR("Failed to parse MHTML part: no header."); - return 0; - } - - RefPtr<MHTMLArchive> archive = MHTMLArchive::create(); - if (!header->isMultipart()) { - // With IE a page with no resource is not multi-part. - bool endOfArchiveReached = false; - RefPtr<ArchiveResource> resource = parseNextPart(*header, String(), String(), endOfArchiveReached); - if (!resource) - return 0; - archive->setMainResource(resource); - return archive; - } - - // Skip the message content (it's a generic browser specific message). - skipLinesUntilBoundaryFound(m_lineReader, header->endOfPartBoundary()); - - bool endOfArchive = false; - while (!endOfArchive) { - RefPtr<MIMEHeader> resourceHeader = MIMEHeader::parseHeader(&m_lineReader); - if (!resourceHeader) { - LOG_ERROR("Failed to parse MHTML, invalid MIME header."); - return 0; - } - if (resourceHeader->contentType() == "multipart/alternative") { - // Ignore IE nesting which makes little sense (IE seems to nest only some of the frames). - RefPtr<MHTMLArchive> subframeArchive = parseArchiveWithHeader(resourceHeader.get()); - if (!subframeArchive) { - LOG_ERROR("Failed to parse MHTML subframe."); - return 0; - } - bool endOfPartReached = skipLinesUntilBoundaryFound(m_lineReader, header->endOfPartBoundary()); - ASSERT_UNUSED(endOfPartReached, endOfPartReached); - // The top-frame is the first frame found, regardless of the nesting level. - if (subframeArchive->mainResource()) - addResourceToArchive(subframeArchive->mainResource(), archive.get()); - archive->addSubframeArchive(subframeArchive); - continue; - } - - RefPtr<ArchiveResource> resource = parseNextPart(*resourceHeader, header->endOfPartBoundary(), header->endOfDocumentBoundary(), endOfArchive); - if (!resource) { - LOG_ERROR("Failed to parse MHTML part."); - return 0; - } - addResourceToArchive(resource.get(), archive.get()); - } - - return archive.release(); -} - -void MHTMLParser::addResourceToArchive(ArchiveResource* resource, MHTMLArchive* archive) -{ - const String& mimeType = resource->mimeType(); - if (!MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || mimeType == "text/css") { - m_resources.append(resource); - return; - } - - // The first document suitable resource is the main frame. - if (!archive->mainResource()) { - archive->setMainResource(resource); - m_frames.append(archive); - return; - } - - RefPtr<MHTMLArchive> subframe = MHTMLArchive::create(); - subframe->setMainResource(resource); - m_frames.append(subframe); -} - -PassRefPtr<ArchiveResource> MHTMLParser::parseNextPart(const MIMEHeader& mimeHeader, const String& endOfPartBoundary, const String& endOfDocumentBoundary, bool& endOfArchiveReached) -{ - ASSERT(endOfPartBoundary.isEmpty() == endOfDocumentBoundary.isEmpty()); - - // If no content transfer encoding is specified, default to binary encoding. - MIMEHeader::Encoding contentTransferEncoding = mimeHeader.contentTransferEncoding(); - if (contentTransferEncoding == MIMEHeader::Unknown) - contentTransferEncoding = MIMEHeader::Binary; - - RefPtr<SharedBuffer> content = SharedBuffer::create(); - const bool checkBoundary = !endOfPartBoundary.isEmpty(); - bool endOfPartReached = false; - if (contentTransferEncoding == MIMEHeader::Binary) { - if (!checkBoundary) { - LOG_ERROR("Binary contents requires end of part"); - return 0; - } - m_lineReader.setSeparator(endOfPartBoundary.utf8().data()); - Vector<char> part; - if (!m_lineReader.nextChunk(part)) { - LOG_ERROR("Binary contents requires end of part"); - return 0; - } - content->append(part); - m_lineReader.setSeparator("\r\n"); - Vector<char> nextChars; - if (m_lineReader.peek(nextChars, 2) != 2) { - LOG_ERROR("Invalid seperator."); - return 0; - } - endOfPartReached = true; - ASSERT(nextChars.size() == 2); - endOfArchiveReached = (nextChars[0] == '-' && nextChars[1] == '-'); - if (!endOfArchiveReached) { - String line = m_lineReader.nextChunkAsUTF8StringWithLatin1Fallback(); - if (!line.isEmpty()) { - LOG_ERROR("No CRLF at end of binary section."); - return 0; - } - } - } else { - String line; - while (!(line = m_lineReader.nextChunkAsUTF8StringWithLatin1Fallback()).isNull()) { - endOfArchiveReached = (line == endOfDocumentBoundary); - if (checkBoundary && (line == endOfPartBoundary || endOfArchiveReached)) { - endOfPartReached = true; - break; - } - // Note that we use line.utf8() and not line.ascii() as ascii turns special characters (such as tab, line-feed...) into '?'. - content->append(line.utf8().data(), line.length()); - if (contentTransferEncoding == MIMEHeader::QuotedPrintable) { - // The line reader removes the \r\n, but we need them for the content in this case as the QuotedPrintable decoder expects CR-LF terminated lines. - content->append("\r\n", 2); - } - } - } - if (!endOfPartReached && checkBoundary) { - LOG_ERROR("No bounday found for MHTML part."); - return 0; - } - - Vector<char> data; - switch (contentTransferEncoding) { - case MIMEHeader::Base64: - if (!base64Decode(content->data(), content->size(), data)) { - LOG_ERROR("Invalid base64 content for MHTML part."); - return 0; - } - break; - case MIMEHeader::QuotedPrintable: - quotedPrintableDecode(content->data(), content->size(), data); - break; - case MIMEHeader::EightBit: - case MIMEHeader::SevenBit: - case MIMEHeader::Binary: - data.append(content->data(), content->size()); - break; - default: - LOG_ERROR("Invalid encoding for MHTML part."); - return 0; - } - RefPtr<SharedBuffer> contentBuffer = SharedBuffer::adoptVector(data); - // FIXME: the URL in the MIME header could be relative, we should resolve it if it is. - // The specs mentions 5 ways to resolve a URL: http://tools.ietf.org/html/rfc2557#section-5 - // IE and Firefox (UNMht) seem to generate only absolute URLs. - KURL location = KURL(KURL(), mimeHeader.contentLocation()); - return ArchiveResource::create(contentBuffer, location, mimeHeader.contentType(), mimeHeader.charset(), String()); -} - -size_t MHTMLParser::frameCount() const -{ - return m_frames.size(); -} - -MHTMLArchive* MHTMLParser::frameAt(size_t index) const -{ - return m_frames[index].get(); -} - -size_t MHTMLParser::subResourceCount() const -{ - return m_resources.size(); -} - -ArchiveResource* MHTMLParser::subResourceAt(size_t index) const -{ - return m_resources[index].get(); -} - -} |