📄 webpreferences.mm
字号:
/* * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. * (C) 2006 Graham Dennis (graham.dennis@gmail.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#import "WebPreferencesPrivate.h"#import "WebPreferenceKeysPrivate.h"#import "WebKitLogging.h"#import "WebKitNSStringExtras.h"#import "WebKitSystemBits.h"#import "WebKitSystemInterface.h"#import "WebKitVersionChecks.h"#import "WebNSDictionaryExtras.h"#import "WebNSURLExtras.h"NSString *WebPreferencesChangedNotification = @"WebPreferencesChangedNotification";NSString *WebPreferencesRemovedNotification = @"WebPreferencesRemovedNotification";#define KEY(x) (_private->identifier ? [_private->identifier stringByAppendingString:(x)] : (x))enum { WebPreferencesVersion = 1 };static WebPreferences *_standardPreferences;static NSMutableDictionary *webPreferencesInstances;static bool contains(const char* const array[], int count, const char* item){ if (!item) return false; for (int i = 0; i < count; i++) if (!strcasecmp(array[i], item)) return true; return false;}static WebCacheModel cacheModelForMainBundle(void){ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Apps that probably need the small setting static const char* const documentViewerIDs[] = { "Microsoft/com.microsoft.Messenger", "com.adiumX.adiumX", "com.alientechnology.Proteus", "com.apple.Dashcode", "com.apple.iChat", "com.barebones.bbedit", "com.barebones.textwrangler", "com.barebones.yojimbo", "com.equinux.iSale4", "com.growl.growlframework", "com.intrarts.PandoraMan", "com.karelia.Sandvox", "com.macromates.textmate", "com.realmacsoftware.rapidweaverpro", "com.red-sweater.marsedit", "com.yahoo.messenger3", "de.codingmonkeys.SubEthaEdit", "fi.karppinen.Pyro", "info.colloquy", "kungfoo.tv.ecto", }; // Apps that probably need the medium setting static const char* const documentBrowserIDs[] = { "com.apple.Dictionary", "com.apple.Xcode", "com.apple.dashboard.client", "com.apple.helpviewer", "com.culturedcode.xyle", "com.macrabbit.CSSEdit", "com.panic.Coda", "com.ranchero.NetNewsWire", "com.thinkmac.NewsLife", "org.xlife.NewsFire", "uk.co.opencommunity.vienna2", }; // Apps that probably need the large setting static const char* const primaryWebBrowserIDs[] = { "com.app4mac.KidsBrowser" "com.app4mac.wKiosk", "com.freeverse.bumpercar", "com.omnigroup.OmniWeb5", "com.sunrisebrowser.Sunrise", "net.hmdt-web.Shiira", }; WebCacheModel cacheModel; const char* bundleID = [[[NSBundle mainBundle] bundleIdentifier] UTF8String]; if (contains(documentViewerIDs, sizeof(documentViewerIDs) / sizeof(documentViewerIDs[0]), bundleID)) cacheModel = WebCacheModelDocumentViewer; else if (contains(documentBrowserIDs, sizeof(documentBrowserIDs) / sizeof(documentBrowserIDs[0]), bundleID)) cacheModel = WebCacheModelDocumentBrowser; else if (contains(primaryWebBrowserIDs, sizeof(primaryWebBrowserIDs) / sizeof(primaryWebBrowserIDs[0]), bundleID)) cacheModel = WebCacheModelPrimaryWebBrowser; else { bool isLegacyApp = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_CACHE_MODEL_API); if (isLegacyApp) cacheModel = WebCacheModelDocumentBrowser; // To avoid regressions in apps that depended on old WebKit's large cache. else cacheModel = WebCacheModelDocumentViewer; // To save memory. } [pool drain]; return cacheModel;}@interface WebPreferencesPrivate : NSObject{@public NSMutableDictionary *values; NSString *identifier; NSString *IBCreatorID; BOOL autosaves; BOOL automaticallyDetectsCacheModel; unsigned numWebViews;}@end@implementation WebPreferencesPrivate- (void)dealloc{ [values release]; [identifier release]; [IBCreatorID release]; [super dealloc];}@end@interface WebPreferences (WebInternal)+ (NSString *)_concatenateKeyWithIBCreatorID:(NSString *)key;+ (NSString *)_IBCreatorID;@end@interface WebPreferences (WebForwardDeclarations)// This pseudo-category is needed so these methods can be used from within other category implementations// without being in the public header file.- (BOOL)_boolValueForKey:(NSString *)key;- (void)_setBoolValue:(BOOL)value forKey:(NSString *)key;- (int)_integerValueForKey:(NSString *)key;- (void)_setIntegerValue:(int)value forKey:(NSString *)key;- (float)_floatValueForKey:(NSString *)key;- (void)_setFloatValue:(float)value forKey:(NSString *)key;- (void)_setUnsignedLongLongValue:(unsigned long long)value forKey:(NSString *)key;- (unsigned long long)_unsignedLongLongValueForKey:(NSString *)key;@end@implementation WebPreferences- init{ // Create fake identifier static int instanceCount = 1; NSString *fakeIdentifier; // At least ensure that identifier hasn't been already used. fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++]; while ([[self class] _getInstanceForIdentifier:fakeIdentifier]){ fakeIdentifier = [NSString stringWithFormat:@"WebPreferences%d", instanceCount++]; } return [self initWithIdentifier:fakeIdentifier];}- (id)initWithIdentifier:(NSString *)anIdentifier{ self = [super init]; if (!self) return nil; _private = [[WebPreferencesPrivate alloc] init]; _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain]; WebPreferences *instance = [[self class] _getInstanceForIdentifier:anIdentifier]; if (instance){ [self release]; return [instance retain]; } _private->values = [[NSMutableDictionary alloc] init]; _private->identifier = [anIdentifier copy]; _private->automaticallyDetectsCacheModel = YES; [[self class] _setInstance:self forIdentifier:_private->identifier]; [self _postPreferencesChangesNotification]; return self;}- (id)initWithCoder:(NSCoder *)decoder{ self = [super init]; if (!self) return nil; _private = [[WebPreferencesPrivate alloc] init]; _private->IBCreatorID = [[WebPreferences _IBCreatorID] retain]; _private->automaticallyDetectsCacheModel = YES; @try { id identifier = nil; id values = nil; if ([decoder allowsKeyedCoding]) { identifier = [decoder decodeObjectForKey:@"Identifier"]; values = [decoder decodeObjectForKey:@"Values"]; } else { int version; [decoder decodeValueOfObjCType:@encode(int) at:&version]; if (version == 1) { identifier = [decoder decodeObject]; values = [decoder decodeObject]; } } if ([identifier isKindOfClass:[NSString class]]) _private->identifier = [identifier copy]; if ([values isKindOfClass:[NSDictionary class]]) _private->values = [values mutableCopy]; // ensure dictionary is mutable LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values); } @catch(id) { [self release]; return nil; } // If we load a nib multiple times, or have instances in multiple // nibs with the same name, the first guy up wins. WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier]; if (instance) { [self release]; self = [instance retain]; } else { [[self class] _setInstance:self forIdentifier:_private->identifier]; } return self;}- (void)encodeWithCoder:(NSCoder *)encoder{ if ([encoder allowsKeyedCoding]){ [encoder encodeObject:_private->identifier forKey:@"Identifier"]; [encoder encodeObject:_private->values forKey:@"Values"]; LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values); } else { int version = WebPreferencesVersion; [encoder encodeValueOfObjCType:@encode(int) at:&version]; [encoder encodeObject:_private->identifier]; [encoder encodeObject:_private->values]; }}+ (WebPreferences *)standardPreferences{ if (_standardPreferences == nil) { _standardPreferences = [[WebPreferences alloc] initWithIdentifier:nil]; [_standardPreferences setAutosaves:YES]; } return _standardPreferences;}// if we ever have more than one WebPreferences object, this would move to init+ (void)initialize{ NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: @"Times", WebKitStandardFontPreferenceKey, @"Courier", WebKitFixedFontPreferenceKey, @"Times", WebKitSerifFontPreferenceKey, @"Helvetica", WebKitSansSerifFontPreferenceKey, @"Apple Chancery", WebKitCursiveFontPreferenceKey, @"Papyrus", WebKitFantasyFontPreferenceKey, @"1", WebKitMinimumFontSizePreferenceKey, @"9", WebKitMinimumLogicalFontSizePreferenceKey, @"16", WebKitDefaultFontSizePreferenceKey, @"13", WebKitDefaultFixedFontSizePreferenceKey, @"ISO-8859-1", WebKitDefaultTextEncodingNamePreferenceKey, [NSNumber numberWithBool:NO], WebKitUserStyleSheetEnabledPreferenceKey, @"", WebKitUserStyleSheetLocationPreferenceKey, [NSNumber numberWithBool:NO], WebKitShouldPrintBackgroundsPreferenceKey, [NSNumber numberWithBool:NO], WebKitTextAreasAreResizablePreferenceKey, [NSNumber numberWithBool:NO], WebKitShrinksStandaloneImagesToFitPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaScriptEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitWebSecurityEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitAllowUniversalAccessFromFileURLsPreferenceKey, [NSNumber numberWithBool:YES], WebKitJavaScriptCanOpenWindowsAutomaticallyPreferenceKey, [NSNumber numberWithBool:YES], WebKitPluginsEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitDatabasesEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitLocalStorageEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitAllowAnimatedImagesPreferenceKey, [NSNumber numberWithBool:YES], WebKitAllowAnimatedImageLoopingPreferenceKey, [NSNumber numberWithBool:YES], WebKitDisplayImagesKey, @"1800", WebKitBackForwardCacheExpirationIntervalKey, [NSNumber numberWithBool:NO], WebKitTabToLinksPreferenceKey, [NSNumber numberWithBool:NO], WebKitPrivateBrowsingEnabledPreferenceKey, [NSNumber numberWithBool:NO], WebKitRespectStandardStyleKeyEquivalentsPreferenceKey, [NSNumber numberWithBool:NO], WebKitShowsURLsInToolTipsPreferenceKey, @"1", WebKitPDFDisplayModePreferenceKey, @"0", WebKitPDFScaleFactorPreferenceKey, @"0", WebKitUseSiteSpecificSpoofingPreferenceKey, [NSNumber numberWithInt:WebKitEditableLinkDefaultBehavior], WebKitEditableLinkBehaviorPreferenceKey,#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) [NSNumber numberWithInt:WebTextDirectionSubmenuAutomaticallyIncluded],#else [NSNumber numberWithInt:WebTextDirectionSubmenuNeverIncluded],#endif WebKitTextDirectionSubmenuInclusionBehaviorPreferenceKey, [NSNumber numberWithBool:NO], WebKitDOMPasteAllowedPreferenceKey, [NSNumber numberWithBool:YES], WebKitUsesPageCachePreferenceKey, [NSNumber numberWithInt:cacheModelForMainBundle()], WebKitCacheModelPreferenceKey, [NSNumber numberWithBool:NO], WebKitDeveloperExtrasEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitAuthorAndUserStylesEnabledPreferenceKey, [NSNumber numberWithBool:NO], WebKitApplicationChromeModeEnabledPreferenceKey, [NSNumber numberWithBool:NO], WebKitWebArchiveDebugModeEnabledPreferenceKey, [NSNumber numberWithBool:NO], WebKitOfflineWebApplicationCacheEnabledPreferenceKey, [NSNumber numberWithBool:YES], WebKitZoomsTextOnlyPreferenceKey,#ifndef NDEBUG // In Release and Production we skip a lot of object teardown during quit to speed up shutdown time. This breaks // our RefCount Leak tracking, and so for Debug we will use the full document teardown. [NSNumber numberWithBool:YES], WebKitEnableFullDocumentTeardownPreferenceKey,#endif nil]; // This value shouldn't ever change, which is assumed in the initialization of WebKitPDFDisplayModePreferenceKey above ASSERT(kPDFDisplaySinglePageContinuous == 1); [[NSUserDefaults standardUserDefaults] registerDefaults:dict];}- (void)dealloc{ [_private release]; [super dealloc];}- (NSString *)identifier{ return _private->identifier;}- (id)_valueForKey:(NSString *)key{ NSString *_key = KEY(key); id o = [_private->values objectForKey:_key]; if (o) return o; o = [[NSUserDefaults standardUserDefaults] objectForKey:_key]; if (!o && key != _key) o = [[NSUserDefaults standardUserDefaults] objectForKey:key];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -