2 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
3 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #import "WebPreferencesPrivate.h"
31 #import "WebPreferenceKeysPrivate.h"
33 #import "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>
43 NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
44 NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";
46 #define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x))
48 enum { WebPreferencesVersion = 1 };
50 static WebPreferences *_standardPreferences;
51 static NSMutableDictionary *webPreferencesInstances;
53 static bool contains(const char* const array[], int count, const char* item)
58 for (int i = 0; i < count; i++)
59 if (!strcasecmp(array[i], item))
64 static WebCacheModel cacheModelForMainBundle(void)
66 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
68 // Apps that probably need the small setting
69 static const char* const documentViewerIDs[] = {
70 "Microsoft/com.microsoft.Messenger",
72 "com.alientechnology.Proteus",
75 "com.barebones.bbedit",
76 "com.barebones.textwrangler",
77 "com.barebones.yojimbo",
79 "com.growl.growlframework",
80 "com.intrarts.PandoraMan",
81 "com.karelia.Sandvox",
82 "com.macromates.textmate",
83 "com.realmacsoftware.rapidweaverpro",
84 "com.red-sweater.marsedit",
85 "com.yahoo.messenger3",
86 "de.codingmonkeys.SubEthaEdit",
92 // Apps that probably need the medium setting
93 static const char* const documentBrowserIDs[] = {
94 "com.apple.Dictionary",
96 "com.apple.dashboard.client",
97 "com.apple.helpviewer",
98 "com.culturedcode.xyle",
99 "com.macrabbit.CSSEdit",
101 "com.ranchero.NetNewsWire",
102 "com.thinkmac.NewsLife",
103 "org.xlife.NewsFire",
104 "uk.co.opencommunity.vienna2",
107 // Apps that probably need the large setting
108 static const char* const primaryWebBrowserIDs[] = {
109 "com.app4mac.KidsBrowser"
110 "com.app4mac.wKiosk",
111 "com.freeverse.bumpercar",
112 "com.omnigroup.OmniWeb5",
113 "com.sunrisebrowser.Sunrise",
114 "net.hmdt-web.Shiira",
117 WebCacheModel cacheModel;
119 const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
120 if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID))
121 cacheModel = WebCacheModelDocumentViewer;
122 else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID))
123 cacheModel = WebCacheModelDocumentBrowser;
124 else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID))
125 cacheModel = WebCacheModelPrimaryWebBrowser;
127 bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API);
129 cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache.
131 cacheModel = WebCacheModelDocumentViewer; // To save memory.
139 @interface WebPreferencesPrivate : NSObject
142 NSMutableDictionary *values;
143 NSString *identifier;
144 NSString *IBCreatorID;
146 BOOL automaticallyDetectsCacheModel;
147 unsigned numWebViews;
151 @implementation WebPreferencesPrivate
155 [identifier release];
156 [IBCreatorID release];
161 @interface WebPreferences (WebInternal)
162 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
163 + (NSString *)_IBCreatorID;
166 @interface WebPreferences (WebForwardDeclarations)
167 // This pseudo-category is needed so these methods can be used from within other category implementations
168 // without being in the public header file.
169 - (BOOL)_boolValueForKey:(NSString *)key;
170 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
171 - (int)_integerValueForKey:(NSString *)key;
172 - (void)_setIntegerValue:(int)value forKey:(NSString *)key;
173 - (float)_floatValueForKey:(NSString *)key;
174 - (void)_setFloatValue:(float)value forKey:(NSString *)key;
175 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key;
176 - (long long)_longLongValueForKey:(NSString *)key;
177 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key;
178 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key;
181 @implementation WebPreferences
185 // Create fake identifier
186 static int instanceCount = 1;
187 NSString *fakeIdentifier;
189 // At least ensure that identifier hasn't been already used.
190 fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
191 while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
192 fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
195 return [self initWithIdentifier:fakeIdentifier];
198 - (id)initWithIdentifier:(NSString *)anIdentifier
204 _private = [[WebPreferencesPrivate alloc] init];
205 _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
207 WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
210 return [instance retain];
213 _private->values = [[NSMutableDictionary alloc] init];
214 _private->identifier = [anIdentifier copy];
215 _private->automaticallyDetectsCacheModel = YES;
217 [[self class] _setInstance:self forIdentifier:_private->identifier];
219 [self _postPreferencesChangesNotification];
224 - (id)initWithCoder:(NSCoder *)decoder
230 _private = [[WebPreferencesPrivate alloc] init];
231 _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
232 _private->automaticallyDetectsCacheModel = YES;
237 if ([decoder allowsKeyedCoding]) {
238 identifier = [decoder decodeObjectForKey:@"Identifier"];
239 values = [decoder decodeObjectForKey:@"Values"];
242 [decoder decodeValueOfObjCType:@encode(int) at:&version];
244 identifier = [decoder decodeObject];
245 values = [decoder decodeObject];
249 if ([identifier isKindOfClass:[NSString class]])
250 _private->identifier = [identifier copy];
251 if ([values isKindOfClass:[NSDictionary class]])
252 _private->values = [values mutableCopy]; // ensure dictionary is mutable
254 LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
260 // If we load a nib multiple times, or have instances in multiple
261 // nibs with the same name, the first guy up wins.
262 WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
265 self = [instance retain];
267 [[self class] _setInstance:self forIdentifier:_private->identifier];
273 - (void)encodeWithCoder:(NSCoder *)encoder
275 if ([encoder allowsKeyedCoding]){
276 [encoder encodeObject:_private->identifier forKey:@"Identifier"];
277 [encoder encodeObject:_private->values forKey:@"Values"];
278 LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
281 int version = WebPreferencesVersion;
282 [encoder encodeValueOfObjCType:@encode(int) at:&version];
283 [encoder encodeObject:_private->identifier];
284 [encoder encodeObject:_private->values];
288 + (WebPreferences *)standardPreferences
290 if (_standardPreferences == nil) {
291 _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
292 [_standardPreferences setAutosaves:YES];
295 return _standardPreferences;
298 // if we ever have more than one WebPreferences object, this would move to init
301 NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
302 @"Times", WebKitStandardFontPreferenceKey,
303 @"Courier", WebKitFixedFontPreferenceKey,
304 @"Times", WebKitSerifFontPreferenceKey,
305 @"Helvetica", WebKitSansSerifFontPreferenceKey,
306 @"Apple Chancery", WebKitCursiveFontPreferenceKey,
307 @"Papyrus", WebKitFantasyFontPreferenceKey,
308 @"1", WebKitMinimumFontSizePreferenceKey,
309 @"9", WebKitMinimumLogicalFontSizePreferenceKey,
310 @"16", WebKitDefaultFontSizePreferenceKey,
311 @"13", WebKitDefaultFixedFontSizePreferenceKey,
312 @"ISO-8859-1", WebKitDefaultTextEncodingNamePreferenceKey,
313 [NSNumber numberWithBool:NO], WebKitUsesEncodingDetectorPreferenceKey,
314 [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey,
315 @"", WebKitUserStyleSheetLocationPreferenceKey,
316 [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey,
317 [NSNumber numberWithBool:NO], WebKitTextAreasAreResizablePreferenceKey,
318 [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFitPreferenceKey,
319 [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey,
320 [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey,
321 [NSNumber numberWithBool:YES], WebKitWebSecurityEnabledPreferenceKey,
322 [NSNumber numberWithBool:YES], WebKitAllowUniversalAccessFromFileURLsPreferenceKey,
323 [NSNumber numberWithBool:YES], WebKitAllowFileAccessFromFileURLsPreferenceKey,
324 [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
325 [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey,
326 [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey,
327 [NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey,
328 [NSNumber numberWithBool:NO], WebKitExperimentalNotificationsEnabledPreferenceKey,
329 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey,
330 [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey,
331 [NSNumber numberWithBool:YES], WebKitDisplayImagesKey,
332 @"1800", WebKitBackForwardCacheExpirationIntervalKey,
333 [NSNumber numberWithBool:NO], WebKitTabToLinksPreferenceKey,
334 [NSNumber numberWithBool:NO], WebKitPrivateBrowsingEnabledPreferenceKey,
335 [NSNumber numberWithBool:NO], WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
336 [NSNumber numberWithBool:NO], WebKitShowsURLsInToolTipsPreferenceKey,
337 @"1", WebKitPDFDisplayModePreferenceKey,
338 @"0", WebKitPDFScaleFactorPreferenceKey,
339 @"0", WebKitUseSiteSpecificSpoofingPreferenceKey,
340 [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
341 [NSNumber numberWithInt:WebKitEditingMacBehavior], WebKitEditingBehaviorPreferenceKey,
342 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
343 [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],
345 [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded],
347 WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey,
348 [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey,
349 [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey,
350 [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
351 [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey,
352 [NSNumber numberWithBool:YES], WebKitAuthorAndUserStylesEnabledPreferenceKey,
353 [NSNumber numberWithBool:NO], WebKitApplicationChromeModeEnabledPreferenceKey,
354 [NSNumber numberWithBool:NO], WebKitWebArchiveDebugModeEnabledPreferenceKey,
355 [NSNumber numberWithBool:NO], WebKitLocalFileContentSniffingEnabledPreferenceKey,
356 [NSNumber numberWithBool:NO], WebKitOfflineWebApplicationCacheEnabledPreferenceKey,
357 [NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey,
358 [NSNumber numberWithBool:NO], WebKitJavaScriptCanAccessClipboardPreferenceKey,
359 [NSNumber numberWithBool:YES], WebKitXSSAuditorEnabledPreferenceKey,
360 [NSNumber numberWithBool:YES], WebKitAcceleratedCompositingEnabledPreferenceKey,
361 [NSNumber numberWithBool:NO], WebKitShowDebugBordersPreferenceKey,
362 [NSNumber numberWithBool:NO], WebKitShowRepaintCounterPreferenceKey,
363 [NSNumber numberWithBool:NO], WebKitWebGLEnabledPreferenceKey,
364 [NSNumber numberWithBool:NO], WebKitUsesProxiedOpenPanelPreferenceKey,
365 [NSNumber numberWithUnsignedInt:4], WebKitPluginAllowedRunTimePreferenceKey,
366 [NSNumber numberWithBool:NO], WebKitFrameFlatteningEnabledPreferenceKey,
367 [NSNumber numberWithBool:YES], WebKitDNSPrefetchingEnabledPreferenceKey,
368 [NSNumber numberWithBool:NO], WebKitMemoryInfoEnabledPreferenceKey,
369 [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
370 [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota,
373 // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
374 ASSERT(kPDFDisplaySinglePageContinuous == 1);
375 [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
384 - (NSString *)identifier
386 return _private->identifier;
389 - (id)_valueForKey:(NSString *)key
391 NSString *_key = KEY(key);
392 id o = [_private->values objectForKey:_key];
395 o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
396 if (!o && key != _key)
397 o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
401 - (NSString *)_stringValueForKey:(NSString *)key
403 id s = [self _valueForKey:key];
404 return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
407 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
409 if ([[self _stringValueForKey:key] isEqualToString:value])
411 NSString *_key = KEY(key);
412 [_private->values setObject:value forKey:_key];
413 if (_private->autosaves)
414 [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
415 [self _postPreferencesChangesNotification];
418 - (int)_integerValueForKey:(NSString *)key
420 id o = [self _valueForKey:key];
421 return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
424 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
426 if ([self _integerValueForKey:key] == value)
428 NSString *_key = KEY(key);
429 [_private->values _webkit_setInt:value forKey:_key];
430 if (_private->autosaves)
431 [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
432 [self _postPreferencesChangesNotification];
435 - (float)_floatValueForKey:(NSString *)key
437 id o = [self _valueForKey:key];
438 return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
441 - (void)_setFloatValue:(float)value forKey:(NSString *)key
443 if ([self _floatValueForKey:key] == value)
445 NSString *_key = KEY(key);
446 [_private->values _webkit_setFloat:value forKey:_key];
447 if (_private->autosaves)
448 [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
449 [self _postPreferencesChangesNotification];
452 - (BOOL)_boolValueForKey:(NSString *)key
454 return [self _integerValueForKey:key] != 0;
457 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
459 if ([self _boolValueForKey:key] == value)
461 NSString *_key = KEY(key);
462 [_private->values _webkit_setBool:value forKey:_key];
463 if (_private->autosaves)
464 [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
465 [self _postPreferencesChangesNotification];
468 - (long long)_longLongValueForKey:(NSString *)key
470 id o = [self _valueForKey:key];
471 return [o respondsToSelector:@selector(longLongValue)] ? [o longLongValue] : 0;
474 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key
476 if ([self _longLongValueForKey:key] == value)
478 NSString *_key = KEY(key);
479 [_private->values _webkit_setLongLong:value forKey:_key];
480 if (_private->autosaves)
481 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key];
482 [self _postPreferencesChangesNotification];
485 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
487 id o = [self _valueForKey:key];
488 return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
491 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
493 if ([self _unsignedLongLongValueForKey:key] == value)
495 NSString *_key = KEY(key);
496 [_private->values _webkit_setUnsignedLongLong:value forKey:_key];
497 if (_private->autosaves)
498 [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
499 [self _postPreferencesChangesNotification];
502 - (NSString *)standardFontFamily
504 return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
507 - (void)setStandardFontFamily:(NSString *)family
509 [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
512 - (NSString *)fixedFontFamily
514 return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
517 - (void)setFixedFontFamily:(NSString *)family
519 [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
522 - (NSString *)serifFontFamily
524 return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
527 - (void)setSerifFontFamily:(NSString *)family
529 [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
532 - (NSString *)sansSerifFontFamily
534 return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
537 - (void)setSansSerifFontFamily:(NSString *)family
539 [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
542 - (NSString *)cursiveFontFamily
544 return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
547 - (void)setCursiveFontFamily:(NSString *)family
549 [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
552 - (NSString *)fantasyFontFamily
554 return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
557 - (void)setFantasyFontFamily:(NSString *)family
559 [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
562 - (int)defaultFontSize
564 return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
567 - (void)setDefaultFontSize:(int)size
569 [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
572 - (int)defaultFixedFontSize
574 return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
577 - (void)setDefaultFixedFontSize:(int)size
579 [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
582 - (int)minimumFontSize
584 return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
587 - (void)setMinimumFontSize:(int)size
589 [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
592 - (int)minimumLogicalFontSize
594 return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
597 - (void)setMinimumLogicalFontSize:(int)size
599 [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
602 - (NSString *)defaultTextEncodingName
604 return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
607 - (void)setDefaultTextEncodingName:(NSString *)encoding
609 [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
612 - (BOOL)userStyleSheetEnabled
614 return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
617 - (void)setUserStyleSheetEnabled:(BOOL)flag
619 [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
622 - (NSURL *)userStyleSheetLocation
624 NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
626 if ([locationString _webkit_looksLikeAbsoluteURL]) {
627 return [NSURL _web_URLWithDataAsString:locationString];
629 locationString = [locationString stringByExpandingTildeInPath];
630 return [NSURL fileURLWithPath:locationString];
634 - (void)setUserStyleSheetLocation:(NSURL *)URL
636 NSString *locationString;
638 if ([URL isFileURL]) {
639 locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
641 locationString = [URL _web_originalDataAsString];
644 [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
647 - (BOOL)shouldPrintBackgrounds
649 return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
652 - (void)setShouldPrintBackgrounds:(BOOL)flag
654 [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
657 - (BOOL)isJavaEnabled
659 return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
662 - (void)setJavaEnabled:(BOOL)flag
664 [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
667 - (BOOL)isJavaScriptEnabled
669 return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
672 - (void)setJavaScriptEnabled:(BOOL)flag
674 [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
677 - (BOOL)javaScriptCanOpenWindowsAutomatically
679 return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
682 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
684 [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
687 - (BOOL)arePlugInsEnabled
689 return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
692 - (void)setPlugInsEnabled:(BOOL)flag
694 [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
697 - (BOOL)allowsAnimatedImages
699 return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
702 - (void)setAllowsAnimatedImages:(BOOL)flag
704 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
707 - (BOOL)allowsAnimatedImageLooping
709 return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
712 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
714 [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
717 - (void)setLoadsImagesAutomatically: (BOOL)flag
719 [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
722 - (BOOL)loadsImagesAutomatically
724 return [self _boolValueForKey: WebKitDisplayImagesKey];
727 - (void)setAutosaves:(BOOL)flag
729 _private->autosaves = flag;
734 return _private->autosaves;
737 - (void)setTabsToLinks:(BOOL)flag
739 [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
744 return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
747 - (void)setPrivateBrowsingEnabled:(BOOL)flag
749 [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
752 - (BOOL)privateBrowsingEnabled
754 return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
757 - (void)setUsesPageCache:(BOOL)usesPageCache
759 [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
762 - (BOOL)usesPageCache
764 return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
767 - (void)setCacheModel:(WebCacheModel)cacheModel
769 [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
770 [self setAutomaticallyDetectsCacheModel:NO];
773 - (WebCacheModel)cacheModel
775 return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
780 @implementation WebPreferences (WebPrivate)
782 - (BOOL)isDNSPrefetchingEnabled
784 return [self _boolValueForKey:WebKitDNSPrefetchingEnabledPreferenceKey];
787 - (void)setDNSPrefetchingEnabled:(BOOL)flag
789 [self _setBoolValue:flag forKey:WebKitDNSPrefetchingEnabledPreferenceKey];
792 - (BOOL)developerExtrasEnabled
794 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
795 if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
798 if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
800 return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
802 return YES; // always enable in debug builds
806 - (void)setDeveloperExtrasEnabled:(BOOL)flag
808 [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
811 - (BOOL)authorAndUserStylesEnabled
813 return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
816 - (void)setAuthorAndUserStylesEnabled:(BOOL)flag
818 [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
821 - (BOOL)applicationChromeModeEnabled
823 return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey];
826 - (void)setApplicationChromeModeEnabled:(BOOL)flag
828 [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey];
831 - (BOOL)webArchiveDebugModeEnabled
833 return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
836 - (void)setWebArchiveDebugModeEnabled:(BOOL)flag
838 [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
841 - (BOOL)localFileContentSniffingEnabled
843 return [self _boolValueForKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
846 - (void)setLocalFileContentSniffingEnabled:(BOOL)flag
848 [self _setBoolValue:flag forKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
851 - (BOOL)offlineWebApplicationCacheEnabled
853 return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
856 - (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
858 [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
861 - (BOOL)zoomsTextOnly
863 return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
866 - (void)setZoomsTextOnly:(BOOL)flag
868 [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
871 - (BOOL)javaScriptCanAccessClipboard
873 return [self _boolValueForKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
876 - (void)setJavaScriptCanAccessClipboard:(BOOL)flag
878 [self _setBoolValue:flag forKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
881 - (BOOL)isXSSAuditorEnabled
883 return [self _boolValueForKey:WebKitXSSAuditorEnabledPreferenceKey];
886 - (void)setXSSAuditorEnabled:(BOOL)flag
888 [self _setBoolValue:flag forKey:WebKitXSSAuditorEnabledPreferenceKey];
891 - (BOOL)respectStandardStyleKeyEquivalents
893 return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
896 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
898 [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
901 - (BOOL)showsURLsInToolTips
903 return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
906 - (void)setShowsURLsInToolTips:(BOOL)flag
908 [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
911 - (BOOL)textAreasAreResizable
913 return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
916 - (void)setTextAreasAreResizable:(BOOL)flag
918 [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
921 - (BOOL)shrinksStandaloneImagesToFit
923 return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
926 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag
928 [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
931 - (BOOL)automaticallyDetectsCacheModel
933 return _private->automaticallyDetectsCacheModel;
936 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
938 _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
941 - (BOOL)usesEncodingDetector
943 return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey];
946 - (void)setUsesEncodingDetector:(BOOL)flag
948 [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey];
951 - (BOOL)isWebSecurityEnabled
953 return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
956 - (void)setWebSecurityEnabled:(BOOL)flag
958 [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
961 - (BOOL)allowUniversalAccessFromFileURLs
963 return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
966 - (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
968 [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
971 - (BOOL)allowFileAccessFromFileURLs
973 return [self _boolValueForKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
976 - (void)setAllowFileAccessFromFileURLs:(BOOL)flag
978 [self _setBoolValue: flag forKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
981 - (NSTimeInterval)_backForwardCacheExpirationInterval
983 // FIXME: There's probably no good reason to read from the standard user defaults instead of self.
984 return (NSTimeInterval)[[NSUserDefaults standardUserDefaults] floatForKey:WebKitBackForwardCacheExpirationIntervalKey];
987 - (float)PDFScaleFactor
989 return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
992 - (void)setPDFScaleFactor:(float)factor
994 [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
997 - (int64_t)applicationCacheTotalQuota
999 return [self _longLongValueForKey:WebKitApplicationCacheTotalQuota];
1002 - (void)setApplicationCacheTotalQuota:(int64_t)quota
1004 [self _setLongLongValue:quota forKey:WebKitApplicationCacheTotalQuota];
1006 // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
1007 [WebApplicationCache setMaximumSize:quota];
1010 - (int64_t)applicationCacheDefaultOriginQuota
1012 return [self _longLongValueForKey:WebKitApplicationCacheDefaultOriginQuota];
1015 - (void)setApplicationCacheDefaultOriginQuota:(int64_t)quota
1017 [self _setLongLongValue:quota forKey:WebKitApplicationCacheDefaultOriginQuota];
1020 - (PDFDisplayMode)PDFDisplayMode
1022 PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
1023 if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
1024 // protect against new modes from future versions of OS X stored in defaults
1025 value = kPDFDisplaySinglePageContinuous;
1030 - (void)setPDFDisplayMode:(PDFDisplayMode)mode
1032 [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
1035 - (WebKitEditableLinkBehavior)editableLinkBehavior
1037 WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
1038 if (value != WebKitEditableLinkDefaultBehavior &&
1039 value != WebKitEditableLinkAlwaysLive &&
1040 value != WebKitEditableLinkNeverLive &&
1041 value != WebKitEditableLinkOnlyLiveWithShiftKey &&
1042 value != WebKitEditableLinkLiveWhenNotFocused) {
1043 // ensure that a valid result is returned
1044 value = WebKitEditableLinkDefaultBehavior;
1050 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
1052 [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
1055 - (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
1057 WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
1058 if (value != WebTextDirectionSubmenuNeverIncluded &&
1059 value != WebTextDirectionSubmenuAutomaticallyIncluded &&
1060 value != WebTextDirectionSubmenuAlwaysIncluded) {
1061 // Ensure that a valid result is returned.
1062 value = WebTextDirectionSubmenuNeverIncluded;
1067 - (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
1069 [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
1072 - (BOOL)_useSiteSpecificSpoofing
1074 return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1077 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
1079 [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1082 - (BOOL)databasesEnabled
1084 return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
1087 - (void)setDatabasesEnabled:(BOOL)databasesEnabled
1089 [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
1092 - (BOOL)localStorageEnabled
1094 return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
1097 - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
1099 [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
1102 - (BOOL)experimentalNotificationsEnabled
1104 return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1107 - (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled
1109 [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1112 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
1114 LOG(Encoding, "requesting for %@\n", ident);
1117 return _standardPreferences;
1119 WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
1124 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
1126 if (!webPreferencesInstances)
1127 webPreferencesInstances = [[NSMutableDictionary alloc] init];
1129 [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1130 LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1134 + (void)_checkLastReferenceForIdentifier:(id)identifier
1136 // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1137 // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1138 WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1139 if ([instance retainCount] == 1)
1140 [webPreferencesInstances removeObjectForKey:identifier];
1143 + (void)_removeReferenceForIdentifier:(NSString *)ident
1146 [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1149 - (void)_postPreferencesChangesNotification
1151 if (!pthread_main_np()) {
1152 [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1156 [[NSNotificationCenter defaultCenter]
1157 postNotificationName:WebPreferencesChangedNotification object:self
1161 + (CFStringEncoding)_systemCFStringEncoding
1163 return WKGetWebDefaultCFStringEncoding();
1166 + (void)_setInitialDefaultTextEncodingToSystemEncoding
1168 NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]);
1170 // CFStringConvertEncodingToIANACharSetName() returns cp949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-949.
1171 // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-949.
1172 // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>.
1173 // On some OS versions, the result is CP949 (uppercase).
1174 if ([systemEncodingName _webkit_isCaseInsensitiveEqualToString:@"cp949"])
1175 systemEncodingName = @"ks_c_5601-1987";
1176 [[NSUserDefaults standardUserDefaults] registerDefaults:
1177 [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1180 static NSString *classIBCreatorID = nil;
1182 + (void)_setIBCreatorID:(NSString *)string
1184 NSString *old = classIBCreatorID;
1185 classIBCreatorID = [string copy];
1189 - (BOOL)isDOMPasteAllowed
1191 return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1194 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1196 [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1199 - (NSString *)_localStorageDatabasePath
1201 return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1204 - (void)_setLocalStorageDatabasePath:(NSString *)path
1206 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1209 - (NSString *)_ftpDirectoryTemplatePath
1211 return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1214 - (void)_setFTPDirectoryTemplatePath:(NSString *)path
1216 [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1219 - (BOOL)_forceFTPDirectoryListings
1221 return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1224 - (void)_setForceFTPDirectoryListings:(BOOL)force
1226 [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1229 - (BOOL)acceleratedCompositingEnabled
1231 return [self _boolValueForKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1234 - (void)setAcceleratedCompositingEnabled:(BOOL)enabled
1236 [self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1239 - (BOOL)showDebugBorders
1241 return [self _boolValueForKey:WebKitShowDebugBordersPreferenceKey];
1244 - (void)setShowDebugBorders:(BOOL)enabled
1246 [self _setBoolValue:enabled forKey:WebKitShowDebugBordersPreferenceKey];
1249 - (BOOL)showRepaintCounter
1251 return [self _boolValueForKey:WebKitShowRepaintCounterPreferenceKey];
1254 - (void)setShowRepaintCounter:(BOOL)enabled
1256 [self _setBoolValue:enabled forKey:WebKitShowRepaintCounterPreferenceKey];
1259 - (BOOL)webGLEnabled
1261 return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey];
1264 - (void)setWebGLEnabled:(BOOL)enabled
1266 [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey];
1269 - (BOOL)usesProxiedOpenPanel
1271 return [self _boolValueForKey:WebKitUsesProxiedOpenPanelPreferenceKey];
1274 - (void)setUsesProxiedOpenPanel:(BOOL)enabled
1276 [self _setBoolValue:enabled forKey:WebKitUsesProxiedOpenPanelPreferenceKey];
1279 - (unsigned)pluginAllowedRunTime
1281 return [self _integerValueForKey:WebKitPluginAllowedRunTimePreferenceKey];
1284 - (void)setPluginAllowedRunTime:(unsigned)allowedRunTime
1286 return [self _setIntegerValue:allowedRunTime forKey:WebKitPluginAllowedRunTimePreferenceKey];
1289 - (BOOL)isFrameFlatteningEnabled
1291 return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey];
1294 - (void)setFrameFlatteningEnabled:(BOOL)flag
1296 [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey];
1299 - (BOOL)paginateDuringLayoutEnabled
1301 return [self _boolValueForKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1304 - (void)setPaginateDuringLayoutEnabled:(BOOL)flag
1306 [self _setBoolValue:flag forKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1309 - (BOOL)memoryInfoEnabled
1311 return [self _boolValueForKey:WebKitMemoryInfoEnabledPreferenceKey];
1314 - (void)setMemoryInfoEnabled:(BOOL)flag
1316 [self _setBoolValue:flag forKey:WebKitMemoryInfoEnabledPreferenceKey];
1319 - (WebKitEditingBehavior)editingBehavior
1321 return static_cast<WebKitEditingBehavior>([self _integerValueForKey:WebKitEditingBehaviorPreferenceKey]);
1324 - (void)setEditingBehavior:(WebKitEditingBehavior)behavior
1326 [self _setIntegerValue:behavior forKey:WebKitEditingBehaviorPreferenceKey];
1329 - (void)didRemoveFromWebView
1331 ASSERT(_private->numWebViews);
1332 if (--_private->numWebViews == 0)
1333 [[NSNotificationCenter defaultCenter]
1334 postNotificationName:WebPreferencesRemovedNotification
1339 - (void)willAddToWebView
1341 ++_private->numWebViews;
1344 - (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key
1346 [self _setStringValue:value forKey:key];
1351 @implementation WebPreferences (WebInternal)
1353 + (NSString *)_IBCreatorID
1355 return classIBCreatorID;
1358 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
1360 NSString *IBCreatorID = [WebPreferences _IBCreatorID];
1363 return [IBCreatorID stringByAppendingString:key];