KHtml

loader.h
1 /*
2  This file is part of the KDE libraries
3 
4  Copyright (C) 1998 Lars Knoll ([email protected])
5  Copyright (C) 2001-2003 Dirk Mueller <[email protected]>
6  Copyright (C) 2003 Apple Computer, Inc
7 
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.
12 
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.
17 
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.
22 
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.
25 */
26 #ifndef _khtml_loader_h
27 #define _khtml_loader_h
28 
29 #include "loader_client.h"
30 
31 #include <stdlib.h>
32 #include <QObject>
33 #include <QPixmap>
34 #include <QBuffer>
35 #include <QStringList>
36 #include <QTextCodec>
37 #include <QTimer>
38 #include <QSet>
39 #include <QDateTime>
40 #include <QLinkedList>
41 #include <QUrl>
42 
43 #include <kio/global.h>
44 
45 #include <khtml_settings.h>
46 #include <dom/dom_string.h>
47 #include "imload/image.h"
48 #include "imload/imageowner.h"
49 
50 class KHTMLPart;
51 
52 class KJob;
53 namespace KIO
54 {
55 class Job;
56 }
57 
58 namespace DOM
59 {
60 class DocumentImpl;
61 }
62 
63 namespace khtml
64 {
65 class CachedObject;
66 class Request;
67 class DocLoader;
68 
69 /**
70  * @internal
71  *
72  * A cached object. Classes who want to use this object should derive
73  * from CachedObjectClient, to get the function calls in case the requested data has arrived.
74  *
75  * This class also does the actual communication with kio and loads the file.
76  */
78 {
79 public:
80  enum Type {
81  Image,
83  Script,
84  Sound,
85  Font
86  };
87 
88  enum Status {
89  Unknown, // let imagecache decide what to do with it
90  New, // inserting new image
91  Pending, // only partially loaded
92  Persistent, // never delete this pixmap
93  Cached // regular case
94  };
95 
96  enum PreloadResult {
97  PreloadNotReferenced = 0,
98  PreloadReferenced,
99  PreloadReferencedWhileLoading,
100  PreloadReferencedWhileComplete
101  };
102 
103  PreloadResult preloadResult() const
104  {
105  return m_preloadResult;
106  }
107  void setProspectiveRequest()
108  {
109  m_prospectiveRequest = true;
110  }
111 
112  CachedObject(const DOM::DOMString &url, Type type, KIO::CacheControl _cachePolicy, int size)
113  : m_url(url), m_type(type), m_cachePolicy(_cachePolicy),
114  m_size(size)
115  {
116  m_status = Pending;
117  m_accessCount = 0;
118  m_cachePolicy = _cachePolicy;
119  m_request = nullptr;
120  m_deleted = false;
121  m_free = false;
122  m_hadError = false;
123  m_wasBlocked = false;
124  m_prev = m_next = nullptr;
125  m_preloadCount = 0;
126  m_preloadResult = PreloadNotReferenced;
127  m_prospectiveRequest = false;
128  }
129  virtual ~CachedObject();
130 
131  virtual void data(QBuffer &buffer, bool eof) = 0;
132  virtual void error(int err, const char *text) = 0;
133 
134  const DOM::DOMString &url() const
135  {
136  return m_url;
137  }
138  Type type() const
139  {
140  return m_type;
141  }
142 
143  virtual void ref(CachedObjectClient *consumer);
144  virtual void deref(CachedObjectClient *consumer);
145 
146  int count() const
147  {
148  return m_clients.count();
149  }
150  int accessCount() const
151  {
152  return m_accessCount;
153  }
154 
155  bool isPreloaded() const
156  {
157  return m_preloadCount;
158  }
159  void increasePreloadCount()
160  {
161  ++m_preloadCount;
162  }
163  void decreasePreloadCount()
164  {
165  assert(m_preloadCount);
166  --m_preloadCount;
167  }
168 
169  void setStatus(Status s)
170  {
171  m_status = s;
172  }
173  Status status() const
174  {
175  return m_status;
176  }
177 
178  virtual void setCharset(const QString & /*charset*/) {}
179 
180  QTextCodec *codecForBuffer(const QString &charset, const QByteArray &buffer) const;
181 
182  int size() const
183  {
184  return m_size;
185  }
186 
187  bool isLoaded() const
188  {
189  return !m_loading;
190  }
191  bool hadError() const
192  {
193  return m_hadError;
194  }
195 
196  bool free() const
197  {
198  return m_free;
199  }
200 
201  KIO::CacheControl cachePolicy() const
202  {
203  return m_cachePolicy;
204  }
205 
206  void setRequest(Request *_request);
207 
208  bool canDelete() const
209  {
210  return (m_clients.count() == 0 && !m_request && !m_preloadCount);
211  }
212 
213  void setExpireDate(const QDateTime &_expireDate)
214  {
215  m_expireDate = _expireDate;
216  }
217 
218  bool isExpired() const;
219 
220  virtual void finish();
221 
222  /**
223  * List of acceptable mimetypes separated by ",". A mimetype may contain a wildcard.
224  */
225  // e.g. "text/*"
226  QString accept() const
227  {
228  return m_accept;
229  }
230  void setAccept(const QString &_accept)
231  {
232  m_accept = _accept;
233  }
234 
235  // the mimetype that was eventually used
236  QString mimetype() const
237  {
238  return m_mimetype;
239  }
240 
241 protected:
242  void setSize(int size);
244  DOM::DOMString m_url;
245  QString m_accept;
246  QString m_mimetype;
247  Request *m_request;
248  Type m_type;
249  Status m_status;
250  int m_accessCount;
251  KIO::CacheControl m_cachePolicy;
252  QDateTime m_expireDate;
253  int m_size;
254  unsigned m_preloadCount;
255  PreloadResult m_preloadResult: 3;
256  bool m_deleted : 1;
257  bool m_loading : 1;
258  bool m_free : 1;
259  bool m_hadError : 1;
260  bool m_wasBlocked : 1;
261  bool m_prospectiveRequest: 1;
262 
263 private:
264  bool allowInLRUList() const
265  {
266  return canDelete() && !m_free && status() != Persistent;
267  }
268  CachedObject *m_next;
269  CachedObject *m_prev;
270  friend class Cache;
271  friend class ::KHTMLPart;
272  friend class Loader;
273 };
274 
275 bool isAcceptableCSSMimetype(const DOM::DOMString &mimetype);
276 
277 /**
278  * a cached style sheet. also used for loading xml documents.
279  *
280  * ### rename to CachedTextDoc or something since it's more generic than just for css
281  */
283 {
284 public:
285  CachedCSSStyleSheet(DocLoader *dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy,
286  const char *accept);
287  CachedCSSStyleSheet(const DOM::DOMString &url, const QString &stylesheet_data);
288 
289  const DOM::DOMString &sheet() const
290  {
291  return m_sheet;
292  }
293 
294  void ref(CachedObjectClient *consumer) override;
295 
296  void data(QBuffer &buffer, bool eof) override;
297  void error(int err, const char *text) override;
298 
299  void setCharsetHint(const QString &charset)
300  {
301  m_charsetHint = charset;
302  }
303  void setCharset(const QString &charset) override
304  {
305  m_charset = charset;
306  }
307  QString checkCharset(const QByteArray &buffer) const;
308 
309 protected:
310  void checkNotify();
311 
312  DOM::DOMString m_sheet;
313  QString m_charset;
314  QString m_charsetHint;
315  int m_err;
316  QString m_errText;
317 };
318 
319 /**
320  * a cached script
321  */
323 {
324 public:
325  CachedScript(DocLoader *dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char *accept);
326  CachedScript(const DOM::DOMString &url, const QString &script_data);
327 
328  const DOM::DOMString &script() const
329  {
330  return m_script;
331  }
332 
333  void ref(CachedObjectClient *consumer) override;
334 
335  void data(QBuffer &buffer, bool eof) override;
336  void error(int err, const char *text) override;
337 
338  void checkNotify();
339 
340  bool isLoaded() const
341  {
342  return !m_loading;
343  }
344  void setCharset(const QString &charset) override
345  {
346  m_charset = charset;
347  }
348 
349 protected:
350  QString m_charset;
351  DOM::DOMString m_script;
352 };
353 
354 class ImageSource;
355 
356 /**
357  * a cached image
358  */
360 {
361  Q_OBJECT
362 public:
363  CachedImage(DocLoader *dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char *accept);
364  virtual ~CachedImage();
365 
366  QPixmap pixmap() const;
367  QPixmap *scaled_pixmap(int xWidth, int xHeight);
368  QPixmap tiled_pixmap(const QColor &bg, int xWidth = -1, int xHeight = -1);
369 
370  QSize pixmap_size() const; // returns the size of the complete (i.e. when finished) loading
371  //QRect valid_rect() const; // returns the rectangle of pixmap that has been loaded already
372 
373  bool canRender() const
374  {
375  return !isErrorImage() && pixmap_size().width() > 0 && pixmap_size().height() > 0;
376  }
377  void ref(CachedObjectClient *consumer) override;
378  void deref(CachedObjectClient *consumer) override;
379 
380  void data(QBuffer &buffer, bool eof) override;
381  void error(int err, const char *text) override;
382 
383  bool isComplete() const
384  {
385  return i && i->complete();
386  }
387  bool isTransparent() const
388  {
389  return false;
390  } //### isFullyTransparent; }
391  bool isErrorImage() const
392  {
393  return m_hadError;
394  }
395  bool isBlockedImage() const
396  {
397  return m_wasBlocked;
398  }
399  const QString &suggestedFilename() const
400  {
401  return m_suggestedFilename;
402  }
403  void setSuggestedFilename(const QString &s)
404  {
405  m_suggestedFilename = s;
406  }
407 #ifdef IMAGE_TITLES
408  const QString &suggestedTitle() const
409  {
410  return m_suggestedTitle;
411  }
412  void setSuggestedTitle(const QString &s)
413  {
414  m_suggestedTitle = s;
415  }
416 #else
417  const QString &suggestedTitle() const
418  {
419  return m_suggestedFilename;
420  }
421 #endif
422 
423  void setShowAnimations(KHTMLSettings::KAnimationAdvice);
424 
425  void finish() override;
426 
427  khtmlImLoad::Image *image()
428  {
429  return i;
430  }
431 
432 protected:
433  void clear();
434 
435 private:
436  /**
437  Interface to the image
438  */
439  void imageHasGeometry(khtmlImLoad::Image *img, int width, int height) override;
440  void imageChange(khtmlImLoad::Image *img, QRect region) override;
441  void imageError(khtmlImLoad::Image *img) override;
442  void imageDone(khtmlImLoad::Image *img) override;
443 private:
444  void doNotifyFinished();
445 
446  void do_notify(const QRect &r);
448 
449  QString m_suggestedFilename;
450 #ifdef IMAGE_TITLES
451  QString m_suggestedTitle;
452 #endif
453  QPixmap *bg;
454  QPixmap *scaled;
455  QRgb bgColor;
456  QSize bgSize;
457 
458  friend class Cache;
459  friend class ::KHTMLPart;
460 };
461 
462 /**
463  * a cached sound
464  */
465 class CachedSound : public CachedObject
466 {
467 public:
468  CachedSound(DocLoader *dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char *accept);
469 
470  QByteArray sound() const
471  {
472  return m_sound;
473  }
474 
475  void ref(CachedObjectClient *consumer) override;
476  void data(QBuffer &buffer, bool eof) override;
477  void error(int err, const char *text) override;
478 
479  void checkNotify();
480 
481  bool isLoaded() const
482  {
483  return !m_loading;
484  }
485 
486 protected:
487  QByteArray m_sound;
488 };
489 
490 /**
491  * a cached font
492  */
493 class CachedFont : public CachedObject
494 {
495 public:
496  CachedFont(DocLoader *dl, const DOM::DOMString &url, KIO::CacheControl cachePolicy, const char *accept);
497 
498  QByteArray font() const
499  {
500  return m_font;
501  }
502 
503  void ref(CachedObjectClient *consumer) override;
504  void data(QBuffer &buffer, bool eof) override;
505  void error(int err, const char *text) override;
506 
507  void checkNotify();
508 
509  bool isLoaded() const
510  {
511  return !m_loading;
512  }
513 
514 protected:
515  QByteArray m_font;
516 };
517 
518 /**
519  * @internal
520  *
521  * Manages the loading of scripts/images/stylesheets for a particular document
522  */
524 {
525 public:
527  ~DocLoader();
528 
529  CachedImage *requestImage(const DOM::DOMString &url);
530  CachedCSSStyleSheet *requestStyleSheet(const DOM::DOMString &url, const QString &charsetHint,
531  const char *accept = "text/css", bool userSheet = false);
532  CachedScript *requestScript(const DOM::DOMString &url, const QString &charset);
533  CachedSound *requestSound(const DOM::DOMString &url);
534  CachedFont *requestFont(const DOM::DOMString &url);
535  bool willLoadMediaElement(const DOM::DOMString &url);
536 
537  bool autoloadImages() const
538  {
539  return m_bautoloadImages;
540  }
541  KIO::CacheControl cachePolicy() const
542  {
543  return m_cachePolicy;
544  }
545  KHTMLSettings::KAnimationAdvice showAnimations() const
546  {
547  return m_showAnimations;
548  }
549  QDateTime expireDate() const
550  {
551  return m_expireDate;
552  }
553  KHTMLPart *part() const
554  {
555  return m_part;
556  }
557  DOM::DocumentImpl *doc() const
558  {
559  return m_doc;
560  }
561 
562  void setCacheCreationDate(const QDateTime &);
563  void setExpireDate(const QDateTime &);
564  void setRelativeExpireDate(qint64 seconds);
565  void setAutoloadImages(bool);
566  void setCachePolicy(KIO::CacheControl cachePolicy)
567  {
568  m_cachePolicy = cachePolicy;
569  }
570  void setShowAnimations(KHTMLSettings::KAnimationAdvice);
571  void insertCachedObject(CachedObject *o) const;
572  void removeCachedObject(CachedObject *o) const
573  {
574  m_docObjects.remove(o);
575  }
576  void clearPreloads();
577  void registerPreload(CachedObject *);
578  void printPreloadStats();
579 
580 private:
581  bool needReload(CachedObject *existing, const QString &fullUrl);
582 
583  friend class Cache;
584  friend class DOM::DocumentImpl;
585  friend class ::KHTMLPart;
586 
587  QStringList m_reloadedURLs;
588  mutable QSet<CachedObject *> m_docObjects;
589  QSet<CachedObject *> m_preloads;
590  QDateTime m_expireDate;
591  QDateTime m_creationDate;
592  KIO::CacheControl m_cachePolicy;
593  bool m_bautoloadImages : 1;
594  KHTMLSettings::KAnimationAdvice m_showAnimations : 2;
595  KHTMLPart *m_part;
596  DOM::DocumentImpl *m_doc;
597 };
598 
599 /**
600  * @internal
601  */
602 class Request
603 {
604 public:
605  Request(DocLoader *dl, CachedObject *_object, bool _incremental, int priority);
606  ~Request();
607  bool incremental;
608  int priority; // -10 to 10, smaller values mean higher priority
609  QBuffer m_buffer;
610  CachedObject *object;
611  DocLoader *m_docLoader;
612 };
613 
614 /**
615  * @internal
616  */
617 class Loader : public QObject
618 {
619 
620  Q_OBJECT
621 
622 public:
623  Loader();
624  ~Loader();
625 
626  void load(DocLoader *dl, CachedObject *object, bool incremental = true, int priority = 0);
627 
628  int numRequests(DocLoader *dl) const;
629  void cancelRequests(DocLoader *dl);
630 
631  // may return 0L
632  KIO::Job *jobForRequest(const DOM::DOMString &url) const;
633 
634 Q_SIGNALS:
635  void requestStarted(khtml::DocLoader *dl, khtml::CachedObject *obj);
636  void requestDone(khtml::DocLoader *dl, khtml::CachedObject *obj);
637  void requestFailed(khtml::DocLoader *dl, khtml::CachedObject *obj);
638 
639 protected Q_SLOTS:
640  void slotFinished(KJob *);
641  void slotMimetype(KIO::Job *, const QString &s);
642  void slotData(KIO::Job *, const QByteArray &);
643 
644 protected:
645  void scheduleRequest(Request *req);
646  QHash<KIO::Job *, Request *> m_requestsLoading;
647  QStringList m_supportedImageTypes;
648 };
649 
650 /**
651 * @internal
652 *
653 * Provides a cache/loader for objects needed for displaying the html page.
654 * At the moment these are stylesheets, scripts and images
655 */
656 class Cache
657 {
658  friend class DocLoader;
659 
660  template<typename CachedObjectType, enum CachedObject::Type CachedType>
661  static CachedObjectType *requestObject(DocLoader *dl, const QUrl &kurl, const char *accept);
662 
663 public:
664  /**
665  * init the cache in case it's not already. This needs to get called once
666  * before using it.
667  */
668  KHTML_EXPORT static void init();
669 
670  /**
671  * Ask the cache for some url. Will return a cachedObject, and
672  * load the requested data in case it's not cached
673  * if the DocLoader is zero, the url must be full-qualified.
674  * Otherwise, it is automatically base-url expanded
675  */
676 // static CachedImage *requestImage(const QUrl& url)
677 // { return Cache::requestObject<CachedImage, CachedObject::Image>( 0, url, 0 ); }
678 
679  /**
680  * Pre-loads a stylesheet into the cache.
681  */
682  static void preloadStyleSheet(const QString &url, const QString &stylesheet_data);
683 
684  /**
685  * Pre-loads a script into the cache.
686  */
687  static void preloadScript(const QString &url, const QString &script_data);
688 
689  static void setSize(int bytes);
690  static int size()
691  {
692  return maxSize;
693  }
694  static void statistics();
695  KHTML_EXPORT static void flush(bool force = false);
696 
697  /**
698  * clears the cache
699  * Warning: call this only at the end of your program, to clean
700  * up memory (useful for finding memory holes)
701  */
702  KHTML_EXPORT static void clear();
703 
704  static Loader *loader()
705  {
706  return m_loader;
707  }
708 
709  static QPixmap *nullPixmap;
710  static QPixmap *brokenPixmap;
711  static QPixmap *blockedPixmap;
712  static int cacheSize;
713 
714  static void removeCacheEntry(CachedObject *object);
715 
716 private:
717 
718  static void checkLRUAndUncacheableListIntegrity();
719 
720  friend class CachedObject;
721 
722  static QHash<QString, CachedObject *> *cache;
723  static QLinkedList<DocLoader *> *docloader;
724  static QLinkedList<CachedObject *> *freeList;
725  static void insertInLRUList(CachedObject *);
726  static void removeFromLRUList(CachedObject *);
727 
728  static int totalSizeOfLRU;
729  static int maxSize;
730 
731  static Loader *m_loader;
732 };
733 
734 } // namespace
735 
736 #endif
Q_OBJECTQ_OBJECT
This file is part of the HTML rendering engine for KDE.
bool complete() const
Returns true if the image has been fully loaded.
Definition: image.cpp:358
Q_SLOTSQ_SLOTS
static KHTML_EXPORT void clear()
clears the cache Warning: call this only at the end of your program, to clean up memory (useful for f...
Definition: loader.cpp:1502
a cached script
Definition: loader.h:322
This library provides a full-featured HTML parser and widget.
This class is khtml's main class.
Definition: khtml_part.h:208
int width() const const
The users of Image's need to inherit off ImageOwner, in order to receive the information about their ...
Definition: imageowner.h:35
int height() const const
static KHTML_EXPORT void init()
init the cache in case it's not already.
Definition: loader.cpp:1470
a cached sound
Definition: loader.h:465
a cached font
Definition: loader.h:493
Q_SIGNALSQ_SIGNALS
a cached style sheet.
Definition: loader.h:282
static void preloadStyleSheet(const QString &url, const QString &stylesheet_data)
Ask the cache for some url.
Definition: loader.cpp:1593
The CSSStyleSheet interface is a concrete interface used to represent a CSS style sheet i....
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
CacheControl
QString accept() const
List of acceptable mimetypes separated by ",".
Definition: loader.h:226
static void preloadScript(const QString &url, const QString &script_data)
Pre-loads a script into the cache.
Definition: loader.cpp:1603
a cached image
Definition: loader.h:359
An image represents a static picture or an animation, that may be incrementally loaded.
Definition: image.h:51
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Dec 5 2023 03:56:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.