1/*
2 * Copyright (C) 2005, 2006, 2007, 2011, 2012, 2014 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 "WebApplicationCache.h"
34#import "WebFrameNetworkingContext.h"
35#import "WebKitLogging.h"
36#import "WebKitNSStringExtras.h"
37#import "WebKitSystemBits.h"
38#import "WebKitSystemInterface.h"
39#import "WebKitVersionChecks.h"
40#import "WebNSDictionaryExtras.h"
41#import "WebNSURLExtras.h"
42#import "WebSystemInterface.h"
43#import <WebCore/ApplicationCacheStorage.h>
44#import <WebCore/NetworkStorageSession.h>
45#import <WebCore/ResourceHandle.h>
46#import <WebCore/RunLoop.h>
47#import <runtime/InitializeThreading.h>
48#import <wtf/MainThread.h>
49#import <wtf/RetainPtr.h>
50
51using namespace WebCore;
52
53NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
54NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";
55NSString *WebPreferencesChangedInternalNotification = @"WebPreferencesChangedInternalNotification";
56NSString *WebPreferencesCacheModelChangedInternalNotification = @"WebPreferencesCacheModelChangedInternalNotification";
57
58#define KEY(x) (_private->identifier ? [_private->identifier.get() stringByAppendingString:(x)] : (x))
59
60enum { WebPreferencesVersion = 1 };
61
62static WebPreferences *_standardPreferences;
63static NSMutableDictionary *webPreferencesInstances;
64
65static bool contains(const char* const array[], int count, const char* item)
66{
67    if (!item)
68        return false;
69
70    for (int i = 0; i < count; i++)
71        if (!strcasecmp(array[i], item))
72            return true;
73    return false;
74}
75
76static WebCacheModel cacheModelForMainBundle(void)
77{
78    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
79
80    // Apps that probably need the small setting
81    static const char* const documentViewerIDs[] = {
82        "Microsoft/com.microsoft.Messenger",
83        "com.adiumX.adiumX",
84        "com.alientechnology.Proteus",
85        "com.apple.Dashcode",
86        "com.apple.iChat",
87        "com.barebones.bbedit",
88        "com.barebones.textwrangler",
89        "com.barebones.yojimbo",
90        "com.equinux.iSale4",
91        "com.growl.growlframework",
92        "com.intrarts.PandoraMan",
93        "com.karelia.Sandvox",
94        "com.macromates.textmate",
95        "com.realmacsoftware.rapidweaverpro",
96        "com.red-sweater.marsedit",
97        "com.yahoo.messenger3",
98        "de.codingmonkeys.SubEthaEdit",
99        "fi.karppinen.Pyro",
100        "info.colloquy",
101        "kungfoo.tv.ecto",
102    };
103
104    // Apps that probably need the medium setting
105    static const char* const documentBrowserIDs[] = {
106        "com.apple.Dictionary",
107        "com.apple.Xcode",
108        "com.apple.dashboard.client",
109        "com.apple.helpviewer",
110        "com.culturedcode.xyle",
111        "com.macrabbit.CSSEdit",
112        "com.panic.Coda",
113        "com.ranchero.NetNewsWire",
114        "com.thinkmac.NewsLife",
115        "org.xlife.NewsFire",
116        "uk.co.opencommunity.vienna2",
117    };
118
119    // Apps that probably need the large setting
120    static const char* const primaryWebBrowserIDs[] = {
121        "com.app4mac.KidsBrowser"
122        "com.app4mac.wKiosk",
123        "com.freeverse.bumpercar",
124        "com.omnigroup.OmniWeb5",
125        "com.sunrisebrowser.Sunrise",
126        "net.hmdt-web.Shiira",
127    };
128
129    WebCacheModel cacheModel;
130
131    const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
132    if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID))
133        cacheModel = WebCacheModelDocumentViewer;
134    else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID))
135        cacheModel = WebCacheModelDocumentBrowser;
136    else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID))
137        cacheModel = WebCacheModelPrimaryWebBrowser;
138    else {
139        bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API);
140        if (isLegacyApp)
141            cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache.
142        else
143            cacheModel = WebCacheModelDocumentViewer; // To save memory.
144    }
145
146    [pool drain];
147
148    return cacheModel;
149}
150
151@interface WebPreferences ()
152- (void)_postCacheModelChangedNotification;
153@end
154
155@interface WebPreferences (WebInternal)
156+ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
157+ (NSString *)_IBCreatorID;
158@end
159
160struct WebPreferencesPrivate
161{
162public:
163    WebPreferencesPrivate()
164    : autosaves(NO)
165    , automaticallyDetectsCacheModel(NO)
166    , numWebViews(0)
167    {
168    }
169
170    RetainPtr<NSMutableDictionary> values;
171    RetainPtr<NSString> identifier;
172    BOOL autosaves;
173    BOOL automaticallyDetectsCacheModel;
174    unsigned numWebViews;
175};
176
177@interface WebPreferences (WebForwardDeclarations)
178// This pseudo-category is needed so these methods can be used from within other category implementations
179// without being in the public header file.
180- (BOOL)_boolValueForKey:(NSString *)key;
181- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
182- (int)_integerValueForKey:(NSString *)key;
183- (void)_setIntegerValue:(int)value forKey:(NSString *)key;
184- (float)_floatValueForKey:(NSString *)key;
185- (void)_setFloatValue:(float)value forKey:(NSString *)key;
186- (void)_setLongLongValue:(long long)value forKey:(NSString *)key;
187- (long long)_longLongValueForKey:(NSString *)key;
188- (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key;
189- (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key;
190@end
191
192@implementation WebPreferences
193
194- (id)init
195{
196    // Create fake identifier
197    static int instanceCount = 1;
198    NSString *fakeIdentifier;
199
200    // At least ensure that identifier hasn't been already used.
201    fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
202    while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
203        fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
204    }
205
206    return [self initWithIdentifier:fakeIdentifier];
207}
208
209- (id)initWithIdentifier:(NSString *)anIdentifier
210{
211    WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
212    if (instance) {
213        [self release];
214        return [instance retain];
215    }
216
217    self = [super init];
218    if (!self)
219        return nil;
220
221    _private = new WebPreferencesPrivate;
222    _private->values = adoptNS([[NSMutableDictionary alloc] init]);
223    _private->identifier = adoptNS([anIdentifier copy]);
224    _private->automaticallyDetectsCacheModel = YES;
225
226    [[self class] _setInstance:self forIdentifier:_private->identifier.get()];
227
228    [self _postPreferencesChangedNotification];
229    [self _postCacheModelChangedNotification];
230
231    return self;
232}
233
234- (id)initWithCoder:(NSCoder *)decoder
235{
236    self = [super init];
237    if (!self)
238        return nil;
239
240    _private = new WebPreferencesPrivate;
241    _private->automaticallyDetectsCacheModel = YES;
242
243    @try {
244        id identifier = nil;
245        id values = nil;
246        if ([decoder allowsKeyedCoding]) {
247            identifier = [decoder decodeObjectForKey:@"Identifier"];
248            values = [decoder decodeObjectForKey:@"Values"];
249        } else {
250            int version;
251            [decoder decodeValueOfObjCType:@encode(int) at:&version];
252            if (version == 1) {
253                identifier = [decoder decodeObject];
254                values = [decoder decodeObject];
255            }
256        }
257
258        if ([identifier isKindOfClass:[NSString class]])
259            _private->identifier = adoptNS([identifier copy]);
260        if ([values isKindOfClass:[NSDictionary class]])
261            _private->values = adoptNS([values mutableCopy]); // ensure dictionary is mutable
262
263        LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier.get(), _private->values.get());
264    } @catch(id) {
265        [self release];
266        return nil;
267    }
268
269    // If we load a nib multiple times, or have instances in multiple
270    // nibs with the same name, the first guy up wins.
271    WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier.get()];
272    if (instance) {
273        [self release];
274        self = [instance retain];
275    } else {
276        [[self class] _setInstance:self forIdentifier:_private->identifier.get()];
277    }
278
279    return self;
280}
281
282- (void)encodeWithCoder:(NSCoder *)encoder
283{
284    if ([encoder allowsKeyedCoding]){
285        [encoder encodeObject:_private->identifier.get() forKey:@"Identifier"];
286        [encoder encodeObject:_private->values.get() forKey:@"Values"];
287        LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier.get(), _private->values.get());
288    }
289    else {
290        int version = WebPreferencesVersion;
291        [encoder encodeValueOfObjCType:@encode(int) at:&version];
292        [encoder encodeObject:_private->identifier.get()];
293        [encoder encodeObject:_private->values.get()];
294    }
295}
296
297+ (WebPreferences *)standardPreferences
298{
299    if (_standardPreferences == nil) {
300        _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
301        [_standardPreferences setAutosaves:YES];
302    }
303
304    return _standardPreferences;
305}
306
307// if we ever have more than one WebPreferences object, this would move to init
308+ (void)initialize
309{
310    JSC::initializeThreading();
311    WTF::initializeMainThreadToProcessMainThread();
312    WebCore::RunLoop::initializeMainRunLoop();
313
314    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
315        @"Times",                       WebKitStandardFontPreferenceKey,
316        @"Courier",                     WebKitFixedFontPreferenceKey,
317        @"Times",                       WebKitSerifFontPreferenceKey,
318        @"Helvetica",                   WebKitSansSerifFontPreferenceKey,
319        @"Apple Chancery",              WebKitCursiveFontPreferenceKey,
320        @"Papyrus",                     WebKitFantasyFontPreferenceKey,
321        @"Apple Color Emoji",           WebKitPictographFontPreferenceKey,
322        @"0",                           WebKitMinimumFontSizePreferenceKey,
323        @"9",                           WebKitMinimumLogicalFontSizePreferenceKey,
324        @"16",                          WebKitDefaultFontSizePreferenceKey,
325        @"13",                          WebKitDefaultFixedFontSizePreferenceKey,
326        @"ISO-8859-1",                  WebKitDefaultTextEncodingNamePreferenceKey,
327        [NSNumber numberWithBool:NO],   WebKitUsesEncodingDetectorPreferenceKey,
328        [NSNumber numberWithBool:NO],   WebKitUserStyleSheetEnabledPreferenceKey,
329        @"",                            WebKitUserStyleSheetLocationPreferenceKey,
330        [NSNumber numberWithBool:NO],   WebKitShouldPrintBackgroundsPreferenceKey,
331        [NSNumber numberWithBool:NO],   WebKitTextAreasAreResizablePreferenceKey,
332        [NSNumber numberWithBool:NO],   WebKitShrinksStandaloneImagesToFitPreferenceKey,
333        [NSNumber numberWithBool:YES],  WebKitJavaEnabledPreferenceKey,
334        [NSNumber numberWithBool:YES],  WebKitJavaScriptEnabledPreferenceKey,
335        [NSNumber numberWithBool:YES],  WebKitWebSecurityEnabledPreferenceKey,
336        [NSNumber numberWithBool:YES],  WebKitAllowUniversalAccessFromFileURLsPreferenceKey,
337        [NSNumber numberWithBool:YES],  WebKitAllowFileAccessFromFileURLsPreferenceKey,
338        [NSNumber numberWithBool:YES],  WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
339        [NSNumber numberWithBool:YES],  WebKitPluginsEnabledPreferenceKey,
340        [NSNumber numberWithBool:YES],  WebKitDatabasesEnabledPreferenceKey,
341        [NSNumber numberWithBool:YES],  WebKitLocalStorageEnabledPreferenceKey,
342        [NSNumber numberWithBool:NO],   WebKitExperimentalNotificationsEnabledPreferenceKey,
343        [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImagesPreferenceKey,
344        [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImageLoopingPreferenceKey,
345        [NSNumber numberWithBool:YES],  WebKitDisplayImagesKey,
346        [NSNumber numberWithBool:NO],   WebKitLoadSiteIconsKey,
347        @"1800",                        WebKitBackForwardCacheExpirationIntervalKey,
348        [NSNumber numberWithBool:NO],   WebKitTabToLinksPreferenceKey,
349        [NSNumber numberWithBool:NO],   WebKitPrivateBrowsingEnabledPreferenceKey,
350        [NSNumber numberWithBool:NO],   WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
351        [NSNumber numberWithBool:NO],   WebKitShowsURLsInToolTipsPreferenceKey,
352        [NSNumber numberWithBool:NO],   WebKitShowsToolTipOverTruncatedTextPreferenceKey,
353        @"1",                           WebKitPDFDisplayModePreferenceKey,
354        @"0",                           WebKitPDFScaleFactorPreferenceKey,
355        @"0",                           WebKitUseSiteSpecificSpoofingPreferenceKey,
356        [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
357        [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],
358                                        WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey,
359        [NSNumber numberWithBool:NO],   WebKitDOMPasteAllowedPreferenceKey,
360        [NSNumber numberWithBool:YES],  WebKitUsesPageCachePreferenceKey,
361        [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
362        [NSNumber numberWithBool:YES],  WebKitPageCacheSupportsPluginsPreferenceKey,
363        [NSNumber numberWithBool:NO],   WebKitDeveloperExtrasEnabledPreferenceKey,
364        [NSNumber numberWithBool:NO],   WebKitJavaScriptExperimentsEnabledPreferenceKey,
365        [NSNumber numberWithBool:YES],  WebKitAuthorAndUserStylesEnabledPreferenceKey,
366        [NSNumber numberWithBool:NO],   WebKitApplicationChromeModeEnabledPreferenceKey,
367        [NSNumber numberWithBool:NO],   WebKitWebArchiveDebugModeEnabledPreferenceKey,
368        [NSNumber numberWithBool:NO],   WebKitLocalFileContentSniffingEnabledPreferenceKey,
369        [NSNumber numberWithBool:NO],   WebKitOfflineWebApplicationCacheEnabledPreferenceKey,
370        [NSNumber numberWithBool:YES],  WebKitZoomsTextOnlyPreferenceKey,
371        [NSNumber numberWithBool:NO],   WebKitJavaScriptCanAccessClipboardPreferenceKey,
372        [NSNumber numberWithBool:YES],  WebKitXSSAuditorEnabledPreferenceKey,
373        [NSNumber numberWithBool:YES],  WebKitAcceleratedCompositingEnabledPreferenceKey,
374        // CSS Shaders also need WebGL enabled (which is disabled by default), so we can keep it enabled for now.
375        [NSNumber numberWithBool:YES], WebKitCSSCustomFilterEnabledPreferenceKey,
376        [NSNumber numberWithBool:YES], WebKitCSSRegionsEnabledPreferenceKey,
377        [NSNumber numberWithBool:YES], WebKitCSSCompositingEnabledPreferenceKey,
378        [NSNumber numberWithBool:NO],  WebKitCSSGridLayoutEnabledPreferenceKey,
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 numberWithBool:NO],   WebKitFrameFlatteningEnabledPreferenceKey,
386        [NSNumber numberWithBool:NO],   WebKitSpatialNavigationEnabledPreferenceKey,
387        [NSNumber numberWithBool:NO],  WebKitDNSPrefetchingEnabledPreferenceKey,
388        [NSNumber numberWithBool:NO],   WebKitFullScreenEnabledPreferenceKey,
389        [NSNumber numberWithBool:NO],   WebKitAsynchronousSpellCheckingEnabledPreferenceKey,
390        [NSNumber numberWithBool:YES],  WebKitHyperlinkAuditingEnabledPreferenceKey,
391        [NSNumber numberWithBool:NO],   WebKitUsePreHTML5ParserQuirksKey,
392        [NSNumber numberWithBool:YES],  WebKitAVFoundationEnabledKey,
393        [NSNumber numberWithBool:NO],   WebKitMediaPlaybackRequiresUserGesturePreferenceKey,
394        [NSNumber numberWithBool:YES],  WebKitMediaPlaybackAllowsInlinePreferenceKey,
395        [NSNumber numberWithBool:NO],   WebKitWebAudioEnabledPreferenceKey,
396        [NSNumber numberWithBool:NO],   WebKitSuppressesIncrementalRenderingKey,
397        [NSNumber numberWithBool:NO],   WebKitRegionBasedColumnsEnabledKey,
398        [NSNumber numberWithBool:YES],  WebKitBackspaceKeyNavigationEnabledKey,
399        [NSNumber numberWithBool:NO],   WebKitShouldDisplaySubtitlesPreferenceKey,
400        [NSNumber numberWithBool:NO],   WebKitShouldDisplayCaptionsPreferenceKey,
401        [NSNumber numberWithBool:NO],   WebKitShouldDisplayTextDescriptionsPreferenceKey,
402        [NSNumber numberWithBool:YES],  WebKitNotificationsEnabledKey,
403        [NSNumber numberWithBool:NO],   WebKitShouldRespectImageOrientationKey,
404        [NSNumber numberWithBool:YES],  WebKitRequestAnimationFrameEnabledPreferenceKey,
405        [NSNumber numberWithBool:NO],   WebKitWantsBalancedSetDefersLoadingBehaviorKey,
406        [NSNumber numberWithBool:NO],   WebKitDiagnosticLoggingEnabledKey,
407#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
408        [NSNumber numberWithBool:NO],
409#else
410        [NSNumber numberWithBool:YES],
411#endif
412                                        WebKitScreenFontSubstitutionEnabledKey,
413        [NSNumber numberWithInt:WebAllowAllStorage], WebKitStorageBlockingPolicyKey,
414        [NSNumber numberWithBool:NO],   WebKitPlugInSnapshottingEnabledPreferenceKey,
415
416        [NSNumber numberWithLongLong:ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
417        [NSNumber numberWithLongLong:ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota,
418        [NSNumber numberWithBool:YES],  WebKitQTKitEnabledPreferenceKey,
419        [NSNumber numberWithBool:NO], WebKitHiddenPageDOMTimerThrottlingEnabledPreferenceKey,
420        [NSNumber numberWithBool:NO], WebKitHiddenPageCSSAnimationSuspensionEnabledPreferenceKey,
421        [NSNumber numberWithBool:NO], WebKitLowPowerVideoAudioBufferSizeEnabledPreferenceKey,
422
423        [NSNumber numberWithBool:NO], WebKitUseLegacyTextAlignPositionedElementBehaviorPreferenceKey,
424        [NSNumber numberWithBool:NO], WebKitEnableInheritURIQueryComponentPreferenceKey,
425        nil];
426
427
428    // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
429    ASSERT(kPDFDisplaySinglePageContinuous == 1);
430    [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
431}
432
433- (void)dealloc
434{
435    delete _private;
436    [super dealloc];
437}
438
439- (NSString *)identifier
440{
441    return _private->identifier.get();
442}
443
444- (id)_valueForKey:(NSString *)key
445{
446    NSString *_key = KEY(key);
447    id o = [_private->values.get() objectForKey:_key];
448    if (o)
449        return o;
450    o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
451    if (!o && key != _key)
452        o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
453    return o;
454}
455
456- (NSString *)_stringValueForKey:(NSString *)key
457{
458    id s = [self _valueForKey:key];
459    return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
460}
461
462- (void)_setStringValue:(NSString *)value forKey:(NSString *)key
463{
464    if ([[self _stringValueForKey:key] isEqualToString:value])
465        return;
466    NSString *_key = KEY(key);
467    [_private->values.get() setObject:value forKey:_key];
468    if (_private->autosaves)
469        [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
470    [self _postPreferencesChangedNotification];
471}
472
473- (int)_integerValueForKey:(NSString *)key
474{
475    id o = [self _valueForKey:key];
476    return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
477}
478
479- (void)_setIntegerValue:(int)value forKey:(NSString *)key
480{
481    if ([self _integerValueForKey:key] == value)
482        return;
483    NSString *_key = KEY(key);
484    [_private->values.get() _webkit_setInt:value forKey:_key];
485    if (_private->autosaves)
486        [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
487    [self _postPreferencesChangedNotification];
488}
489
490- (float)_floatValueForKey:(NSString *)key
491{
492    id o = [self _valueForKey:key];
493    return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
494}
495
496- (void)_setFloatValue:(float)value forKey:(NSString *)key
497{
498    if ([self _floatValueForKey:key] == value)
499        return;
500    NSString *_key = KEY(key);
501    [_private->values.get() _webkit_setFloat:value forKey:_key];
502    if (_private->autosaves)
503        [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
504    [self _postPreferencesChangedNotification];
505}
506
507- (BOOL)_boolValueForKey:(NSString *)key
508{
509    return [self _integerValueForKey:key] != 0;
510}
511
512- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
513{
514    if ([self _boolValueForKey:key] == value)
515        return;
516    NSString *_key = KEY(key);
517    [_private->values.get() _webkit_setBool:value forKey:_key];
518    if (_private->autosaves)
519        [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
520    [self _postPreferencesChangedNotification];
521}
522
523- (long long)_longLongValueForKey:(NSString *)key
524{
525    id o = [self _valueForKey:key];
526    return [o respondsToSelector:@selector(longLongValue)] ? [o longLongValue] : 0;
527}
528
529- (void)_setLongLongValue:(long long)value forKey:(NSString *)key
530{
531    if ([self _longLongValueForKey:key] == value)
532        return;
533    NSString *_key = KEY(key);
534    [_private->values.get() _webkit_setLongLong:value forKey:_key];
535    if (_private->autosaves)
536        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key];
537    [self _postPreferencesChangedNotification];
538}
539
540- (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
541{
542    id o = [self _valueForKey:key];
543    return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
544}
545
546- (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
547{
548    if ([self _unsignedLongLongValueForKey:key] == value)
549        return;
550    NSString *_key = KEY(key);
551    [_private->values.get() _webkit_setUnsignedLongLong:value forKey:_key];
552    if (_private->autosaves)
553        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
554    [self _postPreferencesChangedNotification];
555}
556
557- (NSString *)standardFontFamily
558{
559    return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
560}
561
562- (void)setStandardFontFamily:(NSString *)family
563{
564    [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
565}
566
567- (NSString *)fixedFontFamily
568{
569    return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
570}
571
572- (void)setFixedFontFamily:(NSString *)family
573{
574    [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
575}
576
577- (NSString *)serifFontFamily
578{
579    return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
580}
581
582- (void)setSerifFontFamily:(NSString *)family
583{
584    [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
585}
586
587- (NSString *)sansSerifFontFamily
588{
589    return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
590}
591
592- (void)setSansSerifFontFamily:(NSString *)family
593{
594    [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
595}
596
597- (NSString *)cursiveFontFamily
598{
599    return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
600}
601
602- (void)setCursiveFontFamily:(NSString *)family
603{
604    [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
605}
606
607- (NSString *)fantasyFontFamily
608{
609    return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
610}
611
612- (void)setFantasyFontFamily:(NSString *)family
613{
614    [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
615}
616
617- (int)defaultFontSize
618{
619    return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
620}
621
622- (void)setDefaultFontSize:(int)size
623{
624    [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
625}
626
627- (int)defaultFixedFontSize
628{
629    return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
630}
631
632- (void)setDefaultFixedFontSize:(int)size
633{
634    [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
635}
636
637- (int)minimumFontSize
638{
639    return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
640}
641
642- (void)setMinimumFontSize:(int)size
643{
644    [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
645}
646
647- (int)minimumLogicalFontSize
648{
649  return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
650}
651
652- (void)setMinimumLogicalFontSize:(int)size
653{
654  [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
655}
656
657- (NSString *)defaultTextEncodingName
658{
659    return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
660}
661
662- (void)setDefaultTextEncodingName:(NSString *)encoding
663{
664    [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
665}
666
667- (BOOL)userStyleSheetEnabled
668{
669    return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
670}
671
672- (void)setUserStyleSheetEnabled:(BOOL)flag
673{
674    [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
675}
676
677- (NSURL *)userStyleSheetLocation
678{
679    NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
680
681    if ([locationString _webkit_looksLikeAbsoluteURL]) {
682        return [NSURL _web_URLWithDataAsString:locationString];
683    } else {
684        locationString = [locationString stringByExpandingTildeInPath];
685        return [NSURL fileURLWithPath:locationString];
686    }
687}
688
689- (void)setUserStyleSheetLocation:(NSURL *)URL
690{
691    NSString *locationString;
692
693    if ([URL isFileURL]) {
694        locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
695    } else {
696        locationString = [URL _web_originalDataAsString];
697    }
698
699    if (!locationString)
700        locationString = @"";
701
702    [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
703}
704
705- (BOOL)shouldPrintBackgrounds
706{
707    return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
708}
709
710- (void)setShouldPrintBackgrounds:(BOOL)flag
711{
712    [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
713}
714
715- (BOOL)isJavaEnabled
716{
717    return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
718}
719
720- (void)setJavaEnabled:(BOOL)flag
721{
722    [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
723}
724
725- (BOOL)isJavaScriptEnabled
726{
727    return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
728}
729
730- (void)setJavaScriptEnabled:(BOOL)flag
731{
732    [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
733}
734
735- (BOOL)javaScriptCanOpenWindowsAutomatically
736{
737    return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
738}
739
740- (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
741{
742    [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
743}
744
745- (BOOL)arePlugInsEnabled
746{
747    return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
748}
749
750- (void)setPlugInsEnabled:(BOOL)flag
751{
752    [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
753}
754
755- (BOOL)allowsAnimatedImages
756{
757    return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
758}
759
760- (void)setAllowsAnimatedImages:(BOOL)flag
761{
762    [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
763}
764
765- (BOOL)allowsAnimatedImageLooping
766{
767    return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
768}
769
770- (void)setAllowsAnimatedImageLooping: (BOOL)flag
771{
772    [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
773}
774
775- (void)setLoadsImagesAutomatically: (BOOL)flag
776{
777    [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
778}
779
780- (BOOL)loadsImagesAutomatically
781{
782    return [self _boolValueForKey: WebKitDisplayImagesKey];
783}
784
785- (void)setAutosaves:(BOOL)flag
786{
787    _private->autosaves = flag;
788}
789
790- (BOOL)autosaves
791{
792    return _private->autosaves;
793}
794
795- (void)setTabsToLinks:(BOOL)flag
796{
797    [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
798}
799
800- (BOOL)tabsToLinks
801{
802    return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
803}
804
805- (void)setPrivateBrowsingEnabled:(BOOL)flag
806{
807    [self _setBoolValue:flag forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
808}
809
810- (BOOL)privateBrowsingEnabled
811{
812    return [self _boolValueForKey:WebKitPrivateBrowsingEnabledPreferenceKey];
813}
814
815- (void)setUsesPageCache:(BOOL)usesPageCache
816{
817    [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
818}
819
820- (BOOL)usesPageCache
821{
822    return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
823}
824
825- (void)_postCacheModelChangedNotification
826{
827    if (!pthread_main_np()) {
828        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
829        return;
830    }
831
832    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesCacheModelChangedInternalNotification object:self userInfo:nil];
833}
834
835- (void)setCacheModel:(WebCacheModel)cacheModel
836{
837    [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
838    [self setAutomaticallyDetectsCacheModel:NO];
839    [self _postCacheModelChangedNotification];
840}
841
842- (WebCacheModel)cacheModel
843{
844    return [self _integerValueForKey:WebKitCacheModelPreferenceKey];
845}
846
847
848- (void)setSuppressesIncrementalRendering:(BOOL)suppressesIncrementalRendering
849{
850    [self _setBoolValue:suppressesIncrementalRendering forKey:WebKitSuppressesIncrementalRenderingKey];
851}
852
853- (BOOL)suppressesIncrementalRendering
854{
855    return [self _boolValueForKey:WebKitSuppressesIncrementalRenderingKey];
856}
857
858@end
859
860@implementation WebPreferences (WebPrivate)
861
862- (BOOL)isDNSPrefetchingEnabled
863{
864    return [self _boolValueForKey:WebKitDNSPrefetchingEnabledPreferenceKey];
865}
866
867- (void)setDNSPrefetchingEnabled:(BOOL)flag
868{
869    [self _setBoolValue:flag forKey:WebKitDNSPrefetchingEnabledPreferenceKey];
870}
871
872- (BOOL)developerExtrasEnabled
873{
874    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
875    if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
876        return NO;
877#ifdef NDEBUG
878    if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
879        return YES;
880    return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
881#else
882    return YES; // always enable in debug builds
883#endif
884}
885
886- (void)setJavaScriptExperimentsEnabled:(BOOL)flag
887{
888    [self _setBoolValue:flag forKey:WebKitJavaScriptExperimentsEnabledPreferenceKey];
889}
890
891- (BOOL)javaScriptExperimentsEnabled
892{
893    return [self _boolValueForKey:WebKitJavaScriptExperimentsEnabledPreferenceKey];
894}
895
896- (void)setDeveloperExtrasEnabled:(BOOL)flag
897{
898    [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
899}
900
901- (BOOL)authorAndUserStylesEnabled
902{
903    return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
904}
905
906- (void)setAuthorAndUserStylesEnabled:(BOOL)flag
907{
908    [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
909}
910
911- (BOOL)applicationChromeModeEnabled
912{
913    return [self _boolValueForKey:WebKitApplicationChromeModeEnabledPreferenceKey];
914}
915
916- (void)setApplicationChromeModeEnabled:(BOOL)flag
917{
918    [self _setBoolValue:flag forKey:WebKitApplicationChromeModeEnabledPreferenceKey];
919}
920
921- (BOOL)webArchiveDebugModeEnabled
922{
923    return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
924}
925
926- (void)setWebArchiveDebugModeEnabled:(BOOL)flag
927{
928    [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
929}
930
931- (BOOL)localFileContentSniffingEnabled
932{
933    return [self _boolValueForKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
934}
935
936- (void)setLocalFileContentSniffingEnabled:(BOOL)flag
937{
938    [self _setBoolValue:flag forKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
939}
940
941- (BOOL)offlineWebApplicationCacheEnabled
942{
943    return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
944}
945
946- (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
947{
948    [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
949}
950
951- (BOOL)zoomsTextOnly
952{
953    return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
954}
955
956- (void)setZoomsTextOnly:(BOOL)flag
957{
958    [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
959}
960
961- (BOOL)javaScriptCanAccessClipboard
962{
963    return [self _boolValueForKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
964}
965
966- (void)setJavaScriptCanAccessClipboard:(BOOL)flag
967{
968    [self _setBoolValue:flag forKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
969}
970
971- (BOOL)isXSSAuditorEnabled
972{
973    return [self _boolValueForKey:WebKitXSSAuditorEnabledPreferenceKey];
974}
975
976- (void)setXSSAuditorEnabled:(BOOL)flag
977{
978    [self _setBoolValue:flag forKey:WebKitXSSAuditorEnabledPreferenceKey];
979}
980
981- (BOOL)respectStandardStyleKeyEquivalents
982{
983    return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
984}
985
986- (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
987{
988    [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
989}
990
991- (BOOL)showsURLsInToolTips
992{
993    return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
994}
995
996- (void)setShowsURLsInToolTips:(BOOL)flag
997{
998    [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
999}
1000
1001- (BOOL)showsToolTipOverTruncatedText
1002{
1003    return [self _boolValueForKey:WebKitShowsToolTipOverTruncatedTextPreferenceKey];
1004}
1005
1006- (void)setShowsToolTipOverTruncatedText:(BOOL)flag
1007{
1008    [self _setBoolValue:flag forKey:WebKitShowsToolTipOverTruncatedTextPreferenceKey];
1009}
1010
1011- (BOOL)textAreasAreResizable
1012{
1013    return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
1014}
1015
1016- (void)setTextAreasAreResizable:(BOOL)flag
1017{
1018    [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
1019}
1020
1021- (BOOL)shrinksStandaloneImagesToFit
1022{
1023    return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
1024}
1025
1026- (void)setShrinksStandaloneImagesToFit:(BOOL)flag
1027{
1028    [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
1029}
1030
1031- (BOOL)automaticallyDetectsCacheModel
1032{
1033    return _private->automaticallyDetectsCacheModel;
1034}
1035
1036- (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
1037{
1038    _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
1039}
1040
1041- (BOOL)usesEncodingDetector
1042{
1043    return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey];
1044}
1045
1046- (void)setUsesEncodingDetector:(BOOL)flag
1047{
1048    [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey];
1049}
1050
1051- (BOOL)isWebSecurityEnabled
1052{
1053    return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
1054}
1055
1056- (void)setWebSecurityEnabled:(BOOL)flag
1057{
1058    [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
1059}
1060
1061- (BOOL)allowUniversalAccessFromFileURLs
1062{
1063    return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
1064}
1065
1066- (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
1067{
1068    [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
1069}
1070
1071- (BOOL)allowFileAccessFromFileURLs
1072{
1073    return [self _boolValueForKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
1074}
1075
1076- (void)setAllowFileAccessFromFileURLs:(BOOL)flag
1077{
1078    [self _setBoolValue: flag forKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
1079}
1080
1081- (NSTimeInterval)_backForwardCacheExpirationInterval
1082{
1083    return (NSTimeInterval)[self _floatValueForKey:WebKitBackForwardCacheExpirationIntervalKey];
1084}
1085
1086- (float)PDFScaleFactor
1087{
1088    return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
1089}
1090
1091- (void)setPDFScaleFactor:(float)factor
1092{
1093    [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
1094}
1095
1096- (int64_t)applicationCacheTotalQuota
1097{
1098    return [self _longLongValueForKey:WebKitApplicationCacheTotalQuota];
1099}
1100
1101- (void)setApplicationCacheTotalQuota:(int64_t)quota
1102{
1103    [self _setLongLongValue:quota forKey:WebKitApplicationCacheTotalQuota];
1104
1105    // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
1106    [WebApplicationCache setMaximumSize:quota];
1107}
1108
1109- (int64_t)applicationCacheDefaultOriginQuota
1110{
1111    return [self _longLongValueForKey:WebKitApplicationCacheDefaultOriginQuota];
1112}
1113
1114- (void)setApplicationCacheDefaultOriginQuota:(int64_t)quota
1115{
1116    [self _setLongLongValue:quota forKey:WebKitApplicationCacheDefaultOriginQuota];
1117}
1118
1119- (PDFDisplayMode)PDFDisplayMode
1120{
1121    PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
1122    if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
1123        // protect against new modes from future versions of OS X stored in defaults
1124        value = kPDFDisplaySinglePageContinuous;
1125    }
1126    return value;
1127}
1128
1129- (void)setPDFDisplayMode:(PDFDisplayMode)mode
1130{
1131    [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
1132}
1133
1134- (WebKitEditableLinkBehavior)editableLinkBehavior
1135{
1136    WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
1137    if (value != WebKitEditableLinkDefaultBehavior &&
1138        value != WebKitEditableLinkAlwaysLive &&
1139        value != WebKitEditableLinkNeverLive &&
1140        value != WebKitEditableLinkOnlyLiveWithShiftKey &&
1141        value != WebKitEditableLinkLiveWhenNotFocused) {
1142        // ensure that a valid result is returned
1143        value = WebKitEditableLinkDefaultBehavior;
1144    }
1145
1146    return value;
1147}
1148
1149- (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
1150{
1151    [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
1152}
1153
1154- (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
1155{
1156    WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
1157    if (value != WebTextDirectionSubmenuNeverIncluded &&
1158        value != WebTextDirectionSubmenuAutomaticallyIncluded &&
1159        value != WebTextDirectionSubmenuAlwaysIncluded) {
1160        // Ensure that a valid result is returned.
1161        value = WebTextDirectionSubmenuNeverIncluded;
1162    }
1163    return value;
1164}
1165
1166- (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
1167{
1168    [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
1169}
1170
1171- (BOOL)_useSiteSpecificSpoofing
1172{
1173    return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1174}
1175
1176- (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
1177{
1178    [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1179}
1180
1181- (BOOL)databasesEnabled
1182{
1183    return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
1184}
1185
1186- (void)setDatabasesEnabled:(BOOL)databasesEnabled
1187{
1188    [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
1189}
1190
1191- (BOOL)localStorageEnabled
1192{
1193    return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
1194}
1195
1196- (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
1197{
1198    [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
1199}
1200
1201- (BOOL)experimentalNotificationsEnabled
1202{
1203    return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1204}
1205
1206- (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled
1207{
1208    [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1209}
1210
1211+ (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
1212{
1213    LOG(Encoding, "requesting for %@\n", ident);
1214
1215    if (!ident)
1216        return _standardPreferences;
1217
1218    WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
1219
1220    return instance;
1221}
1222
1223+ (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
1224{
1225    if (!webPreferencesInstances)
1226        webPreferencesInstances = [[NSMutableDictionary alloc] init];
1227    if (ident) {
1228        [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1229        LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1230    }
1231}
1232
1233+ (void)_checkLastReferenceForIdentifier:(id)identifier
1234{
1235    // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1236    // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1237    WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1238    if ([instance retainCount] == 1)
1239        [webPreferencesInstances removeObjectForKey:identifier];
1240}
1241
1242+ (void)_removeReferenceForIdentifier:(NSString *)ident
1243{
1244    if (ident)
1245        [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1246}
1247
1248- (void)_postPreferencesChangedNotification
1249{
1250    if (!pthread_main_np()) {
1251        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1252        return;
1253    }
1254
1255    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedInternalNotification object:self userInfo:nil];
1256    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
1257}
1258
1259- (void)_postPreferencesChangedAPINotification
1260{
1261    if (!pthread_main_np()) {
1262        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1263        return;
1264    }
1265
1266    [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
1267}
1268
1269+ (CFStringEncoding)_systemCFStringEncoding
1270{
1271    return WKGetWebDefaultCFStringEncoding();
1272}
1273
1274+ (void)_setInitialDefaultTextEncodingToSystemEncoding
1275{
1276    NSString *systemEncodingName = (NSString *)CFStringConvertEncodingToIANACharSetName([self _systemCFStringEncoding]);
1277
1278    // CFStringConvertEncodingToIANACharSetName() returns cp949 for kTextEncodingDOSKorean AKA "extended EUC-KR" AKA windows-949.
1279    // ICU uses this name for a different encoding, so we need to change the name to a value that actually gives us windows-949.
1280    // In addition, this value must match what is used in Safari, see <rdar://problem/5579292>.
1281    // On some OS versions, the result is CP949 (uppercase).
1282    if ([systemEncodingName _webkit_isCaseInsensitiveEqualToString:@"cp949"])
1283        systemEncodingName = @"ks_c_5601-1987";
1284    [[NSUserDefaults standardUserDefaults] registerDefaults:
1285        [NSDictionary dictionaryWithObject:systemEncodingName forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1286}
1287
1288static NSString *classIBCreatorID = nil;
1289
1290+ (void)_setIBCreatorID:(NSString *)string
1291{
1292    NSString *old = classIBCreatorID;
1293    classIBCreatorID = [string copy];
1294    [old release];
1295}
1296
1297+ (void)_switchNetworkLoaderToNewTestingSession
1298{
1299    InitWebCoreSystemInterface();
1300    NetworkStorageSession::switchToNewTestingSession();
1301}
1302
1303+ (void)_setCurrentNetworkLoaderSessionCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)policy
1304{
1305    WKSetHTTPCookieAcceptPolicy(NetworkStorageSession::defaultStorageSession().cookieStorage().get(), policy);
1306}
1307
1308- (BOOL)isDOMPasteAllowed
1309{
1310    return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1311}
1312
1313- (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1314{
1315    [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1316}
1317
1318- (NSString *)_localStorageDatabasePath
1319{
1320    return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1321}
1322
1323- (void)_setLocalStorageDatabasePath:(NSString *)path
1324{
1325    [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1326}
1327
1328- (NSString *)_ftpDirectoryTemplatePath
1329{
1330    return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1331}
1332
1333- (void)_setFTPDirectoryTemplatePath:(NSString *)path
1334{
1335    [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1336}
1337
1338- (BOOL)_forceFTPDirectoryListings
1339{
1340    return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1341}
1342
1343- (void)_setForceFTPDirectoryListings:(BOOL)force
1344{
1345    [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1346}
1347
1348- (BOOL)acceleratedDrawingEnabled
1349{
1350    return [self _boolValueForKey:WebKitAcceleratedDrawingEnabledPreferenceKey];
1351}
1352
1353- (void)setAcceleratedDrawingEnabled:(BOOL)enabled
1354{
1355    [self _setBoolValue:enabled forKey:WebKitAcceleratedDrawingEnabledPreferenceKey];
1356}
1357
1358- (BOOL)canvasUsesAcceleratedDrawing
1359{
1360    return [self _boolValueForKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey];
1361}
1362
1363- (void)setCanvasUsesAcceleratedDrawing:(BOOL)enabled
1364{
1365    [self _setBoolValue:enabled forKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey];
1366}
1367
1368- (BOOL)acceleratedCompositingEnabled
1369{
1370    return [self _boolValueForKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1371}
1372
1373- (void)setAcceleratedCompositingEnabled:(BOOL)enabled
1374{
1375    [self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1376}
1377
1378- (BOOL)cssCustomFilterEnabled
1379{
1380    return [self _boolValueForKey:WebKitCSSCustomFilterEnabledPreferenceKey];
1381}
1382
1383- (void)setCSSCustomFilterEnabled:(BOOL)enabled
1384{
1385    [self _setBoolValue:enabled forKey:WebKitCSSCustomFilterEnabledPreferenceKey];
1386}
1387
1388- (BOOL)cssRegionsEnabled
1389{
1390    return [self _boolValueForKey:WebKitCSSRegionsEnabledPreferenceKey];
1391}
1392
1393- (void)setCSSRegionsEnabled:(BOOL)enabled
1394{
1395    [self _setBoolValue:enabled forKey:WebKitCSSRegionsEnabledPreferenceKey];
1396}
1397
1398- (BOOL)cssCompositingEnabled
1399{
1400    return [self _boolValueForKey:WebKitCSSCompositingEnabledPreferenceKey];
1401}
1402
1403- (void)setCSSCompositingEnabled:(BOOL)enabled
1404{
1405    [self _setBoolValue:enabled forKey:WebKitCSSCompositingEnabledPreferenceKey];
1406}
1407
1408- (BOOL)cssGridLayoutEnabled
1409{
1410    return [self _boolValueForKey:WebKitCSSGridLayoutEnabledPreferenceKey];
1411}
1412
1413- (void)setCSSGridLayoutEnabled:(BOOL)enabled
1414{
1415    [self _setBoolValue:enabled forKey:WebKitCSSGridLayoutEnabledPreferenceKey];
1416}
1417
1418- (BOOL)showDebugBorders
1419{
1420    return [self _boolValueForKey:WebKitShowDebugBordersPreferenceKey];
1421}
1422
1423- (void)setShowDebugBorders:(BOOL)enabled
1424{
1425    [self _setBoolValue:enabled forKey:WebKitShowDebugBordersPreferenceKey];
1426}
1427
1428- (BOOL)showRepaintCounter
1429{
1430    return [self _boolValueForKey:WebKitShowRepaintCounterPreferenceKey];
1431}
1432
1433- (void)setShowRepaintCounter:(BOOL)enabled
1434{
1435    [self _setBoolValue:enabled forKey:WebKitShowRepaintCounterPreferenceKey];
1436}
1437
1438- (BOOL)webAudioEnabled
1439{
1440    return [self _boolValueForKey:WebKitWebAudioEnabledPreferenceKey];
1441}
1442
1443- (void)setWebAudioEnabled:(BOOL)enabled
1444{
1445    [self _setBoolValue:enabled forKey:WebKitWebAudioEnabledPreferenceKey];
1446}
1447
1448- (BOOL)webGLEnabled
1449{
1450    return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey];
1451}
1452
1453- (void)setWebGLEnabled:(BOOL)enabled
1454{
1455    [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey];
1456}
1457
1458- (BOOL)accelerated2dCanvasEnabled
1459{
1460    return [self _boolValueForKey:WebKitAccelerated2dCanvasEnabledPreferenceKey];
1461}
1462
1463- (void)setAccelerated2dCanvasEnabled:(BOOL)enabled
1464{
1465    [self _setBoolValue:enabled forKey:WebKitAccelerated2dCanvasEnabledPreferenceKey];
1466}
1467
1468- (BOOL)isFrameFlatteningEnabled
1469{
1470    return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey];
1471}
1472
1473- (void)setFrameFlatteningEnabled:(BOOL)flag
1474{
1475    [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey];
1476}
1477
1478- (BOOL)isSpatialNavigationEnabled
1479{
1480    return [self _boolValueForKey:WebKitSpatialNavigationEnabledPreferenceKey];
1481}
1482
1483- (void)setSpatialNavigationEnabled:(BOOL)flag
1484{
1485    [self _setBoolValue:flag forKey:WebKitSpatialNavigationEnabledPreferenceKey];
1486}
1487
1488- (BOOL)paginateDuringLayoutEnabled
1489{
1490    return [self _boolValueForKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1491}
1492
1493- (void)setPaginateDuringLayoutEnabled:(BOOL)flag
1494{
1495    [self _setBoolValue:flag forKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1496}
1497
1498- (BOOL)hyperlinkAuditingEnabled
1499{
1500    return [self _boolValueForKey:WebKitHyperlinkAuditingEnabledPreferenceKey];
1501}
1502
1503- (void)setHyperlinkAuditingEnabled:(BOOL)flag
1504{
1505    [self _setBoolValue:flag forKey:WebKitHyperlinkAuditingEnabledPreferenceKey];
1506}
1507
1508- (BOOL)usePreHTML5ParserQuirks
1509{
1510    return [self _boolValueForKey:WebKitUsePreHTML5ParserQuirksKey];
1511}
1512
1513- (void)setUsePreHTML5ParserQuirks:(BOOL)flag
1514{
1515    [self _setBoolValue:flag forKey:WebKitUsePreHTML5ParserQuirksKey];
1516}
1517
1518- (void)didRemoveFromWebView
1519{
1520    ASSERT(_private->numWebViews);
1521    if (--_private->numWebViews == 0)
1522        [[NSNotificationCenter defaultCenter]
1523            postNotificationName:WebPreferencesRemovedNotification
1524                          object:self
1525                        userInfo:nil];
1526}
1527
1528- (void)willAddToWebView
1529{
1530    ++_private->numWebViews;
1531}
1532
1533- (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key
1534{
1535    [self _setStringValue:value forKey:key];
1536}
1537
1538- (void)setFullScreenEnabled:(BOOL)flag
1539{
1540    [self _setBoolValue:flag forKey:WebKitFullScreenEnabledPreferenceKey];
1541}
1542
1543- (BOOL)fullScreenEnabled
1544{
1545    return [self _boolValueForKey:WebKitFullScreenEnabledPreferenceKey];
1546}
1547
1548- (void)setAsynchronousSpellCheckingEnabled:(BOOL)flag
1549{
1550    [self _setBoolValue:flag forKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey];
1551}
1552
1553- (BOOL)asynchronousSpellCheckingEnabled
1554{
1555    return [self _boolValueForKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey];
1556}
1557
1558+ (void)setWebKitLinkTimeVersion:(int)version
1559{
1560    setWebKitLinkTimeVersion(version);
1561}
1562
1563- (void)setLoadsSiteIconsIgnoringImageLoadingPreference: (BOOL)flag
1564{
1565    [self _setBoolValue: flag forKey: WebKitLoadSiteIconsKey];
1566}
1567
1568- (BOOL)loadsSiteIconsIgnoringImageLoadingPreference
1569{
1570    return [self _boolValueForKey: WebKitLoadSiteIconsKey];
1571}
1572
1573- (void)setAVFoundationEnabled:(BOOL)flag
1574{
1575    [self _setBoolValue:flag forKey:WebKitAVFoundationEnabledKey];
1576}
1577
1578- (BOOL)isAVFoundationEnabled
1579{
1580    return [self _boolValueForKey:WebKitAVFoundationEnabledKey];
1581}
1582
1583- (void)setQTKitEnabled:(BOOL)flag
1584{
1585    [self _setBoolValue:flag forKey:WebKitQTKitEnabledPreferenceKey];
1586}
1587
1588- (BOOL)isQTKitEnabled
1589{
1590    return [self _boolValueForKey:WebKitQTKitEnabledPreferenceKey];
1591}
1592
1593- (void)setHixie76WebSocketProtocolEnabled:(BOOL)flag
1594{
1595}
1596
1597- (BOOL)isHixie76WebSocketProtocolEnabled
1598{
1599    return false;
1600}
1601
1602- (BOOL)isInheritURIQueryComponentEnabled
1603{
1604    return [self _boolValueForKey: WebKitEnableInheritURIQueryComponentPreferenceKey];
1605}
1606
1607- (void)setEnableInheritURIQueryComponent:(BOOL)flag
1608{
1609    [self _setBoolValue:flag forKey: WebKitEnableInheritURIQueryComponentPreferenceKey];
1610}
1611
1612- (BOOL)mediaPlaybackRequiresUserGesture
1613{
1614    return [self _boolValueForKey:WebKitMediaPlaybackRequiresUserGesturePreferenceKey];
1615}
1616
1617- (void)setMediaPlaybackRequiresUserGesture:(BOOL)flag
1618{
1619    [self _setBoolValue:flag forKey:WebKitMediaPlaybackRequiresUserGesturePreferenceKey];
1620}
1621
1622- (BOOL)mediaPlaybackAllowsInline
1623{
1624    return [self _boolValueForKey:WebKitMediaPlaybackAllowsInlinePreferenceKey];
1625}
1626
1627- (void)setMediaPlaybackAllowsInline:(BOOL)flag
1628{
1629    [self _setBoolValue:flag forKey:WebKitMediaPlaybackAllowsInlinePreferenceKey];
1630}
1631
1632- (BOOL)mockScrollbarsEnabled
1633{
1634    return [self _boolValueForKey:WebKitMockScrollbarsEnabledPreferenceKey];
1635}
1636
1637- (void)setMockScrollbarsEnabled:(BOOL)flag
1638{
1639    [self _setBoolValue:flag forKey:WebKitMockScrollbarsEnabledPreferenceKey];
1640}
1641
1642- (BOOL)seamlessIFramesEnabled
1643{
1644    return [self _boolValueForKey:WebKitSeamlessIFramesEnabledPreferenceKey];
1645}
1646
1647- (void)setSeamlessIFramesEnabled:(BOOL)flag
1648{
1649    [self _setBoolValue:flag forKey:WebKitSeamlessIFramesEnabledPreferenceKey];
1650}
1651
1652- (NSString *)pictographFontFamily
1653{
1654    return [self _stringValueForKey: WebKitPictographFontPreferenceKey];
1655}
1656
1657- (void)setPictographFontFamily:(NSString *)family
1658{
1659    [self _setStringValue: family forKey: WebKitPictographFontPreferenceKey];
1660}
1661
1662- (BOOL)pageCacheSupportsPlugins
1663{
1664    return [self _boolValueForKey:WebKitPageCacheSupportsPluginsPreferenceKey];
1665}
1666
1667- (void)setPageCacheSupportsPlugins:(BOOL)flag
1668{
1669    [self _setBoolValue:flag forKey:WebKitPageCacheSupportsPluginsPreferenceKey];
1670
1671}
1672
1673- (void)setBackspaceKeyNavigationEnabled:(BOOL)flag
1674{
1675    [self _setBoolValue:flag forKey:WebKitBackspaceKeyNavigationEnabledKey];
1676}
1677
1678- (BOOL)backspaceKeyNavigationEnabled
1679{
1680    return [self _boolValueForKey:WebKitBackspaceKeyNavigationEnabledKey];
1681}
1682
1683- (void)setWantsBalancedSetDefersLoadingBehavior:(BOOL)flag
1684{
1685    [self _setBoolValue:flag forKey:WebKitWantsBalancedSetDefersLoadingBehaviorKey];
1686}
1687
1688- (BOOL)wantsBalancedSetDefersLoadingBehavior
1689{
1690    return [self _boolValueForKey:WebKitWantsBalancedSetDefersLoadingBehaviorKey];
1691}
1692
1693- (void)setShouldDisplaySubtitles:(BOOL)flag
1694{
1695    [self _setBoolValue:flag forKey:WebKitShouldDisplaySubtitlesPreferenceKey];
1696}
1697
1698- (BOOL)shouldDisplaySubtitles
1699{
1700    return [self _boolValueForKey:WebKitShouldDisplaySubtitlesPreferenceKey];
1701}
1702
1703- (void)setShouldDisplayCaptions:(BOOL)flag
1704{
1705    [self _setBoolValue:flag forKey:WebKitShouldDisplayCaptionsPreferenceKey];
1706}
1707
1708- (BOOL)shouldDisplayCaptions
1709{
1710    return [self _boolValueForKey:WebKitShouldDisplayCaptionsPreferenceKey];
1711}
1712
1713- (void)setShouldDisplayTextDescriptions:(BOOL)flag
1714{
1715    [self _setBoolValue:flag forKey:WebKitShouldDisplayTextDescriptionsPreferenceKey];
1716}
1717
1718- (BOOL)shouldDisplayTextDescriptions
1719{
1720    return [self _boolValueForKey:WebKitShouldDisplayTextDescriptionsPreferenceKey];
1721}
1722
1723- (void)setNotificationsEnabled:(BOOL)flag
1724{
1725    [self _setBoolValue:flag forKey:WebKitNotificationsEnabledKey];
1726}
1727
1728- (BOOL)notificationsEnabled
1729{
1730    return [self _boolValueForKey:WebKitNotificationsEnabledKey];
1731}
1732
1733- (void)setRegionBasedColumnsEnabled:(BOOL)flag
1734{
1735    [self _setBoolValue:flag forKey:WebKitRegionBasedColumnsEnabledKey];
1736}
1737
1738- (BOOL)regionBasedColumnsEnabled
1739{
1740    return [self _boolValueForKey:WebKitRegionBasedColumnsEnabledKey];
1741}
1742
1743- (void)setShouldRespectImageOrientation:(BOOL)flag
1744{
1745    [self _setBoolValue:flag forKey:WebKitShouldRespectImageOrientationKey];
1746}
1747
1748- (BOOL)shouldRespectImageOrientation
1749{
1750    return [self _boolValueForKey:WebKitShouldRespectImageOrientationKey];
1751}
1752
1753- (BOOL)requestAnimationFrameEnabled
1754{
1755    return [self _boolValueForKey:WebKitRequestAnimationFrameEnabledPreferenceKey];
1756}
1757
1758- (void)setRequestAnimationFrameEnabled:(BOOL)enabled
1759{
1760    [self _setBoolValue:enabled forKey:WebKitRequestAnimationFrameEnabledPreferenceKey];
1761}
1762
1763- (void)setIncrementalRenderingSuppressionTimeoutInSeconds:(NSTimeInterval)timeout
1764{
1765    [self _setFloatValue:timeout forKey:WebKitIncrementalRenderingSuppressionTimeoutInSecondsKey];
1766}
1767
1768- (NSTimeInterval)incrementalRenderingSuppressionTimeoutInSeconds
1769{
1770    return [self _floatValueForKey:WebKitIncrementalRenderingSuppressionTimeoutInSecondsKey];
1771}
1772
1773- (BOOL)diagnosticLoggingEnabled
1774{
1775    return [self _boolValueForKey:WebKitDiagnosticLoggingEnabledKey];
1776}
1777
1778- (void)setDiagnosticLoggingEnabled:(BOOL)enabled
1779{
1780    [self _setBoolValue:enabled forKey:WebKitDiagnosticLoggingEnabledKey];
1781}
1782
1783static bool needsScreenFontsEnabledQuirk()
1784{
1785#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
1786    static bool is1PasswordNeedingScreenFontsQuirk = WKExecutableWasLinkedOnOrBeforeMountainLion()
1787        && [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"ws.agile.1Password"];
1788    return is1PasswordNeedingScreenFontsQuirk;
1789#else
1790    return NO;
1791#endif
1792}
1793
1794- (BOOL)screenFontSubstitutionEnabled
1795{
1796    if (needsScreenFontsEnabledQuirk())
1797        return YES;
1798    return [self _boolValueForKey:WebKitScreenFontSubstitutionEnabledKey];
1799}
1800
1801- (void)setScreenFontSubstitutionEnabled:(BOOL)enabled
1802{
1803    [self _setBoolValue:enabled forKey:WebKitScreenFontSubstitutionEnabledKey];
1804}
1805
1806- (void)setStorageBlockingPolicy:(WebStorageBlockingPolicy)storageBlockingPolicy
1807{
1808    [self _setIntegerValue:storageBlockingPolicy forKey:WebKitStorageBlockingPolicyKey];
1809}
1810
1811- (WebStorageBlockingPolicy)storageBlockingPolicy
1812{
1813    return static_cast<WebStorageBlockingPolicy>([self _integerValueForKey:WebKitStorageBlockingPolicyKey]);
1814}
1815
1816- (BOOL)plugInSnapshottingEnabled
1817{
1818    return [self _boolValueForKey:WebKitPlugInSnapshottingEnabledPreferenceKey];
1819}
1820
1821- (void)setPlugInSnapshottingEnabled:(BOOL)enabled
1822{
1823    [self _setBoolValue:enabled forKey:WebKitPlugInSnapshottingEnabledPreferenceKey];
1824}
1825
1826- (BOOL)hiddenPageDOMTimerThrottlingEnabled
1827{
1828    return [self _boolValueForKey:WebKitHiddenPageDOMTimerThrottlingEnabledPreferenceKey];
1829}
1830
1831- (void)setHiddenPageDOMTimerThrottlingEnabled:(BOOL)enabled
1832{
1833    [self _setBoolValue:enabled forKey:WebKitHiddenPageDOMTimerThrottlingEnabledPreferenceKey];
1834}
1835
1836- (BOOL)hiddenPageCSSAnimationSuspensionEnabled
1837{
1838    return [self _boolValueForKey:WebKitHiddenPageCSSAnimationSuspensionEnabledPreferenceKey];
1839}
1840
1841- (void)setHiddenPageCSSAnimationSuspensionEnabled:(BOOL)enabled
1842{
1843    [self _setBoolValue:enabled forKey:WebKitHiddenPageCSSAnimationSuspensionEnabledPreferenceKey];
1844}
1845
1846- (BOOL)lowPowerVideoAudioBufferSizeEnabled
1847{
1848    return [self _boolValueForKey:WebKitLowPowerVideoAudioBufferSizeEnabledPreferenceKey];
1849}
1850
1851- (void)setLowPowerVideoAudioBufferSizeEnabled:(BOOL)enabled
1852{
1853    [self _setBoolValue:enabled forKey:WebKitLowPowerVideoAudioBufferSizeEnabledPreferenceKey];
1854}
1855
1856- (BOOL)useLegacyTextAlignPositionedElementBehavior
1857{
1858    return [self _boolValueForKey:WebKitUseLegacyTextAlignPositionedElementBehaviorPreferenceKey];
1859}
1860
1861- (void)setUseLegacyTextAlignPositionedElementBehavior:(BOOL)enabled
1862{
1863    [self _setBoolValue:enabled forKey:WebKitUseLegacyTextAlignPositionedElementBehaviorPreferenceKey];
1864}
1865
1866@end
1867
1868@implementation WebPreferences (WebInternal)
1869
1870+ (NSString *)_IBCreatorID
1871{
1872    return classIBCreatorID;
1873}
1874
1875+ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
1876{
1877    NSString *IBCreatorID = [WebPreferences _IBCreatorID];
1878    if (!IBCreatorID)
1879        return key;
1880    return [IBCreatorID stringByAppendingString:key];
1881}
1882
1883@end
1884