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