2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
3 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 #import "WebPreferencesPrivate.h"
31 #import "WebPreferenceKeysPrivate.h"
33 #import "WebKitLogging.h"
34 #import "WebKitNSStringExtras.h"
35 #import "WebKitSystemBits.h"
36 #import "WebKitSystemInterface.h"
37 #import "WebKitVersionChecks.h"
38 #import "WebNSDictionaryExtras.h"
39 #import "WebNSURLExtras.h"
41 NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
42 NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";
44 #define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x))
46 enum { WebPreferencesVersion = 1 };
48 static WebPreferences *_standardPreferences;
49 static NSMutableDictionary *webPreferencesInstances;
51 static bool contains(const char* const array[], int count, const char* item)
56 for (int i = 0; i < count; i++)
57 if (!strcasecmp(array[i], item))
62 static WebCacheModel cacheModelForMainBundle(void)
64 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
66 // Apps that probably need the small setting
67 static const char* const documentViewerIDs[] = {
68 "Microsoft/com.microsoft.Messenger",
70 "com.alientechnology.Proteus",
73 "com.barebones.bbedit",
74 "com.barebones.textwrangler",
75 "com.barebones.yojimbo",
77 "com.growl.growlframework",
78 "com.intrarts.PandoraMan",
79 "com.karelia.Sandvox",
80 "com.macromates.textmate",
81 "com.realmacsoftware.rapidweaverpro",
82 "com.red-sweater.marsedit",
83 "com.yahoo.messenger3",
84 "de.codingmonkeys.SubEthaEdit",
90 // Apps that probably need the medium setting
91 static const char* const documentBrowserIDs[] = {
92 "com.apple.Dictionary",
94 "com.apple.dashboard.client",
95 "com.apple.helpviewer",
96 "com.culturedcode.xyle",
97 "com.macrabbit.CSSEdit",
99 "com.ranchero.NetNewsWire",
100 "com.thinkmac.NewsLife",
101 "org.xlife.NewsFire",
102 "uk.co.opencommunity.vienna2",
105 // Apps that probably need the large setting
106 static const char* const primaryWebBrowserIDs[] = {
107 "com.app4mac.KidsBrowser"
108 "com.app4mac.wKiosk",
109 "com.freeverse.bumpercar",
110 "com.omnigroup.OmniWeb5",
111 "com.sunrisebrowser.Sunrise",
112 "net.hmdt-web.Shiira",
115 WebCacheModel cacheModel;
117 const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
118 if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID))
119 cacheModel = WebCacheModelDocumentViewer;
120 else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID))
121 cacheModel = WebCacheModelDocumentBrowser;
122 else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID))
123 cacheModel = WebCacheModelPrimaryWebBrowser;
125 bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API);
127 cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache.
129 cacheModel = WebCacheModelDocumentViewer; // To save memory.
137 @interface WebPreferencesPrivate : NSObject
140 NSMutableDictionary *values;
141 NSString *identifier;
142 NSString *IBCreatorID;
144 BOOL automaticallyDetectsCacheModel;
145 unsigned numWebViews;
149 @implementation WebPreferencesPrivate
153 [identifier release];
154 [IBCreatorID release];
159 @interface WebPreferences (WebInternal)
160 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
161 + (NSString *)_IBCreatorID;
164 @interface WebPreferences (WebForwardDeclarations)
165 // This pseudo-category is needed so these methods can be used from within other category implementations
166 // without being in the public header file.
167 - (BOOL)_boolValueForKey:(NSString *)key;
168 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
169 - (int)_integerValueForKey:(NSString *)key;
170 - (void)_setIntegerValue:(int)value forKey:(NSString *)key;
171 - (float)_floatValueForKey:(NSString *)key;
172 - (void)_setFloatValue:(float)value forKey:(NSString *)key;
173 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key;
174 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key;
177 @implementation WebPreferences
181 // Create fake identifier
182 static int instanceCount = 1;
183 NSString *fakeIdentifier;
185 // At least ensure that identifier hasn't been already used.
186 fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
187 while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
188 fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
191 return [self initWithIdentifier:fakeIdentifier];
194 - (id)initWithIdentifier:(NSString *)anIdentifier
200 _private = [[WebPreferencesPrivate alloc] init];
201 _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
203 WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
206 return [instance retain];
209 _private->values = [[NSMutableDictionary alloc] init];
210 _private->identifier = [anIdentifier copy];
211 _private->automaticallyDetectsCacheModel = YES;
213 [[self class] _setInstance:self forIdentifier:_private->identifier];
215 [self _postPreferencesChangesNotification];
220 - (id)initWithCoder:(NSCoder *)decoder
226 _private = [[WebPreferencesPrivate alloc] init];
227 _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
228 _private->automaticallyDetectsCacheModel = YES;
233 if ([decoder allowsKeyedCoding]) {
234 identifier = [decoder decodeObjectForKey:@"Identifier"];
235 values = [decoder decodeObjectForKey:@"Values"];
238 [decoder decodeValueOfObjCType:@encode(int) at:&version];
240 identifier = [decoder decodeObject];
241 values = [decoder decodeObject];
245 if ([identifier isKindOfClass:[NSString class]])
246 _private->identifier = [identifier copy];
247 if ([values isKindOfClass:[NSDictionary class]])
248 _private->values = [values mutableCopy]; // ensure dictionary is mutable
250 LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
256 // If we load a nib multiple times, or have instances in multiple
257 // nibs with the same name, the first guy up wins.
258 WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
261 self = [instance retain];
263 [[self class] _setInstance:self forIdentifier:_private->identifier];
269 - (void)encodeWithCoder:(NSCoder *)encoder
271 if ([encoder allowsKeyedCoding]){
272 [encoder encodeObject:_private->identifier forKey:@"Identifier"];
273 [encoder encodeObject:_private->values forKey:@"Values"];
274 LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
277 int version = WebPreferencesVersion;
278 [encoder encodeValueOfObjCType:@encode(int) at:&version];
279 [encoder encodeObject:_private->identifier];
280 [encoder encodeObject:_private->values];
284 + (WebPreferences *)standardPreferences
286 if (_standardPreferences == nil) {
287 _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
288 [_standardPreferences setAutosaves:YES];
291 return _standardPreferences;
294 // if we ever have more than one WebPreferences object, this would move to init
297 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
298 @"Times", WebKitStandardFontPreferenceKey,
299 @"Courier", WebKitFixedFontPreferenceKey,
300 @"Times", WebKitSerifFontPreferenceKey,
301 @"Helvetica", WebKitSansSerifFontPreferenceKey,
302 @"Apple Chancery", WebKitCursiveFontPreferenceKey,
303 @"Papyrus", WebKitFantasyFontPreferenceKey,
304 @"1", WebKitMinimumFontSizePreferenceKey,
305 @"9", WebKitMinimumLogicalFontSizePreferenceKey,
306 @"16", WebKitDefaultFontSizePreferenceKey,
307 @"13", WebKitDefaultFixedFontSizePreferenceKey,
308 @"ISO-8859-1", WebKitDefaultTextEncodingNamePreferenceKey,
309 [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey,
310 @"", WebKitUserStyleSheetLocationPreferenceKey,
311 [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey,
312 [NSNumber numberWithBool:NO], WebKitTextAreasAreResizablePreferenceKey,
313 [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFitPreferenceKey,
314 [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey,
315 [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey,
316 [NSNumber numberWithBool:YES], WebKitWebSecurityEnabledPreferenceKey,
317 [NSNumber numberWithBool:YES], WebKitAllowUniversalAccessFromFileURLsPreferenceKey,
318 [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
319 [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey,
320 [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey,
321 [NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey,
322 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey,
323 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey,
324 [NSNumber numberWithBool:YES], WebKitDisplayImagesKey,
325 @"1800", WebKitBackForwardCacheExpirationIntervalKey,
326 [NSNumber numberWithBool:NO], WebKitTabToLinksPreferenceKey,
327 [NSNumber numberWithBool:NO], WebKitPrivateBrowsingEnabledPreferenceKey,
328 [NSNumber numberWithBool:NO], WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
329 [NSNumber numberWithBool:NO], WebKitShowsURLsInToolTipsPreferenceKey,
330 @"1", WebKitPDFDisplayModePreferenceKey,
331 @"0", WebKitPDFScaleFactorPreferenceKey,
332 @"0", WebKitUseSiteSpecificSpoofingPreferenceKey,
333 [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
334 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
335 [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],
337 [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded],
339 WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey,
340 [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey,
341 [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey,
342 [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
343 [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey,
344 [NSNumber numberWithBool:YES], WebKitAuthorAndUserStylesEnabledPreferenceKey,
345 [NSNumber numberWithBool:NO], WebKitApplicationChromeModeEnabledPreferenceKey,
346 [NSNumber numberWithBool:NO], WebKitWebArchiveDebugModeEnabledPreferenceKey,
347 [NSNumber numberWithBool:NO], WebKitOfflineWebApplicationCacheEnabledPreferenceKey,
348 [NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey,
350 // In Release and Production we skip a lot of object teardown during quit to speed up shutdown time. This breaks
351 // our RefCount Leak tracking, and so for Debug we will use the full document teardown.
352 [NSNumber numberWithBool:YES], WebKitEnableFullDocumentTeardownPreferenceKey,
356 // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
357 ASSERT(kPDFDisplaySinglePageContinuous == 1);
358 [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
367 - (NSString *)identifier
369 return _private->identifier;
372 - (id)_valueForKey:(NSString *)key
374 NSString *_key = KEY(key);
375 id o = [_private->values objectForKey:_key];
378 o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
379 if (!o && key != _key)
380 o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
384 - (NSString *)_stringValueForKey:(NSString *)key
386 id s = [self _valueForKey:key];
387 return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
390 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
392 if ([[self _stringValueForKey:key] isEqualToString:value])
394 NSString *_key = KEY(key);
395 [_private->values setObject:value forKey:_key];
396 if (_private->autosaves)
397 [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
398 [self _postPreferencesChangesNotification];
401 - (int)_integerValueForKey:(NSString *)key
403 id o = [self _valueForKey:key];
404 return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
407 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
409 if ([self _integerValueForKey:key] == value)
411 NSString *_key = KEY(key);
412 [_private->values _webkit_setInt:value forKey:_key];
413 if (_private->autosaves)
414 [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
415 [self _postPreferencesChangesNotification];
418 - (float)_floatValueForKey:(NSString *)key
420 id o = [self _valueForKey:key];
421 return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
424 - (void)_setFloatValue:(float)value forKey:(NSString *)key
426 if ([self _floatValueForKey:key] == value)
428 NSString *_key = KEY(key);
429 [_private->values _webkit_setFloat:value forKey:_key];
430 if (_private->autosaves)
431 [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
432 [self _postPreferencesChangesNotification];
435 - (BOOL)_boolValueForKey:(NSString *)key
437 return [self _integerValueForKey:key] != 0;
440 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
442 if ([self _boolValueForKey:key] == value)
444 NSString *_key = KEY(key);
445 [_private->values _webkit_setBool:value forKey:_key];
446 if (_private->autosaves)
447 [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
448 [self _postPreferencesChangesNotification];
451 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
453 id o = [self _valueForKey:key];
454 return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
457 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
459 if ([self _unsignedLongLongValueForKey:key] == value)
461 NSString *_key = KEY(key);
462 [_private->values _webkit_setUnsignedLongLong:value forKey:_key];
463 if (_private->autosaves)
464 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
465 [self _postPreferencesChangesNotification];
468 - (NSString *)standardFontFamily
470 return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
473 - (void)setStandardFontFamily:(NSString *)family
475 [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
478 - (NSString *)fixedFontFamily
480 return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
483 - (void)setFixedFontFamily:(NSString *)family
485 [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
488 - (NSString *)serifFontFamily
490 return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
493 - (void)setSerifFontFamily:(NSString *)family
495 [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
498 - (NSString *)sansSerifFontFamily
500 return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
503 - (void)setSansSerifFontFamily:(NSString *)family
505 [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
508 - (NSString *)cursiveFontFamily
510 return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
513 - (void)setCursiveFontFamily:(NSString *)family
515 [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
518 - (NSString *)fantasyFontFamily
520 return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
523 - (void)setFantasyFontFamily:(NSString *)family
525 [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
528 - (int)defaultFontSize
530 return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
533 - (void)setDefaultFontSize:(int)size
535 [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
538 - (int)defaultFixedFontSize
540 return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
543 - (void)setDefaultFixedFontSize:(int)size
545 [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
548 - (int)minimumFontSize
550 return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
553 - (void)setMinimumFontSize:(int)size
555 [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
558 - (int)minimumLogicalFontSize
560 return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
563 - (void)setMinimumLogicalFontSize:(int)size
565 [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
568 - (NSString *)defaultTextEncodingName
570 return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
573 - (void)setDefaultTextEncodingName:(NSString *)encoding
575 [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
578 - (BOOL)userStyleSheetEnabled
580 return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
583 - (void)setUserStyleSheetEnabled:(BOOL)flag
585 [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
588 - (NSURL *)userStyleSheetLocation
590 NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
592 if ([locationString _webkit_looksLikeAbsoluteURL]) {
593 return [NSURL _web_URLWithDataAsString:locationString];
595 locationString = [locationString stringByExpandingTildeInPath];
596 return [NSURL fileURLWithPath:locationString];
600 - (void)setUserStyleSheetLocation:(NSURL *)URL
602 NSString *locationString;
604 if ([URL isFileURL]) {
605 locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
607 locationString = [URL _web_originalDataAsString];
610 [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
613 - (BOOL)shouldPrintBackgrounds
615 return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
618 - (void)setShouldPrintBackgrounds:(BOOL)flag
620 [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
623 - (BOOL)isJavaEnabled
625 return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
628 - (void)setJavaEnabled:(BOOL)flag
630 [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
633 - (BOOL)isJavaScriptEnabled
635 return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
638 - (void)setJavaScriptEnabled:(BOOL)flag
640 [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
643 - (BOOL)javaScriptCanOpenWindowsAutomatically
645 return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
648 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
650 [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
653 - (BOOL)arePlugInsEnabled
655 return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
658 - (void)setPlugInsEnabled:(BOOL)flag
660 [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
663 - (BOOL)allowsAnimatedImages
665 return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
668 - (void)setAllowsAnimatedImages:(BOOL)flag
670 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
673 - (BOOL)allowsAnimatedImageLooping
675 return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
678 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
680 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
683 - (void)setLoadsImagesAutomatically: (BOOL)flag
685 [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
688 - (BOOL)loadsImagesAutomatically
690 return [self _boolValueForKey: WebKitDisplayImagesKey];
693 - (void)setAutosaves:(BOOL)flag
695 _private->autosaves = flag;
700 return _private->autosaves;
703 - (void)setTabsToLinks:(BOOL)flag
705 [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
710 return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
713 - (void)setPrivateBrowsingEnabled:(BOOL)flag
715 [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
718 - (BOOL)privateBrowsingEnabled
720 return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
723 - (void)setUsesPageCache:(BOOL)usesPageCache
725 [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
728 - (BOOL)usesPageCache
730 return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
733 - (void)setCacheModel:(WebCacheModel)cacheModel
735 [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
736 [self setAutomaticallyDetectsCacheModel:NO];
739 - (WebCacheModel)cacheModel
741 return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
746 @implementation WebPreferences (WebPrivate)
748 - (BOOL)developerExtrasEnabled
750 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
751 if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
754 if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
756 return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
758 return YES; // always enable in debug builds
762 - (void)setDeveloperExtrasEnabled:(BOOL)flag
764 [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
767 - (BOOL)authorAndUserStylesEnabled
769 return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
772 - (void)setAuthorAndUserStylesEnabled:(BOOL)flag
774 [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
777 - (BOOL)applicationChromeModeEnabled
779 return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey];
782 - (void)setApplicationChromeModeEnabled:(BOOL)flag
784 [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey];
787 - (BOOL)webArchiveDebugModeEnabled
789 return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
792 - (void)setWebArchiveDebugModeEnabled:(BOOL)flag
794 [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
797 - (BOOL)offlineWebApplicationCacheEnabled
799 return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
802 - (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
804 [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
807 - (BOOL)zoomsTextOnly
809 return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
812 - (void)setZoomsTextOnly:(BOOL)flag
814 [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
817 - (BOOL)respectStandardStyleKeyEquivalents
819 return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
822 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
824 [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
827 - (BOOL)showsURLsInToolTips
829 return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
832 - (void)setShowsURLsInToolTips:(BOOL)flag
834 [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
837 - (BOOL)textAreasAreResizable
839 return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
842 - (void)setTextAreasAreResizable:(BOOL)flag
844 [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
847 - (BOOL)shrinksStandaloneImagesToFit
849 return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
852 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag
854 [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
857 - (BOOL)automaticallyDetectsCacheModel
859 return _private->automaticallyDetectsCacheModel;
862 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
864 _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
867 - (BOOL)isWebSecurityEnabled
869 return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
872 - (void)setWebSecurityEnabled:(BOOL)flag
874 [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
877 - (BOOL)allowUniversalAccessFromFileURLs
879 return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
882 - (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
884 [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
887 - (NSTimeInterval)_backForwardCacheExpirationInterval
889 // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
890 return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
893 - (float)PDFScaleFactor
895 return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
898 - (void)setPDFScaleFactor:(float)factor
900 [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
903 - (PDFDisplayMode)PDFDisplayMode
905 PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
906 if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
907 // protect against new modes from future versions of OS X stored in defaults
908 value = kPDFDisplaySinglePageContinuous;
913 - (void)setPDFDisplayMode:(PDFDisplayMode)mode
915 [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
918 - (WebKitEditableLinkBehavior)editableLinkBehavior
920 WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
921 if (value != WebKitEditableLinkDefaultBehavior &&
922 value != WebKitEditableLinkAlwaysLive &&
923 value != WebKitEditableLinkNeverLive &&
924 value != WebKitEditableLinkOnlyLiveWithShiftKey &&
925 value != WebKitEditableLinkLiveWhenNotFocused) {
926 // ensure that a valid result is returned
927 value = WebKitEditableLinkDefaultBehavior;
933 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
935 [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
938 - (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
940 WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
941 if (value != WebTextDirectionSubmenuNeverIncluded &&
942 value != WebTextDirectionSubmenuAutomaticallyIncluded &&
943 value != WebTextDirectionSubmenuAlwaysIncluded) {
944 // Ensure that a valid result is returned.
945 value = WebTextDirectionSubmenuNeverIncluded;
950 - (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
952 [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
955 - (BOOL)_useSiteSpecificSpoofing
957 return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
960 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
962 [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
965 - (BOOL)databasesEnabled
967 return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
970 - (void)setDatabasesEnabled:(BOOL)databasesEnabled
972 [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
975 - (BOOL)localStorageEnabled
977 return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
980 - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
982 [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
985 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
987 LOG(Encoding, "requesting for %@\n", ident);
990 return _standardPreferences;
992 WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
997 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
999 if (!webPreferencesInstances)
1000 webPreferencesInstances = [[NSMutableDictionary alloc] init];
1002 [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1003 LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1007 + (void)_checkLastReferenceForIdentifier:(id)identifier
1009 // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1010 // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1011 WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1012 if ([instance retainCount] == 1)
1013 [webPreferencesInstances removeObjectForKey:identifier];
1016 + (void)_removeReferenceForIdentifier:(NSString *)ident
1019 [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1022 - (void)_postPreferencesChangesNotification
1024 [[NSNotificationCenter defaultCenter]
1025 postNotificationName:WebPreferencesChangedNotification object:self
1029 + (CFStringEncoding)_systemCFStringEncoding
1031 return WKGetWebDefaultCFStringEncoding();
1034 + (void)_setInitialDefaultTextEncodingToSystemEncoding
1036 NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]);
1038 // CFStringConvertEncodingToIANACharSetName() returns CP949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-939.
1039 // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-939.
1040 // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>.
1041 if ([systemEncodingName isEqualToString:@"CP949"])
1042 systemEncodingName = @"ks_c_5601-1987";
1043 [[NSUserDefaults standardUserDefaults] registerDefaults:
1044 [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1047 static NSString *classIBCreatorID = nil;
1049 + (void)_setIBCreatorID:(NSString *)string
1051 NSString *old = classIBCreatorID;
1052 classIBCreatorID = [string copy];
1056 - (BOOL)isDOMPasteAllowed
1058 return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1061 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1063 [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1066 - (void)_setFTPDirectoryTemplatePath:(NSString *)path
1068 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1071 - (NSString *)_localStorageDatabasePath
1073 return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1076 - (void)_setLocalStorageDatabasePath:(NSString *)path
1078 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1081 - (NSString *)_ftpDirectoryTemplatePath
1083 return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1086 - (void)_setForceFTPDirectoryListings:(BOOL)force
1088 [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1091 - (BOOL)_forceFTPDirectoryListings
1093 return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1096 - (void)didRemoveFromWebView
1098 ASSERT(_private->numWebViews);
1099 if (--_private->numWebViews == 0)
1100 [[NSNotificationCenter defaultCenter]
1101 postNotificationName:WebPreferencesRemovedNotification
1106 - (void)willAddToWebView
1108 ++_private->numWebViews;
1111 - (void)setFullDocumentTeardownEnabled:(BOOL)fullDocumentTeardownEnabled
1113 [self _setBoolValue:fullDocumentTeardownEnabled forKey:WebKitEnableFullDocumentTeardownPreferenceKey];
1116 - (BOOL)fullDocumentTeardownEnabled
1118 return [self _boolValueForKey:WebKitEnableFullDocumentTeardownPreferenceKey];
1122 @implementation WebPreferences (WebInternal)
1124 + (NSString *)_IBCreatorID
1126 return classIBCreatorID;
1129 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
1131 NSString *IBCreatorID = [WebPreferences _IBCreatorID];
1134 return [IBCreatorID stringByAppendingString:key];