--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/WebView/WebPreferences.m Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,957 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebPreferencesPrivate.h"
+#import "WebPreferenceKeysPrivate.h"
+
+#import "WebKitLogging.h"
+#import "WebKitNSStringExtras.h"
+#import "WebKitSystemBits.h"
+#import "WebKitSystemInterface.h"
+#import "WebKitVersionChecks.h"
+#import "WebNSDictionaryExtras.h"
+#import "WebNSURLExtras.h"
+
+NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
+NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";
+
+#define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x))
+
+enum { WebPreferencesVersion = 1 };
+
+static WebPreferences *_standardPreferences;
+static NSMutableDictionary *webPreferencesInstances;
+
+static bool contains(const char* const array[], int count, const char* item)
+{
+ if (!item)
+ return false;
+
+ for (int i = 0; i < count; i++)
+ if (!strcasecmp(array[i], item))
+ return true;
+ return false;
+}
+
+static WebCacheModel cacheModelForMainBundle(void)
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ // Apps that probably need the small setting
+ static const char* const documentViewerIDs[] = {
+ "Microsoft/com.microsoft.Messenger",
+ "com.adiumX.adiumX",
+ "com.alientechnology.Proteus",
+ "com.apple.Dashcode",
+ "com.apple.iChat",
+ "com.barebones.bbedit",
+ "com.barebones.textwrangler",
+ "com.barebones.yojimbo",
+ "com.equinux.iSale4",
+ "com.growl.growlframework",
+ "com.intrarts.PandoraMan",
+ "com.karelia.Sandvox",
+ "com.macromates.textmate",
+ "com.realmacsoftware.rapidweaverpro",
+ "com.red-sweater.marsedit",
+ "com.yahoo.messenger3",
+ "de.codingmonkeys.SubEthaEdit",
+ "fi.karppinen.Pyro",
+ "info.colloquy",
+ "kungfoo.tv.ecto",
+ };
+
+ // Apps that probably need the medium setting
+ static const char* const documentBrowserIDs[] = {
+ "com.apple.Dictionary",
+ "com.apple.Xcode",
+ "com.apple.dashboard.client",
+ "com.apple.helpviewer",
+ "com.culturedcode.xyle",
+ "com.macrabbit.CSSEdit",
+ "com.panic.Coda",
+ "com.ranchero.NetNewsWire",
+ "com.thinkmac.NewsLife",
+ "org.xlife.NewsFire",
+ "uk.co.opencommunity.vienna2",
+ };
+
+ // Apps that probably need the large setting
+ static const char* const primaryWebBrowserIDs[] = {
+ "com.app4mac.KidsBrowser"
+ "com.app4mac.wKiosk",
+ "com.freeverse.bumpercar",
+ "com.omnigroup.OmniWeb5",
+ "com.sunrisebrowser.Sunrise",
+ "net.hmdt-web.Shiira",
+ };
+
+ WebCacheModel cacheModel;
+
+ const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
+ if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID))
+ cacheModel = WebCacheModelDocumentViewer;
+ else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID))
+ cacheModel = WebCacheModelDocumentBrowser;
+ else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID))
+ cacheModel = WebCacheModelPrimaryWebBrowser;
+ else {
+ bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API);
+ if (isLegacyApp)
+ cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache.
+ else
+ cacheModel = WebCacheModelDocumentViewer; // To save memory.
+ }
+
+ [pool drain];
+
+ return cacheModel;
+}
+
+@interface WebPreferencesPrivate : NSObject
+{
+@public
+ NSMutableDictionary *values;
+ NSString *identifier;
+ NSString *IBCreatorID;
+ BOOL autosaves;
+ BOOL automaticallyDetectsCacheModel;
+ unsigned numWebViews;
+}
+@end
+
+@implementation WebPreferencesPrivate
+- (void)dealloc
+{
+ [values release];
+ [identifier release];
+ [IBCreatorID release];
+ [super dealloc];
+}
+@end
+
+@interface WebPreferences (WebInternal)
++ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
++ (NSString *)_IBCreatorID;
+@end
+
+@interface WebPreferences (WebForwardDeclarations)
+// This pseudo-category is needed so these methods can be used from within other category implementations
+// without being in the public header file.
+- (BOOL)_boolValueForKey:(NSString *)key;
+- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
+- (int)_integerValueForKey:(NSString *)key;
+- (void)_setIntegerValue:(int)value forKey:(NSString *)key;
+- (float)_floatValueForKey:(NSString *)key;
+- (void)_setFloatValue:(float)value forKey:(NSString *)key;
+@end
+
+@implementation WebPreferences
+
+- init
+{
+ // Create fake identifier
+ static int instanceCount = 1;
+ NSString *fakeIdentifier;
+
+ // At least ensure that identifier hasn't been already used.
+ fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
+ while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
+ fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
+ }
+
+ return [self initWithIdentifier:fakeIdentifier];
+}
+
+- (id)initWithIdentifier:(NSString *)anIdentifier
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ _private = [[WebPreferencesPrivate alloc] init];
+ _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
+
+ WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
+ if (instance){
+ [self release];
+ return [instance retain];
+ }
+
+ _private->values = [[NSMutableDictionary alloc] init];
+ _private->identifier = [anIdentifier copy];
+ _private->automaticallyDetectsCacheModel = YES;
+
+ [[self class] _setInstance:self forIdentifier:_private->identifier];
+
+ [self _postPreferencesChangesNotification];
+
+ return self;
+}
+
+- (id)initWithCoder:(NSCoder *)decoder
+{
+ self = [super init];
+ if (!self)
+ return nil;
+
+ _private = [[WebPreferencesPrivate alloc] init];
+ _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
+ _private->automaticallyDetectsCacheModel = YES;
+
+ @try {
+ id identifier = nil;
+ id values = nil;
+ if ([decoder allowsKeyedCoding]) {
+ identifier = [decoder decodeObjectForKey:@"Identifier"];
+ values = [decoder decodeObjectForKey:@"Values"];
+ } else {
+ int version;
+ [decoder decodeValueOfObjCType:@encode(int) at:&version];
+ if (version == 1) {
+ identifier = [decoder decodeObject];
+ values = [decoder decodeObject];
+ }
+ }
+
+ if ([identifier isKindOfClass:[NSString class]])
+ _private->identifier = [identifier copy];
+ if ([values isKindOfClass:[NSDictionary class]])
+ _private->values = [values mutableCopy]; // ensure dictionary is mutable
+
+ LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
+ } @catch(id) {
+ [self release];
+ return nil;
+ }
+
+ // If we load a nib multiple times, or have instances in multiple
+ // nibs with the same name, the first guy up wins.
+ WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
+ if (instance) {
+ [self release];
+ self = [instance retain];
+ } else {
+ [[self class] _setInstance:self forIdentifier:_private->identifier];
+ }
+
+ return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)encoder
+{
+ if ([encoder allowsKeyedCoding]){
+ [encoder encodeObject:_private->identifier forKey:@"Identifier"];
+ [encoder encodeObject:_private->values forKey:@"Values"];
+ LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
+ }
+ else {
+ int version = WebPreferencesVersion;
+ [encoder encodeValueOfObjCType:@encode(int) at:&version];
+ [encoder encodeObject:_private->identifier];
+ [encoder encodeObject:_private->values];
+ }
+}
+
++ (WebPreferences *)standardPreferences
+{
+ if (_standardPreferences == nil) {
+ _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
+ [_standardPreferences setAutosaves:YES];
+ }
+
+ return _standardPreferences;
+}
+
+// if we ever have more than one WebPreferences object, this would move to init
++ (void)initialize
+{
+ NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
+ @"Times", WebKitStandardFontPreferenceKey,
+ @"Courier", WebKitFixedFontPreferenceKey,
+ @"Times", WebKitSerifFontPreferenceKey,
+ @"Helvetica", WebKitSansSerifFontPreferenceKey,
+ @"Apple Chancery", WebKitCursiveFontPreferenceKey,
+ @"Papyrus", WebKitFantasyFontPreferenceKey,
+ @"1", WebKitMinimumFontSizePreferenceKey,
+ @"9", WebKitMinimumLogicalFontSizePreferenceKey,
+ @"16", WebKitDefaultFontSizePreferenceKey,
+ @"13", WebKitDefaultFixedFontSizePreferenceKey,
+ @"ISO-8859-1", WebKitDefaultTextEncodingNamePreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey,
+ @"", WebKitUserStyleSheetLocationPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitTextAreasAreResizablePreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFit,
+ [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitDisplayImagesKey,
+ @"1800", WebKitBackForwardCacheExpirationIntervalKey,
+ [NSNumber numberWithBool:NO], WebKitTabToLinksPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitPrivateBrowsingEnabledPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitShowsURLsInToolTipsPreferenceKey,
+ @"1", WebKitPDFDisplayModePreferenceKey,
+ @"0", WebKitPDFScaleFactorPreferenceKey,
+ @"1", WebKitUsePDFPreviewViewPreferenceKey,
+ @"0", WebKitUseSiteSpecificSpoofingPreferenceKey,
+ [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
+ [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey,
+ [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey,
+ [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
+ nil];
+
+ // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
+ ASSERT(kPDFDisplaySinglePageContinuous == 1);
+ [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
+}
+
+- (void)dealloc
+{
+ [_private release];
+ [super dealloc];
+}
+
+- (NSString *)identifier
+{
+ return _private->identifier;
+}
+
+- (id)_valueForKey:(NSString *)key
+{
+ NSString *_key = KEY(key);
+ id o = [_private->values objectForKey:_key];
+ if (o)
+ return o;
+ o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
+ if (!o && key != _key)
+ o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
+ return o;
+}
+
+- (NSString *)_stringValueForKey:(NSString *)key
+{
+ id s = [self _valueForKey:key];
+ return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
+}
+
+- (void)_setStringValue:(NSString *)value forKey:(NSString *)key
+{
+ if ([[self _stringValueForKey:key] isEqualToString:value])
+ return;
+ NSString *_key = KEY(key);
+ [_private->values setObject:value forKey:_key];
+ if (_private->autosaves)
+ [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
+ [self _postPreferencesChangesNotification];
+}
+
+- (int)_integerValueForKey:(NSString *)key
+{
+ id o = [self _valueForKey:key];
+ return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
+}
+
+- (void)_setIntegerValue:(int)value forKey:(NSString *)key
+{
+ if ([self _integerValueForKey:key] == value)
+ return;
+ NSString *_key = KEY(key);
+ [_private->values _webkit_setInt:value forKey:_key];
+ if (_private->autosaves)
+ [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
+ [self _postPreferencesChangesNotification];
+}
+
+- (float)_floatValueForKey:(NSString *)key
+{
+ id o = [self _valueForKey:key];
+ return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
+}
+
+- (void)_setFloatValue:(float)value forKey:(NSString *)key
+{
+ if ([self _floatValueForKey:key] == value)
+ return;
+ NSString *_key = KEY(key);
+ [_private->values _webkit_setFloat:value forKey:_key];
+ if (_private->autosaves)
+ [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
+ [self _postPreferencesChangesNotification];
+}
+
+- (BOOL)_boolValueForKey:(NSString *)key
+{
+ return [self _integerValueForKey:key] != 0;
+}
+
+- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
+{
+ if ([self _boolValueForKey:key] == value)
+ return;
+ NSString *_key = KEY(key);
+ [_private->values _webkit_setBool:value forKey:_key];
+ if (_private->autosaves)
+ [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
+ [self _postPreferencesChangesNotification];
+}
+
+- (NSString *)standardFontFamily
+{
+ return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
+}
+
+- (void)setStandardFontFamily:(NSString *)family
+{
+ [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
+}
+
+- (NSString *)fixedFontFamily
+{
+ return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
+}
+
+- (void)setFixedFontFamily:(NSString *)family
+{
+ [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
+}
+
+- (NSString *)serifFontFamily
+{
+ return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
+}
+
+- (void)setSerifFontFamily:(NSString *)family
+{
+ [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
+}
+
+- (NSString *)sansSerifFontFamily
+{
+ return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
+}
+
+- (void)setSansSerifFontFamily:(NSString *)family
+{
+ [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
+}
+
+- (NSString *)cursiveFontFamily
+{
+ return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
+}
+
+- (void)setCursiveFontFamily:(NSString *)family
+{
+ [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
+}
+
+- (NSString *)fantasyFontFamily
+{
+ return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
+}
+
+- (void)setFantasyFontFamily:(NSString *)family
+{
+ [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
+}
+
+- (int)defaultFontSize
+{
+ return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
+}
+
+- (void)setDefaultFontSize:(int)size
+{
+ [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
+}
+
+- (int)defaultFixedFontSize
+{
+ return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
+}
+
+- (void)setDefaultFixedFontSize:(int)size
+{
+ [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
+}
+
+- (int)minimumFontSize
+{
+ return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
+}
+
+- (void)setMinimumFontSize:(int)size
+{
+ [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
+}
+
+- (int)minimumLogicalFontSize
+{
+ return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
+}
+
+- (void)setMinimumLogicalFontSize:(int)size
+{
+ [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
+}
+
+- (NSString *)defaultTextEncodingName
+{
+ return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
+}
+
+- (void)setDefaultTextEncodingName:(NSString *)encoding
+{
+ [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
+}
+
+- (BOOL)userStyleSheetEnabled
+{
+ return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
+}
+
+- (void)setUserStyleSheetEnabled:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
+}
+
+- (NSURL *)userStyleSheetLocation
+{
+ NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
+
+ if ([locationString _webkit_looksLikeAbsoluteURL]) {
+ return [NSURL _web_URLWithDataAsString:locationString];
+ } else {
+ locationString = [locationString stringByExpandingTildeInPath];
+ return [NSURL fileURLWithPath:locationString];
+ }
+}
+
+- (void)setUserStyleSheetLocation:(NSURL *)URL
+{
+ NSString *locationString;
+
+ if ([URL isFileURL]) {
+ locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
+ } else {
+ locationString = [URL _web_originalDataAsString];
+ }
+
+ [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
+}
+
+- (BOOL)shouldPrintBackgrounds
+{
+ return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
+}
+
+- (void)setShouldPrintBackgrounds:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
+}
+
+- (BOOL)isJavaEnabled
+{
+ return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
+}
+
+- (void)setJavaEnabled:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
+}
+
+- (BOOL)isJavaScriptEnabled
+{
+ return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
+}
+
+- (void)setJavaScriptEnabled:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
+}
+
+- (BOOL)javaScriptCanOpenWindowsAutomatically
+{
+ return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
+}
+
+- (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
+}
+
+- (BOOL)arePlugInsEnabled
+{
+ return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
+}
+
+- (void)setPlugInsEnabled:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
+}
+
+- (BOOL)allowsAnimatedImages
+{
+ return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
+}
+
+- (void)setAllowsAnimatedImages:(BOOL)flag;
+{
+ [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
+}
+
+- (BOOL)allowsAnimatedImageLooping
+{
+ return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
+}
+
+- (void)setAllowsAnimatedImageLooping: (BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
+}
+
+- (void)setLoadsImagesAutomatically: (BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
+}
+
+- (BOOL)loadsImagesAutomatically
+{
+ return [self _boolValueForKey: WebKitDisplayImagesKey];
+}
+
+- (void)setAutosaves:(BOOL)flag;
+{
+ _private->autosaves = flag;
+}
+
+- (BOOL)autosaves
+{
+ return _private->autosaves;
+}
+
+- (void)setTabsToLinks:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
+}
+
+- (BOOL)tabsToLinks
+{
+ return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
+}
+
+- (void)setPrivateBrowsingEnabled:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
+}
+
+- (BOOL)privateBrowsingEnabled
+{
+ return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
+}
+
+- (void)setUsesPageCache:(BOOL)usesPageCache
+{
+ [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
+}
+
+- (BOOL)usesPageCache
+{
+ return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
+}
+
+- (void)setCacheModel:(WebCacheModel)cacheModel
+{
+ [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
+ [self setAutomaticallyDetectsCacheModel:NO];
+}
+
+- (WebCacheModel)cacheModel
+{
+ return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
+}
+
+@end
+
+@implementation WebPreferences (WebPrivate)
+
+- (BOOL)respectStandardStyleKeyEquivalents
+{
+ return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
+}
+
+- (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
+}
+
+- (BOOL)showsURLsInToolTips
+{
+ return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
+}
+
+- (void)setShowsURLsInToolTips:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
+}
+
+- (BOOL)textAreasAreResizable
+{
+ return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
+}
+
+- (void)setTextAreasAreResizable:(BOOL)flag
+{
+ [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
+}
+
+- (BOOL)shrinksStandaloneImagesToFit
+{
+ return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFit];
+}
+
+- (void)setShrinksStandaloneImagesToFit:(BOOL)flag
+{
+ [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFit];
+}
+
+- (BOOL)automaticallyDetectsCacheModel
+{
+ return _private->automaticallyDetectsCacheModel;
+}
+
+- (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
+{
+ _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
+}
+
+- (NSTimeInterval)_backForwardCacheExpirationInterval
+{
+ // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
+ return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
+}
+
+- (float)PDFScaleFactor
+{
+ return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
+}
+
+- (void)setPDFScaleFactor:(float)factor
+{
+ [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
+}
+
+- (PDFDisplayMode)PDFDisplayMode;
+{
+ PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
+ if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
+ // protect against new modes from future versions of OS X stored in defaults
+ value = kPDFDisplaySinglePageContinuous;
+ }
+ return value;
+}
+
+- (void)setPDFDisplayMode:(PDFDisplayMode)mode
+{
+ [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
+}
+
+- (BOOL)_usePDFPreviewView
+{
+ return [self _boolValueForKey:WebKitUsePDFPreviewViewPreferenceKey];
+}
+
+- (void)_setUsePDFPreviewView:(BOOL)newValue
+{
+ [self _setBoolValue:newValue forKey:WebKitUsePDFPreviewViewPreferenceKey];
+}
+
+- (WebKitEditableLinkBehavior)editableLinkBehavior
+{
+ WebKitEditableLinkBehavior value = [self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey];
+ if (value != WebKitEditableLinkDefaultBehavior &&
+ value != WebKitEditableLinkAlwaysLive &&
+ value != WebKitEditableLinkNeverLive &&
+ value != WebKitEditableLinkOnlyLiveWithShiftKey &&
+ value != WebKitEditableLinkLiveWhenNotFocused) {
+ // ensure that a valid result is returned
+ value = WebKitEditableLinkDefaultBehavior;
+ }
+
+ return value;
+}
+
+- (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
+{
+ [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
+}
+
+- (BOOL)_useSiteSpecificSpoofing
+{
+ return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
+}
+
+- (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
+{
+ [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
+}
+
++ (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
+{
+ LOG(Encoding, "requesting for %@\n", ident);
+
+ if (!ident)
+ return _standardPreferences;
+
+ WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
+
+ return instance;
+}
+
++ (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
+{
+ if (!webPreferencesInstances)
+ webPreferencesInstances = [[NSMutableDictionary alloc] init];
+ if (ident) {
+ [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
+ LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
+ }
+}
+
++ (void)_checkLastReferenceForIdentifier:(id)identifier
+{
+ // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
+ // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
+ WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
+ if ([instance retainCount] == 1)
+ [webPreferencesInstances removeObjectForKey:identifier];
+}
+
++ (void)_removeReferenceForIdentifier:(NSString *)ident
+{
+ if (ident)
+ [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
+}
+
+- (void)_postPreferencesChangesNotification
+{
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:WebPreferencesChangedNotification object:self
+ userInfo:nil];
+}
+
++ (CFStringEncoding)_systemCFStringEncoding
+{
+ return WKGetWebDefaultCFStringEncoding();
+}
+
++ (void)_setInitialDefaultTextEncodingToSystemEncoding
+{
+ [[NSUserDefaults standardUserDefaults] registerDefaults:
+ [NSDictionary dictionaryWithObject:(NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding])
+ forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
+}
+
+static NSString *classIBCreatorID = nil;
+
++ (void)_setIBCreatorID:(NSString *)string
+{
+ NSString *old = classIBCreatorID;
+ classIBCreatorID = [string copy];
+ [old release];
+}
+
+- (BOOL)isDOMPasteAllowed
+{
+ return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
+}
+
+- (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
+{
+ [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
+}
+
+- (void)_setFTPDirectoryTemplatePath:(NSString *)path
+{
+ [self _setStringValue:path forKey:WebKitFTPDirectoryTemplatePath];
+}
+
+- (NSString *)_ftpDirectoryTemplatePath
+{
+ return [self _stringValueForKey:WebKitFTPDirectoryTemplatePath];
+}
+
+- (void)_setForceFTPDirectoryListings:(BOOL)force
+{
+ [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
+}
+
+- (BOOL)_forceFTPDirectoryListings
+{
+ return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
+}
+
+- (void)didRemoveFromWebView
+{
+ ASSERT(_private->numWebViews);
+ if (--_private->numWebViews == 0)
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:WebPreferencesRemovedNotification
+ object:self
+ userInfo:nil];
+}
+
+- (void)willAddToWebView
+{
+ ++_private->numWebViews;
+}
+
+@end
+
+@implementation WebPreferences (WebInternal)
+
++ (NSString *)_IBCreatorID
+{
+ return classIBCreatorID;
+}
+
++ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
+{
+ NSString *IBCreatorID = [WebPreferences _IBCreatorID];
+ if (!IBCreatorID)
+ return key;
+ return [IBCreatorID stringByAppendingString:key];
+}
+
+@end