File indexing completed on 2024-10-06 12:20:30
0001 /* This file is part of the KDE project 0002 * 0003 * Copyright (C) 2000 Simon Hausmann <hausmann@kde.org> 0004 * Copyright (C) 2007 David Faure <faure@kde.org> 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Library General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Library General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Library General Public License 0017 * along with this library; see the file COPYING.LIB. If not, write to 0018 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "khtml_global.h" 0023 #include "khtml_part.h" 0024 #include "khtml_settings.h" 0025 #include "../khtml_version.h" 0026 0027 #include "css/cssstyleselector.h" 0028 #include "css/css_mediaquery.h" 0029 #include "html/html_imageimpl.h" 0030 #include "rendering/render_style.h" 0031 #include "rendering/break_lines.h" 0032 #include "misc/htmlnames.h" 0033 #include "misc/loader.h" 0034 #include "misc/arena.h" 0035 #include "misc/paintbuffer.h" 0036 0037 #include <QLinkedList> 0038 0039 #include <kiconloader.h> 0040 #include <kaboutdata.h> 0041 #include <klocalizedstring.h> 0042 0043 #include <assert.h> 0044 0045 #include "khtml_debug.h" 0046 0047 // SVG 0048 #include "svg/SVGNames.h" 0049 0050 KHTMLGlobal *KHTMLGlobal::s_self = nullptr; 0051 unsigned long int KHTMLGlobal::s_refcnt = 0; 0052 KIconLoader *KHTMLGlobal::s_iconLoader = nullptr; 0053 KAboutData *KHTMLGlobal::s_about = nullptr; 0054 KHTMLSettings *KHTMLGlobal::s_settings = nullptr; 0055 0056 static QLinkedList<KHTMLPart *> *s_parts = nullptr; 0057 static QLinkedList<DOM::DocumentImpl *> *s_docs = nullptr; 0058 0059 KHTMLGlobal::KHTMLGlobal() 0060 { 0061 assert(!s_self); 0062 s_self = this; 0063 ref(); 0064 0065 khtml::Cache::init(); 0066 0067 khtml::NamespaceFactory::initIdTable(); 0068 khtml::PrefixFactory::initIdTable(); 0069 khtml::LocalNameFactory::initIdTable(); 0070 DOM::emptyLocalName = DOM::LocalName::fromId(0); 0071 DOM::emptyPrefixName = DOM::PrefixName::fromId(0); 0072 DOM::emptyNamespaceName = DOM::NamespaceName::fromId(DOM::emptyNamespace); 0073 WebCore::SVGNames::init(); 0074 } 0075 0076 KHTMLGlobal::~KHTMLGlobal() 0077 { 0078 //qCDebug(KHTML_LOG) << this; 0079 if (s_self == this) { 0080 finalCheck(); 0081 delete s_iconLoader; 0082 delete s_about; 0083 delete s_settings; 0084 delete KHTMLSettings::avFamilies; 0085 if (s_parts) { 0086 assert(s_parts->isEmpty()); 0087 delete s_parts; 0088 } 0089 if (s_docs) { 0090 assert(s_docs->isEmpty()); 0091 delete s_docs; 0092 } 0093 0094 s_iconLoader = nullptr; 0095 s_about = nullptr; 0096 s_settings = nullptr; 0097 s_parts = nullptr; 0098 s_docs = nullptr; 0099 KHTMLSettings::avFamilies = nullptr; 0100 0101 // clean up static data 0102 khtml::CSSStyleSelector::clear(); 0103 khtml::RenderStyle::cleanup(); 0104 khtml::RenderObject::cleanup(); 0105 khtml::PaintBuffer::cleanup(); 0106 khtml::MediaQueryEvaluator::cleanup(); 0107 khtml::Cache::clear(); 0108 khtml::cleanup_thaibreaks(); 0109 khtml::ArenaFinish(); 0110 } else { 0111 deref(); 0112 } 0113 } 0114 0115 void KHTMLGlobal::ref() 0116 { 0117 if (!s_refcnt && !s_self) { 0118 //qCDebug(KHTML_LOG) << "Creating KHTMLGlobal instance"; 0119 // we can't use a staticdeleter here, because that would mean 0120 // that the KHTMLGlobal instance gets deleted from within a qPostRoutine, called 0121 // from the QApplication destructor. That however is too late, because 0122 // we want to destruct a KComponentData object, which involves destructing 0123 // a KConfig object, which might call KGlobal::dirs() (in sync()) which 0124 // probably is not going to work ;-) 0125 // well, perhaps I'm wrong here, but as I'm unsure I try to stay on the 0126 // safe side ;-) -> let's use a simple reference counting scheme 0127 // (Simon) 0128 new KHTMLGlobal; // does initial ref() 0129 } else { 0130 ++s_refcnt; 0131 } 0132 //qCDebug(KHTML_LOG) << "s_refcnt=" << s_refcnt; 0133 } 0134 0135 void KHTMLGlobal::deref() 0136 { 0137 //qCDebug(KHTML_LOG) << "s_refcnt=" << s_refcnt - 1; 0138 if (!--s_refcnt && s_self) { 0139 delete s_self; 0140 s_self = nullptr; 0141 } 0142 } 0143 0144 void KHTMLGlobal::registerPart(KHTMLPart *part) 0145 { 0146 //qCDebug(KHTML_LOG) << part; 0147 if (!s_parts) { 0148 s_parts = new QLinkedList<KHTMLPart *>; 0149 } 0150 0151 if (!s_parts->contains(part)) { 0152 s_parts->append(part); 0153 ref(); 0154 } 0155 } 0156 0157 void KHTMLGlobal::deregisterPart(KHTMLPart *part) 0158 { 0159 //qCDebug(KHTML_LOG) << part; 0160 assert(s_parts); 0161 0162 if (s_parts->removeAll(part)) { 0163 if (s_parts->isEmpty()) { 0164 delete s_parts; 0165 s_parts = nullptr; 0166 } 0167 deref(); 0168 } 0169 } 0170 0171 void KHTMLGlobal::registerDocumentImpl(DOM::DocumentImpl *doc) 0172 { 0173 //qCDebug(KHTML_LOG) << doc; 0174 if (!s_docs) { 0175 s_docs = new QLinkedList<DOM::DocumentImpl *>; 0176 } 0177 0178 if (!s_docs->contains(doc)) { 0179 s_docs->append(doc); 0180 ref(); 0181 } 0182 } 0183 0184 void KHTMLGlobal::deregisterDocumentImpl(DOM::DocumentImpl *doc) 0185 { 0186 //qCDebug(KHTML_LOG) << doc; 0187 assert(s_docs); 0188 0189 if (s_docs->removeAll(doc)) { 0190 if (s_docs->isEmpty()) { 0191 delete s_docs; 0192 s_docs = nullptr; 0193 } 0194 deref(); 0195 } 0196 } 0197 0198 const KAboutData &KHTMLGlobal::aboutData() 0199 { 0200 assert(s_self); 0201 0202 if (!s_about) { 0203 s_about = new KAboutData("khtml", i18n("KHTML"), QStringLiteral(KHTML_VERSION_STRING), 0204 i18n("Embeddable HTML component"), 0205 KAboutLicense::LGPL); 0206 s_about->addAuthor(QStringLiteral("Lars Knoll"), QString(), "knoll@kde.org"); 0207 s_about->addAuthor(QStringLiteral("Antti Koivisto"), QString(), "koivisto@kde.org"); 0208 s_about->addAuthor(QStringLiteral("Waldo Bastian"), QString(), "bastian@kde.org"); 0209 s_about->addAuthor(QStringLiteral("Dirk Mueller"), QString(), "mueller@kde.org"); 0210 s_about->addAuthor(QStringLiteral("Peter Kelly"), QString(), "pmk@kde.org"); 0211 s_about->addAuthor(QStringLiteral("Torben Weis"), QString(), "weis@kde.org"); 0212 s_about->addAuthor(QStringLiteral("Martin Jones"), QString(), "mjones@kde.org"); 0213 s_about->addAuthor(QStringLiteral("Simon Hausmann"), QString(), "hausmann@kde.org"); 0214 s_about->addAuthor(QStringLiteral("Tobias Anton"), QString(), "anton@stud.fbi.fh-darmstadt.de"); 0215 0216 } 0217 0218 return *s_about; 0219 } 0220 0221 KIconLoader *KHTMLGlobal::iconLoader() 0222 { 0223 if (!s_iconLoader) { 0224 s_iconLoader = new KIconLoader(aboutData().componentName()); 0225 } 0226 0227 return s_iconLoader; 0228 } 0229 0230 KHTMLSettings *KHTMLGlobal::defaultHTMLSettings() 0231 { 0232 assert(s_self); 0233 if (!s_settings) { 0234 s_settings = new KHTMLSettings(); 0235 } 0236 0237 return s_settings; 0238 } 0239 0240 void KHTMLGlobal::finalCheck() 0241 { 0242 #ifndef NDEBUG 0243 if (s_refcnt) { 0244 if (s_parts && !s_parts->isEmpty()) { 0245 Q_FOREACH (KHTMLPart *part, *s_parts) { 0246 qCWarning(KHTML_LOG) << "Part" << part->url() << "was not deleted"; 0247 } 0248 } 0249 if (s_docs && !s_docs->isEmpty()) { 0250 Q_FOREACH (DOM::DocumentImpl *doc, *s_docs) { 0251 qCWarning(KHTML_LOG) << "Document" << doc->URL() << "was not deleted"; 0252 } 0253 } 0254 } 0255 #endif 0256 }