📄 webicondatabase.mm
字号:
/* * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * 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 "WebIconDatabaseInternal.h"#import "WebIconDatabaseClient.h"#import "WebIconDatabaseDelegate.h"#import "WebKitLogging.h"#import "WebKitNSStringExtras.h"#import "WebNSFileManagerExtras.h"#import "WebNSNotificationCenterExtras.h"#import "WebNSURLExtras.h"#import "WebPreferences.h"#import "WebTypesInternal.h"#import <WebCore/IconDatabase.h>#import <WebCore/Image.h>#import <WebCore/IntSize.h>#import <WebCore/ThreadCheck.h>using namespace WebCore;NSString * const WebIconDatabaseVersionKey = @"WebIconDatabaseVersion";NSString * const WebURLToIconURLKey = @"WebSiteURLToIconURLKey";NSString *WebIconDatabaseDidAddIconNotification = @"WebIconDatabaseDidAddIconNotification";NSString *WebIconNotificationUserInfoURLKey = @"WebIconNotificationUserInfoURLKey";NSString *WebIconDatabaseDidRemoveAllIconsNotification = @"WebIconDatabaseDidRemoveAllIconsNotification";NSString *WebIconDatabaseDirectoryDefaultsKey = @"WebIconDatabaseDirectoryDefaultsKey";NSString *WebIconDatabaseImportDirectoryDefaultsKey = @"WebIconDatabaseImportDirectoryDefaultsKey";NSString *WebIconDatabaseEnabledDefaultsKey = @"WebIconDatabaseEnabled";NSString *WebIconDatabasePath = @"~/Library/Icons";NSSize WebIconSmallSize = {16, 16};NSSize WebIconMediumSize = {32, 32};NSSize WebIconLargeSize = {128, 128};#define UniqueFilePathSize (34)static WebIconDatabaseClient* defaultClient(){ static WebIconDatabaseClient* defaultClient = new WebIconDatabaseClient(); return defaultClient;}@interface WebIconDatabase (WebReallyInternal)- (void)_sendNotificationForURL:(NSString *)URL;- (void)_sendDidRemoveAllIconsNotification;- (NSImage *)_iconForFileURL:(NSString *)fileURL withSize:(NSSize)size;- (void)_resetCachedWebPreferences:(NSNotification *)notification;- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons;- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon;- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache;- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size;- (NSString *)_databaseDirectory;@end@implementation WebIconDatabase+ (WebIconDatabase *)sharedIconDatabase{ static WebIconDatabase *database = nil; if (!database) database = [[WebIconDatabase alloc] init]; return database;}- init{ [super init]; WebCoreThreadViolationCheck(); _private = [[WebIconDatabasePrivate alloc] init]; // Check the user defaults and see if the icon database should even be enabled. // Inform the bridge and, if we're disabled, bail from init right here NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; // <rdar://problem/4741419> - IconDatabase should be disabled by default NSDictionary *initialDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:YES], WebIconDatabaseEnabledDefaultsKey, nil]; [defaults registerDefaults:initialDefaults]; [initialDefaults release]; BOOL enabled = [defaults boolForKey:WebIconDatabaseEnabledDefaultsKey]; iconDatabase()->setEnabled(enabled); if (enabled) [self _startUpIconDatabase]; return self;}- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size cache:(BOOL)cache{ ASSERT_MAIN_THREAD(); ASSERT(size.width); ASSERT(size.height); if (!URL || ![self isEnabled]) return [self defaultIconForURL:URL withSize:size]; // FIXME - <rdar://problem/4697934> - Move the handling of FileURLs to WebCore and implement in ObjC++ if ([URL _webkit_isFileURL]) return [self _iconForFileURL:URL withSize:size]; if (Image* image = iconDatabase()->iconForPageURL(URL, IntSize(size))) if (NSImage *icon = webGetNSImage(image, size)) return icon; return [self defaultIconForURL:URL withSize:size];}- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size{ return [self iconForURL:URL withSize:size cache:YES];}- (NSString *)iconURLForURL:(NSString *)URL{ if (![self isEnabled]) return nil; ASSERT_MAIN_THREAD(); return iconDatabase()->iconURLForPageURL(URL);}- (NSImage *)defaultIconWithSize:(NSSize)size{ ASSERT_MAIN_THREAD(); ASSERT(size.width); ASSERT(size.height); Image* image = iconDatabase()->defaultIcon(IntSize(size)); return image ? image->getNSImage() : nil;}- (NSImage *)defaultIconForURL:(NSString *)URL withSize:(NSSize)size{ if (_private->delegateImplementsDefaultIconForURL) return [_private->delegate webIconDatabase:self defaultIconForURL:URL withSize:size]; return [self defaultIconWithSize:size];}- (void)retainIconForURL:(NSString *)URL{ ASSERT_MAIN_THREAD(); ASSERT(URL); if (![self isEnabled]) return; iconDatabase()->retainIconForPageURL(URL);}- (void)releaseIconForURL:(NSString *)pageURL{ ASSERT_MAIN_THREAD(); ASSERT(pageURL); if (![self isEnabled]) return; iconDatabase()->releaseIconForPageURL(pageURL);}+ (void)delayDatabaseCleanup{ ASSERT_MAIN_THREAD(); IconDatabase::delayDatabaseCleanup();}+ (void)allowDatabaseCleanup{ ASSERT_MAIN_THREAD(); IconDatabase::allowDatabaseCleanup();}- (void)setDelegate:(id)delegate{ _private->delegate = delegate; _private->delegateImplementsDefaultIconForURL = [delegate respondsToSelector:@selector(webIconDatabase:defaultIconForURL:withSize:)];}- (id)delegate{ return _private->delegate;}@end@implementation WebIconDatabase (WebPendingPublic)- (BOOL)isEnabled{ return iconDatabase()->isEnabled();}- (void)setEnabled:(BOOL)flag{ BOOL currentlyEnabled = [self isEnabled]; if (currentlyEnabled && !flag) { iconDatabase()->setEnabled(false); [self _shutDownIconDatabase]; } else if (!currentlyEnabled && flag) { iconDatabase()->setEnabled(true); [self _startUpIconDatabase]; }}- (void)removeAllIcons{ ASSERT_MAIN_THREAD(); if (![self isEnabled]) return; // Via the IconDatabaseClient interface, removeAllIcons() will send the WebIconDatabaseDidRemoveAllIconsNotification iconDatabase()->removeAllIcons();}@end@implementation WebIconDatabase (WebPrivate)+ (void)_checkIntegrityBeforeOpening{ iconDatabase()->checkIntegrityBeforeOpening();}@end@implementation WebIconDatabase (WebInternal)- (void)_sendNotificationForURL:(NSString *)URL{ ASSERT(URL); NSDictionary *userInfo = [NSDictionary dictionaryWithObject:URL forKey:WebIconNotificationUserInfoURLKey]; [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:WebIconDatabaseDidAddIconNotification object:self userInfo:userInfo];}- (void)_sendDidRemoveAllIconsNotification{ [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:WebIconDatabaseDidRemoveAllIconsNotification object:self userInfo:nil];}- (void)_startUpIconDatabase{ iconDatabase()->setClient(defaultClient()); // Figure out the directory we should be using for the icon.db NSString *databaseDirectory = [self _databaseDirectory]; // Rename legacy icon database files to the new icon database name BOOL isDirectory = NO; NSString *legacyDB = [databaseDirectory stringByAppendingPathComponent:@"icon.db"]; NSFileManager *defaultManager = [NSFileManager defaultManager]; if ([defaultManager fileExistsAtPath:legacyDB isDirectory:&isDirectory] && !isDirectory) { NSString *newDB = [databaseDirectory stringByAppendingPathComponent:iconDatabase()->defaultDatabaseFilename()]; if (![defaultManager fileExistsAtPath:newDB]) rename([legacyDB fileSystemRepresentation], [newDB fileSystemRepresentation]); } // Set the private browsing pref then open the WebCore icon database iconDatabase()->setPrivateBrowsingEnabled([[WebPreferences standardPreferences] privateBrowsingEnabled]); if (!iconDatabase()->open(databaseDirectory)) LOG_ERROR("Unable to open icon database"); // Register for important notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:NSApp]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_resetCachedWebPreferences:) name:WebPreferencesChangedNotification object:nil];}- (void)_shutDownIconDatabase{ // Unregister for important notifications [[NSNotificationCenter defaultCenter] removeObserver:self name:NSApplicationWillTerminateNotification object:NSApp]; [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil];}- (void)_applicationWillTerminate:(NSNotification *)notification{ iconDatabase()->close();}- (NSImage *)_iconForFileURL:(NSString *)file withSize:(NSSize)size{ ASSERT_MAIN_THREAD(); ASSERT(size.width); ASSERT(size.height); NSWorkspace *workspace = [NSWorkspace sharedWorkspace]; NSString *path = [[NSURL _web_URLWithDataAsString:file] path]; NSString *suffix = [path pathExtension]; NSImage *icon = nil; if ([suffix _webkit_isCaseInsensitiveEqualToString:@"htm"] || [suffix _webkit_isCaseInsensitiveEqualToString:@"html"]) { if (!_private->htmlIcons) { icon = [workspace iconForFileType:@"html"]; _private->htmlIcons = [[self _iconsBySplittingRepresentationsOfIcon:icon] retain]; } icon = [self _iconFromDictionary:_private->htmlIcons forSize:size cache:YES]; } else { if (!path || ![path isAbsolutePath]) { // Return the generic icon when there is no path. icon = [workspace iconForFileType:NSFileTypeForHFSTypeCode(kGenericDocumentIcon)]; } else { icon = [workspace iconForFile:path]; } [self _scaleIcon:icon toSize:size]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -