1/*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebKit.h"
28#include "WebKitDLL.h"
29#include "WebPreferences.h"
30
31#include "WebNotificationCenter.h"
32#include "WebPreferenceKeysPrivate.h"
33
34#include <CoreFoundation/CoreFoundation.h>
35#include <WebCore/CACFLayerTreeHost.h>
36#include <WebCore/COMPtr.h>
37#include <WebCore/FileSystem.h>
38#include <WebCore/Font.h>
39#include <WebCore/LocalizedStrings.h>
40#include <limits>
41#include <shlobj.h>
42#include <wchar.h>
43#include <wtf/HashMap.h>
44#include <wtf/OwnArrayPtr.h>
45#include <wtf/text/CString.h>
46#include <wtf/text/StringHash.h>
47#include <wtf/text/WTFString.h>
48
49#if USE(CG)
50#include <CoreGraphics/CoreGraphics.h>
51#include <WebKitSystemInterface/WebKitSystemInterface.h>
52#endif
53
54using namespace WebCore;
55using std::numeric_limits;
56
57static const String& oldPreferencesPath()
58{
59    static String path = pathByAppendingComponent(roamingUserSpecificStorageDirectory(), "WebKitPreferences.plist");
60    return path;
61}
62
63template<typename NumberType> struct CFNumberTraits { static const unsigned Type; };
64template<> struct CFNumberTraits<int> { static const unsigned Type = kCFNumberSInt32Type; };
65template<> struct CFNumberTraits<LONGLONG> { static const unsigned Type = kCFNumberLongLongType; };
66template<> struct CFNumberTraits<float> { static const unsigned Type = kCFNumberFloat32Type; };
67
68template<typename NumberType>
69static NumberType numberValueForPreferencesValue(CFPropertyListRef value)
70{
71    if (!value)
72        return 0;
73
74    CFTypeID cfType = CFGetTypeID(value);
75    if (cfType == CFStringGetTypeID())
76        return static_cast<NumberType>(CFStringGetIntValue(static_cast<CFStringRef>(value)));
77    else if (cfType == CFBooleanGetTypeID()) {
78        Boolean boolVal = CFBooleanGetValue(static_cast<CFBooleanRef>(value));
79        return boolVal ? 1 : 0;
80    } else if (cfType == CFNumberGetTypeID()) {
81        NumberType val = 0;
82        CFNumberGetValue(static_cast<CFNumberRef>(value), CFNumberTraits<NumberType>::Type, &val);
83        return val;
84    }
85
86    return 0;
87}
88
89template<typename NumberType>
90static RetainPtr<CFNumberRef> cfNumber(NumberType value)
91{
92    return RetainPtr<CFNumberRef>(AdoptCF, CFNumberCreate(0, CFNumberTraits<NumberType>::Type, &value));
93}
94
95static bool booleanValueForPreferencesValue(CFPropertyListRef value)
96{
97    return numberValueForPreferencesValue<int>(value);
98}
99
100// WebPreferences ----------------------------------------------------------------
101
102static CFDictionaryRef defaultSettings;
103
104static HashMap<WTF::String, COMPtr<WebPreferences> > webPreferencesInstances;
105
106WebPreferences* WebPreferences::sharedStandardPreferences()
107{
108    static WebPreferences* standardPreferences;
109    if (!standardPreferences) {
110        standardPreferences = WebPreferences::createInstance();
111        standardPreferences->setAutosaves(TRUE);
112        standardPreferences->load();
113    }
114
115    return standardPreferences;
116}
117
118WebPreferences::WebPreferences()
119    : m_refCount(0)
120    , m_autoSaves(0)
121    , m_automaticallyDetectsCacheModel(true)
122    , m_numWebViews(0)
123{
124    gClassCount++;
125    gClassNameCount.add("WebPreferences");
126}
127
128WebPreferences::~WebPreferences()
129{
130    gClassCount--;
131    gClassNameCount.remove("WebPreferences");
132}
133
134WebPreferences* WebPreferences::createInstance()
135{
136    WebPreferences* instance = new WebPreferences();
137    instance->AddRef();
138    return instance;
139}
140
141HRESULT WebPreferences::postPreferencesChangesNotification()
142{
143    IWebNotificationCenter* nc = WebNotificationCenter::defaultCenterInternal();
144    HRESULT hr = nc->postNotificationName(webPreferencesChangedNotification(), static_cast<IWebPreferences*>(this), 0);
145    if (FAILED(hr))
146        return hr;
147
148    return S_OK;
149}
150
151WebPreferences* WebPreferences::getInstanceForIdentifier(BSTR identifier)
152{
153    if (!identifier)
154        return sharedStandardPreferences();
155
156    WTF::String identifierString(identifier, SysStringLen(identifier));
157    return webPreferencesInstances.get(identifierString).get();
158}
159
160void WebPreferences::setInstance(WebPreferences* instance, BSTR identifier)
161{
162    if (!identifier || !instance)
163        return;
164    WTF::String identifierString(identifier, SysStringLen(identifier));
165    webPreferencesInstances.add(identifierString, instance);
166}
167
168void WebPreferences::removeReferenceForIdentifier(BSTR identifier)
169{
170    if (!identifier || webPreferencesInstances.isEmpty())
171        return;
172
173    WTF::String identifierString(identifier, SysStringLen(identifier));
174    WebPreferences* webPreference = webPreferencesInstances.get(identifierString).get();
175    if (webPreference && webPreference->m_refCount == 1)
176        webPreferencesInstances.remove(identifierString);
177}
178
179void WebPreferences::initializeDefaultSettings()
180{
181    if (defaultSettings)
182        return;
183
184    CFMutableDictionaryRef defaults = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
185
186    CFDictionaryAddValue(defaults, CFSTR(WebKitStandardFontPreferenceKey), CFSTR("Times New Roman"));
187    CFDictionaryAddValue(defaults, CFSTR(WebKitFixedFontPreferenceKey), CFSTR("Courier New"));
188    CFDictionaryAddValue(defaults, CFSTR(WebKitSerifFontPreferenceKey), CFSTR("Times New Roman"));
189    CFDictionaryAddValue(defaults, CFSTR(WebKitSansSerifFontPreferenceKey), CFSTR("Arial"));
190    CFDictionaryAddValue(defaults, CFSTR(WebKitCursiveFontPreferenceKey), CFSTR("Comic Sans MS"));
191    CFDictionaryAddValue(defaults, CFSTR(WebKitFantasyFontPreferenceKey), CFSTR("Comic Sans MS"));
192    CFDictionaryAddValue(defaults, CFSTR(WebKitMinimumFontSizePreferenceKey), CFSTR("0"));
193    CFDictionaryAddValue(defaults, CFSTR(WebKitMinimumLogicalFontSizePreferenceKey), CFSTR("9"));
194    CFDictionaryAddValue(defaults, CFSTR(WebKitDefaultFontSizePreferenceKey), CFSTR("16"));
195    CFDictionaryAddValue(defaults, CFSTR(WebKitDefaultFixedFontSizePreferenceKey), CFSTR("13"));
196
197    String defaultDefaultEncoding(WEB_UI_STRING("ISO-8859-1", "The default, default character encoding"));
198    CFDictionaryAddValue(defaults, CFSTR(WebKitDefaultTextEncodingNamePreferenceKey), defaultDefaultEncoding.createCFString());
199
200    CFDictionaryAddValue(defaults, CFSTR(WebKitUserStyleSheetEnabledPreferenceKey), kCFBooleanFalse);
201    CFDictionaryAddValue(defaults, CFSTR(WebKitUserStyleSheetLocationPreferenceKey), CFSTR(""));
202    CFDictionaryAddValue(defaults, CFSTR(WebKitShouldPrintBackgroundsPreferenceKey), kCFBooleanFalse);
203    CFDictionaryAddValue(defaults, CFSTR(WebKitTextAreasAreResizablePreferenceKey), kCFBooleanFalse);
204    CFDictionaryAddValue(defaults, CFSTR(WebKitJavaEnabledPreferenceKey), kCFBooleanTrue);
205    CFDictionaryAddValue(defaults, CFSTR(WebKitJavaScriptEnabledPreferenceKey), kCFBooleanTrue);
206    CFDictionaryAddValue(defaults, CFSTR(WebKitWebSecurityEnabledPreferenceKey), kCFBooleanTrue);
207    CFDictionaryAddValue(defaults, CFSTR(WebKitAllowUniversalAccessFromFileURLsPreferenceKey), kCFBooleanFalse);
208    CFDictionaryAddValue(defaults, CFSTR(WebKitAllowFileAccessFromFileURLsPreferenceKey), kCFBooleanTrue);
209    CFDictionaryAddValue(defaults, CFSTR(WebKitJavaScriptCanAccessClipboardPreferenceKey), kCFBooleanFalse);
210    CFDictionaryAddValue(defaults, CFSTR(WebKitXSSAuditorEnabledPreferenceKey), kCFBooleanTrue);
211    CFDictionaryAddValue(defaults, CFSTR(WebKitFrameFlatteningEnabledPreferenceKey), kCFBooleanFalse);
212    CFDictionaryAddValue(defaults, CFSTR(WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey), kCFBooleanTrue);
213    CFDictionaryAddValue(defaults, CFSTR(WebKitPluginsEnabledPreferenceKey), kCFBooleanTrue);
214    CFDictionaryAddValue(defaults, CFSTR(WebKitDatabasesEnabledPreferenceKey), kCFBooleanTrue);
215    CFDictionaryAddValue(defaults, CFSTR(WebKitLocalStorageEnabledPreferenceKey), kCFBooleanTrue);
216    CFDictionaryAddValue(defaults, CFSTR(WebKitExperimentalNotificationsEnabledPreferenceKey), kCFBooleanFalse);
217    CFDictionaryAddValue(defaults, CFSTR(WebKitZoomsTextOnlyPreferenceKey), kCFBooleanTrue);
218    CFDictionaryAddValue(defaults, CFSTR(WebKitAllowAnimatedImagesPreferenceKey), kCFBooleanTrue);
219    CFDictionaryAddValue(defaults, CFSTR(WebKitAllowAnimatedImageLoopingPreferenceKey), kCFBooleanTrue);
220    CFDictionaryAddValue(defaults, CFSTR(WebKitDisplayImagesKey), kCFBooleanTrue);
221    CFDictionaryAddValue(defaults, CFSTR(WebKitLoadSiteIconsKey), kCFBooleanFalse);
222    CFDictionaryAddValue(defaults, CFSTR(WebKitBackForwardCacheExpirationIntervalKey), CFSTR("1800"));
223    CFDictionaryAddValue(defaults, CFSTR(WebKitTabToLinksPreferenceKey), kCFBooleanFalse);
224    CFDictionaryAddValue(defaults, CFSTR(WebKitPrivateBrowsingEnabledPreferenceKey), kCFBooleanFalse);
225    CFDictionaryAddValue(defaults, CFSTR(WebKitRespectStandardStyleKeyEquivalentsPreferenceKey), kCFBooleanFalse);
226    CFDictionaryAddValue(defaults, CFSTR(WebKitShowsURLsInToolTipsPreferenceKey), kCFBooleanFalse);
227    CFDictionaryAddValue(defaults, CFSTR(WebKitPDFDisplayModePreferenceKey), CFSTR("1"));
228    CFDictionaryAddValue(defaults, CFSTR(WebKitPDFScaleFactorPreferenceKey), CFSTR("0"));
229
230    RetainPtr<CFStringRef> linkBehaviorStringRef(AdoptCF, CFStringCreateWithFormat(0, 0, CFSTR("%d"), WebKitEditableLinkDefaultBehavior));
231    CFDictionaryAddValue(defaults, CFSTR(WebKitEditableLinkBehaviorPreferenceKey), linkBehaviorStringRef.get());
232
233    CFDictionaryAddValue(defaults, CFSTR(WebKitHistoryItemLimitKey), CFSTR("1000"));
234    CFDictionaryAddValue(defaults, CFSTR(WebKitHistoryAgeInDaysLimitKey), CFSTR("7"));
235    CFDictionaryAddValue(defaults, CFSTR(WebKitIconDatabaseLocationKey), CFSTR(""));
236    CFDictionaryAddValue(defaults, CFSTR(WebKitIconDatabaseEnabledPreferenceKey), kCFBooleanTrue);
237    CFDictionaryAddValue(defaults, CFSTR(WebKitFontSmoothingTypePreferenceKey), CFSTR("2"));
238    CFDictionaryAddValue(defaults, CFSTR(WebKitFontSmoothingContrastPreferenceKey), CFSTR("2"));
239    CFDictionaryAddValue(defaults, CFSTR(WebKitCookieStorageAcceptPolicyPreferenceKey), CFSTR("2"));
240    CFDictionaryAddValue(defaults, CFSTR(WebContinuousSpellCheckingEnabledPreferenceKey), kCFBooleanFalse);
241    CFDictionaryAddValue(defaults, CFSTR(WebGrammarCheckingEnabledPreferenceKey), kCFBooleanFalse);
242    CFDictionaryAddValue(defaults, CFSTR(AllowContinuousSpellCheckingPreferenceKey), kCFBooleanTrue);
243    CFDictionaryAddValue(defaults, CFSTR(WebKitUsesPageCachePreferenceKey), kCFBooleanTrue);
244    CFDictionaryAddValue(defaults, CFSTR(WebKitLocalStorageDatabasePathPreferenceKey), CFSTR(""));
245
246    RetainPtr<CFStringRef> cacheModelRef(AdoptCF, CFStringCreateWithFormat(0, 0, CFSTR("%d"), WebCacheModelDocumentViewer));
247    CFDictionaryAddValue(defaults, CFSTR(WebKitCacheModelPreferenceKey), cacheModelRef.get());
248
249    CFDictionaryAddValue(defaults, CFSTR(WebKitAuthorAndUserStylesEnabledPreferenceKey), kCFBooleanTrue);
250    CFDictionaryAddValue(defaults, CFSTR(WebKitApplicationChromeModePreferenceKey), kCFBooleanFalse);
251
252    CFDictionaryAddValue(defaults, CFSTR(WebKitOfflineWebApplicationCacheEnabledPreferenceKey), kCFBooleanFalse);
253
254    CFDictionaryAddValue(defaults, CFSTR(WebKitPaintNativeControlsPreferenceKey), kCFBooleanTrue);
255
256    CFDictionaryAddValue(defaults, CFSTR(WebKitUseHighResolutionTimersPreferenceKey), kCFBooleanTrue);
257
258    RetainPtr<CFStringRef> pluginAllowedRunTime(AdoptCF, CFStringCreateWithFormat(0, 0, CFSTR("%u"), numeric_limits<unsigned>::max()));
259    CFDictionaryAddValue(defaults, CFSTR(WebKitPluginAllowedRunTimePreferenceKey), pluginAllowedRunTime.get());
260
261    CFDictionaryAddValue(defaults, CFSTR(WebKitAcceleratedCompositingEnabledPreferenceKey), kCFBooleanFalse);
262
263    CFDictionaryAddValue(defaults, CFSTR(WebKitShowDebugBordersPreferenceKey), kCFBooleanFalse);
264
265    CFDictionaryAddValue(defaults, CFSTR(WebKitDNSPrefetchingEnabledPreferenceKey), kCFBooleanFalse);
266
267    CFDictionaryAddValue(defaults, CFSTR(WebKitMemoryInfoEnabledPreferenceKey), kCFBooleanFalse);
268    CFDictionaryAddValue(defaults, CFSTR(WebKitHyperlinkAuditingEnabledPreferenceKey), kCFBooleanTrue);
269
270    defaultSettings = defaults;
271}
272
273RetainPtr<CFPropertyListRef> WebPreferences::valueForKey(CFStringRef key)
274{
275    RetainPtr<CFPropertyListRef> value = CFDictionaryGetValue(m_privatePrefs.get(), key);
276    if (value)
277        return value;
278
279    value.adoptCF(CFPreferencesCopyAppValue(key, kCFPreferencesCurrentApplication));
280    if (value)
281        return value;
282
283    return CFDictionaryGetValue(defaultSettings, key);
284}
285
286void WebPreferences::setValueForKey(CFStringRef key, CFPropertyListRef value)
287{
288    CFDictionarySetValue(m_privatePrefs.get(), key, value);
289    if (m_autoSaves) {
290        CFPreferencesSetAppValue(key, value, kCFPreferencesCurrentApplication);
291        save();
292    }
293}
294
295BSTR WebPreferences::stringValueForKey(CFStringRef key)
296{
297    RetainPtr<CFPropertyListRef> value = valueForKey(key);
298
299    if (!value || (CFGetTypeID(value.get()) != CFStringGetTypeID()))
300        return 0;
301
302    CFStringRef str = static_cast<CFStringRef>(value.get());
303
304    CFIndex length = CFStringGetLength(str);
305    const UniChar* uniChars = CFStringGetCharactersPtr(str);
306    if (uniChars)
307        return SysAllocStringLen((LPCTSTR)uniChars, length);
308
309    BSTR bstr = SysAllocStringLen(0, length);
310    if (!bstr)
311        return 0;
312
313    if (!CFStringGetCString(str, (char*)bstr, (length+1)*sizeof(WCHAR), kCFStringEncodingUTF16)) {
314        SysFreeString(bstr);
315        return 0;
316    }
317
318    bstr[length] = 0;
319    return bstr;
320}
321
322int WebPreferences::integerValueForKey(CFStringRef key)
323{
324    return numberValueForPreferencesValue<int>(valueForKey(key).get());
325}
326
327BOOL WebPreferences::boolValueForKey(CFStringRef key)
328{
329    return booleanValueForPreferencesValue(valueForKey(key).get());
330}
331
332float WebPreferences::floatValueForKey(CFStringRef key)
333{
334    return numberValueForPreferencesValue<float>(valueForKey(key).get());
335}
336
337LONGLONG WebPreferences::longlongValueForKey(CFStringRef key)
338{
339    return numberValueForPreferencesValue<LONGLONG>(valueForKey(key).get());
340}
341
342void WebPreferences::setStringValue(CFStringRef key, LPCTSTR value)
343{
344    BSTR val = stringValueForKey(key);
345    if (val && !wcscmp(val, value))
346        return;
347    SysFreeString(val);
348
349    RetainPtr<CFStringRef> valueRef(AdoptCF,
350        CFStringCreateWithCharactersNoCopy(0, (UniChar*)_wcsdup(value), (CFIndex)wcslen(value), kCFAllocatorMalloc));
351    setValueForKey(key, valueRef.get());
352
353    postPreferencesChangesNotification();
354}
355
356void WebPreferences::setIntegerValue(CFStringRef key, int value)
357{
358    if (integerValueForKey(key) == value)
359        return;
360
361    setValueForKey(key, cfNumber(value).get());
362
363    postPreferencesChangesNotification();
364}
365
366void WebPreferences::setFloatValue(CFStringRef key, float value)
367{
368    if (floatValueForKey(key) == value)
369        return;
370
371    setValueForKey(key, cfNumber(value).get());
372
373    postPreferencesChangesNotification();
374}
375
376void WebPreferences::setBoolValue(CFStringRef key, BOOL value)
377{
378    if (boolValueForKey(key) == value)
379        return;
380
381    setValueForKey(key, value ? kCFBooleanTrue : kCFBooleanFalse);
382
383    postPreferencesChangesNotification();
384}
385
386void WebPreferences::setLongLongValue(CFStringRef key, LONGLONG value)
387{
388    if (longlongValueForKey(key) == value)
389        return;
390
391    setValueForKey(key, cfNumber(value).get());
392
393    postPreferencesChangesNotification();
394}
395
396BSTR WebPreferences::webPreferencesChangedNotification()
397{
398    static BSTR webPreferencesChangedNotification = SysAllocString(WebPreferencesChangedNotification);
399    return webPreferencesChangedNotification;
400}
401
402BSTR WebPreferences::webPreferencesRemovedNotification()
403{
404    static BSTR webPreferencesRemovedNotification = SysAllocString(WebPreferencesRemovedNotification);
405    return webPreferencesRemovedNotification;
406}
407
408void WebPreferences::save()
409{
410    CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
411}
412
413void WebPreferences::load()
414{
415    initializeDefaultSettings();
416
417    m_privatePrefs.adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
418
419    migrateWebKitPreferencesToCFPreferences();
420}
421
422void WebPreferences::migrateWebKitPreferencesToCFPreferences()
423{
424    CFStringRef didMigrateKey = CFSTR(WebKitDidMigrateWebKitPreferencesToCFPreferencesPreferenceKey);
425    if (boolValueForKey(didMigrateKey))
426        return;
427    bool oldValue = m_autoSaves;
428    m_autoSaves = true;
429    setBoolValue(didMigrateKey, TRUE);
430    m_autoSaves = oldValue;
431
432    WTF::CString path = oldPreferencesPath().utf8();
433
434    RetainPtr<CFURLRef> urlRef(AdoptCF, CFURLCreateFromFileSystemRepresentation(0, reinterpret_cast<const UInt8*>(path.data()), path.length(), false));
435    if (!urlRef)
436        return;
437
438    RetainPtr<CFReadStreamRef> stream(AdoptCF, CFReadStreamCreateWithFile(0, urlRef.get()));
439    if (!stream)
440        return;
441
442    if (!CFReadStreamOpen(stream.get()))
443        return;
444
445    CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0 | kCFPropertyListXMLFormat_v1_0;
446    RetainPtr<CFPropertyListRef> plist(AdoptCF, CFPropertyListCreateFromStream(0, stream.get(), 0, kCFPropertyListMutableContainersAndLeaves, &format, 0));
447    CFReadStreamClose(stream.get());
448
449    if (!plist || CFGetTypeID(plist.get()) != CFDictionaryGetTypeID())
450        return;
451
452    copyWebKitPreferencesToCFPreferences(static_cast<CFDictionaryRef>(plist.get()));
453
454    deleteFile(oldPreferencesPath());
455}
456
457void WebPreferences::copyWebKitPreferencesToCFPreferences(CFDictionaryRef dict)
458{
459    ASSERT_ARG(dict, dict);
460
461    int count = CFDictionaryGetCount(dict);
462    if (count <= 0)
463        return;
464
465    CFStringRef didRemoveDefaultsKey = CFSTR(WebKitDidMigrateDefaultSettingsFromSafari3BetaPreferenceKey);
466    bool omitDefaults = !booleanValueForPreferencesValue(CFDictionaryGetValue(dict, didRemoveDefaultsKey));
467
468    OwnArrayPtr<CFTypeRef> keys = adoptArrayPtr(new CFTypeRef[count]);
469    OwnArrayPtr<CFTypeRef> values = adoptArrayPtr(new CFTypeRef[count]);
470    CFDictionaryGetKeysAndValues(dict, keys.get(), values.get());
471
472    for (int i = 0; i < count; ++i) {
473        if (!keys[i] || !values[i] || CFGetTypeID(keys[i]) != CFStringGetTypeID())
474            continue;
475
476        if (omitDefaults) {
477            CFTypeRef defaultValue = CFDictionaryGetValue(defaultSettings, keys[i]);
478            if (defaultValue && CFEqual(defaultValue, values[i]))
479                continue;
480        }
481
482        setValueForKey(static_cast<CFStringRef>(keys[i]), values[i]);
483    }
484}
485
486// IUnknown -------------------------------------------------------------------
487
488HRESULT STDMETHODCALLTYPE WebPreferences::QueryInterface(REFIID riid, void** ppvObject)
489{
490    *ppvObject = 0;
491    if (IsEqualGUID(riid, IID_IUnknown))
492        *ppvObject = static_cast<IWebPreferences*>(this);
493    else if (IsEqualGUID(riid, IID_IWebPreferences))
494        *ppvObject = static_cast<IWebPreferences*>(this);
495    else if (IsEqualGUID(riid, IID_IWebPreferencesPrivate))
496        *ppvObject = static_cast<IWebPreferencesPrivate*>(this);
497    else if (IsEqualGUID(riid, CLSID_WebPreferences))
498        *ppvObject = this;
499    else
500        return E_NOINTERFACE;
501
502    AddRef();
503    return S_OK;
504}
505
506ULONG STDMETHODCALLTYPE WebPreferences::AddRef(void)
507{
508    return ++m_refCount;
509}
510
511ULONG STDMETHODCALLTYPE WebPreferences::Release(void)
512{
513    ULONG newRef = --m_refCount;
514    if (!newRef)
515        delete(this);
516
517    return newRef;
518}
519
520// IWebPreferences ------------------------------------------------------------
521
522HRESULT STDMETHODCALLTYPE WebPreferences::standardPreferences(
523    /* [retval][out] */ IWebPreferences** standardPreferences)
524{
525    if (!standardPreferences)
526        return E_POINTER;
527    *standardPreferences = sharedStandardPreferences();
528    (*standardPreferences)->AddRef();
529    return S_OK;
530}
531
532HRESULT STDMETHODCALLTYPE WebPreferences::initWithIdentifier(
533        /* [in] */ BSTR anIdentifier,
534        /* [retval][out] */ IWebPreferences** preferences)
535{
536    WebPreferences *instance = getInstanceForIdentifier(anIdentifier);
537    if (instance) {
538        *preferences = instance;
539        instance->AddRef();
540        return S_OK;
541    }
542
543    load();
544
545    *preferences = this;
546    AddRef();
547
548    if (anIdentifier) {
549        m_identifier = anIdentifier;
550        setInstance(this, m_identifier);
551    }
552
553    this->postPreferencesChangesNotification();
554
555    return S_OK;
556}
557
558HRESULT STDMETHODCALLTYPE WebPreferences::identifier(
559    /* [retval][out] */ BSTR* ident)
560{
561    if (!ident)
562        return E_POINTER;
563    *ident = m_identifier ? SysAllocString(m_identifier) : 0;
564    return S_OK;
565}
566
567HRESULT STDMETHODCALLTYPE WebPreferences::standardFontFamily(
568    /* [retval][out] */ BSTR* family)
569{
570    *family = stringValueForKey(CFSTR(WebKitStandardFontPreferenceKey));
571    return (*family) ? S_OK : E_FAIL;
572}
573
574HRESULT STDMETHODCALLTYPE WebPreferences::setStandardFontFamily(
575    /* [in] */ BSTR family)
576{
577    setStringValue(CFSTR(WebKitStandardFontPreferenceKey), family);
578    return S_OK;
579}
580
581HRESULT STDMETHODCALLTYPE WebPreferences::fixedFontFamily(
582    /* [retval][out] */ BSTR* family)
583{
584    *family = stringValueForKey(CFSTR(WebKitFixedFontPreferenceKey));
585    return (*family) ? S_OK : E_FAIL;
586}
587
588HRESULT STDMETHODCALLTYPE WebPreferences::setFixedFontFamily(
589    /* [in] */ BSTR family)
590{
591    setStringValue(CFSTR(WebKitFixedFontPreferenceKey), family);
592    return S_OK;
593}
594
595HRESULT STDMETHODCALLTYPE WebPreferences::serifFontFamily(
596    /* [retval][out] */ BSTR* fontFamily)
597{
598    *fontFamily = stringValueForKey(CFSTR(WebKitSerifFontPreferenceKey));
599    return (*fontFamily) ? S_OK : E_FAIL;
600}
601
602HRESULT STDMETHODCALLTYPE WebPreferences::setSerifFontFamily(
603    /* [in] */ BSTR family)
604{
605    setStringValue(CFSTR(WebKitSerifFontPreferenceKey), family);
606    return S_OK;
607}
608
609HRESULT STDMETHODCALLTYPE WebPreferences::sansSerifFontFamily(
610    /* [retval][out] */ BSTR* family)
611{
612    *family = stringValueForKey(CFSTR(WebKitSansSerifFontPreferenceKey));
613    return (*family) ? S_OK : E_FAIL;
614}
615
616HRESULT STDMETHODCALLTYPE WebPreferences::setSansSerifFontFamily(
617    /* [in] */ BSTR family)
618{
619    setStringValue(CFSTR(WebKitSansSerifFontPreferenceKey), family);
620    return S_OK;
621}
622
623HRESULT STDMETHODCALLTYPE WebPreferences::cursiveFontFamily(
624    /* [retval][out] */ BSTR* family)
625{
626    *family = stringValueForKey(CFSTR(WebKitCursiveFontPreferenceKey));
627    return (*family) ? S_OK : E_FAIL;
628}
629
630HRESULT STDMETHODCALLTYPE WebPreferences::setCursiveFontFamily(
631    /* [in] */ BSTR family)
632{
633    setStringValue(CFSTR(WebKitCursiveFontPreferenceKey), family);
634    return S_OK;
635}
636
637HRESULT STDMETHODCALLTYPE WebPreferences::fantasyFontFamily(
638    /* [retval][out] */ BSTR* family)
639{
640    *family = stringValueForKey(CFSTR(WebKitFantasyFontPreferenceKey));
641    return (*family) ? S_OK : E_FAIL;
642}
643
644HRESULT STDMETHODCALLTYPE WebPreferences::setFantasyFontFamily(
645    /* [in] */ BSTR family)
646{
647    setStringValue(CFSTR(WebKitFantasyFontPreferenceKey), family);
648    return S_OK;
649}
650
651HRESULT STDMETHODCALLTYPE WebPreferences::defaultFontSize(
652    /* [retval][out] */ int* fontSize)
653{
654    *fontSize = integerValueForKey(CFSTR(WebKitDefaultFontSizePreferenceKey));
655    return S_OK;
656}
657
658HRESULT STDMETHODCALLTYPE WebPreferences::setDefaultFontSize(
659    /* [in] */ int fontSize)
660{
661    setIntegerValue(CFSTR(WebKitDefaultFontSizePreferenceKey), fontSize);
662    return S_OK;
663}
664
665HRESULT STDMETHODCALLTYPE WebPreferences::defaultFixedFontSize(
666    /* [retval][out] */ int* fontSize)
667{
668    *fontSize = integerValueForKey(CFSTR(WebKitDefaultFixedFontSizePreferenceKey));
669    return S_OK;
670}
671
672HRESULT STDMETHODCALLTYPE WebPreferences::setDefaultFixedFontSize(
673    /* [in] */ int fontSize)
674{
675    setIntegerValue(CFSTR(WebKitDefaultFixedFontSizePreferenceKey), fontSize);
676    return S_OK;
677}
678
679HRESULT STDMETHODCALLTYPE WebPreferences::minimumFontSize(
680    /* [retval][out] */ int* fontSize)
681{
682    *fontSize = integerValueForKey(CFSTR(WebKitMinimumFontSizePreferenceKey));
683    return S_OK;
684}
685
686HRESULT STDMETHODCALLTYPE WebPreferences::setMinimumFontSize(
687    /* [in] */ int fontSize)
688{
689    setIntegerValue(CFSTR(WebKitMinimumFontSizePreferenceKey), fontSize);
690    return S_OK;
691}
692
693HRESULT STDMETHODCALLTYPE WebPreferences::minimumLogicalFontSize(
694    /* [retval][out] */ int* fontSize)
695{
696    *fontSize = integerValueForKey(CFSTR(WebKitMinimumLogicalFontSizePreferenceKey));
697    return S_OK;
698}
699
700HRESULT STDMETHODCALLTYPE WebPreferences::setMinimumLogicalFontSize(
701    /* [in] */ int fontSize)
702{
703    setIntegerValue(CFSTR(WebKitMinimumLogicalFontSizePreferenceKey), fontSize);
704    return S_OK;
705}
706
707HRESULT STDMETHODCALLTYPE WebPreferences::defaultTextEncodingName(
708    /* [retval][out] */ BSTR* name)
709{
710    *name = stringValueForKey(CFSTR(WebKitDefaultTextEncodingNamePreferenceKey));
711    return (*name) ? S_OK : E_FAIL;
712}
713
714HRESULT STDMETHODCALLTYPE WebPreferences::setDefaultTextEncodingName(
715    /* [in] */ BSTR name)
716{
717    setStringValue(CFSTR(WebKitDefaultTextEncodingNamePreferenceKey), name);
718    return S_OK;
719}
720
721HRESULT STDMETHODCALLTYPE WebPreferences::userStyleSheetEnabled(
722    /* [retval][out] */ BOOL* enabled)
723{
724    *enabled = boolValueForKey(CFSTR(WebKitUserStyleSheetEnabledPreferenceKey));
725    return S_OK;
726}
727
728HRESULT STDMETHODCALLTYPE WebPreferences::setUserStyleSheetEnabled(
729    /* [in] */ BOOL enabled)
730{
731    setBoolValue(CFSTR(WebKitUserStyleSheetEnabledPreferenceKey), enabled);
732    return S_OK;
733}
734
735HRESULT STDMETHODCALLTYPE WebPreferences::userStyleSheetLocation(
736    /* [retval][out] */ BSTR* location)
737{
738    *location = stringValueForKey(CFSTR(WebKitUserStyleSheetLocationPreferenceKey));
739    return (*location) ? S_OK : E_FAIL;
740}
741
742HRESULT STDMETHODCALLTYPE WebPreferences::setUserStyleSheetLocation(
743    /* [in] */ BSTR location)
744{
745    setStringValue(CFSTR(WebKitUserStyleSheetLocationPreferenceKey), location);
746    return S_OK;
747}
748
749HRESULT STDMETHODCALLTYPE WebPreferences::isJavaEnabled(
750    /* [retval][out] */ BOOL* enabled)
751{
752    *enabled = boolValueForKey(CFSTR(WebKitJavaEnabledPreferenceKey));
753    return S_OK;
754}
755
756HRESULT STDMETHODCALLTYPE WebPreferences::setJavaEnabled(
757    /* [in] */ BOOL enabled)
758{
759    setBoolValue(CFSTR(WebKitJavaEnabledPreferenceKey), enabled);
760    return S_OK;
761}
762
763HRESULT STDMETHODCALLTYPE WebPreferences::isJavaScriptEnabled(
764    /* [retval][out] */ BOOL* enabled)
765{
766    *enabled = boolValueForKey(CFSTR(WebKitJavaScriptEnabledPreferenceKey));
767    return S_OK;
768}
769
770HRESULT STDMETHODCALLTYPE WebPreferences::setJavaScriptEnabled(
771    /* [in] */ BOOL enabled)
772{
773    setBoolValue(CFSTR(WebKitJavaScriptEnabledPreferenceKey), enabled);
774    return S_OK;
775}
776
777HRESULT STDMETHODCALLTYPE WebPreferences::isWebSecurityEnabled(
778    /* [retval][out] */ BOOL* enabled)
779{
780    *enabled = boolValueForKey(CFSTR(WebKitWebSecurityEnabledPreferenceKey));
781    return S_OK;
782}
783
784HRESULT STDMETHODCALLTYPE WebPreferences::setWebSecurityEnabled(
785    /* [in] */ BOOL enabled)
786{
787    setBoolValue(CFSTR(WebKitWebSecurityEnabledPreferenceKey), enabled);
788    return S_OK;
789}
790
791HRESULT STDMETHODCALLTYPE WebPreferences::allowUniversalAccessFromFileURLs(
792    /* [retval][out] */ BOOL* allowAccess)
793{
794    *allowAccess = boolValueForKey(CFSTR(WebKitAllowUniversalAccessFromFileURLsPreferenceKey));
795    return S_OK;
796}
797
798HRESULT STDMETHODCALLTYPE WebPreferences::setAllowUniversalAccessFromFileURLs(
799    /* [in] */ BOOL allowAccess)
800{
801    setBoolValue(CFSTR(WebKitAllowUniversalAccessFromFileURLsPreferenceKey), allowAccess);
802    return S_OK;
803}
804
805HRESULT STDMETHODCALLTYPE WebPreferences::allowFileAccessFromFileURLs(
806    /* [retval][out] */ BOOL* allowAccess)
807{
808    *allowAccess = boolValueForKey(CFSTR(WebKitAllowFileAccessFromFileURLsPreferenceKey));
809    return S_OK;
810}
811
812HRESULT STDMETHODCALLTYPE WebPreferences::setAllowFileAccessFromFileURLs(
813    /* [in] */ BOOL allowAccess)
814{
815    setBoolValue(CFSTR(WebKitAllowFileAccessFromFileURLsPreferenceKey), allowAccess);
816    return S_OK;
817}
818
819HRESULT STDMETHODCALLTYPE WebPreferences::javaScriptCanAccessClipboard(
820    /* [retval][out] */ BOOL* enabled)
821{
822    *enabled = boolValueForKey(CFSTR(WebKitJavaScriptCanAccessClipboardPreferenceKey));
823    return S_OK;
824}
825
826HRESULT STDMETHODCALLTYPE WebPreferences::setJavaScriptCanAccessClipboard(
827    /* [in] */ BOOL enabled)
828{
829    setBoolValue(CFSTR(WebKitJavaScriptCanAccessClipboardPreferenceKey), enabled);
830    return S_OK;
831}
832
833HRESULT STDMETHODCALLTYPE WebPreferences::isXSSAuditorEnabled(
834    /* [retval][out] */ BOOL* enabled)
835{
836    *enabled = boolValueForKey(CFSTR(WebKitXSSAuditorEnabledPreferenceKey));
837    return S_OK;
838}
839
840HRESULT STDMETHODCALLTYPE WebPreferences::setXSSAuditorEnabled(
841    /* [in] */ BOOL enabled)
842{
843    setBoolValue(CFSTR(WebKitXSSAuditorEnabledPreferenceKey), enabled);
844    return S_OK;
845}
846
847HRESULT STDMETHODCALLTYPE WebPreferences::isFrameFlatteningEnabled(
848    /* [retval][out] */ BOOL* enabled)
849{
850    *enabled = boolValueForKey(CFSTR(WebKitFrameFlatteningEnabledPreferenceKey));
851    return S_OK;
852}
853
854HRESULT STDMETHODCALLTYPE WebPreferences::setFrameFlatteningEnabled(
855    /* [in] */ BOOL enabled)
856{
857    setBoolValue(CFSTR(WebKitFrameFlatteningEnabledPreferenceKey), enabled);
858    return S_OK;
859}
860
861HRESULT STDMETHODCALLTYPE WebPreferences::javaScriptCanOpenWindowsAutomatically(
862    /* [retval][out] */ BOOL* enabled)
863{
864    *enabled = boolValueForKey(CFSTR(WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey));
865    return S_OK;
866}
867
868HRESULT STDMETHODCALLTYPE WebPreferences::setJavaScriptCanOpenWindowsAutomatically(
869    /* [in] */ BOOL enabled)
870{
871    setBoolValue(CFSTR(WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey), enabled);
872    return S_OK;
873}
874
875HRESULT STDMETHODCALLTYPE WebPreferences::arePlugInsEnabled(
876    /* [retval][out] */ BOOL* enabled)
877{
878    *enabled = boolValueForKey(CFSTR(WebKitPluginsEnabledPreferenceKey));
879    return S_OK;
880}
881
882HRESULT STDMETHODCALLTYPE WebPreferences::setPlugInsEnabled(
883    /* [in] */ BOOL enabled)
884{
885    setBoolValue(CFSTR(WebKitPluginsEnabledPreferenceKey), enabled);
886    return S_OK;
887}
888
889HRESULT STDMETHODCALLTYPE WebPreferences::allowsAnimatedImages(
890    /* [retval][out] */ BOOL* enabled)
891{
892    *enabled = boolValueForKey(CFSTR(WebKitAllowAnimatedImagesPreferenceKey));
893    return S_OK;
894}
895
896HRESULT STDMETHODCALLTYPE WebPreferences::setAllowsAnimatedImages(
897    /* [in] */ BOOL enabled)
898{
899    setBoolValue(CFSTR(WebKitAllowAnimatedImagesPreferenceKey), enabled);
900    return S_OK;
901}
902
903HRESULT STDMETHODCALLTYPE WebPreferences::allowAnimatedImageLooping(
904    /* [retval][out] */ BOOL* enabled)
905{
906    *enabled = boolValueForKey(CFSTR(WebKitAllowAnimatedImageLoopingPreferenceKey));
907    return S_OK;
908}
909
910HRESULT STDMETHODCALLTYPE WebPreferences::setAllowAnimatedImageLooping(
911    /* [in] */ BOOL enabled)
912{
913    setBoolValue(CFSTR(WebKitAllowAnimatedImageLoopingPreferenceKey), enabled);
914    return S_OK;
915}
916
917HRESULT STDMETHODCALLTYPE WebPreferences::setLoadsImagesAutomatically(
918    /* [in] */ BOOL enabled)
919{
920    setBoolValue(CFSTR(WebKitDisplayImagesKey), enabled);
921    return S_OK;
922}
923
924HRESULT STDMETHODCALLTYPE WebPreferences::loadsImagesAutomatically(
925    /* [retval][out] */ BOOL* enabled)
926{
927    *enabled = boolValueForKey(CFSTR(WebKitDisplayImagesKey));
928    return S_OK;
929}
930
931HRESULT STDMETHODCALLTYPE WebPreferences::setLoadsSiteIconsIgnoringImageLoadingPreference(
932    /* [in] */ BOOL enabled)
933{
934    setBoolValue(CFSTR(WebKitLoadSiteIconsKey), enabled);
935    return S_OK;
936}
937
938HRESULT STDMETHODCALLTYPE WebPreferences::loadsSiteIconsIgnoringImageLoadingPreference(
939    /* [retval][out] */ BOOL* enabled)
940{
941    *enabled = boolValueForKey(CFSTR(WebKitLoadSiteIconsKey));
942    return S_OK;
943}
944
945HRESULT STDMETHODCALLTYPE WebPreferences::setAutosaves(
946    /* [in] */ BOOL enabled)
947{
948    m_autoSaves = !!enabled;
949    return S_OK;
950}
951
952HRESULT STDMETHODCALLTYPE WebPreferences::autosaves(
953    /* [retval][out] */ BOOL* enabled)
954{
955    *enabled = m_autoSaves ? TRUE : FALSE;
956    return S_OK;
957}
958
959HRESULT STDMETHODCALLTYPE WebPreferences::setShouldPrintBackgrounds(
960    /* [in] */ BOOL enabled)
961{
962    setBoolValue(CFSTR(WebKitShouldPrintBackgroundsPreferenceKey), enabled);
963    return S_OK;
964}
965
966HRESULT STDMETHODCALLTYPE WebPreferences::shouldPrintBackgrounds(
967    /* [retval][out] */ BOOL* enabled)
968{
969    *enabled = boolValueForKey(CFSTR(WebKitShouldPrintBackgroundsPreferenceKey));
970    return S_OK;
971}
972
973HRESULT STDMETHODCALLTYPE WebPreferences::setPrivateBrowsingEnabled(
974    /* [in] */ BOOL enabled)
975{
976    setBoolValue(CFSTR(WebKitPrivateBrowsingEnabledPreferenceKey), enabled);
977    return S_OK;
978}
979
980HRESULT STDMETHODCALLTYPE WebPreferences::privateBrowsingEnabled(
981    /* [retval][out] */ BOOL* enabled)
982{
983    *enabled = boolValueForKey(CFSTR(WebKitPrivateBrowsingEnabledPreferenceKey));
984    return S_OK;
985}
986
987HRESULT STDMETHODCALLTYPE WebPreferences::setTabsToLinks(
988    /* [in] */ BOOL enabled)
989{
990    setBoolValue(CFSTR(WebKitTabToLinksPreferenceKey), enabled);
991    return S_OK;
992}
993
994HRESULT STDMETHODCALLTYPE WebPreferences::tabsToLinks(
995    /* [retval][out] */ BOOL* enabled)
996{
997    *enabled = boolValueForKey(CFSTR(WebKitTabToLinksPreferenceKey));
998    return S_OK;
999}
1000
1001HRESULT STDMETHODCALLTYPE WebPreferences::setUsesPageCache(
1002        /* [in] */ BOOL usesPageCache)
1003{
1004    setBoolValue(CFSTR(WebKitUsesPageCachePreferenceKey), usesPageCache);
1005    return S_OK;
1006}
1007
1008HRESULT STDMETHODCALLTYPE WebPreferences::usesPageCache(
1009    /* [retval][out] */ BOOL* usesPageCache)
1010{
1011    *usesPageCache = boolValueForKey(CFSTR(WebKitUsesPageCachePreferenceKey));
1012    return S_OK;
1013}
1014
1015HRESULT STDMETHODCALLTYPE WebPreferences::textAreasAreResizable(
1016    /* [retval][out] */ BOOL* enabled)
1017{
1018    *enabled = boolValueForKey(CFSTR(WebKitTextAreasAreResizablePreferenceKey));
1019    return S_OK;
1020}
1021
1022HRESULT STDMETHODCALLTYPE WebPreferences::setTextAreasAreResizable(
1023    /* [in] */ BOOL enabled)
1024{
1025    setBoolValue(CFSTR(WebKitTextAreasAreResizablePreferenceKey), enabled);
1026    return S_OK;
1027}
1028
1029HRESULT WebPreferences::historyItemLimit(int* limit)
1030{
1031    *limit = integerValueForKey(CFSTR(WebKitHistoryItemLimitKey));
1032    return S_OK;
1033}
1034
1035HRESULT WebPreferences::setHistoryItemLimit(int limit)
1036{
1037    setIntegerValue(CFSTR(WebKitHistoryItemLimitKey), limit);
1038    return S_OK;
1039}
1040
1041HRESULT WebPreferences::historyAgeInDaysLimit(int* limit)
1042{
1043    *limit = integerValueForKey(CFSTR(WebKitHistoryAgeInDaysLimitKey));
1044    return S_OK;
1045}
1046
1047HRESULT WebPreferences::setHistoryAgeInDaysLimit(int limit)
1048{
1049    setIntegerValue(CFSTR(WebKitHistoryAgeInDaysLimitKey), limit);
1050    return S_OK;
1051}
1052
1053HRESULT WebPreferences::unused1()
1054{
1055    ASSERT_NOT_REACHED();
1056    return E_FAIL;
1057}
1058
1059HRESULT WebPreferences::unused2()
1060{
1061    ASSERT_NOT_REACHED();
1062    return E_FAIL;
1063}
1064
1065HRESULT WebPreferences::iconDatabaseLocation(
1066    /* [out] */ BSTR* location)
1067{
1068    *location = stringValueForKey(CFSTR(WebKitIconDatabaseLocationKey));
1069    return (*location) ? S_OK : E_FAIL;
1070}
1071
1072HRESULT WebPreferences::setIconDatabaseLocation(
1073    /* [in] */ BSTR location)
1074{
1075    setStringValue(CFSTR(WebKitIconDatabaseLocationKey), location);
1076    return S_OK;
1077}
1078
1079HRESULT WebPreferences::iconDatabaseEnabled(BOOL* enabled)//location)
1080{
1081    *enabled = boolValueForKey(CFSTR(WebKitIconDatabaseEnabledPreferenceKey));
1082    return S_OK;
1083}
1084
1085HRESULT WebPreferences::setIconDatabaseEnabled(BOOL enabled )//location)
1086{
1087    setBoolValue(CFSTR(WebKitIconDatabaseEnabledPreferenceKey), enabled);
1088    return S_OK;
1089}
1090
1091HRESULT STDMETHODCALLTYPE WebPreferences::fontSmoothing(
1092    /* [retval][out] */ FontSmoothingType* smoothingType)
1093{
1094    *smoothingType = (FontSmoothingType) integerValueForKey(CFSTR(WebKitFontSmoothingTypePreferenceKey));
1095    return S_OK;
1096}
1097
1098HRESULT STDMETHODCALLTYPE WebPreferences::setFontSmoothing(
1099    /* [in] */ FontSmoothingType smoothingType)
1100{
1101    setIntegerValue(CFSTR(WebKitFontSmoothingTypePreferenceKey), smoothingType);
1102    if (smoothingType == FontSmoothingTypeWindows)
1103        smoothingType = FontSmoothingTypeMedium;
1104#if USE(CG)
1105    wkSetFontSmoothingLevel((int)smoothingType);
1106#endif
1107    return S_OK;
1108}
1109
1110HRESULT STDMETHODCALLTYPE WebPreferences::fontSmoothingContrast(
1111    /* [retval][out] */ float* contrast)
1112{
1113    *contrast = floatValueForKey(CFSTR(WebKitFontSmoothingContrastPreferenceKey));
1114    return S_OK;
1115}
1116
1117HRESULT STDMETHODCALLTYPE WebPreferences::setFontSmoothingContrast(
1118    /* [in] */ float contrast)
1119{
1120    setFloatValue(CFSTR(WebKitFontSmoothingContrastPreferenceKey), contrast);
1121#if USE(CG)
1122    wkSetFontSmoothingContrast(contrast);
1123#endif
1124    return S_OK;
1125}
1126
1127HRESULT STDMETHODCALLTYPE WebPreferences::editableLinkBehavior(
1128    /* [out, retval] */ WebKitEditableLinkBehavior* editableLinkBehavior)
1129{
1130    WebKitEditableLinkBehavior value = (WebKitEditableLinkBehavior) integerValueForKey(CFSTR(WebKitEditableLinkBehaviorPreferenceKey));
1131    switch (value) {
1132        case WebKitEditableLinkDefaultBehavior:
1133        case WebKitEditableLinkAlwaysLive:
1134        case WebKitEditableLinkOnlyLiveWithShiftKey:
1135        case WebKitEditableLinkLiveWhenNotFocused:
1136        case WebKitEditableLinkNeverLive:
1137            *editableLinkBehavior = value;
1138            break;
1139        default: // ensure that a valid result is returned
1140            *editableLinkBehavior = WebKitEditableLinkDefaultBehavior;
1141            break;
1142    }
1143    return S_OK;
1144}
1145
1146HRESULT STDMETHODCALLTYPE WebPreferences::setEditableLinkBehavior(
1147    /* [in] */ WebKitEditableLinkBehavior behavior)
1148{
1149    setIntegerValue(CFSTR(WebKitEditableLinkBehaviorPreferenceKey), behavior);
1150    return S_OK;
1151}
1152
1153HRESULT STDMETHODCALLTYPE WebPreferences::editingBehavior(
1154    /* [out, retval] */ WebKitEditingBehavior* editingBehavior)
1155{
1156    *editingBehavior = (WebKitEditingBehavior) integerValueForKey(CFSTR(WebKitEditingBehaviorPreferenceKey));
1157    return S_OK;
1158}
1159
1160HRESULT STDMETHODCALLTYPE WebPreferences::setEditingBehavior(
1161    /* [in] */ WebKitEditingBehavior behavior)
1162{
1163    setIntegerValue(CFSTR(WebKitEditingBehaviorPreferenceKey), behavior);
1164    return S_OK;
1165}
1166
1167HRESULT STDMETHODCALLTYPE WebPreferences::hyperlinkAuditingEnabled(
1168    /* [in] */ BOOL* enabled)
1169{
1170    *enabled = boolValueForKey(CFSTR(WebKitHyperlinkAuditingEnabledPreferenceKey));
1171    return S_OK;
1172}
1173
1174HRESULT STDMETHODCALLTYPE WebPreferences::setHyperlinkAuditingEnabled(
1175    /* [retval][out] */ BOOL enabled)
1176{
1177    setBoolValue(CFSTR(WebKitHyperlinkAuditingEnabledPreferenceKey), enabled);
1178    return S_OK;
1179}
1180
1181HRESULT STDMETHODCALLTYPE WebPreferences::cookieStorageAcceptPolicy(
1182        /* [retval][out] */ WebKitCookieStorageAcceptPolicy *acceptPolicy )
1183{
1184    if (!acceptPolicy)
1185        return E_POINTER;
1186
1187    *acceptPolicy = (WebKitCookieStorageAcceptPolicy)integerValueForKey(CFSTR(WebKitCookieStorageAcceptPolicyPreferenceKey));
1188    return S_OK;
1189}
1190
1191HRESULT STDMETHODCALLTYPE WebPreferences::setCookieStorageAcceptPolicy(
1192        /* [in] */ WebKitCookieStorageAcceptPolicy acceptPolicy)
1193{
1194    setIntegerValue(CFSTR(WebKitCookieStorageAcceptPolicyPreferenceKey), acceptPolicy);
1195    return S_OK;
1196}
1197
1198
1199HRESULT WebPreferences::continuousSpellCheckingEnabled(BOOL* enabled)
1200{
1201    *enabled = boolValueForKey(CFSTR(WebContinuousSpellCheckingEnabledPreferenceKey));
1202    return S_OK;
1203}
1204
1205HRESULT WebPreferences::setContinuousSpellCheckingEnabled(BOOL enabled)
1206{
1207    setBoolValue(CFSTR(WebContinuousSpellCheckingEnabledPreferenceKey), enabled);
1208    return S_OK;
1209}
1210
1211HRESULT WebPreferences::grammarCheckingEnabled(BOOL* enabled)
1212{
1213    *enabled = boolValueForKey(CFSTR(WebGrammarCheckingEnabledPreferenceKey));
1214    return S_OK;
1215}
1216
1217HRESULT WebPreferences::setGrammarCheckingEnabled(BOOL enabled)
1218{
1219    setBoolValue(CFSTR(WebGrammarCheckingEnabledPreferenceKey), enabled);
1220    return S_OK;
1221}
1222
1223HRESULT WebPreferences::allowContinuousSpellChecking(BOOL* enabled)
1224{
1225    *enabled = boolValueForKey(CFSTR(AllowContinuousSpellCheckingPreferenceKey));
1226    return S_OK;
1227}
1228
1229HRESULT WebPreferences::setAllowContinuousSpellChecking(BOOL enabled)
1230{
1231    setBoolValue(CFSTR(AllowContinuousSpellCheckingPreferenceKey), enabled);
1232    return S_OK;
1233}
1234
1235HRESULT WebPreferences::isDOMPasteAllowed(BOOL* enabled)
1236{
1237    *enabled = boolValueForKey(CFSTR(WebKitDOMPasteAllowedPreferenceKey));
1238    return S_OK;
1239}
1240
1241HRESULT WebPreferences::setDOMPasteAllowed(BOOL enabled)
1242{
1243    setBoolValue(CFSTR(WebKitDOMPasteAllowedPreferenceKey), enabled);
1244    return S_OK;
1245}
1246
1247HRESULT WebPreferences::cacheModel(WebCacheModel* cacheModel)
1248{
1249    if (!cacheModel)
1250        return E_POINTER;
1251
1252    *cacheModel = (WebCacheModel)integerValueForKey(CFSTR(WebKitCacheModelPreferenceKey));
1253    return S_OK;
1254}
1255
1256HRESULT WebPreferences::setCacheModel(WebCacheModel cacheModel)
1257{
1258    setIntegerValue(CFSTR(WebKitCacheModelPreferenceKey), cacheModel);
1259    return S_OK;
1260}
1261
1262HRESULT WebPreferences::setShouldPaintCustomScrollbars(BOOL shouldPaint)
1263{
1264    setBoolValue(CFSTR(WebKitPaintCustomScrollbarsPreferenceKey), shouldPaint);
1265    return S_OK;
1266}
1267
1268HRESULT WebPreferences::shouldPaintCustomScrollbars(BOOL* shouldPaint)
1269{
1270    *shouldPaint = boolValueForKey(CFSTR(WebKitPaintCustomScrollbarsPreferenceKey));
1271    return S_OK;
1272}
1273
1274HRESULT WebPreferences::shouldPaintNativeControls(BOOL* shouldPaint)
1275{
1276    *shouldPaint = boolValueForKey(CFSTR(WebKitPaintNativeControlsPreferenceKey));
1277    return S_OK;
1278}
1279
1280HRESULT WebPreferences::setShouldPaintNativeControls(BOOL shouldPaint)
1281{
1282    setBoolValue(CFSTR(WebKitPaintNativeControlsPreferenceKey), shouldPaint);
1283    return S_OK;
1284}
1285
1286HRESULT WebPreferences::setDeveloperExtrasEnabled(BOOL enabled)
1287{
1288    setBoolValue(CFSTR(WebKitDeveloperExtrasEnabledPreferenceKey), enabled);
1289    return S_OK;
1290}
1291
1292HRESULT WebPreferences::developerExtrasEnabled(BOOL* enabled)
1293{
1294    if (!enabled)
1295        return E_POINTER;
1296
1297    *enabled = boolValueForKey(CFSTR(WebKitDeveloperExtrasEnabledPreferenceKey));
1298    return S_OK;
1299}
1300
1301bool WebPreferences::developerExtrasDisabledByOverride()
1302{
1303    return !!boolValueForKey(CFSTR(DisableWebKitDeveloperExtrasPreferenceKey));
1304}
1305
1306HRESULT WebPreferences::setAutomaticallyDetectsCacheModel(BOOL automaticallyDetectsCacheModel)
1307{
1308    m_automaticallyDetectsCacheModel = !!automaticallyDetectsCacheModel;
1309    return S_OK;
1310}
1311
1312HRESULT WebPreferences::automaticallyDetectsCacheModel(BOOL* automaticallyDetectsCacheModel)
1313{
1314    if (!automaticallyDetectsCacheModel)
1315        return E_POINTER;
1316
1317    *automaticallyDetectsCacheModel = m_automaticallyDetectsCacheModel;
1318    return S_OK;
1319}
1320
1321HRESULT STDMETHODCALLTYPE WebPreferences::setAuthorAndUserStylesEnabled(BOOL enabled)
1322{
1323    setBoolValue(CFSTR(WebKitAuthorAndUserStylesEnabledPreferenceKey), enabled);
1324    return S_OK;
1325}
1326
1327HRESULT STDMETHODCALLTYPE WebPreferences::authorAndUserStylesEnabled(BOOL* enabled)
1328{
1329    if (!enabled)
1330        return E_POINTER;
1331
1332    *enabled = boolValueForKey(CFSTR(WebKitAuthorAndUserStylesEnabledPreferenceKey));
1333    return S_OK;
1334}
1335
1336HRESULT WebPreferences::inApplicationChromeMode(BOOL* enabled)
1337{
1338    *enabled = boolValueForKey(CFSTR(WebKitApplicationChromeModePreferenceKey));
1339    return S_OK;
1340}
1341
1342HRESULT WebPreferences::setApplicationChromeMode(BOOL enabled)
1343{
1344    setBoolValue(CFSTR(WebKitApplicationChromeModePreferenceKey), enabled);
1345    return S_OK;
1346}
1347
1348HRESULT STDMETHODCALLTYPE WebPreferences::setOfflineWebApplicationCacheEnabled(BOOL enabled)
1349{
1350    setBoolValue(CFSTR(WebKitOfflineWebApplicationCacheEnabledPreferenceKey), enabled);
1351    return S_OK;
1352}
1353
1354HRESULT STDMETHODCALLTYPE WebPreferences::offlineWebApplicationCacheEnabled(BOOL* enabled)
1355{
1356    *enabled = boolValueForKey(CFSTR(WebKitOfflineWebApplicationCacheEnabledPreferenceKey));
1357    return S_OK;
1358}
1359
1360HRESULT STDMETHODCALLTYPE WebPreferences::setDatabasesEnabled(BOOL enabled)
1361{
1362    setBoolValue(CFSTR(WebKitDatabasesEnabledPreferenceKey), enabled);
1363    return S_OK;
1364}
1365
1366HRESULT STDMETHODCALLTYPE WebPreferences::databasesEnabled(BOOL* enabled)
1367{
1368    *enabled = boolValueForKey(CFSTR(WebKitDatabasesEnabledPreferenceKey));
1369    return S_OK;
1370}
1371
1372HRESULT STDMETHODCALLTYPE WebPreferences::setLocalStorageEnabled(BOOL enabled)
1373{
1374    setBoolValue(CFSTR(WebKitLocalStorageEnabledPreferenceKey), enabled);
1375    return S_OK;
1376}
1377
1378HRESULT STDMETHODCALLTYPE WebPreferences::localStorageEnabled(BOOL* enabled)
1379{
1380    *enabled = boolValueForKey(CFSTR(WebKitLocalStorageEnabledPreferenceKey));
1381    return S_OK;
1382}
1383
1384HRESULT STDMETHODCALLTYPE WebPreferences::localStorageDatabasePath(BSTR* location)
1385{
1386    *location = stringValueForKey(CFSTR(WebKitLocalStorageDatabasePathPreferenceKey));
1387    return (*location) ? S_OK : E_FAIL;
1388}
1389
1390HRESULT STDMETHODCALLTYPE WebPreferences::setLocalStorageDatabasePath(BSTR location)
1391{
1392    setStringValue(CFSTR(WebKitLocalStorageDatabasePathPreferenceKey), location);
1393    return S_OK;
1394}
1395
1396HRESULT STDMETHODCALLTYPE WebPreferences::setExperimentalNotificationsEnabled(BOOL enabled)
1397{
1398    setBoolValue(CFSTR(WebKitExperimentalNotificationsEnabledPreferenceKey), enabled);
1399    return S_OK;
1400}
1401
1402HRESULT STDMETHODCALLTYPE WebPreferences::experimentalNotificationsEnabled(BOOL* enabled)
1403{
1404    *enabled = boolValueForKey(CFSTR(WebKitExperimentalNotificationsEnabledPreferenceKey));
1405    return S_OK;
1406}
1407
1408HRESULT WebPreferences::setZoomsTextOnly(BOOL zoomsTextOnly)
1409{
1410    setBoolValue(CFSTR(WebKitZoomsTextOnlyPreferenceKey), zoomsTextOnly);
1411    return S_OK;
1412}
1413
1414HRESULT WebPreferences::zoomsTextOnly(BOOL* zoomsTextOnly)
1415{
1416    *zoomsTextOnly = boolValueForKey(CFSTR(WebKitZoomsTextOnlyPreferenceKey));
1417    return S_OK;
1418}
1419
1420HRESULT STDMETHODCALLTYPE WebPreferences::setShouldUseHighResolutionTimers(BOOL useHighResolutionTimers)
1421{
1422    setBoolValue(CFSTR(WebKitUseHighResolutionTimersPreferenceKey), useHighResolutionTimers);
1423    return S_OK;
1424}
1425
1426HRESULT STDMETHODCALLTYPE WebPreferences::shouldUseHighResolutionTimers(BOOL* useHighResolutionTimers)
1427{
1428    *useHighResolutionTimers = boolValueForKey(CFSTR(WebKitUseHighResolutionTimersPreferenceKey));
1429    return S_OK;
1430}
1431
1432HRESULT WebPreferences::setPluginAllowedRunTime(UINT allowedRunTime)
1433{
1434    setIntegerValue(CFSTR(WebKitPluginAllowedRunTimePreferenceKey), allowedRunTime);
1435    return S_OK;
1436}
1437
1438HRESULT WebPreferences::pluginAllowedRunTime(UINT* allowedRunTime)
1439{
1440    *allowedRunTime = integerValueForKey(CFSTR(WebKitPluginAllowedRunTimePreferenceKey));
1441    return S_OK;
1442}
1443
1444HRESULT WebPreferences::setPreferenceForTest(BSTR key, BSTR value)
1445{
1446    if (!SysStringLen(key) || !SysStringLen(value))
1447        return E_FAIL;
1448    RetainPtr<CFStringRef> keyString(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<UniChar*>(key), SysStringLen(key)));
1449    RetainPtr<CFStringRef> valueString(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<UniChar*>(value), SysStringLen(value)));
1450    setValueForKey(keyString.get(), valueString.get());
1451    postPreferencesChangesNotification();
1452    return S_OK;
1453}
1454
1455HRESULT WebPreferences::setAcceleratedCompositingEnabled(BOOL enabled)
1456{
1457    setBoolValue(CFSTR(WebKitAcceleratedCompositingEnabledPreferenceKey), enabled);
1458    return S_OK;
1459}
1460
1461HRESULT WebPreferences::acceleratedCompositingEnabled(BOOL* enabled)
1462{
1463#if USE(ACCELERATED_COMPOSITING)
1464    *enabled = CACFLayerTreeHost::acceleratedCompositingAvailable() && boolValueForKey(CFSTR(WebKitAcceleratedCompositingEnabledPreferenceKey));
1465#else
1466    *enabled = FALSE;
1467#endif
1468    return S_OK;
1469}
1470
1471HRESULT WebPreferences::showDebugBorders(BOOL* enabled)
1472{
1473    *enabled = boolValueForKey(CFSTR(WebKitShowDebugBordersPreferenceKey));
1474    return S_OK;
1475}
1476
1477HRESULT WebPreferences::setShowDebugBorders(BOOL enabled)
1478{
1479    setBoolValue(CFSTR(WebKitShowDebugBordersPreferenceKey), enabled);
1480    return S_OK;
1481}
1482
1483HRESULT WebPreferences::showRepaintCounter(BOOL* enabled)
1484{
1485    *enabled = boolValueForKey(CFSTR(WebKitShowRepaintCounterPreferenceKey));
1486    return S_OK;
1487}
1488
1489HRESULT WebPreferences::setShowRepaintCounter(BOOL enabled)
1490{
1491    setBoolValue(CFSTR(WebKitShowRepaintCounterPreferenceKey), enabled);
1492    return S_OK;
1493}
1494
1495HRESULT WebPreferences::setCustomDragCursorsEnabled(BOOL enabled)
1496{
1497    setBoolValue(CFSTR(WebKitCustomDragCursorsEnabledPreferenceKey), enabled);
1498    return S_OK;
1499}
1500
1501HRESULT WebPreferences::customDragCursorsEnabled(BOOL* enabled)
1502{
1503    *enabled = boolValueForKey(CFSTR(WebKitCustomDragCursorsEnabledPreferenceKey));
1504    return S_OK;
1505}
1506
1507HRESULT WebPreferences::setDNSPrefetchingEnabled(BOOL enabled)
1508{
1509    setBoolValue(CFSTR(WebKitDNSPrefetchingEnabledPreferenceKey), enabled);
1510    return S_OK;
1511}
1512
1513HRESULT WebPreferences::isDNSPrefetchingEnabled(BOOL* enabled)
1514{
1515    *enabled = boolValueForKey(CFSTR(WebKitDNSPrefetchingEnabledPreferenceKey));
1516    return S_OK;
1517}
1518
1519HRESULT WebPreferences::memoryInfoEnabled(BOOL* enabled)
1520{
1521    *enabled = boolValueForKey(CFSTR(WebKitMemoryInfoEnabledPreferenceKey));
1522    return S_OK;
1523}
1524
1525HRESULT WebPreferences::setMemoryInfoEnabled(BOOL enabled)
1526{
1527    setBoolValue(CFSTR(WebKitMemoryInfoEnabledPreferenceKey), enabled);
1528    return S_OK;
1529}
1530
1531void WebPreferences::willAddToWebView()
1532{
1533    ++m_numWebViews;
1534}
1535
1536void WebPreferences::didRemoveFromWebView()
1537{
1538    ASSERT(m_numWebViews);
1539    if (--m_numWebViews == 0) {
1540        IWebNotificationCenter* nc = WebNotificationCenter::defaultCenterInternal();
1541        nc->postNotificationName(webPreferencesRemovedNotification(), static_cast<IWebPreferences*>(this), 0);
1542    }
1543}
1544