File indexing completed on 2023-05-30 09:09:56
0001 /* This file is part of the KDE project 0002 Copyright (C) 1999 David Faure <faure@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "khtml_settings.h" 0021 #include "khtmldefaults.h" 0022 0023 #include <kparts/htmlsettingsinterface.h> 0024 #include <kconfig.h> 0025 #include <kconfiggroup.h> 0026 #include "khtml_debug.h" 0027 #include <klocalizedstring.h> 0028 #include <kmessagebox.h> 0029 #include <khtml_filter_p.h> 0030 0031 #include <kjob.h> 0032 #include <kio/job.h> 0033 0034 #include <QFile> 0035 #include <QFileInfo> 0036 #include <QFontDatabase> 0037 #include <QByteArray> 0038 #include <QUrl> 0039 #include <qstandardpaths.h> 0040 #include <ksharedconfig.h> 0041 0042 /** 0043 * @internal 0044 * Contains all settings which are both available globally and per-domain 0045 */ 0046 struct KPerDomainSettings { 0047 bool m_bEnableJava : 1; 0048 bool m_bEnableJavaScript : 1; 0049 bool m_bEnablePlugins : 1; 0050 // don't forget to maintain the bitfields as the enums grow 0051 KHTMLSettings::KJSWindowOpenPolicy m_windowOpenPolicy : 2; 0052 KHTMLSettings::KJSWindowStatusPolicy m_windowStatusPolicy : 1; 0053 KHTMLSettings::KJSWindowFocusPolicy m_windowFocusPolicy : 1; 0054 KHTMLSettings::KJSWindowMovePolicy m_windowMovePolicy : 1; 0055 KHTMLSettings::KJSWindowResizePolicy m_windowResizePolicy : 1; 0056 0057 #ifdef DEBUG_SETTINGS 0058 void dump(const QString &infix = QString()) const 0059 { 0060 // qCDebug(KHTML_LOG) << "KPerDomainSettings " << infix << " @" << this << ":"; 0061 // qCDebug(KHTML_LOG) << " m_bEnableJava: " << m_bEnableJava; 0062 // qCDebug(KHTML_LOG) << " m_bEnableJavaScript: " << m_bEnableJavaScript; 0063 // qCDebug(KHTML_LOG) << " m_bEnablePlugins: " << m_bEnablePlugins; 0064 // qCDebug(KHTML_LOG) << " m_windowOpenPolicy: " << m_windowOpenPolicy; 0065 // qCDebug(KHTML_LOG) << " m_windowStatusPolicy: " << m_windowStatusPolicy; 0066 // qCDebug(KHTML_LOG) << " m_windowFocusPolicy: " << m_windowFocusPolicy; 0067 // qCDebug(KHTML_LOG) << " m_windowMovePolicy: " << m_windowMovePolicy; 0068 // qCDebug(KHTML_LOG) << " m_windowResizePolicy: " << m_windowResizePolicy; 0069 } 0070 #endif 0071 }; 0072 0073 QString *KHTMLSettings::avFamilies = nullptr; 0074 typedef QMap<QString, KPerDomainSettings> PolicyMap; 0075 0076 // The "struct" that contains all the data. Must be copiable (no pointers). 0077 class KHTMLSettingsData 0078 { 0079 public: 0080 bool m_bChangeCursor : 1; 0081 bool m_bOpenMiddleClick : 1; 0082 bool m_underlineLink : 1; 0083 bool m_hoverLink : 1; 0084 bool m_bEnableJavaScriptDebug : 1; 0085 bool m_bEnableJavaScriptErrorReporting : 1; 0086 bool enforceCharset : 1; 0087 bool m_bAutoLoadImages : 1; 0088 bool m_bUnfinishedImageFrame : 1; 0089 bool m_formCompletionEnabled : 1; 0090 bool m_autoDelayedActionsEnabled : 1; 0091 bool m_jsErrorsEnabled : 1; 0092 bool m_follow_system_colors : 1; 0093 bool m_allowTabulation : 1; 0094 bool m_autoSpellCheck : 1; 0095 bool m_adFilterEnabled : 1; 0096 bool m_hideAdsEnabled : 1; 0097 bool m_jsPopupBlockerPassivePopup : 1; 0098 bool m_accessKeysEnabled : 1; 0099 0100 // the virtual global "domain" 0101 KPerDomainSettings global; 0102 0103 int m_fontSize; 0104 int m_minFontSize; 0105 int m_maxFormCompletionItems; 0106 KHTMLSettings::KAnimationAdvice m_showAnimations; 0107 KHTMLSettings::KSmoothScrollingMode m_smoothScrolling; 0108 KHTMLSettings::KDNSPrefetch m_dnsPrefetch; 0109 0110 QString m_encoding; 0111 QString m_userSheet; 0112 0113 QColor m_textColor; 0114 QColor m_baseColor; 0115 QColor m_linkColor; 0116 QColor m_vLinkColor; 0117 0118 PolicyMap domainPolicy; 0119 QStringList fonts; 0120 QStringList defaultFonts; 0121 0122 khtml::FilterSet adBlackList; 0123 khtml::FilterSet adWhiteList; 0124 QList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments; 0125 }; 0126 0127 class KHTMLSettingsPrivate : public QObject, public KHTMLSettingsData 0128 { 0129 Q_OBJECT 0130 public: 0131 0132 void adblockFilterLoadList(const QString &filename) 0133 { 0134 // qCDebug(KHTML_LOG) << "Loading filter list from" << filename; 0135 /** load list file and process each line */ 0136 QFile file(filename); 0137 if (file.open(QIODevice::ReadOnly)) { 0138 QTextStream ts(&file); 0139 QString line = ts.readLine(); 0140 #ifndef NDEBUG /// only count when compiled for debugging 0141 int whiteCounter = 0, blackCounter = 0; 0142 #endif // NDEBUG 0143 while (!line.isEmpty()) { 0144 /** white list lines start with "@@" */ 0145 if (line.startsWith(QLatin1String("@@"))) { 0146 #ifndef NDEBUG 0147 ++whiteCounter; 0148 #endif // NDEBUG 0149 adWhiteList.addFilter(line); 0150 } else { 0151 #ifndef NDEBUG 0152 ++blackCounter; 0153 #endif // NDEBUG 0154 adBlackList.addFilter(line); 0155 } 0156 0157 line = ts.readLine(); 0158 } 0159 file.close(); 0160 0161 #ifndef NDEBUG 0162 // qCDebug(KHTML_LOG) << "Filter list loaded" << whiteCounter << "white list entries and" << blackCounter << "black list entries"; 0163 #endif // NDEBUG 0164 } 0165 } 0166 0167 public Q_SLOTS: 0168 void adblockFilterResult(KJob *job) 0169 { 0170 KIO::StoredTransferJob *tJob = qobject_cast<KIO::StoredTransferJob *>(job); 0171 Q_ASSERT(tJob); 0172 0173 if (tJob->error()) { 0174 // qCDebug(KHTML_LOG) << "Failed to download" << tJob->url() << "with message:" << tJob->errorText(); 0175 } else if (tJob->isErrorPage()) { // 4XX error code 0176 // qCDebug(KHTML_LOG) << "Failed to fetch filter list" << tJob->url(); 0177 } else { 0178 const QByteArray byteArray = tJob->data(); 0179 const QString localFileName = tJob->property("khtmlsettings_adBlock_filename").toString(); 0180 0181 QFile file(localFileName); 0182 if (file.open(QFile::WriteOnly)) { 0183 bool success = file.write(byteArray) == byteArray.size(); 0184 file.close(); 0185 if (success) { 0186 adblockFilterLoadList(localFileName); 0187 } else { 0188 // qCDebug(KHTML_LOG) << "Could not write" << byteArray.size() << "to file" << localFileName; 0189 } 0190 } else { 0191 // qCDebug(KHTML_LOG) << "Cannot open file" << localFileName << "for filter list"; 0192 } 0193 } 0194 0195 } 0196 }; 0197 0198 /** Returns a writeable per-domains settings instance for the given domain 0199 * or a deep copy of the global settings if not existent. 0200 */ 0201 static KPerDomainSettings &setup_per_domain_policy( 0202 KHTMLSettingsPrivate *const d, 0203 const QString &domain) 0204 { 0205 if (domain.isEmpty()) { 0206 qCWarning(KHTML_LOG) << "setup_per_domain_policy: domain is empty"; 0207 } 0208 const QString ldomain = domain.toLower(); 0209 PolicyMap::iterator it = d->domainPolicy.find(ldomain); 0210 if (it == d->domainPolicy.end()) { 0211 // simply copy global domain settings (they should have been initialized 0212 // by this time) 0213 it = d->domainPolicy.insert(ldomain, d->global); 0214 } 0215 return *it; 0216 } 0217 0218 KHTMLSettings::KJavaScriptAdvice KHTMLSettings::strToAdvice(const QString &_str) 0219 { 0220 return static_cast<KJavaScriptAdvice>(KParts::HtmlSettingsInterface::textToJavascriptAdvice(_str)); 0221 } 0222 0223 const char *KHTMLSettings::adviceToStr(KJavaScriptAdvice _advice) 0224 { 0225 return KParts::HtmlSettingsInterface::javascriptAdviceToText(static_cast<KParts::HtmlSettingsInterface::JavaScriptAdvice>(_advice)); 0226 } 0227 0228 void KHTMLSettings::splitDomainAdvice(const QString &configStr, QString &domain, 0229 KJavaScriptAdvice &javaAdvice, KJavaScriptAdvice &javaScriptAdvice) 0230 { 0231 KParts::HtmlSettingsInterface::JavaScriptAdvice jAdvice, jsAdvice; 0232 KParts::HtmlSettingsInterface::splitDomainAdvice(configStr, domain, jAdvice, jsAdvice); 0233 javaAdvice = static_cast<KJavaScriptAdvice>(jAdvice); 0234 javaScriptAdvice = static_cast<KJavaScriptAdvice>(jsAdvice); 0235 } 0236 0237 void KHTMLSettings::readDomainSettings(const KConfigGroup &config, bool reset, 0238 bool global, KPerDomainSettings &pd_settings) 0239 { 0240 QString jsPrefix = global ? QString() 0241 : QString::fromLatin1("javascript."); 0242 QString javaPrefix = global ? QString() 0243 : QString::fromLatin1("java."); 0244 QString pluginsPrefix = global ? QString() 0245 : QString::fromLatin1("plugins."); 0246 0247 // The setting for Java 0248 QString key = javaPrefix + QLatin1String("EnableJava"); 0249 if ((global && reset) || config.hasKey(key)) { 0250 pd_settings.m_bEnableJava = config.readEntry(key, false); 0251 } else if (!global) { 0252 pd_settings.m_bEnableJava = d->global.m_bEnableJava; 0253 } 0254 0255 // The setting for Plugins 0256 key = pluginsPrefix + QLatin1String("EnablePlugins"); 0257 if ((global && reset) || config.hasKey(key)) { 0258 pd_settings.m_bEnablePlugins = config.readEntry(key, true); 0259 } else if (!global) { 0260 pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins; 0261 } 0262 0263 // The setting for JavaScript 0264 key = jsPrefix + QLatin1String("EnableJavaScript"); 0265 if ((global && reset) || config.hasKey(key)) { 0266 pd_settings.m_bEnableJavaScript = config.readEntry(key, true); 0267 } else if (!global) { 0268 pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript; 0269 } 0270 0271 // window property policies 0272 key = jsPrefix + QLatin1String("WindowOpenPolicy"); 0273 if ((global && reset) || config.hasKey(key)) 0274 pd_settings.m_windowOpenPolicy = (KJSWindowOpenPolicy) 0275 config.readEntry(key, uint(KJSWindowOpenSmart)); 0276 else if (!global) { 0277 pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy; 0278 } 0279 0280 key = jsPrefix + QLatin1String("WindowMovePolicy"); 0281 if ((global && reset) || config.hasKey(key)) 0282 pd_settings.m_windowMovePolicy = (KJSWindowMovePolicy) 0283 config.readEntry(key, uint(KJSWindowMoveAllow)); 0284 else if (!global) { 0285 pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy; 0286 } 0287 0288 key = jsPrefix + QLatin1String("WindowResizePolicy"); 0289 if ((global && reset) || config.hasKey(key)) 0290 pd_settings.m_windowResizePolicy = (KJSWindowResizePolicy) 0291 config.readEntry(key, uint(KJSWindowResizeAllow)); 0292 else if (!global) { 0293 pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy; 0294 } 0295 0296 key = jsPrefix + QLatin1String("WindowStatusPolicy"); 0297 if ((global && reset) || config.hasKey(key)) 0298 pd_settings.m_windowStatusPolicy = (KJSWindowStatusPolicy) 0299 config.readEntry(key, uint(KJSWindowStatusAllow)); 0300 else if (!global) { 0301 pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy; 0302 } 0303 0304 key = jsPrefix + QLatin1String("WindowFocusPolicy"); 0305 if ((global && reset) || config.hasKey(key)) 0306 pd_settings.m_windowFocusPolicy = (KJSWindowFocusPolicy) 0307 config.readEntry(key, uint(KJSWindowFocusAllow)); 0308 else if (!global) { 0309 pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy; 0310 } 0311 0312 } 0313 0314 KHTMLSettings::KHTMLSettings() 0315 : d(new KHTMLSettingsPrivate()) 0316 { 0317 init(); 0318 } 0319 0320 KHTMLSettings::KHTMLSettings(const KHTMLSettings &other) 0321 : d(new KHTMLSettingsPrivate()) 0322 { 0323 KHTMLSettingsData *data = d; 0324 *data = *other.d; 0325 } 0326 0327 KHTMLSettings::~KHTMLSettings() 0328 { 0329 delete d; 0330 } 0331 0332 bool KHTMLSettings::changeCursor() const 0333 { 0334 return d->m_bChangeCursor; 0335 } 0336 0337 bool KHTMLSettings::underlineLink() const 0338 { 0339 return d->m_underlineLink; 0340 } 0341 0342 bool KHTMLSettings::hoverLink() const 0343 { 0344 return d->m_hoverLink; 0345 } 0346 0347 void KHTMLSettings::init() 0348 { 0349 KConfig global("khtmlrc", KConfig::NoGlobals); 0350 init(&global, true); 0351 0352 KSharedConfig::Ptr local = KSharedConfig::openConfig(); 0353 if (!local) { 0354 return; 0355 } 0356 0357 init(local.data(), false); 0358 } 0359 0360 void KHTMLSettings::init(KConfig *config, bool reset) 0361 { 0362 KConfigGroup cg(config, "MainView Settings"); 0363 if (reset || cg.exists()) { 0364 if (reset || cg.hasKey("OpenMiddleClick")) { 0365 d->m_bOpenMiddleClick = cg.readEntry("OpenMiddleClick", true); 0366 } 0367 } 0368 0369 KConfigGroup cgAccess(config, "Access Keys"); 0370 if (reset || cgAccess.exists()) { 0371 d->m_accessKeysEnabled = cgAccess.readEntry("Enabled", true); 0372 } 0373 0374 KConfigGroup cgFilter(config, "Filter Settings"); 0375 0376 if (reset || cgFilter.exists()) { 0377 d->m_adFilterEnabled = cgFilter.readEntry("Enabled", false); 0378 d->m_hideAdsEnabled = cgFilter.readEntry("Shrink", false); 0379 0380 d->adBlackList.clear(); 0381 d->adWhiteList.clear(); 0382 0383 if (d->m_adFilterEnabled) { 0384 0385 /** read maximum age for filter list files, minimum is one day */ 0386 int htmlFilterListMaxAgeDays = cgFilter.readEntry(QString("HTMLFilterListMaxAgeDays")).toInt(); 0387 if (htmlFilterListMaxAgeDays < 1) { 0388 htmlFilterListMaxAgeDays = 1; 0389 } 0390 0391 QMap<QString, QString> entryMap = cgFilter.entryMap(); 0392 QMap<QString, QString>::ConstIterator it; 0393 for (it = entryMap.constBegin(); it != entryMap.constEnd(); ++it) { 0394 int id = -1; 0395 QString name = it.key(); 0396 QString url = it.value(); 0397 0398 if (name.startsWith("Filter")) { 0399 if (url.startsWith(QLatin1String("@@"))) { 0400 d->adWhiteList.addFilter(url); 0401 } else { 0402 d->adBlackList.addFilter(url); 0403 } 0404 } else if (name.startsWith("HTMLFilterListName-") && (id = name.mid(19).toInt()) > 0) { 0405 /** check if entry is enabled */ 0406 bool filterEnabled = cgFilter.readEntry(QString("HTMLFilterListEnabled-").append(QString::number(id))) != QLatin1String("false"); 0407 0408 /** get url for HTMLFilterList */ 0409 QUrl url(cgFilter.readEntry(QString("HTMLFilterListURL-").append(QString::number(id)))); 0410 0411 if (filterEnabled && url.isValid()) { 0412 /** determine where to cache HTMLFilterList file */ 0413 QString localFile = cgFilter.readEntry(QString("HTMLFilterListLocalFilename-").append(QString::number(id))); 0414 localFile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + "khtml/" + localFile; 0415 0416 /** determine existence and age of cache file */ 0417 QFileInfo fileInfo(localFile); 0418 0419 /** load cached file if it exists, irrespective of age */ 0420 if (fileInfo.exists()) { 0421 d->adblockFilterLoadList(localFile); 0422 } 0423 0424 /** if no cache list file exists or if it is too old ... */ 0425 if (!fileInfo.exists() || fileInfo.lastModified().daysTo(QDateTime::currentDateTime()) > htmlFilterListMaxAgeDays) { 0426 /** ... in this case, refetch list asynchronously */ 0427 // qCDebug(KHTML_LOG) << "Asynchronously fetching filter list from" << url << "to" << localFile; 0428 0429 KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); 0430 QObject::connect(job, SIGNAL(result(KJob*)), d, SLOT(adblockFilterResult(KJob*))); 0431 /** for later reference, store name of cache file */ 0432 job->setProperty("khtmlsettings_adBlock_filename", localFile); 0433 } 0434 } 0435 } 0436 } 0437 } 0438 0439 } 0440 0441 KConfigGroup cgHtml(config, "HTML Settings"); 0442 if (reset || cgHtml.exists()) { 0443 // Fonts and colors 0444 if (reset) { 0445 d->defaultFonts = QStringList(); 0446 d->defaultFonts.append(cgHtml.readEntry("StandardFont", QFontDatabase::systemFont(QFontDatabase::GeneralFont).family())); 0447 d->defaultFonts.append(cgHtml.readEntry("FixedFont", QFontDatabase::systemFont(QFontDatabase::FixedFont).family())); 0448 // Resolve generic font family names 0449 const QString serifFont = QFontInfo(QFont(QLatin1String(HTML_DEFAULT_VIEW_SERIF_FONT))).family(); 0450 const QString sansSerifFont = QFontInfo(QFont(QLatin1String(HTML_DEFAULT_VIEW_SANSSERIF_FONT))).family(); 0451 const QString cursiveFont = QFontInfo(QFont(QLatin1String(HTML_DEFAULT_VIEW_CURSIVE_FONT))).family(); 0452 const QString fantasyFont = QFontInfo(QFont(QLatin1String(HTML_DEFAULT_VIEW_FANTASY_FONT))).family(); 0453 d->defaultFonts.append(cgHtml.readEntry("SerifFont", serifFont)); 0454 d->defaultFonts.append(cgHtml.readEntry("SansSerifFont", sansSerifFont)); 0455 d->defaultFonts.append(cgHtml.readEntry("CursiveFont", cursiveFont)); 0456 d->defaultFonts.append(cgHtml.readEntry("FantasyFont", fantasyFont)); 0457 d->defaultFonts.append(QString("0")); // font size adjustment 0458 } 0459 0460 if (reset || cgHtml.hasKey("MinimumFontSize")) { 0461 d->m_minFontSize = cgHtml.readEntry("MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE); 0462 } 0463 0464 if (reset || cgHtml.hasKey("MediumFontSize")) { 0465 d->m_fontSize = cgHtml.readEntry("MediumFontSize", 12); 0466 } 0467 0468 d->fonts = cgHtml.readEntry("Fonts", QStringList()); 0469 const int fontsListLength = d->fonts.length(); 0470 // Resolve generic font family names 0471 for (int i = 0; i < fontsListLength; ++i) { 0472 const QString fontFamily = d->fonts.at(i); 0473 if (!fontFamily.isEmpty()) { 0474 d->fonts[i] = QFontInfo(QFont(fontFamily)).family(); 0475 //qCWarning(KHTML_LOG) << "Font family name:" << fontFamily << "resolved to:" << d->fonts.at(i); 0476 } 0477 } 0478 0479 if (reset || cgHtml.hasKey("DefaultEncoding")) { 0480 d->m_encoding = cgHtml.readEntry("DefaultEncoding", ""); 0481 } 0482 0483 if (reset || cgHtml.hasKey("EnforceDefaultCharset")) { 0484 d->enforceCharset = cgHtml.readEntry("EnforceDefaultCharset", false); 0485 } 0486 0487 // Behavior 0488 if (reset || cgHtml.hasKey("ChangeCursor")) { 0489 d->m_bChangeCursor = cgHtml.readEntry("ChangeCursor", true); 0490 } 0491 0492 if (reset || cgHtml.hasKey("UnderlineLinks")) { 0493 d->m_underlineLink = cgHtml.readEntry("UnderlineLinks", true); 0494 } 0495 0496 if (reset || cgHtml.hasKey("HoverLinks")) { 0497 if ((d->m_hoverLink = cgHtml.readEntry("HoverLinks", false))) { 0498 d->m_underlineLink = false; 0499 } 0500 } 0501 0502 if (reset || cgHtml.hasKey("AllowTabulation")) { 0503 d->m_allowTabulation = cgHtml.readEntry("AllowTabulation", false); 0504 } 0505 0506 if (reset || cgHtml.hasKey("AutoSpellCheck")) { 0507 d->m_autoSpellCheck = cgHtml.readEntry("AutoSpellCheck", true); 0508 } 0509 0510 // Other 0511 if (reset || cgHtml.hasKey("AutoLoadImages")) { 0512 d->m_bAutoLoadImages = cgHtml.readEntry("AutoLoadImages", true); 0513 } 0514 0515 if (reset || cgHtml.hasKey("UnfinishedImageFrame")) { 0516 d->m_bUnfinishedImageFrame = cgHtml.readEntry("UnfinishedImageFrame", true); 0517 } 0518 0519 if (reset || cgHtml.hasKey("ShowAnimations")) { 0520 QString value = cgHtml.readEntry("ShowAnimations").toLower(); 0521 if (value == "disabled") { 0522 d->m_showAnimations = KAnimationDisabled; 0523 } else if (value == "looponce") { 0524 d->m_showAnimations = KAnimationLoopOnce; 0525 } else { 0526 d->m_showAnimations = KAnimationEnabled; 0527 } 0528 } 0529 0530 if (reset || cgHtml.hasKey("SmoothScrolling")) { 0531 QString value = cgHtml.readEntry("SmoothScrolling", "whenefficient").toLower(); 0532 if (value == "disabled") { 0533 d->m_smoothScrolling = KSmoothScrollingDisabled; 0534 } else if (value == "whenefficient") { 0535 d->m_smoothScrolling = KSmoothScrollingWhenEfficient; 0536 } else { 0537 d->m_smoothScrolling = KSmoothScrollingEnabled; 0538 } 0539 } 0540 0541 if (reset || cgHtml.hasKey("DNSPrefetch")) { 0542 // Enabled, Disabled, OnlyWWWAndSLD 0543 QString value = cgHtml.readEntry("DNSPrefetch", "Enabled").toLower(); 0544 if (value == "enabled") { 0545 d->m_dnsPrefetch = KDNSPrefetchEnabled; 0546 } else if (value == "onlywwwandsld") { 0547 d->m_dnsPrefetch = KDNSPrefetchOnlyWWWAndSLD; 0548 } else { 0549 d->m_dnsPrefetch = KDNSPrefetchDisabled; 0550 } 0551 } 0552 0553 if (cgHtml.readEntry("UserStyleSheetEnabled", false) == true) { 0554 if (reset || cgHtml.hasKey("UserStyleSheet")) { 0555 d->m_userSheet = cgHtml.readEntry("UserStyleSheet", ""); 0556 } 0557 } 0558 0559 d->m_formCompletionEnabled = cgHtml.readEntry("FormCompletion", true); 0560 d->m_maxFormCompletionItems = cgHtml.readEntry("MaxFormCompletionItems", 10); 0561 d->m_autoDelayedActionsEnabled = cgHtml.readEntry("AutoDelayedActions", true); 0562 d->m_jsErrorsEnabled = cgHtml.readEntry("ReportJSErrors", true); 0563 const QStringList accesskeys = cgHtml.readEntry("FallbackAccessKeysAssignments", QStringList()); 0564 d->m_fallbackAccessKeysAssignments.clear(); 0565 for (QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it) 0566 if ((*it).length() > 2 && (*it)[ 1 ] == ':') { 0567 d->m_fallbackAccessKeysAssignments.append(qMakePair((*it).mid(2), (*it)[ 0 ])); 0568 } 0569 } 0570 0571 // Colors 0572 //In which group ????? 0573 if (reset || cg.hasKey("FollowSystemColors")) { 0574 d->m_follow_system_colors = cg.readEntry("FollowSystemColors", false); 0575 } 0576 0577 KConfigGroup cgGeneral(config, "General"); 0578 if (reset || cgGeneral.exists()) { 0579 if (reset || cgGeneral.hasKey("foreground")) { 0580 QColor def(HTML_DEFAULT_TXT_COLOR); 0581 d->m_textColor = cgGeneral.readEntry("foreground", def); 0582 } 0583 0584 if (reset || cgGeneral.hasKey("linkColor")) { 0585 QColor def(HTML_DEFAULT_LNK_COLOR); 0586 d->m_linkColor = cgGeneral.readEntry("linkColor", def); 0587 } 0588 0589 if (reset || cgGeneral.hasKey("visitedLinkColor")) { 0590 QColor def(HTML_DEFAULT_VLNK_COLOR); 0591 d->m_vLinkColor = cgGeneral.readEntry("visitedLinkColor", def); 0592 } 0593 0594 if (reset || cgGeneral.hasKey("background")) { 0595 QColor def(HTML_DEFAULT_BASE_COLOR); 0596 d->m_baseColor = cgGeneral.readEntry("background", def); 0597 } 0598 } 0599 0600 KConfigGroup cgJava(config, "Java/JavaScript Settings"); 0601 if (reset || cgJava.exists()) { 0602 // The global setting for JavaScript debugging 0603 // This is currently always enabled by default 0604 if (reset || cgJava.hasKey("EnableJavaScriptDebug")) { 0605 d->m_bEnableJavaScriptDebug = cgJava.readEntry("EnableJavaScriptDebug", false); 0606 } 0607 0608 // The global setting for JavaScript error reporting 0609 if (reset || cgJava.hasKey("ReportJavaScriptErrors")) { 0610 d->m_bEnableJavaScriptErrorReporting = cgJava.readEntry("ReportJavaScriptErrors", false); 0611 } 0612 0613 // The global setting for popup block passive popup 0614 if (reset || cgJava.hasKey("PopupBlockerPassivePopup")) { 0615 d->m_jsPopupBlockerPassivePopup = cgJava.readEntry("PopupBlockerPassivePopup", true); 0616 } 0617 0618 // Read options from the global "domain" 0619 readDomainSettings(cgJava, reset, true, d->global); 0620 #ifdef DEBUG_SETTINGS 0621 d->global.dump("init global"); 0622 #endif 0623 0624 // The domain-specific settings. 0625 0626 static const char *const domain_keys[] = { // always keep order of keys 0627 "ECMADomains", "JavaDomains", "PluginDomains" 0628 }; 0629 bool check_old_ecma_settings = true; 0630 bool check_old_java_settings = true; 0631 // merge all domains into one list 0632 QMap<QString, int> domainList; // why can't Qt have a QSet? 0633 for (unsigned i = 0; i < sizeof domain_keys / sizeof domain_keys[0]; ++i) { 0634 if (reset || cgJava.hasKey(domain_keys[i])) { 0635 if (i == 0) { 0636 check_old_ecma_settings = false; 0637 } else if (i == 1) { 0638 check_old_java_settings = false; 0639 } 0640 const QStringList dl = cgJava.readEntry(domain_keys[i], QStringList()); 0641 const QMap<QString, int>::Iterator notfound = domainList.end(); 0642 QStringList::ConstIterator it = dl.begin(); 0643 const QStringList::ConstIterator itEnd = dl.end(); 0644 for (; it != itEnd; ++it) { 0645 const QString domain = (*it).toLower(); 0646 QMap<QString, int>::Iterator pos = domainList.find(domain); 0647 if (pos == notfound) { 0648 domainList.insert(domain, 0); 0649 } 0650 }/*next it*/ 0651 } 0652 }/*next i*/ 0653 0654 if (reset) { 0655 d->domainPolicy.clear(); 0656 } 0657 0658 { 0659 QMap<QString, int>::ConstIterator it = domainList.constBegin(); 0660 const QMap<QString, int>::ConstIterator itEnd = domainList.constEnd(); 0661 for (; it != itEnd; ++it) { 0662 const QString domain = it.key(); 0663 KConfigGroup cg(config, domain); 0664 readDomainSettings(cg, reset, false, d->domainPolicy[domain]); 0665 #ifdef DEBUG_SETTINGS 0666 d->domainPolicy[domain].dump("init " + domain); 0667 #endif 0668 } 0669 } 0670 0671 bool check_old_java = true; 0672 if ((reset || cgJava.hasKey("JavaDomainSettings")) 0673 && check_old_java_settings) { 0674 check_old_java = false; 0675 const QStringList domainList = cgJava.readEntry("JavaDomainSettings", QStringList()); 0676 QStringList::ConstIterator it = domainList.constBegin(); 0677 const QStringList::ConstIterator itEnd = domainList.constEnd(); 0678 for (; it != itEnd; ++it) { 0679 QString domain; 0680 KJavaScriptAdvice javaAdvice; 0681 KJavaScriptAdvice javaScriptAdvice; 0682 splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice); 0683 setup_per_domain_policy(d, domain).m_bEnableJava = 0684 javaAdvice == KJavaScriptAccept; 0685 #ifdef DEBUG_SETTINGS 0686 setup_per_domain_policy(d, domain).dump("JavaDomainSettings 4 " + domain); 0687 #endif 0688 } 0689 } 0690 0691 bool check_old_ecma = true; 0692 if ((reset || cgJava.hasKey("ECMADomainSettings")) 0693 && check_old_ecma_settings) { 0694 check_old_ecma = false; 0695 const QStringList domainList = cgJava.readEntry("ECMADomainSettings", QStringList()); 0696 QStringList::ConstIterator it = domainList.constBegin(); 0697 const QStringList::ConstIterator itEnd = domainList.constEnd(); 0698 for (; it != itEnd; ++it) { 0699 QString domain; 0700 KJavaScriptAdvice javaAdvice; 0701 KJavaScriptAdvice javaScriptAdvice; 0702 splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice); 0703 setup_per_domain_policy(d, domain).m_bEnableJavaScript = 0704 javaScriptAdvice == KJavaScriptAccept; 0705 #ifdef DEBUG_SETTINGS 0706 setup_per_domain_policy(d, domain).dump("ECMADomainSettings 4 " + domain); 0707 #endif 0708 } 0709 } 0710 0711 if ((reset || cgJava.hasKey("JavaScriptDomainAdvice")) 0712 && (check_old_java || check_old_ecma) 0713 && (check_old_ecma_settings || check_old_java_settings)) { 0714 const QStringList domainList = cgJava.readEntry("JavaScriptDomainAdvice", QStringList()); 0715 QStringList::ConstIterator it = domainList.constBegin(); 0716 const QStringList::ConstIterator itEnd = domainList.constEnd(); 0717 for (; it != itEnd; ++it) { 0718 QString domain; 0719 KJavaScriptAdvice javaAdvice; 0720 KJavaScriptAdvice javaScriptAdvice; 0721 splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice); 0722 if (check_old_java) 0723 setup_per_domain_policy(d, domain).m_bEnableJava = 0724 javaAdvice == KJavaScriptAccept; 0725 if (check_old_ecma) 0726 setup_per_domain_policy(d, domain).m_bEnableJavaScript = 0727 javaScriptAdvice == KJavaScriptAccept; 0728 #ifdef DEBUG_SETTINGS 0729 setup_per_domain_policy(d, domain).dump("JavaScriptDomainAdvice 4 " + domain); 0730 #endif 0731 } 0732 0733 //save all the settings into the new keywords if they don't exist 0734 #if 0 0735 if (check_old_java) { 0736 QStringList domainConfig; 0737 PolicyMap::Iterator it; 0738 for (it = d->javaDomainPolicy.begin(); it != d->javaDomainPolicy.end(); ++it) { 0739 QByteArray javaPolicy = adviceToStr(it.value()); 0740 QByteArray javaScriptPolicy = adviceToStr(KJavaScriptDunno); 0741 domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy)); 0742 } 0743 cg.writeEntry("JavaDomainSettings", domainConfig); 0744 } 0745 0746 if (check_old_ecma) { 0747 QStringList domainConfig; 0748 PolicyMap::Iterator it; 0749 for (it = d->javaScriptDomainPolicy.begin(); it != d->javaScriptDomainPolicy.end(); ++it) { 0750 QByteArray javaPolicy = adviceToStr(KJavaScriptDunno); 0751 QByteArray javaScriptPolicy = adviceToStr(it.value()); 0752 domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy)); 0753 } 0754 cg.writeEntry("ECMADomainSettings", domainConfig); 0755 } 0756 #endif 0757 } 0758 } 0759 } 0760 0761 /** Local helper for retrieving per-domain settings. 0762 * 0763 * In case of doubt, the global domain is returned. 0764 */ 0765 static const KPerDomainSettings &lookup_hostname_policy( 0766 const KHTMLSettingsPrivate *const d, 0767 const QString &hostname) 0768 { 0769 #ifdef DEBUG_SETTINGS 0770 // qCDebug(KHTML_LOG) << "lookup_hostname_policy(" << hostname << ")"; 0771 #endif 0772 if (hostname.isEmpty()) { 0773 #ifdef DEBUG_SETTINGS 0774 d->global.dump("global"); 0775 #endif 0776 return d->global; 0777 } 0778 0779 const PolicyMap::const_iterator notfound = d->domainPolicy.constEnd(); 0780 0781 // First check whether there is a perfect match. 0782 PolicyMap::const_iterator it = d->domainPolicy.find(hostname); 0783 if (it != notfound) { 0784 #ifdef DEBUG_SETTINGS 0785 // qCDebug(KHTML_LOG) << "perfect match"; 0786 (*it).dump(hostname); 0787 #endif 0788 // yes, use it (unless dunno) 0789 return *it; 0790 } 0791 0792 // Now, check for partial match. Chop host from the left until 0793 // there's no dots left. 0794 QString host_part = hostname; 0795 int dot_idx = -1; 0796 while ((dot_idx = host_part.indexOf(QChar('.'))) >= 0) { 0797 host_part.remove(0, dot_idx); 0798 it = d->domainPolicy.find(host_part); 0799 Q_ASSERT(notfound == d->domainPolicy.end()); 0800 if (it != notfound) { 0801 #ifdef DEBUG_SETTINGS 0802 // qCDebug(KHTML_LOG) << "partial match"; 0803 (*it).dump(host_part); 0804 #endif 0805 return *it; 0806 } 0807 // assert(host_part[0] == QChar('.')); 0808 host_part.remove(0, 1); // Chop off the dot. 0809 } 0810 0811 // No domain-specific entry: use global domain 0812 #ifdef DEBUG_SETTINGS 0813 // qCDebug(KHTML_LOG) << "no match"; 0814 d->global.dump("global"); 0815 #endif 0816 return d->global; 0817 } 0818 0819 bool KHTMLSettings::isOpenMiddleClickEnabled() 0820 { 0821 return d->m_bOpenMiddleClick; 0822 } 0823 0824 bool KHTMLSettings::isBackRightClickEnabled() 0825 { 0826 return false; // ## the feature moved to konqueror 0827 } 0828 0829 bool KHTMLSettings::accessKeysEnabled() const 0830 { 0831 return d->m_accessKeysEnabled; 0832 } 0833 0834 bool KHTMLSettings::isAdFilterEnabled() const 0835 { 0836 return d->m_adFilterEnabled; 0837 } 0838 0839 bool KHTMLSettings::isHideAdsEnabled() const 0840 { 0841 return d->m_hideAdsEnabled; 0842 } 0843 0844 bool KHTMLSettings::isAdFiltered(const QString &url) const 0845 { 0846 if (d->m_adFilterEnabled) { 0847 if (!url.startsWith("data:")) { 0848 // Check the blacklist, and only if that matches, the whitelist 0849 return d->adBlackList.isUrlMatched(url) && !d->adWhiteList.isUrlMatched(url); 0850 } 0851 } 0852 return false; 0853 } 0854 0855 QString KHTMLSettings::adFilteredBy(const QString &url, bool *isWhiteListed) const 0856 { 0857 QString m = d->adWhiteList.urlMatchedBy(url); 0858 if (!m.isEmpty()) { 0859 if (isWhiteListed != nullptr) { 0860 *isWhiteListed = true; 0861 } 0862 return (m); 0863 } 0864 0865 m = d->adBlackList.urlMatchedBy(url); 0866 if (!m.isEmpty()) { 0867 if (isWhiteListed != nullptr) { 0868 *isWhiteListed = false; 0869 } 0870 return (m); 0871 } 0872 0873 return (QString()); 0874 } 0875 0876 void KHTMLSettings::addAdFilter(const QString &url) 0877 { 0878 KConfigGroup config = KSharedConfig::openConfig("khtmlrc", KConfig::NoGlobals)->group("Filter Settings"); 0879 0880 QRegExp rx; 0881 0882 // Try compiling to avoid invalid stuff. Only support the basic syntax here... 0883 // ### refactor somewhat 0884 if (url.length() > 2 && url[0] == '/' && url[url.length() - 1] == '/') { 0885 QString inside = url.mid(1, url.length() - 2); 0886 rx.setPattern(inside); 0887 } else { 0888 rx.setPatternSyntax(QRegExp::Wildcard); 0889 rx.setPattern(url); 0890 } 0891 0892 if (rx.isValid()) { 0893 int last = config.readEntry("Count", 0); 0894 QString key = "Filter-" + QString::number(last); 0895 config.writeEntry(key, url); 0896 config.writeEntry("Count", last + 1); 0897 config.sync(); 0898 if (url.startsWith(QLatin1String("@@"))) { 0899 d->adWhiteList.addFilter(url); 0900 } else { 0901 d->adBlackList.addFilter(url); 0902 } 0903 } else { 0904 KMessageBox::error(nullptr, 0905 rx.errorString(), 0906 i18n("Filter error")); 0907 } 0908 } 0909 0910 bool KHTMLSettings::isJavaEnabled(const QString &hostname) const 0911 { 0912 return lookup_hostname_policy(d, hostname.toLower()).m_bEnableJava; 0913 } 0914 0915 bool KHTMLSettings::isJavaScriptEnabled(const QString &hostname) const 0916 { 0917 return lookup_hostname_policy(d, hostname.toLower()).m_bEnableJavaScript; 0918 } 0919 0920 bool KHTMLSettings::isJavaScriptDebugEnabled(const QString & /*hostname*/) const 0921 { 0922 // debug setting is global for now, but could change in the future 0923 return d->m_bEnableJavaScriptDebug; 0924 } 0925 0926 bool KHTMLSettings::isJavaScriptErrorReportingEnabled(const QString & /*hostname*/) const 0927 { 0928 // error reporting setting is global for now, but could change in the future 0929 return d->m_bEnableJavaScriptErrorReporting; 0930 } 0931 0932 bool KHTMLSettings::isPluginsEnabled(const QString &hostname) const 0933 { 0934 return lookup_hostname_policy(d, hostname.toLower()).m_bEnablePlugins; 0935 } 0936 0937 KHTMLSettings::KJSWindowOpenPolicy KHTMLSettings::windowOpenPolicy( 0938 const QString &hostname) const 0939 { 0940 return lookup_hostname_policy(d, hostname.toLower()).m_windowOpenPolicy; 0941 } 0942 0943 KHTMLSettings::KJSWindowMovePolicy KHTMLSettings::windowMovePolicy( 0944 const QString &hostname) const 0945 { 0946 return lookup_hostname_policy(d, hostname.toLower()).m_windowMovePolicy; 0947 } 0948 0949 KHTMLSettings::KJSWindowResizePolicy KHTMLSettings::windowResizePolicy( 0950 const QString &hostname) const 0951 { 0952 return lookup_hostname_policy(d, hostname.toLower()).m_windowResizePolicy; 0953 } 0954 0955 KHTMLSettings::KJSWindowStatusPolicy KHTMLSettings::windowStatusPolicy( 0956 const QString &hostname) const 0957 { 0958 return lookup_hostname_policy(d, hostname.toLower()).m_windowStatusPolicy; 0959 } 0960 0961 KHTMLSettings::KJSWindowFocusPolicy KHTMLSettings::windowFocusPolicy( 0962 const QString &hostname) const 0963 { 0964 return lookup_hostname_policy(d, hostname.toLower()).m_windowFocusPolicy; 0965 } 0966 0967 int KHTMLSettings::mediumFontSize() const 0968 { 0969 return d->m_fontSize; 0970 } 0971 0972 int KHTMLSettings::minFontSize() const 0973 { 0974 return d->m_minFontSize; 0975 } 0976 0977 QString KHTMLSettings::settingsToCSS() const 0978 { 0979 // lets start with the link properties 0980 QString str = "a:link {\ncolor: "; 0981 str += d->m_linkColor.name(); 0982 str += ';'; 0983 if (d->m_underlineLink) { 0984 str += "\ntext-decoration: underline;"; 0985 } 0986 0987 if (d->m_bChangeCursor) { 0988 str += "\ncursor: pointer;"; 0989 str += "\n}\ninput[type=image] { cursor: pointer;"; 0990 } 0991 str += "\n}\n"; 0992 str += "a:visited {\ncolor: "; 0993 str += d->m_vLinkColor.name(); 0994 str += ';'; 0995 if (d->m_underlineLink) { 0996 str += "\ntext-decoration: underline;"; 0997 } 0998 0999 if (d->m_bChangeCursor) { 1000 str += "\ncursor: pointer;"; 1001 } 1002 str += "\n}\n"; 1003 1004 if (d->m_hoverLink) { 1005 str += "a:link:hover, a:visited:hover { text-decoration: underline; }\n"; 1006 } 1007 1008 return str; 1009 } 1010 1011 const QString &KHTMLSettings::availableFamilies() 1012 { 1013 if (!avFamilies) { 1014 avFamilies = new QString; 1015 QFontDatabase db; 1016 QStringList families = db.families(); 1017 QStringList s; 1018 QRegExp foundryExp(" \\[.+\\]"); 1019 1020 //remove foundry info 1021 QStringList::Iterator f = families.begin(); 1022 const QStringList::Iterator fEnd = families.end(); 1023 1024 for (; f != fEnd; ++f) { 1025 (*f).replace(foundryExp, ""); 1026 if (!s.contains(*f)) { 1027 s << *f; 1028 } 1029 } 1030 s.sort(); 1031 1032 *avFamilies = ',' + s.join(",") + ','; 1033 } 1034 1035 return *avFamilies; 1036 } 1037 1038 QString KHTMLSettings::lookupFont(int i) const 1039 { 1040 QString font; 1041 if (d->fonts.count() > i) { 1042 font = d->fonts[i]; 1043 } 1044 if (font.isEmpty()) { 1045 font = d->defaultFonts[i]; 1046 } 1047 return font; 1048 } 1049 1050 QString KHTMLSettings::stdFontName() const 1051 { 1052 return lookupFont(0); 1053 } 1054 1055 QString KHTMLSettings::fixedFontName() const 1056 { 1057 return lookupFont(1); 1058 } 1059 1060 QString KHTMLSettings::serifFontName() const 1061 { 1062 return lookupFont(2); 1063 } 1064 1065 QString KHTMLSettings::sansSerifFontName() const 1066 { 1067 return lookupFont(3); 1068 } 1069 1070 QString KHTMLSettings::cursiveFontName() const 1071 { 1072 return lookupFont(4); 1073 } 1074 1075 QString KHTMLSettings::fantasyFontName() const 1076 { 1077 return lookupFont(5); 1078 } 1079 1080 void KHTMLSettings::setStdFontName(const QString &n) 1081 { 1082 while (d->fonts.count() <= 0) { 1083 d->fonts.append(QString()); 1084 } 1085 d->fonts[0] = n; 1086 } 1087 1088 void KHTMLSettings::setFixedFontName(const QString &n) 1089 { 1090 while (d->fonts.count() <= 1) { 1091 d->fonts.append(QString()); 1092 } 1093 d->fonts[1] = n; 1094 } 1095 1096 QString KHTMLSettings::userStyleSheet() const 1097 { 1098 return d->m_userSheet; 1099 } 1100 1101 bool KHTMLSettings::isFormCompletionEnabled() const 1102 { 1103 return d->m_formCompletionEnabled; 1104 } 1105 1106 int KHTMLSettings::maxFormCompletionItems() const 1107 { 1108 return d->m_maxFormCompletionItems; 1109 } 1110 1111 const QString &KHTMLSettings::encoding() const 1112 { 1113 return d->m_encoding; 1114 } 1115 1116 bool KHTMLSettings::followSystemColors() const 1117 { 1118 return d->m_follow_system_colors; 1119 } 1120 1121 const QColor &KHTMLSettings::textColor() const 1122 { 1123 return d->m_textColor; 1124 } 1125 1126 const QColor &KHTMLSettings::baseColor() const 1127 { 1128 return d->m_baseColor; 1129 } 1130 1131 const QColor &KHTMLSettings::linkColor() const 1132 { 1133 return d->m_linkColor; 1134 } 1135 1136 const QColor &KHTMLSettings::vLinkColor() const 1137 { 1138 return d->m_vLinkColor; 1139 } 1140 1141 bool KHTMLSettings::autoLoadImages() const 1142 { 1143 return d->m_bAutoLoadImages; 1144 } 1145 1146 bool KHTMLSettings::unfinishedImageFrame() const 1147 { 1148 return d->m_bUnfinishedImageFrame; 1149 } 1150 1151 KHTMLSettings::KAnimationAdvice KHTMLSettings::showAnimations() const 1152 { 1153 return d->m_showAnimations; 1154 } 1155 1156 KHTMLSettings::KSmoothScrollingMode KHTMLSettings::smoothScrolling() const 1157 { 1158 return d->m_smoothScrolling; 1159 } 1160 1161 KHTMLSettings::KDNSPrefetch KHTMLSettings::dnsPrefetch() const 1162 { 1163 return d->m_dnsPrefetch; 1164 } 1165 1166 bool KHTMLSettings::isAutoDelayedActionsEnabled() const 1167 { 1168 return d->m_autoDelayedActionsEnabled; 1169 } 1170 1171 bool KHTMLSettings::jsErrorsEnabled() const 1172 { 1173 return d->m_jsErrorsEnabled; 1174 } 1175 1176 void KHTMLSettings::setJSErrorsEnabled(bool enabled) 1177 { 1178 d->m_jsErrorsEnabled = enabled; 1179 // save it 1180 KConfigGroup cg(KSharedConfig::openConfig(), "HTML Settings"); 1181 cg.writeEntry("ReportJSErrors", enabled); 1182 cg.sync(); 1183 } 1184 1185 bool KHTMLSettings::allowTabulation() const 1186 { 1187 return d->m_allowTabulation; 1188 } 1189 1190 bool KHTMLSettings::autoSpellCheck() const 1191 { 1192 return d->m_autoSpellCheck; 1193 } 1194 1195 QList< QPair< QString, QChar > > KHTMLSettings::fallbackAccessKeysAssignments() const 1196 { 1197 return d->m_fallbackAccessKeysAssignments; 1198 } 1199 1200 void KHTMLSettings::setJSPopupBlockerPassivePopup(bool enabled) 1201 { 1202 d->m_jsPopupBlockerPassivePopup = enabled; 1203 // save it 1204 KConfigGroup cg(KSharedConfig::openConfig(), "Java/JavaScript Settings"); 1205 cg.writeEntry("PopupBlockerPassivePopup", enabled); 1206 cg.sync(); 1207 } 1208 1209 bool KHTMLSettings::jsPopupBlockerPassivePopup() const 1210 { 1211 return d->m_jsPopupBlockerPassivePopup; 1212 } 1213 1214 #include "khtml_settings.moc"