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