diff options
Diffstat (limited to 'WebCore/loader')
31 files changed, 420 insertions, 236 deletions
diff --git a/WebCore/loader/CachedResource.h b/WebCore/loader/CachedResource.h index 05d24fc..66ca1b1 100644 --- a/WebCore/loader/CachedResource.h +++ b/WebCore/loader/CachedResource.h @@ -46,7 +46,7 @@ class PurgeableBuffer; // A resource that is held in the cache. Classes who want to use this object should derive // from CachedResourceClient, to get the function calls in case the requested data has arrived. // This class also does the actual communication with the loader to obtain the resource from the network. -class CachedResource { +class CachedResource : public Noncopyable { friend class Cache; friend class InspectorResource; diff --git a/WebCore/loader/CrossOriginAccessControl.cpp b/WebCore/loader/CrossOriginAccessControl.cpp index f0f8b6a..7a21280 100644 --- a/WebCore/loader/CrossOriginAccessControl.cpp +++ b/WebCore/loader/CrossOriginAccessControl.cpp @@ -100,6 +100,10 @@ bool passesAccessControlCheck(const ResourceResponse& response, bool includeCred if (accessControlOriginString == "*" && !includeCredentials) return true; + // A sandboxed frame has a unique origin (for same-origin purposes). + if (securityOrigin->isSandboxed(SandboxOrigin)) + return false; + RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString); if (!accessControlOrigin->isSameSchemeHostPort(securityOrigin)) return false; diff --git a/WebCore/loader/DocLoader.h b/WebCore/loader/DocLoader.h index fdc1776..06d8a47 100644 --- a/WebCore/loader/DocLoader.h +++ b/WebCore/loader/DocLoader.h @@ -47,7 +47,7 @@ class ImageLoader; class KURL; // The DocLoader manages the loading of scripts/images/stylesheets for a single document. -class DocLoader +class DocLoader : public Noncopyable { friend class Cache; friend class ImageLoader; diff --git a/WebCore/loader/DocumentLoader.cpp b/WebCore/loader/DocumentLoader.cpp index 5ca6e58..e8c3652 100644 --- a/WebCore/loader/DocumentLoader.cpp +++ b/WebCore/loader/DocumentLoader.cpp @@ -203,7 +203,7 @@ const KURL& DocumentLoader::url() const return request().url(); } -void DocumentLoader::replaceRequestURLForAnchorScroll(const KURL& url) +void DocumentLoader::replaceRequestURLForSameDocumentNavigation(const KURL& url) { m_originalRequestCopy.setURL(url); m_request.setURL(url); diff --git a/WebCore/loader/DocumentLoader.h b/WebCore/loader/DocumentLoader.h index 1fa2b65..b8e659c 100644 --- a/WebCore/loader/DocumentLoader.h +++ b/WebCore/loader/DocumentLoader.h @@ -90,7 +90,7 @@ namespace WebCore { const KURL& responseURL() const; const String& responseMIMEType() const; - void replaceRequestURLForAnchorScroll(const KURL&); + void replaceRequestURLForSameDocumentNavigation(const KURL&); bool isStopping() const { return m_isStopping; } void stopLoading(DatabasePolicy = DatabasePolicyStop); void setCommitted(bool committed) { m_committed = committed; } diff --git a/WebCore/loader/DocumentThreadableLoader.h b/WebCore/loader/DocumentThreadableLoader.h index 64b1a22..7eb7f1c 100644 --- a/WebCore/loader/DocumentThreadableLoader.h +++ b/WebCore/loader/DocumentThreadableLoader.h @@ -41,7 +41,7 @@ namespace WebCore { class Document; class KURL; - struct ResourceRequest; + class ResourceRequest; class ThreadableLoaderClient; class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, public ThreadableLoader, private SubresourceLoaderClient { diff --git a/WebCore/loader/EmptyClients.h b/WebCore/loader/EmptyClients.h index 5fcd4cd..c6ae799 100644 --- a/WebCore/loader/EmptyClients.h +++ b/WebCore/loader/EmptyClients.h @@ -80,6 +80,8 @@ public: virtual bool canTakeFocus(FocusDirection) { return false; } virtual void takeFocus(FocusDirection) { } + virtual void focusedNodeChanged(Node*) { } + virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&) { return 0; } virtual void show() { } @@ -204,6 +206,9 @@ public: virtual void dispatchDidCancelClientRedirect() { } virtual void dispatchWillPerformClientRedirect(const KURL&, double, double) { } virtual void dispatchDidChangeLocationWithinPage() { } + virtual void dispatchDidPushStateWithinPage() { } + virtual void dispatchDidReplaceStateWithinPage() { } + virtual void dispatchDidPopStateWithinPage() { } virtual void dispatchWillClose() { } virtual void dispatchDidReceiveIcon() { } virtual void dispatchDidStartProvisionalLoad() { } @@ -283,8 +288,13 @@ public: virtual void updateGlobalHistory() { } virtual void updateGlobalHistoryRedirectLinks() { } virtual bool shouldGoToHistoryItem(HistoryItem*) const { return false; } +<<<<<<< HEAD:WebCore/loader/EmptyClients.h virtual void dispatchDidAddBackForwardItem(HistoryItem*) const { } virtual void dispatchDidRemoveBackForwardItem(HistoryItem*) const { } +======= + virtual void dispatchDidAddBackForwardItem(HistoryItem*) const { } + virtual void dispatchDidRemoveBackForwardItem(HistoryItem*) const { }; +>>>>>>> webkit.org at r51976:WebCore/loader/EmptyClients.h virtual void dispatchDidChangeBackForwardIndex() const { } virtual void saveViewStateToItem(HistoryItem*) { } virtual bool canCachePage() const { return false; } @@ -298,7 +308,7 @@ public: virtual String overrideMediaType() const { return String(); } virtual void redirectDataToPlugin(Widget*) { } - virtual void windowObjectCleared() { } + virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) { } virtual void documentElementAvailable() { } virtual void didPerformFirstNavigation() const { } @@ -484,20 +494,12 @@ public: virtual void hideHighlight() { } virtual void inspectedURLChanged(const String&) { } - virtual void populateSetting(const String&, InspectorController::Setting&) { } - virtual void storeSetting(const String&, const InspectorController::Setting&) { } - virtual void removeSetting(const String&) { } + virtual void populateSetting(const String&, String*) { } + virtual void storeSetting(const String&, const String&) { } virtual void inspectorWindowObjectCleared() { } }; -class EmptyPluginHalterClient : public PluginHalterClient -{ -public: - virtual bool shouldHaltPlugin(Node*) const { return false; } - virtual bool enabled() const { return false; } -}; - } #endif // EmptyClients_h diff --git a/WebCore/loader/FrameLoader.cpp b/WebCore/loader/FrameLoader.cpp index 98b8e61..22399b0 100644 --- a/WebCore/loader/FrameLoader.cpp +++ b/WebCore/loader/FrameLoader.cpp @@ -203,6 +203,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client) , m_didPerformFirstNavigation(false) , m_loadingFromCachedPage(false) , m_suppressOpenerInNewFrame(false) + , m_sandboxFlags(SandboxAll) #ifndef NDEBUG , m_didDispatchDidCommitLoad(false) #endif @@ -235,6 +236,9 @@ void FrameLoader::init() m_frame->document()->cancelParsing(); m_creatingInitialEmptyDocument = false; m_didCallImplicitClose = true; + + // Propagate sandbox attributes to this Frameloader and its descendants. + updateSandboxFlags(); } void FrameLoader::setDefersLoading(bool defers) @@ -452,6 +456,9 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F if (u.isEmpty()) return; + if (isSandboxed(SandboxForms)) + return; + if (protocolIsJavaScript(u)) { m_isExecutingJavaScriptFormAction = true; m_frame->script()->executeIfJavaScriptURL(u, false, false); @@ -530,7 +537,10 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy, DatabasePolic if (m_frame->domWindow()) { if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document()); +<<<<<<< HEAD:WebCore/loader/FrameLoader.cpp #ifndef ANDROID_PAGE_CACHE_UNLOAD +======= +>>>>>>> webkit.org at r51976:WebCore/loader/FrameLoader.cpp if (!m_frame->document()->inPageCache()) #endif m_frame->domWindow()->dispatchEvent(Event::create(eventNames().unloadEvent, false, false), m_frame->domWindow()->document()); @@ -624,8 +634,8 @@ KURL FrameLoader::iconURL() KURL url; url.setProtocol(m_URL.protocol()); url.setHost(m_URL.host()); - if (int port = m_URL.port()) - url.setPort(port); + if (m_URL.hasPort()) + url.setPort(m_URL.port()); url.setPath("/favicon.ico"); return url; } @@ -759,7 +769,7 @@ void FrameLoader::receivedFirstData() begin(m_workingURL, false); dispatchDidCommitLoad(); - dispatchWindowObjectAvailable(); + dispatchDidClearWindowObjectsInAllWorlds(); if (m_documentLoader) { String ptitle = m_documentLoader->title(); @@ -848,7 +858,7 @@ void FrameLoader::begin(const KURL& url, bool dispatch, SecurityOrigin* origin) m_frame->domWindow()->setSecurityOrigin(document->securityOrigin()); if (dispatch) - dispatchWindowObjectAvailable(); + dispatchDidClearWindowObjectsInAllWorlds(); updateFirstPartyForCookies(); @@ -1285,14 +1295,18 @@ bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const A if (!settings || !settings->arePluginsEnabled() || (!settings->isJavaEnabled() && MIMETypeRegistry::isJavaAppletMIMEType(mimeType))) return false; + if (isSandboxed(SandboxPlugins)) + return false; return loadPlugin(renderer, completedURL, mimeType, paramNames, paramValues, useFallback); } ASSERT(renderer->node()->hasTagName(objectTag) || renderer->node()->hasTagName(embedTag)); HTMLPlugInElement* element = static_cast<HTMLPlugInElement*>(renderer->node()); - - // FIXME: OK to always make a new frame? When does the old frame get removed? - return loadSubframe(element, completedURL, frameName, m_outgoingReferrer); + + // If the plug-in element already contains a subframe, requestFrame will re-use it. Otherwise, + // it will create a new frame and set it as the RenderPart's widget, causing what was previously + // in the widget to be torn down. + return requestFrame(element, completedURL, frameName); } bool FrameLoader::shouldUsePlugin(const KURL& url, const String& mimeType, bool hasFallback, bool& useFallback) @@ -1730,52 +1744,70 @@ void FrameLoader::setFirstPartyForCookies(const KURL& url) child->loader()->setFirstPartyForCookies(url); } -class HashChangeEventTask : public ScriptExecutionContext::Task { -public: - static PassRefPtr<HashChangeEventTask> create(PassRefPtr<Document> document) - { - return adoptRef(new HashChangeEventTask(document)); - } - - virtual void performTask(ScriptExecutionContext* context) - { - ASSERT_UNUSED(context, context->isDocument()); - m_document->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false)); - } - -private: - HashChangeEventTask(PassRefPtr<Document> document) - : m_document(document) - { - ASSERT(m_document); - } - - RefPtr<Document> m_document; -}; - // This does the same kind of work that didOpenURL does, except it relies on the fact // that a higher level already checked that the URLs match and the scrolling is the right thing to do. -void FrameLoader::scrollToAnchor(const KURL& url) -{ - ASSERT(equalIgnoringFragmentIdentifier(url, m_URL)); - if (equalIgnoringFragmentIdentifier(url, m_URL) && !equalIgnoringNullity(url.fragmentIdentifier(), m_URL.fragmentIdentifier())) { - Document* currentDocument = frame()->document(); - currentDocument->postTask(HashChangeEventTask::create(currentDocument)); +void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* stateObject, bool isNewNavigation) +{ + // If we have a state object, we cannot also be a new navigation. + ASSERT(!stateObject || (stateObject && !isNewNavigation)); + + // Update the data source's request with the new URL to fake the URL change + m_frame->document()->setURL(url); + documentLoader()->replaceRequestURLForSameDocumentNavigation(url); + if (isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject) { + // NB: must happen after replaceRequestURLForSameDocumentNavigation(), since we add + // based on the current request. Must also happen before we openURL and displace the + // scroll position, since adding the BF item will save away scroll state. + + // NB2: If we were loading a long, slow doc, and the user anchor nav'ed before + // it was done, currItem is now set the that slow doc, and prevItem is whatever was + // before it. Adding the b/f item will bump the slow doc down to prevItem, even + // though its load is not yet done. I think this all works out OK, for one because + // we have already saved away the scroll and doc state for the long slow load, + // but it's not an obvious case. + + history()->updateBackForwardListForFragmentScroll(); } + bool hashChange = equalIgnoringFragmentIdentifier(url, m_URL) && url.fragmentIdentifier() != m_URL.fragmentIdentifier(); m_URL = url; - history()->updateForAnchorScroll(); + history()->updateForSameDocumentNavigation(); // If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor - m_frame->eventHandler()->stopAutoscrollTimer(); - started(); - if (FrameView* view = m_frame->view()) - view->scrollToFragment(m_URL); - + if (hashChange) + m_frame->eventHandler()->stopAutoscrollTimer(); + // It's important to model this as a load that starts and immediately finishes. // Otherwise, the parent frame may think we never finished loading. + started(); + + if (hashChange) { + if (FrameView* view = m_frame->view()) + view->scrollToFragment(m_URL); + } + m_isComplete = false; checkCompleted(); + + if (isNewNavigation) { + // This will clear previousItem from the rest of the frame tree that didn't + // doing any loading. We need to make a pass on this now, since for anchor nav + // we'll not go through a real load and reach Completed state. + checkLoadComplete(); + } + + if (stateObject) { + m_frame->document()->statePopped(stateObject); + m_client->dispatchDidPopStateWithinPage(); + } + + if (hashChange) { + m_frame->document()->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false)); + m_client->dispatchDidChangeLocationWithinPage(); + } + + // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error + m_client->didFinishLoad(); } bool FrameLoader::isComplete() const @@ -2256,6 +2288,10 @@ bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const if (m_frame == targetFrame) return true; + // A sandboxed frame can only navigate itself and its descendants. + if (isSandboxed(SandboxNavigation) && !targetFrame->tree()->isDescendantOf(m_frame)) + return false; + // Let a frame navigate the top-level window that contains it. This is // important to allow because it lets a site "frame-bust" (escape from a // frame created by another web site). @@ -2957,8 +2993,8 @@ void FrameLoader::checkLoadCompleteForThisFrame() // delegate callback. if (pdl == m_provisionalDocumentLoader) clearProvisionalLoad(); - else if (m_provisionalDocumentLoader) { - KURL unreachableURL = m_provisionalDocumentLoader->unreachableURL(); + else if (activeDocumentLoader()) { + KURL unreachableURL = activeDocumentLoader()->unreachableURL(); if (!unreachableURL.isEmpty() && unreachableURL == pdl->request().url()) shouldReset = false; } @@ -3339,10 +3375,16 @@ unsigned long FrameLoader::loadResourceSynchronously(const ResourceRequest& requ ResourceRequest initialRequest = request; initialRequest.setTimeoutInterval(10); + // Use the original request's cache policy for two reasons: + // 1. For POST requests, we mutate the cache policy for the main resource, + // but we do not want this to apply to subresources + // 2. Delegates that modify the cache policy using willSendRequest: should + // not affect any other resources. Such changes need to be done + // per request. if (initialRequest.isConditional()) initialRequest.setCachePolicy(ReloadIgnoringCacheData); else - initialRequest.setCachePolicy(documentLoader()->request().cachePolicy()); + initialRequest.setCachePolicy(originalRequest().cachePolicy()); if (!referrer.isEmpty()) initialRequest.setHTTPReferrer(referrer); @@ -3423,12 +3465,12 @@ void FrameLoader::callContinueFragmentScrollAfterNavigationPolicy(void* argument void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequest& request, bool shouldContinue) { - bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList; m_quickRedirectComing = false; if (!shouldContinue) return; +<<<<<<< HEAD:WebCore/loader/FrameLoader.cpp KURL url = request.url(); m_documentLoader->replaceRequestURLForAnchorScroll(url); @@ -3464,6 +3506,10 @@ void FrameLoader::continueFragmentScrollAfterNavigationPolicy(const ResourceRequ m_client->dispatchDidChangeLocationWithinPage(); m_client->didFinishLoad(); +======= + bool isRedirect = m_quickRedirectComing || policyChecker()->loadType() == FrameLoadTypeRedirectWithLockedBackForwardList; + loadInSameDocument(request.url(), 0, !isRedirect); +>>>>>>> webkit.org at r51976:WebCore/loader/FrameLoader.cpp } bool FrameLoader::shouldScrollToAnchor(bool isFormSubmission, FrameLoadType loadType, const KURL& url) @@ -3738,14 +3784,51 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name) return frame; } -// Loads content into this frame, as specified by history item +void FrameLoader::navigateWithinDocument(HistoryItem* item) +{ + ASSERT(!item->document() || item->document() == m_frame->document()); + + // Save user view state to the current history item here since we don't do a normal load. + // FIXME: Does form state need to be saved here too? + history()->saveScrollPositionAndViewStateToItem(history()->currentItem()); + if (FrameView* view = m_frame->view()) + view->setWasScrolledByUser(false); + + history()->setCurrentItem(item); + + // loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load + loadInSameDocument(item->url(), item->stateObject(), false); + + // Restore user view state from the current history item here since we don't do a normal load. + // Even though we just manually set the current history item, this ASSERT verifies nothing + // inside of loadInSameDocument() caused it to change. + ASSERT(history()->currentItem() == item); + history()->restoreScrollPositionAndViewState(); +} + // FIXME: This function should really be split into a couple pieces, some of // which should be methods of HistoryController and some of which should be // methods of FrameLoader. -void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) +void FrameLoader::navigateToDifferentDocument(HistoryItem* item, FrameLoadType loadType) { - if (!m_frame->page()) - return; + // Remember this item so we can traverse any child items as child frames load + history()->setProvisionalItem(item); + + // Check if we'll be using the page cache. We only use the page cache + // if one exists and it is less than _backForwardCacheExpirationInterval + // seconds old. If the cache is expired it gets flushed here. + if (RefPtr<CachedPage> cachedPage = pageCache()->get(item)) { + // FIXME: 1800 should not be hardcoded, it should come from + // WebKitBackForwardCacheExpirationIntervalKey in WebKit. + // Or we should remove WebKitBackForwardCacheExpirationIntervalKey. + if (currentTime() - cachedPage->timeStamp() <= 1800) { + loadWithDocumentLoader(cachedPage->documentLoader(), loadType, 0); + return; + } + + LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", history()->provisionalItem()->url().string().ascii().data()); + pageCache()->remove(item); + } KURL itemURL = item->url(); KURL itemOriginalURL = item->originalURL(); @@ -3754,138 +3837,96 @@ void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) currentURL = documentLoader()->url(); RefPtr<FormData> formData = item->formData(); - // Are we navigating to an anchor within the page? - // Note if we have child frames we do a real reload, since the child frames might not - // match our current frame structure, or they might not have the right content. We could - // check for all that as an additional optimization. - // We also do not do anchor-style navigation if we're posting a form or navigating from - // a page that was resulted from a form post. - bool shouldScroll = !formData && !(history()->currentItem() && history()->currentItem()->formData()) && history()->urlsMatchItem(item); + bool addedExtraFields = false; + ResourceRequest request(itemURL); -#if ENABLE(WML) - // All WML decks should go through the real load mechanism, not the scroll-to-anchor code - if (frameContainsWMLContent(m_frame)) - shouldScroll = false; -#endif - - if (shouldScroll) { - // Must do this maintenance here, since we don't go through a real page reload - history()->saveScrollPositionAndViewStateToItem(history()->currentItem()); - - if (FrameView* view = m_frame->view()) - view->setWasScrolledByUser(false); - - history()->setCurrentItem(item); - - // FIXME: Form state might need to be saved here too. - - // We always call scrollToAnchor here, even if the URL doesn't have an - // anchor fragment. This is so we'll keep the WebCore Frame's URL up-to-date. - scrollToAnchor(item->url()); + if (!item->referrer().isNull()) + request.setHTTPReferrer(item->referrer()); - // must do this maintenance here, since we don't go through a real page reload - history()->restoreScrollPositionAndViewState(); + // If this was a repost that failed the page cache, we might try to repost the form. + NavigationAction action; + if (formData) { + formData->generateFiles(m_frame->page()->chrome()->client()); + + request.setHTTPMethod("POST"); + request.setHTTPBody(formData); + request.setHTTPContentType(item->formContentType()); + RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer()); + addHTTPOriginIfNeeded(request, securityOrigin->toString()); + + // Make sure to add extra fields to the request after the Origin header is added for the FormData case. + // See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion. + addExtraFieldsToRequest(request, m_loadType, true, formData); + addedExtraFields = true; - // Fake the URL change by updating the data source's request. This will no longer - // be necessary if we do the better fix described above. - documentLoader()->replaceRequestURLForAnchorScroll(itemURL); - - m_client->dispatchDidChangeLocationWithinPage(); + // FIXME: Slight hack to test if the NSURL cache contains the page we're going to. + // We want to know this before talking to the policy delegate, since it affects whether + // we show the DoYouReallyWantToRepost nag. + // + // This trick has a small bug (3123893) where we might find a cache hit, but then + // have the item vanish when we try to use it in the ensuing nav. This should be + // extremely rare, but in that case the user will get an error on the navigation. - // FrameLoaderClient::didFinishLoad() tells the internal load delegate the load finished with no error - m_client->didFinishLoad(); + if (ResourceHandle::willLoadFromCache(request, m_frame)) + action = NavigationAction(itemURL, loadType, false); + else { + request.setCachePolicy(ReloadIgnoringCacheData); + action = NavigationAction(itemURL, NavigationTypeFormResubmitted); + } } else { - // Remember this item so we can traverse any child items as child frames load - history()->setProvisionalItem(item); - - bool inPageCache = false; - - // Check if we'll be using the page cache. We only use the page cache - // if one exists and it is less than _backForwardCacheExpirationInterval - // seconds old. If the cache is expired it gets flushed here. - if (RefPtr<CachedPage> cachedPage = pageCache()->get(item)) { - double interval = currentTime() - cachedPage->timeStamp(); - - // FIXME: 1800 should not be hardcoded, it should come from - // WebKitBackForwardCacheExpirationIntervalKey in WebKit. - // Or we should remove WebKitBackForwardCacheExpirationIntervalKey. - if (interval <= 1800) { - loadWithDocumentLoader(cachedPage->documentLoader(), loadType, 0); - inPageCache = true; - } else { - LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", history()->provisionalItem()->url().string().ascii().data()); - pageCache()->remove(item); - } + switch (loadType) { + case FrameLoadTypeReload: + case FrameLoadTypeReloadFromOrigin: + request.setCachePolicy(ReloadIgnoringCacheData); + break; + case FrameLoadTypeBack: + case FrameLoadTypeBackWMLDeckNotAccessible: + case FrameLoadTypeForward: + case FrameLoadTypeIndexedBackForward: + if (!itemURL.protocolIs("https")) + request.setCachePolicy(ReturnCacheDataElseLoad); + break; + case FrameLoadTypeStandard: + case FrameLoadTypeRedirectWithLockedBackForwardList: + break; + case FrameLoadTypeSame: + default: + ASSERT_NOT_REACHED(); } - - if (!inPageCache) { - bool addedExtraFields = false; - ResourceRequest request(itemURL); - if (!item->referrer().isNull()) - request.setHTTPReferrer(item->referrer()); - - // If this was a repost that failed the page cache, we might try to repost the form. - NavigationAction action; - if (formData) { - - formData->generateFiles(m_frame->page()->chrome()->client()); + action = NavigationAction(itemOriginalURL, loadType, false); + } + + if (!addedExtraFields) + addExtraFieldsToRequest(request, m_loadType, true, formData); - request.setHTTPMethod("POST"); - request.setHTTPBody(formData); - request.setHTTPContentType(item->formContentType()); - RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer()); - addHTTPOriginIfNeeded(request, securityOrigin->toString()); - - // Make sure to add extra fields to the request after the Origin header is added for the FormData case. - // See https://bugs.webkit.org/show_bug.cgi?id=22194 for more discussion. - addExtraFieldsToRequest(request, m_loadType, true, formData); - addedExtraFields = true; - - // FIXME: Slight hack to test if the NSURL cache contains the page we're going to. - // We want to know this before talking to the policy delegate, since it affects whether - // we show the DoYouReallyWantToRepost nag. - // - // This trick has a small bug (3123893) where we might find a cache hit, but then - // have the item vanish when we try to use it in the ensuing nav. This should be - // extremely rare, but in that case the user will get an error on the navigation. - - if (ResourceHandle::willLoadFromCache(request, m_frame)) - action = NavigationAction(itemURL, loadType, false); - else { - request.setCachePolicy(ReloadIgnoringCacheData); - action = NavigationAction(itemURL, NavigationTypeFormResubmitted); - } - } else { - switch (loadType) { - case FrameLoadTypeReload: - case FrameLoadTypeReloadFromOrigin: - request.setCachePolicy(ReloadIgnoringCacheData); - break; - case FrameLoadTypeBack: - case FrameLoadTypeBackWMLDeckNotAccessible: - case FrameLoadTypeForward: - case FrameLoadTypeIndexedBackForward: - if (itemURL.protocol() != "https") - request.setCachePolicy(ReturnCacheDataElseLoad); - break; - case FrameLoadTypeStandard: - case FrameLoadTypeRedirectWithLockedBackForwardList: - break; - case FrameLoadTypeSame: - default: - ASSERT_NOT_REACHED(); - } + loadWithNavigationAction(request, action, false, loadType, 0); +} - action = NavigationAction(itemOriginalURL, loadType, false); - } - - if (!addedExtraFields) - addExtraFieldsToRequest(request, m_loadType, true, formData); +// Loads content into this frame, as specified by history item +void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType) +{ + // We do same-document navigation in the following cases: + // - The HistoryItem has a history state object + // - Navigating to an anchor within the page, with no form data stored on the target item or the current history entry, + // and the URLs in the frame tree match the history item for fragment scrolling. + bool sameDocumentNavigation = (!item->formData() && !(history()->currentItem() && history()->currentItem()->formData()) && history()->urlsMatchItem(item)) || item->document() == m_frame->document(); - loadWithNavigationAction(request, action, false, loadType, 0); - } - } +#if ENABLE(WML) + // All WML decks should go through the real load mechanism, not the scroll-to-anchor code + // FIXME: Why do WML decks have this different behavior? + // Are WML decks incompatible with HTML5 pushState/replaceState which require inter-document history navigations? + // Should this new API be disabled for WML pages, or does WML need to update their mechanism to act like normal loads? + // If scroll-to-anchor navigations were broken for WML and required them to have different loading behavior, then + // state object loads are certainly also broken for them. + if (frameContainsWMLContent(m_frame)) + sameDocumentNavigation = false; +#endif + + if (sameDocumentNavigation) + navigateWithinDocument(item); + else + navigateToDifferentDocument(item, loadType); } void FrameLoader::setMainDocumentError(DocumentLoader* loader, const ResourceError& error) @@ -3955,15 +3996,28 @@ void FrameLoader::dispatchDocumentElementAvailable() m_client->documentElementAvailable(); } -void FrameLoader::dispatchWindowObjectAvailable() +void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds() { - // FIXME: should this be isolated-worlds-aware? - if (!m_frame->script()->isEnabled() || !m_frame->script()->existingWindowShell(mainThreadNormalWorld())) + if (!m_frame->script()->isEnabled()) return; - m_client->windowObjectCleared(); + Vector<DOMWrapperWorld*> worlds; + ScriptController::getAllWorlds(worlds); + for (size_t i = 0; i < worlds.size(); ++i) + dispatchDidClearWindowObjectInWorld(worlds[i]); +} + +void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world) +{ + if (!m_frame->script()->isEnabled() || !m_frame->script()->existingWindowShell(world)) + return; + + m_client->dispatchDidClearWindowObjectInWorld(world); #if ENABLE(INSPECTOR) + if (world != mainThreadNormalWorld()) + return; + if (Page* page = m_frame->page()) { if (InspectorController* inspector = page->inspectorController()) inspector->inspectedWindowScriptObjectCleared(m_frame); @@ -3973,6 +4027,25 @@ void FrameLoader::dispatchWindowObjectAvailable() #endif } +void FrameLoader::updateSandboxFlags() +{ + SandboxFlags flags = SandboxNone; + if (Frame* parentFrame = m_frame->tree()->parent()) + flags |= parentFrame->loader()->sandboxFlags(); + if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement()) + flags |= ownerElement->sandboxFlags(); + + if (m_sandboxFlags == flags) + return; + + m_sandboxFlags = flags; + + m_frame->document()->updateSandboxFlags(); + + for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) + child->loader()->updateSandboxFlags(); + } + PassRefPtr<Widget> FrameLoader::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const HashMap<String, String>& args) { String baseURLString; diff --git a/WebCore/loader/FrameLoader.h b/WebCore/loader/FrameLoader.h index 31351a3..875736f 100644 --- a/WebCore/loader/FrameLoader.h +++ b/WebCore/loader/FrameLoader.h @@ -52,6 +52,7 @@ class AuthenticationChallenge; class CachedFrameBase; class CachedPage; class CachedResource; +class DOMWrapperWorld; class Document; class DocumentLoader; class Event; @@ -74,6 +75,7 @@ class ScriptSourceCode; class ScriptString; class ScriptValue; class SecurityOrigin; +class SerializedScriptValue; class SharedBuffer; class SubstituteData; class TextResourceDecoder; @@ -250,9 +252,15 @@ public: PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const HashMap<String, String>& args); - void dispatchWindowObjectAvailable(); + void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*); + void dispatchDidClearWindowObjectsInAllWorlds(); void dispatchDocumentElementAvailable(); + void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); } + + bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; } + SandboxFlags sandboxFlags() const { return m_sandboxFlags; } + // Mixed content related functions. static bool isMixedContent(SecurityOrigin* context, const KURL&); void checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&); @@ -347,6 +355,9 @@ private: bool loadPlugin(RenderPart*, const KURL&, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback); + void navigateWithinDocument(HistoryItem*); + void navigateToDifferentDocument(HistoryItem*, FrameLoadType); + bool loadProvisionalItemFromCachedPage(); void cachePageForHistoryItem(HistoryItem*); void pageHidden(); @@ -428,7 +439,7 @@ private: Frame* loadSubframe(HTMLFrameOwnerElement*, const KURL&, const String& name, const String& referrer); - void scrollToAnchor(const KURL&); + void loadInSameDocument(const KURL&, SerializedScriptValue* stateObject, bool isNewNavigation); void provisionalLoadStarted(); @@ -444,6 +455,8 @@ private: bool shouldTreatURLAsSameAsCurrent(const KURL&) const; + void updateSandboxFlags(); + Frame* m_frame; FrameLoaderClient* m_client; @@ -515,6 +528,8 @@ private: bool m_loadingFromCachedPage; bool m_suppressOpenerInNewFrame; + SandboxFlags m_sandboxFlags; + #ifndef NDEBUG bool m_didDispatchDidCommitLoad; #endif diff --git a/WebCore/loader/FrameLoaderClient.h b/WebCore/loader/FrameLoaderClient.h index 7d988f1..434e163 100644 --- a/WebCore/loader/FrameLoaderClient.h +++ b/WebCore/loader/FrameLoaderClient.h @@ -47,6 +47,7 @@ namespace WebCore { class AuthenticationChallenge; class CachedFrame; class Color; + class DOMWrapperWorld; class DocumentLoader; class Element; class FormState; @@ -64,7 +65,7 @@ namespace WebCore { class ResourceError; class ResourceHandle; class ResourceLoader; - struct ResourceRequest; + class ResourceRequest; class ResourceResponse; class ScriptString; class SecurityOrigin; @@ -116,6 +117,9 @@ namespace WebCore { virtual void dispatchDidCancelClientRedirect() = 0; virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate) = 0; virtual void dispatchDidChangeLocationWithinPage() = 0; + virtual void dispatchDidPushStateWithinPage() = 0; + virtual void dispatchDidReplaceStateWithinPage() = 0; + virtual void dispatchDidPopStateWithinPage() = 0; virtual void dispatchWillClose() = 0; virtual void dispatchDidReceiveIcon() = 0; virtual void dispatchDidStartProvisionalLoad() = 0; @@ -225,7 +229,7 @@ namespace WebCore { virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType) = 0; virtual String overrideMediaType() const = 0; - virtual void windowObjectCleared() = 0; + virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) = 0; virtual void documentElementAvailable() = 0; virtual void didPerformFirstNavigation() const = 0; // "Navigation" here means a transition from one page to another that ends up in the back/forward list. @@ -252,6 +256,10 @@ namespace WebCore { virtual bool shouldUsePluginDocument(const String& /*mimeType*/) const { return false; } virtual bool shouldLoadMediaElementURL(const KURL&) const { return true; } + + virtual void didChangeScrollOffset() { } + + virtual bool allowJavaScript(bool enabledPerSettings) { return enabledPerSettings; } }; } // namespace WebCore diff --git a/WebCore/loader/FrameLoaderTypes.h b/WebCore/loader/FrameLoaderTypes.h index e7d51c7..af3dde4 100644 --- a/WebCore/loader/FrameLoaderTypes.h +++ b/WebCore/loader/FrameLoaderTypes.h @@ -92,6 +92,18 @@ namespace WebCore { SendReferrer, NoReferrer }; + + enum SandboxFlag { + SandboxNone = 0, + SandboxNavigation = 1, + SandboxPlugins = 1 << 1, + SandboxOrigin = 1 << 2, + SandboxForms = 1 << 3, + SandboxScripts = 1 << 4, + SandboxAll = -1 // Mask with all bits set to 1. + }; + + typedef int SandboxFlags; } #endif diff --git a/WebCore/loader/HistoryController.cpp b/WebCore/loader/HistoryController.cpp index 501640a..d30b231 100644 --- a/WebCore/loader/HistoryController.cpp +++ b/WebCore/loader/HistoryController.cpp @@ -402,7 +402,7 @@ void HistoryController::updateForCommit() } } -void HistoryController::updateForAnchorScroll() +void HistoryController::updateForSameDocumentNavigation() { if (m_frame->loader()->url().isEmpty()) return; @@ -624,4 +624,39 @@ void HistoryController::updateBackForwardListClippedAtTarget(bool doClip) page->backForwardList()->addItem(item); } +void HistoryController::pushState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) +{ + Page* page = m_frame->page(); + ASSERT(page); + + // Get a HistoryItem tree for the current frame tree. + RefPtr<HistoryItem> item = createItemTree(m_frame, false); + + // Override data in the target item to reflect the pushState() arguments. + HistoryItem* targetItem = item->targetItem(); + ASSERT(targetItem->isTargetItem()); + targetItem->setDocument(m_frame->document()); + targetItem->setTitle(title); + targetItem->setStateObject(stateObject); + targetItem->setURLString(urlString); + + page->backForwardList()->pushStateItem(item.release()); +} + +void HistoryController::replaceState(PassRefPtr<SerializedScriptValue> stateObject, const String& title, const String& urlString) +{ + Page* page = m_frame->page(); + ASSERT(page); + HistoryItem* current = page->backForwardList()->currentItem(); + ASSERT(current); + + ASSERT(!current->document() || current->document() == m_frame->document()); + current->setDocument(m_frame->document()); + + if (!urlString.isEmpty()) + current->setURLString(urlString); + current->setTitle(title); + current->setStateObject(stateObject); +} + } // namespace WebCore diff --git a/WebCore/loader/HistoryController.h b/WebCore/loader/HistoryController.h index 4ecae69..7c4a1ac 100644 --- a/WebCore/loader/HistoryController.h +++ b/WebCore/loader/HistoryController.h @@ -39,6 +39,7 @@ namespace WebCore { class Frame; class HistoryItem; +class SerializedScriptValue; class HistoryController : public Noncopyable { public: @@ -65,7 +66,7 @@ public: void updateForRedirectWithLockedBackForwardList(); void updateForClientRedirect(); void updateForCommit(); - void updateForAnchorScroll(); + void updateForSameDocumentNavigation(); void updateForFrameLoadCompleted(); HistoryItem* currentItem() const { return m_currentItem.get(); } @@ -75,6 +76,9 @@ public: HistoryItem* provisionalItem() const { return m_provisionalItem.get(); } void setProvisionalItem(HistoryItem*); + void pushState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url); + void replaceState(PassRefPtr<SerializedScriptValue>, const String& title, const String& url); + private: PassRefPtr<HistoryItem> createItem(bool useOriginal); PassRefPtr<HistoryItem> createItemTree(Frame* targetFrame, bool clipAtTarget); diff --git a/WebCore/loader/ImageLoader.cpp b/WebCore/loader/ImageLoader.cpp index cdc31bc..e09d574 100644 --- a/WebCore/loader/ImageLoader.cpp +++ b/WebCore/loader/ImageLoader.cpp @@ -31,7 +31,7 @@ namespace WebCore { -class ImageEventSender { +class ImageEventSender : public Noncopyable { public: ImageEventSender(const AtomicString& eventType); diff --git a/WebCore/loader/MainResourceLoader.h b/WebCore/loader/MainResourceLoader.h index d3f411b..1d5be45 100644 --- a/WebCore/loader/MainResourceLoader.h +++ b/WebCore/loader/MainResourceLoader.h @@ -40,7 +40,7 @@ namespace WebCore { class FormState; - struct ResourceRequest; + class ResourceRequest; class MainResourceLoader : public ResourceLoader { public: diff --git a/WebCore/loader/ProgressTracker.cpp b/WebCore/loader/ProgressTracker.cpp index e682b9b..0c9f2fb 100644 --- a/WebCore/loader/ProgressTracker.cpp +++ b/WebCore/loader/ProgressTracker.cpp @@ -47,7 +47,7 @@ static const double finalProgressValue = 0.9; // 1.0 - initialProgressValue static const int progressItemDefaultEstimatedLength = 1024 * 16; -struct ProgressItem { +struct ProgressItem : Noncopyable { ProgressItem(long long length) : bytesReceived(0) , estimatedLength(length) { } @@ -176,8 +176,10 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i // FIXME: Can this ever happen? if (!item) return; + + RefPtr<Frame> frame = m_originatingProgressFrame; - m_originatingProgressFrame->loader()->client()->willChangeEstimatedProgress(); + frame->loader()->client()->willChangeEstimatedProgress(); unsigned bytesReceived = length; double increment, percentOfRemainingBytes; @@ -189,7 +191,7 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i item->estimatedLength = item->bytesReceived * 2; } - int numPendingOrLoadingRequests = m_originatingProgressFrame->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. @@ -199,8 +201,8 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i // For documents that use WebCore's layout system, treat first layout as the half-way point. // FIXME: The hasHTMLView function is a sort of roundabout way of asking "do you use WebCore's layout system". - bool useClampedMaxProgress = m_originatingProgressFrame->loader()->client()->hasHTMLView() - && !m_originatingProgressFrame->loader()->firstLayoutDone(); + bool useClampedMaxProgress = frame->loader()->client()->hasHTMLView() + && !frame->loader()->firstLayoutDone(); double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue; increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes; m_progressValue += increment; @@ -221,14 +223,14 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i if (m_progressValue == 1) m_finalProgressChangedSent = true; - m_originatingProgressFrame->loader()->client()->postProgressEstimateChangedNotification(); + frame->loader()->client()->postProgressEstimateChangedNotification(); m_lastNotifiedProgressValue = m_progressValue; m_lastNotifiedProgressTime = now; } } - m_originatingProgressFrame->loader()->client()->didChangeEstimatedProgress(); + frame->loader()->client()->didChangeEstimatedProgress(); } void ProgressTracker::completeProgress(unsigned long identifier) diff --git a/WebCore/loader/RedirectScheduler.cpp b/WebCore/loader/RedirectScheduler.cpp index c0d78ae..f2202cc 100644 --- a/WebCore/loader/RedirectScheduler.cpp +++ b/WebCore/loader/RedirectScheduler.cpp @@ -39,11 +39,12 @@ #include "FrameLoadRequest.h" #include "FrameLoader.h" #include "HTMLFormElement.h" +#include "Page.h" #include <wtf/CurrentTime.h> namespace WebCore { -struct ScheduledRedirection { +struct ScheduledRedirection : Noncopyable { enum Type { redirection, locationChange, historyNavigation, formSubmission }; const Type type; @@ -171,7 +172,7 @@ bool RedirectScheduler::mustLockBackForwardList(Frame* targetFrame) for (Frame* ancestor = targetFrame->tree()->parent(); ancestor; ancestor = ancestor->tree()->parent()) { Document* document = ancestor->document(); - if (!ancestor->loader()->isComplete() || document && document->processingLoadEvent()) + if (!ancestor->loader()->isComplete() || (document && document->processingLoadEvent())) return true; } return false; diff --git a/WebCore/loader/Request.h b/WebCore/loader/Request.h index 07d1b82..1e02d77 100644 --- a/WebCore/loader/Request.h +++ b/WebCore/loader/Request.h @@ -30,7 +30,7 @@ namespace WebCore { class CachedResource; class DocLoader; - class Request { + class Request : public Noncopyable { public: Request(DocLoader*, CachedResource*, bool incremental, bool skipCanLoadCheck, bool sendResourceLoadCallbacks); ~Request(); diff --git a/WebCore/loader/ResourceLoadNotifier.cpp b/WebCore/loader/ResourceLoadNotifier.cpp index 4cddd01..9280434 100644 --- a/WebCore/loader/ResourceLoadNotifier.cpp +++ b/WebCore/loader/ResourceLoadNotifier.cpp @@ -96,6 +96,11 @@ void ResourceLoadNotifier::didFailToLoad(ResourceLoader* loader, const ResourceE if (!error.isNull()) m_frame->loader()->client()->dispatchDidFailLoading(loader->documentLoader(), loader->identifier(), error); + +#if ENABLE(INSPECTOR) + if (Page* page = m_frame->page()) + page->inspectorController()->didFailLoading(loader->identifier(), error); +#endif } void ResourceLoadNotifier::didLoadResourceByXMLHttpRequest(unsigned long identifier, const ScriptString& sourceString) @@ -126,7 +131,7 @@ void ResourceLoadNotifier::dispatchWillSendRequest(DocumentLoader* loader, unsig #if ENABLE(INSPECTOR) if (Page* page = m_frame->page()) - page->inspectorController()->willSendRequest(loader, identifier, request, redirectResponse); + page->inspectorController()->willSendRequest(identifier, request, redirectResponse); #endif } @@ -136,7 +141,7 @@ void ResourceLoadNotifier::dispatchDidReceiveResponse(DocumentLoader* loader, un #if ENABLE(INSPECTOR) if (Page* page = m_frame->page()) - page->inspectorController()->didReceiveResponse(loader, identifier, r); + page->inspectorController()->didReceiveResponse(identifier, r); #endif } @@ -146,7 +151,7 @@ void ResourceLoadNotifier::dispatchDidReceiveContentLength(DocumentLoader* loade #if ENABLE(INSPECTOR) if (Page* page = m_frame->page()) - page->inspectorController()->didReceiveContentLength(loader, identifier, length); + page->inspectorController()->didReceiveContentLength(identifier, length); #endif } @@ -156,7 +161,7 @@ void ResourceLoadNotifier::dispatchDidFinishLoading(DocumentLoader* loader, unsi #if ENABLE(INSPECTOR) if (Page* page = m_frame->page()) - page->inspectorController()->didFinishLoading(loader, identifier); + page->inspectorController()->didFinishLoading(identifier); #endif } diff --git a/WebCore/loader/ResourceLoadNotifier.h b/WebCore/loader/ResourceLoadNotifier.h index b09d7be..23e4246 100644 --- a/WebCore/loader/ResourceLoadNotifier.h +++ b/WebCore/loader/ResourceLoadNotifier.h @@ -41,7 +41,7 @@ class ResourceError; class ResourceLoader; class ResourceResponse; class ScriptString; -struct ResourceRequest; +class ResourceRequest; class ResourceLoadNotifier : public Noncopyable { public: diff --git a/WebCore/loader/SubresourceLoader.h b/WebCore/loader/SubresourceLoader.h index 0fce930..1a94c73 100644 --- a/WebCore/loader/SubresourceLoader.h +++ b/WebCore/loader/SubresourceLoader.h @@ -33,7 +33,7 @@ namespace WebCore { - struct ResourceRequest; + class ResourceRequest; class SubresourceLoaderClient; class SubresourceLoader : public ResourceLoader { diff --git a/WebCore/loader/SubresourceLoaderClient.h b/WebCore/loader/SubresourceLoaderClient.h index acf8e6a..76fde47 100644 --- a/WebCore/loader/SubresourceLoaderClient.h +++ b/WebCore/loader/SubresourceLoaderClient.h @@ -33,7 +33,7 @@ namespace WebCore { class AuthenticationChallenge; class ResourceError; -struct ResourceRequest; +class ResourceRequest; class ResourceResponse; class SubresourceLoader; diff --git a/WebCore/loader/ThreadableLoader.h b/WebCore/loader/ThreadableLoader.h index a52bfad..f41a774 100644 --- a/WebCore/loader/ThreadableLoader.h +++ b/WebCore/loader/ThreadableLoader.h @@ -38,7 +38,7 @@ namespace WebCore { class ResourceError; - struct ResourceRequest; + class ResourceRequest; class ResourceResponse; class ScriptExecutionContext; class ThreadableLoaderClient; diff --git a/WebCore/loader/ThreadableLoaderClient.h b/WebCore/loader/ThreadableLoaderClient.h index 93a8e86..b8a6584 100644 --- a/WebCore/loader/ThreadableLoaderClient.h +++ b/WebCore/loader/ThreadableLoaderClient.h @@ -36,7 +36,7 @@ namespace WebCore { class ResourceError; class ResourceResponse; - class ThreadableLoaderClient { + class ThreadableLoaderClient : public Noncopyable { public: virtual void didSendData(unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) { } diff --git a/WebCore/loader/WorkerThreadableLoader.h b/WebCore/loader/WorkerThreadableLoader.h index 230c77d..86083f5 100644 --- a/WebCore/loader/WorkerThreadableLoader.h +++ b/WebCore/loader/WorkerThreadableLoader.h @@ -47,7 +47,7 @@ namespace WebCore { class ResourceError; - struct ResourceRequest; + class ResourceRequest; class WorkerContext; class WorkerLoaderProxy; struct CrossThreadResourceResponseData; @@ -94,7 +94,7 @@ namespace WebCore { // thread do "ThreadableLoaderClientWrapper::ref" (automatically inside of the cross thread copy // done in createCallbackTask), so the ThreadableLoaderClientWrapper instance is there until all // tasks are executed. - class MainThreadBridge : ThreadableLoaderClient { + class MainThreadBridge : public ThreadableLoaderClient { public: // All executed on the worker context's thread. MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerLoaderProxy&, const String& taskMode, const ResourceRequest&, const ThreadableLoaderOptions&); diff --git a/WebCore/loader/appcache/ApplicationCache.h b/WebCore/loader/appcache/ApplicationCache.h index d1444c0..08e2dd3 100644 --- a/WebCore/loader/appcache/ApplicationCache.h +++ b/WebCore/loader/appcache/ApplicationCache.h @@ -42,7 +42,7 @@ class ApplicationCacheResource; class DocumentLoader; class KURL; -struct ResourceRequest; +class ResourceRequest; typedef Vector<std::pair<KURL, KURL> > FallbackURLVector; diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp index 1a223ce..7398ef4 100644 --- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp +++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp @@ -622,7 +622,7 @@ void ApplicationCacheGroup::didFinishLoadingManifest() ASSERT(newestManifest); if (!m_manifestResource || // The resource will be null if HTTP response was 304 Not Modified. - newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size())) { + (newestManifest->data()->size() == m_manifestResource->data()->size() && !memcmp(newestManifest->data()->data(), m_manifestResource->data()->data(), newestManifest->data()->size()))) { m_completionType = NoUpdate; m_manifestResource = 0; @@ -947,9 +947,9 @@ void ApplicationCacheGroup::scheduleReachedMaxAppCacheSizeCallback() class CallCacheListenerTask : public ScriptExecutionContext::Task { public: - static PassRefPtr<CallCacheListenerTask> create(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID) + static PassOwnPtr<CallCacheListenerTask> create(PassRefPtr<DocumentLoader> loader, ApplicationCacheHost::EventID eventID) { - return adoptRef(new CallCacheListenerTask(loader, eventID)); + return new CallCacheListenerTask(loader, eventID); } virtual void performTask(ScriptExecutionContext* context) diff --git a/WebCore/loader/appcache/ApplicationCacheHost.h b/WebCore/loader/appcache/ApplicationCacheHost.h index 236013d..9c355de 100644 --- a/WebCore/loader/appcache/ApplicationCacheHost.h +++ b/WebCore/loader/appcache/ApplicationCacheHost.h @@ -45,7 +45,7 @@ namespace WebCore { class KURL; class ResourceLoader; class ResourceError; - struct ResourceRequest; + class ResourceRequest; class ResourceResponse; class SubstituteData; #if PLATFORM(CHROMIUM) @@ -57,7 +57,7 @@ namespace WebCore { class ApplicationCacheStorage; #endif - class ApplicationCacheHost { + class ApplicationCacheHost : public Noncopyable { public: // The Status numeric values are specified in the HTML5 spec. enum Status { diff --git a/WebCore/loader/appcache/ApplicationCacheStorage.h b/WebCore/loader/appcache/ApplicationCacheStorage.h index 1348aa9..aaa5c9c 100644 --- a/WebCore/loader/appcache/ApplicationCacheStorage.h +++ b/WebCore/loader/appcache/ApplicationCacheStorage.h @@ -44,7 +44,7 @@ class KURL; template <class T> class StorageIDJournal; -class ApplicationCacheStorage { +class ApplicationCacheStorage : public Noncopyable { public: void setCacheDirectory(const String&); const String& cacheDirectory() const; diff --git a/WebCore/loader/archive/ArchiveFactory.cpp b/WebCore/loader/archive/ArchiveFactory.cpp index 1322dbb..d09b064 100644 --- a/WebCore/loader/archive/ArchiveFactory.cpp +++ b/WebCore/loader/archive/ArchiveFactory.cpp @@ -29,12 +29,13 @@ #include "config.h" #include "ArchiveFactory.h" -#if PLATFORM(CF) -#include "LegacyWebArchive.h" -#endif #include "MIMETypeRegistry.h" #include "PlatformString.h" +#if PLATFORM(CF) && !PLATFORM(QT) +#include "LegacyWebArchive.h" +#endif + #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/StdLibExtras.h> @@ -55,14 +56,14 @@ static ArchiveMIMETypesMap& archiveMIMETypes() { DEFINE_STATIC_LOCAL(ArchiveMIMETypesMap, mimeTypes, ()); static bool initialized = false; - + if (initialized) return mimeTypes; - -#if PLATFORM(CF) + +#if PLATFORM(CF) && !PLATFORM(QT) mimeTypes.set("application/x-webarchive", archiveFactoryCreate<LegacyWebArchive>); #endif - + initialized = true; return mimeTypes; } diff --git a/WebCore/loader/loader.cpp b/WebCore/loader/loader.cpp index eb606d8..c98a2f0 100644 --- a/WebCore/loader/loader.cpp +++ b/WebCore/loader/loader.cpp @@ -71,6 +71,27 @@ Loader::~Loader() ASSERT_NOT_REACHED(); } +static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource::Type type) +{ + switch (type) { + case CachedResource::CSSStyleSheet: +#if ENABLE(XSLT) + case CachedResource::XSLStyleSheet: +#endif +#if ENABLE(XBL) + case CachedResource::XBL: +#endif + return ResourceRequest::TargetIsStyleSheet; + case CachedResource::Script: + return ResourceRequest::TargetIsScript; + case CachedResource::FontResource: + return ResourceRequest::TargetIsFontResource; + case CachedResource::ImageResource: + return ResourceRequest::TargetIsImage; + } + return ResourceRequest::TargetIsSubresource; +} + Loader::Priority Loader::determinePriority(const CachedResource* resource) const { #if REQUEST_MANAGEMENT_ENABLED @@ -301,6 +322,7 @@ void Loader::Host::servePendingRequests(RequestQueue& requestsPending, bool& ser requestsPending.removeFirst(); ResourceRequest resourceRequest(request->cachedResource()->url()); + resourceRequest.setTargetType(cachedResourceTypeToTargetType(request->cachedResource()->type())); if (!request->cachedResource()->accept().isEmpty()) resourceRequest.setHTTPAccept(request->cachedResource()->accept()); @@ -377,7 +399,7 @@ void Loader::Host::didFinishLoading(SubresourceLoader* loader) docLoader->checkForPendingPreloads(); #if REQUEST_DEBUG - KURL u(resource->url()); + KURL u(ParsedURLString, resource->url()); printf("HOST %s COUNT %d RECEIVED %s\n", u.host().latin1().data(), m_requestsLoading.size(), resource->url().latin1().data()); #endif servePendingRequests(); |