don't discard iframe children.
[kdelibs.git] / khtml / misc / loader.h
blobed77f941f9e694695c80bfe56351112bc2aef7c4
1 /*
2 This file is part of the KDE libraries
4 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
5 Copyright (C) 2001-2003 Dirk Mueller <mueller@kde.org>
6 Copyright (C) 2003 Apple Computer, Inc
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
23 This class provides all functionality needed for loading images, style sheets and html
24 pages from the web. It has a memory cache for these objects.
26 #ifndef _khtml_loader_h
27 #define _khtml_loader_h
29 #include <config.h>
30 #include <time.h>
32 #include "loader_client.h"
33 #ifdef HAVE_LIBJPEG
34 #include "loader_jpeg.h"
35 #endif
37 #include <stdlib.h>
38 #include <QtCore/QObject>
39 #include <QtGui/QPixmap>
40 #include <QtCore/QBuffer>
41 #include <QtCore/QStringList>
42 #include <QtCore/QTextCodec>
43 #include <QtCore/QTimer>
44 #include <QtCore/QSet>
45 #include <QLinkedList>
47 #include <kurl.h>
48 #include <kio/global.h>
50 #include <khtml_settings.h>
51 #include <dom/dom_string.h>
52 #include "imload/image.h"
53 #include "imload/imageowner.h"
55 class KHTMLPart;
57 class KJob;
58 namespace KIO {
59 class Job;
62 namespace DOM
64 class DocumentImpl;
67 namespace khtml
69 class CachedObject;
70 class Request;
71 class DocLoader;
73 /**
74 * @internal
76 * A cached object. Classes who want to use this object should derive
77 * from CachedObjectClient, to get the function calls in case the requested data has arrived.
79 * This class also does the actual communication with kio and loads the file.
81 class CachedObject
83 public:
84 enum Type {
85 Image,
86 CSSStyleSheet,
87 Script,
88 Sound
91 enum Status {
92 Unknown, // let imagecache decide what to do with it
93 New, // inserting new image
94 Pending, // only partially loaded
95 Persistent, // never delete this pixmap
96 Cached // regular case
99 enum PreloadResult {
100 PreloadNotReferenced = 0,
101 PreloadReferenced,
102 PreloadReferencedWhileLoading,
103 PreloadReferencedWhileComplete
106 PreloadResult preloadResult() const { return m_preloadResult; }
107 void setProspectiveRequest() { m_prospectiveRequest = true; }
109 CachedObject(const DOM::DOMString &url, Type type, KIO::CacheControl _cachePolicy, int size)
110 : m_url(url), m_type(type), m_cachePolicy(_cachePolicy),
111 m_expireDate(0), m_size(size)
113 m_status = Pending;
114 m_accessCount = 0;
115 m_cachePolicy = _cachePolicy;
116 m_request = 0;
117 m_deleted = false;
118 m_free = false;
119 m_hadError = false;
120 m_wasBlocked = false;
121 m_prev = m_next = 0;
122 m_preloadCount = 0;
123 m_preloadResult = PreloadNotReferenced;
124 m_prospectiveRequest = false;
126 virtual ~CachedObject();
128 virtual void data( QBuffer &buffer, bool eof) = 0;
129 virtual void error( int err, const char *text ) = 0;
131 const DOM::DOMString &url() const { return m_url; }
132 Type type() const { return m_type; }
134 virtual void ref(CachedObjectClient *consumer);
135 virtual void deref(CachedObjectClient *consumer);
137 int count() const { return m_clients.count(); }
138 int accessCount() const { return m_accessCount; }
140 bool isPreloaded() const { return m_preloadCount; }
141 void increasePreloadCount() { ++m_preloadCount; }
142 void decreasePreloadCount() { assert(m_preloadCount); --m_preloadCount; }
144 void setStatus(Status s) { m_status = s; }
145 Status status() const { return m_status; }
147 virtual void setCharset( const QString& /*charset*/ ) {}
149 QTextCodec* codecForBuffer( const QString& charset, const QByteArray& buffer ) const;
151 int size() const { return m_size; }
153 bool isLoaded() const { return !m_loading; }
154 bool hadError() const { return m_hadError; }
156 bool free() const { return m_free; }
158 KIO::CacheControl cachePolicy() const { return m_cachePolicy; }
160 void setRequest(Request *_request);
162 bool canDelete() const { return (m_clients.count() == 0 && !m_request && !m_preloadCount); }
164 void setExpireDate(time_t _expireDate) { m_expireDate = _expireDate; }
166 bool isExpired() const;
168 virtual bool schedule() const { return false; }
169 virtual void finish();
172 * List of acceptable mimetypes separated by ",". A mimetype may contain a wildcard.
174 // e.g. "text/*"
175 QString accept() const { return m_accept; }
176 void setAccept(const QString &_accept) { m_accept = _accept; }
178 // the mimetype that was eventually used
179 QString mimetype() const { return m_mimetype; }
181 protected:
182 void setSize(int size);
183 QHash<CachedObjectClient*,CachedObjectClient*> m_clients;
184 DOM::DOMString m_url;
185 QString m_accept;
186 QString m_mimetype;
187 Request *m_request;
188 Type m_type;
189 Status m_status;
190 int m_accessCount;
191 KIO::CacheControl m_cachePolicy;
192 time_t m_expireDate;
193 int m_size;
194 unsigned m_preloadCount;
195 PreloadResult m_preloadResult: 3;
196 bool m_deleted : 1;
197 bool m_loading : 1;
198 bool m_free : 1;
199 bool m_hadError : 1;
200 bool m_wasBlocked : 1;
201 bool m_prospectiveRequest: 1;
203 private:
204 bool allowInLRUList() const { return canDelete() && !m_free && status() != Persistent; }
205 CachedObject* m_next;
206 CachedObject* m_prev;
207 friend class Cache;
208 friend class ::KHTMLPart;
209 friend class Loader;
213 bool isAcceptableCSSMimetype( const DOM::DOMString& mimetype );
216 * a cached style sheet. also used for loading xml documents.
218 * ### rename to CachedTextDoc or something since it's more generic than just for css
220 class CachedCSSStyleSheet : public CachedObject
222 public:
223 CachedCSSStyleSheet(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy,
224 const char *accept);
225 CachedCSSStyleSheet(const DOM::DOMString &url, const QString &stylesheet_data);
227 const DOM::DOMString &sheet() const { return m_sheet; }
229 virtual void ref(CachedObjectClient *consumer);
231 virtual void data( QBuffer &buffer, bool eof );
232 virtual void error( int err, const char *text );
234 virtual bool schedule() const { return true; }
235 void setCharsetHint( const QString& charset ) { m_charsetHint = charset; }
236 void setCharset( const QString& charset ) { m_charset = charset; }
239 protected:
240 void checkNotify();
242 DOM::DOMString m_sheet;
243 QString m_charset;
244 QString m_charsetHint;
245 int m_err;
246 QString m_errText;
250 * a cached script
252 class CachedScript : public CachedObject
254 public:
255 CachedScript(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char* accept );
256 CachedScript(const DOM::DOMString &url, const QString &script_data);
258 const DOM::DOMString &script() const { return m_script; }
260 virtual void ref(CachedObjectClient *consumer);
262 virtual void data( QBuffer &buffer, bool eof );
263 virtual void error( int err, const char *text );
265 virtual bool schedule() const { return false; }
267 void checkNotify();
269 bool isLoaded() const { return !m_loading; }
270 void setCharset( const QString& charset ) { m_charset = charset; }
272 protected:
273 QString m_charset;
274 DOM::DOMString m_script;
277 class ImageSource;
280 * a cached image
282 class CachedImage : public QObject, public CachedObject, public khtmlImLoad::ImageOwner
284 Q_OBJECT
285 public:
286 CachedImage(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char* accept);
287 virtual ~CachedImage();
289 QPixmap pixmap() const;
290 QPixmap* scaled_pixmap(int xWidth, int xHeight);
291 QPixmap tiled_pixmap(const QColor& bg, int xWidth = -1, int xHeight = -1);
293 QSize pixmap_size() const; // returns the size of the complete (i.e. when finished) loading
294 //QRect valid_rect() const; // returns the rectangle of pixmap that has been loaded already
296 bool canRender() const { return !isErrorImage() && pixmap_size().width() > 0 && pixmap_size().height() > 0; }
297 void ref(CachedObjectClient *consumer);
298 virtual void deref(CachedObjectClient *consumer);
301 virtual void data( QBuffer &buffer, bool eof );
302 virtual void error( int err, const char *text );
305 bool isComplete() const { return i && i->complete(); }
306 bool isTransparent() const { return false; } //### isFullyTransparent; }
307 bool isErrorImage() const { return m_hadError; }
308 bool isBlockedImage() const { return m_wasBlocked; }
309 const QString& suggestedFilename() const { return m_suggestedFilename; }
310 void setSuggestedFilename( const QString& s ) { m_suggestedFilename = s; }
311 #ifdef IMAGE_TITLES
312 const QString& suggestedTitle() const { return m_suggestedTitle; }
313 void setSuggestedTitle( const QString& s ) { m_suggestedTitle = s; }
314 #else
315 const QString& suggestedTitle() const { return m_suggestedFilename; }
316 #endif
318 void setShowAnimations( KHTMLSettings::KAnimationAdvice );
319 void pauseAnimations();
320 void resumeAnimations();
322 virtual bool schedule() const { return true; }
324 virtual void finish();
327 khtmlImLoad::Image* image() { return i; }
329 protected:
330 void clear();
332 private:
334 Interface to the image
336 virtual void imageHasGeometry(khtmlImLoad::Image* img, int width, int height);
337 virtual void imageChange (khtmlImLoad::Image* img, QRect region);
338 virtual void imageError (khtmlImLoad::Image* img);
339 virtual void imageDone (khtmlImLoad::Image* img);
340 private:
341 void doNotifyFinished();
343 void do_notify(const QRect& r);
344 khtmlImLoad::Image* i;
346 QString m_suggestedFilename;
347 #ifdef IMAGE_TITLES
348 QString m_suggestedTitle;
349 #endif
350 QPixmap* bg;
351 QPixmap* scaled;
352 QRgb bgColor;
353 QSize bgSize;
355 ImageSource* imgSource;
356 const char* formatType; // Is the name of the movie format type
358 int width;
359 int height;
361 // Is set if movie format type ( incremental/animation) was checked
362 bool typeChecked : 1;
363 bool isFullyTransparent : 1;
364 bool monochrome : 1;
366 friend class Cache;
367 friend class ::KHTMLPart;
371 * a cached sound
373 class CachedSound : public CachedObject
375 public:
376 CachedSound(DocLoader* dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char* accept );
378 QByteArray sound() const { return m_sound; }
380 virtual void ref(CachedObjectClient *consumer);
381 virtual void data( QBuffer &buffer, bool eof );
382 virtual void error( int err, const char *text );
383 virtual bool schedule() const { return false; }
385 void checkNotify();
387 bool isLoaded() const { return !m_loading; }
389 protected:
390 QByteArray m_sound;
395 * @internal
397 * Manages the loading of scripts/images/stylesheets for a particular document
399 class DocLoader
401 public:
402 DocLoader(KHTMLPart*, DOM::DocumentImpl*);
403 ~DocLoader();
405 CachedImage *requestImage( const DOM::DOMString &url);
406 CachedCSSStyleSheet *requestStyleSheet( const DOM::DOMString &url, const QString& charsetHint,
407 const char *accept = "text/css", bool userSheet = false );
408 CachedScript *requestScript( const DOM::DOMString &url, const QString& charset);
409 CachedSound *requestSound( const DOM::DOMString &url );
411 bool autoloadImages() const { return m_bautoloadImages; }
412 KIO::CacheControl cachePolicy() const { return m_cachePolicy; }
413 KHTMLSettings::KAnimationAdvice showAnimations() const { return m_showAnimations; }
414 time_t expireDate() const { return m_expireDate; }
415 KHTMLPart* part() const { return m_part; }
416 DOM::DocumentImpl* doc() const { return m_doc; }
418 void setCacheCreationDate( time_t );
419 void setExpireDate( time_t, bool relative );
420 void setAutoloadImages( bool );
421 void setCachePolicy( KIO::CacheControl cachePolicy ) { m_cachePolicy = cachePolicy; }
422 void setShowAnimations( KHTMLSettings::KAnimationAdvice );
423 void pauseAnimations();
424 void resumeAnimations();
425 void insertCachedObject( CachedObject* o ) const;
426 void removeCachedObject( CachedObject* o) const { m_docObjects.remove( o ); }
427 void clearPreloads();
428 void registerPreload(CachedObject*);
429 void printPreloadStats();
431 private:
432 bool needReload(CachedObject *existing, const QString &fullUrl);
434 friend class Cache;
435 friend class DOM::DocumentImpl;
436 friend class ::KHTMLPart;
438 QStringList m_reloadedURLs;
439 mutable QSet<CachedObject*> m_docObjects;
440 QSet<CachedObject*> m_preloads;
441 time_t m_expireDate;
442 time_t m_creationDate;
443 KIO::CacheControl m_cachePolicy;
444 bool m_bautoloadImages : 1;
445 KHTMLSettings::KAnimationAdvice m_showAnimations : 2;
446 KHTMLPart* m_part;
447 DOM::DocumentImpl* m_doc;
451 * @internal
453 class Request
455 public:
456 Request(DocLoader* dl, CachedObject *_object, bool _incremental);
457 ~Request();
458 bool incremental;
459 QBuffer m_buffer;
460 CachedObject *object;
461 DocLoader* m_docLoader;
465 * @internal
467 class Loader : public QObject
470 Q_OBJECT
472 public:
473 Loader();
474 ~Loader();
476 void load(DocLoader* dl, CachedObject *object, bool incremental = true, bool highPriority = false);
478 int numRequests( DocLoader* dl ) const;
479 void cancelRequests( DocLoader* dl );
481 // may return 0L
482 KIO::Job *jobForRequest( const DOM::DOMString &url ) const;
484 Q_SIGNALS:
485 void requestStarted( khtml::DocLoader* dl, khtml::CachedObject* obj );
486 void requestDone( khtml::DocLoader* dl, khtml::CachedObject *obj );
487 void requestFailed( khtml::DocLoader* dl, khtml::CachedObject *obj );
489 protected Q_SLOTS:
490 void slotFinished( KJob * );
491 void slotMimetype( KIO::Job *, const QString& s);
492 void slotData( KIO::Job *, const QByteArray & );
493 void servePendingRequests();
495 protected:
496 QLinkedList<Request*> m_requestsPending;
497 Request* m_highPriorityRequestPending;
498 QHash<KIO::Job*,Request*> m_requestsLoading;
499 #ifdef HAVE_LIBJPEG
500 // TODO KJPEGFormatType m_jpegloader;
501 #endif
502 QTimer m_timer;
506 * @internal
508 * Provides a cache/loader for objects needed for displaying the html page.
509 * At the moment these are stylesheets, scripts and images
511 class Cache
513 friend class DocLoader;
515 template<typename CachedObjectType, enum CachedObject::Type CachedType>
516 static CachedObjectType* requestObject( DocLoader* dl, const KUrl& kurl, const char* accept );
518 public:
520 * init the cache in case it's not already. This needs to get called once
521 * before using it.
523 KHTML_EXPORT static void init();
526 * Ask the cache for some url. Will return a cachedObject, and
527 * load the requested data in case it's not cached
528 * if the DocLoader is zero, the url must be full-qualified.
529 * Otherwise, it is automatically base-url expanded
531 // static CachedImage *requestImage(const KUrl& url)
532 // { return Cache::requestObject<CachedImage, CachedObject::Image>( 0, url, 0 ); }
535 * Pre-loads a stylesheet into the cache.
537 static void preloadStyleSheet(const QString &url, const QString &stylesheet_data);
540 * Pre-loads a script into the cache.
542 static void preloadScript(const QString &url, const QString &script_data);
544 static void setSize( int bytes );
545 static int size() { return maxSize; }
546 static void statistics();
547 KHTML_EXPORT static void flush(bool force=false);
550 * clears the cache
551 * Warning: call this only at the end of your program, to clean
552 * up memory (useful for finding memory holes)
554 KHTML_EXPORT static void clear();
556 static Loader *loader() { return m_loader; }
558 static QPixmap *nullPixmap;
559 static QPixmap *brokenPixmap;
560 static QPixmap *blockedPixmap;
561 static int cacheSize;
563 static void removeCacheEntry( CachedObject *object );
565 private:
567 static void checkLRUAndUncacheableListIntegrity();
569 friend class CachedObject;
571 static QHash<QString,CachedObject*> *cache;
572 static QLinkedList<DocLoader*>* docloader;
573 static QLinkedList<CachedObject*> *freeList;
574 static void insertInLRUList(CachedObject*);
575 static void removeFromLRUList(CachedObject*);
577 static int totalSizeOfLRU;
578 static int maxSize;
580 static Loader *m_loader;
583 } // namespace
585 #endif