2006-09-25 Anders Carlsson <acarlsson@apple.com>
[WebKit-https.git] / WebCore / loader / DocLoader.cpp
1 /*
2     This file is part of the KDE libraries
3
4     Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
5     Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
6     Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
7     Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
8
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Library General Public
11     License as published by the Free Software Foundation; either
12     version 2 of the License, or (at your option) any later version.
13
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Library General Public License for more details.
18
19     You should have received a copy of the GNU Library General Public License
20     along with this library; see the file COPYING.LIB.  If not, write to
21     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22     Boston, MA 02111-1307, USA.
23
24     This class provides all functionality needed for loading images, style sheets and html
25     pages from the web. It has a memory cache for these objects.
26 */
27
28 #include "config.h"
29 #include "DocLoader.h"
30
31 #include "Cache.h"
32 #include "CachedCSSStyleSheet.h"
33 #include "CachedImage.h"
34 #include "CachedScript.h"
35 #include "CachedXSLStyleSheet.h"
36 #include "Document.h"
37 #include "Frame.h"
38 #include "LoaderFunctions.h"
39 #include "loader.h"
40
41 namespace WebCore {
42
43 DocLoader::DocLoader(Frame *frame, Document* doc)
44 {
45     m_cachePolicy = CachePolicyVerify;
46     m_expireDate = 0;
47     m_bautoloadImages = true;
48     m_frame = frame;
49     m_doc = doc;
50     m_loadInProgress = false;
51
52     Cache::init();
53     Cache::docloaders->add(this);
54 }
55
56 DocLoader::~DocLoader()
57 {
58     Cache::docloaders->remove(this);
59 }
60
61 void DocLoader::setExpireDate(time_t _expireDate)
62 {
63     m_expireDate = _expireDate;
64 }
65
66 bool DocLoader::needReload(const KURL& fullURL)
67 {
68     bool reload = false;
69     if (m_cachePolicy == CachePolicyVerify) {
70        if (!m_reloadedURLs.contains(fullURL.url())) {
71           CachedResource* existing = Cache::get(fullURL.url());
72           if (existing && existing->isExpired()) {
73              Cache::remove(existing);
74              m_reloadedURLs.add(fullURL.url());
75              reload = true;
76           }
77        }
78     } else if ((m_cachePolicy == CachePolicyReload) || (m_cachePolicy == CachePolicyRefresh)) {
79        if (!m_reloadedURLs.contains(fullURL.url())) {
80           CachedResource* existing = Cache::get(fullURL.url());
81           if (existing)
82              Cache::remove(existing);
83           m_reloadedURLs.add(fullURL.url());
84           reload = true;
85        }
86     }
87     return reload;
88 }
89
90 CachedImage *DocLoader::requestImage(const String& url)
91 {
92     KURL fullURL = m_doc->completeURL(url.deprecatedString());
93
94     if (CheckIfReloading(this))
95         setCachePolicy(CachePolicyReload);
96
97     bool reload = needReload(fullURL);
98
99     CachedImage *cachedObject = Cache::requestImage(this, fullURL, reload, m_expireDate);
100     CheckCacheObjectStatus(this, cachedObject);
101     return cachedObject;
102 }
103
104 CachedCSSStyleSheet *DocLoader::requestStyleSheet(const String& url, const String& charset)
105 {
106     KURL fullURL = m_doc->completeURL(url.deprecatedString());
107
108     if (CheckIfReloading(this))
109         setCachePolicy(CachePolicyReload);
110
111     bool reload = needReload(fullURL);
112
113     CachedCSSStyleSheet* cachedObject = Cache::requestStyleSheet(this, url, reload, m_expireDate, charset);
114     CheckCacheObjectStatus(this, cachedObject);
115     return cachedObject;
116 }
117
118 CachedScript* DocLoader::requestScript(const String& url, const String& charset)
119 {
120     KURL fullURL = m_doc->completeURL(url.deprecatedString());
121
122     if (CheckIfReloading(this))
123         setCachePolicy(CachePolicyReload);
124
125     bool reload = needReload(fullURL);
126
127     CachedScript *cachedObject = Cache::requestScript(this, url, reload, m_expireDate, charset);
128     CheckCacheObjectStatus(this, cachedObject);
129     return cachedObject;
130 }
131
132 #ifdef XSLT_SUPPORT
133 CachedXSLStyleSheet* DocLoader::requestXSLStyleSheet(const String& url)
134 {
135     KURL fullURL = m_doc->completeURL(url.deprecatedString());
136     
137     if (CheckIfReloading(this))
138         setCachePolicy(CachePolicyReload);
139     
140     bool reload = needReload(fullURL);
141     
142     CachedXSLStyleSheet *cachedObject = Cache::requestXSLStyleSheet(this, url, reload, m_expireDate);
143     CheckCacheObjectStatus(this, cachedObject);
144     return cachedObject;
145 }
146 #endif
147
148 #ifdef XBL_SUPPORT
149 CachedXBLDocument* DocLoader::requestXBLDocument(const String& url)
150 {
151     KURL fullURL = m_doc->completeURL(url.deprecatedString());
152     
153     // FIXME: Is this right for XBL?
154     if (m_frame && m_frame->onlyLocalReferences() && fullURL.protocol() != "file") return 0;
155     
156     if (CheckIfReloading(this))
157         setCachePolicy(CachePolicyReload);
158     
159     bool reload = needReload(fullURL);
160     
161     CachedXBLDocument *cachedObject = Cache::requestXBLDocument(this, url, reload, m_expireDate);
162     CheckCacheObjectStatus(this, cachedObject);
163     return cachedObject;
164 }
165 #endif
166
167 void DocLoader::setAutoloadImages(bool enable)
168 {
169     if (enable == m_bautoloadImages)
170         return;
171
172     m_bautoloadImages = enable;
173
174     if (!m_bautoloadImages)
175         return;
176
177     HashMap<String, CachedResource*>::iterator end = m_docObjects.end();
178     for (HashMap<String, CachedResource*>::iterator it = m_docObjects.begin(); it != end; ++it) {
179         CachedResource* co = it->second;
180         if (co->type() == CachedResource::ImageResource) {
181             CachedImage *img = const_cast<CachedImage*>(static_cast<const CachedImage *>(co));
182
183             CachedResource::Status status = img->status();
184             if (status != CachedResource::Unknown)
185                 continue;
186
187             Cache::loader()->load(this, img, true);
188         }
189     }
190 }
191
192 void DocLoader::setCachePolicy(CachePolicy cachePolicy)
193 {
194     m_cachePolicy = cachePolicy;
195 }
196
197 void DocLoader::removeCachedObject(CachedResource* o) const
198 {
199     m_docObjects.remove(o->url());
200 }
201
202 void DocLoader::setLoadInProgress(bool load)
203 {
204     m_loadInProgress = load;
205     if (!load)
206         m_frame->loadDone();
207 }
208
209 }