REGRESSION(r179429): Can't type comments in Facebook
[WebKit-https.git] / Source / WebKit / mac / WebView / WebPreferences.mm
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 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/AudioSession.h>
45 #import <WebCore/NetworkStorageSession.h>
46 #import <WebCore/PlatformCookieJar.h>
47 #import <WebCore/ResourceHandle.h>
48 #import <WebCore/TextEncodingRegistry.h>
49 #import <runtime/InitializeThreading.h>
50 #import <wtf/MainThread.h>
51 #import <wtf/RetainPtr.h>
52 #import <wtf/RunLoop.h>
53
54 enum {
55     NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain = 3
56 };
57
58 using namespace WebCore;
59
60 #if PLATFORM(IOS)
61 #import <AudioToolbox/AudioSession.h>
62 #import <WebCore/GraphicsContext.h>
63 #import <WebCore/ImageSource.h>
64 #import <WebCore/WebCoreThreadMessage.h>
65 #endif
66
67 NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";
68 NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";
69 NSString *WebPreferencesChangedInternalNotification = @"WebPreferencesChangedInternalNotification";
70 NSString *WebPreferencesCacheModelChangedInternalNotification = @"WebPreferencesCacheModelChangedInternalNotification";
71
72 #define KEY(x) (_private->identifier ? [_private->identifier.get() stringByAppendingString:(x)] : (x))
73
74 enum { WebPreferencesVersion = 1 };
75
76 static WebPreferences *_standardPreferences;
77 static NSMutableDictionary *webPreferencesInstances;
78
79 static unsigned webPreferencesInstanceCountWithPrivateBrowsingEnabled;
80
81 static bool contains(const char* const array[], int count, const char* item)
82 {
83     if (!item)
84         return false;
85
86     for (int i = 0; i < count; i++)
87         if (!strcasecmp(array[i], item))
88             return true;
89     return false;
90 }
91
92 static WebCacheModel cacheModelForMainBundle(void)
93 {
94     @autoreleasepool {
95         // Apps that probably need the small setting
96         static const char* const documentViewerIDs[] = {
97             "Microsoft/com.microsoft.Messenger",
98             "com.adiumX.adiumX", 
99             "com.alientechnology.Proteus",
100             "com.apple.Dashcode",
101             "com.apple.iChat", 
102             "com.barebones.bbedit",
103             "com.barebones.textwrangler",
104             "com.barebones.yojimbo",
105             "com.equinux.iSale4",
106             "com.growl.growlframework",
107             "com.intrarts.PandoraMan",
108             "com.karelia.Sandvox",
109             "com.macromates.textmate",
110             "com.realmacsoftware.rapidweaverpro",
111             "com.red-sweater.marsedit",
112             "com.yahoo.messenger3",
113             "de.codingmonkeys.SubEthaEdit",
114             "fi.karppinen.Pyro",
115             "info.colloquy", 
116             "kungfoo.tv.ecto",
117         };
118
119         // Apps that probably need the medium setting
120         static const char* const documentBrowserIDs[] = {
121             "com.apple.Dictionary",
122             "com.apple.Xcode",
123             "com.apple.dashboard.client", 
124             "com.apple.helpviewer",
125             "com.culturedcode.xyle",
126             "com.macrabbit.CSSEdit",
127             "com.panic.Coda",
128             "com.ranchero.NetNewsWire",
129             "com.thinkmac.NewsLife",
130             "org.xlife.NewsFire",
131             "uk.co.opencommunity.vienna2",
132         };
133
134         // Apps that probably need the large setting
135         static const char* const primaryWebBrowserIDs[] = {
136             "com.app4mac.KidsBrowser"
137             "com.app4mac.wKiosk",
138             "com.freeverse.bumpercar",
139             "com.omnigroup.OmniWeb5",
140             "com.sunrisebrowser.Sunrise",
141             "net.hmdt-web.Shiira",
142         };
143
144         const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
145         if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID))
146             return WebCacheModelDocumentViewer;
147         if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID))
148             return WebCacheModelDocumentBrowser;
149         if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID))
150             return WebCacheModelPrimaryWebBrowser;
151
152         bool isLinkedAgainstWebKit = WebKitLinkedOnOrAfter(0);
153         if (!isLinkedAgainstWebKit)
154             return WebCacheModelDocumentViewer; // Apps that don't link against WebKit probably aren't meant to be browsers.
155
156 #if !PLATFORM(IOS)
157         bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API);
158 #else
159         bool isLegacyApp = false;
160 #endif
161         if (isLegacyApp)
162             return WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache.
163
164         return WebCacheModelDocumentViewer; // To save memory.
165     }
166 }
167
168 @interface WebPreferences ()
169 - (void)_postCacheModelChangedNotification;
170 @end
171
172 @interface WebPreferences (WebInternal)
173 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;
174 + (NSString *)_IBCreatorID;
175 @end
176
177 struct WebPreferencesPrivate
178 {
179 public:
180     WebPreferencesPrivate()
181     : inPrivateBrowsing(NO)
182     , autosaves(NO)
183     , automaticallyDetectsCacheModel(NO)
184     , numWebViews(0)
185 #if PLATFORM(IOS)
186     , readWriteQueue(dispatch_queue_create("com.apple.WebPreferences.ReadWriteQueue", DISPATCH_QUEUE_CONCURRENT))
187 #endif
188     {
189     }
190
191 #if PLATFORM(IOS)
192     ~WebPreferencesPrivate()
193     {
194         dispatch_release(readWriteQueue);
195     }
196 #endif
197
198     RetainPtr<NSMutableDictionary> values;
199     BOOL inPrivateBrowsing;
200     RetainPtr<NSString> identifier;
201     BOOL autosaves;
202     BOOL automaticallyDetectsCacheModel;
203     unsigned numWebViews;
204 #if PLATFORM(IOS)
205     dispatch_queue_t readWriteQueue;
206 #endif
207 };
208
209 @interface WebPreferences (WebForwardDeclarations)
210 // This pseudo-category is needed so these methods can be used from within other category implementations
211 // without being in the public header file.
212 - (BOOL)_boolValueForKey:(NSString *)key;
213 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;
214 - (int)_integerValueForKey:(NSString *)key;
215 - (void)_setIntegerValue:(int)value forKey:(NSString *)key;
216 - (float)_floatValueForKey:(NSString *)key;
217 - (void)_setFloatValue:(float)value forKey:(NSString *)key;
218 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key;
219 - (long long)_longLongValueForKey:(NSString *)key;
220 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key;
221 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key;
222 @end
223
224 #if PLATFORM(IOS)
225 @interface WebPreferences ()
226 - (id)initWithIdentifier:(NSString *)anIdentifier sendChangeNotification:(BOOL)sendChangeNotification;
227 @end
228 #endif
229
230 @implementation WebPreferences
231
232 - (instancetype)init
233 {
234     // Create fake identifier
235     static int instanceCount = 1;
236     NSString *fakeIdentifier;
237     
238     // At least ensure that identifier hasn't been already used.  
239     fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
240     while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){
241         fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++];
242     }
243     
244     return [self initWithIdentifier:fakeIdentifier];
245 }
246
247 #if PLATFORM(IOS)
248 - (id)initWithIdentifier:(NSString *)anIdentifier
249 {
250     return [self initWithIdentifier:anIdentifier sendChangeNotification:YES];
251 }
252 #endif
253
254 #if PLATFORM(IOS)
255 - (instancetype)initWithIdentifier:(NSString *)anIdentifier sendChangeNotification:(BOOL)sendChangeNotification
256 #else
257 - (instancetype)initWithIdentifier:(NSString *)anIdentifier
258 #endif
259 {
260     WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier];
261     if (instance) {
262         [self release];
263         return [instance retain];
264     }
265
266     self = [super init];
267     if (!self)
268         return nil;
269
270     _private = new WebPreferencesPrivate;
271     _private->values = adoptNS([[NSMutableDictionary alloc] init]);
272     _private->identifier = adoptNS([anIdentifier copy]);
273     _private->automaticallyDetectsCacheModel = YES;
274
275     [[self class] _setInstance:self forIdentifier:_private->identifier.get()];
276
277     [self _updatePrivateBrowsingStateTo:[self privateBrowsingEnabled]];
278
279 #if PLATFORM(IOS)
280     if (sendChangeNotification) {
281         [self _postPreferencesChangedNotification];
282         [self _postCacheModelChangedNotification];
283     }
284 #else
285     [self _postPreferencesChangedNotification];
286     [self _postCacheModelChangedNotification];
287 #endif
288
289     return self;
290 }
291
292 - (instancetype)initWithCoder:(NSCoder *)decoder
293 {
294     self = [super init];
295     if (!self)
296         return nil;
297
298     _private = new WebPreferencesPrivate;
299     _private->automaticallyDetectsCacheModel = YES;
300
301     @try {
302         id identifier = nil;
303         id values = nil;
304         if ([decoder allowsKeyedCoding]) {
305             identifier = [decoder decodeObjectForKey:@"Identifier"];
306             values = [decoder decodeObjectForKey:@"Values"];
307         } else {
308             int version;
309             [decoder decodeValueOfObjCType:@encode(int) at:&version];
310             if (version == 1) {
311                 identifier = [decoder decodeObject];
312                 values = [decoder decodeObject];
313             }
314         }
315
316         if ([identifier isKindOfClass:[NSString class]])
317             _private->identifier = adoptNS([identifier copy]);
318         if ([values isKindOfClass:[NSDictionary class]])
319             _private->values = adoptNS([values mutableCopy]); // ensure dictionary is mutable
320
321         LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier.get(), _private->values.get());
322     } @catch(id) {
323         [self release];
324         return nil;
325     }
326
327     // If we load a nib multiple times, or have instances in multiple
328     // nibs with the same name, the first guy up wins.
329     WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier.get()];
330     if (instance) {
331         [self release];
332         self = [instance retain];
333     } else {
334         [[self class] _setInstance:self forIdentifier:_private->identifier.get()];
335         [self _updatePrivateBrowsingStateTo:[self privateBrowsingEnabled]];
336     }
337
338     return self;
339 }
340
341 - (void)encodeWithCoder:(NSCoder *)encoder
342 {
343     if ([encoder allowsKeyedCoding]){
344         [encoder encodeObject:_private->identifier.get() forKey:@"Identifier"];
345 #if PLATFORM(IOS)
346         dispatch_sync(_private->readWriteQueue, ^{
347 #endif
348         [encoder encodeObject:_private->values.get() forKey:@"Values"];
349         LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier.get(), _private->values.get());
350 #if PLATFORM(IOS)
351         });
352 #endif
353     }
354     else {
355         int version = WebPreferencesVersion;
356         [encoder encodeValueOfObjCType:@encode(int) at:&version];
357         [encoder encodeObject:_private->identifier.get()];
358 #if PLATFORM(IOS)
359         dispatch_sync(_private->readWriteQueue, ^{
360 #endif
361         [encoder encodeObject:_private->values.get()];
362 #if PLATFORM(IOS)
363         });
364 #endif
365     }
366 }
367
368 + (WebPreferences *)standardPreferences
369 {
370 #if !PLATFORM(IOS)
371     if (_standardPreferences == nil) {
372         _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil];
373         [_standardPreferences setAutosaves:YES];
374     }
375 #else
376     // FIXME: This check is necessary to avoid recursion (see <rdar://problem/9564337>), but it also makes _standardPreferences construction not thread safe.
377     if (_standardPreferences)
378         return _standardPreferences;
379
380     static dispatch_once_t pred;
381     dispatch_once(&pred, ^{
382         _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil sendChangeNotification:NO];
383         [_standardPreferences _postPreferencesChangedNotification];
384         [_standardPreferences setAutosaves:YES];
385     });
386 #endif
387
388     return _standardPreferences;
389 }
390
391 // if we ever have more than one WebPreferences object, this would move to init
392 + (void)initialize
393 {
394 #if !PLATFORM(IOS)
395     JSC::initializeThreading();
396     WTF::initializeMainThreadToProcessMainThread();
397     RunLoop::initializeMainRunLoop();
398 #endif
399     InitWebCoreSystemInterface();
400
401     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
402         @"Times",                       WebKitStandardFontPreferenceKey,
403         @"Courier",                     WebKitFixedFontPreferenceKey,
404         @"Times",                       WebKitSerifFontPreferenceKey,
405         @"Helvetica",                   WebKitSansSerifFontPreferenceKey,
406 #if !PLATFORM(IOS)
407         @"Apple Chancery",              WebKitCursiveFontPreferenceKey,
408 #else
409         @"Snell Roundhand",             WebKitCursiveFontPreferenceKey,
410 #endif
411         @"Papyrus",                     WebKitFantasyFontPreferenceKey,
412 #if PLATFORM(IOS)
413         @"AppleColorEmoji",             WebKitPictographFontPreferenceKey,
414 #else
415         @"Apple Color Emoji",           WebKitPictographFontPreferenceKey,
416 #endif
417         @"0",                           WebKitMinimumFontSizePreferenceKey,
418         @"9",                           WebKitMinimumLogicalFontSizePreferenceKey, 
419         @"16",                          WebKitDefaultFontSizePreferenceKey,
420         @"13",                          WebKitDefaultFixedFontSizePreferenceKey,
421         @"ISO-8859-1",                  WebKitDefaultTextEncodingNamePreferenceKey,
422         [NSNumber numberWithBool:NO],   WebKitUsesEncodingDetectorPreferenceKey,
423         [NSNumber numberWithBool:NO],   WebKitUserStyleSheetEnabledPreferenceKey,
424         @"",                            WebKitUserStyleSheetLocationPreferenceKey,
425 #if !PLATFORM(IOS)
426         [NSNumber numberWithBool:NO],   WebKitShouldPrintBackgroundsPreferenceKey,
427         [NSNumber numberWithBool:NO],   WebKitTextAreasAreResizablePreferenceKey,
428 #endif
429         [NSNumber numberWithBool:NO],   WebKitShrinksStandaloneImagesToFitPreferenceKey,
430 #if !PLATFORM(IOS)
431         [NSNumber numberWithBool:YES],  WebKitJavaEnabledPreferenceKey,
432 #endif
433         [NSNumber numberWithBool:YES],  WebKitJavaScriptEnabledPreferenceKey,
434         [NSNumber numberWithBool:YES],  WebKitWebSecurityEnabledPreferenceKey,
435         [NSNumber numberWithBool:YES],  WebKitAllowUniversalAccessFromFileURLsPreferenceKey,
436         [NSNumber numberWithBool:YES],  WebKitAllowFileAccessFromFileURLsPreferenceKey,
437 #if PLATFORM(IOS)
438         [NSNumber numberWithBool:NO],   WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
439 #else
440         [NSNumber numberWithBool:YES],  WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey,
441 #endif
442         [NSNumber numberWithBool:YES],  WebKitPluginsEnabledPreferenceKey,
443         [NSNumber numberWithBool:YES],  WebKitDatabasesEnabledPreferenceKey,
444 #if PLATFORM(IOS)
445         [NSNumber numberWithBool:NO],   WebKitStorageTrackerEnabledPreferenceKey,
446 #endif
447         [NSNumber numberWithBool:YES],  WebKitLocalStorageEnabledPreferenceKey,
448         [NSNumber numberWithBool:NO],   WebKitExperimentalNotificationsEnabledPreferenceKey,
449         [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImagesPreferenceKey,
450         [NSNumber numberWithBool:YES],  WebKitAllowAnimatedImageLoopingPreferenceKey,
451         [NSNumber numberWithBool:YES],  WebKitDisplayImagesKey,
452         [NSNumber numberWithBool:NO],   WebKitLoadSiteIconsKey,
453         @"1800",                        WebKitBackForwardCacheExpirationIntervalKey,
454 #if !PLATFORM(IOS)
455         [NSNumber numberWithBool:NO],   WebKitTabToLinksPreferenceKey,
456 #endif
457         [NSNumber numberWithBool:NO],   WebKitPrivateBrowsingEnabledPreferenceKey,
458 #if !PLATFORM(IOS)
459         [NSNumber numberWithBool:NO],   WebKitRespectStandardStyleKeyEquivalentsPreferenceKey,
460         [NSNumber numberWithBool:NO],   WebKitShowsURLsInToolTipsPreferenceKey,
461         [NSNumber numberWithBool:NO],   WebKitShowsToolTipOverTruncatedTextPreferenceKey,
462         @"1",                           WebKitPDFDisplayModePreferenceKey,
463         @"0",                           WebKitPDFScaleFactorPreferenceKey,
464 #endif
465         @"0",                           WebKitUseSiteSpecificSpoofingPreferenceKey,
466         [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,
467 #if !PLATFORM(IOS)
468         [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],
469                                         WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey,
470         [NSNumber numberWithBool:NO],   WebKitDOMPasteAllowedPreferenceKey,
471 #endif
472         [NSNumber numberWithBool:YES],  WebKitUsesPageCachePreferenceKey,
473         [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey,
474         [NSNumber numberWithBool:YES],  WebKitPageCacheSupportsPluginsPreferenceKey,
475         [NSNumber numberWithBool:NO],   WebKitDeveloperExtrasEnabledPreferenceKey,
476         [NSNumber numberWithUnsignedInt:0], WebKitJavaScriptRuntimeFlagsPreferenceKey,
477         [NSNumber numberWithBool:YES],  WebKitAuthorAndUserStylesEnabledPreferenceKey,
478         [NSNumber numberWithBool:YES],  WebKitDOMTimersThrottlingEnabledPreferenceKey,
479         [NSNumber numberWithBool:NO],   WebKitWebArchiveDebugModeEnabledPreferenceKey,
480         [NSNumber numberWithBool:NO],   WebKitLocalFileContentSniffingEnabledPreferenceKey,
481         [NSNumber numberWithBool:NO],   WebKitOfflineWebApplicationCacheEnabledPreferenceKey,
482         [NSNumber numberWithBool:YES],  WebKitZoomsTextOnlyPreferenceKey,
483         [NSNumber numberWithBool:NO],   WebKitJavaScriptCanAccessClipboardPreferenceKey,
484         [NSNumber numberWithBool:YES],  WebKitXSSAuditorEnabledPreferenceKey,
485         [NSNumber numberWithBool:YES],  WebKitAcceleratedCompositingEnabledPreferenceKey,
486         [NSNumber numberWithBool:YES], WebKitCSSRegionsEnabledPreferenceKey,
487         [NSNumber numberWithBool:YES], WebKitCSSCompositingEnabledPreferenceKey,
488 #if PLATFORM(IOS) && !PLATFORM(IOS_SIMULATOR)
489         [NSNumber numberWithBool:YES],  WebKitAcceleratedDrawingEnabledPreferenceKey,
490         [NSNumber numberWithBool:YES],  WebKitCanvasUsesAcceleratedDrawingPreferenceKey,
491 #else
492         [NSNumber numberWithBool:NO],  WebKitAcceleratedDrawingEnabledPreferenceKey,
493         [NSNumber numberWithBool:NO],  WebKitCanvasUsesAcceleratedDrawingPreferenceKey,
494 #endif
495         [NSNumber numberWithBool:NO],   WebKitShowDebugBordersPreferenceKey,
496         [NSNumber numberWithBool:NO],   WebKitSimpleLineLayoutDebugBordersEnabledPreferenceKey,
497         [NSNumber numberWithBool:NO],   WebKitShowRepaintCounterPreferenceKey,
498         [NSNumber numberWithBool:YES],  WebKitWebGLEnabledPreferenceKey,
499         [NSNumber numberWithBool:NO],  WebKitForceSoftwareWebGLRenderingPreferenceKey,
500         [NSNumber numberWithBool:NO],   WebKitAccelerated2dCanvasEnabledPreferenceKey,
501         [NSNumber numberWithBool:NO],  WebKitSubpixelCSSOMElementMetricsEnabledPreferenceKey,
502 #if PLATFORM(IOS)
503         [NSNumber numberWithBool:YES],  WebKitFrameFlatteningEnabledPreferenceKey,
504 #else
505         [NSNumber numberWithBool:NO],   WebKitFrameFlatteningEnabledPreferenceKey,
506 #endif
507         [NSNumber numberWithBool:NO],   WebKitSpatialNavigationEnabledPreferenceKey,
508         [NSNumber numberWithBool:NO],  WebKitDNSPrefetchingEnabledPreferenceKey,
509         [NSNumber numberWithBool:NO],   WebKitFullScreenEnabledPreferenceKey,
510         [NSNumber numberWithBool:NO],   WebKitAsynchronousSpellCheckingEnabledPreferenceKey,
511         [NSNumber numberWithBool:YES],  WebKitHyperlinkAuditingEnabledPreferenceKey,
512         [NSNumber numberWithBool:NO],   WebKitUsePreHTML5ParserQuirksKey,
513         [NSNumber numberWithBool:YES],  WebKitAVFoundationEnabledKey,
514         [NSNumber numberWithBool:NO],   WebKitSuppressesIncrementalRenderingKey,
515 #if !PLATFORM(IOS)
516         [NSNumber numberWithBool:NO],   WebKitMediaPlaybackRequiresUserGesturePreferenceKey,
517         [NSNumber numberWithBool:YES],  WebKitMediaPlaybackAllowsInlinePreferenceKey,
518         [NSNumber numberWithBool:NO],   WebKitWebAudioEnabledPreferenceKey,
519         [NSNumber numberWithBool:YES],  WebKitBackspaceKeyNavigationEnabledKey,
520         [NSNumber numberWithBool:NO],   WebKitShouldDisplaySubtitlesPreferenceKey,
521         [NSNumber numberWithBool:NO],   WebKitShouldDisplayCaptionsPreferenceKey,
522         [NSNumber numberWithBool:NO],   WebKitShouldDisplayTextDescriptionsPreferenceKey,
523         [NSNumber numberWithBool:YES],  WebKitNotificationsEnabledKey,
524         [NSNumber numberWithBool:NO],   WebKitShouldRespectImageOrientationKey,
525 #else
526         [NSNumber numberWithBool:YES],  WebKitMediaPlaybackRequiresUserGesturePreferenceKey,
527         [NSNumber numberWithBool:NO],   WebKitMediaPlaybackAllowsInlinePreferenceKey,
528         [NSNumber numberWithBool:YES],  WebKitMediaPlaybackAllowsAirPlayPreferenceKey,
529         [NSNumber numberWithUnsignedInt:AudioSession::None],  WebKitAudioSessionCategoryOverride,
530         [NSNumber numberWithBool:YES],  WebKitAVKitEnabled,
531         [NSNumber numberWithLongLong:WebCore::ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
532
533         // Per-Origin Quota on iOS is 25MB. When the quota is reached for a particular origin
534         // the quota for that origin can be increased. See also webView:exceededApplicationCacheOriginQuotaForSecurityOrigin:totalSpaceNeeded in WebUI/WebUIDelegate.m.
535         [NSNumber numberWithLongLong:(25 * 1024 * 1024)], WebKitApplicationCacheDefaultOriginQuota,
536
537         // Enable WebAudio by default in all iOS UIWebViews
538         [NSNumber numberWithBool:YES],   WebKitWebAudioEnabledPreferenceKey,
539
540         [NSNumber numberWithBool:YES],   WebKitShouldRespectImageOrientationKey,
541 #endif // PLATFORM(IOS)
542         [NSNumber numberWithBool:YES],  WebKitAllowsAlternateFullscreenPreferenceKey,
543         [NSNumber numberWithBool:YES],  WebKitRequestAnimationFrameEnabledPreferenceKey,
544         [NSNumber numberWithBool:NO],   WebKitWantsBalancedSetDefersLoadingBehaviorKey,
545         [NSNumber numberWithBool:NO],   WebKitDiagnosticLoggingEnabledKey,
546         [NSNumber numberWithInt:WebAllowAllStorage], WebKitStorageBlockingPolicyKey,
547         [NSNumber numberWithBool:NO],   WebKitPlugInSnapshottingEnabledPreferenceKey,
548
549 #if PLATFORM(IOS)
550         [NSNumber numberWithBool:NO],   WebKitTelephoneParsingEnabledPreferenceKey,
551         [NSNumber numberWithInt:-1],      WebKitLayoutIntervalPreferenceKey,
552         [NSNumber numberWithFloat:-1.0f], WebKitMaxParseDurationPreferenceKey,
553         [NSNumber numberWithBool:NO],     WebKitAllowMultiElementImplicitFormSubmissionPreferenceKey,
554         [NSNumber numberWithBool:NO],     WebKitAlwaysRequestGeolocationPermissionPreferenceKey,
555         [NSNumber numberWithInt:InterpolationLow], WebKitInterpolationQualityPreferenceKey,
556         [NSNumber numberWithBool:YES],    WebKitPasswordEchoEnabledPreferenceKey,
557         [NSNumber numberWithFloat:2.0f],  WebKitPasswordEchoDurationPreferenceKey,
558         [NSNumber numberWithBool:NO],     WebKitNetworkDataUsageTrackingEnabledPreferenceKey,
559         @"",                              WebKitNetworkInterfaceNamePreferenceKey,
560 #endif
561 #if ENABLE(IOS_TEXT_AUTOSIZING)
562         [NSNumber numberWithFloat:WKGetMinimumZoomFontSize()], WebKitMinimumZoomFontSizePreferenceKey,
563 #endif
564         [NSNumber numberWithLongLong:ApplicationCacheStorage::noQuota()], WebKitApplicationCacheTotalQuota,
565         [NSNumber numberWithLongLong:ApplicationCacheStorage::noQuota()], WebKitApplicationCacheDefaultOriginQuota,
566         [NSNumber numberWithBool:YES],  WebKitQTKitEnabledPreferenceKey,
567         [NSNumber numberWithBool:NO], WebKitHiddenPageDOMTimerThrottlingEnabledPreferenceKey,
568         [NSNumber numberWithBool:NO], WebKitHiddenPageCSSAnimationSuspensionEnabledPreferenceKey,
569         [NSNumber numberWithBool:NO], WebKitLowPowerVideoAudioBufferSizeEnabledPreferenceKey,
570         
571         [NSNumber numberWithBool:NO], WebKitUseLegacyTextAlignPositionedElementBehaviorPreferenceKey,
572 #if ENABLE(MEDIA_SOURCE)
573         [NSNumber numberWithBool:YES], WebKitMediaSourceEnabledPreferenceKey,
574 #endif
575 #if ENABLE(SERVICE_CONTROLS)
576         [NSNumber numberWithBool:NO], WebKitImageControlsEnabledPreferenceKey,
577         [NSNumber numberWithBool:NO], WebKitServiceControlsEnabledPreferenceKey,
578 #endif
579         [NSNumber numberWithBool:NO], WebKitEnableInheritURIQueryComponentPreferenceKey,
580 #if ENABLE(ENCRYPTED_MEDIA_V2)
581         @"~/Library/WebKit/MediaKeys", WebKitMediaKeysStorageDirectoryKey,
582 #endif
583         nil];
584
585 #if !PLATFORM(IOS)
586     // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above
587     ASSERT(kPDFDisplaySinglePageContinuous == 1);
588 #endif
589     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
590 }
591
592 - (void)dealloc
593 {
594     [self _updatePrivateBrowsingStateTo:NO];
595
596     delete _private;
597     [super dealloc];
598 }
599
600 - (NSString *)identifier
601 {
602     return _private->identifier.get();
603 }
604
605 - (id)_valueForKey:(NSString *)key
606 {
607     NSString *_key = KEY(key);
608 #if PLATFORM(IOS)
609     __block id o = nil;
610     dispatch_sync(_private->readWriteQueue, ^{
611         o = [_private->values.get() objectForKey:_key];
612     });
613 #else
614     id o = [_private->values.get() objectForKey:_key];
615 #endif
616     if (o)
617         return o;
618     o = [[NSUserDefaults standardUserDefaults] objectForKey:_key];
619     if (!o && key != _key)
620         o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
621     return o;
622 }
623
624 - (NSString *)_stringValueForKey:(NSString *)key
625 {
626     id s = [self _valueForKey:key];
627     return [s isKindOfClass:[NSString class]] ? (NSString *)s : nil;
628 }
629
630 - (void)_setStringValue:(NSString *)value forKey:(NSString *)key
631 {
632     if ([[self _stringValueForKey:key] isEqualToString:value])
633         return;
634     NSString *_key = KEY(key);
635 #if PLATFORM(IOS)
636     dispatch_barrier_sync(_private->readWriteQueue, ^{
637 #endif
638     [_private->values.get() setObject:value forKey:_key];
639 #if PLATFORM(IOS)
640     });
641 #endif
642     if (_private->autosaves)
643         [[NSUserDefaults standardUserDefaults] setObject:value forKey:_key];
644     [self _postPreferencesChangedNotification];
645 }
646
647 - (int)_integerValueForKey:(NSString *)key
648 {
649     id o = [self _valueForKey:key];
650     return [o respondsToSelector:@selector(intValue)] ? [o intValue] : 0;
651 }
652
653 - (void)_setIntegerValue:(int)value forKey:(NSString *)key
654 {
655     if ([self _integerValueForKey:key] == value)
656         return;
657     NSString *_key = KEY(key);
658 #if PLATFORM(IOS)
659     dispatch_barrier_sync(_private->readWriteQueue, ^{
660 #endif
661     [_private->values.get() _webkit_setInt:value forKey:_key];
662 #if PLATFORM(IOS)
663     });
664 #endif
665     if (_private->autosaves)
666         [[NSUserDefaults standardUserDefaults] setInteger:value forKey:_key];
667     [self _postPreferencesChangedNotification];
668 }
669
670 - (unsigned int)_unsignedIntValueForKey:(NSString *)key
671 {
672     id o = [self _valueForKey:key];
673     return [o respondsToSelector:@selector(unsignedIntValue)] ? [o unsignedIntValue] : 0;
674 }
675
676 - (void)_setUnsignedIntValue:(unsigned int)value forKey:(NSString *)key
677 {    if ([self _unsignedIntValueForKey:key] == value)
678         return;
679     NSString *_key = KEY(key);
680 #if PLATFORM(IOS)
681     dispatch_barrier_sync(_private->readWriteQueue, ^{
682 #endif
683     [_private->values.get() _webkit_setUnsignedInt:value forKey:_key];
684 #if PLATFORM(IOS)
685     });
686 #endif
687     if (_private->autosaves)
688         [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedInt:value] forKey:_key];
689     [self _postPreferencesChangedNotification];
690 }
691
692 - (float)_floatValueForKey:(NSString *)key
693 {
694     id o = [self _valueForKey:key];
695     return [o respondsToSelector:@selector(floatValue)] ? [o floatValue] : 0.0f;
696 }
697
698 - (void)_setFloatValue:(float)value forKey:(NSString *)key
699 {
700     if ([self _floatValueForKey:key] == value)
701         return;
702     NSString *_key = KEY(key);
703 #if PLATFORM(IOS)
704     dispatch_barrier_sync(_private->readWriteQueue, ^{
705 #endif
706     [_private->values.get() _webkit_setFloat:value forKey:_key];
707 #if PLATFORM(IOS)
708     });
709 #endif
710     if (_private->autosaves)
711         [[NSUserDefaults standardUserDefaults] setFloat:value forKey:_key];
712     [self _postPreferencesChangedNotification];
713 }
714
715 - (BOOL)_boolValueForKey:(NSString *)key
716 {
717     return [self _integerValueForKey:key] != 0;
718 }
719
720 - (void)_setBoolValue:(BOOL)value forKey:(NSString *)key
721 {
722     if ([self _boolValueForKey:key] == value)
723         return;
724     NSString *_key = KEY(key);
725 #if PLATFORM(IOS)
726     dispatch_barrier_sync(_private->readWriteQueue, ^{
727 #endif
728     [_private->values.get() _webkit_setBool:value forKey:_key];
729 #if PLATFORM(IOS)
730     });
731 #endif
732     if (_private->autosaves)
733         [[NSUserDefaults standardUserDefaults] setBool:value forKey:_key];
734     [self _postPreferencesChangedNotification];
735 }
736
737 - (long long)_longLongValueForKey:(NSString *)key
738 {
739     id o = [self _valueForKey:key];
740     return [o respondsToSelector:@selector(longLongValue)] ? [o longLongValue] : 0;
741 }
742
743 - (void)_setLongLongValue:(long long)value forKey:(NSString *)key
744 {
745     if ([self _longLongValueForKey:key] == value)
746         return;
747     NSString *_key = KEY(key);
748 #if PLATFORM(IOS)
749     dispatch_barrier_sync(_private->readWriteQueue, ^{
750 #endif
751     [_private->values.get() _webkit_setLongLong:value forKey:_key];
752 #if PLATFORM(IOS)
753     });
754 #endif
755     if (_private->autosaves)
756         [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithLongLong:value] forKey:_key];
757     [self _postPreferencesChangedNotification];
758 }
759
760 - (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key
761 {
762     id o = [self _valueForKey:key];
763     return [o respondsToSelector:@selector(unsignedLongLongValue)] ? [o unsignedLongLongValue] : 0;
764 }
765
766 - (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key
767 {
768     if ([self _unsignedLongLongValueForKey:key] == value)
769         return;
770     NSString *_key = KEY(key);
771 #if PLATFORM(IOS)
772     dispatch_barrier_sync(_private->readWriteQueue, ^{
773 #endif
774     [_private->values.get() _webkit_setUnsignedLongLong:value forKey:_key];
775 #if PLATFORM(IOS)
776     });
777 #endif
778     if (_private->autosaves)
779         [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithUnsignedLongLong:value] forKey:_key];
780     [self _postPreferencesChangedNotification];
781 }
782
783 - (NSString *)standardFontFamily
784 {
785     return [self _stringValueForKey: WebKitStandardFontPreferenceKey];
786 }
787
788 - (void)setStandardFontFamily:(NSString *)family
789 {
790     [self _setStringValue: family forKey: WebKitStandardFontPreferenceKey];
791 }
792
793 - (NSString *)fixedFontFamily
794 {
795     return [self _stringValueForKey: WebKitFixedFontPreferenceKey];
796 }
797
798 - (void)setFixedFontFamily:(NSString *)family
799 {
800     [self _setStringValue: family forKey: WebKitFixedFontPreferenceKey];
801 }
802
803 - (NSString *)serifFontFamily
804 {
805     return [self _stringValueForKey: WebKitSerifFontPreferenceKey];
806 }
807
808 - (void)setSerifFontFamily:(NSString *)family 
809 {
810     [self _setStringValue: family forKey: WebKitSerifFontPreferenceKey];
811 }
812
813 - (NSString *)sansSerifFontFamily
814 {
815     return [self _stringValueForKey: WebKitSansSerifFontPreferenceKey];
816 }
817
818 - (void)setSansSerifFontFamily:(NSString *)family
819 {
820     [self _setStringValue: family forKey: WebKitSansSerifFontPreferenceKey];
821 }
822
823 - (NSString *)cursiveFontFamily
824 {
825     return [self _stringValueForKey: WebKitCursiveFontPreferenceKey];
826 }
827
828 - (void)setCursiveFontFamily:(NSString *)family
829 {
830     [self _setStringValue: family forKey: WebKitCursiveFontPreferenceKey];
831 }
832
833 - (NSString *)fantasyFontFamily
834 {
835     return [self _stringValueForKey: WebKitFantasyFontPreferenceKey];
836 }
837
838 - (void)setFantasyFontFamily:(NSString *)family
839 {
840     [self _setStringValue: family forKey: WebKitFantasyFontPreferenceKey];
841 }
842
843 - (int)defaultFontSize
844 {
845     return [self _integerValueForKey: WebKitDefaultFontSizePreferenceKey];
846 }
847
848 - (void)setDefaultFontSize:(int)size
849 {
850     [self _setIntegerValue: size forKey: WebKitDefaultFontSizePreferenceKey];
851 }
852
853 - (int)defaultFixedFontSize
854 {
855     return [self _integerValueForKey: WebKitDefaultFixedFontSizePreferenceKey];
856 }
857
858 - (void)setDefaultFixedFontSize:(int)size
859 {
860     [self _setIntegerValue: size forKey: WebKitDefaultFixedFontSizePreferenceKey];
861 }
862
863 - (int)minimumFontSize
864 {
865     return [self _integerValueForKey: WebKitMinimumFontSizePreferenceKey];
866 }
867
868 - (void)setMinimumFontSize:(int)size
869 {
870     [self _setIntegerValue: size forKey: WebKitMinimumFontSizePreferenceKey];
871 }
872
873 - (int)minimumLogicalFontSize
874 {
875   return [self _integerValueForKey: WebKitMinimumLogicalFontSizePreferenceKey];
876 }
877
878 - (void)setMinimumLogicalFontSize:(int)size
879 {
880   [self _setIntegerValue: size forKey: WebKitMinimumLogicalFontSizePreferenceKey];
881 }
882
883 - (NSString *)defaultTextEncodingName
884 {
885     return [self _stringValueForKey: WebKitDefaultTextEncodingNamePreferenceKey];
886 }
887
888 - (void)setDefaultTextEncodingName:(NSString *)encoding
889 {
890     [self _setStringValue: encoding forKey: WebKitDefaultTextEncodingNamePreferenceKey];
891 }
892
893 #if !PLATFORM(IOS)
894 - (BOOL)userStyleSheetEnabled
895 {
896     return [self _boolValueForKey: WebKitUserStyleSheetEnabledPreferenceKey];
897 }
898
899 - (void)setUserStyleSheetEnabled:(BOOL)flag
900 {
901     [self _setBoolValue: flag forKey: WebKitUserStyleSheetEnabledPreferenceKey];
902 }
903
904 - (NSURL *)userStyleSheetLocation
905 {
906     NSString *locationString = [self _stringValueForKey: WebKitUserStyleSheetLocationPreferenceKey];
907     
908     if ([locationString _webkit_looksLikeAbsoluteURL]) {
909         return [NSURL _web_URLWithDataAsString:locationString];
910     } else {
911         locationString = [locationString stringByExpandingTildeInPath];
912         return [NSURL fileURLWithPath:locationString];
913     }
914 }
915
916 - (void)setUserStyleSheetLocation:(NSURL *)URL
917 {
918     NSString *locationString;
919     
920     if ([URL isFileURL]) {
921         locationString = [[URL path] _web_stringByAbbreviatingWithTildeInPath];
922     } else {
923         locationString = [URL _web_originalDataAsString];
924     }
925
926     if (!locationString)
927         locationString = @"";
928
929     [self _setStringValue:locationString forKey: WebKitUserStyleSheetLocationPreferenceKey];
930 }
931 #else
932
933 // These methods have had their implementations removed on iOS since it
934 // is wrong to have such a setting stored in preferences that, when read,
935 // is applied to all WebViews in a iOS process. Such a design might work
936 // OK for an application like Safari on Mac OS X, where the only WebViews
937 // in use display web content in a straightforward manner. However, it is
938 // wrong for iOS, where WebViews are used for various purposes, like
939 // text editing, text rendering, and displaying web content.
940 // 
941 // I have changed the user style sheet mechanism to be a per-WebView
942 // setting, rather than a per-process preference. This seems to give the
943 // behavior we want for iOS.
944
945 - (BOOL)userStyleSheetEnabled
946 {
947     return NO;
948 }
949
950 - (void)setUserStyleSheetEnabled:(BOOL)flag
951 {
952     // no-op
953 }
954
955 - (NSURL *)userStyleSheetLocation
956 {
957     return nil;
958 }
959
960 - (void)setUserStyleSheetLocation:(NSURL *)URL
961 {
962     // no-op
963 }
964 #endif // PLATFORM(IOS)
965
966 #if !PLATFORM(IOS)
967 - (BOOL)shouldPrintBackgrounds
968 {
969     return [self _boolValueForKey: WebKitShouldPrintBackgroundsPreferenceKey];
970 }
971
972 - (void)setShouldPrintBackgrounds:(BOOL)flag
973 {
974     [self _setBoolValue: flag forKey: WebKitShouldPrintBackgroundsPreferenceKey];
975 }
976 #endif
977
978 - (BOOL)isJavaEnabled
979 {
980     return [self _boolValueForKey: WebKitJavaEnabledPreferenceKey];
981 }
982
983 - (void)setJavaEnabled:(BOOL)flag
984 {
985     [self _setBoolValue: flag forKey: WebKitJavaEnabledPreferenceKey];
986 }
987
988 - (BOOL)isJavaScriptEnabled
989 {
990     return [self _boolValueForKey: WebKitJavaScriptEnabledPreferenceKey];
991 }
992
993 - (void)setJavaScriptEnabled:(BOOL)flag
994 {
995     [self _setBoolValue: flag forKey: WebKitJavaScriptEnabledPreferenceKey];
996 }
997
998 - (BOOL)javaScriptCanOpenWindowsAutomatically
999 {
1000     return [self _boolValueForKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
1001 }
1002
1003 - (void)setJavaScriptCanOpenWindowsAutomatically:(BOOL)flag
1004 {
1005     [self _setBoolValue: flag forKey: WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey];
1006 }
1007
1008 - (BOOL)arePlugInsEnabled
1009 {
1010     return [self _boolValueForKey: WebKitPluginsEnabledPreferenceKey];
1011 }
1012
1013 - (void)setPlugInsEnabled:(BOOL)flag
1014 {
1015     [self _setBoolValue: flag forKey: WebKitPluginsEnabledPreferenceKey];
1016 }
1017
1018 - (BOOL)allowsAnimatedImages
1019 {
1020     return [self _boolValueForKey: WebKitAllowAnimatedImagesPreferenceKey];
1021 }
1022
1023 - (void)setAllowsAnimatedImages:(BOOL)flag
1024 {
1025     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImagesPreferenceKey];
1026 }
1027
1028 - (BOOL)allowsAnimatedImageLooping
1029 {
1030     return [self _boolValueForKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
1031 }
1032
1033 - (void)setAllowsAnimatedImageLooping: (BOOL)flag
1034 {
1035     [self _setBoolValue: flag forKey: WebKitAllowAnimatedImageLoopingPreferenceKey];
1036 }
1037
1038 - (void)setLoadsImagesAutomatically: (BOOL)flag
1039 {
1040     [self _setBoolValue: flag forKey: WebKitDisplayImagesKey];
1041 }
1042
1043 - (BOOL)loadsImagesAutomatically
1044 {
1045     return [self _boolValueForKey: WebKitDisplayImagesKey];
1046 }
1047
1048 - (void)setAutosaves:(BOOL)flag
1049 {
1050     _private->autosaves = flag;
1051 }
1052
1053 - (BOOL)autosaves
1054 {
1055     return _private->autosaves;
1056 }
1057
1058 #if !PLATFORM(IOS)
1059 - (void)setTabsToLinks:(BOOL)flag
1060 {
1061     [self _setBoolValue: flag forKey: WebKitTabToLinksPreferenceKey];
1062 }
1063
1064 - (BOOL)tabsToLinks
1065 {
1066     return [self _boolValueForKey:WebKitTabToLinksPreferenceKey];
1067 }
1068 #endif
1069
1070 - (void)setPrivateBrowsingEnabled:(BOOL)enabled
1071 {
1072     [self _updatePrivateBrowsingStateTo:enabled];
1073     [self _setBoolValue:enabled forKey:WebKitPrivateBrowsingEnabledPreferenceKey];
1074 }
1075
1076 - (BOOL)privateBrowsingEnabled
1077 {
1078     // Changes to private browsing defaults do not have effect on existing WebPreferences, and must be done through -setPrivateBrowsingEnabled.
1079     // This is needed to accurately track private browsing sessions in the process.
1080     return _private->inPrivateBrowsing;
1081 }
1082
1083 - (void)_updatePrivateBrowsingStateTo:(BOOL)enabled
1084 {
1085     if (!_private) {
1086         ASSERT(!enabled);
1087         return;
1088     }
1089
1090     if (enabled == _private->inPrivateBrowsing)
1091         return;
1092     if (enabled > _private->inPrivateBrowsing) {
1093         WebFrameNetworkingContext::ensurePrivateBrowsingSession();
1094         ++webPreferencesInstanceCountWithPrivateBrowsingEnabled;
1095     } else {
1096         ASSERT(webPreferencesInstanceCountWithPrivateBrowsingEnabled);
1097         --webPreferencesInstanceCountWithPrivateBrowsingEnabled;
1098         if (!webPreferencesInstanceCountWithPrivateBrowsingEnabled)
1099             WebFrameNetworkingContext::destroyPrivateBrowsingSession();
1100     }
1101     _private->inPrivateBrowsing = enabled;
1102 }
1103
1104 - (void)setUsesPageCache:(BOOL)usesPageCache
1105 {
1106     [self _setBoolValue:usesPageCache forKey:WebKitUsesPageCachePreferenceKey];
1107 }
1108
1109 - (BOOL)usesPageCache
1110 {
1111     return [self _boolValueForKey:WebKitUsesPageCachePreferenceKey];
1112 }
1113
1114 - (void)_postCacheModelChangedNotification
1115 {
1116 #if !PLATFORM(IOS)
1117     if (!pthread_main_np()) {
1118         [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1119         return;
1120     }
1121 #endif
1122
1123     [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesCacheModelChangedInternalNotification object:self userInfo:nil];
1124 }
1125
1126 - (void)setCacheModel:(WebCacheModel)cacheModel
1127 {
1128     [self _setIntegerValue:cacheModel forKey:WebKitCacheModelPreferenceKey];
1129     [self setAutomaticallyDetectsCacheModel:NO];
1130     [self _postCacheModelChangedNotification];
1131 }
1132
1133 - (WebCacheModel)cacheModel
1134 {
1135     return (WebCacheModel)[self _integerValueForKey:WebKitCacheModelPreferenceKey];
1136 }
1137
1138
1139 - (void)setSuppressesIncrementalRendering:(BOOL)suppressesIncrementalRendering
1140 {
1141     [self _setBoolValue:suppressesIncrementalRendering forKey:WebKitSuppressesIncrementalRenderingKey];
1142 }
1143
1144 - (BOOL)suppressesIncrementalRendering
1145 {
1146     return [self _boolValueForKey:WebKitSuppressesIncrementalRenderingKey];
1147 }
1148
1149 @end
1150
1151 @implementation WebPreferences (WebPrivate)
1152
1153 #if PLATFORM(IOS) && !(__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000)
1154 - (void) setWebInspectorServerEnabled:(BOOL)flag
1155 {
1156 }
1157 #endif
1158
1159 #if PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
1160 - (void)_setAllowCompositingLayerVisualDegradation:(BOOL)flag
1161 {
1162 }
1163 #endif
1164
1165 - (BOOL)isDNSPrefetchingEnabled
1166 {
1167     return [self _boolValueForKey:WebKitDNSPrefetchingEnabledPreferenceKey];
1168 }
1169
1170 - (void)setDNSPrefetchingEnabled:(BOOL)flag
1171 {
1172     [self _setBoolValue:flag forKey:WebKitDNSPrefetchingEnabledPreferenceKey];
1173 }
1174
1175 - (BOOL)developerExtrasEnabled
1176 {
1177     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
1178     if ([defaults boolForKey:@"DisableWebKitDeveloperExtras"])
1179         return NO;
1180 #ifdef NDEBUG
1181     if ([defaults boolForKey:@"WebKitDeveloperExtras"] || [defaults boolForKey:@"IncludeDebugMenu"])
1182         return YES;
1183     return [self _boolValueForKey:WebKitDeveloperExtrasEnabledPreferenceKey];
1184 #else
1185     return YES; // always enable in debug builds
1186 #endif
1187 }
1188
1189 - (WebKitJavaScriptRuntimeFlags)javaScriptRuntimeFlags
1190 {
1191     return static_cast<WebKitJavaScriptRuntimeFlags>([self _unsignedIntValueForKey:WebKitJavaScriptRuntimeFlagsPreferenceKey]);
1192 }
1193
1194 - (void)setJavaScriptRuntimeFlags:(WebKitJavaScriptRuntimeFlags)flags
1195 {
1196     [self _setUnsignedIntValue:flags forKey:WebKitJavaScriptRuntimeFlagsPreferenceKey];
1197 }
1198
1199 - (void)setDeveloperExtrasEnabled:(BOOL)flag
1200 {
1201     [self _setBoolValue:flag forKey:WebKitDeveloperExtrasEnabledPreferenceKey];
1202 }
1203
1204 - (BOOL)authorAndUserStylesEnabled
1205 {
1206     return [self _boolValueForKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
1207 }
1208
1209 - (void)setAuthorAndUserStylesEnabled:(BOOL)flag
1210 {
1211     [self _setBoolValue:flag forKey:WebKitAuthorAndUserStylesEnabledPreferenceKey];
1212 }
1213
1214 // FIXME: applicationChromeMode is no longer needed by ToT, but is still used in Safari 8.
1215 - (BOOL)applicationChromeModeEnabled
1216 {
1217     return NO;
1218 }
1219
1220 - (void)setApplicationChromeModeEnabled:(BOOL)flag
1221 {
1222 }
1223
1224 - (BOOL)domTimersThrottlingEnabled
1225 {
1226     return [self _boolValueForKey:WebKitDOMTimersThrottlingEnabledPreferenceKey];
1227 }
1228
1229 - (void)setDOMTimersThrottlingEnabled:(BOOL)flag
1230 {
1231     [self _setBoolValue:flag forKey:WebKitDOMTimersThrottlingEnabledPreferenceKey];
1232 }
1233
1234 - (BOOL)webArchiveDebugModeEnabled
1235 {
1236     return [self _boolValueForKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
1237 }
1238
1239 - (void)setWebArchiveDebugModeEnabled:(BOOL)flag
1240 {
1241     [self _setBoolValue:flag forKey:WebKitWebArchiveDebugModeEnabledPreferenceKey];
1242 }
1243
1244 - (BOOL)localFileContentSniffingEnabled
1245 {
1246     return [self _boolValueForKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
1247 }
1248
1249 - (void)setLocalFileContentSniffingEnabled:(BOOL)flag
1250 {
1251     [self _setBoolValue:flag forKey:WebKitLocalFileContentSniffingEnabledPreferenceKey];
1252 }
1253
1254 - (BOOL)offlineWebApplicationCacheEnabled
1255 {
1256     return [self _boolValueForKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
1257 }
1258
1259 - (void)setOfflineWebApplicationCacheEnabled:(BOOL)flag
1260 {
1261     [self _setBoolValue:flag forKey:WebKitOfflineWebApplicationCacheEnabledPreferenceKey];
1262 }
1263
1264 - (BOOL)zoomsTextOnly
1265 {
1266     return [self _boolValueForKey:WebKitZoomsTextOnlyPreferenceKey];
1267 }
1268
1269 - (void)setZoomsTextOnly:(BOOL)flag
1270 {
1271     [self _setBoolValue:flag forKey:WebKitZoomsTextOnlyPreferenceKey];
1272 }
1273
1274 - (BOOL)javaScriptCanAccessClipboard
1275 {
1276     return [self _boolValueForKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
1277 }
1278
1279 - (void)setJavaScriptCanAccessClipboard:(BOOL)flag
1280 {
1281     [self _setBoolValue:flag forKey:WebKitJavaScriptCanAccessClipboardPreferenceKey];
1282 }
1283
1284 - (BOOL)isXSSAuditorEnabled
1285 {
1286     return [self _boolValueForKey:WebKitXSSAuditorEnabledPreferenceKey];
1287 }
1288
1289 - (void)setXSSAuditorEnabled:(BOOL)flag
1290 {
1291     [self _setBoolValue:flag forKey:WebKitXSSAuditorEnabledPreferenceKey];
1292 }
1293
1294 #if !PLATFORM(IOS)
1295 - (BOOL)respectStandardStyleKeyEquivalents
1296 {
1297     return [self _boolValueForKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
1298 }
1299
1300 - (void)setRespectStandardStyleKeyEquivalents:(BOOL)flag
1301 {
1302     [self _setBoolValue:flag forKey:WebKitRespectStandardStyleKeyEquivalentsPreferenceKey];
1303 }
1304
1305 - (BOOL)showsURLsInToolTips
1306 {
1307     return [self _boolValueForKey:WebKitShowsURLsInToolTipsPreferenceKey];
1308 }
1309
1310 - (void)setShowsURLsInToolTips:(BOOL)flag
1311 {
1312     [self _setBoolValue:flag forKey:WebKitShowsURLsInToolTipsPreferenceKey];
1313 }
1314
1315 - (BOOL)showsToolTipOverTruncatedText
1316 {
1317     return [self _boolValueForKey:WebKitShowsToolTipOverTruncatedTextPreferenceKey];
1318 }
1319
1320 - (void)setShowsToolTipOverTruncatedText:(BOOL)flag
1321 {
1322     [self _setBoolValue:flag forKey:WebKitShowsToolTipOverTruncatedTextPreferenceKey];
1323 }
1324
1325 - (BOOL)textAreasAreResizable
1326 {
1327     return [self _boolValueForKey: WebKitTextAreasAreResizablePreferenceKey];
1328 }
1329
1330 - (void)setTextAreasAreResizable:(BOOL)flag
1331 {
1332     [self _setBoolValue: flag forKey: WebKitTextAreasAreResizablePreferenceKey];
1333 }
1334 #endif // !PLATFORM(IOS)
1335
1336 - (BOOL)shrinksStandaloneImagesToFit
1337 {
1338     return [self _boolValueForKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
1339 }
1340
1341 - (void)setShrinksStandaloneImagesToFit:(BOOL)flag
1342 {
1343     [self _setBoolValue:flag forKey:WebKitShrinksStandaloneImagesToFitPreferenceKey];
1344 }
1345
1346 - (BOOL)automaticallyDetectsCacheModel
1347 {
1348     return _private->automaticallyDetectsCacheModel;
1349 }
1350
1351 - (void)setAutomaticallyDetectsCacheModel:(BOOL)automaticallyDetectsCacheModel
1352 {
1353     _private->automaticallyDetectsCacheModel = automaticallyDetectsCacheModel;
1354 }
1355
1356 - (BOOL)usesEncodingDetector
1357 {
1358     return [self _boolValueForKey: WebKitUsesEncodingDetectorPreferenceKey];
1359 }
1360
1361 - (void)setUsesEncodingDetector:(BOOL)flag
1362 {
1363     [self _setBoolValue: flag forKey: WebKitUsesEncodingDetectorPreferenceKey];
1364 }
1365
1366 - (BOOL)isWebSecurityEnabled
1367 {
1368     return [self _boolValueForKey: WebKitWebSecurityEnabledPreferenceKey];
1369 }
1370
1371 - (void)setWebSecurityEnabled:(BOOL)flag
1372 {
1373     [self _setBoolValue: flag forKey: WebKitWebSecurityEnabledPreferenceKey];
1374 }
1375
1376 - (BOOL)allowUniversalAccessFromFileURLs
1377 {
1378     return [self _boolValueForKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
1379 }
1380
1381 - (void)setAllowUniversalAccessFromFileURLs:(BOOL)flag
1382 {
1383     [self _setBoolValue: flag forKey: WebKitAllowUniversalAccessFromFileURLsPreferenceKey];
1384 }
1385
1386 - (BOOL)allowFileAccessFromFileURLs
1387 {
1388     return [self _boolValueForKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
1389 }
1390
1391 - (void)setAllowFileAccessFromFileURLs:(BOOL)flag
1392 {
1393     [self _setBoolValue: flag forKey: WebKitAllowFileAccessFromFileURLsPreferenceKey];
1394 }
1395
1396 - (NSTimeInterval)_backForwardCacheExpirationInterval
1397 {
1398     return (NSTimeInterval)[self _floatValueForKey:WebKitBackForwardCacheExpirationIntervalKey];
1399 }
1400
1401 #if PLATFORM(IOS)
1402 - (BOOL)_standalone
1403 {
1404     return [self _boolValueForKey:WebKitStandalonePreferenceKey];
1405 }
1406
1407 - (void)_setStandalone:(BOOL)flag
1408 {
1409     [self _setBoolValue:flag forKey:WebKitStandalonePreferenceKey];
1410 }
1411
1412 - (void)_setTelephoneNumberParsingEnabled:(BOOL)flag
1413 {
1414     [self _setBoolValue:flag forKey:WebKitTelephoneParsingEnabledPreferenceKey];
1415 }
1416
1417 - (BOOL)_telephoneNumberParsingEnabled
1418 {
1419     return [self _boolValueForKey:WebKitTelephoneParsingEnabledPreferenceKey];
1420 }
1421 #endif
1422
1423 #if ENABLE(IOS_TEXT_AUTOSIZING)
1424 - (void)_setMinimumZoomFontSize:(float)size
1425 {
1426     [self _setFloatValue:size forKey:WebKitMinimumZoomFontSizePreferenceKey];
1427 }
1428
1429 - (float)_minimumZoomFontSize
1430 {
1431     return [self _floatValueForKey:WebKitMinimumZoomFontSizePreferenceKey];
1432 }
1433 #endif
1434
1435 #if PLATFORM(IOS)
1436 - (void)_setLayoutInterval:(int)l
1437 {
1438     [self _setIntegerValue:l forKey:WebKitLayoutIntervalPreferenceKey];
1439 }
1440
1441 - (int)_layoutInterval
1442 {
1443     return [self _integerValueForKey:WebKitLayoutIntervalPreferenceKey];
1444 }
1445
1446 - (void)_setMaxParseDuration:(float)d
1447 {
1448     [self _setFloatValue:d forKey:WebKitMaxParseDurationPreferenceKey];
1449 }
1450
1451 - (float)_maxParseDuration
1452 {
1453     return [self _floatValueForKey:WebKitMaxParseDurationPreferenceKey];
1454 }
1455
1456 - (void)_setAllowMultiElementImplicitFormSubmission:(BOOL)flag
1457 {
1458     [self _setBoolValue:flag forKey:WebKitAllowMultiElementImplicitFormSubmissionPreferenceKey];
1459 }
1460
1461 - (BOOL)_allowMultiElementImplicitFormSubmission
1462 {
1463     return [self _boolValueForKey:WebKitAllowMultiElementImplicitFormSubmissionPreferenceKey];
1464 }
1465
1466 - (void)_setAlwaysRequestGeolocationPermission:(BOOL)flag
1467 {
1468     [self _setBoolValue:flag forKey:WebKitAlwaysRequestGeolocationPermissionPreferenceKey];
1469 }
1470
1471 - (BOOL)_alwaysRequestGeolocationPermission
1472 {
1473     return [self _boolValueForKey:WebKitAlwaysRequestGeolocationPermissionPreferenceKey];
1474 }
1475
1476 - (void)_setAlwaysUseAcceleratedOverflowScroll:(BOOL)flag
1477 {
1478     [self _setBoolValue:flag forKey:WebKitAlwaysUseAcceleratedOverflowScrollPreferenceKey];
1479 }
1480
1481 - (BOOL)_alwaysUseAcceleratedOverflowScroll
1482 {
1483     return [self _boolValueForKey:WebKitAlwaysUseAcceleratedOverflowScrollPreferenceKey];
1484 }
1485
1486 - (void)_setInterpolationQuality:(int)quality
1487 {
1488     [self _setIntegerValue:quality forKey:WebKitInterpolationQualityPreferenceKey];
1489 }
1490
1491 - (int)_interpolationQuality
1492 {
1493     return [self _integerValueForKey:WebKitInterpolationQualityPreferenceKey];
1494 }
1495
1496 - (BOOL)_allowPasswordEcho
1497 {
1498     return [self _boolValueForKey:WebKitPasswordEchoEnabledPreferenceKey];
1499 }
1500
1501 - (float)_passwordEchoDuration
1502 {
1503     return [self _floatValueForKey:WebKitPasswordEchoDurationPreferenceKey];
1504 }
1505
1506 #endif // PLATFORM(IOS)
1507
1508 #if !PLATFORM(IOS)
1509 - (float)PDFScaleFactor
1510 {
1511     return [self _floatValueForKey:WebKitPDFScaleFactorPreferenceKey];
1512 }
1513
1514 - (void)setPDFScaleFactor:(float)factor
1515 {
1516     [self _setFloatValue:factor forKey:WebKitPDFScaleFactorPreferenceKey];
1517 }
1518 #endif
1519
1520 - (int64_t)applicationCacheTotalQuota
1521 {
1522     return [self _longLongValueForKey:WebKitApplicationCacheTotalQuota];
1523 }
1524
1525 - (void)setApplicationCacheTotalQuota:(int64_t)quota
1526 {
1527     [self _setLongLongValue:quota forKey:WebKitApplicationCacheTotalQuota];
1528
1529     // Application Cache Preferences are stored on the global cache storage manager, not in Settings.
1530     [WebApplicationCache setMaximumSize:quota];
1531 }
1532
1533 - (int64_t)applicationCacheDefaultOriginQuota
1534 {
1535     return [self _longLongValueForKey:WebKitApplicationCacheDefaultOriginQuota];
1536 }
1537
1538 - (void)setApplicationCacheDefaultOriginQuota:(int64_t)quota
1539 {
1540     [self _setLongLongValue:quota forKey:WebKitApplicationCacheDefaultOriginQuota];
1541 }
1542
1543 #if !PLATFORM(IOS)
1544 - (PDFDisplayMode)PDFDisplayMode
1545 {
1546     PDFDisplayMode value = [self _integerValueForKey:WebKitPDFDisplayModePreferenceKey];
1547     if (value != kPDFDisplaySinglePage && value != kPDFDisplaySinglePageContinuous && value != kPDFDisplayTwoUp && value != kPDFDisplayTwoUpContinuous) {
1548         // protect against new modes from future versions of OS X stored in defaults
1549         value = kPDFDisplaySinglePageContinuous;
1550     }
1551     return value;
1552 }
1553
1554 - (void)setPDFDisplayMode:(PDFDisplayMode)mode
1555 {
1556     [self _setIntegerValue:mode forKey:WebKitPDFDisplayModePreferenceKey];
1557 }
1558 #endif
1559
1560 - (WebKitEditableLinkBehavior)editableLinkBehavior
1561 {
1562     WebKitEditableLinkBehavior value = static_cast<WebKitEditableLinkBehavior> ([self _integerValueForKey:WebKitEditableLinkBehaviorPreferenceKey]);
1563     if (value != WebKitEditableLinkDefaultBehavior &&
1564         value != WebKitEditableLinkAlwaysLive &&
1565         value != WebKitEditableLinkNeverLive &&
1566         value != WebKitEditableLinkOnlyLiveWithShiftKey &&
1567         value != WebKitEditableLinkLiveWhenNotFocused) {
1568         // ensure that a valid result is returned
1569         value = WebKitEditableLinkDefaultBehavior;
1570     }
1571     
1572     return value;
1573 }
1574
1575 - (void)setEditableLinkBehavior:(WebKitEditableLinkBehavior)behavior
1576 {
1577     [self _setIntegerValue:behavior forKey:WebKitEditableLinkBehaviorPreferenceKey];
1578 }
1579
1580 - (WebTextDirectionSubmenuInclusionBehavior)textDirectionSubmenuInclusionBehavior
1581 {
1582     WebTextDirectionSubmenuInclusionBehavior value = static_cast<WebTextDirectionSubmenuInclusionBehavior>([self _integerValueForKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey]);
1583     if (value != WebTextDirectionSubmenuNeverIncluded &&
1584         value != WebTextDirectionSubmenuAutomaticallyIncluded &&
1585         value != WebTextDirectionSubmenuAlwaysIncluded) {
1586         // Ensure that a valid result is returned.
1587         value = WebTextDirectionSubmenuNeverIncluded;
1588     }
1589     return value;
1590 }
1591
1592 - (void)setTextDirectionSubmenuInclusionBehavior:(WebTextDirectionSubmenuInclusionBehavior)behavior
1593 {
1594     [self _setIntegerValue:behavior forKey:WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey];
1595 }
1596
1597 - (BOOL)_useSiteSpecificSpoofing
1598 {
1599     return [self _boolValueForKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1600 }
1601
1602 - (void)_setUseSiteSpecificSpoofing:(BOOL)newValue
1603 {
1604     [self _setBoolValue:newValue forKey:WebKitUseSiteSpecificSpoofingPreferenceKey];
1605 }
1606
1607 - (BOOL)databasesEnabled
1608 {
1609     return [self _boolValueForKey:WebKitDatabasesEnabledPreferenceKey];
1610 }
1611
1612 - (void)setDatabasesEnabled:(BOOL)databasesEnabled
1613 {
1614     [self _setBoolValue:databasesEnabled forKey:WebKitDatabasesEnabledPreferenceKey];
1615 }
1616
1617 #if PLATFORM(IOS)
1618 - (BOOL)storageTrackerEnabled
1619 {
1620     return [self _boolValueForKey:WebKitStorageTrackerEnabledPreferenceKey];
1621 }
1622
1623 - (void)setStorageTrackerEnabled:(BOOL)storageTrackerEnabled
1624 {
1625     [self _setBoolValue:storageTrackerEnabled forKey:WebKitStorageTrackerEnabledPreferenceKey];
1626 }
1627 #endif
1628
1629 - (BOOL)localStorageEnabled
1630 {
1631     return [self _boolValueForKey:WebKitLocalStorageEnabledPreferenceKey];
1632 }
1633
1634 - (void)setLocalStorageEnabled:(BOOL)localStorageEnabled
1635 {
1636     [self _setBoolValue:localStorageEnabled forKey:WebKitLocalStorageEnabledPreferenceKey];
1637 }
1638
1639 - (BOOL)experimentalNotificationsEnabled
1640 {
1641     return [self _boolValueForKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1642 }
1643
1644 - (void)setExperimentalNotificationsEnabled:(BOOL)experimentalNotificationsEnabled
1645 {
1646     [self _setBoolValue:experimentalNotificationsEnabled forKey:WebKitExperimentalNotificationsEnabledPreferenceKey];
1647 }
1648
1649 + (WebPreferences *)_getInstanceForIdentifier:(NSString *)ident
1650 {
1651     LOG(Encoding, "requesting for %@\n", ident);
1652
1653     if (!ident)
1654         return _standardPreferences;
1655     
1656     WebPreferences *instance = [webPreferencesInstances objectForKey:[self _concatenateKeyWithIBCreatorID:ident]];
1657
1658     return instance;
1659 }
1660
1661 + (void)_setInstance:(WebPreferences *)instance forIdentifier:(NSString *)ident
1662 {
1663     if (!webPreferencesInstances)
1664         webPreferencesInstances = [[NSMutableDictionary alloc] init];
1665     if (ident) {
1666         [webPreferencesInstances setObject:instance forKey:[self _concatenateKeyWithIBCreatorID:ident]];
1667         LOG(Encoding, "recording %p for %@\n", instance, [self _concatenateKeyWithIBCreatorID:ident]);
1668     }
1669 }
1670
1671 + (void)_checkLastReferenceForIdentifier:(id)identifier
1672 {
1673     // FIXME: This won't work at all under garbage collection because retainCount returns a constant.
1674     // We may need to change WebPreferences API so there's an explicit way to end the lifetime of one.
1675     WebPreferences *instance = [webPreferencesInstances objectForKey:identifier];
1676     if ([instance retainCount] == 1)
1677         [webPreferencesInstances removeObjectForKey:identifier];
1678 }
1679
1680 + (void)_removeReferenceForIdentifier:(NSString *)ident
1681 {
1682     if (ident)
1683         [self performSelector:@selector(_checkLastReferenceForIdentifier:) withObject:[self _concatenateKeyWithIBCreatorID:ident] afterDelay:0.1];
1684 }
1685
1686 - (void)_postPreferencesChangedNotification
1687 {
1688 #if !PLATFORM(IOS)
1689     if (!pthread_main_np()) {
1690         [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1691         return;
1692     }
1693 #endif
1694
1695     [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedInternalNotification object:self userInfo:nil];
1696     [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
1697 }
1698
1699 - (void)_postPreferencesChangedAPINotification
1700 {
1701     if (!pthread_main_np()) {
1702         [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
1703         return;
1704     }
1705
1706     [[NSNotificationCenter defaultCenter] postNotificationName:WebPreferencesChangedNotification object:self userInfo:nil];
1707 }
1708
1709 + (CFStringEncoding)_systemCFStringEncoding
1710 {
1711     return WKGetWebDefaultCFStringEncoding();
1712 }
1713
1714 + (void)_setInitialDefaultTextEncodingToSystemEncoding
1715 {
1716     [[NSUserDefaults standardUserDefaults] registerDefaults:
1717         [NSDictionary dictionaryWithObject:defaultTextEncodingNameForSystemLanguage() forKey:WebKitDefaultTextEncodingNamePreferenceKey]];
1718 }
1719
1720 static NSString *classIBCreatorID = nil;
1721
1722 + (void)_setIBCreatorID:(NSString *)string
1723 {
1724     NSString *old = classIBCreatorID;
1725     classIBCreatorID = [string copy];
1726     [old release];
1727 }
1728
1729 + (void)_switchNetworkLoaderToNewTestingSession
1730 {
1731     NetworkStorageSession::switchToNewTestingSession();
1732 }
1733
1734 + (void)_clearNetworkLoaderSession
1735 {
1736     WebCore::deleteAllCookies(NetworkStorageSession::defaultStorageSession());
1737 }
1738
1739 + (void)_setCurrentNetworkLoaderSessionCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)policy
1740 {
1741     WKSetHTTPCookieAcceptPolicy(NetworkStorageSession::defaultStorageSession().cookieStorage().get(), policy);
1742 }
1743
1744 - (BOOL)isDOMPasteAllowed
1745 {
1746     return [self _boolValueForKey:WebKitDOMPasteAllowedPreferenceKey];
1747 }
1748
1749 - (void)setDOMPasteAllowed:(BOOL)DOMPasteAllowed
1750 {
1751     [self _setBoolValue:DOMPasteAllowed forKey:WebKitDOMPasteAllowedPreferenceKey];
1752 }
1753
1754 - (NSString *)_localStorageDatabasePath
1755 {
1756     return [[self _stringValueForKey:WebKitLocalStorageDatabasePathPreferenceKey] stringByStandardizingPath];
1757 }
1758
1759 - (void)_setLocalStorageDatabasePath:(NSString *)path
1760 {
1761     [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitLocalStorageDatabasePathPreferenceKey];
1762 }
1763
1764 - (NSString *)_ftpDirectoryTemplatePath
1765 {
1766     return [[self _stringValueForKey:WebKitFTPDirectoryTemplatePath] stringByStandardizingPath];
1767 }
1768
1769 - (void)_setFTPDirectoryTemplatePath:(NSString *)path
1770 {
1771     [self _setStringValue:[path stringByStandardizingPath] forKey:WebKitFTPDirectoryTemplatePath];
1772 }
1773
1774 - (BOOL)_forceFTPDirectoryListings
1775 {
1776     return [self _boolValueForKey:WebKitForceFTPDirectoryListings];
1777 }
1778
1779 - (void)_setForceFTPDirectoryListings:(BOOL)force
1780 {
1781     [self _setBoolValue:force forKey:WebKitForceFTPDirectoryListings];
1782 }
1783
1784 - (BOOL)acceleratedDrawingEnabled
1785 {
1786     return [self _boolValueForKey:WebKitAcceleratedDrawingEnabledPreferenceKey];
1787 }
1788
1789 - (void)setAcceleratedDrawingEnabled:(BOOL)enabled
1790 {
1791     [self _setBoolValue:enabled forKey:WebKitAcceleratedDrawingEnabledPreferenceKey];
1792 }
1793
1794 - (BOOL)canvasUsesAcceleratedDrawing
1795 {
1796     return [self _boolValueForKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey];
1797 }
1798
1799 - (void)setCanvasUsesAcceleratedDrawing:(BOOL)enabled
1800 {
1801     [self _setBoolValue:enabled forKey:WebKitCanvasUsesAcceleratedDrawingPreferenceKey];
1802 }
1803
1804 - (BOOL)acceleratedCompositingEnabled
1805 {
1806     return [self _boolValueForKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1807 }
1808
1809 - (void)setAcceleratedCompositingEnabled:(BOOL)enabled
1810 {
1811     [self _setBoolValue:enabled forKey:WebKitAcceleratedCompositingEnabledPreferenceKey];
1812 }
1813
1814 - (BOOL)cssRegionsEnabled
1815 {
1816     return [self _boolValueForKey:WebKitCSSRegionsEnabledPreferenceKey];
1817 }
1818
1819 - (void)setCSSRegionsEnabled:(BOOL)enabled
1820 {
1821     [self _setBoolValue:enabled forKey:WebKitCSSRegionsEnabledPreferenceKey];
1822 }
1823
1824 - (BOOL)cssCompositingEnabled
1825 {
1826     return [self _boolValueForKey:WebKitCSSCompositingEnabledPreferenceKey];
1827 }
1828
1829 - (void)setCSSCompositingEnabled:(BOOL)enabled
1830 {
1831     [self _setBoolValue:enabled forKey:WebKitCSSCompositingEnabledPreferenceKey];
1832 }
1833
1834 - (BOOL)showDebugBorders
1835 {
1836     return [self _boolValueForKey:WebKitShowDebugBordersPreferenceKey];
1837 }
1838
1839 - (void)setShowDebugBorders:(BOOL)enabled
1840 {
1841     [self _setBoolValue:enabled forKey:WebKitShowDebugBordersPreferenceKey];
1842 }
1843
1844 - (BOOL)simpleLineLayoutDebugBordersEnabled
1845 {
1846     return [self _boolValueForKey:WebKitSimpleLineLayoutDebugBordersEnabledPreferenceKey];
1847 }
1848
1849 - (void)setSimpleLineLayoutDebugBordersEnabled:(BOOL)enabled
1850 {
1851     [self _setBoolValue:enabled forKey:WebKitSimpleLineLayoutDebugBordersEnabledPreferenceKey];
1852 }
1853
1854 - (BOOL)showRepaintCounter
1855 {
1856     return [self _boolValueForKey:WebKitShowRepaintCounterPreferenceKey];
1857 }
1858
1859 - (void)setShowRepaintCounter:(BOOL)enabled
1860 {
1861     [self _setBoolValue:enabled forKey:WebKitShowRepaintCounterPreferenceKey];
1862 }
1863
1864 - (BOOL)webAudioEnabled
1865 {
1866     return [self _boolValueForKey:WebKitWebAudioEnabledPreferenceKey];
1867 }
1868
1869 - (void)setWebAudioEnabled:(BOOL)enabled
1870 {
1871     [self _setBoolValue:enabled forKey:WebKitWebAudioEnabledPreferenceKey];
1872 }
1873
1874 - (BOOL)subpixelCSSOMElementMetricsEnabled
1875 {
1876     return [self _boolValueForKey:WebKitSubpixelCSSOMElementMetricsEnabledPreferenceKey];
1877 }
1878
1879 - (void)setSubpixelCSSOMElementMetricsEnabled:(BOOL)enabled
1880 {
1881     [self _setBoolValue:enabled forKey:WebKitSubpixelCSSOMElementMetricsEnabledPreferenceKey];
1882 }
1883
1884 - (BOOL)webGLEnabled
1885 {
1886     return [self _boolValueForKey:WebKitWebGLEnabledPreferenceKey];
1887 }
1888
1889 - (void)setWebGLEnabled:(BOOL)enabled
1890 {
1891     [self _setBoolValue:enabled forKey:WebKitWebGLEnabledPreferenceKey];
1892 }
1893
1894 - (BOOL)forceSoftwareWebGLRendering
1895 {
1896     return [self _boolValueForKey:WebKitForceSoftwareWebGLRenderingPreferenceKey];
1897 }
1898
1899 - (void)setForceSoftwareWebGLRendering:(BOOL)forced
1900 {
1901     [self _setBoolValue:forced forKey:WebKitForceSoftwareWebGLRenderingPreferenceKey];
1902 }
1903
1904 - (BOOL)accelerated2dCanvasEnabled
1905 {
1906     return [self _boolValueForKey:WebKitAccelerated2dCanvasEnabledPreferenceKey];
1907 }
1908
1909 - (void)setAccelerated2dCanvasEnabled:(BOOL)enabled
1910 {
1911     [self _setBoolValue:enabled forKey:WebKitAccelerated2dCanvasEnabledPreferenceKey];
1912 }
1913
1914 - (void)setDiskImageCacheEnabled:(BOOL)enabled
1915 {
1916     // Staging. Can be removed once there are no more callers.
1917 }
1918
1919 - (BOOL)isFrameFlatteningEnabled
1920 {
1921     return [self _boolValueForKey:WebKitFrameFlatteningEnabledPreferenceKey];
1922 }
1923
1924 - (void)setFrameFlatteningEnabled:(BOOL)flag
1925 {
1926     [self _setBoolValue:flag forKey:WebKitFrameFlatteningEnabledPreferenceKey];
1927 }
1928
1929 - (BOOL)isSpatialNavigationEnabled
1930 {
1931     return [self _boolValueForKey:WebKitSpatialNavigationEnabledPreferenceKey];
1932 }
1933
1934 - (void)setSpatialNavigationEnabled:(BOOL)flag
1935 {
1936     [self _setBoolValue:flag forKey:WebKitSpatialNavigationEnabledPreferenceKey];
1937 }
1938
1939 - (BOOL)paginateDuringLayoutEnabled
1940 {
1941     return [self _boolValueForKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1942 }
1943
1944 - (void)setPaginateDuringLayoutEnabled:(BOOL)flag
1945 {
1946     [self _setBoolValue:flag forKey:WebKitPaginateDuringLayoutEnabledPreferenceKey];
1947 }
1948
1949 - (BOOL)hyperlinkAuditingEnabled
1950 {
1951     return [self _boolValueForKey:WebKitHyperlinkAuditingEnabledPreferenceKey];
1952 }
1953
1954 - (void)setHyperlinkAuditingEnabled:(BOOL)flag
1955 {
1956     [self _setBoolValue:flag forKey:WebKitHyperlinkAuditingEnabledPreferenceKey];
1957 }
1958
1959 - (BOOL)usePreHTML5ParserQuirks
1960 {
1961     return [self _boolValueForKey:WebKitUsePreHTML5ParserQuirksKey];
1962 }
1963
1964 - (void)setUsePreHTML5ParserQuirks:(BOOL)flag
1965 {
1966     [self _setBoolValue:flag forKey:WebKitUsePreHTML5ParserQuirksKey];
1967 }
1968
1969 - (void)didRemoveFromWebView
1970 {
1971     ASSERT(_private->numWebViews);
1972     if (--_private->numWebViews == 0)
1973         [[NSNotificationCenter defaultCenter]
1974             postNotificationName:WebPreferencesRemovedNotification
1975                           object:self
1976                         userInfo:nil];
1977 }
1978
1979 - (void)willAddToWebView
1980 {
1981     ++_private->numWebViews;
1982 }
1983
1984 - (void)_setPreferenceForTestWithValue:(NSString *)value forKey:(NSString *)key
1985 {
1986     [self _setStringValue:value forKey:key];
1987 }
1988
1989 - (void)setFullScreenEnabled:(BOOL)flag
1990 {
1991     [self _setBoolValue:flag forKey:WebKitFullScreenEnabledPreferenceKey];
1992 }
1993
1994 - (BOOL)fullScreenEnabled
1995 {
1996     return [self _boolValueForKey:WebKitFullScreenEnabledPreferenceKey];
1997 }
1998
1999 - (void)setAsynchronousSpellCheckingEnabled:(BOOL)flag
2000 {
2001     [self _setBoolValue:flag forKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey];
2002 }
2003
2004 - (BOOL)asynchronousSpellCheckingEnabled
2005 {
2006     return [self _boolValueForKey:WebKitAsynchronousSpellCheckingEnabledPreferenceKey];
2007 }
2008
2009 + (void)setWebKitLinkTimeVersion:(int)version
2010 {
2011     setWebKitLinkTimeVersion(version);
2012 }
2013
2014 - (void)setLoadsSiteIconsIgnoringImageLoadingPreference: (BOOL)flag
2015 {
2016     [self _setBoolValue: flag forKey: WebKitLoadSiteIconsKey];
2017 }
2018
2019 - (BOOL)loadsSiteIconsIgnoringImageLoadingPreference
2020 {
2021     return [self _boolValueForKey: WebKitLoadSiteIconsKey];
2022 }
2023
2024 - (void)setAVFoundationEnabled:(BOOL)flag
2025 {
2026     [self _setBoolValue:flag forKey:WebKitAVFoundationEnabledKey];
2027 }
2028
2029 - (BOOL)isAVFoundationEnabled
2030 {
2031     return [self _boolValueForKey:WebKitAVFoundationEnabledKey];
2032 }
2033
2034 - (void)setQTKitEnabled:(BOOL)flag
2035 {
2036     [self _setBoolValue:flag forKey:WebKitQTKitEnabledPreferenceKey];
2037 }
2038
2039 - (BOOL)isQTKitEnabled
2040 {
2041     return [self _boolValueForKey:WebKitQTKitEnabledPreferenceKey];
2042 }
2043
2044 - (void)setVideoPluginProxyEnabled:(BOOL)flag
2045 {
2046     // No-op, left for SPI compatibility.
2047 }
2048
2049 - (BOOL)isVideoPluginProxyEnabled
2050 {
2051     return NO;
2052 }
2053
2054 - (void)setHixie76WebSocketProtocolEnabled:(BOOL)flag
2055 {
2056 }
2057
2058 - (BOOL)isHixie76WebSocketProtocolEnabled
2059 {
2060     return false;
2061 }
2062
2063 - (BOOL)isInheritURIQueryComponentEnabled
2064 {
2065     return [self _boolValueForKey: WebKitEnableInheritURIQueryComponentPreferenceKey];
2066 }
2067
2068 - (void)setEnableInheritURIQueryComponent:(BOOL)flag
2069 {
2070     [self _setBoolValue:flag forKey: WebKitEnableInheritURIQueryComponentPreferenceKey];
2071 }
2072
2073 #if PLATFORM(IOS)
2074 - (BOOL)mediaPlaybackAllowsAirPlay
2075 {
2076     return [self _boolValueForKey:WebKitMediaPlaybackAllowsAirPlayPreferenceKey];
2077 }
2078
2079 - (void)setMediaPlaybackAllowsAirPlay:(BOOL)flag
2080 {
2081     [self _setBoolValue:flag forKey:WebKitMediaPlaybackAllowsAirPlayPreferenceKey];
2082 }
2083
2084 - (unsigned)audioSessionCategoryOverride
2085 {
2086     return [self _unsignedIntValueForKey:WebKitAudioSessionCategoryOverride];
2087 }
2088
2089 - (void)setAudioSessionCategoryOverride:(unsigned)override
2090 {
2091     if (override > AudioSession::AudioProcessing) {
2092         // Clients are passing us OSTypes values from AudioToolbox/AudioSession.h,
2093         // which need to be translated into AudioSession::CategoryType:
2094         switch (override) {
2095         case kAudioSessionCategory_AmbientSound:
2096             override = AudioSession::AmbientSound;
2097             break;
2098         case kAudioSessionCategory_SoloAmbientSound:
2099             override = AudioSession::SoloAmbientSound;
2100             break;
2101         case kAudioSessionCategory_MediaPlayback:
2102             override = AudioSession::MediaPlayback;
2103             break;
2104         case kAudioSessionCategory_RecordAudio:
2105             override = AudioSession::RecordAudio;
2106             break;
2107         case kAudioSessionCategory_PlayAndRecord:
2108             override = AudioSession::PlayAndRecord;
2109             break;
2110         case kAudioSessionCategory_AudioProcessing:
2111             override = AudioSession::AudioProcessing;
2112             break;
2113         default:
2114             override = AudioSession::None;
2115             break;
2116         }
2117     }
2118
2119     [self _setUnsignedIntValue:override forKey:WebKitAudioSessionCategoryOverride];
2120 }
2121
2122 - (BOOL)avKitEnabled
2123 {
2124     return [self _boolValueForKey:WebKitAVKitEnabled];
2125 }
2126
2127 - (void)setAVKitEnabled:(bool)flag
2128 {
2129     [self _setBoolValue:flag forKey:WebKitAVKitEnabled];
2130 }
2131
2132 - (BOOL)networkDataUsageTrackingEnabled
2133 {
2134     return [self _boolValueForKey:WebKitNetworkDataUsageTrackingEnabledPreferenceKey];
2135 }
2136
2137 - (void)setNetworkDataUsageTrackingEnabled:(bool)trackingEnabled
2138 {
2139     [self _setBoolValue:trackingEnabled forKey:WebKitNetworkDataUsageTrackingEnabledPreferenceKey];
2140 }
2141
2142 - (NSString *)networkInterfaceName
2143 {
2144     return [self _stringValueForKey:WebKitNetworkInterfaceNamePreferenceKey];
2145 }
2146
2147 - (void)setNetworkInterfaceName:(NSString *)name
2148 {
2149     [self _setStringValue:name forKey:WebKitNetworkInterfaceNamePreferenceKey];
2150 }
2151 #endif // PLATFORM(IOS)
2152
2153 - (BOOL)mediaPlaybackRequiresUserGesture
2154 {
2155     return [self _boolValueForKey:WebKitMediaPlaybackRequiresUserGesturePreferenceKey];
2156 }
2157
2158 - (void)setMediaPlaybackRequiresUserGesture:(BOOL)flag
2159 {
2160     [self _setBoolValue:flag forKey:WebKitMediaPlaybackRequiresUserGesturePreferenceKey];
2161 }
2162
2163 - (BOOL)mediaPlaybackAllowsInline
2164 {
2165     return [self _boolValueForKey:WebKitMediaPlaybackAllowsInlinePreferenceKey];
2166 }
2167
2168 - (void)setMediaPlaybackAllowsInline:(BOOL)flag
2169 {
2170     [self _setBoolValue:flag forKey:WebKitMediaPlaybackAllowsInlinePreferenceKey];
2171 }
2172
2173 - (BOOL)allowsAlternateFullscreen
2174 {
2175     return [self _boolValueForKey:WebKitAllowsAlternateFullscreenPreferenceKey];
2176 }
2177
2178 - (void)setAllowsAlternateFullscreen:(BOOL)flag
2179 {
2180     [self _setBoolValue:flag forKey:WebKitAllowsAlternateFullscreenPreferenceKey];
2181 }
2182
2183 - (BOOL)mockScrollbarsEnabled
2184 {
2185     return [self _boolValueForKey:WebKitMockScrollbarsEnabledPreferenceKey];
2186 }
2187
2188 - (void)setMockScrollbarsEnabled:(BOOL)flag
2189 {
2190     [self _setBoolValue:flag forKey:WebKitMockScrollbarsEnabledPreferenceKey];
2191 }
2192
2193 - (NSString *)pictographFontFamily
2194 {
2195     return [self _stringValueForKey: WebKitPictographFontPreferenceKey];
2196 }
2197
2198 - (void)setPictographFontFamily:(NSString *)family
2199 {
2200     [self _setStringValue: family forKey: WebKitPictographFontPreferenceKey];
2201 }
2202
2203 - (BOOL)pageCacheSupportsPlugins
2204 {
2205     return [self _boolValueForKey:WebKitPageCacheSupportsPluginsPreferenceKey];
2206 }
2207
2208 - (void)setPageCacheSupportsPlugins:(BOOL)flag
2209 {
2210     [self _setBoolValue:flag forKey:WebKitPageCacheSupportsPluginsPreferenceKey];
2211
2212 }
2213
2214 #if PLATFORM(IOS)
2215 - (void)_invalidateCachedPreferences
2216 {
2217     dispatch_barrier_sync(_private->readWriteQueue, ^{
2218         if (_private->values)
2219             _private->values = adoptNS([[NSMutableDictionary alloc] init]);
2220     });
2221
2222     [self _updatePrivateBrowsingStateTo:[self privateBrowsingEnabled]];
2223
2224     // Tell any live WebViews to refresh their preferences
2225     [self _postPreferencesChangedNotification];
2226 }
2227
2228 - (void)_synchronizeWebStoragePolicyWithCookiePolicy
2229 {
2230     // FIXME: This should be done in clients, WebKit shouldn't be making such policy decisions.
2231
2232     NSHTTPCookieAcceptPolicy cookieAcceptPolicy = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy];
2233     WebStorageBlockingPolicy storageBlockingPolicy;
2234     switch (static_cast<unsigned>(cookieAcceptPolicy)) {
2235     case NSHTTPCookieAcceptPolicyAlways:
2236         storageBlockingPolicy = WebAllowAllStorage;
2237         break;
2238     case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
2239     case NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain:
2240         storageBlockingPolicy = WebBlockThirdPartyStorage;
2241         break;
2242     case NSHTTPCookieAcceptPolicyNever:
2243         storageBlockingPolicy = WebBlockAllStorage;
2244         break;
2245     default:
2246         ASSERT_NOT_REACHED();
2247         storageBlockingPolicy = WebBlockAllStorage;
2248         break;
2249     }    
2250
2251     [self setStorageBlockingPolicy:storageBlockingPolicy];
2252 }
2253 #endif
2254
2255 - (void)setBackspaceKeyNavigationEnabled:(BOOL)flag
2256 {
2257     [self _setBoolValue:flag forKey:WebKitBackspaceKeyNavigationEnabledKey];
2258 }
2259
2260 - (BOOL)backspaceKeyNavigationEnabled
2261 {
2262     return [self _boolValueForKey:WebKitBackspaceKeyNavigationEnabledKey];
2263 }
2264
2265 - (void)setWantsBalancedSetDefersLoadingBehavior:(BOOL)flag
2266 {
2267     [self _setBoolValue:flag forKey:WebKitWantsBalancedSetDefersLoadingBehaviorKey];
2268 }
2269
2270 - (BOOL)wantsBalancedSetDefersLoadingBehavior
2271 {
2272     return [self _boolValueForKey:WebKitWantsBalancedSetDefersLoadingBehaviorKey];
2273 }
2274
2275 - (void)setShouldDisplaySubtitles:(BOOL)flag
2276 {
2277     [self _setBoolValue:flag forKey:WebKitShouldDisplaySubtitlesPreferenceKey];
2278 }
2279
2280 - (BOOL)shouldDisplaySubtitles
2281 {
2282     return [self _boolValueForKey:WebKitShouldDisplaySubtitlesPreferenceKey];
2283 }
2284
2285 - (void)setShouldDisplayCaptions:(BOOL)flag
2286 {
2287     [self _setBoolValue:flag forKey:WebKitShouldDisplayCaptionsPreferenceKey];
2288 }
2289
2290 - (BOOL)shouldDisplayCaptions
2291 {
2292     return [self _boolValueForKey:WebKitShouldDisplayCaptionsPreferenceKey];
2293 }
2294
2295 - (void)setShouldDisplayTextDescriptions:(BOOL)flag
2296 {
2297     [self _setBoolValue:flag forKey:WebKitShouldDisplayTextDescriptionsPreferenceKey];
2298 }
2299
2300 - (BOOL)shouldDisplayTextDescriptions
2301 {
2302     return [self _boolValueForKey:WebKitShouldDisplayTextDescriptionsPreferenceKey];
2303 }
2304
2305 - (void)setNotificationsEnabled:(BOOL)flag
2306 {
2307     [self _setBoolValue:flag forKey:WebKitNotificationsEnabledKey];
2308 }
2309
2310 - (BOOL)notificationsEnabled
2311 {
2312     return [self _boolValueForKey:WebKitNotificationsEnabledKey];
2313 }
2314
2315 - (void)setShouldRespectImageOrientation:(BOOL)flag
2316 {
2317     [self _setBoolValue:flag forKey:WebKitShouldRespectImageOrientationKey];
2318 }
2319
2320 - (BOOL)shouldRespectImageOrientation
2321 {
2322     return [self _boolValueForKey:WebKitShouldRespectImageOrientationKey];
2323 }
2324
2325 - (BOOL)requestAnimationFrameEnabled
2326 {
2327     return [self _boolValueForKey:WebKitRequestAnimationFrameEnabledPreferenceKey];
2328 }
2329
2330 - (void)setRequestAnimationFrameEnabled:(BOOL)enabled
2331 {
2332     [self _setBoolValue:enabled forKey:WebKitRequestAnimationFrameEnabledPreferenceKey];
2333 }
2334
2335 - (void)setIncrementalRenderingSuppressionTimeoutInSeconds:(NSTimeInterval)timeout
2336 {
2337     [self _setFloatValue:timeout forKey:WebKitIncrementalRenderingSuppressionTimeoutInSecondsKey];
2338 }
2339
2340 - (NSTimeInterval)incrementalRenderingSuppressionTimeoutInSeconds
2341 {
2342     return [self _floatValueForKey:WebKitIncrementalRenderingSuppressionTimeoutInSecondsKey];
2343 }
2344
2345 - (BOOL)diagnosticLoggingEnabled
2346 {
2347     return [self _boolValueForKey:WebKitDiagnosticLoggingEnabledKey];
2348 }
2349
2350 - (void)setDiagnosticLoggingEnabled:(BOOL)enabled
2351 {
2352     [self _setBoolValue:enabled forKey:WebKitDiagnosticLoggingEnabledKey];
2353 }
2354
2355 - (void)setStorageBlockingPolicy:(WebStorageBlockingPolicy)storageBlockingPolicy
2356 {
2357 #if PLATFORM(IOS)
2358     // We don't want to write the setting out, so we just reset the default instead of storing the new setting.
2359     // FIXME: This code removes any defaults previously registered by client process, which is not appropriate for this method to do.
2360     NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:storageBlockingPolicy] forKey:WebKitStorageBlockingPolicyKey];
2361     [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
2362 #else
2363     [self _setIntegerValue:storageBlockingPolicy forKey:WebKitStorageBlockingPolicyKey];
2364 #endif
2365 }
2366
2367 - (WebStorageBlockingPolicy)storageBlockingPolicy
2368 {
2369     return static_cast<WebStorageBlockingPolicy>([self _integerValueForKey:WebKitStorageBlockingPolicyKey]);
2370 }
2371
2372 - (BOOL)plugInSnapshottingEnabled
2373 {
2374     return [self _boolValueForKey:WebKitPlugInSnapshottingEnabledPreferenceKey];
2375 }
2376
2377 - (void)setPlugInSnapshottingEnabled:(BOOL)enabled
2378 {
2379     [self _setBoolValue:enabled forKey:WebKitPlugInSnapshottingEnabledPreferenceKey];
2380 }
2381
2382 - (BOOL)hiddenPageDOMTimerThrottlingEnabled
2383 {
2384     return [self _boolValueForKey:WebKitHiddenPageDOMTimerThrottlingEnabledPreferenceKey];
2385 }
2386
2387 - (void)setHiddenPageDOMTimerThrottlingEnabled:(BOOL)enabled
2388 {
2389     [self _setBoolValue:enabled forKey:WebKitHiddenPageDOMTimerThrottlingEnabledPreferenceKey];
2390 }
2391
2392 - (BOOL)hiddenPageCSSAnimationSuspensionEnabled
2393 {
2394     return [self _boolValueForKey:WebKitHiddenPageCSSAnimationSuspensionEnabledPreferenceKey];
2395 }
2396
2397 - (void)setHiddenPageCSSAnimationSuspensionEnabled:(BOOL)enabled
2398 {
2399     [self _setBoolValue:enabled forKey:WebKitHiddenPageCSSAnimationSuspensionEnabledPreferenceKey];
2400 }
2401
2402 - (BOOL)lowPowerVideoAudioBufferSizeEnabled
2403 {
2404     return [self _boolValueForKey:WebKitLowPowerVideoAudioBufferSizeEnabledPreferenceKey];
2405 }
2406
2407 - (void)setLowPowerVideoAudioBufferSizeEnabled:(BOOL)enabled
2408 {
2409     [self _setBoolValue:enabled forKey:WebKitLowPowerVideoAudioBufferSizeEnabledPreferenceKey];
2410 }
2411
2412 - (BOOL)useLegacyTextAlignPositionedElementBehavior
2413 {
2414     return [self _boolValueForKey:WebKitUseLegacyTextAlignPositionedElementBehaviorPreferenceKey];
2415 }
2416
2417 - (void)setUseLegacyTextAlignPositionedElementBehavior:(BOOL)enabled
2418 {
2419     [self _setBoolValue:enabled forKey:WebKitUseLegacyTextAlignPositionedElementBehaviorPreferenceKey];
2420 }
2421
2422 - (BOOL)mediaSourceEnabled
2423 {
2424     return [self _boolValueForKey:WebKitMediaSourceEnabledPreferenceKey];
2425 }
2426
2427 - (void)setMediaSourceEnabled:(BOOL)enabled
2428 {
2429     [self _setBoolValue:enabled forKey:WebKitMediaSourceEnabledPreferenceKey];
2430 }
2431
2432 - (BOOL)imageControlsEnabled
2433 {
2434     return [self _boolValueForKey:WebKitImageControlsEnabledPreferenceKey];
2435 }
2436
2437 - (void)setImageControlsEnabled:(BOOL)enabled
2438 {
2439     [self _setBoolValue:enabled forKey:WebKitImageControlsEnabledPreferenceKey];
2440 }
2441
2442 - (BOOL)serviceControlsEnabled
2443 {
2444     return [self _boolValueForKey:WebKitServiceControlsEnabledPreferenceKey];
2445 }
2446
2447 - (void)setServiceControlsEnabled:(BOOL)enabled
2448 {
2449     [self _setBoolValue:enabled forKey:WebKitServiceControlsEnabledPreferenceKey];
2450 }
2451
2452 - (BOOL)gamepadsEnabled
2453 {
2454     return [self _boolValueForKey:WebKitGamepadsEnabledPreferenceKey];
2455 }
2456
2457 - (void)setGamepadsEnabled:(BOOL)flag
2458 {
2459     [self _setBoolValue:flag forKey:WebKitGamepadsEnabledPreferenceKey];
2460 }
2461
2462 - (BOOL)shouldConvertPositionStyleOnCopy
2463 {
2464     return [self _boolValueForKey:WebKitShouldConvertPositionStyleOnCopyPreferenceKey];
2465 }
2466
2467 - (void)setShouldConvertPositionStyleOnCopy:(BOOL)enabled
2468 {
2469     [self _setBoolValue:enabled forKey:WebKitShouldConvertPositionStyleOnCopyPreferenceKey];
2470 }
2471
2472 - (NSString *)mediaKeysStorageDirectory
2473 {
2474     return [[self _stringValueForKey:WebKitMediaKeysStorageDirectoryKey] stringByStandardizingPath];
2475 }
2476
2477 - (void)setMediaKeysStorageDirectory:(NSString *)directory
2478 {
2479     [self _setStringValue:directory forKey:WebKitMediaKeysStorageDirectoryKey];
2480 }
2481
2482 @end
2483
2484 @implementation WebPreferences (WebInternal)
2485
2486 + (NSString *)_IBCreatorID
2487 {
2488     return classIBCreatorID;
2489 }
2490
2491 + (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key
2492 {
2493     NSString *IBCreatorID = [WebPreferences _IBCreatorID];
2494     if (!IBCreatorID)
2495         return key;
2496     return [IBCreatorID stringByAppendingString:key];
2497 }
2498
2499 @end