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