File indexing completed on 2024-12-22 04:43:21
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "webenginesettings.h" 0008 0009 #include "webengine_filter.h" 0010 #include <webenginepart_debug.h> 0011 #include "../../src/htmldefaults.h" 0012 #include "profile.h" 0013 0014 #include <KConfig> 0015 #include <KSharedConfig> 0016 #include <KLocalizedString> 0017 #include <KConfigGroup> 0018 #include <KJob> 0019 #include <KIO/StoredTransferJob> 0020 #include <KMessageBox> 0021 0022 #include <QWebEngineSettings> 0023 #include <QFontDatabase> 0024 #include <QFileInfo> 0025 #include <QDir> 0026 #include <QStringView> 0027 #include <QRegularExpression> 0028 0029 using namespace KonqWebEnginePart; 0030 0031 QDataStream & operator<<(QDataStream& ds, const WebEngineSettings::WebFormInfo& info) 0032 { 0033 ds << info.name<< info.framePath << info.fields; 0034 return ds; 0035 } 0036 0037 QDataStream & operator>>(QDataStream& ds, WebEngineSettings::WebFormInfo& info) 0038 { 0039 ds >> info.name >> info.framePath >> info.fields; 0040 return ds; 0041 } 0042 0043 /** 0044 * @internal 0045 * Contains all settings which are both available globally and per-domain 0046 */ 0047 struct KPerDomainSettings { 0048 bool m_bEnableJava : 1; 0049 bool m_bEnableJavaScript : 1; 0050 bool m_bEnablePlugins : 1; 0051 // don't forget to maintain the bitfields as the enums grow 0052 HtmlSettingsInterface::JSWindowOpenPolicy m_windowOpenPolicy : 2; 0053 HtmlSettingsInterface::JSWindowStatusPolicy m_windowStatusPolicy : 1; 0054 HtmlSettingsInterface::JSWindowFocusPolicy m_windowFocusPolicy : 1; 0055 HtmlSettingsInterface::JSWindowMovePolicy m_windowMovePolicy : 1; 0056 HtmlSettingsInterface::JSWindowResizePolicy m_windowResizePolicy : 1; 0057 0058 #ifdef DEBUG_SETTINGS 0059 void dump(const QString &infix = QString()) const { 0060 qCDebug(WEBENGINEPART_LOG) << "KPerDomainSettings " << infix << " @" << this << ":"; 0061 qCDebug(WEBENGINEPART_LOG) << " m_bEnableJava: " << m_bEnableJava; 0062 qCDebug(WEBENGINEPART_LOG) << " m_bEnableJavaScript: " << m_bEnableJavaScript; 0063 qCDebug(WEBENGINEPART_LOG) << " m_bEnablePlugins: " << m_bEnablePlugins; 0064 qCDebug(WEBENGINEPART_LOG) << " m_windowOpenPolicy: " << m_windowOpenPolicy; 0065 qCDebug(WEBENGINEPART_LOG) << " m_windowStatusPolicy: " << m_windowStatusPolicy; 0066 qCDebug(WEBENGINEPART_LOG) << " m_windowFocusPolicy: " << m_windowFocusPolicy; 0067 qCDebug(WEBENGINEPART_LOG) << " m_windowMovePolicy: " << m_windowMovePolicy; 0068 qCDebug(WEBENGINEPART_LOG) << " m_windowResizePolicy: " << m_windowResizePolicy; 0069 } 0070 #endif 0071 }; 0072 0073 typedef QMap<QString,KPerDomainSettings> PolicyMap; 0074 0075 class WebEngineSettingsData 0076 { 0077 public: 0078 bool m_bChangeCursor : 1; 0079 bool m_bOpenMiddleClick : 1; 0080 bool m_underlineLink : 1; 0081 bool m_hoverLink : 1; 0082 bool m_bEnableJavaScriptDebug : 1; 0083 bool m_bEnableJavaScriptErrorReporting : 1; 0084 bool enforceCharset : 1; 0085 bool m_bAutoLoadImages : 1; 0086 bool m_bUnfinishedImageFrame : 1; 0087 bool m_formCompletionEnabled : 1; 0088 bool m_autoDelayedActionsEnabled : 1; 0089 bool m_jsErrorsEnabled : 1; 0090 bool m_follow_system_colors : 1; 0091 bool m_allowTabulation : 1; 0092 bool m_autoSpellCheck : 1; 0093 bool m_adFilterEnabled : 1; 0094 bool m_hideAdsEnabled : 1; 0095 bool m_jsPopupBlockerPassivePopup : 1; 0096 bool m_accessKeysEnabled : 1; 0097 bool m_zoomTextOnly : 1; 0098 bool m_useCookieJar : 1; 0099 #ifndef MANAGE_COOKIES_INTERNALLY 0100 bool m_acceptCrossDomainCookies : 1; 0101 #endif 0102 bool m_bAutoRefreshPage: 1; 0103 bool m_bEnableFavicon:1; 0104 bool m_disableInternalPluginHandling:1; 0105 bool m_offerToSaveWebSitePassword:1; 0106 bool m_loadPluginsOnDemand:1; 0107 bool m_enableLocalStorage:1; 0108 bool m_enableOfflineStorageDb:1; 0109 bool m_enableOfflineWebAppCache:1; 0110 bool m_enableWebGL:1; 0111 bool m_zoomToDPI:1; 0112 bool m_allowActiveMixedContent:1; 0113 bool m_allowMixedContentDisplay:1; 0114 0115 // the virtual global "domain" 0116 KPerDomainSettings global; 0117 0118 int m_fontSize; 0119 int m_minFontSize; 0120 int m_maxFormCompletionItems; 0121 WebEngineSettings::KAnimationAdvice m_showAnimations; 0122 WebEngineSettings::KSmoothScrollingMode m_smoothScrolling; 0123 0124 QString m_encoding; 0125 QString m_userSheet; 0126 0127 QColor m_textColor; 0128 QColor m_baseColor; 0129 QColor m_linkColor; 0130 QColor m_vLinkColor; 0131 0132 PolicyMap domainPolicy; 0133 QStringList fonts; 0134 QStringList defaultFonts; 0135 0136 KDEPrivate::FilterSet adBlackList; 0137 KDEPrivate::FilterSet adWhiteList; 0138 QList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments; 0139 0140 KSharedConfig::Ptr nonPasswordStorableSites; 0141 KSharedConfig::Ptr sitesWithCustomForms; 0142 bool m_internalPdfViewer; 0143 }; 0144 0145 class WebEngineSettingsPrivate : public QObject, public WebEngineSettingsData 0146 { 0147 Q_OBJECT 0148 public: 0149 void adblockFilterLoadList(const QString& filename) 0150 { 0151 /** load list file and process each line */ 0152 QFile file(filename); 0153 if (file.open(QIODevice::ReadOnly)) { 0154 QTextStream ts(&file); 0155 QString line = ts.readLine(); 0156 while (!line.isEmpty()) { 0157 //qCDebug(WEBENGINEPART_LOG) << "Adding filter:" << line; 0158 /** white list lines start with "@@" */ 0159 if (line.startsWith(QLatin1String("@@"))) 0160 adWhiteList.addFilter(line); 0161 else 0162 adBlackList.addFilter(line); 0163 line = ts.readLine(); 0164 } 0165 file.close(); 0166 } 0167 } 0168 0169 public Q_SLOTS: 0170 void adblockFilterResult(KJob *job) 0171 { 0172 KIO::StoredTransferJob *tJob = qobject_cast<KIO::StoredTransferJob*>(job); 0173 Q_ASSERT(tJob); 0174 0175 if ( job->error() == KJob::NoError ) 0176 { 0177 const QByteArray byteArray = tJob->data(); 0178 const QString localFileName = tJob->property( "webenginesettings_adBlock_filename" ).toString(); 0179 0180 QFile file(localFileName); 0181 if ( file.open(QFile::WriteOnly) ) 0182 { 0183 const bool success = (file.write(byteArray) == byteArray.size()); 0184 if ( success ) 0185 adblockFilterLoadList(localFileName); 0186 else 0187 qCWarning(WEBENGINEPART_LOG) << "Could not write" << byteArray.size() << "to file" << localFileName; 0188 file.close(); 0189 } 0190 else 0191 qCDebug(WEBENGINEPART_LOG) << "Cannot open file" << localFileName << "for filter list"; 0192 } 0193 else 0194 qCDebug(WEBENGINEPART_LOG) << "Downloading" << tJob->url() << "failed with message:" << job->errorText(); 0195 } 0196 }; 0197 0198 0199 /** Returns a writeable per-domains settings instance for the given domain 0200 * or a deep copy of the global settings if not existent. 0201 */ 0202 static KPerDomainSettings &setup_per_domain_policy(WebEngineSettingsPrivate* const d, const QString &domain) 0203 { 0204 if (domain.isEmpty()) 0205 qCWarning(WEBENGINEPART_LOG) << "setup_per_domain_policy: domain is empty"; 0206 0207 const QString ldomain = domain.toLower(); 0208 PolicyMap::iterator it = d->domainPolicy.find(ldomain); 0209 if (it == d->domainPolicy.end()) { 0210 // simply copy global domain settings (they should have been initialized 0211 // by this time) 0212 it = d->domainPolicy.insert(ldomain,d->global); 0213 } 0214 return *it; 0215 } 0216 0217 template<typename T> 0218 static T readEntry(const KConfigGroup& config, const QString& key, int defaultValue) 0219 { 0220 return static_cast<T>(config.readEntry(key, defaultValue)); 0221 } 0222 0223 void WebEngineSettings::readDomainSettings(const KConfigGroup &config, bool reset, 0224 bool global, KPerDomainSettings &pd_settings) 0225 { 0226 const QString javaPrefix ((global ? QString() : QStringLiteral("java."))); 0227 const QString jsPrefix ((global ? QString() : QStringLiteral("javascript."))); 0228 const QString pluginsPrefix (global ? QString() : QStringLiteral("plugins.")); 0229 0230 // The setting for Java 0231 QString key = javaPrefix + QLatin1String("EnableJava"); 0232 if ( (global && reset) || config.hasKey( key ) ) 0233 pd_settings.m_bEnableJava = config.readEntry( key, false ); 0234 else if ( !global ) 0235 pd_settings.m_bEnableJava = d->global.m_bEnableJava; 0236 0237 // The setting for Plugins 0238 key = pluginsPrefix + QLatin1String("EnablePlugins"); 0239 if ( (global && reset) || config.hasKey( key ) ) 0240 pd_settings.m_bEnablePlugins = config.readEntry( key, true ); 0241 else if ( !global ) 0242 pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins; 0243 0244 // The setting for JavaScript 0245 key = jsPrefix + QLatin1String("EnableJavaScript"); 0246 if ( (global && reset) || config.hasKey( key ) ) 0247 pd_settings.m_bEnableJavaScript = config.readEntry( key, true ); 0248 else if ( !global ) 0249 pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript; 0250 0251 // window property policies 0252 key = jsPrefix + QLatin1String("WindowOpenPolicy"); 0253 if ( (global && reset) || config.hasKey( key ) ) 0254 pd_settings.m_windowOpenPolicy = readEntry<HtmlSettingsInterface::JSWindowOpenPolicy>(config, key, HtmlSettingsInterface::JSWindowOpenSmart); 0255 else if ( !global ) 0256 pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy; 0257 0258 key = jsPrefix + QLatin1String("WindowMovePolicy"); 0259 if ( (global && reset) || config.hasKey( key ) ) 0260 pd_settings.m_windowMovePolicy = readEntry<HtmlSettingsInterface::JSWindowMovePolicy>(config, key, HtmlSettingsInterface::JSWindowMoveAllow); 0261 else if ( !global ) 0262 pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy; 0263 0264 key = jsPrefix + QLatin1String("WindowResizePolicy"); 0265 if ( (global && reset) || config.hasKey( key ) ) 0266 pd_settings.m_windowResizePolicy = readEntry<HtmlSettingsInterface::JSWindowResizePolicy>(config, key, HtmlSettingsInterface::JSWindowResizeAllow); 0267 else if ( !global ) 0268 pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy; 0269 0270 key = jsPrefix + QLatin1String("WindowStatusPolicy"); 0271 if ( (global && reset) || config.hasKey( key ) ) 0272 pd_settings.m_windowStatusPolicy = readEntry<HtmlSettingsInterface::JSWindowStatusPolicy>(config, key, HtmlSettingsInterface::JSWindowStatusAllow); 0273 else if ( !global ) 0274 pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy; 0275 0276 key = jsPrefix + QLatin1String("WindowFocusPolicy"); 0277 if ( (global && reset) || config.hasKey( key ) ) 0278 pd_settings.m_windowFocusPolicy = readEntry<HtmlSettingsInterface::JSWindowFocusPolicy>(config, key, HtmlSettingsInterface::JSWindowFocusAllow); 0279 else if ( !global ) 0280 pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy; 0281 } 0282 0283 0284 WebEngineSettings::WebEngineSettings() 0285 :d (new WebEngineSettingsPrivate) 0286 { 0287 init(); 0288 } 0289 0290 WebEngineSettings::~WebEngineSettings() 0291 { 0292 delete d; 0293 } 0294 0295 bool WebEngineSettings::changeCursor() const 0296 { 0297 return d->m_bChangeCursor; 0298 } 0299 0300 bool WebEngineSettings::underlineLink() const 0301 { 0302 return d->m_underlineLink; 0303 } 0304 0305 bool WebEngineSettings::hoverLink() const 0306 { 0307 return d->m_hoverLink; 0308 } 0309 0310 bool WebEngineSettings::internalPdfViewer() const 0311 { 0312 return d->m_internalPdfViewer; 0313 } 0314 0315 void WebEngineSettings::init() 0316 { 0317 initWebEngineSettings(); 0318 0319 KConfig global( QStringLiteral("khtmlrc"), KConfig::NoGlobals ); 0320 init( &global, true ); 0321 0322 KSharedConfig::Ptr local = KSharedConfig::openConfig(); 0323 if ( local ) { 0324 init( local.data(), false ); 0325 } 0326 0327 initNSPluginSettings(); 0328 initCookieJarSettings(); 0329 } 0330 0331 void WebEngineSettings::init( KConfig * config, bool reset ) 0332 { 0333 KConfigGroup cg( config, "MainView Settings" ); 0334 if (reset || cg.exists() ) 0335 { 0336 if ( reset || cg.hasKey( "OpenMiddleClick" ) ) 0337 d->m_bOpenMiddleClick = cg.readEntry( "OpenMiddleClick", true ); 0338 } 0339 0340 KConfigGroup cgAccess(config,"Access Keys" ); 0341 if (reset || cgAccess.exists() ) { 0342 d->m_accessKeysEnabled = cgAccess.readEntry( "Enabled", true ); 0343 } 0344 0345 KConfigGroup cgFilter( config, "Filter Settings" ); 0346 if ((reset || cgFilter.exists()) && (d->m_adFilterEnabled = cgFilter.readEntry("Enabled", false))) 0347 { 0348 d->m_hideAdsEnabled = cgFilter.readEntry("Shrink", false); 0349 0350 d->adBlackList.clear(); 0351 d->adWhiteList.clear(); 0352 0353 /** read maximum age for filter list files, minimum is one day */ 0354 int htmlFilterListMaxAgeDays = cgFilter.readEntry(QStringLiteral("HTMLFilterListMaxAgeDays")).toInt(); 0355 if (htmlFilterListMaxAgeDays < 1) 0356 htmlFilterListMaxAgeDays = 1; 0357 0358 QMapIterator<QString,QString> it (cgFilter.entryMap()); 0359 while (it.hasNext()) 0360 { 0361 it.next(); 0362 int id = -1; 0363 const QString name = it.key(); 0364 const QString url = it.value(); 0365 0366 if (name.startsWith(QLatin1String("Filter"))) 0367 { 0368 if (url.startsWith(QLatin1String("@@"))) 0369 d->adWhiteList.addFilter(url); 0370 else 0371 d->adBlackList.addFilter(url); 0372 } 0373 else if (name.startsWith(QLatin1String("HTMLFilterListName-")) && (id = QStringView{name}.mid(19).toInt()) > 0) 0374 { 0375 /** check if entry is enabled */ 0376 bool filterEnabled = cgFilter.readEntry(QStringLiteral("HTMLFilterListEnabled-").append(QString::number(id))) != QLatin1String("false"); 0377 0378 /** get url for HTMLFilterList */ 0379 QUrl url(cgFilter.readEntry(QStringLiteral("HTMLFilterListURL-").append(QString::number(id)))); 0380 0381 if (filterEnabled && url.isValid()) { 0382 /** determine where to cache HTMLFilterList file */ 0383 QString localFile = cgFilter.readEntry(QStringLiteral("HTMLFilterListLocalFilename-").append(QString::number(id))); 0384 QString dirName = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); 0385 QDir().mkpath(dirName); 0386 localFile = dirName + '/' + localFile; 0387 0388 /** determine existence and age of cache file */ 0389 QFileInfo fileInfo(localFile); 0390 0391 /** load cached file if it exists, irrespective of age */ 0392 if (fileInfo.exists()) 0393 d->adblockFilterLoadList( localFile ); 0394 0395 /** if no cache list file exists or if it is too old ... */ 0396 if (!fileInfo.exists() || fileInfo.lastModified().daysTo(QDateTime::currentDateTime()) > htmlFilterListMaxAgeDays) 0397 { 0398 /** ... in this case, refetch list asynchronously */ 0399 // qCDebug(WEBENGINEPART_LOG) << "Fetching filter list from" << url << "to" << localFile; 0400 KIO::StoredTransferJob *job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo ); 0401 QObject::connect( job, &KJob::result, d, &WebEngineSettingsPrivate::adblockFilterResult); 0402 /** for later reference, store name of cache file */ 0403 job->setProperty("webenginesettings_adBlock_filename", localFile); 0404 } 0405 } 0406 } 0407 } 0408 } 0409 0410 KConfigGroup cgHtml( config, "HTML Settings" ); 0411 if (reset || cgHtml.exists() ) 0412 { 0413 // Fonts and colors 0414 if( reset ) { 0415 d->defaultFonts = QStringList(); 0416 d->defaultFonts.append( cgHtml.readEntry( "StandardFont", QFontDatabase::systemFont(QFontDatabase::GeneralFont).family() ) ); 0417 d->defaultFonts.append( cgHtml.readEntry( "FixedFont", QFontDatabase::systemFont(QFontDatabase::FixedFont).family() )); 0418 d->defaultFonts.append( cgHtml.readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) ); 0419 d->defaultFonts.append( cgHtml.readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) ); 0420 d->defaultFonts.append( cgHtml.readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) ); 0421 d->defaultFonts.append( cgHtml.readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) ); 0422 d->defaultFonts.append( QStringLiteral( "0" ) ); // font size adjustment 0423 } 0424 0425 if ( reset || cgHtml.hasKey( "MinimumFontSize" ) ) 0426 d->m_minFontSize = cgHtml.readEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE ); 0427 0428 if ( reset || cgHtml.hasKey( "MediumFontSize" ) ) 0429 d->m_fontSize = cgHtml.readEntry( "MediumFontSize", 12 ); 0430 0431 d->fonts = cgHtml.readEntry( "Fonts", QStringList() ); 0432 0433 if ( reset || cgHtml.hasKey( "DefaultEncoding" ) ) 0434 d->m_encoding = cgHtml.readEntry( "DefaultEncoding", "" ); 0435 0436 if ( reset || cgHtml.hasKey( "EnforceDefaultCharset" ) ) 0437 d->enforceCharset = cgHtml.readEntry( "EnforceDefaultCharset", false ); 0438 0439 // Behavior 0440 0441 if ( reset || cgHtml.hasKey("UnderlineLinks") ) 0442 d->m_underlineLink = cgHtml.readEntry( "UnderlineLinks", true ); 0443 0444 if ( reset || cgHtml.hasKey( "HoverLinks" ) ) 0445 { 0446 if ( (d->m_hoverLink = cgHtml.readEntry( "HoverLinks", false ))) 0447 d->m_underlineLink = false; 0448 } 0449 0450 if ( reset || cgHtml.hasKey( "AllowTabulation" ) ) 0451 d->m_allowTabulation = cgHtml.readEntry( "AllowTabulation", false ); 0452 0453 if ( reset || cgHtml.hasKey( "AutoSpellCheck" ) ) 0454 d->m_autoSpellCheck = cgHtml.readEntry( "AutoSpellCheck", true ); 0455 0456 // Other 0457 if ( reset || cgHtml.hasKey( "AutoLoadImages" ) ) 0458 d->m_bAutoLoadImages = cgHtml.readEntry( "AutoLoadImages", true ); 0459 0460 if ( reset || cgHtml.hasKey( "AutoDelayedActions" ) ) 0461 d->m_bAutoRefreshPage = cgHtml.readEntry( "AutoDelayedActions", true ); 0462 0463 if ( reset || cgHtml.hasKey( "UnfinishedImageFrame" ) ) 0464 d->m_bUnfinishedImageFrame = cgHtml.readEntry( "UnfinishedImageFrame", true ); 0465 0466 if ( reset || cgHtml.hasKey( "ShowAnimations" ) ) 0467 { 0468 QString value = cgHtml.readEntry( "ShowAnimations").toLower(); 0469 if (value == QLatin1String("disabled")) 0470 d->m_showAnimations = KAnimationDisabled; 0471 else if (value == QLatin1String("looponce")) 0472 d->m_showAnimations = KAnimationLoopOnce; 0473 else 0474 d->m_showAnimations = KAnimationEnabled; 0475 } 0476 0477 if ( reset || cgHtml.hasKey( "SmoothScrolling" ) ) 0478 { 0479 QString value = cgHtml.readEntry( "SmoothScrolling", "whenefficient" ).toLower(); 0480 if (value == QLatin1String("disabled")) 0481 d->m_smoothScrolling = KSmoothScrollingDisabled; 0482 else if (value == QLatin1String("whenefficient")) 0483 d->m_smoothScrolling = KSmoothScrollingWhenEfficient; 0484 else 0485 d->m_smoothScrolling = KSmoothScrollingEnabled; 0486 } 0487 0488 if ( reset || cgHtml.hasKey( "ZoomTextOnly" ) ) { 0489 d->m_zoomTextOnly = cgHtml.readEntry( "ZoomTextOnly", false ); 0490 } 0491 0492 if ( reset || cgHtml.hasKey( "ZoomToDPI" ) ) { 0493 d->m_zoomToDPI = cgHtml.readEntry( "ZoomToDPI", false ); 0494 } 0495 0496 if (cgHtml.readEntry("UserStyleSheetEnabled", false)) { 0497 if (reset || cgHtml.hasKey("UserStyleSheet")) 0498 d->m_userSheet = cgHtml.readEntry("UserStyleSheet", QString()); 0499 } else { 0500 d->m_userSheet.clear(); 0501 } 0502 0503 if (reset || cgHtml.hasKey("InternalPdfViewer")) { 0504 d->m_internalPdfViewer = cgHtml.readEntry("InternalPdfViewer", false); 0505 } 0506 0507 d->m_formCompletionEnabled = cgHtml.readEntry("FormCompletion", true); 0508 d->m_maxFormCompletionItems = cgHtml.readEntry("MaxFormCompletionItems", 10); 0509 d->m_autoDelayedActionsEnabled = cgHtml.readEntry ("AutoDelayedActions", true); 0510 d->m_jsErrorsEnabled = cgHtml.readEntry("ReportJSErrors", true); 0511 const QStringList accesskeys = cgHtml.readEntry("FallbackAccessKeysAssignments", QStringList()); 0512 d->m_fallbackAccessKeysAssignments.clear(); 0513 for( QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it ) 0514 if( (*it).length() > 2 && (*it)[ 1 ] == ':' ) 0515 d->m_fallbackAccessKeysAssignments.append( qMakePair( (*it).mid( 2 ), (*it)[ 0 ] )); 0516 0517 d->m_bEnableFavicon = cgHtml.readEntry("EnableFavicon", true); 0518 d->m_offerToSaveWebSitePassword = cgHtml.readEntry("OfferToSaveWebsitePassword", true); 0519 } 0520 0521 // Colors 0522 //In which group ????? 0523 if ( reset || cg.hasKey( "FollowSystemColors" ) ) 0524 d->m_follow_system_colors = cg.readEntry( "FollowSystemColors", false ); 0525 0526 KConfigGroup cgGeneral( config, "General" ); 0527 if ( reset || cgGeneral.exists( ) ) 0528 { 0529 if ( reset || cgGeneral.hasKey( "foreground" ) ) { 0530 QColor def(HTML_DEFAULT_TXT_COLOR); 0531 d->m_textColor = cgGeneral.readEntry( "foreground", def ); 0532 } 0533 0534 if ( reset || cgGeneral.hasKey( "linkColor" ) ) { 0535 QColor def(HTML_DEFAULT_LNK_COLOR); 0536 d->m_linkColor = cgGeneral.readEntry( "linkColor", def ); 0537 } 0538 0539 if ( reset || cgGeneral.hasKey( "visitedLinkColor" ) ) { 0540 QColor def(HTML_DEFAULT_VLNK_COLOR); 0541 d->m_vLinkColor = cgGeneral.readEntry( "visitedLinkColor", def); 0542 } 0543 0544 if ( reset || cgGeneral.hasKey( "background" ) ) { 0545 QColor def(HTML_DEFAULT_BASE_COLOR); 0546 d->m_baseColor = cgGeneral.readEntry( "background", def); 0547 } 0548 } 0549 0550 KConfigGroup cgJava( config, "Java/JavaScript Settings" ); 0551 if( reset || cgJava.exists() ) 0552 { 0553 // The global setting for JavaScript debugging 0554 // This is currently always enabled by default 0555 if ( reset || cgJava.hasKey( "EnableJavaScriptDebug" ) ) 0556 d->m_bEnableJavaScriptDebug = cgJava.readEntry( "EnableJavaScriptDebug", false ); 0557 0558 // The global setting for JavaScript error reporting 0559 if ( reset || cgJava.hasKey( "ReportJavaScriptErrors" ) ) 0560 d->m_bEnableJavaScriptErrorReporting = cgJava.readEntry( "ReportJavaScriptErrors", false ); 0561 0562 // The global setting for popup block passive popup 0563 if ( reset || cgJava.hasKey( "PopupBlockerPassivePopup" ) ) 0564 d->m_jsPopupBlockerPassivePopup = cgJava.readEntry("PopupBlockerPassivePopup", true ); 0565 0566 // Read options from the global "domain" 0567 readDomainSettings(cgJava,reset,true,d->global); 0568 #ifdef DEBUG_SETTINGS 0569 d->global.dump("init global"); 0570 #endif 0571 0572 // The domain-specific settings. 0573 0574 static const char *const domain_keys[] = { // always keep order of keys 0575 "ECMADomains", "JavaDomains", "PluginDomains" 0576 }; 0577 bool check_old_ecma_settings = true; 0578 bool check_old_java_settings = true; 0579 // merge all domains into one list 0580 QSet<QString> domainList; 0581 for (unsigned i = 0; i < sizeof domain_keys/sizeof domain_keys[0]; ++i) { 0582 if (reset || cgJava.hasKey(domain_keys[i])) { 0583 if (i == 0) check_old_ecma_settings = false; 0584 else if (i == 1) check_old_java_settings = false; 0585 const QStringList dl = cgJava.readEntry( domain_keys[i], QStringList() ); 0586 const QSet<QString>::Iterator notfound = domainList.end(); 0587 QStringList::ConstIterator it = dl.begin(); 0588 const QStringList::ConstIterator itEnd = dl.end(); 0589 for (; it != itEnd; ++it) { 0590 const QString domain = (*it).toLower(); 0591 QSet<QString>::Iterator pos = domainList.find(domain); 0592 if (pos == notfound) domainList.insert(domain); 0593 }/*next it*/ 0594 } 0595 }/*next i*/ 0596 0597 if (reset) 0598 d->domainPolicy.clear(); 0599 0600 { 0601 QSet<QString>::ConstIterator it = domainList.constBegin(); 0602 const QSet<QString>::ConstIterator itEnd = domainList.constEnd(); 0603 for ( ; it != itEnd; ++it) 0604 { 0605 const QString domain = *it; 0606 KConfigGroup cg( config, domain ); 0607 readDomainSettings(cg,reset,false,d->domainPolicy[domain]); 0608 #ifdef DEBUG_SETTINGS 0609 d->domainPolicy[domain].dump("init "+domain); 0610 #endif 0611 } 0612 } 0613 0614 bool check_old_java = true; 0615 if( (reset || cgJava.hasKey("JavaDomainSettings")) && check_old_java_settings) 0616 { 0617 check_old_java = false; 0618 const QStringList domainList = cgJava.readEntry( "JavaDomainSettings", QStringList() ); 0619 QStringList::ConstIterator it = domainList.constBegin(); 0620 const QStringList::ConstIterator itEnd = domainList.constEnd(); 0621 for ( ; it != itEnd; ++it) 0622 { 0623 QString domain; 0624 HtmlSettingsInterface::JavaScriptAdvice javaAdvice; 0625 HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice; 0626 HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice); 0627 setup_per_domain_policy(d,domain).m_bEnableJava = javaAdvice == HtmlSettingsInterface::JavaScriptAccept; 0628 #ifdef DEBUG_SETTINGS 0629 setup_per_domain_policy(d,domain).dump("JavaDomainSettings 4 "+domain); 0630 #endif 0631 } 0632 } 0633 0634 bool check_old_ecma = true; 0635 if( ( reset || cgJava.hasKey( "ECMADomainSettings" ) ) && check_old_ecma_settings ) 0636 { 0637 check_old_ecma = false; 0638 const QStringList domainList = cgJava.readEntry( "ECMADomainSettings", QStringList() ); 0639 QStringList::ConstIterator it = domainList.constBegin(); 0640 const QStringList::ConstIterator itEnd = domainList.constEnd(); 0641 for ( ; it != itEnd; ++it) 0642 { 0643 QString domain; 0644 HtmlSettingsInterface::JavaScriptAdvice javaAdvice; 0645 HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice; 0646 HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice); 0647 setup_per_domain_policy(d,domain).m_bEnableJavaScript = javaScriptAdvice == HtmlSettingsInterface::JavaScriptAccept; 0648 #ifdef DEBUG_SETTINGS 0649 setup_per_domain_policy(d,domain).dump("ECMADomainSettings 4 "+domain); 0650 #endif 0651 } 0652 } 0653 0654 if( ( reset || cgJava.hasKey( "JavaScriptDomainAdvice" ) ) 0655 && ( check_old_java || check_old_ecma ) 0656 && ( check_old_ecma_settings || check_old_java_settings ) ) 0657 { 0658 const QStringList domainList = cgJava.readEntry( "JavaScriptDomainAdvice", QStringList() ); 0659 QStringList::ConstIterator it = domainList.constBegin(); 0660 const QStringList::ConstIterator itEnd = domainList.constEnd(); 0661 for ( ; it != itEnd; ++it) 0662 { 0663 QString domain; 0664 HtmlSettingsInterface::JavaScriptAdvice javaAdvice; 0665 HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice; 0666 HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice); 0667 if( check_old_java ) 0668 setup_per_domain_policy(d,domain).m_bEnableJava = javaAdvice == HtmlSettingsInterface::JavaScriptAccept; 0669 if( check_old_ecma ) 0670 setup_per_domain_policy(d,domain).m_bEnableJavaScript = javaScriptAdvice == HtmlSettingsInterface::JavaScriptAccept; 0671 #ifdef DEBUG_SETTINGS 0672 setup_per_domain_policy(d,domain).dump("JavaScriptDomainAdvice 4 "+domain); 0673 #endif 0674 } 0675 } 0676 } 0677 0678 #if 0 0679 // DNS Prefect support... 0680 if ( reset || cgHtml.hasKey( "DNSPrefetch" ) ) 0681 { 0682 // Enabled, Disabled, OnlyWWWAndSLD 0683 QString value = cgHtml.readEntry( "DNSPrefetch", "Enabled" ).toLower(); 0684 0685 if (value == "enabled") 0686 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true); 0687 else 0688 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, false); 0689 } 0690 0691 // Sync with QWebEngineSettings. 0692 if (!d->m_encoding.isEmpty()) 0693 Profile::defaultProfile()->settings()->setDefaultTextEncoding(d->m_encoding); 0694 Profile::defaultProfile()->settings()->setUserStyleSheetUrl(QUrl::fromUserInput(userStyleSheet())); 0695 #endif 0696 0697 0698 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::AutoLoadImages, autoLoadImages()); 0699 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, isJavaScriptEnabled()); 0700 // Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::JavaEnabled, isJavaEnabled()); 0701 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::PluginsEnabled, isPluginsEnabled()); 0702 0703 // By default disable JS window.open when policy is deny or smart. 0704 const HtmlSettingsInterface::JSWindowOpenPolicy policy = windowOpenPolicy(); 0705 if (policy == HtmlSettingsInterface::JSWindowOpenDeny || policy == HtmlSettingsInterface::JSWindowOpenSmart) 0706 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); 0707 else 0708 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); 0709 0710 // Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::ZoomTextOnly, zoomTextOnly()); 0711 // Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, isJavaScriptDebugEnabled()); 0712 Profile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::StandardFont, stdFontName()); 0713 Profile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::FixedFont, fixedFontName()); 0714 Profile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::SerifFont, serifFontName()); 0715 Profile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::SansSerifFont, sansSerifFontName()); 0716 Profile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::CursiveFont, cursiveFontName()); 0717 Profile::defaultProfile()->settings()->setFontFamily(QWebEngineSettings::FantasyFont, fantasyFontName()); 0718 0719 // TODO: Create a webengine config module that gets embedded into Konqueror's kcm. 0720 // Turn on WebGL support 0721 // Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::WebGLEnabled, d->m_enableWebGL); 0722 // Turn on HTML 5 local and offline storage capabilities... 0723 // Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled, d->m_enableOfflineStorageDb); 0724 // Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled, d->m_enableOfflineWebAppCache); 0725 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, d->m_enableLocalStorage); 0726 0727 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, smoothScrolling() != KSmoothScrollingDisabled); 0728 0729 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::PdfViewerEnabled, internalPdfViewer()); 0730 0731 Profile::defaultProfile()->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); 0732 0733 // These numbers should be calculated from real "logical" DPI/72, using a default dpi of 96 for now 0734 computeFontSizes(96); 0735 0736 } 0737 0738 0739 void WebEngineSettings::computeFontSizes( int logicalDpi ) 0740 { 0741 if (zoomToDPI()) 0742 logicalDpi = 96; 0743 0744 float toPix = logicalDpi/72.0; 0745 0746 if (toPix < 96.0/72.0) 0747 toPix = 96.0/72.0; 0748 0749 Profile::defaultProfile()->settings()->setFontSize(QWebEngineSettings::MinimumFontSize, qRound(minFontSize() * toPix)); 0750 Profile::defaultProfile()->settings()->setFontSize(QWebEngineSettings::DefaultFontSize, qRound(mediumFontSize() * toPix)); 0751 } 0752 0753 bool WebEngineSettings::zoomToDPI() const 0754 { 0755 return d->m_zoomToDPI; 0756 } 0757 0758 void WebEngineSettings::setZoomToDPI(bool enabled) 0759 { 0760 d->m_zoomToDPI = enabled; 0761 // save it 0762 KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings"); 0763 cg.writeEntry("ZoomToDPI", enabled); 0764 cg.sync(); 0765 } 0766 0767 /** Local helper for retrieving per-domain settings. 0768 * 0769 * In case of doubt, the global domain is returned. 0770 */ 0771 static const KPerDomainSettings& lookup_hostname_policy(const WebEngineSettingsPrivate* const d, 0772 const QString& hostname) 0773 { 0774 #ifdef DEBUG_SETTINGS 0775 qCDebug(WEBENGINEPART_LOG) << "lookup_hostname_policy(" << hostname << ")"; 0776 #endif 0777 if (hostname.isEmpty()) { 0778 #ifdef DEBUG_SETTINGS 0779 d->global.dump("global"); 0780 #endif 0781 return d->global; 0782 } 0783 0784 const PolicyMap::const_iterator notfound = d->domainPolicy.constEnd(); 0785 0786 // First check whether there is a perfect match. 0787 PolicyMap::const_iterator it = d->domainPolicy.find(hostname); 0788 if( it != notfound ) { 0789 #ifdef DEBUG_SETTINGS 0790 qCDebug(WEBENGINEPART_LOG) << "perfect match"; 0791 (*it).dump(hostname); 0792 #endif 0793 // yes, use it (unless dunno) 0794 return *it; 0795 } 0796 0797 // Now, check for partial match. Chop host from the left until 0798 // there's no dots left. 0799 QString host_part = hostname; 0800 int dot_idx = -1; 0801 while( (dot_idx = host_part.indexOf(QChar('.'))) >= 0 ) { 0802 host_part.remove(0,dot_idx); 0803 it = d->domainPolicy.find(host_part); 0804 Q_ASSERT(notfound == d->domainPolicy.end()); 0805 if( it != notfound ) { 0806 #ifdef DEBUG_SETTINGS 0807 qCDebug(WEBENGINEPART_LOG) << "partial match"; 0808 (*it).dump(host_part); 0809 #endif 0810 return *it; 0811 } 0812 // assert(host_part[0] == QChar('.')); 0813 host_part.remove(0,1); // Chop off the dot. 0814 } 0815 0816 // No domain-specific entry: use global domain 0817 #ifdef DEBUG_SETTINGS 0818 qCDebug(WEBENGINEPART_LOG) << "no match"; 0819 d->global.dump("global"); 0820 #endif 0821 return d->global; 0822 } 0823 0824 bool WebEngineSettings::isOpenMiddleClickEnabled() 0825 { 0826 return d->m_bOpenMiddleClick; 0827 } 0828 0829 bool WebEngineSettings::accessKeysEnabled() const 0830 { 0831 return d->m_accessKeysEnabled; 0832 } 0833 0834 bool WebEngineSettings::favIconsEnabled() const 0835 { 0836 return d->m_bEnableFavicon; 0837 } 0838 0839 bool WebEngineSettings::isAdFilterEnabled() const 0840 { 0841 return d->m_adFilterEnabled; 0842 } 0843 0844 bool WebEngineSettings::isHideAdsEnabled() const 0845 { 0846 return d->m_hideAdsEnabled; 0847 } 0848 0849 bool WebEngineSettings::isAdFiltered( const QString &url ) const 0850 { 0851 if (!d->m_adFilterEnabled) 0852 return false; 0853 0854 if (url.startsWith(QLatin1String("data:"))) 0855 return false; 0856 0857 return d->adBlackList.isUrlMatched(url) && !d->adWhiteList.isUrlMatched(url); 0858 } 0859 0860 QString WebEngineSettings::adFilteredBy( const QString &url, bool *isWhiteListed ) const 0861 { 0862 QString m = d->adWhiteList.urlMatchedBy(url); 0863 0864 if (!m.isEmpty()) { 0865 if (isWhiteListed != nullptr) 0866 *isWhiteListed = true; 0867 return m; 0868 } 0869 0870 m = d->adBlackList.urlMatchedBy(url); 0871 if (m.isEmpty()) 0872 return QString(); 0873 0874 if (isWhiteListed != nullptr) 0875 *isWhiteListed = false; 0876 return m; 0877 } 0878 0879 void WebEngineSettings::addAdFilter( const QString &url ) 0880 { 0881 KConfigGroup config = KSharedConfig::openConfig( QStringLiteral("khtmlrc"), KConfig::NoGlobals )->group( "Filter Settings" ); 0882 0883 QRegularExpression rx; 0884 0885 // Try compiling to avoid invalid stuff. Only support the basic syntax here... 0886 // ### refactor somewhat 0887 if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/') 0888 { 0889 const QString inside = url.mid(1, url.length()-2); 0890 rx.setPattern(inside); 0891 } 0892 else 0893 { 0894 rx.setPattern(QRegularExpression::wildcardToRegularExpression(url)); 0895 } 0896 0897 if (rx.isValid()) 0898 { 0899 int last=config.readEntry("Count", 0); 0900 const QString key = "Filter-" + QString::number(last); 0901 config.writeEntry(key, url); 0902 config.writeEntry("Count",last+1); 0903 config.sync(); 0904 0905 if (url.startsWith(QLatin1String("@@"))) 0906 d->adWhiteList.addFilter(url); 0907 else 0908 d->adBlackList.addFilter(url); 0909 } 0910 else 0911 { 0912 KMessageBox::error(nullptr, 0913 rx.errorString(), 0914 i18n("Filter error")); 0915 } 0916 } 0917 0918 bool WebEngineSettings::isJavaEnabled( const QString& hostname ) const 0919 { 0920 return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJava; 0921 } 0922 0923 bool WebEngineSettings::isJavaScriptEnabled( const QString& hostname ) const 0924 { 0925 return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJavaScript; 0926 } 0927 0928 bool WebEngineSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ ) const 0929 { 0930 // debug setting is global for now, but could change in the future 0931 return d->m_bEnableJavaScriptDebug; 0932 } 0933 0934 bool WebEngineSettings::isJavaScriptErrorReportingEnabled( const QString& /*hostname*/ ) const 0935 { 0936 // error reporting setting is global for now, but could change in the future 0937 return d->m_bEnableJavaScriptErrorReporting; 0938 } 0939 0940 bool WebEngineSettings::isPluginsEnabled( const QString& hostname ) const 0941 { 0942 return lookup_hostname_policy(d,hostname.toLower()).m_bEnablePlugins; 0943 } 0944 0945 HtmlSettingsInterface::JSWindowOpenPolicy WebEngineSettings::windowOpenPolicy(const QString& hostname) const { 0946 return lookup_hostname_policy(d,hostname.toLower()).m_windowOpenPolicy; 0947 } 0948 0949 HtmlSettingsInterface::JSWindowMovePolicy WebEngineSettings::windowMovePolicy(const QString& hostname) const { 0950 return lookup_hostname_policy(d,hostname.toLower()).m_windowMovePolicy; 0951 } 0952 0953 HtmlSettingsInterface::JSWindowResizePolicy WebEngineSettings::windowResizePolicy(const QString& hostname) const { 0954 return lookup_hostname_policy(d,hostname.toLower()).m_windowResizePolicy; 0955 } 0956 0957 HtmlSettingsInterface::JSWindowStatusPolicy WebEngineSettings::windowStatusPolicy(const QString& hostname) const { 0958 return lookup_hostname_policy(d,hostname.toLower()).m_windowStatusPolicy; 0959 } 0960 0961 HtmlSettingsInterface::JSWindowFocusPolicy WebEngineSettings::windowFocusPolicy(const QString& hostname) const { 0962 return lookup_hostname_policy(d,hostname.toLower()).m_windowFocusPolicy; 0963 } 0964 0965 int WebEngineSettings::mediumFontSize() const 0966 { 0967 return d->m_fontSize; 0968 } 0969 0970 int WebEngineSettings::minFontSize() const 0971 { 0972 return d->m_minFontSize; 0973 } 0974 0975 QString WebEngineSettings::settingsToCSS() const 0976 { 0977 // lets start with the link properties 0978 QString str = QStringLiteral("a:link {\ncolor: "); 0979 str += d->m_linkColor.name(); 0980 str += ';'; 0981 if(d->m_underlineLink) 0982 str += QLatin1String("\ntext-decoration: underline;"); 0983 0984 if( d->m_bChangeCursor ) 0985 { 0986 str += QLatin1String("\ncursor: pointer;"); 0987 str += QLatin1String("\n}\ninput[type=image] { cursor: pointer;"); 0988 } 0989 str += QLatin1String("\n}\n"); 0990 str += QLatin1String("a:visited {\ncolor: "); 0991 str += d->m_vLinkColor.name(); 0992 str += ';'; 0993 if(d->m_underlineLink) 0994 str += QLatin1String("\ntext-decoration: underline;"); 0995 0996 if( d->m_bChangeCursor ) 0997 str += QLatin1String("\ncursor: pointer;"); 0998 str += QLatin1String("\n}\n"); 0999 1000 if(d->m_hoverLink) 1001 str += QLatin1String("a:link:hover, a:visited:hover { text-decoration: underline; }\n"); 1002 1003 return str; 1004 } 1005 1006 QString WebEngineSettings::lookupFont(int i) const 1007 { 1008 if (d->fonts.count() > i) { 1009 return d->fonts.at(i); 1010 } 1011 1012 if (d->defaultFonts.count() > i) { 1013 return d->defaultFonts.at(i); 1014 } 1015 1016 return QString(); 1017 } 1018 1019 QString WebEngineSettings::stdFontName() const 1020 { 1021 return lookupFont(0); 1022 } 1023 1024 QString WebEngineSettings::fixedFontName() const 1025 { 1026 return lookupFont(1); 1027 } 1028 1029 QString WebEngineSettings::serifFontName() const 1030 { 1031 return lookupFont(2); 1032 } 1033 1034 QString WebEngineSettings::sansSerifFontName() const 1035 { 1036 return lookupFont(3); 1037 } 1038 1039 QString WebEngineSettings::cursiveFontName() const 1040 { 1041 return lookupFont(4); 1042 } 1043 1044 QString WebEngineSettings::fantasyFontName() const 1045 { 1046 return lookupFont(5); 1047 } 1048 1049 void WebEngineSettings::setStdFontName(const QString &n) 1050 { 1051 while(d->fonts.count() <= 0) 1052 d->fonts.append(QString()); 1053 d->fonts[0] = n; 1054 } 1055 1056 void WebEngineSettings::setFixedFontName(const QString &n) 1057 { 1058 while(d->fonts.count() <= 1) 1059 d->fonts.append(QString()); 1060 d->fonts[1] = n; 1061 } 1062 1063 QString WebEngineSettings::userStyleSheet() const 1064 { 1065 return d->m_userSheet; 1066 } 1067 1068 bool WebEngineSettings::isFormCompletionEnabled() const 1069 { 1070 return d->m_formCompletionEnabled; 1071 } 1072 1073 int WebEngineSettings::maxFormCompletionItems() const 1074 { 1075 return d->m_maxFormCompletionItems; 1076 } 1077 1078 const QString &WebEngineSettings::encoding() const 1079 { 1080 return d->m_encoding; 1081 } 1082 1083 bool WebEngineSettings::followSystemColors() const 1084 { 1085 return d->m_follow_system_colors; 1086 } 1087 1088 const QColor& WebEngineSettings::textColor() const 1089 { 1090 return d->m_textColor; 1091 } 1092 1093 const QColor& WebEngineSettings::baseColor() const 1094 { 1095 return d->m_baseColor; 1096 } 1097 1098 const QColor& WebEngineSettings::linkColor() const 1099 { 1100 return d->m_linkColor; 1101 } 1102 1103 const QColor& WebEngineSettings::vLinkColor() const 1104 { 1105 return d->m_vLinkColor; 1106 } 1107 1108 bool WebEngineSettings::autoPageRefresh() const 1109 { 1110 return d->m_bAutoRefreshPage; 1111 } 1112 1113 bool WebEngineSettings::autoLoadImages() const 1114 { 1115 return d->m_bAutoLoadImages; 1116 } 1117 1118 bool WebEngineSettings::unfinishedImageFrame() const 1119 { 1120 return d->m_bUnfinishedImageFrame; 1121 } 1122 1123 WebEngineSettings::KAnimationAdvice WebEngineSettings::showAnimations() const 1124 { 1125 return d->m_showAnimations; 1126 } 1127 1128 WebEngineSettings::KSmoothScrollingMode WebEngineSettings::smoothScrolling() const 1129 { 1130 return d->m_smoothScrolling; 1131 } 1132 1133 bool WebEngineSettings::zoomTextOnly() const 1134 { 1135 return d->m_zoomTextOnly; 1136 } 1137 1138 bool WebEngineSettings::isAutoDelayedActionsEnabled() const 1139 { 1140 return d->m_autoDelayedActionsEnabled; 1141 } 1142 1143 bool WebEngineSettings::jsErrorsEnabled() const 1144 { 1145 return d->m_jsErrorsEnabled; 1146 } 1147 1148 void WebEngineSettings::setJSErrorsEnabled(bool enabled) 1149 { 1150 d->m_jsErrorsEnabled = enabled; 1151 // save it 1152 KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings"); 1153 cg.writeEntry("ReportJSErrors", enabled); 1154 cg.sync(); 1155 } 1156 1157 bool WebEngineSettings::allowTabulation() const 1158 { 1159 return d->m_allowTabulation; 1160 } 1161 1162 bool WebEngineSettings::autoSpellCheck() const 1163 { 1164 return d->m_autoSpellCheck; 1165 } 1166 1167 QList< QPair< QString, QChar > > WebEngineSettings::fallbackAccessKeysAssignments() const 1168 { 1169 return d->m_fallbackAccessKeysAssignments; 1170 } 1171 1172 void WebEngineSettings::setJSPopupBlockerPassivePopup(bool enabled) 1173 { 1174 d->m_jsPopupBlockerPassivePopup = enabled; 1175 // save it 1176 KConfigGroup cg( KSharedConfig::openConfig(), "Java/JavaScript Settings"); 1177 cg.writeEntry("PopupBlockerPassivePopup", enabled); 1178 cg.sync(); 1179 } 1180 1181 bool WebEngineSettings::jsPopupBlockerPassivePopup() const 1182 { 1183 return d->m_jsPopupBlockerPassivePopup; 1184 } 1185 1186 #ifndef MANAGE_COOKIES_INTERNALLY 1187 bool WebEngineSettings::isCookieJarEnabled() const 1188 { 1189 return d->m_useCookieJar; 1190 } 1191 1192 bool WebEngineSettings::acceptCrossDomainCookies() const 1193 { 1194 return d->m_acceptCrossDomainCookies; 1195 } 1196 #endif 1197 1198 // Password storage... 1199 KConfigGroup WebEngineSettings::nonPasswordStorableSitesCg() const 1200 { 1201 if (!d->nonPasswordStorableSites) { 1202 d->nonPasswordStorableSites = KSharedConfig::openConfig(QString(), KConfig::NoGlobals); 1203 } 1204 return KConfigGroup(d->nonPasswordStorableSites, "NonPasswordStorableSites"); 1205 } 1206 1207 bool WebEngineSettings::isNonPasswordStorableSite(const QString &host) const 1208 { 1209 KConfigGroup cg = nonPasswordStorableSitesCg(); 1210 const QStringList sites = cg.readEntry("Sites", QStringList()); 1211 return sites.contains(host); 1212 } 1213 1214 void WebEngineSettings::addNonPasswordStorableSite(const QString &host) 1215 { 1216 KConfigGroup cg = nonPasswordStorableSitesCg(); 1217 QStringList sites = cg.readEntry("Sites", QStringList()); 1218 sites.append(host); 1219 cg.writeEntry("Sites", sites); 1220 cg.sync(); 1221 } 1222 1223 void WebEngineSettings::removeNonPasswordStorableSite(const QString &host) 1224 { 1225 KConfigGroup cg = nonPasswordStorableSitesCg(); 1226 QStringList sites = cg.readEntry("Sites", QStringList()); 1227 sites.removeOne(host); 1228 cg.writeEntry("Sites", sites); 1229 cg.sync(); 1230 } 1231 1232 KConfigGroup WebEngineSettings::pagesWithCustomizedCacheableFieldsCg() const 1233 { 1234 if (!d->sitesWithCustomForms) { 1235 d->sitesWithCustomForms = KSharedConfig::openConfig(QString(), KConfig::NoGlobals); 1236 } 1237 return KConfigGroup(d->sitesWithCustomForms, "PagesWithCustomizedCacheableFields"); 1238 } 1239 1240 void WebEngineSettings::setCustomizedCacheableFieldsForPage(const QString& url, const WebFormInfoList& forms) 1241 { 1242 KConfigGroup cg = pagesWithCustomizedCacheableFieldsCg(); 1243 QByteArray data; 1244 QDataStream ds(&data, QIODevice::WriteOnly); 1245 ds << forms; 1246 cg.writeEntry(url, data); 1247 cg.sync(); 1248 } 1249 1250 bool WebEngineSettings::hasPageCustomizedCacheableFields(const QString& url) const 1251 { 1252 KConfigGroup cg = pagesWithCustomizedCacheableFieldsCg(); 1253 return cg.hasKey(url); 1254 } 1255 1256 void WebEngineSettings::removeCacheableFieldsCustomizationForPage(const QString& url) 1257 { 1258 KConfigGroup cg = pagesWithCustomizedCacheableFieldsCg(); 1259 cg.deleteEntry(url); 1260 cg.sync(); 1261 } 1262 1263 WebEngineSettings::WebFormInfoList WebEngineSettings::customizedCacheableFieldsForPage(const QString& url) 1264 { 1265 KConfigGroup cg = pagesWithCustomizedCacheableFieldsCg(); 1266 QByteArray data = cg.readEntry(url, QByteArray()); 1267 if (data.isEmpty()) { 1268 return {}; 1269 } 1270 QDataStream ds(data); 1271 WebFormInfoList res; 1272 ds >> res; 1273 return res; 1274 } 1275 1276 bool WebEngineSettings::askToSaveSitePassword() const 1277 { 1278 return d->m_offerToSaveWebSitePassword; 1279 } 1280 1281 bool WebEngineSettings::isInternalPluginHandlingDisabled() const 1282 { 1283 return d->m_disableInternalPluginHandling; 1284 } 1285 1286 bool WebEngineSettings::isLoadPluginsOnDemandEnabled() const 1287 { 1288 return d->m_loadPluginsOnDemand; 1289 } 1290 1291 bool WebEngineSettings::allowMixedContentDisplay() const 1292 { 1293 return d->m_allowMixedContentDisplay; 1294 } 1295 1296 bool WebEngineSettings::alowActiveMixedContent() const 1297 { 1298 return d->m_allowActiveMixedContent; 1299 } 1300 1301 1302 void WebEngineSettings::initWebEngineSettings() 1303 { 1304 KConfig cfg (QStringLiteral("webenginepartrc"), KConfig::NoGlobals); 1305 KConfigGroup generalCfg (&cfg, "General"); 1306 d->m_disableInternalPluginHandling = generalCfg.readEntry("DisableInternalPluginHandling", false); 1307 d->m_enableLocalStorage = generalCfg.readEntry("EnableLocalStorage", true); 1308 d->m_enableOfflineStorageDb = generalCfg.readEntry("EnableOfflineStorageDatabase", true); 1309 d->m_enableOfflineWebAppCache = generalCfg.readEntry("EnableOfflineWebApplicationCache", true); 1310 d->m_enableWebGL = generalCfg.readEntry("EnableWebGL", true); 1311 d->m_allowActiveMixedContent = generalCfg.readEntry("AllowActiveMixedContent", false); 1312 d->m_allowMixedContentDisplay = generalCfg.readEntry("AllowMixedContentDisplay", true); 1313 1314 // Force the reloading of the non password storable sites settings. 1315 d->nonPasswordStorableSites.reset(); 1316 } 1317 1318 void WebEngineSettings::initCookieJarSettings() 1319 { 1320 KSharedConfig::Ptr cookieCfgPtr = KSharedConfig::openConfig(QStringLiteral("kcookiejarrc"), KConfig::NoGlobals); 1321 KConfigGroup cookieCfg ( cookieCfgPtr, "Cookie Policy"); 1322 d->m_useCookieJar = cookieCfg.readEntry("Cookies", false); 1323 #ifndef MANAGE_COOKIES_INTERNALLY 1324 d->m_acceptCrossDomainCookies = !cookieCfg.readEntry("RejectCrossDomainCookies", true); 1325 #endif 1326 } 1327 1328 void WebEngineSettings::initNSPluginSettings() 1329 { 1330 KSharedConfig::Ptr cookieCfgPtr = KSharedConfig::openConfig(QStringLiteral("kcmnspluginrc"), KConfig::NoGlobals); 1331 KConfigGroup cookieCfg ( cookieCfgPtr, "Misc"); 1332 d->m_loadPluginsOnDemand = cookieCfg.readEntry("demandLoad", false); 1333 } 1334 1335 1336 WebEngineSettings* WebEngineSettings::self() 1337 { 1338 static WebEngineSettings s_webEngineSettings; 1339 return &s_webEngineSettings; 1340 } 1341 1342 QDebug operator<<(QDebug dbg, const WebEngineSettings::WebFormInfo& info) 1343 { 1344 QDebugStateSaver state(dbg); 1345 dbg.nospace() << "CustomWebFormInfo{"; 1346 dbg << info.name << ", " << info.framePath << ", " << info.fields << "}"; 1347 return dbg; 1348 } 1349 1350 #include "webenginesettings.moc"