fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / khtml / khtml_settings.cpp
blob194de2762f7b6f182706a83ceaafe7551587a745
1 /* This file is part of the KDE project
2 Copyright (C) 1999 David Faure <faure@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "khtml_settings.h"
21 #include "khtmldefaults.h"
23 #include <kconfig.h>
24 #include <kconfiggroup.h>
25 #include <kdebug.h>
26 #include <kglobal.h>
27 #include <kglobalsettings.h>
28 #include <klocale.h>
29 #include <kmessagebox.h>
30 #include <khtml_filter_p.h>
32 #include <QtGui/QFontDatabase>
34 /**
35 * @internal
36 * Contains all settings which are both available globally and per-domain
38 struct KPerDomainSettings {
39 bool m_bEnableJava : 1;
40 bool m_bEnableJavaScript : 1;
41 bool m_bEnablePlugins : 1;
42 // don't forget to maintain the bitfields as the enums grow
43 KHTMLSettings::KJSWindowOpenPolicy m_windowOpenPolicy : 2;
44 KHTMLSettings::KJSWindowStatusPolicy m_windowStatusPolicy : 1;
45 KHTMLSettings::KJSWindowFocusPolicy m_windowFocusPolicy : 1;
46 KHTMLSettings::KJSWindowMovePolicy m_windowMovePolicy : 1;
47 KHTMLSettings::KJSWindowResizePolicy m_windowResizePolicy : 1;
49 #ifdef DEBUG_SETTINGS
50 void dump(const QString &infix = QString()) const {
51 kDebug() << "KPerDomainSettings " << infix << " @" << this << ":";
52 kDebug() << " m_bEnableJava: " << m_bEnableJava;
53 kDebug() << " m_bEnableJavaScript: " << m_bEnableJavaScript;
54 kDebug() << " m_bEnablePlugins: " << m_bEnablePlugins;
55 kDebug() << " m_windowOpenPolicy: " << m_windowOpenPolicy;
56 kDebug() << " m_windowStatusPolicy: " << m_windowStatusPolicy;
57 kDebug() << " m_windowFocusPolicy: " << m_windowFocusPolicy;
58 kDebug() << " m_windowMovePolicy: " << m_windowMovePolicy;
59 kDebug() << " m_windowResizePolicy: " << m_windowResizePolicy;
61 #endif
64 QString *KHTMLSettings::avFamilies = 0;
65 typedef QMap<QString,KPerDomainSettings> PolicyMap;
67 class KHTMLSettingsPrivate
69 public:
70 bool m_bChangeCursor : 1;
71 bool m_bOpenMiddleClick : 1;
72 bool m_bBackRightClick : 1;
73 bool m_underlineLink : 1;
74 bool m_hoverLink : 1;
75 bool m_bEnableJavaScriptDebug : 1;
76 bool m_bEnableJavaScriptErrorReporting : 1;
77 bool enforceCharset : 1;
78 bool m_bAutoLoadImages : 1;
79 bool m_bUnfinishedImageFrame : 1;
80 bool m_formCompletionEnabled : 1;
81 bool m_autoDelayedActionsEnabled : 1;
82 bool m_jsErrorsEnabled : 1;
83 bool m_follow_system_colors : 1;
84 bool m_allowTabulation : 1;
85 bool m_autoSpellCheck : 1;
86 bool m_adFilterEnabled : 1;
87 bool m_hideAdsEnabled : 1;
88 bool m_jsPopupBlockerPassivePopup : 1;
89 bool m_accessKeysEnabled : 1;
91 // the virtual global "domain"
92 KPerDomainSettings global;
94 int m_fontSize;
95 int m_minFontSize;
96 int m_maxFormCompletionItems;
97 KHTMLSettings::KAnimationAdvice m_showAnimations;
98 KHTMLSettings::KSmoothScrollingMode m_smoothScrolling;
99 KHTMLSettings::KDNSPrefetch m_dnsPrefetch;
101 QString m_encoding;
102 QString m_userSheet;
104 QColor m_textColor;
105 QColor m_baseColor;
106 QColor m_linkColor;
107 QColor m_vLinkColor;
109 PolicyMap domainPolicy;
110 QStringList fonts;
111 QStringList defaultFonts;
113 khtml::FilterSet adBlackList;
114 khtml::FilterSet adWhiteList;
115 QList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments;
119 /** Returns a writeable per-domains settings instance for the given domain
120 * or a deep copy of the global settings if not existent.
122 static KPerDomainSettings &setup_per_domain_policy(
123 KHTMLSettingsPrivate* const d,
124 const QString &domain) {
125 if (domain.isEmpty()) {
126 kWarning() << "setup_per_domain_policy: domain is empty";
128 const QString ldomain = domain.toLower();
129 PolicyMap::iterator it = d->domainPolicy.find(ldomain);
130 if (it == d->domainPolicy.end()) {
131 // simply copy global domain settings (they should have been initialized
132 // by this time)
133 it = d->domainPolicy.insert(ldomain,d->global);
135 return *it;
139 KHTMLSettings::KJavaScriptAdvice KHTMLSettings::strToAdvice(const QString& _str)
141 KJavaScriptAdvice ret = KJavaScriptDunno;
143 if (_str.isNull())
144 ret = KJavaScriptDunno;
146 if (_str.toLower() == QLatin1String("accept"))
147 ret = KJavaScriptAccept;
148 else if (_str.toLower() == QLatin1String("reject"))
149 ret = KJavaScriptReject;
151 return ret;
154 const char* KHTMLSettings::adviceToStr(KJavaScriptAdvice _advice)
156 switch( _advice ) {
157 case KJavaScriptAccept: return I18N_NOOP("Accept");
158 case KJavaScriptReject: return I18N_NOOP("Reject");
159 default: return 0;
161 return 0;
165 void KHTMLSettings::splitDomainAdvice(const QString& configStr, QString &domain,
166 KJavaScriptAdvice &javaAdvice, KJavaScriptAdvice& javaScriptAdvice)
168 QString tmp(configStr);
169 int splitIndex = tmp.indexOf(':');
170 if ( splitIndex == -1)
172 domain = configStr.toLower();
173 javaAdvice = KJavaScriptDunno;
174 javaScriptAdvice = KJavaScriptDunno;
176 else
178 domain = tmp.left(splitIndex).toLower();
179 QString adviceString = tmp.mid( splitIndex+1, tmp.length() );
180 int splitIndex2 = adviceString.indexOf( ':' );
181 if( splitIndex2 == -1 ) {
182 // Java advice only
183 javaAdvice = strToAdvice( adviceString );
184 javaScriptAdvice = KJavaScriptDunno;
185 } else {
186 // Java and JavaScript advice
187 javaAdvice = strToAdvice( adviceString.left( splitIndex2 ) );
188 javaScriptAdvice = strToAdvice( adviceString.mid( splitIndex2+1,
189 adviceString.length() ) );
194 void KHTMLSettings::readDomainSettings(const KConfigGroup &config, bool reset,
195 bool global, KPerDomainSettings &pd_settings) {
196 QString jsPrefix = global ? QString()
197 : QString::fromLatin1("javascript.");
198 QString javaPrefix = global ? QString()
199 : QString::fromLatin1("java.");
200 QString pluginsPrefix = global ? QString()
201 : QString::fromLatin1("plugins.");
203 // The setting for Java
204 QString key = javaPrefix + QLatin1String("EnableJava");
205 if ( (global && reset) || config.hasKey( key ) )
206 pd_settings.m_bEnableJava = config.readEntry( key, false );
207 else if ( !global )
208 pd_settings.m_bEnableJava = d->global.m_bEnableJava;
210 // The setting for Plugins
211 key = pluginsPrefix + QLatin1String("EnablePlugins");
212 if ( (global && reset) || config.hasKey( key ) )
213 pd_settings.m_bEnablePlugins = config.readEntry( key, true );
214 else if ( !global )
215 pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins;
217 // The setting for JavaScript
218 key = jsPrefix + QLatin1String("EnableJavaScript");
219 if ( (global && reset) || config.hasKey( key ) )
220 pd_settings.m_bEnableJavaScript = config.readEntry( key, true );
221 else if ( !global )
222 pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript;
224 // window property policies
225 key = jsPrefix + QLatin1String("WindowOpenPolicy");
226 if ( (global && reset) || config.hasKey( key ) )
227 pd_settings.m_windowOpenPolicy = (KJSWindowOpenPolicy)
228 config.readEntry( key, uint(KJSWindowOpenSmart) );
229 else if ( !global )
230 pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy;
232 key = jsPrefix + QLatin1String("WindowMovePolicy");
233 if ( (global && reset) || config.hasKey( key ) )
234 pd_settings.m_windowMovePolicy = (KJSWindowMovePolicy)
235 config.readEntry( key, uint(KJSWindowMoveAllow) );
236 else if ( !global )
237 pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy;
239 key = jsPrefix + QLatin1String("WindowResizePolicy");
240 if ( (global && reset) || config.hasKey( key ) )
241 pd_settings.m_windowResizePolicy = (KJSWindowResizePolicy)
242 config.readEntry( key, uint(KJSWindowResizeAllow) );
243 else if ( !global )
244 pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy;
246 key = jsPrefix + QLatin1String("WindowStatusPolicy");
247 if ( (global && reset) || config.hasKey( key ) )
248 pd_settings.m_windowStatusPolicy = (KJSWindowStatusPolicy)
249 config.readEntry( key, uint(KJSWindowStatusAllow) );
250 else if ( !global )
251 pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy;
253 key = jsPrefix + QLatin1String("WindowFocusPolicy");
254 if ( (global && reset) || config.hasKey( key ) )
255 pd_settings.m_windowFocusPolicy = (KJSWindowFocusPolicy)
256 config.readEntry( key, uint(KJSWindowFocusAllow) );
257 else if ( !global )
258 pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy;
263 KHTMLSettings::KHTMLSettings()
264 :d (new KHTMLSettingsPrivate())
266 init();
269 KHTMLSettings::KHTMLSettings(const KHTMLSettings &other)
270 :d(new KHTMLSettingsPrivate())
272 *d = *other.d;
275 KHTMLSettings::~KHTMLSettings()
277 delete d;
280 bool KHTMLSettings::changeCursor() const
282 return d->m_bChangeCursor;
285 bool KHTMLSettings::underlineLink() const
287 return d->m_underlineLink;
290 bool KHTMLSettings::hoverLink() const
292 return d->m_hoverLink;
295 void KHTMLSettings::init()
297 KConfig global( "khtmlrc", KConfig::NoGlobals );
298 init( &global, true );
300 KSharedConfig::Ptr local = KGlobal::config();
301 if ( !local )
302 return;
304 init( local.data(), false );
307 void KHTMLSettings::init( KConfig * config, bool reset )
309 KConfigGroup cg( config, "MainView Settings" );
310 if (reset || cg.exists() )
312 if ( reset || cg.hasKey( "OpenMiddleClick" ) )
313 d->m_bOpenMiddleClick = cg.readEntry( "OpenMiddleClick", true );
315 if ( reset || cg.hasKey( "BackRightClick" ) )
316 d->m_bBackRightClick = cg.readEntry( "BackRightClick", false );
319 KConfigGroup cgAccess(config,"Access Keys" );
320 if (reset || cgAccess.exists() ) {
321 d->m_accessKeysEnabled = cgAccess.readEntry( "Enabled", true );
324 KConfigGroup cgFilter( config, "Filter Settings" );
326 if (reset || cgFilter.exists() )
328 d->m_adFilterEnabled = cgFilter.readEntry("Enabled", false);
329 d->m_hideAdsEnabled = cgFilter.readEntry("Shrink", false);
331 d->adBlackList.clear();
332 d->adWhiteList.clear();
334 QMap<QString,QString> entryMap = cgFilter.entryMap();
335 QMap<QString,QString>::ConstIterator it;
336 for( it = entryMap.constBegin(); it != entryMap.constEnd(); ++it )
338 QString name = it.key();
339 QString url = it.value();
341 if (name.startsWith("Filter"))
343 if (url.startsWith(QLatin1String("@@")))
344 d->adWhiteList.addFilter(url);
345 else
346 d->adBlackList.addFilter(url);
351 KConfigGroup cgHtml( config, "HTML Settings" );
352 if (reset || cgHtml.exists() )
354 // Fonts and colors
355 if( reset ) {
356 d->defaultFonts = QStringList();
357 d->defaultFonts.append( cgHtml.readEntry( "StandardFont", KGlobalSettings::generalFont().family() ) );
358 d->defaultFonts.append( cgHtml.readEntry( "FixedFont", KGlobalSettings::fixedFont().family() ) );
359 d->defaultFonts.append( cgHtml.readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) );
360 d->defaultFonts.append( cgHtml.readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) );
361 d->defaultFonts.append( cgHtml.readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) );
362 d->defaultFonts.append( cgHtml.readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) );
363 d->defaultFonts.append( QString( "0" ) ); // font size adjustment
366 if ( reset || cgHtml.hasKey( "MinimumFontSize" ) )
367 d->m_minFontSize = cgHtml.readEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE );
369 if ( reset || cgHtml.hasKey( "MediumFontSize" ) )
370 d->m_fontSize = cgHtml.readEntry( "MediumFontSize", 12 );
372 d->fonts = cgHtml.readEntry( "Fonts", QStringList() );
374 if ( reset || cgHtml.hasKey( "DefaultEncoding" ) )
375 d->m_encoding = cgHtml.readEntry( "DefaultEncoding", "" );
377 if ( reset || cgHtml.hasKey( "EnforceDefaultCharset" ) )
378 d->enforceCharset = cgHtml.readEntry( "EnforceDefaultCharset", false );
380 // Behavior
381 if ( reset || cgHtml.hasKey( "ChangeCursor" ) )
382 d->m_bChangeCursor = cgHtml.readEntry( "ChangeCursor", KDE_DEFAULT_CHANGECURSOR );
384 if ( reset || cgHtml.hasKey("UnderlineLinks") )
385 d->m_underlineLink = cgHtml.readEntry( "UnderlineLinks", true );
387 if ( reset || cgHtml.hasKey( "HoverLinks" ) )
389 if ( (d->m_hoverLink = cgHtml.readEntry( "HoverLinks", false )))
390 d->m_underlineLink = false;
393 if ( reset || cgHtml.hasKey( "AllowTabulation" ) )
394 d->m_allowTabulation = cgHtml.readEntry( "AllowTabulation", false );
396 if ( reset || cgHtml.hasKey( "AutoSpellCheck" ) )
397 d->m_autoSpellCheck = cgHtml.readEntry( "AutoSpellCheck", true );
399 // Other
400 if ( reset || cgHtml.hasKey( "AutoLoadImages" ) )
401 d->m_bAutoLoadImages = cgHtml.readEntry( "AutoLoadImages", true );
403 if ( reset || cgHtml.hasKey( "UnfinishedImageFrame" ) )
404 d->m_bUnfinishedImageFrame = cgHtml.readEntry( "UnfinishedImageFrame", true );
406 if ( reset || cgHtml.hasKey( "ShowAnimations" ) )
408 QString value = cgHtml.readEntry( "ShowAnimations").toLower();
409 if (value == "disabled")
410 d->m_showAnimations = KAnimationDisabled;
411 else if (value == "looponce")
412 d->m_showAnimations = KAnimationLoopOnce;
413 else
414 d->m_showAnimations = KAnimationEnabled;
417 if ( reset || cgHtml.hasKey( "SmoothScrolling" ) )
419 QString value = cgHtml.readEntry( "SmoothScrolling", "whenefficient" ).toLower();
420 if (value == "disabled")
421 d->m_smoothScrolling = KSmoothScrollingDisabled;
422 else if (value == "whenefficient")
423 d->m_smoothScrolling = KSmoothScrollingWhenEfficient;
424 else
425 d->m_smoothScrolling = KSmoothScrollingEnabled;
428 if ( reset || cgHtml.hasKey( "DNSPrefetch" ) )
430 // Enabled, Disabled, OnlyWWWAndSLD
431 QString value = cgHtml.readEntry( "DNSPrefetch", "Enabled" ).toLower();
432 if (value == "enabled")
433 d->m_dnsPrefetch = KDNSPrefetchEnabled;
434 else if (value == "onlywwwandsld")
435 d->m_dnsPrefetch = KDNSPrefetchOnlyWWWAndSLD;
436 else
437 d->m_dnsPrefetch = KDNSPrefetchDisabled;
440 if ( cgHtml.readEntry( "UserStyleSheetEnabled", false ) == true ) {
441 if ( reset || cgHtml.hasKey( "UserStyleSheet" ) )
442 d->m_userSheet = cgHtml.readEntry( "UserStyleSheet", "" );
445 d->m_formCompletionEnabled = cgHtml.readEntry("FormCompletion", true);
446 d->m_maxFormCompletionItems = cgHtml.readEntry("MaxFormCompletionItems", 10);
447 d->m_autoDelayedActionsEnabled = cgHtml.readEntry ("AutoDelayedActions", true);
448 d->m_jsErrorsEnabled = cgHtml.readEntry("ReportJSErrors", true);
449 const QStringList accesskeys = cgHtml.readEntry("FallbackAccessKeysAssignments", QStringList());
450 d->m_fallbackAccessKeysAssignments.clear();
451 for( QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it )
452 if( (*it).length() > 2 && (*it)[ 1 ] == ':' )
453 d->m_fallbackAccessKeysAssignments.append( qMakePair( (*it).mid( 2 ), (*it)[ 0 ] ));
456 // Colors
457 //In which group ?????
458 if ( reset || cg.hasKey( "FollowSystemColors" ) )
459 d->m_follow_system_colors = cg.readEntry( "FollowSystemColors", false );
461 KConfigGroup cgGeneral( config, "General" );
462 if ( reset || cgGeneral.exists( ) )
464 if ( reset || cgGeneral.hasKey( "foreground" ) ) {
465 QColor def(HTML_DEFAULT_TXT_COLOR);
466 d->m_textColor = cgGeneral.readEntry( "foreground", def );
469 if ( reset || cgGeneral.hasKey( "linkColor" ) ) {
470 QColor def(HTML_DEFAULT_LNK_COLOR);
471 d->m_linkColor = cgGeneral.readEntry( "linkColor", def );
474 if ( reset || cgGeneral.hasKey( "visitedLinkColor" ) ) {
475 QColor def(HTML_DEFAULT_VLNK_COLOR);
476 d->m_vLinkColor = cgGeneral.readEntry( "visitedLinkColor", def);
479 if ( reset || cgGeneral.hasKey( "background" ) ) {
480 QColor def(HTML_DEFAULT_BASE_COLOR);
481 d->m_baseColor = cgGeneral.readEntry( "background", def);
485 KConfigGroup cgJava( config, "Java/JavaScript Settings" );
486 if( reset || cgJava.exists() )
488 // The global setting for JavaScript debugging
489 // This is currently always enabled by default
490 if ( reset || cgJava.hasKey( "EnableJavaScriptDebug" ) )
491 d->m_bEnableJavaScriptDebug = cgJava.readEntry( "EnableJavaScriptDebug", false );
493 // The global setting for JavaScript error reporting
494 if ( reset || cgJava.hasKey( "ReportJavaScriptErrors" ) )
495 d->m_bEnableJavaScriptErrorReporting = cgJava.readEntry( "ReportJavaScriptErrors", false );
497 // The global setting for popup block passive popup
498 if ( reset || cgJava.hasKey( "PopupBlockerPassivePopup" ) )
499 d->m_jsPopupBlockerPassivePopup = cgJava.readEntry("PopupBlockerPassivePopup", true );
501 // Read options from the global "domain"
502 readDomainSettings(cgJava,reset,true,d->global);
503 #ifdef DEBUG_SETTINGS
504 d->global.dump("init global");
505 #endif
507 // The domain-specific settings.
509 static const char *const domain_keys[] = { // always keep order of keys
510 "ECMADomains", "JavaDomains", "PluginDomains"
512 bool check_old_ecma_settings = true;
513 bool check_old_java_settings = true;
514 // merge all domains into one list
515 QMap<QString,int> domainList; // why can't Qt have a QSet?
516 for (unsigned i = 0; i < sizeof domain_keys/sizeof domain_keys[0]; ++i) {
517 if ( reset || cgJava.hasKey(domain_keys[i]) ) {
518 if (i == 0) check_old_ecma_settings = false;
519 else if (i == 1) check_old_java_settings = false;
520 const QStringList dl = cgJava.readEntry( domain_keys[i], QStringList() );
521 const QMap<QString,int>::Iterator notfound = domainList.end();
522 QStringList::ConstIterator it = dl.begin();
523 const QStringList::ConstIterator itEnd = dl.end();
524 for (; it != itEnd; ++it) {
525 const QString domain = (*it).toLower();
526 QMap<QString,int>::Iterator pos = domainList.find(domain);
527 if (pos == notfound) domainList.insert(domain,0);
528 }/*next it*/
530 }/*next i*/
532 if (reset)
533 d->domainPolicy.clear();
536 QMap<QString,int>::ConstIterator it = domainList.constBegin();
537 const QMap<QString,int>::ConstIterator itEnd = domainList.constEnd();
538 for ( ; it != itEnd; ++it)
540 const QString domain = it.key();
541 KConfigGroup cg( config, domain );
542 readDomainSettings(cg,reset,false,d->domainPolicy[domain]);
543 #ifdef DEBUG_SETTINGS
544 d->domainPolicy[domain].dump("init "+domain);
545 #endif
549 bool check_old_java = true;
550 if( ( reset || cgJava.hasKey( "JavaDomainSettings" ) )
551 && check_old_java_settings )
553 check_old_java = false;
554 const QStringList domainList = cgJava.readEntry( "JavaDomainSettings", QStringList() );
555 QStringList::ConstIterator it = domainList.constBegin();
556 const QStringList::ConstIterator itEnd = domainList.constEnd();
557 for ( ; it != itEnd; ++it)
559 QString domain;
560 KJavaScriptAdvice javaAdvice;
561 KJavaScriptAdvice javaScriptAdvice;
562 splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
563 setup_per_domain_policy(d,domain).m_bEnableJava =
564 javaAdvice == KJavaScriptAccept;
565 #ifdef DEBUG_SETTINGS
566 setup_per_domain_policy(d,domain).dump("JavaDomainSettings 4 "+domain);
567 #endif
571 bool check_old_ecma = true;
572 if( ( reset || cgJava.hasKey( "ECMADomainSettings" ) )
573 && check_old_ecma_settings )
575 check_old_ecma = false;
576 const QStringList domainList = cgJava.readEntry( "ECMADomainSettings", QStringList() );
577 QStringList::ConstIterator it = domainList.constBegin();
578 const QStringList::ConstIterator itEnd = domainList.constEnd();
579 for ( ; it != itEnd; ++it)
581 QString domain;
582 KJavaScriptAdvice javaAdvice;
583 KJavaScriptAdvice javaScriptAdvice;
584 splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
585 setup_per_domain_policy(d,domain).m_bEnableJavaScript =
586 javaScriptAdvice == KJavaScriptAccept;
587 #ifdef DEBUG_SETTINGS
588 setup_per_domain_policy(d,domain).dump("ECMADomainSettings 4 "+domain);
589 #endif
593 if( ( reset || cgJava.hasKey( "JavaScriptDomainAdvice" ) )
594 && ( check_old_java || check_old_ecma )
595 && ( check_old_ecma_settings || check_old_java_settings ) )
597 const QStringList domainList = cgJava.readEntry( "JavaScriptDomainAdvice", QStringList() );
598 QStringList::ConstIterator it = domainList.constBegin();
599 const QStringList::ConstIterator itEnd = domainList.constEnd();
600 for ( ; it != itEnd; ++it)
602 QString domain;
603 KJavaScriptAdvice javaAdvice;
604 KJavaScriptAdvice javaScriptAdvice;
605 splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
606 if( check_old_java )
607 setup_per_domain_policy(d,domain).m_bEnableJava =
608 javaAdvice == KJavaScriptAccept;
609 if( check_old_ecma )
610 setup_per_domain_policy(d,domain).m_bEnableJavaScript =
611 javaScriptAdvice == KJavaScriptAccept;
612 #ifdef DEBUG_SETTINGS
613 setup_per_domain_policy(d,domain).dump("JavaScriptDomainAdvice 4 "+domain);
614 #endif
617 //save all the settings into the new keywords if they don't exist
618 #if 0
619 if( check_old_java )
621 QStringList domainConfig;
622 PolicyMap::Iterator it;
623 for( it = d->javaDomainPolicy.begin(); it != d->javaDomainPolicy.end(); ++it )
625 QByteArray javaPolicy = adviceToStr( it.value() );
626 QByteArray javaScriptPolicy = adviceToStr( KJavaScriptDunno );
627 domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
629 cg.writeEntry( "JavaDomainSettings", domainConfig );
632 if( check_old_ecma )
634 QStringList domainConfig;
635 PolicyMap::Iterator it;
636 for( it = d->javaScriptDomainPolicy.begin(); it != d->javaScriptDomainPolicy.end(); ++it )
638 QByteArray javaPolicy = adviceToStr( KJavaScriptDunno );
639 QByteArray javaScriptPolicy = adviceToStr( it.value() );
640 domainConfig.append(QString::fromLatin1("%1:%2:%3").arg(it.key()).arg(javaPolicy).arg(javaScriptPolicy));
642 cg.writeEntry( "ECMADomainSettings", domainConfig );
644 #endif
650 /** Local helper for retrieving per-domain settings.
652 * In case of doubt, the global domain is returned.
654 static const KPerDomainSettings &lookup_hostname_policy(
655 const KHTMLSettingsPrivate* const d,
656 const QString& hostname)
658 #ifdef DEBUG_SETTINGS
659 kDebug() << "lookup_hostname_policy(" << hostname << ")";
660 #endif
661 if (hostname.isEmpty()) {
662 #ifdef DEBUG_SETTINGS
663 d->global.dump("global");
664 #endif
665 return d->global;
668 const PolicyMap::const_iterator notfound = d->domainPolicy.constEnd();
670 // First check whether there is a perfect match.
671 PolicyMap::const_iterator it = d->domainPolicy.find(hostname);
672 if( it != notfound ) {
673 #ifdef DEBUG_SETTINGS
674 kDebug() << "perfect match";
675 (*it).dump(hostname);
676 #endif
677 // yes, use it (unless dunno)
678 return *it;
681 // Now, check for partial match. Chop host from the left until
682 // there's no dots left.
683 QString host_part = hostname;
684 int dot_idx = -1;
685 while( (dot_idx = host_part.indexOf(QChar('.'))) >= 0 ) {
686 host_part.remove(0,dot_idx);
687 it = d->domainPolicy.find(host_part);
688 Q_ASSERT(notfound == d->domainPolicy.end());
689 if( it != notfound ) {
690 #ifdef DEBUG_SETTINGS
691 kDebug() << "partial match";
692 (*it).dump(host_part);
693 #endif
694 return *it;
696 // assert(host_part[0] == QChar('.'));
697 host_part.remove(0,1); // Chop off the dot.
700 // No domain-specific entry: use global domain
701 #ifdef DEBUG_SETTINGS
702 kDebug() << "no match";
703 d->global.dump("global");
704 #endif
705 return d->global;
708 bool KHTMLSettings::isOpenMiddleClickEnabled()
710 return d->m_bOpenMiddleClick;
713 bool KHTMLSettings::isBackRightClickEnabled()
715 return d->m_bBackRightClick;
718 bool KHTMLSettings::accessKeysEnabled() const
720 return d->m_accessKeysEnabled;
723 bool KHTMLSettings::isAdFilterEnabled() const
725 return d->m_adFilterEnabled;
728 bool KHTMLSettings::isHideAdsEnabled() const
730 return d->m_hideAdsEnabled;
733 bool KHTMLSettings::isAdFiltered( const QString &url ) const
735 if (d->m_adFilterEnabled)
737 if (!url.startsWith("data:"))
739 // Check the blacklist, and only if that matches, the whitelist
740 return d->adBlackList.isUrlMatched(url) && !d->adWhiteList.isUrlMatched(url);
743 return false;
746 void KHTMLSettings::addAdFilter( const QString &url )
748 KConfigGroup config = KSharedConfig::openConfig( "khtmlrc", KConfig::NoGlobals )->group( "Filter Settings" );
750 QRegExp rx;
752 // Try compiling to avoid invalid stuff. Only support the basic syntax here...
753 // ### refactor somewhat
754 if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/')
756 QString inside = url.mid(1, url.length()-2);
757 rx.setPattern(inside);
759 else
761 rx.setPatternSyntax(QRegExp::Wildcard);
762 rx.setPattern(url);
765 if (rx.isValid())
767 int last=config.readEntry("Count", 0);
768 QString key = "Filter-" + QString::number(last);
769 config.writeEntry(key, url);
770 config.writeEntry("Count",last+1);
771 config.sync();
772 if (url.startsWith(QLatin1String("@@")))
773 d->adWhiteList.addFilter(url);
774 else
775 d->adBlackList.addFilter(url);
777 else
779 KMessageBox::error(0,
780 rx.errorString(),
781 i18n("Filter error"));
785 bool KHTMLSettings::isJavaEnabled( const QString& hostname ) const
787 return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJava;
790 bool KHTMLSettings::isJavaScriptEnabled( const QString& hostname ) const
792 return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJavaScript;
795 bool KHTMLSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ ) const
797 // debug setting is global for now, but could change in the future
798 return d->m_bEnableJavaScriptDebug;
801 bool KHTMLSettings::isJavaScriptErrorReportingEnabled( const QString& /*hostname*/ ) const
803 // error reporting setting is global for now, but could change in the future
804 return d->m_bEnableJavaScriptErrorReporting;
807 bool KHTMLSettings::isPluginsEnabled( const QString& hostname ) const
809 return lookup_hostname_policy(d,hostname.toLower()).m_bEnablePlugins;
812 KHTMLSettings::KJSWindowOpenPolicy KHTMLSettings::windowOpenPolicy(
813 const QString& hostname) const {
814 return lookup_hostname_policy(d,hostname.toLower()).m_windowOpenPolicy;
817 KHTMLSettings::KJSWindowMovePolicy KHTMLSettings::windowMovePolicy(
818 const QString& hostname) const {
819 return lookup_hostname_policy(d,hostname.toLower()).m_windowMovePolicy;
822 KHTMLSettings::KJSWindowResizePolicy KHTMLSettings::windowResizePolicy(
823 const QString& hostname) const {
824 return lookup_hostname_policy(d,hostname.toLower()).m_windowResizePolicy;
827 KHTMLSettings::KJSWindowStatusPolicy KHTMLSettings::windowStatusPolicy(
828 const QString& hostname) const {
829 return lookup_hostname_policy(d,hostname.toLower()).m_windowStatusPolicy;
832 KHTMLSettings::KJSWindowFocusPolicy KHTMLSettings::windowFocusPolicy(
833 const QString& hostname) const {
834 return lookup_hostname_policy(d,hostname.toLower()).m_windowFocusPolicy;
837 int KHTMLSettings::mediumFontSize() const
839 return d->m_fontSize;
842 int KHTMLSettings::minFontSize() const
844 return d->m_minFontSize;
847 QString KHTMLSettings::settingsToCSS() const
849 // lets start with the link properties
850 QString str = "a:link {\ncolor: ";
851 str += d->m_linkColor.name();
852 str += ';';
853 if(d->m_underlineLink)
854 str += "\ntext-decoration: underline;";
856 if( d->m_bChangeCursor )
858 str += "\ncursor: pointer;";
859 str += "\n}\ninput[type=image] { cursor: pointer;";
861 str += "\n}\n";
862 str += "a:visited {\ncolor: ";
863 str += d->m_vLinkColor.name();
864 str += ';';
865 if(d->m_underlineLink)
866 str += "\ntext-decoration: underline;";
868 if( d->m_bChangeCursor )
869 str += "\ncursor: pointer;";
870 str += "\n}\n";
872 if(d->m_hoverLink)
873 str += "a:link:hover, a:visited:hover { text-decoration: underline; }\n";
875 return str;
878 const QString &KHTMLSettings::availableFamilies()
880 if ( !avFamilies ) {
881 avFamilies = new QString;
882 QFontDatabase db;
883 QStringList families = db.families();
884 QStringList s;
885 QRegExp foundryExp(" \\[.+\\]");
887 //remove foundry info
888 QStringList::Iterator f = families.begin();
889 const QStringList::Iterator fEnd = families.end();
891 for ( ; f != fEnd; ++f ) {
892 (*f).replace( foundryExp, "");
893 if (!s.contains(*f))
894 s << *f;
896 s.sort();
898 *avFamilies = ',' + s.join(",") + ',';
901 return *avFamilies;
904 QString KHTMLSettings::lookupFont(int i) const
906 QString font;
907 if (d->fonts.count() > i)
908 font = d->fonts[i];
909 if (font.isEmpty())
910 font = d->defaultFonts[i];
911 return font;
914 QString KHTMLSettings::stdFontName() const
916 return lookupFont(0);
919 QString KHTMLSettings::fixedFontName() const
921 return lookupFont(1);
924 QString KHTMLSettings::serifFontName() const
926 return lookupFont(2);
929 QString KHTMLSettings::sansSerifFontName() const
931 return lookupFont(3);
934 QString KHTMLSettings::cursiveFontName() const
936 return lookupFont(4);
939 QString KHTMLSettings::fantasyFontName() const
941 return lookupFont(5);
944 void KHTMLSettings::setStdFontName(const QString &n)
946 while(d->fonts.count() <= 0)
947 d->fonts.append(QString());
948 d->fonts[0] = n;
951 void KHTMLSettings::setFixedFontName(const QString &n)
953 while(d->fonts.count() <= 1)
954 d->fonts.append(QString());
955 d->fonts[1] = n;
958 QString KHTMLSettings::userStyleSheet() const
960 return d->m_userSheet;
963 bool KHTMLSettings::isFormCompletionEnabled() const
965 return d->m_formCompletionEnabled;
968 int KHTMLSettings::maxFormCompletionItems() const
970 return d->m_maxFormCompletionItems;
973 const QString &KHTMLSettings::encoding() const
975 return d->m_encoding;
978 bool KHTMLSettings::followSystemColors() const
980 return d->m_follow_system_colors;
983 const QColor& KHTMLSettings::textColor() const
985 return d->m_textColor;
988 const QColor& KHTMLSettings::baseColor() const
990 return d->m_baseColor;
993 const QColor& KHTMLSettings::linkColor() const
995 return d->m_linkColor;
998 const QColor& KHTMLSettings::vLinkColor() const
1000 return d->m_vLinkColor;
1003 bool KHTMLSettings::autoLoadImages() const
1005 return d->m_bAutoLoadImages;
1008 bool KHTMLSettings::unfinishedImageFrame() const
1010 return d->m_bUnfinishedImageFrame;
1013 KHTMLSettings::KAnimationAdvice KHTMLSettings::showAnimations() const
1015 return d->m_showAnimations;
1018 KHTMLSettings::KSmoothScrollingMode KHTMLSettings::smoothScrolling() const
1020 return d->m_smoothScrolling;
1023 KHTMLSettings::KDNSPrefetch KHTMLSettings::dnsPrefetch() const
1025 return d->m_dnsPrefetch;
1028 bool KHTMLSettings::isAutoDelayedActionsEnabled() const
1030 return d->m_autoDelayedActionsEnabled;
1033 bool KHTMLSettings::jsErrorsEnabled() const
1035 return d->m_jsErrorsEnabled;
1038 void KHTMLSettings::setJSErrorsEnabled(bool enabled)
1040 d->m_jsErrorsEnabled = enabled;
1041 // save it
1042 KConfigGroup cg( KGlobal::config(), "HTML Settings");
1043 cg.writeEntry("ReportJSErrors", enabled);
1044 cg.sync();
1047 bool KHTMLSettings::allowTabulation() const
1049 return d->m_allowTabulation;
1052 bool KHTMLSettings::autoSpellCheck() const
1054 return d->m_autoSpellCheck;
1057 QList< QPair< QString, QChar > > KHTMLSettings::fallbackAccessKeysAssignments() const
1059 return d->m_fallbackAccessKeysAssignments;
1062 void KHTMLSettings::setJSPopupBlockerPassivePopup(bool enabled)
1064 d->m_jsPopupBlockerPassivePopup = enabled;
1065 // save it
1066 KConfigGroup cg( KGlobal::config(), "Java/JavaScript Settings");
1067 cg.writeEntry("PopupBlockerPassivePopup", enabled);
1068 cg.sync();
1071 bool KHTMLSettings::jsPopupBlockerPassivePopup() const
1073 return d->m_jsPopupBlockerPassivePopup;