webengine/osswebengine/WebKit/WebView/WebPreferences.m
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     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 @end
       
   174 
       
   175 @implementation WebPreferences
       
   176 
       
   177 - init
       
   178 {
       
   179     // Create fake identifier
       
   180     static int instanceCount = 1;
       
   181     NSString *fakeIdentifier;
       
   182     
       
   183     // At least ensure that identifier hasn't been already used.  
       
   184     fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
       
   185     while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
       
   186         fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
       
   187     }
       
   188     
       
   189     return [self initWithIdentifier:fakeIdentifier];
       
   190 }
       
   191 
       
   192 - (id)initWithIdentifier:(NSString *)anIdentifier
       
   193 {
       
   194     self = [super init];
       
   195     if (!self)
       
   196         return nil;
       
   197 
       
   198     _private = [[WebPreferencesPrivate alloc] init];
       
   199     _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
       
   200 
       
   201     WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
       
   202     if (instance){
       
   203         [self release];
       
   204         return [instance retain];
       
   205     }
       
   206 
       
   207     _private->values = [[NSMutableDictionary alloc] init];
       
   208     _private->identifier = [anIdentifier copy];
       
   209     _private->automaticallyDetectsCacheModel = YES;
       
   210 
       
   211     [[self class] _setInstance:self forIdentifier:_private->identifier];
       
   212 
       
   213     [self _postPreferencesChangesNotification];
       
   214 
       
   215     return self;
       
   216 }
       
   217 
       
   218 - (id)initWithCoder:(NSCoder *)decoder
       
   219 {
       
   220     self = [super init];
       
   221     if (!self)
       
   222         return nil;
       
   223 
       
   224     _private = [[WebPreferencesPrivate alloc] init];
       
   225     _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
       
   226     _private->automaticallyDetectsCacheModel = YES;
       
   227 
       
   228     @try {
       
   229         id identifier = nil;
       
   230         id values = nil;
       
   231         if ([decoder allowsKeyedCoding]) {
       
   232             identifier = [decoder decodeObjectForKey:@"Identifier"];
       
   233             values = [decoder decodeObjectForKey:@"Values"];
       
   234         } else {
       
   235             int version;
       
   236             [decoder decodeValueOfObjCType:@encode(int) at:&version];
       
   237             if (version == 1) {
       
   238                 identifier = [decoder decodeObject];
       
   239                 values = [decoder decodeObject];
       
   240             }
       
   241         }
       
   242 
       
   243         if ([identifier isKindOfClass:[NSString class]])
       
   244             _private->identifier = [identifier copy];
       
   245         if ([values isKindOfClass:[NSDictionary class]])
       
   246             _private->values = [values mutableCopy]; // ensure dictionary is mutable
       
   247 
       
   248         LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
       
   249     } @catch(id) {
       
   250         [self release];
       
   251         return nil;
       
   252     }
       
   253 
       
   254     // If we load a nib multiple times, or have instances in multiple
       
   255     // nibs with the same name, the first guy up wins.
       
   256     WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
       
   257     if (instance) {
       
   258         [self release];
       
   259         self = [instance retain];
       
   260     } else {
       
   261         [[self class] _setInstance:self forIdentifier:_private->identifier];
       
   262     }
       
   263 
       
   264     return self;
       
   265 }
       
   266 
       
   267 - (void)encodeWithCoder:(NSCoder *)encoder
       
   268 {
       
   269     if ([encoder allowsKeyedCoding]){
       
   270         [encoder encodeObject:_private->identifier forKey:@"Identifier"];
       
   271         [encoder encodeObject:_private->values forKey:@"Values"];
       
   272         LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
       
   273     }
       
   274     else {
       
   275         int version = WebPreferencesVersion;
       
   276         [encoder encodeValueOfObjCType:@encode(int) at:&version];
       
   277         [encoder encodeObject:_private->identifier];
       
   278         [encoder encodeObject:_private->values];
       
   279     }
       
   280 }
       
   281 
       
   282 + (WebPreferences *)standardPreferences
       
   283 {
       
   284     if (_standardPreferences == nil) {
       
   285         _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
       
   286         [_standardPreferences setAutosaves:YES];
       
   287     }
       
   288 
       
   289     return _standardPreferences;
       
   290 }
       
   291 
       
   292 // if we ever have more than one WebPreferences object, this would move to init
       
   293 + (void)initialize
       
   294 {
       
   295     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
       
   296         @"Times",                       WebKitStandardFontPreferenceKey,
       
   297         @"Courier",                     WebKitFixedFontPreferenceKey,
       
   298         @"Times",                       WebKitSerifFontPreferenceKey,
       
   299         @"Helvetica",                   WebKitSansSerifFontPreferenceKey,
       
   300         @"Apple Chancery",              WebKitCursiveFontPreferenceKey,
       
   301         @"Papyrus",                     WebKitFantasyFontPreferenceKey,
       
   302         @"1",                           WebKitMinimumFontSizePreferenceKey,
       
   303         @"9",                           WebKitMinimumLogicalFontSizePreferenceKey, 
       
   304         @"16",                          WebKitDefaultFontSizePreferenceKey,
       
   305         @"13",                          WebKitDefaultFixedFontSizePreferenceKey,
       
   306         @"ISO-8859-1",                  WebKitDefaultTextEncodingNamePreferenceKey,
       
   307         [NSNumber numberWithBool:NO],   WebKitUserStyleSheetEnabledPreferenceKey,
       
   308         @"",                            WebKitUserStyleSheetLocationPreferenceKey,
       
   309         [NSNumber numberWithBool:NO],   WebKitShouldPrintBackgroundsPreferenceKey,
       
   310         [NSNumber numberWithBool:NO],   WebKitTextAreasAreResizablePreferenceKey,
       
   311         [NSNumber numberWithBool:NO],   WebKitShrinksStandaloneImagesToFit,
       
   312         [NSNumber numberWithBool:YES],  WebKitJavaEnabledPreferenceKey,
       
   313         [NSNumber numberWithBool:YES],  WebKitJavaScriptEnabledPreferenceKey,
       
   314         [NSNumber numberWithBool:YES],  WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
       
   315         [NSNumber numberWithBool:YES],  WebKitPluginsEnabledPreferenceKey,
       
   316         [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImagesPreferenceKey,
       
   317         [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImageLoopingPreferenceKey,
       
   318         [NSNumber numberWithBool:YES],  WebKitDisplayImagesKey,
       
   319         @"1800",                        WebKitBackForwardCacheExpirationIntervalKey,
       
   320         [NSNumber numberWithBool:NO],   WebKitTabToLinksPreferenceKey,
       
   321         [NSNumber numberWithBool:NO],   WebKitPrivateBrowsingEnabledPreferenceKey,
       
   322         [NSNumber numberWithBool:NO],   WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
       
   323         [NSNumber numberWithBool:NO],   WebKitShowsURLsInToolTipsPreferenceKey,
       
   324         @"1",                           WebKitPDFDisplayModePreferenceKey,
       
   325         @"0",                           WebKitPDFScaleFactorPreferenceKey,
       
   326         @"1",                           WebKitUsePDFPreviewViewPreferenceKey,
       
   327         @"0",                           WebKitUseSiteSpecificSpoofingPreferenceKey,
       
   328         [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
       
   329         [NSNumber numberWithBool:NO],   WebKitDOMPasteAllowedPreferenceKey,
       
   330         [NSNumber numberWithBool:YES],  WebKitUsesPageCachePreferenceKey,
       
   331         [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
       
   332         nil];
       
   333 
       
   334     // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
       
   335     ASSERT(kPDFDisplaySinglePageContinuous == 1);
       
   336     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
       
   337 }
       
   338 
       
   339 - (void)dealloc
       
   340 {
       
   341     [_private release];
       
   342     [super dealloc];
       
   343 }
       
   344 
       
   345 - (NSString *)identifier
       
   346 {
       
   347     return _private->identifier;
       
   348 }
       
   349 
       
   350 - (id)_valueForKey:(NSString *)key
       
   351 {
       
   352     NSString *_key = KEY(key);
       
   353     id o = [_private->values objectForKey:_key];
       
   354     if (o)
       
   355         return o;
       
   356     o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
       
   357     if (!o && key != _key)
       
   358         o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
       
   359     return o;
       
   360 }
       
   361 
       
   362 - (NSString *)_stringValueForKey:(NSString *)key
       
   363 {
       
   364     id s = [self _valueForKey:key];
       
   365     return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
       
   366 }
       
   367 
       
   368 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
       
   369 {
       
   370     if ([[self _stringValueForKey:key] isEqualToString:value])
       
   371         return;
       
   372     NSString *_key = KEY(key);
       
   373     [_private->values setObject:value forKey:_key];
       
   374     if (_private->autosaves)
       
   375         [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
       
   376     [self _postPreferencesChangesNotification];
       
   377 }
       
   378 
       
   379 - (int)_integerValueForKey:(NSString *)key
       
   380 {
       
   381     id o = [self _valueForKey:key];
       
   382     return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
       
   383 }
       
   384 
       
   385 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
       
   386 {
       
   387     if ([self _integerValueForKey:key] == value)
       
   388         return;
       
   389     NSString *_key = KEY(key);
       
   390     [_private->values _webkit_setInt:value forKey:_key];
       
   391     if (_private->autosaves)
       
   392         [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
       
   393     [self _postPreferencesChangesNotification];
       
   394 }
       
   395 
       
   396 - (float)_floatValueForKey:(NSString *)key
       
   397 {
       
   398     id o = [self _valueForKey:key];
       
   399     return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
       
   400 }
       
   401 
       
   402 - (void)_setFloatValue:(float)value forKey:(NSString *)key
       
   403 {
       
   404     if ([self _floatValueForKey:key] == value)
       
   405         return;
       
   406     NSString *_key = KEY(key);
       
   407     [_private->values _webkit_setFloat:value forKey:_key];
       
   408     if (_private->autosaves)
       
   409         [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
       
   410     [self _postPreferencesChangesNotification];
       
   411 }
       
   412 
       
   413 - (BOOL)_boolValueForKey:(NSString *)key
       
   414 {
       
   415     return [self _integerValueForKey:key] != 0;
       
   416 }
       
   417 
       
   418 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
       
   419 {
       
   420     if ([self _boolValueForKey:key] == value)
       
   421         return;
       
   422     NSString *_key = KEY(key);
       
   423     [_private->values _webkit_setBool:value forKey:_key];
       
   424     if (_private->autosaves)
       
   425         [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
       
   426     [self _postPreferencesChangesNotification];
       
   427 }
       
   428 
       
   429 - (NSString *)standardFontFamily
       
   430 {
       
   431     return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
       
   432 }
       
   433 
       
   434 - (void)setStandardFontFamily:(NSString *)family
       
   435 {
       
   436     [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
       
   437 }
       
   438 
       
   439 - (NSString *)fixedFontFamily
       
   440 {
       
   441     return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
       
   442 }
       
   443 
       
   444 - (void)setFixedFontFamily:(NSString *)family
       
   445 {
       
   446     [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
       
   447 }
       
   448 
       
   449 - (NSString *)serifFontFamily
       
   450 {
       
   451     return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
       
   452 }
       
   453 
       
   454 - (void)setSerifFontFamily:(NSString *)family 
       
   455 {
       
   456     [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
       
   457 }
       
   458 
       
   459 - (NSString *)sansSerifFontFamily
       
   460 {
       
   461     return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
       
   462 }
       
   463 
       
   464 - (void)setSansSerifFontFamily:(NSString *)family
       
   465 {
       
   466     [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
       
   467 }
       
   468 
       
   469 - (NSString *)cursiveFontFamily
       
   470 {
       
   471     return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
       
   472 }
       
   473 
       
   474 - (void)setCursiveFontFamily:(NSString *)family
       
   475 {
       
   476     [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
       
   477 }
       
   478 
       
   479 - (NSString *)fantasyFontFamily
       
   480 {
       
   481     return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
       
   482 }
       
   483 
       
   484 - (void)setFantasyFontFamily:(NSString *)family
       
   485 {
       
   486     [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
       
   487 }
       
   488 
       
   489 - (int)defaultFontSize
       
   490 {
       
   491     return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
       
   492 }
       
   493 
       
   494 - (void)setDefaultFontSize:(int)size
       
   495 {
       
   496     [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
       
   497 }
       
   498 
       
   499 - (int)defaultFixedFontSize
       
   500 {
       
   501     return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
       
   502 }
       
   503 
       
   504 - (void)setDefaultFixedFontSize:(int)size
       
   505 {
       
   506     [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
       
   507 }
       
   508 
       
   509 - (int)minimumFontSize
       
   510 {
       
   511     return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
       
   512 }
       
   513 
       
   514 - (void)setMinimumFontSize:(int)size
       
   515 {
       
   516     [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
       
   517 }
       
   518 
       
   519 - (int)minimumLogicalFontSize
       
   520 {
       
   521   return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
       
   522 }
       
   523 
       
   524 - (void)setMinimumLogicalFontSize:(int)size
       
   525 {
       
   526   [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
       
   527 }
       
   528 
       
   529 - (NSString *)defaultTextEncodingName
       
   530 {
       
   531     return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
       
   532 }
       
   533 
       
   534 - (void)setDefaultTextEncodingName:(NSString *)encoding
       
   535 {
       
   536     [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
       
   537 }
       
   538 
       
   539 - (BOOL)userStyleSheetEnabled
       
   540 {
       
   541     return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
       
   542 }
       
   543 
       
   544 - (void)setUserStyleSheetEnabled:(BOOL)flag
       
   545 {
       
   546     [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
       
   547 }
       
   548 
       
   549 - (NSURL *)userStyleSheetLocation
       
   550 {
       
   551     NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
       
   552     
       
   553     if ([locationString _webkit_looksLikeAbsoluteURL]) {
       
   554         return [NSURL _web_URLWithDataAsString:locationString];
       
   555     } else {
       
   556         locationString = [locationString stringByExpandingTildeInPath];
       
   557         return [NSURL fileURLWithPath:locationString];
       
   558     }
       
   559 }
       
   560 
       
   561 - (void)setUserStyleSheetLocation:(NSURL *)URL
       
   562 {
       
   563     NSString *locationString;
       
   564     
       
   565     if ([URL isFileURL]) {
       
   566         locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
       
   567     } else {
       
   568         locationString = [URL _web_originalDataAsString];
       
   569     }
       
   570     
       
   571     [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
       
   572 }
       
   573 
       
   574 - (BOOL)shouldPrintBackgrounds
       
   575 {
       
   576     return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
       
   577 }
       
   578 
       
   579 - (void)setShouldPrintBackgrounds:(BOOL)flag
       
   580 {
       
   581     [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
       
   582 }
       
   583 
       
   584 - (BOOL)isJavaEnabled
       
   585 {
       
   586     return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
       
   587 }
       
   588 
       
   589 - (void)setJavaEnabled:(BOOL)flag
       
   590 {
       
   591     [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
       
   592 }
       
   593 
       
   594 - (BOOL)isJavaScriptEnabled
       
   595 {
       
   596     return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
       
   597 }
       
   598 
       
   599 - (void)setJavaScriptEnabled:(BOOL)flag
       
   600 {
       
   601     [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
       
   602 }
       
   603 
       
   604 - (BOOL)javaScriptCanOpenWindowsAutomatically
       
   605 {
       
   606     return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
       
   607 }
       
   608 
       
   609 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
       
   610 {
       
   611     [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
       
   612 }
       
   613 
       
   614 - (BOOL)arePlugInsEnabled
       
   615 {
       
   616     return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
       
   617 }
       
   618 
       
   619 - (void)setPlugInsEnabled:(BOOL)flag
       
   620 {
       
   621     [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
       
   622 }
       
   623 
       
   624 - (BOOL)allowsAnimatedImages
       
   625 {
       
   626     return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
       
   627 }
       
   628 
       
   629 - (void)setAllowsAnimatedImages:(BOOL)flag;
       
   630 {
       
   631     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
       
   632 }
       
   633 
       
   634 - (BOOL)allowsAnimatedImageLooping
       
   635 {
       
   636     return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
       
   637 }
       
   638 
       
   639 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
       
   640 {
       
   641     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
       
   642 }
       
   643 
       
   644 - (void)setLoadsImagesAutomatically: (BOOL)flag
       
   645 {
       
   646     [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
       
   647 }
       
   648 
       
   649 - (BOOL)loadsImagesAutomatically
       
   650 {
       
   651     return [self _boolValueForKey: WebKitDisplayImagesKey];
       
   652 }
       
   653 
       
   654 - (void)setAutosaves:(BOOL)flag;
       
   655 {
       
   656     _private->autosaves = flag;
       
   657 }
       
   658 
       
   659 - (BOOL)autosaves
       
   660 {
       
   661     return _private->autosaves;
       
   662 }
       
   663 
       
   664 - (void)setTabsToLinks:(BOOL)flag
       
   665 {
       
   666     [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
       
   667 }
       
   668 
       
   669 - (BOOL)tabsToLinks
       
   670 {
       
   671     return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
       
   672 }
       
   673 
       
   674 - (void)setPrivateBrowsingEnabled:(BOOL)flag
       
   675 {
       
   676     [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
       
   677 }
       
   678 
       
   679 - (BOOL)privateBrowsingEnabled
       
   680 {
       
   681     return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
       
   682 }
       
   683 
       
   684 - (void)setUsesPageCache:(BOOL)usesPageCache
       
   685 {
       
   686     [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
       
   687 }
       
   688 
       
   689 - (BOOL)usesPageCache
       
   690 {
       
   691     return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
       
   692 }
       
   693 
       
   694 - (void)setCacheModel:(WebCacheModel)cacheModel
       
   695 {
       
   696     [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
       
   697     [self setAutomaticallyDetectsCacheModel:NO];
       
   698 }
       
   699 
       
   700 - (WebCacheModel)cacheModel
       
   701 {
       
   702     return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
       
   703 }
       
   704 
       
   705 @end
       
   706 
       
   707 @implementation WebPreferences (WebPrivate)
       
   708 
       
   709 - (BOOL)respectStandardStyleKeyEquivalents
       
   710 {
       
   711     return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
       
   712 }
       
   713 
       
   714 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
       
   715 {
       
   716     [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
       
   717 }
       
   718 
       
   719 - (BOOL)showsURLsInToolTips
       
   720 {
       
   721     return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
       
   722 }
       
   723 
       
   724 - (void)setShowsURLsInToolTips:(BOOL)flag
       
   725 {
       
   726     [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
       
   727 }
       
   728 
       
   729 - (BOOL)textAreasAreResizable
       
   730 {
       
   731     return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
       
   732 }
       
   733 
       
   734 - (void)setTextAreasAreResizable:(BOOL)flag
       
   735 {
       
   736     [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
       
   737 }
       
   738 
       
   739 - (BOOL)shrinksStandaloneImagesToFit
       
   740 {
       
   741     return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFit];
       
   742 }
       
   743 
       
   744 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag
       
   745 {
       
   746     [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFit];
       
   747 }
       
   748 
       
   749 - (BOOL)automaticallyDetectsCacheModel
       
   750 {
       
   751     return _private->automaticallyDetectsCacheModel;
       
   752 }
       
   753 
       
   754 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
       
   755 {
       
   756     _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
       
   757 }
       
   758 
       
   759 - (NSTimeInterval)_backForwardCacheExpirationInterval
       
   760 {
       
   761     // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
       
   762     return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
       
   763 }
       
   764 
       
   765 - (float)PDFScaleFactor
       
   766 {
       
   767     return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
       
   768 }
       
   769 
       
   770 - (void)setPDFScaleFactor:(float)factor
       
   771 {
       
   772     [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
       
   773 }
       
   774 
       
   775 - (PDFDisplayMode)PDFDisplayMode;
       
   776 {
       
   777     PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
       
   778     if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
       
   779         // protect against new modes from future versions of OS X stored in defaults
       
   780         value = kPDFDisplaySinglePageContinuous;
       
   781     }
       
   782     return value;
       
   783 }
       
   784 
       
   785 - (void)setPDFDisplayMode:(PDFDisplayMode)mode
       
   786 {
       
   787     [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
       
   788 }
       
   789 
       
   790 - (BOOL)_usePDFPreviewView
       
   791 {
       
   792     return [self _boolValueForKey:WebKitUsePDFPreviewViewPreferenceKey];
       
   793 }
       
   794 
       
   795 - (void)_setUsePDFPreviewView:(BOOL)newValue
       
   796 {
       
   797     [self _setBoolValue:newValue forKey:WebKitUsePDFPreviewViewPreferenceKey];
       
   798 }
       
   799 
       
   800 - (WebKitEditableLinkBehavior)editableLinkBehavior
       
   801 {
       
   802     WebKitEditableLinkBehavior value = [self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey];
       
   803     if (value != WebKitEditableLinkDefaultBehavior &&
       
   804         value != WebKitEditableLinkAlwaysLive &&
       
   805         value != WebKitEditableLinkNeverLive &&
       
   806         value != WebKitEditableLinkOnlyLiveWithShiftKey &&
       
   807         value != WebKitEditableLinkLiveWhenNotFocused) {
       
   808         // ensure that a valid result is returned
       
   809         value = WebKitEditableLinkDefaultBehavior;
       
   810     }
       
   811     
       
   812     return value;
       
   813 }
       
   814 
       
   815 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
       
   816 {
       
   817     [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
       
   818 }
       
   819 
       
   820 - (BOOL)_useSiteSpecificSpoofing
       
   821 {
       
   822     return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
       
   823 }
       
   824 
       
   825 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
       
   826 {
       
   827     [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
       
   828 }
       
   829 
       
   830 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
       
   831 {
       
   832     LOG(Encoding, "requesting for %@\n", ident);
       
   833 
       
   834     if (!ident)
       
   835         return _standardPreferences;
       
   836     
       
   837     WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
       
   838 
       
   839     return instance;
       
   840 }
       
   841 
       
   842 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
       
   843 {
       
   844     if (!webPreferencesInstances)
       
   845         webPreferencesInstances = [[NSMutableDictionary alloc] init];
       
   846     if (ident) {
       
   847         [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
       
   848         LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
       
   849     }
       
   850 }
       
   851 
       
   852 + (void)_checkLastReferenceForIdentifier:(id)identifier
       
   853 {
       
   854     // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
       
   855     // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
       
   856     WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
       
   857     if ([instance retainCount] == 1)
       
   858         [webPreferencesInstances removeObjectForKey:identifier];
       
   859 }
       
   860 
       
   861 + (void)_removeReferenceForIdentifier:(NSString *)ident
       
   862 {
       
   863     if (ident)
       
   864         [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
       
   865 }
       
   866 
       
   867 - (void)_postPreferencesChangesNotification
       
   868 {
       
   869     [[NSNotificationCenter defaultCenter]
       
   870         postNotificationName:WebPreferencesChangedNotification object:self
       
   871                     userInfo:nil];
       
   872 }
       
   873 
       
   874 + (CFStringEncoding)_systemCFStringEncoding
       
   875 {
       
   876     return WKGetWebDefaultCFStringEncoding();
       
   877 }
       
   878 
       
   879 + (void)_setInitialDefaultTextEncodingToSystemEncoding
       
   880 {
       
   881     [[NSUserDefaults standardUserDefaults] registerDefaults:
       
   882         [NSDictionary dictionaryWithObject:(NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding])
       
   883                                     forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
       
   884 }
       
   885 
       
   886 static NSString *classIBCreatorID = nil;
       
   887 
       
   888 + (void)_setIBCreatorID:(NSString *)string
       
   889 {
       
   890     NSString *old = classIBCreatorID;
       
   891     classIBCreatorID = [string copy];
       
   892     [old release];
       
   893 }
       
   894 
       
   895 - (BOOL)isDOMPasteAllowed
       
   896 {
       
   897     return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
       
   898 }
       
   899 
       
   900 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
       
   901 {
       
   902     [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
       
   903 }
       
   904 
       
   905 - (void)_setFTPDirectoryTemplatePath:(NSString *)path
       
   906 {
       
   907     [self _setStringValue:path forKey:WebKitFTPDirectoryTemplatePath];
       
   908 }
       
   909 
       
   910 - (NSString *)_ftpDirectoryTemplatePath
       
   911 {
       
   912     return [self _stringValueForKey:WebKitFTPDirectoryTemplatePath];
       
   913 }
       
   914 
       
   915 - (void)_setForceFTPDirectoryListings:(BOOL)force
       
   916 {
       
   917     [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
       
   918 }
       
   919 
       
   920 - (BOOL)_forceFTPDirectoryListings
       
   921 {
       
   922     return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
       
   923 }
       
   924 
       
   925 - (void)didRemoveFromWebView
       
   926 {
       
   927     ASSERT(_private->numWebViews);
       
   928     if (--_private->numWebViews == 0)
       
   929         [[NSNotificationCenter defaultCenter]
       
   930             postNotificationName:WebPreferencesRemovedNotification
       
   931                           object:self
       
   932                         userInfo:nil];
       
   933 }
       
   934 
       
   935 - (void)willAddToWebView
       
   936 {
       
   937     ++_private->numWebViews;
       
   938 }
       
   939 
       
   940 @end
       
   941 
       
   942 @implementation WebPreferences (WebInternal)
       
   943 
       
   944 + (NSString *)_IBCreatorID
       
   945 {
       
   946     return classIBCreatorID;
       
   947 }
       
   948 
       
   949 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
       
   950 {
       
   951     NSString *IBCreatorID = [WebPreferences _IBCreatorID];
       
   952     if (!IBCreatorID)
       
   953         return key;
       
   954     return [IBCreatorID stringByAppendingString:key];
       
   955 }
       
   956 
       
   957 @end