WebKit/chromium/src/ApplicationCacheHost.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions are
       
     6  * met:
       
     7  *
       
     8  *     * Redistributions of source code must retain the above copyright
       
     9  * notice, this list of conditions and the following disclaimer.
       
    10  *     * Redistributions in binary form must reproduce the above
       
    11  * copyright notice, this list of conditions and the following disclaimer
       
    12  * in the documentation and/or other materials provided with the
       
    13  * distribution.
       
    14  *     * Neither the name of Google Inc. nor the names of its
       
    15  * contributors may be used to endorse or promote products derived from
       
    16  * this software without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    29  */
       
    30 
       
    31 #include "config.h"
       
    32 #include "ApplicationCacheHost.h"
       
    33 
       
    34 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
       
    35 
       
    36 #include "ApplicationCacheHostInternal.h"
       
    37 #include "DocumentLoader.h"
       
    38 #include "DOMApplicationCache.h"
       
    39 #include "Frame.h"
       
    40 #include "ProgressEvent.h"
       
    41 #include "Settings.h"
       
    42 #include "WebURL.h"
       
    43 #include "WebURLError.h"
       
    44 #include "WebURLResponse.h"
       
    45 #include "WrappedResourceRequest.h"
       
    46 #include "WrappedResourceResponse.h"
       
    47 
       
    48 using namespace WebKit;
       
    49 
       
    50 namespace WebCore {
       
    51 
       
    52 // We provide a custom implementation of this class that calls out to the
       
    53 // embedding application instead of using WebCore's built in appcache system.
       
    54 // This file replaces webcore/appcache/ApplicationCacheHost.cpp in our build.
       
    55 
       
    56 ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader)
       
    57     : m_domApplicationCache(0)
       
    58     , m_documentLoader(documentLoader)
       
    59     , m_defersEvents(true)
       
    60 {
       
    61     ASSERT(m_documentLoader);
       
    62 }
       
    63 
       
    64 ApplicationCacheHost::~ApplicationCacheHost()
       
    65 {
       
    66 }
       
    67 
       
    68 void ApplicationCacheHost::maybeLoadMainResource(ResourceRequest& request, SubstituteData&)
       
    69 {
       
    70     // We defer creating the outer host object to avoid spurious creation/destruction
       
    71     // around creating empty documents. At this point, we're initiating a main resource
       
    72     // load for the document, so its for real.
       
    73 
       
    74     if (!isApplicationCacheEnabled())
       
    75         return;
       
    76 
       
    77     m_internal.set(new ApplicationCacheHostInternal(this));
       
    78     if (m_internal->m_outerHost) {
       
    79         WrappedResourceRequest wrapped(request);
       
    80         m_internal->m_outerHost->willStartMainResourceRequest(wrapped);
       
    81     } else
       
    82         m_internal.clear();
       
    83 
       
    84     // NOTE: The semantics of this method, and others in this interface, are subtly different
       
    85     // than the method names would suggest. For example, in this method never returns an appcached
       
    86     // response in the SubstituteData out argument, instead we return the appcached response thru
       
    87     // the usual resource loading pipeline.
       
    88 }
       
    89 
       
    90 void ApplicationCacheHost::selectCacheWithoutManifest()
       
    91 {
       
    92     if (m_internal)
       
    93         m_internal->m_outerHost->selectCacheWithoutManifest();
       
    94 }
       
    95 
       
    96 void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL)
       
    97 {
       
    98     if (m_internal) {
       
    99         if (!m_internal->m_outerHost->selectCacheWithManifest(manifestURL)) {
       
   100             // It's a foreign entry, restart the current navigation from the top
       
   101             // of the navigation algorithm. The navigation will not result in the
       
   102             // same resource being loaded, because "foreign" entries are never picked
       
   103             // during navigation.
       
   104             // see WebCore::ApplicationCacheGroup::selectCache()
       
   105             const KURL& docURL = m_documentLoader->frame()->document()->url();
       
   106             String referrer = m_documentLoader->frameLoader()->referrer();
       
   107             m_documentLoader->frame()->redirectScheduler()->scheduleLocationChange(docURL, referrer);
       
   108         }
       
   109     }
       
   110 }
       
   111 
       
   112 bool ApplicationCacheHost::maybeLoadFallbackForMainResponse(const ResourceRequest&, const ResourceResponse& response)
       
   113 {
       
   114     if (m_internal) {
       
   115         WrappedResourceResponse wrapped(response);
       
   116         m_internal->m_outerHost->didReceiveResponseForMainResource(wrapped);
       
   117     }
       
   118     return false;
       
   119 }
       
   120 
       
   121 bool ApplicationCacheHost::maybeLoadFallbackForMainError(const ResourceRequest&, const ResourceError& error)
       
   122 {
       
   123     // N/A to the chromium port
       
   124     return false;
       
   125 }
       
   126 
       
   127 void ApplicationCacheHost::mainResourceDataReceived(const char* data, int length, long long, bool)
       
   128 {
       
   129     if (m_internal)
       
   130         m_internal->m_outerHost->didReceiveDataForMainResource(data, length);
       
   131 }
       
   132 
       
   133 void ApplicationCacheHost::failedLoadingMainResource()
       
   134 {
       
   135     if (m_internal)
       
   136         m_internal->m_outerHost->didFinishLoadingMainResource(false);
       
   137 }
       
   138 
       
   139 void ApplicationCacheHost::finishedLoadingMainResource()
       
   140 {
       
   141     if (m_internal)
       
   142         m_internal->m_outerHost->didFinishLoadingMainResource(true);
       
   143 }
       
   144 
       
   145 bool ApplicationCacheHost::maybeLoadResource(ResourceLoader*, ResourceRequest& request, const KURL&)
       
   146 {
       
   147     // FIXME: look into the purpose of the unused KURL& originalURL parameter
       
   148     if (m_internal) {
       
   149         WrappedResourceRequest wrapped(request);
       
   150         m_internal->m_outerHost->willStartSubResourceRequest(wrapped);
       
   151     }
       
   152     return false;
       
   153 }
       
   154 
       
   155 bool ApplicationCacheHost::maybeLoadFallbackForRedirect(ResourceLoader*, ResourceRequest&, const ResourceResponse&)
       
   156 {
       
   157     // N/A to the chromium port
       
   158     return false;
       
   159 }
       
   160 
       
   161 bool ApplicationCacheHost::maybeLoadFallbackForResponse(ResourceLoader*, const ResourceResponse&)
       
   162 {
       
   163     // N/A to the chromium port
       
   164     return false;
       
   165 }
       
   166 
       
   167 bool ApplicationCacheHost::maybeLoadFallbackForError(ResourceLoader*, const ResourceError&)
       
   168 {
       
   169     // N/A to the chromium port
       
   170     return false;
       
   171 }
       
   172 
       
   173 bool ApplicationCacheHost::maybeLoadSynchronously(ResourceRequest& request, ResourceError&, ResourceResponse&, Vector<char>&)
       
   174 {
       
   175     if (m_internal) {
       
   176         WrappedResourceRequest wrapped(request);
       
   177         m_internal->m_outerHost->willStartSubResourceRequest(wrapped);
       
   178     }
       
   179     return false;
       
   180 }
       
   181 
       
   182 void ApplicationCacheHost::maybeLoadFallbackSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>&)
       
   183 {
       
   184     // N/A to the chromium port
       
   185 }
       
   186 
       
   187 bool ApplicationCacheHost::canCacheInPageCache() const
       
   188 {
       
   189     // N/A to the chromium port which doesn't use the page cache.
       
   190     return false;
       
   191 }
       
   192 
       
   193 void ApplicationCacheHost::setDOMApplicationCache(DOMApplicationCache* domApplicationCache)
       
   194 {
       
   195     ASSERT(!m_domApplicationCache || !domApplicationCache);
       
   196     m_domApplicationCache = domApplicationCache;
       
   197 }
       
   198 
       
   199 void ApplicationCacheHost::notifyDOMApplicationCache(EventID id, int total, int done)
       
   200 {
       
   201     if (m_defersEvents) {
       
   202         // Event dispatching is deferred until document.onload has fired.
       
   203         m_deferredEvents.append(DeferredEvent(id, total, done));
       
   204         return;
       
   205     }
       
   206     dispatchDOMEvent(id, total, done);
       
   207 }
       
   208 
       
   209 void ApplicationCacheHost::stopDeferringEvents()
       
   210 {
       
   211     RefPtr<DocumentLoader> protect(documentLoader());
       
   212     for (unsigned i = 0; i < m_deferredEvents.size(); ++i) {
       
   213         const DeferredEvent& deferred = m_deferredEvents[i];
       
   214         dispatchDOMEvent(deferred.eventID, deferred.progressTotal, deferred.progressDone);
       
   215     }
       
   216     m_deferredEvents.clear();
       
   217     m_defersEvents = false;
       
   218 }
       
   219 
       
   220 void ApplicationCacheHost::dispatchDOMEvent(EventID id, int total, int done)
       
   221 {
       
   222     if (m_domApplicationCache) {
       
   223         const AtomicString& eventType = DOMApplicationCache::toEventType(id);
       
   224         ExceptionCode ec = 0;
       
   225         RefPtr<Event> event;
       
   226         if (id == PROGRESS_EVENT)
       
   227             event = ProgressEvent::create(eventType, true, done, total);
       
   228         else
       
   229             event = Event::create(eventType, false, false);
       
   230         m_domApplicationCache->dispatchEvent(event, ec);
       
   231         ASSERT(!ec);
       
   232     }
       
   233 }
       
   234 
       
   235 ApplicationCacheHost::Status ApplicationCacheHost::status() const
       
   236 {
       
   237     return m_internal ? static_cast<Status>(m_internal->m_outerHost->status()) : UNCACHED;
       
   238 }
       
   239 
       
   240 bool ApplicationCacheHost::update()
       
   241 {
       
   242     return m_internal ? m_internal->m_outerHost->startUpdate() : false;
       
   243 }
       
   244 
       
   245 bool ApplicationCacheHost::swapCache()
       
   246 {
       
   247     return m_internal ? m_internal->m_outerHost->swapCache() : false;
       
   248 }
       
   249 
       
   250 bool ApplicationCacheHost::isApplicationCacheEnabled()
       
   251 {
       
   252     ASSERT(m_documentLoader->frame());
       
   253     return m_documentLoader->frame()->settings()
       
   254            && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled();
       
   255 }
       
   256 
       
   257 }  // namespace WebCore
       
   258 
       
   259 #endif  // ENABLE(OFFLINE_WEB_APPLICATIONS)