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], WebKitUsesEncodingDetectorPreferenceKey,
310 [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey,
311 @"", WebKitUserStyleSheetLocationPreferenceKey,
312 [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey,
313 [NSNumber numberWithBool:NO], WebKitTextAreasAreResizablePreferenceKey,
314 [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFitPreferenceKey,
315 [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey,
316 [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey,
317 [NSNumber numberWithBool:YES], WebKitWebSecurityEnabledPreferenceKey,
318 [NSNumber numberWithBool:YES], WebKitAllowUniversalAccessFromFileURLsPreferenceKey,
319 [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
320 [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey,
321 [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey,
322 [NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey,
323 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey,
324 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey,
325 [NSNumber numberWithBool:YES], WebKitDisplayImagesKey,
326 @"1800", WebKitBackForwardCacheExpirationIntervalKey,
327 [NSNumber numberWithBool:NO], WebKitTabToLinksPreferenceKey,
328 [NSNumber numberWithBool:NO], WebKitPrivateBrowsingEnabledPreferenceKey,
329 [NSNumber numberWithBool:NO], WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
330 [NSNumber numberWithBool:NO], WebKitShowsURLsInToolTipsPreferenceKey,
331 @"1", WebKitPDFDisplayModePreferenceKey,
332 @"0", WebKitPDFScaleFactorPreferenceKey,
333 @"0", WebKitUseSiteSpecificSpoofingPreferenceKey,
334 [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
335 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
336 [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],
338 [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded],
340 WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey,
341 [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey,
342 [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey,
343 [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
344 [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey,
345 [NSNumber numberWithBool:YES], WebKitAuthorAndUserStylesEnabledPreferenceKey,
346 [NSNumber numberWithBool:NO], WebKitApplicationChromeModeEnabledPreferenceKey,
347 [NSNumber numberWithBool:NO], WebKitWebArchiveDebugModeEnabledPreferenceKey,
348 [NSNumber numberWithBool:NO], WebKitOfflineWebApplicationCacheEnabledPreferenceKey,
349 [NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey,
351 // In Release and Production we skip a lot of object teardown during quit to speed up shutdown time. This breaks
352 // our RefCount Leak tracking, and so for Debug we will use the full document teardown.
353 [NSNumber numberWithBool:YES], WebKitEnableFullDocumentTeardownPreferenceKey,
357 // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
358 ASSERT(kPDFDisplaySinglePageContinuous == 1);
359 [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
368 - (NSString *)identifier
370 return _private->identifier;
373 - (id)_valueForKey:(NSString *)key
375 NSString *_key = KEY(key);
376 id o = [_private->values objectForKey:_key];
379 o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
380 if (!o && key != _key)
381 o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
385 - (NSString *)_stringValueForKey:(NSString *)key
387 id s = [self _valueForKey:key];
388 return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
391 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
393 if ([[self _stringValueForKey:key] isEqualToString:value])
395 NSString *_key = KEY(key);
396 [_private->values setObject:value forKey:_key];
397 if (_private->autosaves)
398 [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
399 [self _postPreferencesChangesNotification];
402 - (int)_integerValueForKey:(NSString *)key
404 id o = [self _valueForKey:key];
405 return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
408 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
410 if ([self _integerValueForKey:key] == value)
412 NSString *_key = KEY(key);
413 [_private->values _webkit_setInt:value forKey:_key];
414 if (_private->autosaves)
415 [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
416 [self _postPreferencesChangesNotification];
419 - (float)_floatValueForKey:(NSString *)key
421 id o = [self _valueForKey:key];
422 return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
425 - (void)_setFloatValue:(float)value forKey:(NSString *)key
427 if ([self _floatValueForKey:key] == value)
429 NSString *_key = KEY(key);
430 [_private->values _webkit_setFloat:value forKey:_key];
431 if (_private->autosaves)
432 [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
433 [self _postPreferencesChangesNotification];
436 - (BOOL)_boolValueForKey:(NSString *)key
438 return [self _integerValueForKey:key] != 0;
441 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
443 if ([self _boolValueForKey:key] == value)
445 NSString *_key = KEY(key);
446 [_private->values _webkit_setBool:value forKey:_key];
447 if (_private->autosaves)
448 [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
449 [self _postPreferencesChangesNotification];
452 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
454 id o = [self _valueForKey:key];
455 return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
458 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
460 if ([self _unsignedLongLongValueForKey:key] == value)
462 NSString *_key = KEY(key);
463 [_private->values _webkit_setUnsignedLongLong:value forKey:_key];
464 if (_private->autosaves)
465 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
466 [self _postPreferencesChangesNotification];
469 - (NSString *)standardFontFamily
471 return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
474 - (void)setStandardFontFamily:(NSString *)family
476 [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
479 - (NSString *)fixedFontFamily
481 return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
484 - (void)setFixedFontFamily:(NSString *)family
486 [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
489 - (NSString *)serifFontFamily
491 return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
494 - (void)setSerifFontFamily:(NSString *)family
496 [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
499 - (NSString *)sansSerifFontFamily
501 return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
504 - (void)setSansSerifFontFamily:(NSString *)family
506 [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
509 - (NSString *)cursiveFontFamily
511 return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
514 - (void)setCursiveFontFamily:(NSString *)family
516 [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
519 - (NSString *)fantasyFontFamily
521 return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
524 - (void)setFantasyFontFamily:(NSString *)family
526 [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
529 - (int)defaultFontSize
531 return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
534 - (void)setDefaultFontSize:(int)size
536 [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
539 - (int)defaultFixedFontSize
541 return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
544 - (void)setDefaultFixedFontSize:(int)size
546 [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
549 - (int)minimumFontSize
551 return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
554 - (void)setMinimumFontSize:(int)size
556 [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
559 - (int)minimumLogicalFontSize
561 return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
564 - (void)setMinimumLogicalFontSize:(int)size
566 [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
569 - (NSString *)defaultTextEncodingName
571 return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
574 - (void)setDefaultTextEncodingName:(NSString *)encoding
576 [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
579 - (BOOL)userStyleSheetEnabled
581 return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
584 - (void)setUserStyleSheetEnabled:(BOOL)flag
586 [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
589 - (NSURL *)userStyleSheetLocation
591 NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
593 if ([locationString _webkit_looksLikeAbsoluteURL]) {
594 return [NSURL _web_URLWithDataAsString:locationString];
596 locationString = [locationString stringByExpandingTildeInPath];
597 return [NSURL fileURLWithPath:locationString];
601 - (void)setUserStyleSheetLocation:(NSURL *)URL
603 NSString *locationString;
605 if ([URL isFileURL]) {
606 locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
608 locationString = [URL _web_originalDataAsString];
611 [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
614 - (BOOL)shouldPrintBackgrounds
616 return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
619 - (void)setShouldPrintBackgrounds:(BOOL)flag
621 [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
624 - (BOOL)isJavaEnabled
626 return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
629 - (void)setJavaEnabled:(BOOL)flag
631 [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
634 - (BOOL)isJavaScriptEnabled
636 return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
639 - (void)setJavaScriptEnabled:(BOOL)flag
641 [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
644 - (BOOL)javaScriptCanOpenWindowsAutomatically
646 return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
649 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
651 [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
654 - (BOOL)arePlugInsEnabled
656 return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
659 - (void)setPlugInsEnabled:(BOOL)flag
661 [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
664 - (BOOL)allowsAnimatedImages
666 return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
669 - (void)setAllowsAnimatedImages:(BOOL)flag
671 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
674 - (BOOL)allowsAnimatedImageLooping
676 return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
679 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
681 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
684 - (void)setLoadsImagesAutomatically: (BOOL)flag
686 [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
689 - (BOOL)loadsImagesAutomatically
691 return [self _boolValueForKey: WebKitDisplayImagesKey];
694 - (void)setAutosaves:(BOOL)flag
696 _private->autosaves = flag;
701 return _private->autosaves;
704 - (void)setTabsToLinks:(BOOL)flag
706 [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
711 return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
714 - (void)setPrivateBrowsingEnabled:(BOOL)flag
716 [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
719 - (BOOL)privateBrowsingEnabled
721 return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
724 - (void)setUsesPageCache:(BOOL)usesPageCache
726 [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
729 - (BOOL)usesPageCache
731 return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
734 - (void)setCacheModel:(WebCacheModel)cacheModel
736 [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
737 [self setAutomaticallyDetectsCacheModel:NO];
740 - (WebCacheModel)cacheModel
742 return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
747 @implementation WebPreferences (WebPrivate)
749 - (BOOL)developerExtrasEnabled
751 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
752 if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
755 if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
757 return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
759 return YES; // always enable in debug builds
763 - (void)setDeveloperExtrasEnabled:(BOOL)flag
765 [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
768 - (BOOL)authorAndUserStylesEnabled
770 return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
773 - (void)setAuthorAndUserStylesEnabled:(BOOL)flag
775 [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
778 - (BOOL)applicationChromeModeEnabled
780 return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey];
783 - (void)setApplicationChromeModeEnabled:(BOOL)flag
785 [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey];
788 - (BOOL)webArchiveDebugModeEnabled
790 return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
793 - (void)setWebArchiveDebugModeEnabled:(BOOL)flag
795 [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
798 - (BOOL)offlineWebApplicationCacheEnabled
800 return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
803 - (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
805 [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
808 - (BOOL)zoomsTextOnly
810 return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
813 - (void)setZoomsTextOnly:(BOOL)flag
815 [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
818 - (BOOL)respectStandardStyleKeyEquivalents
820 return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
823 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
825 [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
828 - (BOOL)showsURLsInToolTips
830 return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
833 - (void)setShowsURLsInToolTips:(BOOL)flag
835 [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
838 - (BOOL)textAreasAreResizable
840 return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
843 - (void)setTextAreasAreResizable:(BOOL)flag
845 [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
848 - (BOOL)shrinksStandaloneImagesToFit
850 return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
853 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag
855 [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
858 - (BOOL)automaticallyDetectsCacheModel
860 return _private->automaticallyDetectsCacheModel;
863 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
865 _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
868 - (BOOL)usesEncodingDetector
870 return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey];
873 - (void)setUsesEncodingDetector:(BOOL)flag
875 [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey];
878 - (BOOL)isWebSecurityEnabled
880 return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
883 - (void)setWebSecurityEnabled:(BOOL)flag
885 [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
888 - (BOOL)allowUniversalAccessFromFileURLs
890 return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
893 - (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
895 [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
898 - (NSTimeInterval)_backForwardCacheExpirationInterval
900 // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
901 return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
904 - (float)PDFScaleFactor
906 return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
909 - (void)setPDFScaleFactor:(float)factor
911 [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
914 - (PDFDisplayMode)PDFDisplayMode
916 PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
917 if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
918 // protect against new modes from future versions of OS X stored in defaults
919 value = kPDFDisplaySinglePageContinuous;
924 - (void)setPDFDisplayMode:(PDFDisplayMode)mode
926 [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
929 - (WebKitEditableLinkBehavior)editableLinkBehavior
931 WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
932 if (value != WebKitEditableLinkDefaultBehavior &&
933 value != WebKitEditableLinkAlwaysLive &&
934 value != WebKitEditableLinkNeverLive &&
935 value != WebKitEditableLinkOnlyLiveWithShiftKey &&
936 value != WebKitEditableLinkLiveWhenNotFocused) {
937 // ensure that a valid result is returned
938 value = WebKitEditableLinkDefaultBehavior;
944 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
946 [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
949 - (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
951 WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
952 if (value != WebTextDirectionSubmenuNeverIncluded &&
953 value != WebTextDirectionSubmenuAutomaticallyIncluded &&
954 value != WebTextDirectionSubmenuAlwaysIncluded) {
955 // Ensure that a valid result is returned.
956 value = WebTextDirectionSubmenuNeverIncluded;
961 - (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
963 [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
966 - (BOOL)_useSiteSpecificSpoofing
968 return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
971 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
973 [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
976 - (BOOL)databasesEnabled
978 return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
981 - (void)setDatabasesEnabled:(BOOL)databasesEnabled
983 [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
986 - (BOOL)localStorageEnabled
988 return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
991 - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
993 [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
996 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
998 LOG(Encoding, "requesting for %@\n", ident);
1001 return _standardPreferences;
1003 WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
1008 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
1010 if (!webPreferencesInstances)
1011 webPreferencesInstances = [[NSMutableDictionary alloc] init];
1013 [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1014 LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1018 + (void)_checkLastReferenceForIdentifier:(id)identifier
1020 // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1021 // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1022 WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1023 if ([instance retainCount] == 1)
1024 [webPreferencesInstances removeObjectForKey:identifier];
1027 + (void)_removeReferenceForIdentifier:(NSString *)ident
1030 [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1033 - (void)_postPreferencesChangesNotification
1035 [[NSNotificationCenter defaultCenter]
1036 postNotificationName:WebPreferencesChangedNotification object:self
1040 + (CFStringEncoding)_systemCFStringEncoding
1042 return WKGetWebDefaultCFStringEncoding();
1045 + (void)_setInitialDefaultTextEncodingToSystemEncoding
1047 NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]);
1049 // CFStringConvertEncodingToIANACharSetName() returns CP949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-939.
1050 // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-939.
1051 // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>.
1052 if ([systemEncodingName isEqualToString:@"CP949"])
1053 systemEncodingName = @"ks_c_5601-1987";
1054 [[NSUserDefaults standardUserDefaults] registerDefaults:
1055 [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1058 static NSString *classIBCreatorID = nil;
1060 + (void)_setIBCreatorID:(NSString *)string
1062 NSString *old = classIBCreatorID;
1063 classIBCreatorID = [string copy];
1067 - (BOOL)isDOMPasteAllowed
1069 return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1072 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1074 [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1077 - (void)_setFTPDirectoryTemplatePath:(NSString *)path
1079 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1082 - (NSString *)_localStorageDatabasePath
1084 return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1087 - (void)_setLocalStorageDatabasePath:(NSString *)path
1089 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1092 - (NSString *)_ftpDirectoryTemplatePath
1094 return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1097 - (void)_setForceFTPDirectoryListings:(BOOL)force
1099 [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1102 - (BOOL)_forceFTPDirectoryListings
1104 return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1107 - (void)didRemoveFromWebView
1109 ASSERT(_private->numWebViews);
1110 if (--_private->numWebViews == 0)
1111 [[NSNotificationCenter defaultCenter]
1112 postNotificationName:WebPreferencesRemovedNotification
1117 - (void)willAddToWebView
1119 ++_private->numWebViews;
1122 - (void)setFullDocumentTeardownEnabled:(BOOL)fullDocumentTeardownEnabled
1124 [self _setBoolValue:fullDocumentTeardownEnabled forKey:WebKitEnableFullDocumentTeardownPreferenceKey];
1127 - (BOOL)fullDocumentTeardownEnabled
1129 return [self _boolValueForKey:WebKitEnableFullDocumentTeardownPreferenceKey];
1133 @implementation WebPreferences (WebInternal)
1135 + (NSString *)_IBCreatorID
1137 return classIBCreatorID;
1140 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
1142 NSString *IBCreatorID = [WebPreferences _IBCreatorID];
1145 return [IBCreatorID stringByAppendingString:key];