OLD | NEW |
| (Empty) |
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 "core/loader/appcache/ApplicationCacheHost.h" | |
33 | |
34 #include "public/platform/WebURL.h" | |
35 #include "public/platform/WebURLError.h" | |
36 #include "public/platform/WebURLResponse.h" | |
37 #include "public/platform/WebVector.h" | |
38 #include "ApplicationCacheHostInternal.h" | |
39 #include "WebFrameImpl.h" | |
40 #include "bindings/v8/ExceptionStatePlaceholder.h" | |
41 #include "core/events/ProgressEvent.h" | |
42 #include "core/inspector/InspectorApplicationCacheAgent.h" | |
43 #include "core/inspector/InspectorInstrumentation.h" | |
44 #include "core/loader/DocumentLoader.h" | |
45 #include "core/loader/FrameLoader.h" | |
46 #include "core/loader/appcache/ApplicationCache.h" | |
47 #include "core/frame/Frame.h" | |
48 #include "core/page/Page.h" | |
49 #include "core/frame/Settings.h" | |
50 #include "platform/exported/WrappedResourceRequest.h" | |
51 #include "platform/exported/WrappedResourceResponse.h" | |
52 #include "platform/weborigin/SecurityOrigin.h" | |
53 | |
54 using namespace blink; | |
55 | |
56 namespace WebCore { | |
57 | |
58 // We provide a custom implementation of this class that calls out to the | |
59 // embedding application instead of using WebCore's built in appcache system. | |
60 // This file replaces webcore/appcache/ApplicationCacheHost.cpp in our build. | |
61 | |
62 ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader) | |
63 : m_domApplicationCache(0) | |
64 , m_documentLoader(documentLoader) | |
65 , m_defersEvents(true) | |
66 { | |
67 ASSERT(m_documentLoader); | |
68 } | |
69 | |
70 ApplicationCacheHost::~ApplicationCacheHost() | |
71 { | |
72 } | |
73 | |
74 void ApplicationCacheHost::willStartLoadingMainResource(ResourceRequest& request
) | |
75 { | |
76 // We defer creating the outer host object to avoid spurious creation/destru
ction | |
77 // around creating empty documents. At this point, we're initiating a main r
esource | |
78 // load for the document, so its for real. | |
79 | |
80 if (!isApplicationCacheEnabled()) | |
81 return; | |
82 | |
83 m_internal = adoptPtr(new ApplicationCacheHostInternal(this)); | |
84 if (m_internal->m_outerHost) { | |
85 WrappedResourceRequest wrapped(request); | |
86 m_internal->m_outerHost->willStartMainResourceRequest(wrapped, WebFrameI
mpl::fromFrame(m_documentLoader->frame())); | |
87 } else | |
88 m_internal.clear(); | |
89 | |
90 // NOTE: The semantics of this method, and others in this interface, are sub
tly different | |
91 // than the method names would suggest. For example, in this method never re
turns an appcached | |
92 // response in the SubstituteData out argument, instead we return the appcac
hed response thru | |
93 // the usual resource loading pipeline. | |
94 } | |
95 | |
96 void ApplicationCacheHost::selectCacheWithoutManifest() | |
97 { | |
98 if (m_internal) | |
99 m_internal->m_outerHost->selectCacheWithoutManifest(); | |
100 } | |
101 | |
102 void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL) | |
103 { | |
104 if (m_internal) { | |
105 if (!m_internal->m_outerHost->selectCacheWithManifest(manifestURL)) { | |
106 // It's a foreign entry, restart the current navigation from the top | |
107 // of the navigation algorithm. The navigation will not result in th
e | |
108 // same resource being loaded, because "foreign" entries are never p
icked | |
109 // during navigation. | |
110 // see WebCore::ApplicationCacheGroup::selectCache() | |
111 Frame* frame = m_documentLoader->frame(); | |
112 frame->navigationScheduler().scheduleLocationChange(frame->document(
), | |
113 frame->document()->url(), Referrer(frame->document()->referrer()
, frame->document()->referrerPolicy())); | |
114 } | |
115 } | |
116 } | |
117 | |
118 void ApplicationCacheHost::didReceiveResponseForMainResource(const ResourceRespo
nse& response) | |
119 { | |
120 if (m_internal) { | |
121 WrappedResourceResponse wrapped(response); | |
122 m_internal->m_outerHost->didReceiveResponseForMainResource(wrapped); | |
123 } | |
124 } | |
125 | |
126 void ApplicationCacheHost::mainResourceDataReceived(const char* data, int length
) | |
127 { | |
128 if (m_internal) | |
129 m_internal->m_outerHost->didReceiveDataForMainResource(data, length); | |
130 } | |
131 | |
132 void ApplicationCacheHost::failedLoadingMainResource() | |
133 { | |
134 if (m_internal) | |
135 m_internal->m_outerHost->didFinishLoadingMainResource(false); | |
136 } | |
137 | |
138 void ApplicationCacheHost::finishedLoadingMainResource() | |
139 { | |
140 if (m_internal) | |
141 m_internal->m_outerHost->didFinishLoadingMainResource(true); | |
142 } | |
143 | |
144 void ApplicationCacheHost::willStartLoadingResource(ResourceRequest& request) | |
145 { | |
146 // FIXME: look into the purpose of the unused KURL& originalURL parameter | |
147 if (m_internal) { | |
148 WrappedResourceRequest wrapped(request); | |
149 m_internal->m_outerHost->willStartSubResourceRequest(wrapped); | |
150 } | |
151 } | |
152 | |
153 void ApplicationCacheHost::setApplicationCache(ApplicationCache* domApplicationC
ache) | |
154 { | |
155 ASSERT(!m_domApplicationCache || !domApplicationCache); | |
156 m_domApplicationCache = domApplicationCache; | |
157 } | |
158 | |
159 void ApplicationCacheHost::notifyApplicationCache(EventID id, int total, int don
e) | |
160 { | |
161 if (id != PROGRESS_EVENT) | |
162 InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader-
>frame()); | |
163 | |
164 if (m_defersEvents) { | |
165 // Event dispatching is deferred until document.onload has fired. | |
166 m_deferredEvents.append(DeferredEvent(id, total, done)); | |
167 return; | |
168 } | |
169 dispatchDOMEvent(id, total, done); | |
170 } | |
171 | |
172 ApplicationCacheHost::CacheInfo ApplicationCacheHost::applicationCacheInfo() | |
173 { | |
174 if (!m_internal) | |
175 return CacheInfo(KURL(), 0, 0, 0); | |
176 | |
177 blink::WebApplicationCacheHost::CacheInfo webInfo; | |
178 m_internal->m_outerHost->getAssociatedCacheInfo(&webInfo); | |
179 return CacheInfo(webInfo.manifestURL, webInfo.creationTime, webInfo.updateTi
me, webInfo.totalSize); | |
180 } | |
181 | |
182 void ApplicationCacheHost::fillResourceList(ResourceInfoList* resources) | |
183 { | |
184 if (!m_internal) | |
185 return; | |
186 | |
187 blink::WebVector<blink::WebApplicationCacheHost::ResourceInfo> webResources; | |
188 m_internal->m_outerHost->getResourceList(&webResources); | |
189 for (size_t i = 0; i < webResources.size(); ++i) { | |
190 resources->append(ResourceInfo( | |
191 webResources[i].url, webResources[i].isMaster, webResources[i].isMan
ifest, webResources[i].isFallback, | |
192 webResources[i].isForeign, webResources[i].isExplicit, webResources[
i].size)); | |
193 } | |
194 } | |
195 | |
196 void ApplicationCacheHost::stopDeferringEvents() | |
197 { | |
198 RefPtr<DocumentLoader> protect(documentLoader()); | |
199 for (unsigned i = 0; i < m_deferredEvents.size(); ++i) { | |
200 const DeferredEvent& deferred = m_deferredEvents[i]; | |
201 dispatchDOMEvent(deferred.eventID, deferred.progressTotal, deferred.prog
ressDone); | |
202 } | |
203 m_deferredEvents.clear(); | |
204 m_defersEvents = false; | |
205 } | |
206 | |
207 void ApplicationCacheHost::dispatchDOMEvent(EventID id, int total, int done) | |
208 { | |
209 if (m_domApplicationCache) { | |
210 const AtomicString& eventType = ApplicationCache::toEventType(id); | |
211 RefPtr<Event> event; | |
212 if (id == PROGRESS_EVENT) | |
213 event = ProgressEvent::create(eventType, true, done, total); | |
214 else | |
215 event = Event::create(eventType); | |
216 m_domApplicationCache->dispatchEvent(event, ASSERT_NO_EXCEPTION); | |
217 } | |
218 } | |
219 | |
220 ApplicationCacheHost::Status ApplicationCacheHost::status() const | |
221 { | |
222 return m_internal ? static_cast<Status>(m_internal->m_outerHost->status()) :
UNCACHED; | |
223 } | |
224 | |
225 bool ApplicationCacheHost::update() | |
226 { | |
227 return m_internal ? m_internal->m_outerHost->startUpdate() : false; | |
228 } | |
229 | |
230 bool ApplicationCacheHost::swapCache() | |
231 { | |
232 bool success = m_internal ? m_internal->m_outerHost->swapCache() : false; | |
233 if (success) | |
234 InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader-
>frame()); | |
235 return success; | |
236 } | |
237 | |
238 void ApplicationCacheHost::abort() | |
239 { | |
240 if (m_internal) | |
241 m_internal->m_outerHost->abort(); | |
242 } | |
243 | |
244 bool ApplicationCacheHost::isApplicationCacheEnabled() | |
245 { | |
246 ASSERT(m_documentLoader->frame()); | |
247 return m_documentLoader->frame()->settings() | |
248 && m_documentLoader->frame()->settings()->offlineWebApplicationCacheE
nabled(); | |
249 } | |
250 | |
251 } // namespace WebCore | |
OLD | NEW |