1 /* 2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. 3 * (C) 2006 Graham Dennis (graham.dennis (at) 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 "WebApplicationCache.h" 34 #import "WebKitLogging.h" 35 #import "WebKitNSStringExtras.h" 36 #import "WebKitSystemBits.h" 37 #import "WebKitSystemInterface.h" 38 #import "WebKitVersionChecks.h" 39 #import "WebNSDictionaryExtras.h" 40 #import "WebNSURLExtras.h" 41 #import <WebCore/ApplicationCacheStorage.h> 42 43 NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification"; 44 NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification"; 45 NSString *WebPreferencesChangedInternalNotification = @"WebPreferencesChangedInternalNotification"; 46 47 #define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x)) 48 49 enum { WebPreferencesVersion = 1 }; 50 51 static WebPreferences *_standardPreferences; 52 static NSMutableDictionary *webPreferencesInstances; 53 54 static bool contains(const char* const array[], int count, const char* item) 55 { 56 if (!item) 57 return false; 58 59 for (int i = 0; i < count; i++) 60 if (!strcasecmp(array[i], item)) 61 return true; 62 return false; 63 } 64 65 static WebCacheModel cacheModelForMainBundle(void) 66 { 67 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 68 69 // Apps that probably need the small setting 70 static const char* const documentViewerIDs[] = { 71 "Microsoft/com.microsoft.Messenger", 72 "com.adiumX.adiumX", 73 "com.alientechnology.Proteus", 74 "com.apple.Dashcode", 75 "com.apple.iChat", 76 "com.barebones.bbedit", 77 "com.barebones.textwrangler", 78 "com.barebones.yojimbo", 79 "com.equinux.iSale4", 80 "com.growl.growlframework", 81 "com.intrarts.PandoraMan", 82 "com.karelia.Sandvox", 83 "com.macromates.textmate", 84 "com.realmacsoftware.rapidweaverpro", 85 "com.red-sweater.marsedit", 86 "com.yahoo.messenger3", 87 "de.codingmonkeys.SubEthaEdit", 88 "fi.karppinen.Pyro", 89 "info.colloquy", 90 "kungfoo.tv.ecto", 91 }; 92 93 // Apps that probably need the medium setting 94 static const char* const documentBrowserIDs[] = { 95 "com.apple.Dictionary", 96 "com.apple.Xcode", 97 "com.apple.dashboard.client", 98 "com.apple.helpviewer", 99 "com.culturedcode.xyle", 100 "com.macrabbit.CSSEdit", 101 "com.panic.Coda", 102 "com.ranchero.NetNewsWire", 103 "com.thinkmac.NewsLife", 104 "org.xlife.NewsFire", 105 "uk.co.opencommunity.vienna2", 106 }; 107 108 // Apps that probably need the large setting 109 static const char* const primaryWebBrowserIDs[] = { 110 "com.app4mac.KidsBrowser" 111 "com.app4mac.wKiosk", 112 "com.freeverse.bumpercar", 113 "com.omnigroup.OmniWeb5", 114 "com.sunrisebrowser.Sunrise", 115 "net.hmdt-web.Shiira", 116 }; 117 118 WebCacheModel cacheModel; 119 120 const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String]; 121 if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID)) 122 cacheModel = WebCacheModelDocumentViewer; 123 else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID)) 124 cacheModel = WebCacheModelDocumentBrowser; 125 else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID)) 126 cacheModel = WebCacheModelPrimaryWebBrowser; 127 else { 128 bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API); 129 if (isLegacyApp) 130 cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache. 131 else 132 cacheModel = WebCacheModelDocumentViewer; // To save memory. 133 } 134 135 [pool drain]; 136 137 return cacheModel; 138 } 139 140 static bool useQuickLookQuirks(void) 141 { 142 NSArray* frameworks = [NSBundle allFrameworks]; 143 144 if (!frameworks) 145 return false; 146 147 for (unsigned int i = 0; i < [frameworks count]; i++) { 148 NSBundle* bundle = [frameworks objectAtIndex: i]; 149 const char* bundleID = [[bundle bundleIdentifier] UTF8String]; 150 if (bundleID && !strcasecmp(bundleID, "com.apple.QuickLookUIFramework")) 151 return true; 152 } 153 return false; 154 } 155 156 @interface WebPreferencesPrivate : NSObject 157 { 158 @public 159 NSMutableDictionary *values; 160 NSString *identifier; 161 NSString *IBCreatorID; 162 BOOL autosaves; 163 BOOL automaticallyDetectsCacheModel; 164 unsigned numWebViews; 165 } 166 @end 167 168 @implementation WebPreferencesPrivate 169 - (void)dealloc 170 { 171 [values release]; 172 [identifier release]; 173 [IBCreatorID release]; 174 [super dealloc]; 175 } 176 @end 177 178 @interface WebPreferences (WebInternal) 179 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key; 180 + (NSString *)_IBCreatorID; 181 @end 182 183 @interface WebPreferences (WebForwardDeclarations) 184 // This pseudo-category is needed so these methods can be used from within other category implementations 185 // without being in the public header file. 186 - (BOOL)_boolValueForKey:(NSString *)key; 187 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key; 188 - (int)_integerValueForKey:(NSString *)key; 189 - (void)_setIntegerValue:(int)value forKey:(NSString *)key; 190 - (float)_floatValueForKey:(NSString *)key; 191 - (void)_setFloatValue:(float)value forKey:(NSString *)key; 192 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key; 193 - (long long)_longLongValueForKey:(NSString *)key; 194 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key; 195 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key; 196 @end 197 198 @implementation WebPreferences 199 200 - (id)init 201 { 202 // Create fake identifier 203 static int instanceCount = 1; 204 NSString *fakeIdentifier; 205 206 // At least ensure that identifier hasn't been already used. 207 fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++]; 208 while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){ 209 fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++]; 210 } 211 212 return [self initWithIdentifier:fakeIdentifier]; 213 } 214 215 - (id)initWithIdentifier:(NSString *)anIdentifier 216 { 217 self = [super init]; 218 if (!self) 219 return nil; 220 221 _private = [[WebPreferencesPrivate alloc] init]; 222 _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain]; 223 224 WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier]; 225 if (instance){ 226 [self release]; 227 return [instance retain]; 228 } 229 230 _private->values = [[NSMutableDictionary alloc] init]; 231 _private->identifier = [anIdentifier copy]; 232 _private->automaticallyDetectsCacheModel = YES; 233 234 [[self class] _setInstance:self forIdentifier:_private->identifier]; 235 236 [self _postPreferencesChangedNotification]; 237 238 return self; 239 } 240 241 - (id)initWithCoder:(NSCoder *)decoder 242 { 243 self = [super init]; 244 if (!self) 245 return nil; 246 247 _private = [[WebPreferencesPrivate alloc] init]; 248 _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain]; 249 _private->automaticallyDetectsCacheModel = YES; 250 251 @try { 252 id identifier = nil; 253 id values = nil; 254 if ([decoder allowsKeyedCoding]) { 255 identifier = [decoder decodeObjectForKey:@"Identifier"]; 256 values = [decoder decodeObjectForKey:@"Values"]; 257 } else { 258 int version; 259 [decoder decodeValueOfObjCType:@encode(int) at:&version]; 260 if (version == 1) { 261 identifier = [decoder decodeObject]; 262 values = [decoder decodeObject]; 263 } 264 } 265 266 if ([identifier isKindOfClass:[NSString class]]) 267 _private->identifier = [identifier copy]; 268 if ([values isKindOfClass:[NSDictionary class]]) 269 _private->values = [values mutableCopy]; // ensure dictionary is mutable 270 271 LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values); 272 } @catch(id) { 273 [self release]; 274 return nil; 275 } 276 277 // If we load a nib multiple times, or have instances in multiple 278 // nibs with the same name, the first guy up wins. 279 WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier]; 280 if (instance) { 281 [self release]; 282 self = [instance retain]; 283 } else { 284 [[self class] _setInstance:self forIdentifier:_private->identifier]; 285 } 286 287 return self; 288 } 289 290 - (void)encodeWithCoder:(NSCoder *)encoder 291 { 292 if ([encoder allowsKeyedCoding]){ 293 [encoder encodeObject:_private->identifier forKey:@"Identifier"]; 294 [encoder encodeObject:_private->values forKey:@"Values"]; 295 LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values); 296 } 297 else { 298 int version = WebPreferencesVersion; 299 [encoder encodeValueOfObjCType:@encode(int) at:&version]; 300 [encoder encodeObject:_private->identifier]; 301 [encoder encodeObject:_private->values]; 302 } 303 } 304 305 + (WebPreferences *)standardPreferences 306 { 307 if (_standardPreferences == nil) { 308 _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil]; 309 [_standardPreferences setAutosaves:YES]; 310 } 311 312 return _standardPreferences; 313 } 314 315 // if we ever have more than one WebPreferences object, this would move to init 316 + (void)initialize 317 { 318 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 319 @"Times", WebKitStandardFontPreferenceKey, 320 @"Courier", WebKitFixedFontPreferenceKey, 321 @"Times", WebKitSerifFontPreferenceKey, 322 @"Helvetica", WebKitSansSerifFontPreferenceKey, 323 @"Apple Chancery", WebKitCursiveFontPreferenceKey, 324 @"Papyrus", WebKitFantasyFontPreferenceKey, 325 @"0", WebKitMinimumFontSizePreferenceKey, 326 @"9", WebKitMinimumLogicalFontSizePreferenceKey, 327 @"16", WebKitDefaultFontSizePreferenceKey, 328 @"13", WebKitDefaultFixedFontSizePreferenceKey, 329 @"ISO-8859-1", WebKitDefaultTextEncodingNamePreferenceKey, 330 [NSNumber numberWithBool:NO], WebKitUsesEncodingDetectorPreferenceKey, 331 [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey, 332 @"", WebKitUserStyleSheetLocationPreferenceKey, 333 [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey, 334 [NSNumber numberWithBool:NO], WebKitTextAreasAreResizablePreferenceKey, 335 [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFitPreferenceKey, 336 [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey, 337 [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey, 338 [NSNumber numberWithBool:YES], WebKitWebSecurityEnabledPreferenceKey, 339 [NSNumber numberWithBool:YES], WebKitAllowUniversalAccessFromFileURLsPreferenceKey, 340 [NSNumber numberWithBool:YES], WebKitAllowFileAccessFromFileURLsPreferenceKey, 341 [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey, 342 [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey, 343 [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey, 344 [NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey, 345 [NSNumber numberWithBool:NO], WebKitExperimentalNotificationsEnabledPreferenceKey, 346 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey, 347 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey, 348 [NSNumber numberWithBool:YES], WebKitDisplayImagesKey, 349 [NSNumber numberWithBool:NO], WebKitLoadSiteIconsKey, 350 @"1800", WebKitBackForwardCacheExpirationIntervalKey, 351 [NSNumber numberWithBool:NO], WebKitTabToLinksPreferenceKey, 352 [NSNumber numberWithBool:NO], WebKitPrivateBrowsingEnabledPreferenceKey, 353 [NSNumber numberWithBool:NO], WebKitRespectStandardStyleKeyEquivalentsPreferenceKey, 354 [NSNumber numberWithBool:NO], WebKitShowsURLsInToolTipsPreferenceKey, 355 @"1", WebKitPDFDisplayModePreferenceKey, 356 @"0", WebKitPDFScaleFactorPreferenceKey, 357 @"0", WebKitUseSiteSpecificSpoofingPreferenceKey, 358 [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey, 359 [NSNumber numberWithInt:WebKitEditingMacBehavior], WebKitEditingBehaviorPreferenceKey, 360 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) 361 [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded], 362 #else 363 [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded], 364 #endif 365 WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey, 366 [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey, 367 [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey, 368 [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey, 369 [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey, 370 [NSNumber numberWithBool:YES], WebKitAuthorAndUserStylesEnabledPreferenceKey, 371 [NSNumber numberWithBool:NO], WebKitApplicationChromeModeEnabledPreferenceKey, 372 [NSNumber numberWithBool:NO], WebKitWebArchiveDebugModeEnabledPreferenceKey, 373 [NSNumber numberWithBool:NO], WebKitLocalFileContentSniffingEnabledPreferenceKey, 374 [NSNumber numberWithBool:NO], WebKitOfflineWebApplicationCacheEnabledPreferenceKey, 375 [NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey, 376 [NSNumber numberWithBool:NO], WebKitJavaScriptCanAccessClipboardPreferenceKey, 377 [NSNumber numberWithBool:YES], WebKitXSSAuditorEnabledPreferenceKey, 378 [NSNumber numberWithBool:YES], WebKitAcceleratedCompositingEnabledPreferenceKey, 379 [NSNumber numberWithBool:NO], WebKitAcceleratedDrawingEnabledPreferenceKey, 380 [NSNumber numberWithBool:NO], WebKitCanvasUsesAcceleratedDrawingPreferenceKey, 381 [NSNumber numberWithBool:NO], WebKitShowDebugBordersPreferenceKey, 382 [NSNumber numberWithBool:NO], WebKitShowRepaintCounterPreferenceKey, 383 [NSNumber numberWithBool:NO], WebKitWebGLEnabledPreferenceKey, 384 [NSNumber numberWithBool:NO], WebKitAccelerated2dCanvasEnabledPreferenceKey, 385 [NSNumber numberWithUnsignedInt:4], WebKitPluginAllowedRunTimePreferenceKey, 386 [NSNumber numberWithBool:NO], WebKitFrameFlatteningEnabledPreferenceKey, 387 [NSNumber numberWithBool:NO], WebKitSpatialNavigationEnabledPreferenceKey, 388 [NSNumber numberWithBool:NO], WebKitDNSPrefetchingEnabledPreferenceKey, 389 [NSNumber numberWithBool:YES], WebKitFullScreenEnabledPreferenceKey, 390 [NSNumber numberWithBool:NO], WebKitAsynchronousSpellCheckingEnabledPreferenceKey, 391 [NSNumber numberWithBool:NO], WebKitMemoryInfoEnabledPreferenceKey, 392 [NSNumber numberWithBool:YES], WebKitHyperlinkAuditingEnabledPreferenceKey, 393 [NSNumber numberWithBool:NO], WebKitUsePreHTML5ParserQuirksKey, 394 [NSNumber numberWithBool:useQuickLookQuirks()], WebKitUseQuickLookResourceCachingQuirksPreferenceKey, 395 [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota, 396 [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota, 397 nil]; 398 399 // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above 400 ASSERT(kPDFDisplaySinglePageContinuous == 1); 401 [[NSUserDefaults standardUserDefaults] registerDefaults:dict]; 402 } 403 404 - (void)dealloc 405 { 406 [_private release]; 407 [super dealloc]; 408 } 409 410 - (NSString *)identifier 411 { 412 return _private->identifier; 413 } 414 415 - (id)_valueForKey:(NSString *)key 416 { 417 NSString *_key = KEY(key); 418 id o = [_private->values objectForKey:_key]; 419 if (o) 420 return o; 421 o = [[NSUserDefaults standardUserDefaults] objectForKey:_key]; 422 if (!o && key != _key) 423 o = [[NSUserDefaults standardUserDefaults] objectForKey:key]; 424 return o; 425 } 426 427 - (NSString *)_stringValueForKey:(NSString *)key 428 { 429 id s = [self _valueForKey:key]; 430 return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil; 431 } 432 433 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key 434 { 435 if ([[self _stringValueForKey:key] isEqualToString:value]) 436 return; 437 NSString *_key = KEY(key); 438 [_private->values setObject:value forKey:_key]; 439 if (_private->autosaves) 440 [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key]; 441 [self _postPreferencesChangedNotification]; 442 } 443 444 - (int)_integerValueForKey:(NSString *)key 445 { 446 id o = [self _valueForKey:key]; 447 return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0; 448 } 449 450 - (void)_setIntegerValue:(int)value forKey:(NSString *)key 451 { 452 if ([self _integerValueForKey:key] == value) 453 return; 454 NSString *_key = KEY(key); 455 [_private->values _webkit_setInt:value forKey:_key]; 456 if (_private->autosaves) 457 [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key]; 458 [self _postPreferencesChangedNotification]; 459 } 460 461 - (float)_floatValueForKey:(NSString *)key 462 { 463 id o = [self _valueForKey:key]; 464 return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f; 465 } 466 467 - (void)_setFloatValue:(float)value forKey:(NSString *)key 468 { 469 if ([self _floatValueForKey:key] == value) 470 return; 471 NSString *_key = KEY(key); 472 [_private->values _webkit_setFloat:value forKey:_key]; 473 if (_private->autosaves) 474 [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key]; 475 [self _postPreferencesChangedNotification]; 476 } 477 478 - (BOOL)_boolValueForKey:(NSString *)key 479 { 480 return [self _integerValueForKey:key] != 0; 481 } 482 483 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key 484 { 485 if ([self _boolValueForKey:key] == value) 486 return; 487 NSString *_key = KEY(key); 488 [_private->values _webkit_setBool:value forKey:_key]; 489 if (_private->autosaves) 490 [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key]; 491 [self _postPreferencesChangedNotification]; 492 } 493 494 - (long long)_longLongValueForKey:(NSString *)key 495 { 496 id o = [self _valueForKey:key]; 497 return [o respondsToSelector:@selector(longLongValue)] ? [o longLongValue] : 0; 498 } 499 500 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key 501 { 502 if ([self _longLongValueForKey:key] == value) 503 return; 504 NSString *_key = KEY(key); 505 [_private->values _webkit_setLongLong:value forKey:_key]; 506 if (_private->autosaves) 507 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key]; 508 [self _postPreferencesChangedNotification]; 509 } 510 511 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key 512 { 513 id o = [self _valueForKey:key]; 514 return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0; 515 } 516 517 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key 518 { 519 if ([self _unsignedLongLongValueForKey:key] == value) 520 return; 521 NSString *_key = KEY(key); 522 [_private->values _webkit_setUnsignedLongLong:value forKey:_key]; 523 if (_private->autosaves) 524 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key]; 525 [self _postPreferencesChangedNotification]; 526 } 527 528 - (NSString *)standardFontFamily 529 { 530 return [self _stringValueForKey: WebKitStandardFontPreferenceKey]; 531 } 532 533 - (void)setStandardFontFamily:(NSString *)family 534 { 535 [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey]; 536 } 537 538 - (NSString *)fixedFontFamily 539 { 540 return [self _stringValueForKey: WebKitFixedFontPreferenceKey]; 541 } 542 543 - (void)setFixedFontFamily:(NSString *)family 544 { 545 [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey]; 546 } 547 548 - (NSString *)serifFontFamily 549 { 550 return [self _stringValueForKey: WebKitSerifFontPreferenceKey]; 551 } 552 553 - (void)setSerifFontFamily:(NSString *)family 554 { 555 [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey]; 556 } 557 558 - (NSString *)sansSerifFontFamily 559 { 560 return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey]; 561 } 562 563 - (void)setSansSerifFontFamily:(NSString *)family 564 { 565 [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey]; 566 } 567 568 - (NSString *)cursiveFontFamily 569 { 570 return [self _stringValueForKey: WebKitCursiveFontPreferenceKey]; 571 } 572 573 - (void)setCursiveFontFamily:(NSString *)family 574 { 575 [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey]; 576 } 577 578 - (NSString *)fantasyFontFamily 579 { 580 return [self _stringValueForKey: WebKitFantasyFontPreferenceKey]; 581 } 582 583 - (void)setFantasyFontFamily:(NSString *)family 584 { 585 [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey]; 586 } 587 588 - (int)defaultFontSize 589 { 590 return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey]; 591 } 592 593 - (void)setDefaultFontSize:(int)size 594 { 595 [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey]; 596 } 597 598 - (int)defaultFixedFontSize 599 { 600 return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey]; 601 } 602 603 - (void)setDefaultFixedFontSize:(int)size 604 { 605 [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey]; 606 } 607 608 - (int)minimumFontSize 609 { 610 return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey]; 611 } 612 613 - (void)setMinimumFontSize:(int)size 614 { 615 [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey]; 616 } 617 618 - (int)minimumLogicalFontSize 619 { 620 return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey]; 621 } 622 623 - (void)setMinimumLogicalFontSize:(int)size 624 { 625 [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey]; 626 } 627 628 - (NSString *)defaultTextEncodingName 629 { 630 return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey]; 631 } 632 633 - (void)setDefaultTextEncodingName:(NSString *)encoding 634 { 635 [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey]; 636 } 637 638 - (BOOL)userStyleSheetEnabled 639 { 640 return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey]; 641 } 642 643 - (void)setUserStyleSheetEnabled:(BOOL)flag 644 { 645 [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey]; 646 } 647 648 - (NSURL *)userStyleSheetLocation 649 { 650 NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey]; 651 652 if ([locationString _webkit_looksLikeAbsoluteURL]) { 653 return [NSURL _web_URLWithDataAsString:locationString]; 654 } else { 655 locationString = [locationString stringByExpandingTildeInPath]; 656 return [NSURL fileURLWithPath:locationString]; 657 } 658 } 659 660 - (void)setUserStyleSheetLocation:(NSURL *)URL 661 { 662 NSString *locationString; 663 664 if ([URL isFileURL]) { 665 locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath]; 666 } else { 667 locationString = [URL _web_originalDataAsString]; 668 } 669 670 if (!locationString) 671 locationString = @""; 672 673 [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey]; 674 } 675 676 - (BOOL)shouldPrintBackgrounds 677 { 678 return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey]; 679 } 680 681 - (void)setShouldPrintBackgrounds:(BOOL)flag 682 { 683 [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey]; 684 } 685 686 - (BOOL)isJavaEnabled 687 { 688 return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey]; 689 } 690 691 - (void)setJavaEnabled:(BOOL)flag 692 { 693 [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey]; 694 } 695 696 - (BOOL)isJavaScriptEnabled 697 { 698 return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey]; 699 } 700 701 - (void)setJavaScriptEnabled:(BOOL)flag 702 { 703 [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey]; 704 } 705 706 - (BOOL)javaScriptCanOpenWindowsAutomatically 707 { 708 return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey]; 709 } 710 711 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag 712 { 713 [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey]; 714 } 715 716 - (BOOL)arePlugInsEnabled 717 { 718 return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey]; 719 } 720 721 - (void)setPlugInsEnabled:(BOOL)flag 722 { 723 [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey]; 724 } 725 726 - (BOOL)allowsAnimatedImages 727 { 728 return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey]; 729 } 730 731 - (void)setAllowsAnimatedImages:(BOOL)flag 732 { 733 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey]; 734 } 735 736 - (BOOL)allowsAnimatedImageLooping 737 { 738 return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey]; 739 } 740 741 - (void)setAllowsAnimatedImageLooping: (BOOL)flag 742 { 743 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey]; 744 } 745 746 - (void)setLoadsImagesAutomatically: (BOOL)flag 747 { 748 [self _setBoolValue: flag forKey: WebKitDisplayImagesKey]; 749 } 750 751 - (BOOL)loadsImagesAutomatically 752 { 753 return [self _boolValueForKey: WebKitDisplayImagesKey]; 754 } 755 756 - (void)setAutosaves:(BOOL)flag 757 { 758 _private->autosaves = flag; 759 } 760 761 - (BOOL)autosaves 762 { 763 return _private->autosaves; 764 } 765 766 - (void)setTabsToLinks:(BOOL)flag 767 { 768 [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey]; 769 } 770 771 - (BOOL)tabsToLinks 772 { 773 return [self _boolValueForKey:WebKitTabToLinksPreferenceKey]; 774 } 775 776 - (void)setPrivateBrowsingEnabled:(BOOL)flag 777 { 778 [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey]; 779 } 780 781 - (BOOL)privateBrowsingEnabled 782 { 783 return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey]; 784 } 785 786 - (void)setUsesPageCache:(BOOL)usesPageCache 787 { 788 [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey]; 789 } 790 791 - (BOOL)usesPageCache 792 { 793 return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey]; 794 } 795 796 - (void)setCacheModel:(WebCacheModel)cacheModel 797 { 798 [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey]; 799 [self setAutomaticallyDetectsCacheModel:NO]; 800 } 801 802 - (WebCacheModel)cacheModel 803 { 804 return [self _integerValueForKey:WebKitCacheModelPreferenceKey]; 805 } 806 807 @end 808 809 @implementation WebPreferences (WebPrivate) 810 811 - (BOOL)isDNSPrefetchingEnabled 812 { 813 return [self _boolValueForKey:WebKitDNSPrefetchingEnabledPreferenceKey]; 814 } 815 816 - (void)setDNSPrefetchingEnabled:(BOOL)flag 817 { 818 [self _setBoolValue:flag forKey:WebKitDNSPrefetchingEnabledPreferenceKey]; 819 } 820 821 - (BOOL)developerExtrasEnabled 822 { 823 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 824 if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"]) 825 return NO; 826 #ifdef NDEBUG 827 if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"]) 828 return YES; 829 return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey]; 830 #else 831 return YES; // always enable in debug builds 832 #endif 833 } 834 835 - (void)setDeveloperExtrasEnabled:(BOOL)flag 836 { 837 [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey]; 838 } 839 840 - (BOOL)authorAndUserStylesEnabled 841 { 842 return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey]; 843 } 844 845 - (void)setAuthorAndUserStylesEnabled:(BOOL)flag 846 { 847 [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey]; 848 } 849 850 - (BOOL)applicationChromeModeEnabled 851 { 852 return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey]; 853 } 854 855 - (void)setApplicationChromeModeEnabled:(BOOL)flag 856 { 857 [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey]; 858 } 859 860 - (BOOL)webArchiveDebugModeEnabled 861 { 862 return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey]; 863 } 864 865 - (void)setWebArchiveDebugModeEnabled:(BOOL)flag 866 { 867 [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey]; 868 } 869 870 - (BOOL)localFileContentSniffingEnabled 871 { 872 return [self _boolValueForKey:WebKitLocalFileContentSniffingEnabledPreferenceKey]; 873 } 874 875 - (void)setLocalFileContentSniffingEnabled:(BOOL)flag 876 { 877 [self _setBoolValue:flag forKey:WebKitLocalFileContentSniffingEnabledPreferenceKey]; 878 } 879 880 - (BOOL)offlineWebApplicationCacheEnabled 881 { 882 return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey]; 883 } 884 885 - (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag 886 { 887 [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey]; 888 } 889 890 - (BOOL)zoomsTextOnly 891 { 892 return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey]; 893 } 894 895 - (void)setZoomsTextOnly:(BOOL)flag 896 { 897 [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey]; 898 } 899 900 - (BOOL)javaScriptCanAccessClipboard 901 { 902 return [self _boolValueForKey:WebKitJavaScriptCanAccessClipboardPreferenceKey]; 903 } 904 905 - (void)setJavaScriptCanAccessClipboard:(BOOL)flag 906 { 907 [self _setBoolValue:flag forKey:WebKitJavaScriptCanAccessClipboardPreferenceKey]; 908 } 909 910 - (BOOL)isXSSAuditorEnabled 911 { 912 return [self _boolValueForKey:WebKitXSSAuditorEnabledPreferenceKey]; 913 } 914 915 - (void)setXSSAuditorEnabled:(BOOL)flag 916 { 917 [self _setBoolValue:flag forKey:WebKitXSSAuditorEnabledPreferenceKey]; 918 } 919 920 - (BOOL)respectStandardStyleKeyEquivalents 921 { 922 return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey]; 923 } 924 925 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag 926 { 927 [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey]; 928 } 929 930 - (BOOL)showsURLsInToolTips 931 { 932 return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey]; 933 } 934 935 - (void)setShowsURLsInToolTips:(BOOL)flag 936 { 937 [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey]; 938 } 939 940 - (BOOL)textAreasAreResizable 941 { 942 return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey]; 943 } 944 945 - (void)setTextAreasAreResizable:(BOOL)flag 946 { 947 [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey]; 948 } 949 950 - (BOOL)shrinksStandaloneImagesToFit 951 { 952 return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey]; 953 } 954 955 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag 956 { 957 [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey]; 958 } 959 960 - (BOOL)automaticallyDetectsCacheModel 961 { 962 return _private->automaticallyDetectsCacheModel; 963 } 964 965 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel 966 { 967 _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel; 968 } 969 970 - (BOOL)usesEncodingDetector 971 { 972 return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey]; 973 } 974 975 - (void)setUsesEncodingDetector:(BOOL)flag 976 { 977 [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey]; 978 } 979 980 - (BOOL)isWebSecurityEnabled 981 { 982 return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey]; 983 } 984 985 - (void)setWebSecurityEnabled:(BOOL)flag 986 { 987 [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey]; 988 } 989 990 - (BOOL)allowUniversalAccessFromFileURLs 991 { 992 return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey]; 993 } 994 995 - (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag 996 { 997 [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey]; 998 } 999 1000 - (BOOL)allowFileAccessFromFileURLs 1001 { 1002 return [self _boolValueForKey: WebKitAllowFileAccessFromFileURLsPreferenceKey]; 1003 } 1004 1005 - (void)setAllowFileAccessFromFileURLs:(BOOL)flag 1006 { 1007 [self _setBoolValue: flag forKey: WebKitAllowFileAccessFromFileURLsPreferenceKey]; 1008 } 1009 1010 - (NSTimeInterval)_backForwardCacheExpirationInterval 1011 { 1012 // FIXME: There's probably no good reason to read from the standard user defaults instead of self. 1013 return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey]; 1014 } 1015 1016 - (float)PDFScaleFactor 1017 { 1018 return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey]; 1019 } 1020 1021 - (void)setPDFScaleFactor:(float)factor 1022 { 1023 [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey]; 1024 } 1025 1026 - (int64_t)applicationCacheTotalQuota 1027 { 1028 return [self _longLongValueForKey:WebKitApplicationCacheTotalQuota]; 1029 } 1030 1031 - (void)setApplicationCacheTotalQuota:(int64_t)quota 1032 { 1033 [self _setLongLongValue:quota forKey:WebKitApplicationCacheTotalQuota]; 1034 1035 // Application Cache Preferences are stored on the global cache storage manager, not in Settings. 1036 [WebApplicationCache setMaximumSize:quota]; 1037 } 1038 1039 - (int64_t)applicationCacheDefaultOriginQuota 1040 { 1041 return [self _longLongValueForKey:WebKitApplicationCacheDefaultOriginQuota]; 1042 } 1043 1044 - (void)setApplicationCacheDefaultOriginQuota:(int64_t)quota 1045 { 1046 [self _setLongLongValue:quota forKey:WebKitApplicationCacheDefaultOriginQuota]; 1047 } 1048 1049 - (PDFDisplayMode)PDFDisplayMode 1050 { 1051 PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey]; 1052 if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) { 1053 // protect against new modes from future versions of OS X stored in defaults 1054 value = kPDFDisplaySinglePageContinuous; 1055 } 1056 return value; 1057 } 1058 1059 - (void)setPDFDisplayMode:(PDFDisplayMode)mode 1060 { 1061 [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey]; 1062 } 1063 1064 - (WebKitEditableLinkBehavior)editableLinkBehavior 1065 { 1066 WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]); 1067 if (value != WebKitEditableLinkDefaultBehavior && 1068 value != WebKitEditableLinkAlwaysLive && 1069 value != WebKitEditableLinkNeverLive && 1070 value != WebKitEditableLinkOnlyLiveWithShiftKey && 1071 value != WebKitEditableLinkLiveWhenNotFocused) { 1072 // ensure that a valid result is returned 1073 value = WebKitEditableLinkDefaultBehavior; 1074 } 1075 1076 return value; 1077 } 1078 1079 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior 1080 { 1081 [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey]; 1082 } 1083 1084 - (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior 1085 { 1086 WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]); 1087 if (value != WebTextDirectionSubmenuNeverIncluded && 1088 value != WebTextDirectionSubmenuAutomaticallyIncluded && 1089 value != WebTextDirectionSubmenuAlwaysIncluded) { 1090 // Ensure that a valid result is returned. 1091 value = WebTextDirectionSubmenuNeverIncluded; 1092 } 1093 return value; 1094 } 1095 1096 - (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior 1097 { 1098 [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]; 1099 } 1100 1101 - (BOOL)_useSiteSpecificSpoofing 1102 { 1103 return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey]; 1104 } 1105 1106 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue 1107 { 1108 [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey]; 1109 } 1110 1111 - (BOOL)databasesEnabled 1112 { 1113 return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey]; 1114 } 1115 1116 - (void)setDatabasesEnabled:(BOOL)databasesEnabled 1117 { 1118 [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey]; 1119 } 1120 1121 - (BOOL)localStorageEnabled 1122 { 1123 return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey]; 1124 } 1125 1126 - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled 1127 { 1128 [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey]; 1129 } 1130 1131 - (BOOL)experimentalNotificationsEnabled 1132 { 1133 return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey]; 1134 } 1135 1136 - (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled 1137 { 1138 [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey]; 1139 } 1140 1141 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident 1142 { 1143 LOG(Encoding, "requesting for %@\n", ident); 1144 1145 if (!ident) 1146 return _standardPreferences; 1147 1148 WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]]; 1149 1150 return instance; 1151 } 1152 1153 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident 1154 { 1155 if (!webPreferencesInstances) 1156 webPreferencesInstances = [[NSMutableDictionary alloc] init]; 1157 if (ident) { 1158 [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]]; 1159 LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]); 1160 } 1161 } 1162 1163 + (void)_checkLastReferenceForIdentifier:(id)identifier 1164 { 1165 // FIXME: This won't work at all under garbage collection because retainCount returns a constant. 1166 // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one. 1167 WebPreferences *instance = [webPreferencesInstances objectForKey:identifier]; 1168 if ([instance retainCount] == 1) 1169 [webPreferencesInstances removeObjectForKey:identifier]; 1170 } 1171 1172 + (void)_removeReferenceForIdentifier:(NSString *)ident 1173 { 1174 if (ident) 1175 [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1]; 1176 } 1177 1178 - (void)_postPreferencesChangedNotification 1179 { 1180 if (!pthread_main_np()) { 1181 [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO]; 1182 return; 1183 } 1184 1185 [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedInternalNotification object:self userInfo:nil]; 1186 [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil]; 1187 } 1188 1189 - (void)_postPreferencesChangedAPINotification 1190 { 1191 if (!pthread_main_np()) { 1192 [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO]; 1193 return; 1194 } 1195 1196 [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil]; 1197 } 1198 1199 + (CFStringEncoding)_systemCFStringEncoding 1200 { 1201 return WKGetWebDefaultCFStringEncoding(); 1202 } 1203 1204 + (void)_setInitialDefaultTextEncodingToSystemEncoding 1205 { 1206 NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]); 1207 1208 // CFStringConvertEncodingToIANACharSetName() returns cp949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-949. 1209 // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-949. 1210 // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>. 1211 // On some OS versions, the result is CP949 (uppercase). 1212 if ([systemEncodingName _webkit_isCaseInsensitiveEqualToString:@"cp949"]) 1213 systemEncodingName = @"ks_c_5601-1987"; 1214 [[NSUserDefaults standardUserDefaults] registerDefaults: 1215 [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]]; 1216 } 1217 1218 static NSString *classIBCreatorID = nil; 1219 1220 + (void)_setIBCreatorID:(NSString *)string 1221 { 1222 NSString *old = classIBCreatorID; 1223 classIBCreatorID = [string copy]; 1224 [old release]; 1225 } 1226 1227 - (BOOL)isDOMPasteAllowed 1228 { 1229 return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey]; 1230 } 1231 1232 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed 1233 { 1234 [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey]; 1235 } 1236 1237 - (NSString *)_localStorageDatabasePath 1238 { 1239 return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath]; 1240 } 1241 1242 - (void)_setLocalStorageDatabasePath:(NSString *)path 1243 { 1244 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey]; 1245 } 1246 1247 - (NSString *)_ftpDirectoryTemplatePath 1248 { 1249 return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath]; 1250 } 1251 1252 - (void)_setFTPDirectoryTemplatePath:(NSString *)path 1253 { 1254 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath]; 1255 } 1256 1257 - (BOOL)_forceFTPDirectoryListings 1258 { 1259 return [self _boolValueForKey:WebKitForceFTPDirectoryListings]; 1260 } 1261 1262 - (void)_setForceFTPDirectoryListings:(BOOL)force 1263 { 1264 [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings]; 1265 } 1266 1267 - (BOOL)acceleratedDrawingEnabled 1268 { 1269 return [self _boolValueForKey:WebKitAcceleratedDrawingEnabledPreferenceKey]; 1270 } 1271 1272 - (void)setAcceleratedDrawingEnabled:(BOOL)enabled 1273 { 1274 [self _setBoolValue:enabled forKey:WebKitAcceleratedDrawingEnabledPreferenceKey]; 1275 } 1276 1277 - (BOOL)canvasUsesAcceleratedDrawing 1278 { 1279 return [self _boolValueForKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey]; 1280 } 1281 1282 - (void)setCanvasUsesAcceleratedDrawing:(BOOL)enabled 1283 { 1284 [self _setBoolValue:enabled forKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey]; 1285 } 1286 1287 - (BOOL)acceleratedCompositingEnabled 1288 { 1289 return [self _boolValueForKey:WebKitAcceleratedCompositingEnabledPreferenceKey]; 1290 } 1291 1292 - (void)setAcceleratedCompositingEnabled:(BOOL)enabled 1293 { 1294 [self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey]; 1295 } 1296 1297 - (BOOL)showDebugBorders 1298 { 1299 return [self _boolValueForKey:WebKitShowDebugBordersPreferenceKey]; 1300 } 1301 1302 - (void)setShowDebugBorders:(BOOL)enabled 1303 { 1304 [self _setBoolValue:enabled forKey:WebKitShowDebugBordersPreferenceKey]; 1305 } 1306 1307 - (BOOL)showRepaintCounter 1308 { 1309 return [self _boolValueForKey:WebKitShowRepaintCounterPreferenceKey]; 1310 } 1311 1312 - (void)setShowRepaintCounter:(BOOL)enabled 1313 { 1314 [self _setBoolValue:enabled forKey:WebKitShowRepaintCounterPreferenceKey]; 1315 } 1316 1317 - (BOOL)webAudioEnabled 1318 { 1319 return [self _boolValueForKey:WebKitWebAudioEnabledPreferenceKey]; 1320 } 1321 1322 - (void)setWebAudioEnabled:(BOOL)enabled 1323 { 1324 [self _setBoolValue:enabled forKey:WebKitWebAudioEnabledPreferenceKey]; 1325 } 1326 1327 - (BOOL)webGLEnabled 1328 { 1329 return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey]; 1330 } 1331 1332 - (void)setWebGLEnabled:(BOOL)enabled 1333 { 1334 [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey]; 1335 } 1336 1337 - (BOOL)accelerated2dCanvasEnabled 1338 { 1339 return [self _boolValueForKey:WebKitAccelerated2dCanvasEnabledPreferenceKey]; 1340 } 1341 1342 - (void)setAccelerated2dCanvasEnabled:(BOOL)enabled 1343 { 1344 [self _setBoolValue:enabled forKey:WebKitAccelerated2dCanvasEnabledPreferenceKey]; 1345 } 1346 1347 - (unsigned)pluginAllowedRunTime 1348 { 1349 return [self _integerValueForKey:WebKitPluginAllowedRunTimePreferenceKey]; 1350 } 1351 1352 - (void)setPluginAllowedRunTime:(unsigned)allowedRunTime 1353 { 1354 return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey]; 1355 } 1356 1357 - (BOOL)isFrameFlatteningEnabled 1358 { 1359 return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey]; 1360 } 1361 1362 - (void)setFrameFlatteningEnabled:(BOOL)flag 1363 { 1364 [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey]; 1365 } 1366 1367 - (BOOL)isSpatialNavigationEnabled 1368 { 1369 return [self _boolValueForKey:WebKitSpatialNavigationEnabledPreferenceKey]; 1370 } 1371 1372 - (void)setSpatialNavigationEnabled:(BOOL)flag 1373 { 1374 [self _setBoolValue:flag forKey:WebKitSpatialNavigationEnabledPreferenceKey]; 1375 } 1376 1377 - (BOOL)paginateDuringLayoutEnabled 1378 { 1379 return [self _boolValueForKey:WebKitPaginateDuringLayoutEnabledPreferenceKey]; 1380 } 1381 1382 - (void)setPaginateDuringLayoutEnabled:(BOOL)flag 1383 { 1384 [self _setBoolValue:flag forKey:WebKitPaginateDuringLayoutEnabledPreferenceKey]; 1385 } 1386 1387 - (BOOL)memoryInfoEnabled 1388 { 1389 return [self _boolValueForKey:WebKitMemoryInfoEnabledPreferenceKey]; 1390 } 1391 1392 - (void)setMemoryInfoEnabled:(BOOL)flag 1393 { 1394 [self _setBoolValue:flag forKey:WebKitMemoryInfoEnabledPreferenceKey]; 1395 } 1396 1397 - (BOOL)hyperlinkAuditingEnabled 1398 { 1399 return [self _boolValueForKey:WebKitHyperlinkAuditingEnabledPreferenceKey]; 1400 } 1401 1402 - (void)setHyperlinkAuditingEnabled:(BOOL)flag 1403 { 1404 [self _setBoolValue:flag forKey:WebKitHyperlinkAuditingEnabledPreferenceKey]; 1405 } 1406 1407 - (WebKitEditingBehavior)editingBehavior 1408 { 1409 return static_cast<WebKitEditingBehavior>([self _integerValueForKey:WebKitEditingBehaviorPreferenceKey]); 1410 } 1411 1412 - (void)setEditingBehavior:(WebKitEditingBehavior)behavior 1413 { 1414 [self _setIntegerValue:behavior forKey:WebKitEditingBehaviorPreferenceKey]; 1415 } 1416 1417 - (BOOL)usePreHTML5ParserQuirks 1418 { 1419 return [self _boolValueForKey:WebKitUsePreHTML5ParserQuirksKey]; 1420 } 1421 1422 - (void)setUsePreHTML5ParserQuirks:(BOOL)flag 1423 { 1424 [self _setBoolValue:flag forKey:WebKitUsePreHTML5ParserQuirksKey]; 1425 } 1426 1427 - (BOOL)useQuickLookResourceCachingQuirks 1428 { 1429 return [self _boolValueForKey:WebKitUseQuickLookResourceCachingQuirksPreferenceKey]; 1430 } 1431 1432 - (void)didRemoveFromWebView 1433 { 1434 ASSERT(_private->numWebViews); 1435 if (--_private->numWebViews == 0) 1436 [[NSNotificationCenter defaultCenter] 1437 postNotificationName:WebPreferencesRemovedNotification 1438 object:self 1439 userInfo:nil]; 1440 } 1441 1442 - (void)willAddToWebView 1443 { 1444 ++_private->numWebViews; 1445 } 1446 1447 - (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key 1448 { 1449 [self _setStringValue:value forKey:key]; 1450 } 1451 1452 - (void)setFullScreenEnabled:(BOOL)flag 1453 { 1454 [self _setBoolValue:flag forKey:WebKitFullScreenEnabledPreferenceKey]; 1455 } 1456 1457 - (BOOL)fullScreenEnabled 1458 { 1459 return [self _boolValueForKey:WebKitFullScreenEnabledPreferenceKey]; 1460 } 1461 1462 - (void)setAsynchronousSpellCheckingEnabled:(BOOL)flag 1463 { 1464 [self _setBoolValue:flag forKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey]; 1465 } 1466 1467 - (BOOL)asynchronousSpellCheckingEnabled 1468 { 1469 return [self _boolValueForKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey]; 1470 } 1471 1472 + (void)setWebKitLinkTimeVersion:(int)version 1473 { 1474 setWebKitLinkTimeVersion(version); 1475 } 1476 1477 - (void)setLoadsSiteIconsIgnoringImageLoadingPreference: (BOOL)flag 1478 { 1479 [self _setBoolValue: flag forKey: WebKitLoadSiteIconsKey]; 1480 } 1481 1482 - (BOOL)loadsSiteIconsIgnoringImageLoadingPreference 1483 { 1484 return [self _boolValueForKey: WebKitLoadSiteIconsKey]; 1485 } 1486 1487 @end 1488 1489 @implementation WebPreferences (WebInternal) 1490 1491 + (NSString *)_IBCreatorID 1492 { 1493 return classIBCreatorID; 1494 } 1495 1496 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key 1497 { 1498 NSString *IBCreatorID = [WebPreferences _IBCreatorID]; 1499 if (!IBCreatorID) 1500 return key; 1501 return [IBCreatorID stringByAppendingString:key]; 1502 } 1503 1504 @end 1505