• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
3 *           (C) 2006 Graham Dennis (graham.dennis@gmail.com)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1.  Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 * 2.  Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 *     its contributors may be used to endorse or promote products derived
16 *     from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#import "WebPreferencesPrivate.h"
31#import "WebPreferenceKeysPrivate.h"
32
33#import "WebApplicationCache.h"
34#import "WebKitLogging.h"
35#import "WebKitNSStringExtras.h"
36#import "WebKitSystemBits.h"
37#import "WebKitSystemInterface.h"
38#import "WebKitVersionChecks.h"
39#import "WebNSDictionaryExtras.h"
40#import "WebNSURLExtras.h"
41#import <WebCore/ApplicationCacheStorage.h>
42
43NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
44NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";
45NSString *WebPreferencesChangedInternalNotification = @"WebPreferencesChangedInternalNotification";
46
47#define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x))
48
49enum { WebPreferencesVersion = 1 };
50
51static WebPreferences *_standardPreferences;
52static NSMutableDictionary *webPreferencesInstances;
53
54static bool contains(const char* const array[], int count, const char* item)
55{
56    if (!item)
57        return false;
58
59    for (int i = 0; i < count; i++)
60        if (!strcasecmp(array[i], item))
61            return true;
62    return false;
63}
64
65static WebCacheModel cacheModelForMainBundle(void)
66{
67    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
68
69    // Apps that probably need the small setting
70    static const char* const documentViewerIDs[] = {
71        "Microsoft/com.microsoft.Messenger",
72        "com.adiumX.adiumX",
73        "com.alientechnology.Proteus",
74        "com.apple.Dashcode",
75        "com.apple.iChat",
76        "com.barebones.bbedit",
77        "com.barebones.textwrangler",
78        "com.barebones.yojimbo",
79        "com.equinux.iSale4",
80        "com.growl.growlframework",
81        "com.intrarts.PandoraMan",
82        "com.karelia.Sandvox",
83        "com.macromates.textmate",
84        "com.realmacsoftware.rapidweaverpro",
85        "com.red-sweater.marsedit",
86        "com.yahoo.messenger3",
87        "de.codingmonkeys.SubEthaEdit",
88        "fi.karppinen.Pyro",
89        "info.colloquy",
90        "kungfoo.tv.ecto",
91    };
92
93    // Apps that probably need the medium setting
94    static const char* const documentBrowserIDs[] = {
95        "com.apple.Dictionary",
96        "com.apple.Xcode",
97        "com.apple.dashboard.client",
98        "com.apple.helpviewer",
99        "com.culturedcode.xyle",
100        "com.macrabbit.CSSEdit",
101        "com.panic.Coda",
102        "com.ranchero.NetNewsWire",
103        "com.thinkmac.NewsLife",
104        "org.xlife.NewsFire",
105        "uk.co.opencommunity.vienna2",
106    };
107
108    // Apps that probably need the large setting
109    static const char* const primaryWebBrowserIDs[] = {
110        "com.app4mac.KidsBrowser"
111        "com.app4mac.wKiosk",
112        "com.freeverse.bumpercar",
113        "com.omnigroup.OmniWeb5",
114        "com.sunrisebrowser.Sunrise",
115        "net.hmdt-web.Shiira",
116    };
117
118    WebCacheModel cacheModel;
119
120    const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
121    if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID))
122        cacheModel = WebCacheModelDocumentViewer;
123    else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID))
124        cacheModel = WebCacheModelDocumentBrowser;
125    else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID))
126        cacheModel = WebCacheModelPrimaryWebBrowser;
127    else {
128        bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API);
129        if (isLegacyApp)
130            cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache.
131        else
132            cacheModel = WebCacheModelDocumentViewer; // To save memory.
133    }
134
135    [pool drain];
136
137    return cacheModel;
138}
139
140static bool useQuickLookQuirks(void)
141{
142    NSArray* frameworks = [NSBundle allFrameworks];
143
144    if (!frameworks)
145        return false;
146
147    for (unsigned int i = 0; i < [frameworks count]; i++) {
148        NSBundle* bundle = [frameworks objectAtIndex: i];
149        const char* bundleID = [[bundle bundleIdentifier] UTF8String];
150        if (bundleID && !strcasecmp(bundleID, "com.apple.QuickLookUIFramework"))
151            return true;
152    }
153    return false;
154}
155
156@interface WebPreferencesPrivate : NSObject
157{
158@public
159    NSMutableDictionary *values;
160    NSString *identifier;
161    NSString *IBCreatorID;
162    BOOL autosaves;
163    BOOL automaticallyDetectsCacheModel;
164    unsigned numWebViews;
165}
166@end
167
168@implementation WebPreferencesPrivate
169- (void)dealloc
170{
171    [values release];
172    [identifier release];
173    [IBCreatorID release];
174    [super dealloc];
175}
176@end
177
178@interface WebPreferences (WebInternal)
179+ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
180+ (NSString *)_IBCreatorID;
181@end
182
183@interface WebPreferences (WebForwardDeclarations)
184// This pseudo-category is needed so these methods can be used from within other category implementations
185// without being in the public header file.
186- (BOOL)_boolValueForKey:(NSString *)key;
187- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
188- (int)_integerValueForKey:(NSString *)key;
189- (void)_setIntegerValue:(int)value forKey:(NSString *)key;
190- (float)_floatValueForKey:(NSString *)key;
191- (void)_setFloatValue:(float)value forKey:(NSString *)key;
192- (void)_setLongLongValue:(long long)value forKey:(NSString *)key;
193- (long long)_longLongValueForKey:(NSString *)key;
194- (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key;
195- (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key;
196@end
197
198@implementation WebPreferences
199
200- (id)init
201{
202    // Create fake identifier
203    static int instanceCount = 1;
204    NSString *fakeIdentifier;
205
206    // At least ensure that identifier hasn't been already used.
207    fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
208    while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
209        fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
210    }
211
212    return [self initWithIdentifier:fakeIdentifier];
213}
214
215- (id)initWithIdentifier:(NSString *)anIdentifier
216{
217    self = [super init];
218    if (!self)
219        return nil;
220
221    _private = [[WebPreferencesPrivate alloc] init];
222    _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
223
224    WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
225    if (instance){
226        [self release];
227        return [instance retain];
228    }
229
230    _private->values = [[NSMutableDictionary alloc] init];
231    _private->identifier = [anIdentifier copy];
232    _private->automaticallyDetectsCacheModel = YES;
233
234    [[self class] _setInstance:self forIdentifier:_private->identifier];
235
236    [self _postPreferencesChangedNotification];
237
238    return self;
239}
240
241- (id)initWithCoder:(NSCoder *)decoder
242{
243    self = [super init];
244    if (!self)
245        return nil;
246
247    _private = [[WebPreferencesPrivate alloc] init];
248    _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
249    _private->automaticallyDetectsCacheModel = YES;
250
251    @try {
252        id identifier = nil;
253        id values = nil;
254        if ([decoder allowsKeyedCoding]) {
255            identifier = [decoder decodeObjectForKey:@"Identifier"];
256            values = [decoder decodeObjectForKey:@"Values"];
257        } else {
258            int version;
259            [decoder decodeValueOfObjCType:@encode(int) at:&version];
260            if (version == 1) {
261                identifier = [decoder decodeObject];
262                values = [decoder decodeObject];
263            }
264        }
265
266        if ([identifier isKindOfClass:[NSString class]])
267            _private->identifier = [identifier copy];
268        if ([values isKindOfClass:[NSDictionary class]])
269            _private->values = [values mutableCopy]; // ensure dictionary is mutable
270
271        LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
272    } @catch(id) {
273        [self release];
274        return nil;
275    }
276
277    // If we load a nib multiple times, or have instances in multiple
278    // nibs with the same name, the first guy up wins.
279    WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
280    if (instance) {
281        [self release];
282        self = [instance retain];
283    } else {
284        [[self class] _setInstance:self forIdentifier:_private->identifier];
285    }
286
287    return self;
288}
289
290- (void)encodeWithCoder:(NSCoder *)encoder
291{
292    if ([encoder allowsKeyedCoding]){
293        [encoder encodeObject:_private->identifier forKey:@"Identifier"];
294        [encoder encodeObject:_private->values forKey:@"Values"];
295        LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
296    }
297    else {
298        int version = WebPreferencesVersion;
299        [encoder encodeValueOfObjCType:@encode(int) at:&version];
300        [encoder encodeObject:_private->identifier];
301        [encoder encodeObject:_private->values];
302    }
303}
304
305+ (WebPreferences *)standardPreferences
306{
307    if (_standardPreferences == nil) {
308        _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
309        [_standardPreferences setAutosaves:YES];
310    }
311
312    return _standardPreferences;
313}
314
315// if we ever have more than one WebPreferences object, this would move to init
316+ (void)initialize
317{
318    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
319        @"Times",                       WebKitStandardFontPreferenceKey,
320        @"Courier",                     WebKitFixedFontPreferenceKey,
321        @"Times",                       WebKitSerifFontPreferenceKey,
322        @"Helvetica",                   WebKitSansSerifFontPreferenceKey,
323        @"Apple Chancery",              WebKitCursiveFontPreferenceKey,
324        @"Papyrus",                     WebKitFantasyFontPreferenceKey,
325        @"0",                           WebKitMinimumFontSizePreferenceKey,
326        @"9",                           WebKitMinimumLogicalFontSizePreferenceKey,
327        @"16",                          WebKitDefaultFontSizePreferenceKey,
328        @"13",                          WebKitDefaultFixedFontSizePreferenceKey,
329        @"ISO-8859-1",                  WebKitDefaultTextEncodingNamePreferenceKey,
330        [NSNumber numberWithBool:NO],   WebKitUsesEncodingDetectorPreferenceKey,
331        [NSNumber numberWithBool:NO],   WebKitUserStyleSheetEnabledPreferenceKey,
332        @"",                            WebKitUserStyleSheetLocationPreferenceKey,
333        [NSNumber numberWithBool:NO],   WebKitShouldPrintBackgroundsPreferenceKey,
334        [NSNumber numberWithBool:NO],   WebKitTextAreasAreResizablePreferenceKey,
335        [NSNumber numberWithBool:NO],   WebKitShrinksStandaloneImagesToFitPreferenceKey,
336        [NSNumber numberWithBool:YES],  WebKitJavaEnabledPreferenceKey,
337        [NSNumber numberWithBool:YES],  WebKitJavaScriptEnabledPreferenceKey,
338        [NSNumber numberWithBool:YES],  WebKitWebSecurityEnabledPreferenceKey,
339        [NSNumber numberWithBool:YES],  WebKitAllowUniversalAccessFromFileURLsPreferenceKey,
340        [NSNumber numberWithBool:YES],  WebKitAllowFileAccessFromFileURLsPreferenceKey,
341        [NSNumber numberWithBool:YES],  WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
342        [NSNumber numberWithBool:YES],  WebKitPluginsEnabledPreferenceKey,
343        [NSNumber numberWithBool:YES],  WebKitDatabasesEnabledPreferenceKey,
344        [NSNumber numberWithBool:YES],  WebKitLocalStorageEnabledPreferenceKey,
345        [NSNumber numberWithBool:NO],   WebKitExperimentalNotificationsEnabledPreferenceKey,
346        [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImagesPreferenceKey,
347        [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImageLoopingPreferenceKey,
348        [NSNumber numberWithBool:YES],  WebKitDisplayImagesKey,
349        [NSNumber numberWithBool:NO],   WebKitLoadSiteIconsKey,
350        @"1800",                        WebKitBackForwardCacheExpirationIntervalKey,
351        [NSNumber numberWithBool:NO],   WebKitTabToLinksPreferenceKey,
352        [NSNumber numberWithBool:NO],   WebKitPrivateBrowsingEnabledPreferenceKey,
353        [NSNumber numberWithBool:NO],   WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
354        [NSNumber numberWithBool:NO],   WebKitShowsURLsInToolTipsPreferenceKey,
355        @"1",                           WebKitPDFDisplayModePreferenceKey,
356        @"0",                           WebKitPDFScaleFactorPreferenceKey,
357        @"0",                           WebKitUseSiteSpecificSpoofingPreferenceKey,
358        [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
359        [NSNumber numberWithInt:WebKitEditingMacBehavior], WebKitEditingBehaviorPreferenceKey,
360#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
361        [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],
362#else
363        [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded],
364#endif
365                                        WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey,
366        [NSNumber numberWithBool:NO],   WebKitDOMPasteAllowedPreferenceKey,
367        [NSNumber numberWithBool:YES],  WebKitUsesPageCachePreferenceKey,
368        [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
369        [NSNumber numberWithBool:NO],   WebKitDeveloperExtrasEnabledPreferenceKey,
370        [NSNumber numberWithBool:YES],  WebKitAuthorAndUserStylesEnabledPreferenceKey,
371        [NSNumber numberWithBool:NO],   WebKitApplicationChromeModeEnabledPreferenceKey,
372        [NSNumber numberWithBool:NO],   WebKitWebArchiveDebugModeEnabledPreferenceKey,
373        [NSNumber numberWithBool:NO],   WebKitLocalFileContentSniffingEnabledPreferenceKey,
374        [NSNumber numberWithBool:NO],   WebKitOfflineWebApplicationCacheEnabledPreferenceKey,
375        [NSNumber numberWithBool:YES],  WebKitZoomsTextOnlyPreferenceKey,
376        [NSNumber numberWithBool:NO],   WebKitJavaScriptCanAccessClipboardPreferenceKey,
377        [NSNumber numberWithBool:YES],  WebKitXSSAuditorEnabledPreferenceKey,
378        [NSNumber numberWithBool:YES],  WebKitAcceleratedCompositingEnabledPreferenceKey,
379        [NSNumber numberWithBool:NO],  WebKitAcceleratedDrawingEnabledPreferenceKey,
380        [NSNumber numberWithBool:NO],  WebKitCanvasUsesAcceleratedDrawingPreferenceKey,
381        [NSNumber numberWithBool:NO],   WebKitShowDebugBordersPreferenceKey,
382        [NSNumber numberWithBool:NO],   WebKitShowRepaintCounterPreferenceKey,
383        [NSNumber numberWithBool:NO],   WebKitWebGLEnabledPreferenceKey,
384        [NSNumber numberWithBool:NO],   WebKitAccelerated2dCanvasEnabledPreferenceKey,
385        [NSNumber numberWithUnsignedInt:4], WebKitPluginAllowedRunTimePreferenceKey,
386        [NSNumber numberWithBool:NO],   WebKitFrameFlatteningEnabledPreferenceKey,
387        [NSNumber numberWithBool:NO],   WebKitSpatialNavigationEnabledPreferenceKey,
388        [NSNumber numberWithBool:NO],  WebKitDNSPrefetchingEnabledPreferenceKey,
389        [NSNumber numberWithBool:YES],  WebKitFullScreenEnabledPreferenceKey,
390        [NSNumber numberWithBool:NO],   WebKitAsynchronousSpellCheckingEnabledPreferenceKey,
391        [NSNumber numberWithBool:NO],   WebKitMemoryInfoEnabledPreferenceKey,
392        [NSNumber numberWithBool:YES],  WebKitHyperlinkAuditingEnabledPreferenceKey,
393        [NSNumber numberWithBool:NO],   WebKitUsePreHTML5ParserQuirksKey,
394        [NSNumber numberWithBool:useQuickLookQuirks()], WebKitUseQuickLookResourceCachingQuirksPreferenceKey,
395        [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
396        [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota,
397        nil];
398
399    // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
400    ASSERT(kPDFDisplaySinglePageContinuous == 1);
401    [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
402}
403
404- (void)dealloc
405{
406    [_private release];
407    [super dealloc];
408}
409
410- (NSString *)identifier
411{
412    return _private->identifier;
413}
414
415- (id)_valueForKey:(NSString *)key
416{
417    NSString *_key = KEY(key);
418    id o = [_private->values objectForKey:_key];
419    if (o)
420        return o;
421    o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
422    if (!o && key != _key)
423        o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
424    return o;
425}
426
427- (NSString *)_stringValueForKey:(NSString *)key
428{
429    id s = [self _valueForKey:key];
430    return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
431}
432
433- (void)_setStringValue:(NSString *)value forKey:(NSString *)key
434{
435    if ([[self _stringValueForKey:key] isEqualToString:value])
436        return;
437    NSString *_key = KEY(key);
438    [_private->values setObject:value forKey:_key];
439    if (_private->autosaves)
440        [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
441    [self _postPreferencesChangedNotification];
442}
443
444- (int)_integerValueForKey:(NSString *)key
445{
446    id o = [self _valueForKey:key];
447    return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
448}
449
450- (void)_setIntegerValue:(int)value forKey:(NSString *)key
451{
452    if ([self _integerValueForKey:key] == value)
453        return;
454    NSString *_key = KEY(key);
455    [_private->values _webkit_setInt:value forKey:_key];
456    if (_private->autosaves)
457        [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
458    [self _postPreferencesChangedNotification];
459}
460
461- (float)_floatValueForKey:(NSString *)key
462{
463    id o = [self _valueForKey:key];
464    return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
465}
466
467- (void)_setFloatValue:(float)value forKey:(NSString *)key
468{
469    if ([self _floatValueForKey:key] == value)
470        return;
471    NSString *_key = KEY(key);
472    [_private->values _webkit_setFloat:value forKey:_key];
473    if (_private->autosaves)
474        [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
475    [self _postPreferencesChangedNotification];
476}
477
478- (BOOL)_boolValueForKey:(NSString *)key
479{
480    return [self _integerValueForKey:key] != 0;
481}
482
483- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
484{
485    if ([self _boolValueForKey:key] == value)
486        return;
487    NSString *_key = KEY(key);
488    [_private->values _webkit_setBool:value forKey:_key];
489    if (_private->autosaves)
490        [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
491    [self _postPreferencesChangedNotification];
492}
493
494- (long long)_longLongValueForKey:(NSString *)key
495{
496    id o = [self _valueForKey:key];
497    return [o respondsToSelector:@selector(longLongValue)] ? [o longLongValue] : 0;
498}
499
500- (void)_setLongLongValue:(long long)value forKey:(NSString *)key
501{
502    if ([self _longLongValueForKey:key] == value)
503        return;
504    NSString *_key = KEY(key);
505    [_private->values _webkit_setLongLong:value forKey:_key];
506    if (_private->autosaves)
507        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key];
508    [self _postPreferencesChangedNotification];
509}
510
511- (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
512{
513    id o = [self _valueForKey:key];
514    return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
515}
516
517- (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
518{
519    if ([self _unsignedLongLongValueForKey:key] == value)
520        return;
521    NSString *_key = KEY(key);
522    [_private->values _webkit_setUnsignedLongLong:value forKey:_key];
523    if (_private->autosaves)
524        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
525    [self _postPreferencesChangedNotification];
526}
527
528- (NSString *)standardFontFamily
529{
530    return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
531}
532
533- (void)setStandardFontFamily:(NSString *)family
534{
535    [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
536}
537
538- (NSString *)fixedFontFamily
539{
540    return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
541}
542
543- (void)setFixedFontFamily:(NSString *)family
544{
545    [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
546}
547
548- (NSString *)serifFontFamily
549{
550    return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
551}
552
553- (void)setSerifFontFamily:(NSString *)family
554{
555    [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
556}
557
558- (NSString *)sansSerifFontFamily
559{
560    return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
561}
562
563- (void)setSansSerifFontFamily:(NSString *)family
564{
565    [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
566}
567
568- (NSString *)cursiveFontFamily
569{
570    return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
571}
572
573- (void)setCursiveFontFamily:(NSString *)family
574{
575    [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
576}
577
578- (NSString *)fantasyFontFamily
579{
580    return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
581}
582
583- (void)setFantasyFontFamily:(NSString *)family
584{
585    [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
586}
587
588- (int)defaultFontSize
589{
590    return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
591}
592
593- (void)setDefaultFontSize:(int)size
594{
595    [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
596}
597
598- (int)defaultFixedFontSize
599{
600    return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
601}
602
603- (void)setDefaultFixedFontSize:(int)size
604{
605    [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
606}
607
608- (int)minimumFontSize
609{
610    return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
611}
612
613- (void)setMinimumFontSize:(int)size
614{
615    [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
616}
617
618- (int)minimumLogicalFontSize
619{
620  return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
621}
622
623- (void)setMinimumLogicalFontSize:(int)size
624{
625  [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
626}
627
628- (NSString *)defaultTextEncodingName
629{
630    return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
631}
632
633- (void)setDefaultTextEncodingName:(NSString *)encoding
634{
635    [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
636}
637
638- (BOOL)userStyleSheetEnabled
639{
640    return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
641}
642
643- (void)setUserStyleSheetEnabled:(BOOL)flag
644{
645    [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
646}
647
648- (NSURL *)userStyleSheetLocation
649{
650    NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
651
652    if ([locationString _webkit_looksLikeAbsoluteURL]) {
653        return [NSURL _web_URLWithDataAsString:locationString];
654    } else {
655        locationString = [locationString stringByExpandingTildeInPath];
656        return [NSURL fileURLWithPath:locationString];
657    }
658}
659
660- (void)setUserStyleSheetLocation:(NSURL *)URL
661{
662    NSString *locationString;
663
664    if ([URL isFileURL]) {
665        locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
666    } else {
667        locationString = [URL _web_originalDataAsString];
668    }
669
670    if (!locationString)
671        locationString = @"";
672
673    [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
674}
675
676- (BOOL)shouldPrintBackgrounds
677{
678    return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
679}
680
681- (void)setShouldPrintBackgrounds:(BOOL)flag
682{
683    [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
684}
685
686- (BOOL)isJavaEnabled
687{
688    return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
689}
690
691- (void)setJavaEnabled:(BOOL)flag
692{
693    [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
694}
695
696- (BOOL)isJavaScriptEnabled
697{
698    return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
699}
700
701- (void)setJavaScriptEnabled:(BOOL)flag
702{
703    [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
704}
705
706- (BOOL)javaScriptCanOpenWindowsAutomatically
707{
708    return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
709}
710
711- (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
712{
713    [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
714}
715
716- (BOOL)arePlugInsEnabled
717{
718    return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
719}
720
721- (void)setPlugInsEnabled:(BOOL)flag
722{
723    [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
724}
725
726- (BOOL)allowsAnimatedImages
727{
728    return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
729}
730
731- (void)setAllowsAnimatedImages:(BOOL)flag
732{
733    [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
734}
735
736- (BOOL)allowsAnimatedImageLooping
737{
738    return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
739}
740
741- (void)setAllowsAnimatedImageLooping: (BOOL)flag
742{
743    [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
744}
745
746- (void)setLoadsImagesAutomatically: (BOOL)flag
747{
748    [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
749}
750
751- (BOOL)loadsImagesAutomatically
752{
753    return [self _boolValueForKey: WebKitDisplayImagesKey];
754}
755
756- (void)setAutosaves:(BOOL)flag
757{
758    _private->autosaves = flag;
759}
760
761- (BOOL)autosaves
762{
763    return _private->autosaves;
764}
765
766- (void)setTabsToLinks:(BOOL)flag
767{
768    [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
769}
770
771- (BOOL)tabsToLinks
772{
773    return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
774}
775
776- (void)setPrivateBrowsingEnabled:(BOOL)flag
777{
778    [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
779}
780
781- (BOOL)privateBrowsingEnabled
782{
783    return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
784}
785
786- (void)setUsesPageCache:(BOOL)usesPageCache
787{
788    [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
789}
790
791- (BOOL)usesPageCache
792{
793    return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
794}
795
796- (void)setCacheModel:(WebCacheModel)cacheModel
797{
798    [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
799    [self setAutomaticallyDetectsCacheModel:NO];
800}
801
802- (WebCacheModel)cacheModel
803{
804    return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
805}
806
807@end
808
809@implementation WebPreferences (WebPrivate)
810
811- (BOOL)isDNSPrefetchingEnabled
812{
813    return [self _boolValueForKey:WebKitDNSPrefetchingEnabledPreferenceKey];
814}
815
816- (void)setDNSPrefetchingEnabled:(BOOL)flag
817{
818    [self _setBoolValue:flag forKey:WebKitDNSPrefetchingEnabledPreferenceKey];
819}
820
821- (BOOL)developerExtrasEnabled
822{
823    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
824    if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
825        return NO;
826#ifdef NDEBUG
827    if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
828        return YES;
829    return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
830#else
831    return YES; // always enable in debug builds
832#endif
833}
834
835- (void)setDeveloperExtrasEnabled:(BOOL)flag
836{
837    [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
838}
839
840- (BOOL)authorAndUserStylesEnabled
841{
842    return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
843}
844
845- (void)setAuthorAndUserStylesEnabled:(BOOL)flag
846{
847    [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
848}
849
850- (BOOL)applicationChromeModeEnabled
851{
852    return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey];
853}
854
855- (void)setApplicationChromeModeEnabled:(BOOL)flag
856{
857    [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey];
858}
859
860- (BOOL)webArchiveDebugModeEnabled
861{
862    return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
863}
864
865- (void)setWebArchiveDebugModeEnabled:(BOOL)flag
866{
867    [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
868}
869
870- (BOOL)localFileContentSniffingEnabled
871{
872    return [self _boolValueForKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
873}
874
875- (void)setLocalFileContentSniffingEnabled:(BOOL)flag
876{
877    [self _setBoolValue:flag forKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
878}
879
880- (BOOL)offlineWebApplicationCacheEnabled
881{
882    return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
883}
884
885- (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
886{
887    [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
888}
889
890- (BOOL)zoomsTextOnly
891{
892    return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
893}
894
895- (void)setZoomsTextOnly:(BOOL)flag
896{
897    [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
898}
899
900- (BOOL)javaScriptCanAccessClipboard
901{
902    return [self _boolValueForKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
903}
904
905- (void)setJavaScriptCanAccessClipboard:(BOOL)flag
906{
907    [self _setBoolValue:flag forKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
908}
909
910- (BOOL)isXSSAuditorEnabled
911{
912    return [self _boolValueForKey:WebKitXSSAuditorEnabledPreferenceKey];
913}
914
915- (void)setXSSAuditorEnabled:(BOOL)flag
916{
917    [self _setBoolValue:flag forKey:WebKitXSSAuditorEnabledPreferenceKey];
918}
919
920- (BOOL)respectStandardStyleKeyEquivalents
921{
922    return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
923}
924
925- (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
926{
927    [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
928}
929
930- (BOOL)showsURLsInToolTips
931{
932    return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
933}
934
935- (void)setShowsURLsInToolTips:(BOOL)flag
936{
937    [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
938}
939
940- (BOOL)textAreasAreResizable
941{
942    return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
943}
944
945- (void)setTextAreasAreResizable:(BOOL)flag
946{
947    [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
948}
949
950- (BOOL)shrinksStandaloneImagesToFit
951{
952    return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
953}
954
955- (void)setShrinksStandaloneImagesToFit:(BOOL)flag
956{
957    [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
958}
959
960- (BOOL)automaticallyDetectsCacheModel
961{
962    return _private->automaticallyDetectsCacheModel;
963}
964
965- (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
966{
967    _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
968}
969
970- (BOOL)usesEncodingDetector
971{
972    return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey];
973}
974
975- (void)setUsesEncodingDetector:(BOOL)flag
976{
977    [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey];
978}
979
980- (BOOL)isWebSecurityEnabled
981{
982    return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
983}
984
985- (void)setWebSecurityEnabled:(BOOL)flag
986{
987    [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
988}
989
990- (BOOL)allowUniversalAccessFromFileURLs
991{
992    return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
993}
994
995- (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
996{
997    [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
998}
999
1000- (BOOL)allowFileAccessFromFileURLs
1001{
1002    return [self _boolValueForKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
1003}
1004
1005- (void)setAllowFileAccessFromFileURLs:(BOOL)flag
1006{
1007    [self _setBoolValue: flag forKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
1008}
1009
1010- (NSTimeInterval)_backForwardCacheExpirationInterval
1011{
1012    // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
1013    return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
1014}
1015
1016- (float)PDFScaleFactor
1017{
1018    return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
1019}
1020
1021- (void)setPDFScaleFactor:(float)factor
1022{
1023    [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
1024}
1025
1026- (int64_t)applicationCacheTotalQuota
1027{
1028    return [self _longLongValueForKey:WebKitApplicationCacheTotalQuota];
1029}
1030
1031- (void)setApplicationCacheTotalQuota:(int64_t)quota
1032{
1033    [self _setLongLongValue:quota forKey:WebKitApplicationCacheTotalQuota];
1034
1035    // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
1036    [WebApplicationCache setMaximumSize:quota];
1037}
1038
1039- (int64_t)applicationCacheDefaultOriginQuota
1040{
1041    return [self _longLongValueForKey:WebKitApplicationCacheDefaultOriginQuota];
1042}
1043
1044- (void)setApplicationCacheDefaultOriginQuota:(int64_t)quota
1045{
1046    [self _setLongLongValue:quota forKey:WebKitApplicationCacheDefaultOriginQuota];
1047}
1048
1049- (PDFDisplayMode)PDFDisplayMode
1050{
1051    PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
1052    if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
1053        // protect against new modes from future versions of OS X stored in defaults
1054        value = kPDFDisplaySinglePageContinuous;
1055    }
1056    return value;
1057}
1058
1059- (void)setPDFDisplayMode:(PDFDisplayMode)mode
1060{
1061    [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
1062}
1063
1064- (WebKitEditableLinkBehavior)editableLinkBehavior
1065{
1066    WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
1067    if (value != WebKitEditableLinkDefaultBehavior &&
1068        value != WebKitEditableLinkAlwaysLive &&
1069        value != WebKitEditableLinkNeverLive &&
1070        value != WebKitEditableLinkOnlyLiveWithShiftKey &&
1071        value != WebKitEditableLinkLiveWhenNotFocused) {
1072        // ensure that a valid result is returned
1073        value = WebKitEditableLinkDefaultBehavior;
1074    }
1075
1076    return value;
1077}
1078
1079- (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
1080{
1081    [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
1082}
1083
1084- (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
1085{
1086    WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
1087    if (value != WebTextDirectionSubmenuNeverIncluded &&
1088        value != WebTextDirectionSubmenuAutomaticallyIncluded &&
1089        value != WebTextDirectionSubmenuAlwaysIncluded) {
1090        // Ensure that a valid result is returned.
1091        value = WebTextDirectionSubmenuNeverIncluded;
1092    }
1093    return value;
1094}
1095
1096- (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
1097{
1098    [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
1099}
1100
1101- (BOOL)_useSiteSpecificSpoofing
1102{
1103    return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1104}
1105
1106- (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
1107{
1108    [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1109}
1110
1111- (BOOL)databasesEnabled
1112{
1113    return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
1114}
1115
1116- (void)setDatabasesEnabled:(BOOL)databasesEnabled
1117{
1118    [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
1119}
1120
1121- (BOOL)localStorageEnabled
1122{
1123    return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
1124}
1125
1126- (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
1127{
1128    [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
1129}
1130
1131- (BOOL)experimentalNotificationsEnabled
1132{
1133    return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1134}
1135
1136- (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled
1137{
1138    [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1139}
1140
1141+ (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
1142{
1143    LOG(Encoding, "requesting for %@\n", ident);
1144
1145    if (!ident)
1146        return _standardPreferences;
1147
1148    WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
1149
1150    return instance;
1151}
1152
1153+ (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
1154{
1155    if (!webPreferencesInstances)
1156        webPreferencesInstances = [[NSMutableDictionary alloc] init];
1157    if (ident) {
1158        [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1159        LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1160    }
1161}
1162
1163+ (void)_checkLastReferenceForIdentifier:(id)identifier
1164{
1165    // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1166    // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1167    WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1168    if ([instance retainCount] == 1)
1169        [webPreferencesInstances removeObjectForKey:identifier];
1170}
1171
1172+ (void)_removeReferenceForIdentifier:(NSString *)ident
1173{
1174    if (ident)
1175        [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1176}
1177
1178- (void)_postPreferencesChangedNotification
1179{
1180    if (!pthread_main_np()) {
1181        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1182        return;
1183    }
1184
1185    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedInternalNotification object:self userInfo:nil];
1186    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
1187}
1188
1189- (void)_postPreferencesChangedAPINotification
1190{
1191    if (!pthread_main_np()) {
1192        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1193        return;
1194    }
1195
1196    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
1197}
1198
1199+ (CFStringEncoding)_systemCFStringEncoding
1200{
1201    return WKGetWebDefaultCFStringEncoding();
1202}
1203
1204+ (void)_setInitialDefaultTextEncodingToSystemEncoding
1205{
1206    NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]);
1207
1208    // CFStringConvertEncodingToIANACharSetName() returns cp949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-949.
1209    // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-949.
1210    // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>.
1211    // On some OS versions, the result is CP949 (uppercase).
1212    if ([systemEncodingName _webkit_isCaseInsensitiveEqualToString:@"cp949"])
1213        systemEncodingName = @"ks_c_5601-1987";
1214    [[NSUserDefaults standardUserDefaults] registerDefaults:
1215        [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1216}
1217
1218static NSString *classIBCreatorID = nil;
1219
1220+ (void)_setIBCreatorID:(NSString *)string
1221{
1222    NSString *old = classIBCreatorID;
1223    classIBCreatorID = [string copy];
1224    [old release];
1225}
1226
1227- (BOOL)isDOMPasteAllowed
1228{
1229    return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1230}
1231
1232- (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1233{
1234    [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1235}
1236
1237- (NSString *)_localStorageDatabasePath
1238{
1239    return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1240}
1241
1242- (void)_setLocalStorageDatabasePath:(NSString *)path
1243{
1244    [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1245}
1246
1247- (NSString *)_ftpDirectoryTemplatePath
1248{
1249    return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1250}
1251
1252- (void)_setFTPDirectoryTemplatePath:(NSString *)path
1253{
1254    [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1255}
1256
1257- (BOOL)_forceFTPDirectoryListings
1258{
1259    return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1260}
1261
1262- (void)_setForceFTPDirectoryListings:(BOOL)force
1263{
1264    [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1265}
1266
1267- (BOOL)acceleratedDrawingEnabled
1268{
1269    return [self _boolValueForKey:WebKitAcceleratedDrawingEnabledPreferenceKey];
1270}
1271
1272- (void)setAcceleratedDrawingEnabled:(BOOL)enabled
1273{
1274    [self _setBoolValue:enabled forKey:WebKitAcceleratedDrawingEnabledPreferenceKey];
1275}
1276
1277- (BOOL)canvasUsesAcceleratedDrawing
1278{
1279    return [self _boolValueForKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey];
1280}
1281
1282- (void)setCanvasUsesAcceleratedDrawing:(BOOL)enabled
1283{
1284    [self _setBoolValue:enabled forKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey];
1285}
1286
1287- (BOOL)acceleratedCompositingEnabled
1288{
1289    return [self _boolValueForKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1290}
1291
1292- (void)setAcceleratedCompositingEnabled:(BOOL)enabled
1293{
1294    [self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1295}
1296
1297- (BOOL)showDebugBorders
1298{
1299    return [self _boolValueForKey:WebKitShowDebugBordersPreferenceKey];
1300}
1301
1302- (void)setShowDebugBorders:(BOOL)enabled
1303{
1304    [self _setBoolValue:enabled forKey:WebKitShowDebugBordersPreferenceKey];
1305}
1306
1307- (BOOL)showRepaintCounter
1308{
1309    return [self _boolValueForKey:WebKitShowRepaintCounterPreferenceKey];
1310}
1311
1312- (void)setShowRepaintCounter:(BOOL)enabled
1313{
1314    [self _setBoolValue:enabled forKey:WebKitShowRepaintCounterPreferenceKey];
1315}
1316
1317- (BOOL)webAudioEnabled
1318{
1319    return [self _boolValueForKey:WebKitWebAudioEnabledPreferenceKey];
1320}
1321
1322- (void)setWebAudioEnabled:(BOOL)enabled
1323{
1324    [self _setBoolValue:enabled forKey:WebKitWebAudioEnabledPreferenceKey];
1325}
1326
1327- (BOOL)webGLEnabled
1328{
1329    return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey];
1330}
1331
1332- (void)setWebGLEnabled:(BOOL)enabled
1333{
1334    [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey];
1335}
1336
1337- (BOOL)accelerated2dCanvasEnabled
1338{
1339    return [self _boolValueForKey:WebKitAccelerated2dCanvasEnabledPreferenceKey];
1340}
1341
1342- (void)setAccelerated2dCanvasEnabled:(BOOL)enabled
1343{
1344    [self _setBoolValue:enabled forKey:WebKitAccelerated2dCanvasEnabledPreferenceKey];
1345}
1346
1347- (unsigned)pluginAllowedRunTime
1348{
1349    return [self _integerValueForKey:WebKitPluginAllowedRunTimePreferenceKey];
1350}
1351
1352- (void)setPluginAllowedRunTime:(unsigned)allowedRunTime
1353{
1354    return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey];
1355}
1356
1357- (BOOL)isFrameFlatteningEnabled
1358{
1359    return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey];
1360}
1361
1362- (void)setFrameFlatteningEnabled:(BOOL)flag
1363{
1364    [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey];
1365}
1366
1367- (BOOL)isSpatialNavigationEnabled
1368{
1369    return [self _boolValueForKey:WebKitSpatialNavigationEnabledPreferenceKey];
1370}
1371
1372- (void)setSpatialNavigationEnabled:(BOOL)flag
1373{
1374    [self _setBoolValue:flag forKey:WebKitSpatialNavigationEnabledPreferenceKey];
1375}
1376
1377- (BOOL)paginateDuringLayoutEnabled
1378{
1379    return [self _boolValueForKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1380}
1381
1382- (void)setPaginateDuringLayoutEnabled:(BOOL)flag
1383{
1384    [self _setBoolValue:flag forKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1385}
1386
1387- (BOOL)memoryInfoEnabled
1388{
1389    return [self _boolValueForKey:WebKitMemoryInfoEnabledPreferenceKey];
1390}
1391
1392- (void)setMemoryInfoEnabled:(BOOL)flag
1393{
1394    [self _setBoolValue:flag forKey:WebKitMemoryInfoEnabledPreferenceKey];
1395}
1396
1397- (BOOL)hyperlinkAuditingEnabled
1398{
1399    return [self _boolValueForKey:WebKitHyperlinkAuditingEnabledPreferenceKey];
1400}
1401
1402- (void)setHyperlinkAuditingEnabled:(BOOL)flag
1403{
1404    [self _setBoolValue:flag forKey:WebKitHyperlinkAuditingEnabledPreferenceKey];
1405}
1406
1407- (WebKitEditingBehavior)editingBehavior
1408{
1409    return static_cast<WebKitEditingBehavior>([self _integerValueForKey:WebKitEditingBehaviorPreferenceKey]);
1410}
1411
1412- (void)setEditingBehavior:(WebKitEditingBehavior)behavior
1413{
1414    [self _setIntegerValue:behavior forKey:WebKitEditingBehaviorPreferenceKey];
1415}
1416
1417- (BOOL)usePreHTML5ParserQuirks
1418{
1419    return [self _boolValueForKey:WebKitUsePreHTML5ParserQuirksKey];
1420}
1421
1422- (void)setUsePreHTML5ParserQuirks:(BOOL)flag
1423{
1424    [self _setBoolValue:flag forKey:WebKitUsePreHTML5ParserQuirksKey];
1425}
1426
1427- (BOOL)useQuickLookResourceCachingQuirks
1428{
1429    return [self _boolValueForKey:WebKitUseQuickLookResourceCachingQuirksPreferenceKey];
1430}
1431
1432- (void)didRemoveFromWebView
1433{
1434    ASSERT(_private->numWebViews);
1435    if (--_private->numWebViews == 0)
1436        [[NSNotificationCenter defaultCenter]
1437            postNotificationName:WebPreferencesRemovedNotification
1438                          object:self
1439                        userInfo:nil];
1440}
1441
1442- (void)willAddToWebView
1443{
1444    ++_private->numWebViews;
1445}
1446
1447- (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key
1448{
1449    [self _setStringValue:value forKey:key];
1450}
1451
1452- (void)setFullScreenEnabled:(BOOL)flag
1453{
1454    [self _setBoolValue:flag forKey:WebKitFullScreenEnabledPreferenceKey];
1455}
1456
1457- (BOOL)fullScreenEnabled
1458{
1459    return [self _boolValueForKey:WebKitFullScreenEnabledPreferenceKey];
1460}
1461
1462- (void)setAsynchronousSpellCheckingEnabled:(BOOL)flag
1463{
1464    [self _setBoolValue:flag forKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey];
1465}
1466
1467- (BOOL)asynchronousSpellCheckingEnabled
1468{
1469    return [self _boolValueForKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey];
1470}
1471
1472+ (void)setWebKitLinkTimeVersion:(int)version
1473{
1474    setWebKitLinkTimeVersion(version);
1475}
1476
1477- (void)setLoadsSiteIconsIgnoringImageLoadingPreference: (BOOL)flag
1478{
1479    [self _setBoolValue: flag forKey: WebKitLoadSiteIconsKey];
1480}
1481
1482- (BOOL)loadsSiteIconsIgnoringImageLoadingPreference
1483{
1484    return [self _boolValueForKey: WebKitLoadSiteIconsKey];
1485}
1486
1487@end
1488
1489@implementation WebPreferences (WebInternal)
1490
1491+ (NSString *)_IBCreatorID
1492{
1493    return classIBCreatorID;
1494}
1495
1496+ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
1497{
1498    NSString *IBCreatorID = [WebPreferences _IBCreatorID];
1499    if (!IBCreatorID)
1500        return key;
1501    return [IBCreatorID stringByAppendingString:key];
1502}
1503
1504@end
1505