2010-08-24 Eric Seidel <eric@webkit.org>
[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],  WebKitDNSPrefetchingEnabledPreferenceKey,
368         [NSNumber numberWithBool:NO],   WebKitMemoryInfoEnabledPreferenceKey,
369         [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
370         [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota,
371         nil];
372
373     // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
374     ASSERT(kPDFDisplaySinglePageContinuous == 1);
375     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
376 }
377
378 - (void)dealloc
379 {
380     [_private release];
381     [super dealloc];
382 }
383
384 - (NSString *)identifier
385 {
386     return _private->identifier;
387 }
388
389 - (id)_valueForKey:(NSString *)key
390 {
391     NSString *_key = KEY(key);
392     id o = [_private->values objectForKey:_key];
393     if (o)
394         return o;
395     o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
396     if (!o && key != _key)
397         o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
398     return o;
399 }
400
401 - (NSString *)_stringValueForKey:(NSString *)key
402 {
403     id s = [self _valueForKey:key];
404     return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
405 }
406
407 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
408 {
409     if ([[self _stringValueForKey:key] isEqualToString:value])
410         return;
411     NSString *_key = KEY(key);
412     [_private->values setObject:value forKey:_key];
413     if (_private->autosaves)
414         [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
415     [self _postPreferencesChangesNotification];
416 }
417
418 - (int)_integerValueForKey:(NSString *)key
419 {
420     id o = [self _valueForKey:key];
421     return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
422 }
423
424 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
425 {
426     if ([self _integerValueForKey:key] == value)
427         return;
428     NSString *_key = KEY(key);
429     [_private->values _webkit_setInt:value forKey:_key];
430     if (_private->autosaves)
431         [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
432     [self _postPreferencesChangesNotification];
433 }
434
435 - (float)_floatValueForKey:(NSString *)key
436 {
437     id o = [self _valueForKey:key];
438     return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
439 }
440
441 - (void)_setFloatValue:(float)value forKey:(NSString *)key
442 {
443     if ([self _floatValueForKey:key] == value)
444         return;
445     NSString *_key = KEY(key);
446     [_private->values _webkit_setFloat:value forKey:_key];
447     if (_private->autosaves)
448         [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
449     [self _postPreferencesChangesNotification];
450 }
451
452 - (BOOL)_boolValueForKey:(NSString *)key
453 {
454     return [self _integerValueForKey:key] != 0;
455 }
456
457 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
458 {
459     if ([self _boolValueForKey:key] == value)
460         return;
461     NSString *_key = KEY(key);
462     [_private->values _webkit_setBool:value forKey:_key];
463     if (_private->autosaves)
464         [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
465     [self _postPreferencesChangesNotification];
466 }
467
468 - (long long)_longLongValueForKey:(NSString *)key
469 {
470     id o = [self _valueForKey:key];
471     return [o respondsToSelector:@selector(longLongValue)] ? [o longLongValue] : 0;
472 }
473
474 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key
475 {
476     if ([self _longLongValueForKey:key] == value)
477         return;
478     NSString *_key = KEY(key);
479     [_private->values _webkit_setLongLong:value forKey:_key];
480     if (_private->autosaves)
481         [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key];
482     [self _postPreferencesChangesNotification];
483 }
484
485 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
486 {
487     id o = [self _valueForKey:key];
488     return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
489 }
490
491 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
492 {
493     if ([self _unsignedLongLongValueForKey:key] == value)
494         return;
495     NSString *_key = KEY(key);
496     [_private->values _webkit_setUnsignedLongLong:value forKey:_key];
497     if (_private->autosaves)
498         [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
499     [self _postPreferencesChangesNotification];
500 }
501
502 - (NSString *)standardFontFamily
503 {
504     return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
505 }
506
507 - (void)setStandardFontFamily:(NSString *)family
508 {
509     [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
510 }
511
512 - (NSString *)fixedFontFamily
513 {
514     return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
515 }
516
517 - (void)setFixedFontFamily:(NSString *)family
518 {
519     [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
520 }
521
522 - (NSString *)serifFontFamily
523 {
524     return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
525 }
526
527 - (void)setSerifFontFamily:(NSString *)family 
528 {
529     [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
530 }
531
532 - (NSString *)sansSerifFontFamily
533 {
534     return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
535 }
536
537 - (void)setSansSerifFontFamily:(NSString *)family
538 {
539     [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
540 }
541
542 - (NSString *)cursiveFontFamily
543 {
544     return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
545 }
546
547 - (void)setCursiveFontFamily:(NSString *)family
548 {
549     [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
550 }
551
552 - (NSString *)fantasyFontFamily
553 {
554     return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
555 }
556
557 - (void)setFantasyFontFamily:(NSString *)family
558 {
559     [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
560 }
561
562 - (int)defaultFontSize
563 {
564     return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
565 }
566
567 - (void)setDefaultFontSize:(int)size
568 {
569     [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
570 }
571
572 - (int)defaultFixedFontSize
573 {
574     return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
575 }
576
577 - (void)setDefaultFixedFontSize:(int)size
578 {
579     [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
580 }
581
582 - (int)minimumFontSize
583 {
584     return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
585 }
586
587 - (void)setMinimumFontSize:(int)size
588 {
589     [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
590 }
591
592 - (int)minimumLogicalFontSize
593 {
594   return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
595 }
596
597 - (void)setMinimumLogicalFontSize:(int)size
598 {
599   [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
600 }
601
602 - (NSString *)defaultTextEncodingName
603 {
604     return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
605 }
606
607 - (void)setDefaultTextEncodingName:(NSString *)encoding
608 {
609     [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
610 }
611
612 - (BOOL)userStyleSheetEnabled
613 {
614     return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
615 }
616
617 - (void)setUserStyleSheetEnabled:(BOOL)flag
618 {
619     [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
620 }
621
622 - (NSURL *)userStyleSheetLocation
623 {
624     NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
625     
626     if ([locationString _webkit_looksLikeAbsoluteURL]) {
627         return [NSURL _web_URLWithDataAsString:locationString];
628     } else {
629         locationString = [locationString stringByExpandingTildeInPath];
630         return [NSURL fileURLWithPath:locationString];
631     }
632 }
633
634 - (void)setUserStyleSheetLocation:(NSURL *)URL
635 {
636     NSString *locationString;
637     
638     if ([URL isFileURL]) {
639         locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
640     } else {
641         locationString = [URL _web_originalDataAsString];
642     }
643     
644     [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
645 }
646
647 - (BOOL)shouldPrintBackgrounds
648 {
649     return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
650 }
651
652 - (void)setShouldPrintBackgrounds:(BOOL)flag
653 {
654     [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
655 }
656
657 - (BOOL)isJavaEnabled
658 {
659     return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
660 }
661
662 - (void)setJavaEnabled:(BOOL)flag
663 {
664     [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
665 }
666
667 - (BOOL)isJavaScriptEnabled
668 {
669     return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
670 }
671
672 - (void)setJavaScriptEnabled:(BOOL)flag
673 {
674     [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
675 }
676
677 - (BOOL)javaScriptCanOpenWindowsAutomatically
678 {
679     return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
680 }
681
682 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
683 {
684     [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
685 }
686
687 - (BOOL)arePlugInsEnabled
688 {
689     return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
690 }
691
692 - (void)setPlugInsEnabled:(BOOL)flag
693 {
694     [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
695 }
696
697 - (BOOL)allowsAnimatedImages
698 {
699     return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
700 }
701
702 - (void)setAllowsAnimatedImages:(BOOL)flag
703 {
704     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
705 }
706
707 - (BOOL)allowsAnimatedImageLooping
708 {
709     return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
710 }
711
712 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
713 {
714     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
715 }
716
717 - (void)setLoadsImagesAutomatically: (BOOL)flag
718 {
719     [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
720 }
721
722 - (BOOL)loadsImagesAutomatically
723 {
724     return [self _boolValueForKey: WebKitDisplayImagesKey];
725 }
726
727 - (void)setAutosaves:(BOOL)flag
728 {
729     _private->autosaves = flag;
730 }
731
732 - (BOOL)autosaves
733 {
734     return _private->autosaves;
735 }
736
737 - (void)setTabsToLinks:(BOOL)flag
738 {
739     [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
740 }
741
742 - (BOOL)tabsToLinks
743 {
744     return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
745 }
746
747 - (void)setPrivateBrowsingEnabled:(BOOL)flag
748 {
749     [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
750 }
751
752 - (BOOL)privateBrowsingEnabled
753 {
754     return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
755 }
756
757 - (void)setUsesPageCache:(BOOL)usesPageCache
758 {
759     [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
760 }
761
762 - (BOOL)usesPageCache
763 {
764     return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
765 }
766
767 - (void)setCacheModel:(WebCacheModel)cacheModel
768 {
769     [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
770     [self setAutomaticallyDetectsCacheModel:NO];
771 }
772
773 - (WebCacheModel)cacheModel
774 {
775     return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
776 }
777
778 @end
779
780 @implementation WebPreferences (WebPrivate)
781
782 - (BOOL)isDNSPrefetchingEnabled
783 {
784     return [self _boolValueForKey:WebKitDNSPrefetchingEnabledPreferenceKey];
785 }
786
787 - (void)setDNSPrefetchingEnabled:(BOOL)flag
788 {
789     [self _setBoolValue:flag forKey:WebKitDNSPrefetchingEnabledPreferenceKey];
790 }
791
792 - (BOOL)developerExtrasEnabled
793 {
794     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
795     if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
796         return NO;
797 #ifdef NDEBUG
798     if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
799         return YES;
800     return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
801 #else
802     return YES; // always enable in debug builds
803 #endif
804 }
805
806 - (void)setDeveloperExtrasEnabled:(BOOL)flag
807 {
808     [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
809 }
810
811 - (BOOL)authorAndUserStylesEnabled
812 {
813     return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
814 }
815
816 - (void)setAuthorAndUserStylesEnabled:(BOOL)flag
817 {
818     [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
819 }
820
821 - (BOOL)applicationChromeModeEnabled
822 {
823     return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey];
824 }
825
826 - (void)setApplicationChromeModeEnabled:(BOOL)flag
827 {
828     [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey];
829 }
830
831 - (BOOL)webArchiveDebugModeEnabled
832 {
833     return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
834 }
835
836 - (void)setWebArchiveDebugModeEnabled:(BOOL)flag
837 {
838     [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
839 }
840
841 - (BOOL)localFileContentSniffingEnabled
842 {
843     return [self _boolValueForKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
844 }
845
846 - (void)setLocalFileContentSniffingEnabled:(BOOL)flag
847 {
848     [self _setBoolValue:flag forKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
849 }
850
851 - (BOOL)offlineWebApplicationCacheEnabled
852 {
853     return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
854 }
855
856 - (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
857 {
858     [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
859 }
860
861 - (BOOL)zoomsTextOnly
862 {
863     return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
864 }
865
866 - (void)setZoomsTextOnly:(BOOL)flag
867 {
868     [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
869 }
870
871 - (BOOL)javaScriptCanAccessClipboard
872 {
873     return [self _boolValueForKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
874 }
875
876 - (void)setJavaScriptCanAccessClipboard:(BOOL)flag
877 {
878     [self _setBoolValue:flag forKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
879 }
880
881 - (BOOL)isXSSAuditorEnabled
882 {
883     return [self _boolValueForKey:WebKitXSSAuditorEnabledPreferenceKey];
884 }
885
886 - (void)setXSSAuditorEnabled:(BOOL)flag
887 {
888     [self _setBoolValue:flag forKey:WebKitXSSAuditorEnabledPreferenceKey];
889 }
890
891 - (BOOL)respectStandardStyleKeyEquivalents
892 {
893     return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
894 }
895
896 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
897 {
898     [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
899 }
900
901 - (BOOL)showsURLsInToolTips
902 {
903     return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
904 }
905
906 - (void)setShowsURLsInToolTips:(BOOL)flag
907 {
908     [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
909 }
910
911 - (BOOL)textAreasAreResizable
912 {
913     return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
914 }
915
916 - (void)setTextAreasAreResizable:(BOOL)flag
917 {
918     [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
919 }
920
921 - (BOOL)shrinksStandaloneImagesToFit
922 {
923     return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
924 }
925
926 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag
927 {
928     [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
929 }
930
931 - (BOOL)automaticallyDetectsCacheModel
932 {
933     return _private->automaticallyDetectsCacheModel;
934 }
935
936 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
937 {
938     _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
939 }
940
941 - (BOOL)usesEncodingDetector
942 {
943     return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey];
944 }
945
946 - (void)setUsesEncodingDetector:(BOOL)flag
947 {
948     [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey];
949 }
950
951 - (BOOL)isWebSecurityEnabled
952 {
953     return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
954 }
955
956 - (void)setWebSecurityEnabled:(BOOL)flag
957 {
958     [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
959 }
960
961 - (BOOL)allowUniversalAccessFromFileURLs
962 {
963     return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
964 }
965
966 - (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
967 {
968     [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
969 }
970
971 - (BOOL)allowFileAccessFromFileURLs
972 {
973     return [self _boolValueForKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
974 }
975
976 - (void)setAllowFileAccessFromFileURLs:(BOOL)flag
977 {
978     [self _setBoolValue: flag forKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
979 }
980
981 - (NSTimeInterval)_backForwardCacheExpirationInterval
982 {
983     // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
984     return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
985 }
986
987 - (float)PDFScaleFactor
988 {
989     return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
990 }
991
992 - (void)setPDFScaleFactor:(float)factor
993 {
994     [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
995 }
996
997 - (int64_t)applicationCacheTotalQuota
998 {
999     return [self _longLongValueForKey:WebKitApplicationCacheTotalQuota];
1000 }
1001
1002 - (void)setApplicationCacheTotalQuota:(int64_t)quota
1003 {
1004     [self _setLongLongValue:quota forKey:WebKitApplicationCacheTotalQuota];
1005
1006     // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
1007     [WebApplicationCache setMaximumSize:quota];
1008 }
1009
1010 - (int64_t)applicationCacheDefaultOriginQuota
1011 {
1012     return [self _longLongValueForKey:WebKitApplicationCacheDefaultOriginQuota];
1013 }
1014
1015 - (void)setApplicationCacheDefaultOriginQuota:(int64_t)quota
1016 {
1017     [self _setLongLongValue:quota forKey:WebKitApplicationCacheDefaultOriginQuota];
1018 }
1019
1020 - (PDFDisplayMode)PDFDisplayMode
1021 {
1022     PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
1023     if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
1024         // protect against new modes from future versions of OS X stored in defaults
1025         value = kPDFDisplaySinglePageContinuous;
1026     }
1027     return value;
1028 }
1029
1030 - (void)setPDFDisplayMode:(PDFDisplayMode)mode
1031 {
1032     [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
1033 }
1034
1035 - (WebKitEditableLinkBehavior)editableLinkBehavior
1036 {
1037     WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
1038     if (value != WebKitEditableLinkDefaultBehavior &&
1039         value != WebKitEditableLinkAlwaysLive &&
1040         value != WebKitEditableLinkNeverLive &&
1041         value != WebKitEditableLinkOnlyLiveWithShiftKey &&
1042         value != WebKitEditableLinkLiveWhenNotFocused) {
1043         // ensure that a valid result is returned
1044         value = WebKitEditableLinkDefaultBehavior;
1045     }
1046     
1047     return value;
1048 }
1049
1050 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
1051 {
1052     [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
1053 }
1054
1055 - (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
1056 {
1057     WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
1058     if (value != WebTextDirectionSubmenuNeverIncluded &&
1059         value != WebTextDirectionSubmenuAutomaticallyIncluded &&
1060         value != WebTextDirectionSubmenuAlwaysIncluded) {
1061         // Ensure that a valid result is returned.
1062         value = WebTextDirectionSubmenuNeverIncluded;
1063     }
1064     return value;
1065 }
1066
1067 - (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
1068 {
1069     [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
1070 }
1071
1072 - (BOOL)_useSiteSpecificSpoofing
1073 {
1074     return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1075 }
1076
1077 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
1078 {
1079     [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1080 }
1081
1082 - (BOOL)databasesEnabled
1083 {
1084     return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
1085 }
1086
1087 - (void)setDatabasesEnabled:(BOOL)databasesEnabled
1088 {
1089     [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
1090 }
1091
1092 - (BOOL)localStorageEnabled
1093 {
1094     return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
1095 }
1096
1097 - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
1098 {
1099     [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
1100 }
1101
1102 - (BOOL)experimentalNotificationsEnabled
1103 {
1104     return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1105 }
1106
1107 - (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled
1108 {
1109     [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1110 }
1111
1112 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
1113 {
1114     LOG(Encoding, "requesting for %@\n", ident);
1115
1116     if (!ident)
1117         return _standardPreferences;
1118     
1119     WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
1120
1121     return instance;
1122 }
1123
1124 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
1125 {
1126     if (!webPreferencesInstances)
1127         webPreferencesInstances = [[NSMutableDictionary alloc] init];
1128     if (ident) {
1129         [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1130         LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1131     }
1132 }
1133
1134 + (void)_checkLastReferenceForIdentifier:(id)identifier
1135 {
1136     // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1137     // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1138     WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1139     if ([instance retainCount] == 1)
1140         [webPreferencesInstances removeObjectForKey:identifier];
1141 }
1142
1143 + (void)_removeReferenceForIdentifier:(NSString *)ident
1144 {
1145     if (ident)
1146         [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1147 }
1148
1149 - (void)_postPreferencesChangesNotification
1150 {
1151     if (!pthread_main_np()) {
1152         [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1153         return;
1154     }
1155
1156     [[NSNotificationCenter defaultCenter]
1157         postNotificationName:WebPreferencesChangedNotification object:self
1158                     userInfo:nil];
1159 }
1160
1161 + (CFStringEncoding)_systemCFStringEncoding
1162 {
1163     return WKGetWebDefaultCFStringEncoding();
1164 }
1165
1166 + (void)_setInitialDefaultTextEncodingToSystemEncoding
1167 {
1168     NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]);
1169
1170     // CFStringConvertEncodingToIANACharSetName() returns cp949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-949.
1171     // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-949.
1172     // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>.
1173     // On some OS versions, the result is CP949 (uppercase).
1174     if ([systemEncodingName _webkit_isCaseInsensitiveEqualToString:@"cp949"])
1175         systemEncodingName = @"ks_c_5601-1987";
1176     [[NSUserDefaults standardUserDefaults] registerDefaults:
1177         [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1178 }
1179
1180 static NSString *classIBCreatorID = nil;
1181
1182 + (void)_setIBCreatorID:(NSString *)string
1183 {
1184     NSString *old = classIBCreatorID;
1185     classIBCreatorID = [string copy];
1186     [old release];
1187 }
1188
1189 - (BOOL)isDOMPasteAllowed
1190 {
1191     return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1192 }
1193
1194 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1195 {
1196     [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1197 }
1198
1199 - (NSString *)_localStorageDatabasePath
1200 {
1201     return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1202 }
1203
1204 - (void)_setLocalStorageDatabasePath:(NSString *)path
1205 {
1206     [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1207 }
1208
1209 - (NSString *)_ftpDirectoryTemplatePath
1210 {
1211     return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1212 }
1213
1214 - (void)_setFTPDirectoryTemplatePath:(NSString *)path
1215 {
1216     [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1217 }
1218
1219 - (BOOL)_forceFTPDirectoryListings
1220 {
1221     return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1222 }
1223
1224 - (void)_setForceFTPDirectoryListings:(BOOL)force
1225 {
1226     [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1227 }
1228
1229 - (BOOL)acceleratedCompositingEnabled
1230 {
1231     return [self _boolValueForKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1232 }
1233
1234 - (void)setAcceleratedCompositingEnabled:(BOOL)enabled
1235 {
1236     [self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1237 }
1238
1239 - (BOOL)showDebugBorders
1240 {
1241     return [self _boolValueForKey:WebKitShowDebugBordersPreferenceKey];
1242 }
1243
1244 - (void)setShowDebugBorders:(BOOL)enabled
1245 {
1246     [self _setBoolValue:enabled forKey:WebKitShowDebugBordersPreferenceKey];
1247 }
1248
1249 - (BOOL)showRepaintCounter
1250 {
1251     return [self _boolValueForKey:WebKitShowRepaintCounterPreferenceKey];
1252 }
1253
1254 - (void)setShowRepaintCounter:(BOOL)enabled
1255 {
1256     [self _setBoolValue:enabled forKey:WebKitShowRepaintCounterPreferenceKey];
1257 }
1258
1259 - (BOOL)webGLEnabled
1260 {
1261     return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey];
1262 }
1263
1264 - (void)setWebGLEnabled:(BOOL)enabled
1265 {
1266     [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey];
1267 }
1268
1269 - (BOOL)usesProxiedOpenPanel
1270 {
1271     return [self _boolValueForKey:WebKitUsesProxiedOpenPanelPreferenceKey];
1272 }
1273
1274 - (void)setUsesProxiedOpenPanel:(BOOL)enabled
1275 {
1276     [self _setBoolValue:enabled forKey:WebKitUsesProxiedOpenPanelPreferenceKey];
1277 }
1278
1279 - (unsigned)pluginAllowedRunTime
1280 {
1281     return [self _integerValueForKey:WebKitPluginAllowedRunTimePreferenceKey];
1282 }
1283
1284 - (void)setPluginAllowedRunTime:(unsigned)allowedRunTime
1285 {
1286     return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey];
1287 }
1288
1289 - (BOOL)isFrameFlatteningEnabled
1290 {
1291     return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey];
1292 }
1293
1294 - (void)setFrameFlatteningEnabled:(BOOL)flag
1295 {
1296     [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey];
1297 }
1298
1299 - (BOOL)paginateDuringLayoutEnabled
1300 {
1301     return [self _boolValueForKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1302 }
1303
1304 - (void)setPaginateDuringLayoutEnabled:(BOOL)flag
1305 {
1306     [self _setBoolValue:flag forKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1307 }
1308
1309 - (BOOL)memoryInfoEnabled
1310 {
1311     return [self _boolValueForKey:WebKitMemoryInfoEnabledPreferenceKey];
1312 }
1313
1314 - (void)setMemoryInfoEnabled:(BOOL)flag
1315 {
1316     [self _setBoolValue:flag forKey:WebKitMemoryInfoEnabledPreferenceKey];
1317 }
1318
1319 - (WebKitEditingBehavior)editingBehavior
1320 {
1321     return static_cast<WebKitEditingBehavior>([self _integerValueForKey:WebKitEditingBehaviorPreferenceKey]);
1322 }
1323
1324 - (void)setEditingBehavior:(WebKitEditingBehavior)behavior
1325 {
1326     [self _setIntegerValue:behavior forKey:WebKitEditingBehaviorPreferenceKey];
1327 }
1328
1329 - (void)didRemoveFromWebView
1330 {
1331     ASSERT(_private->numWebViews);
1332     if (--_private->numWebViews == 0)
1333         [[NSNotificationCenter defaultCenter]
1334             postNotificationName:WebPreferencesRemovedNotification
1335                           object:self
1336                         userInfo:nil];
1337 }
1338
1339 - (void)willAddToWebView
1340 {
1341     ++_private->numWebViews;
1342 }
1343
1344 - (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key
1345 {
1346     [self _setStringValue:value forKey:key];
1347 }
1348
1349 @end
1350
1351 @implementation WebPreferences (WebInternal)
1352
1353 + (NSString *)_IBCreatorID
1354 {
1355     return classIBCreatorID;
1356 }
1357
1358 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
1359 {
1360     NSString *IBCreatorID = [WebPreferences _IBCreatorID];
1361     if (!IBCreatorID)
1362         return key;
1363     return [IBCreatorID stringByAppendingString:key];
1364 }
1365
1366 @end