[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

cblu cblu at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 06:35:52 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 74610cc22e6585f8caa610520677c3eca7f2cd54
Author: cblu <cblu at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Sep 3 06:28:29 2002 +0000

    WebKit:
    
    	First implementation of the icon DB.
    
            * History.subproj/WebHistoryItem.m:
            (-[WebHistoryItem _retainIconInDatabase:]): calls retainIconForSiteURL: or releaseIconForSiteURL:
            (-[WebHistoryItem initWithURL:target:parent:title:]): call _retainIconInDatabase:
            (-[WebHistoryItem dealloc]): call _retainIconInDatabase:
            (-[WebHistoryItem icon]): call iconForSiteURL:withSize:
            (-[WebHistoryItem setURL:]): call _retainIconInDatabase:
            (-[WebHistoryItem initFromDictionaryRepresentation:]): call _retainIconInDatabase:
            * Misc.subproj/WebIconDatabase.h: Added.
            * Misc.subproj/WebIconDatabase.m: Added.
            (+[WebIconDatabase sharedIconDatabase]):
            (-[WebIconDatabase init]):
            (-[WebIconDatabase iconForSiteURL:withSize:]):
            (-[WebIconDatabase setIcon:forSiteURL:]):
            (-[WebIconDatabase setIcon:forHost:]):
            (-[WebIconDatabase retainIconForSiteURL:]):
            (-[WebIconDatabase releaseIconForSiteURL:]):
            (-[WebIconDatabase delayDatabaseCleanup]):
            (-[WebIconDatabase allowDatabaseCleanup]):
            (-[WebIconDatabase applicationWillTerminate:]):
            (-[WebIconDatabase _createFileDatabase]):
            (-[WebIconDatabase _loadIconDictionaries]):
            (-[WebIconDatabase _updateFileDatabase]):
            (-[WebIconDatabase _iconForIconURL:]):
            (-[WebIconDatabase _iconsForIconURL:]):
            (-[WebIconDatabase _iconForFileURL:withSize:]):
            (-[WebIconDatabase _setIcon:forIconURL:]):
            (-[WebIconDatabase _setIconURL:forSiteURL:]):
            (-[WebIconDatabase _setBuiltInIcon:forHost:]):
            (-[WebIconDatabase _retainIconForIconURL:]):
            (-[WebIconDatabase _releaseIconForIconURL:]):
            (-[WebIconDatabase _retainFutureIconForSiteURL:]):
            (-[WebIconDatabase _releaseFutureIconForSiteURL:]):
            (-[WebIconDatabase _retainOriginalIconsOnDisk]):
            (-[WebIconDatabase _releaseOriginalIconsOnDisk]):
            (-[WebIconDatabase _sendNotificationForSiteURL:]):
            (-[WebIconDatabase _addObject:toSetForKey:inDictionary:]):
            (-[WebIconDatabase _uniqueIconURL]):
            (-[WebIconDatabase _cachedIconFromArray:withSize:]):
            (-[WebIconDatabase _scaleIcon:toSize:]):
            * Misc.subproj/WebIconDatabasePrivate.h: Added.
            * Misc.subproj/WebIconLoader.h:
            * Misc.subproj/WebIconLoader.m:
            (+[WebIconLoader iconForFileAtPath:]):
            (-[WebIconLoader startLoading]):
            (-[WebIconLoader handleDidFinishLoading:data:]):
            * WebKit.exp:
            * WebKit.pbproj/project.pbxproj:
            * WebView.subproj/WebDataSourcePrivate.m:
            (-[WebDataSource _loadIcon]):
    
    WebBrowser:
    
    	Start using the icon DB.
    
            * AppController.m:
            (-[AppController _installBuiltItIcons]):
            (-[AppController awakeFromNib]): call _installBuiltItIcons, there might be a better place for this.
            * LocationChangeHandler.m:
            (-[LocationChangeHandler receivedPageIcon:fromURL:forDataSource:]): use the icon db instead of the passed icon
            * WebBrowser.pbproj/project.pbxproj:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@1950 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index e90985e..07d9175 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,57 @@
+2002-09-02  Chris Blumenberg  <cblu at apple.com>
+
+	Icon DB.
+
+        * History.subproj/WebHistoryItem.m:
+        (-[WebHistoryItem _retainIconInDatabase:]): calls retainIconForSiteURL: or releaseIconForSiteURL:
+        (-[WebHistoryItem initWithURL:target:parent:title:]): call _retainIconInDatabase:
+        (-[WebHistoryItem dealloc]): call _retainIconInDatabase:
+        (-[WebHistoryItem icon]): call iconForSiteURL:withSize:
+        (-[WebHistoryItem setURL:]): call _retainIconInDatabase:
+        (-[WebHistoryItem initFromDictionaryRepresentation:]): call _retainIconInDatabase:
+        * Misc.subproj/WebIconDatabase.h: Added.
+        * Misc.subproj/WebIconDatabase.m: Added.
+        (+[WebIconDatabase sharedIconDatabase]):
+        (-[WebIconDatabase init]):
+        (-[WebIconDatabase iconForSiteURL:withSize:]):
+        (-[WebIconDatabase setIcon:forSiteURL:]):
+        (-[WebIconDatabase setIcon:forHost:]):
+        (-[WebIconDatabase retainIconForSiteURL:]):
+        (-[WebIconDatabase releaseIconForSiteURL:]):
+        (-[WebIconDatabase delayDatabaseCleanup]):
+        (-[WebIconDatabase allowDatabaseCleanup]):
+        (-[WebIconDatabase applicationWillTerminate:]):
+        (-[WebIconDatabase _createFileDatabase]):
+        (-[WebIconDatabase _loadIconDictionaries]):
+        (-[WebIconDatabase _updateFileDatabase]):
+        (-[WebIconDatabase _iconForIconURL:]):
+        (-[WebIconDatabase _iconsForIconURL:]):
+        (-[WebIconDatabase _iconForFileURL:withSize:]):
+        (-[WebIconDatabase _setIcon:forIconURL:]):
+        (-[WebIconDatabase _setIconURL:forSiteURL:]):
+        (-[WebIconDatabase _setBuiltInIcon:forHost:]):
+        (-[WebIconDatabase _retainIconForIconURL:]):
+        (-[WebIconDatabase _releaseIconForIconURL:]):
+        (-[WebIconDatabase _retainFutureIconForSiteURL:]):
+        (-[WebIconDatabase _releaseFutureIconForSiteURL:]):
+        (-[WebIconDatabase _retainOriginalIconsOnDisk]):
+        (-[WebIconDatabase _releaseOriginalIconsOnDisk]):
+        (-[WebIconDatabase _sendNotificationForSiteURL:]):
+        (-[WebIconDatabase _addObject:toSetForKey:inDictionary:]):
+        (-[WebIconDatabase _uniqueIconURL]):
+        (-[WebIconDatabase _cachedIconFromArray:withSize:]):
+        (-[WebIconDatabase _scaleIcon:toSize:]):
+        * Misc.subproj/WebIconDatabasePrivate.h: Added.
+        * Misc.subproj/WebIconLoader.h:
+        * Misc.subproj/WebIconLoader.m:
+        (+[WebIconLoader iconForFileAtPath:]):
+        (-[WebIconLoader startLoading]):
+        (-[WebIconLoader handleDidFinishLoading:data:]):
+        * WebKit.exp:
+        * WebKit.pbproj/project.pbxproj:
+        * WebView.subproj/WebDataSourcePrivate.m:
+        (-[WebDataSource _loadIcon]):
+
 2002-08-30  Ken Kocienda  <kocienda at apple.com>
 
 	Removed one last reference to the now-removed WebDefaultMIMEType symbol.
diff --git a/WebKit/ChangeLog-2002-12-03 b/WebKit/ChangeLog-2002-12-03
index e90985e..07d9175 100644
--- a/WebKit/ChangeLog-2002-12-03
+++ b/WebKit/ChangeLog-2002-12-03
@@ -1,3 +1,57 @@
+2002-09-02  Chris Blumenberg  <cblu at apple.com>
+
+	Icon DB.
+
+        * History.subproj/WebHistoryItem.m:
+        (-[WebHistoryItem _retainIconInDatabase:]): calls retainIconForSiteURL: or releaseIconForSiteURL:
+        (-[WebHistoryItem initWithURL:target:parent:title:]): call _retainIconInDatabase:
+        (-[WebHistoryItem dealloc]): call _retainIconInDatabase:
+        (-[WebHistoryItem icon]): call iconForSiteURL:withSize:
+        (-[WebHistoryItem setURL:]): call _retainIconInDatabase:
+        (-[WebHistoryItem initFromDictionaryRepresentation:]): call _retainIconInDatabase:
+        * Misc.subproj/WebIconDatabase.h: Added.
+        * Misc.subproj/WebIconDatabase.m: Added.
+        (+[WebIconDatabase sharedIconDatabase]):
+        (-[WebIconDatabase init]):
+        (-[WebIconDatabase iconForSiteURL:withSize:]):
+        (-[WebIconDatabase setIcon:forSiteURL:]):
+        (-[WebIconDatabase setIcon:forHost:]):
+        (-[WebIconDatabase retainIconForSiteURL:]):
+        (-[WebIconDatabase releaseIconForSiteURL:]):
+        (-[WebIconDatabase delayDatabaseCleanup]):
+        (-[WebIconDatabase allowDatabaseCleanup]):
+        (-[WebIconDatabase applicationWillTerminate:]):
+        (-[WebIconDatabase _createFileDatabase]):
+        (-[WebIconDatabase _loadIconDictionaries]):
+        (-[WebIconDatabase _updateFileDatabase]):
+        (-[WebIconDatabase _iconForIconURL:]):
+        (-[WebIconDatabase _iconsForIconURL:]):
+        (-[WebIconDatabase _iconForFileURL:withSize:]):
+        (-[WebIconDatabase _setIcon:forIconURL:]):
+        (-[WebIconDatabase _setIconURL:forSiteURL:]):
+        (-[WebIconDatabase _setBuiltInIcon:forHost:]):
+        (-[WebIconDatabase _retainIconForIconURL:]):
+        (-[WebIconDatabase _releaseIconForIconURL:]):
+        (-[WebIconDatabase _retainFutureIconForSiteURL:]):
+        (-[WebIconDatabase _releaseFutureIconForSiteURL:]):
+        (-[WebIconDatabase _retainOriginalIconsOnDisk]):
+        (-[WebIconDatabase _releaseOriginalIconsOnDisk]):
+        (-[WebIconDatabase _sendNotificationForSiteURL:]):
+        (-[WebIconDatabase _addObject:toSetForKey:inDictionary:]):
+        (-[WebIconDatabase _uniqueIconURL]):
+        (-[WebIconDatabase _cachedIconFromArray:withSize:]):
+        (-[WebIconDatabase _scaleIcon:toSize:]):
+        * Misc.subproj/WebIconDatabasePrivate.h: Added.
+        * Misc.subproj/WebIconLoader.h:
+        * Misc.subproj/WebIconLoader.m:
+        (+[WebIconLoader iconForFileAtPath:]):
+        (-[WebIconLoader startLoading]):
+        (-[WebIconLoader handleDidFinishLoading:data:]):
+        * WebKit.exp:
+        * WebKit.pbproj/project.pbxproj:
+        * WebView.subproj/WebDataSourcePrivate.m:
+        (-[WebDataSource _loadIcon]):
+
 2002-08-30  Ken Kocienda  <kocienda at apple.com>
 
 	Removed one last reference to the now-removed WebDefaultMIMEType symbol.
diff --git a/WebKit/History.subproj/WebHistoryItem.m b/WebKit/History.subproj/WebHistoryItem.m
index 5e7b6b3..32c617c 100644
--- a/WebKit/History.subproj/WebHistoryItem.m
+++ b/WebKit/History.subproj/WebHistoryItem.m
@@ -4,6 +4,7 @@
 */
 
 #import <WebKit/WebHistoryItem.h>
+#import <WebKit/WebIconDatabase.h>
 #import <WebKit/WebIconLoader.h>
 #import <WebKit/WebKitReallyPrivate.h>
 
@@ -11,6 +12,19 @@
 
 @implementation WebHistoryItem
 
+- (void)_retainIconInDatabase:(BOOL)retain
+{
+    if(_URL){
+        WebIconDatabase *iconDB = [WebIconDatabase sharedIconDatabase];
+
+        if(retain){
+            [iconDB retainIconForSiteURL:_URL];
+        }else{
+            [iconDB releaseIconForSiteURL:_URL];
+        }
+    }
+}
+
 +(WebHistoryItem *)entryWithURL:(NSURL *)URL
 {
     return [[[self alloc] initWithURL:URL title:nil] autorelease];
@@ -38,12 +52,16 @@
     _parent = [parent retain];
     _title = [title retain];
     _lastVisitedDate = [[NSCalendarDate alloc] init];
+
+    [self _retainIconInDatabase:YES];
     
     return self;
 }
 
 - (void)dealloc
 {
+    [self _retainIconInDatabase:NO];
+    
     [_URL release];
     [_target release];
     [_parent release];
@@ -98,11 +116,9 @@
     if (!_loadedIcon) {
         NSImage *newIcon;
         
-        if (_iconURL != nil) {
-            newIcon = [[WebIconLoader iconLoaderWithURL:_iconURL] iconFromCache];
-        } else if ([_URL isFileURL]) {
-            newIcon = [WebIconLoader iconForFileAtPath:[_URL path]];
-        } else {
+        if (_URL != nil) {
+            newIcon = [[WebIconDatabase sharedIconDatabase] iconForSiteURL:_URL withSize:WebIconSmallSize];
+        }else{
             newIcon = nil;
         }
         [self _setIcon:newIcon];
@@ -121,8 +137,10 @@
 -(void)setURL:(NSURL *)URL
 {
     if (URL != _URL) {
+        [self _retainIconInDatabase:NO];
         [_URL release];
         _URL = [URL retain];
+        [self _retainIconInDatabase:YES];
     }
 }
 
@@ -256,6 +274,7 @@
     storedURLString = [dict objectForKey: @""];
     if (storedURLString != nil) {
         _URL = [[NSURL _web_URLWithString:storedURLString] retain];
+        [self _retainIconInDatabase:YES];
     }
     
     iconURLString = [dict objectForKey:@"iconURL"];
diff --git a/WebKit/Misc.subproj/WebIconDatabase.h b/WebKit/Misc.subproj/WebIconDatabase.h
new file mode 100644
index 0000000..38e0d0d
--- /dev/null
+++ b/WebKit/Misc.subproj/WebIconDatabase.h
@@ -0,0 +1,87 @@
+/*
+ WebIconDatabase.h
+ Copyright 2001, 2002, Apple, Inc. All rights reserved.
+*/
+
+#import <Cocoa/Cocoa.h>
+
+
+/*
+
+ WebIconDatabase
+
+ Features:
+ - memory cache icons at different sizes
+ - disk storage
+ - icon update notification
+ - user/client icon customization
+
+ Uses:
+ - WebIconLoader to cache icon images
+ - UI elements to retrieve icons that represent site URLs.
+ - Save icons to disk for later use.
+ 
+ */
+
+// Sent whenever a site icon has changed. The object of the notification is the icon database.
+// Upon receiving this notification the receiver should call doesNotificationUserInfo: matchSiteURL:
+// to determine if the site URL in question has an updated icon.
+extern NSString *WebIconDidChangeNotification;
+
+extern NSString *WebIconNotificationUserInfoSiteURLKey;
+
+extern NSSize WebIconSmallSize;  // 16 x 16
+extern NSSize WebIconMediumSize; // 32 x 32
+
+ at class WebIconDatabasePrivate;
+
+ at interface WebIconDatabase : NSObject {
+
+ at private
+    WebIconDatabasePrivate *_private;
+}
+
+
+// Returns a shared instance of the icon database
++ (WebIconDatabase *)sharedIconDatabase;
+
+// Returns an icon for a web site URL from memory or disk. nil if none is found.
+// Usually called by a UI element to determine if a site URL has an associated icon.
+// Also usually called by the observer of WebIconChangedNotification after the notification is sent.
+- (NSImage *)iconForSiteURL:(NSURL *)siteURL withSize:(NSSize)size;
+
+// Customize the site icon for all web sites with the given host name.
+- (void)setIcon:(NSImage *)icon forHost:(NSString *)host;
+
+// Customize the site icon for a specific web page.
+- (void)setIcon:(NSImage *)icon forSiteURL:(NSURL *)siteURL;
+
+/*
+
+Retention
+
+Every icon in the database has a retain count.  If an icon has a retain count greater than 0, it will be written to disk for later use. If an icon's retain count equals zero it will be removed from disk.  The retain count is not persistent across launches. If the WebKit client wishes to retain an icon it should retain the icon once for every launch.  This is best done at initialization time before the database begins removing icons.  To make sure that the database does not remove unretained icons prematurely, call delayDatabaseCleanup until all desired icons are retained.  Once all are retained, call allowDatabaseCleanup.
+
+Note that an icon can be retained after the database clean-up has begun. This just has to be done before the icon is removed. Icons are removed from the database whenever new icons are added to it.
+
+Retention methods can be called for icons that are not yet in the database.
+ 
+*/
+
+// Increments the retain count of the icon.
+- (void)retainIconForSiteURL:(NSURL *)siteURL;
+
+// Decrements the retain count of the icon.
+- (void)releaseIconForSiteURL:(NSURL *)siteURL;
+
+// Only effective if called before the database begins removing icons.
+// delayDatabaseCleanUp increments an internal counter that when 0 begins the database clean-up.
+// The counter equals 0 at initialization.
+- (void)delayDatabaseCleanup;
+
+// Informs the database that it now can begin removing icons.
+// allowDatabaseCleanup decrements an internal counter that when 0 begins the database clean-up.
+// The counter equals 0 at initialization.
+- (void)allowDatabaseCleanup;
+
+ at end
diff --git a/WebKit/Misc.subproj/WebIconDatabase.m b/WebKit/Misc.subproj/WebIconDatabase.m
new file mode 100644
index 0000000..ecd03e9
--- /dev/null
+++ b/WebKit/Misc.subproj/WebIconDatabase.m
@@ -0,0 +1,638 @@
+//
+//  WebIconDatabase.m
+//  WebKit
+//
+//  Created by Chris Blumenberg on Tue Aug 27 2002.
+//  Copyright (c) 2002 __MyCompanyName__. All rights reserved.
+//
+
+#import <WebKit/WebKitDebug.h>
+#import <WebKit/WebIconDatabase.h>
+#import <WebKit/WebIconDatabasePrivate.h>
+
+#import <WebFoundation/WebNSURLExtras.h>
+#import <WebFoundation/WebFileDatabase.h>
+
+#define WebIconDatabaseDefaultDirectory ([NSString stringWithFormat:@"%@/%@", NSHomeDirectory(), @"Library/Caches/com.apple.WebKit/Icons"])
+
+#define WebIconsOnDiskKey @"WebIconsOnDisk"
+#define WebSiteURLToIconURLKey 	@"WebSiteURLToIconURLKey"
+#define WebIconURLToSiteURLsKey @"WebIconURLToSiteURLs"
+#define WebHostToSiteURLsKey @"WebHostToSiteURLs"
+
+NSString *WebIconDidChangeNotification = @"WebIconDidChangeNotification";
+NSString *WebIconNotificationUserInfoSiteURLKey = @"WebIconNotificationUserInfoSiteURLKey";
+
+NSSize WebIconSmallSize = {16, 16};
+NSSize WebIconMediumSize = {32, 32};
+
+
+ at interface WebIconDatabase (WebInternal)
+
+- (void)_createFileDatabase;
+- (void)_loadIconDictionaries;
+- (void)_updateFileDatabase;
+- (NSMutableArray *)_iconsForIconURL:(NSURL *)iconURL;
+- (NSImage *)_iconForFileURL:(NSURL *)fileURL withSize:(NSSize)size;
+- (void)_retainIconForIconURL:(NSURL *)iconURL;
+- (void)_releaseIconForIconURL:(NSURL *)iconURL;
+- (void)_retainFutureIconForSiteURL:(NSURL *)siteURL;
+- (void)_releaseFutureIconForSiteURL:(NSURL *)siteURL;
+- (void)_retainOriginalIconsOnDisk;
+- (void)_releaseOriginalIconsOnDisk;
+- (void)_sendNotificationForSiteURL:(NSURL *)siteURL;
+- (void)_addObject:(id)object toSetForKey:(id)key inDictionary:(NSMutableDictionary *)dictionary;
+- (NSURL *)_uniqueIconURL;
+- (NSImage *)_cachedIconFromArray:(NSMutableArray *)icons withSize:(NSSize)size;
+- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size;
+
+ at end
+
+
+ at implementation WebIconDatabase
+
++ (WebIconDatabase *)sharedIconDatabase
+{
+    static WebIconDatabase *database = nil;
+    
+    if (!database) {
+        database = [[WebIconDatabase alloc] init];
+    }
+    return database;
+}
+
+- init
+{
+    [super init];
+    
+    _private = [[WebIconDatabasePrivate alloc] init];
+    
+    [self _createFileDatabase];
+    [self _loadIconDictionaries];
+
+    _private->iconURLToIcons = [[NSMutableDictionary dictionary] retain];
+    _private->iconURLToRetainCount = [[NSMutableDictionary dictionary] retain];
+    _private->futureSiteURLToRetainCount = [[NSMutableDictionary dictionary] retain];
+    _private->hostToBuiltItIcons = [[NSMutableDictionary dictionary] retain];
+
+    _private->iconsToEraseWithURLs = [[NSMutableSet set] retain];
+    _private->iconsToSaveWithURLs = [[NSMutableSet set] retain];
+    
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(applicationWillTerminate:)
+                                                 name:NSApplicationWillTerminateNotification
+                                               object:NSApp];
+
+    // Retain icons on disk then release them once clean-up has begun.
+    // This gives the client the opportunity to retain them before they are erased.
+    [self _retainOriginalIconsOnDisk];
+    [self performSelector:@selector(_releaseOriginalIconsOnDisk) withObject:nil afterDelay:0];
+    
+    return self;
+}
+
+- (NSImage *)iconForSiteURL:(NSURL *)siteURL withSize:(NSSize)size
+{
+    if([siteURL isFileURL]){
+        return [self _iconForFileURL:siteURL withSize:size];
+    }
+    
+    NSMutableArray *icons = [_private->hostToBuiltItIcons objectForKey:[siteURL host]];
+
+    if(!icons){
+        NSURL *iconURL = [_private->siteURLToIconURL objectForKey:siteURL];
+        
+        if(!iconURL){
+            // Don't have it
+            //NSLog(@"iconForSiteURL no iconURL for siteURL: %@", siteURL);
+            return nil;
+        }
+
+        icons = [self _iconsForIconURL:iconURL];
+        if(!icons){
+            // This should not happen
+            //NSLog(@"iconForSiteURL no icon for iconURL: %@", iconURL);
+            return nil;
+        }        
+    }
+
+    if(size.width == 0 && size.height == 0){
+        // Don't cause a resize, just send the original in this case
+        return [icons objectAtIndex:0];
+    }else{
+        return [self _cachedIconFromArray:icons withSize:size];
+    }
+}
+
+- (void)setIcon:(NSImage *)icon forSiteURL:(NSURL *)siteURL
+{
+    if(!icon || !siteURL){
+        return;
+    }
+
+    NSURL *iconURL = [self _uniqueIconURL];
+    
+    [self _setIcon:icon forIconURL:iconURL];
+    [self _setIconURL:iconURL forSiteURL:siteURL];
+}
+
+- (void)setIcon:(NSImage *)icon forHost:(NSString *)host
+{
+    if(!icon || !host){
+        return;
+    }
+
+    NSMutableSet *siteURLs = [_private->hostToSiteURLs objectForKey:host];
+    NSURL *iconURL = [self _uniqueIconURL];
+    NSEnumerator *enumerator;
+    NSURL *siteURL;
+    
+    [self _setIcon:icon forIconURL:iconURL];
+
+    if(siteURLs){
+        enumerator = [siteURLs objectEnumerator];
+    
+        while ((siteURL = [enumerator nextObject]) != nil) {
+            [self releaseIconForSiteURL:siteURL];
+            [self _setIconURL:iconURL forSiteURL:siteURL];
+            [self retainIconForSiteURL:siteURL];
+        }
+    }
+}
+
+- (void)retainIconForSiteURL:(NSURL *)siteURL
+{
+    NSURL *iconURL = [_private->siteURLToIconURL objectForKey:siteURL];
+    
+    if(iconURL){
+        [self _retainIconForIconURL:iconURL];
+    }else{
+        // Retaining an icon not in the DB. This is OK. Just remember this.
+        [self _retainFutureIconForSiteURL:siteURL];
+    }
+}
+
+- (void)releaseIconForSiteURL:(NSURL *)siteURL
+{
+    NSURL *iconURL = [_private->siteURLToIconURL objectForKey:siteURL];
+    
+    if(iconURL){
+        [self _releaseIconForIconURL:iconURL];
+    }else{
+        // Releasing an icon not in the DB. This is OK. Just remember this.
+        [self _releaseFutureIconForSiteURL:siteURL];        
+    }
+}
+
+- (void)delayDatabaseCleanup
+{
+    if(_private->didCleanup){
+        [NSException raise:NSGenericException format:@"delayDatabaseCleanup cannot be called after cleanup has begun"];
+    }
+    
+    _private->cleanupCount++;
+    //NSLog(@"delayDatabaseCleanup %d", _private->cleanupCount);
+}
+
+- (void)allowDatabaseCleanup
+{
+    if(_private->didCleanup){
+        [NSException raise:NSGenericException format:@"allowDatabaseCleanup cannot be called after cleanup has begun"];
+    }
+    
+    _private->cleanupCount--;
+    //NSLog(@"allowDatabaseCleanup %d", _private->cleanupCount);
+
+    if(_private->cleanupCount == 0 && _private->waitingToCleanup){
+        [self _releaseOriginalIconsOnDisk];
+    }
+}
+
+- (void)applicationWillTerminate:(NSNotification *)notification
+{
+    // Should only cause a write if user quit before 3 seconds after the last _updateFileDatabase
+    [_private->fileDatabase sync];
+}
+
+ at end
+
+
+ at implementation WebIconDatabase (WebPrivate)
+
+- (void)_createFileDatabase
+{
+    // FIXME: Make defaults key public somehow
+    NSString *databaseDirectory = [[NSUserDefaults standardUserDefaults] objectForKey:@"WebIconDatabaseDirectory"];
+
+    if (!databaseDirectory) {
+        databaseDirectory = WebIconDatabaseDefaultDirectory;
+    }
+
+    _private->fileDatabase = [[WebFileDatabase alloc] initWithPath:databaseDirectory];
+    [_private->fileDatabase setSizeLimit:20000000];
+    [_private->fileDatabase open];
+}
+
+- (void)_loadIconDictionaries
+{
+    WebFileDatabase *fileDB = _private->fileDatabase;
+
+    _private->iconsOnDiskWithURLs = [fileDB objectForKey:WebIconsOnDiskKey];
+    _private->siteURLToIconURL = [fileDB objectForKey:WebSiteURLToIconURLKey];
+    _private->iconURLToSiteURLs = [fileDB objectForKey:WebIconURLToSiteURLsKey];
+    _private->hostToSiteURLs = [fileDB objectForKey:WebHostToSiteURLsKey];
+
+    if(!_private->iconsOnDiskWithURLs ||
+       !_private->siteURLToIconURL ||
+       !_private->iconURLToSiteURLs ||
+       !_private->hostToSiteURLs){
+
+        _private->iconsOnDiskWithURLs = [NSMutableSet set];
+        _private->siteURLToIconURL = [NSMutableDictionary dictionary];
+        _private->iconURLToSiteURLs = [NSMutableDictionary dictionary];
+        _private->hostToSiteURLs = [NSMutableDictionary dictionary];
+    }
+
+    [_private->iconsOnDiskWithURLs retain];
+    [_private->iconURLToSiteURLs retain];
+    [_private->siteURLToIconURL retain];
+    [_private->hostToSiteURLs retain];
+}
+
+// Only called by _setIconURL:forKey:
+- (void)_updateFileDatabase
+{
+    if(_private->cleanupCount != 0){
+        return;
+    }
+
+    //NSLog(@"_updateFileDatabase");
+
+    WebFileDatabase *fileDB = _private->fileDatabase;
+
+    NSEnumerator *enumerator;
+    NSData *iconData;
+    NSURL *iconURL;
+
+    // Erase icons that have been released that are on disk
+    enumerator = [_private->iconsToEraseWithURLs objectEnumerator];
+
+    while ((iconURL = [enumerator nextObject]) != nil) {
+        //NSLog(@"removing %@", iconURL);
+        [fileDB removeObjectForKey:iconURL];
+        [_private->iconsOnDiskWithURLs removeObject:iconURL];
+    }
+
+    // Save icons that have been retained that are not already on disk
+    enumerator = [_private->iconsToSaveWithURLs objectEnumerator];
+
+    while ((iconURL = [enumerator nextObject]) != nil) {
+        //NSLog(@"writing %@", iconURL);
+        iconData = [[self _iconForIconURL:iconURL] TIFFRepresentation];
+        [fileDB setObject:iconData forKey:iconURL];
+        [_private->iconsOnDiskWithURLs addObject:iconURL];
+    }
+    
+    [_private->iconsToEraseWithURLs removeAllObjects];
+    [_private->iconsToSaveWithURLs removeAllObjects];
+
+    // Save the icon dictionaries to disk
+    [fileDB setObject:_private->iconsOnDiskWithURLs forKey:WebIconsOnDiskKey];
+    [fileDB setObject:_private->siteURLToIconURL forKey:WebSiteURLToIconURLKey];
+    [fileDB setObject:_private->iconURLToSiteURLs forKey:WebIconURLToSiteURLsKey];
+    [fileDB setObject:_private->hostToSiteURLs forKey:WebHostToSiteURLsKey];
+}
+
+- (NSImage *)_iconForIconURL:(NSURL *)iconURL
+{
+    // The first item in the icon array is the original non-resized icon
+    return [[self _iconsForIconURL:iconURL] objectAtIndex:0];
+}
+
+- (NSMutableArray *)_iconsForIconURL:(NSURL *)iconURL
+{
+    if(!iconURL){
+        return nil;
+    }
+
+    NSMutableArray *icons = [_private->iconURLToIcons objectForKey:iconURL];
+    double start, duration;
+    
+    if(!icons){
+        // Not in memory, check disk
+        if([_private->iconsOnDiskWithURLs containsObject:iconURL]){
+            
+            start = CFAbsoluteTimeGetCurrent();
+            NSData *iconData = [_private->fileDatabase objectForKey:iconURL];
+            
+            if(iconData){
+                NSImage *icon = [[NSImage alloc] initWithData:iconData];
+                if(icon){
+                    duration = CFAbsoluteTimeGetCurrent() - start;
+                    WEBKITDEBUGLEVEL (WEBKIT_LOG_TIMING, "loading and creating icon %s took %f seconds\n",
+                                      DEBUG_OBJECT(iconURL), duration);
+                    
+                    // Cache it
+                    icons = [NSMutableArray arrayWithObject:icon];
+                    [icon release];
+                    [_private->iconURLToIcons setObject:icons forKey:iconURL];
+                }
+            }
+        }
+    }
+    
+    return icons;
+}
+
+
+- (NSImage *)_iconForFileURL:(NSURL *)fileURL withSize:(NSSize)size
+{
+    NSWorkspace *workspace = [NSWorkspace sharedWorkspace];
+    NSImage *icon;
+    
+    if([[[fileURL path] pathExtension] rangeOfString:@"htm"].length > 0){
+        if(!_private->htmlIcons){
+            icon = [workspace iconForFileType:@"html"];
+            _private->htmlIcons = [NSMutableArray arrayWithObject:icon];
+        }
+        return [self _cachedIconFromArray:_private->htmlIcons withSize:size];
+    }else{
+        icon = [workspace iconForFile:[fileURL path]];
+        [self _scaleIcon:icon toSize:size];
+        return icon;
+    }
+}
+
+- (void)_setIcon:(NSImage *)icon forIconURL:(NSURL *)iconURL
+{
+    if(!icon || !iconURL){
+        return;
+    }
+
+    NSMutableArray *icons = [_private->iconURLToIcons objectForKey:iconURL];
+    [icons removeAllObjects];
+    
+    [_private->iconURLToIcons setObject:[NSMutableArray arrayWithObject:icon] forKey:iconURL];
+
+    [self _retainIconForIconURL:iconURL];
+    
+    // Retain and release the newly created icon much like an autorelease.
+    // This gives the client enough time to retain it.
+    [self performSelector:@selector(_releaseIconForIconURL:) withObject:iconURL afterDelay:0];
+}
+
+// FIXME: fix custom icons
+- (void)_setIconURL:(NSURL *)iconURL forSiteURL:(NSURL *)siteURL
+{
+    if(!iconURL || !siteURL){
+        return;
+    }
+
+    [_private->siteURLToIconURL setObject:iconURL forKey:siteURL];
+    
+    [self _addObject:siteURL toSetForKey:iconURL inDictionary:_private->iconURLToSiteURLs];
+
+    [self _addObject:siteURL toSetForKey:[siteURL host] inDictionary:_private->hostToSiteURLs];
+    
+    NSNumber *predeterminedRetainCount = [_private->futureSiteURLToRetainCount objectForKey:siteURL];
+
+    if(predeterminedRetainCount){
+        NSNumber *retainCount = [_private->iconURLToRetainCount objectForKey:iconURL];
+
+        if(!retainCount){
+            //NSLog(@"_setIconURL: forKey: no retainCount for iconURL");
+            return;
+        }
+
+        int newRetainCount = [retainCount intValue] + [predeterminedRetainCount intValue];
+        [_private->iconURLToRetainCount setObject:[NSNumber numberWithInt:newRetainCount] forKey:iconURL];
+        [_private->futureSiteURLToRetainCount removeObjectForKey:siteURL];
+    }
+
+    [self _sendNotificationForSiteURL:siteURL];
+    [self _updateFileDatabase];
+}
+
+- (void)_setBuiltInIcon:(NSImage *)icon forHost:(NSString *)host
+{
+    if(!icon || !host){
+        return;
+    }
+    
+    NSMutableSet *siteURLs = [_private->hostToSiteURLs objectForKey:host];
+    NSURL *siteURL;
+    
+    [_private->hostToBuiltItIcons setObject:[NSMutableArray arrayWithObject:icon] forKey:host];
+
+    if(siteURLs){
+        NSEnumerator *enumerator = [siteURLs objectEnumerator];
+        while ((siteURL = [enumerator nextObject]) != nil) {
+            [self _sendNotificationForSiteURL:siteURL];
+        }
+    }
+}
+
+- (void)_retainIconForIconURL:(NSURL *)iconURL
+{
+    NSNumber *retainCount = [_private->iconURLToRetainCount objectForKey:iconURL];
+    int newRetainCount;
+    
+    if(!retainCount){
+        newRetainCount = 1;
+    }else{
+        newRetainCount = [retainCount intValue] + 1;
+    }
+
+    [_private->iconURLToRetainCount setObject:[NSNumber numberWithInt:newRetainCount] forKey:iconURL];
+
+    if(newRetainCount == 1 && ![_private->iconsOnDiskWithURLs containsObject:iconURL]){
+        [_private->iconsToSaveWithURLs addObject:iconURL];
+        [_private->iconsToEraseWithURLs removeObject:iconURL];
+    }
+
+    //NSLog(@"_retainIconForIconURL: %@ %d", iconURL, newRetainCount);
+}
+
+- (void)_releaseIconForIconURL:(NSURL *)iconURL
+{
+    NSNumber *retainCount = [_private->iconURLToRetainCount objectForKey:iconURL];
+
+    if(!retainCount){
+        //NSLog(@"_retainIconForIconURL: no retainCount for iconURL");
+        return;
+    }
+    
+    int newRetainCount = [retainCount intValue] - 1;
+    [_private->iconURLToRetainCount setObject:[NSNumber numberWithInt:newRetainCount] forKey:iconURL];
+
+    if(newRetainCount == 0){
+
+        if([_private->iconsOnDiskWithURLs containsObject:iconURL]){
+            [_private->iconsToEraseWithURLs addObject:iconURL];
+            [_private->iconsToSaveWithURLs removeObject:iconURL];
+        }
+
+        // Remove the icon's images
+        NSMutableArray *icons = [_private->iconURLToIcons objectForKey:iconURL];
+        [icons removeAllObjects];
+        [_private->iconURLToIcons removeObjectForKey:iconURL];
+
+        // Remove the icon's retain count
+        [_private->iconURLToRetainCount removeObjectForKey:iconURL];
+
+        // Remove the icon's associated site URLs
+        NSMutableSet *siteURLsForHost, *siteURLs;
+        NSEnumerator *enumerator;
+        NSURL *siteURL;
+        
+        siteURLs = [_private->iconURLToSiteURLs objectForKey:iconURL];
+        [_private->siteURLToIconURL removeObjectsForKeys:[siteURLs allObjects]];
+
+        enumerator = [siteURLs objectEnumerator];
+        while ((siteURL = [enumerator nextObject]) != nil) {
+            siteURLsForHost = [_private->hostToSiteURLs objectForKey:[siteURL host]];
+            [siteURLsForHost removeObject:siteURL];
+            if([siteURLsForHost count] == 0){
+                [_private->hostToSiteURLs removeObjectForKey:[siteURL host]];
+            }
+        }
+        
+        [siteURLs removeAllObjects];
+        [_private->iconURLToSiteURLs removeObjectForKey:iconURL];
+    }
+
+    //NSLog(@"_releaseIconForIconURL: %@ %d", iconURL, newRetainCount);
+}
+
+- (void)_retainFutureIconForSiteURL:(NSURL *)siteURL
+{
+    NSNumber *retainCount = [_private->futureSiteURLToRetainCount objectForKey:siteURL];
+    int newRetainCount;
+
+    if(retainCount){
+        newRetainCount = [retainCount intValue] + 1;
+    }else{
+        newRetainCount = 1;
+    }
+
+    [_private->futureSiteURLToRetainCount setObject:[NSNumber numberWithInt:newRetainCount] forKey:siteURL];
+
+    ////NSLog(@"_setFutureIconRetainToDictionary: %@ %d", key, newRetainCount);
+}
+
+- (void)_releaseFutureIconForSiteURL:(NSURL *)siteURL
+{
+    NSNumber *retainCount = [_private->futureSiteURLToRetainCount objectForKey:siteURL];
+
+    if(!retainCount){
+        [NSException raise:NSGenericException
+                    format:@"Releasing a future icon that was not previously retained."];
+    }
+
+    int newRetainCount = [retainCount intValue] - 1;
+
+    if(newRetainCount == 0){
+        [_private->futureSiteURLToRetainCount removeObjectForKey:siteURL];
+    }else{
+        [_private->futureSiteURLToRetainCount setObject:[NSNumber numberWithInt:newRetainCount] forKey:siteURL];
+    }
+
+    ////NSLog(@"_setFutureIconReleaseToDictionary: %@ %d", key, newRetainCount);
+}
+
+- (void)_retainOriginalIconsOnDisk
+{
+    NSEnumerator *enumerator;
+    NSURL *iconURL;
+
+    //NSLog(@"_retainOriginalOnDiskIcons");
+    enumerator = [_private->iconsOnDiskWithURLs objectEnumerator];
+
+    while ((iconURL = [enumerator nextObject]) != nil) {
+        [self _retainIconForIconURL:iconURL];
+    }
+}
+
+- (void)_releaseOriginalIconsOnDisk
+{
+    if(_private->cleanupCount > 0){
+        _private->waitingToCleanup = YES;
+        return;
+    }
+    //NSLog(@"_releaseOriginalOnDiskIcons, %@", _private->iconsOnDiskWithURLs);
+    NSEnumerator *enumerator = [_private->iconsOnDiskWithURLs objectEnumerator];
+    NSURL *iconURL;
+
+    while ((iconURL = [enumerator nextObject]) != nil) {
+        [self _releaseIconForIconURL:iconURL];
+    }
+
+    _private->didCleanup = YES;
+}
+
+- (void)_sendNotificationForSiteURL:(NSURL *)siteURL
+{
+    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:siteURL forKey:WebIconNotificationUserInfoSiteURLKey];
+    [[NSNotificationCenter defaultCenter] postNotificationName:WebIconDidChangeNotification
+                                                        object:self
+                                                      userInfo:userInfo];
+}
+
+- (void)_addObject:(id)object toSetForKey:(id)key inDictionary:(NSMutableDictionary *)dictionary
+{
+    NSMutableSet *set = [dictionary objectForKey:key];
+
+    if(!set){
+        set = [NSMutableSet set];
+    }
+        
+    [set addObject:object];
+    [dictionary setObject:set forKey:key];
+}
+
+- (NSURL *)_uniqueIconURL
+{
+    CFUUIDRef uid = CFUUIDCreate(NULL);
+    NSString *string = (NSString *)CFUUIDCreateString(NULL, uid);
+    NSURL *uniqueURL = [NSURL _web_URLWithString:[NSString stringWithFormat:@"icon:%@", string]];
+
+    CFRelease(uid);
+    CFRelease(string);
+
+    return uniqueURL;
+}
+
+- (NSImage *)_cachedIconFromArray:(NSMutableArray *)icons withSize:(NSSize)size
+{
+    NSEnumerator *enumerator = [icons objectEnumerator];
+    NSImage *icon;
+    
+    while ((icon = [enumerator nextObject]) != nil) {
+        if(NSEqualSizes([icon size], size)){
+            return icon;
+        }
+    }
+
+    // The first item in the icon array is the original non-resized icon
+    // Assume that it's best to resize the original
+    NSImage *originalIcon = [icons objectAtIndex:0];
+    icon = [originalIcon copy];
+    [self _scaleIcon:icon toSize:size];
+
+    // Cache it
+    [icons addObject:icon];
+
+    return [icon autorelease];
+}
+
+- (void)_scaleIcon:(NSImage *)icon toSize:(NSSize)size
+{
+    [icon setScalesWhenResized:YES];
+    [icon setSize:size];
+}
+
+ at end
+
+ at implementation WebIconDatabasePrivate
+
+ at end
diff --git a/WebKit/Misc.subproj/WebIconDatabasePrivate.h b/WebKit/Misc.subproj/WebIconDatabasePrivate.h
new file mode 100644
index 0000000..f10cd21
--- /dev/null
+++ b/WebKit/Misc.subproj/WebIconDatabasePrivate.h
@@ -0,0 +1,54 @@
+/*
+ *  WebIconDatabasePrivate.h
+ *  
+ *
+ *  Created by Chris Blumenberg on Tue Aug 27 2002.
+ *  Copyright (c) 2002 Apple Computer Inc. All rights reserved.
+ *
+ */
+
+#import <Cocoa/Cocoa.h>
+
+ at class WebFileDatabase;
+
+ at interface WebIconDatabasePrivate : NSObject {
+
+ at public
+    WebFileDatabase *fileDatabase;
+
+    NSMutableDictionary *iconURLToIcons;
+    NSMutableDictionary *iconURLToRetainCount;
+    NSMutableDictionary *iconURLToSiteURLs;
+    NSMutableDictionary *siteURLToIconURL;    
+    NSMutableDictionary *futureSiteURLToRetainCount;
+    NSMutableDictionary *hostToSiteURLs;
+    NSMutableDictionary *hostToBuiltItIcons;
+    
+    NSMutableSet *iconsOnDiskWithURLs;
+    NSMutableSet *iconsToEraseWithURLs;
+    NSMutableSet *iconsToSaveWithURLs;
+    
+    int cleanupCount;
+
+    BOOL didCleanup;
+    BOOL waitingToCleanup;
+
+    NSMutableArray *htmlIcons;
+}
+
+ at end
+
+ at interface WebIconDatabase (WebPrivate)
+
+// Called by WebIconLoader to determine if a load is necessary.
+- (NSImage *)_iconForIconURL:(NSURL *)iconURL;
+
+// Called by WebIconLoader after loading an icon.
+- (void)_setIcon:(NSImage *)icon forIconURL:(NSURL *)iconURL;
+
+// Called by WebDataSource to bind a web site URL to a icon URL and icon image.
+- (void)_setIconURL:(NSURL *)iconURL forSiteURL:(NSURL *)siteURL;
+
+- (void)_setBuiltInIcon:(NSImage *)icon forHost:(NSString *)host;
+
+ at end
\ No newline at end of file
diff --git a/WebKit/Misc.subproj/WebIconLoader.h b/WebKit/Misc.subproj/WebIconLoader.h
index 372a61d..495d932 100644
--- a/WebKit/Misc.subproj/WebIconLoader.h
+++ b/WebKit/Misc.subproj/WebIconLoader.h
@@ -29,7 +29,6 @@
 - (NSURL *)URL;
 - (id)delegate;
 - (void)setDelegate:(id)delegate;
-- (NSImage *)iconFromCache;
 - (void)startLoading;
 - (void)stopLoading;
 @end
diff --git a/WebKit/Misc.subproj/WebIconLoader.m b/WebKit/Misc.subproj/WebIconLoader.m
index 451e584..2394897 100644
--- a/WebKit/Misc.subproj/WebIconLoader.m
+++ b/WebKit/Misc.subproj/WebIconLoader.m
@@ -6,6 +6,9 @@
 //  Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
 //
 
+#import <WebKit/WebKitDebug.h>
+#import <WebKit/WebIconDatabase.h>
+#import <WebKit/WebIconDatabasePrivate.h>
 #import <WebKit/WebIconLoader.h>
 
 #import <WebFoundation/WebFoundation.h>
@@ -68,7 +71,7 @@
 
     if([[path pathExtension] rangeOfString:@"htm"].length != 0){
         if(!htmlIcon){
-            htmlIcon = [[[NSWorkspace sharedWorkspace] iconForFile:path] retain];
+            htmlIcon = [[[NSWorkspace sharedWorkspace] iconForFileType:@"html"] retain];
             [[self class] _resizeImage:htmlIcon];
         }
         icon = htmlIcon;
@@ -104,16 +107,6 @@
     return _private->URL;
 }
 
-- (NSMutableDictionary *)_icons{
-    static NSMutableDictionary *icons = nil;
-
-    if(!icons){
-        icons = [[NSMutableDictionary dictionary] retain];
-    }
-    
-    return icons;
-}
-
 - (id)delegate
 {
     return _private->delegate;
@@ -124,45 +117,13 @@
     _private->delegate = delegate;
 }
 
-- (NSImage *)iconFromCache
-{
-    NSImage *icon = [[self _icons] objectForKey:_private->URL];
-    
-    if (icon) {
-        return icon;
-    }
-
-    NSDictionary *attributes, *headers;
-    
-    headers = [NSDictionary dictionaryWithObject:@"only-if-cached" forKey:@"Cache-Control"];
-    attributes = [NSDictionary dictionaryWithObject:headers forKey:WebHTTPResourceHandleRequestHeaders];
-    
-    WebResourceHandle *handle = [[WebResourceHandle alloc] initWithURL:_private->URL
-                                                             userAgent:nil
-                                                            attributes:attributes
-                                                                 flags:WebResourceHandleFlagNone];
-    if (handle) {        
-        NSData *data = [handle loadInForeground];
-        if (data) {
-            icon = [[[NSImage alloc] initWithData:data] autorelease];
-            if (icon) {
-                [[self class] _resizeImage:icon];
-                [[self _icons] setObject:icon forKey:_private->URL];
-            }
-        }
-        [handle release];
-    }
-    
-    return icon;
-}
-
 - (void)startLoading
 {
     if (_private->handle != nil) {
         return;
     }
-    
-    NSImage *icon = [[self _icons] objectForKey:_private->URL];
+
+    NSImage *icon = [[WebIconDatabase sharedIconDatabase] _iconForIconURL:_private->URL];
     if (icon) {
         [_private->delegate iconLoader:self receivedPageIcon:icon];
         return;
@@ -198,8 +159,7 @@
 {
     NSImage *icon = [[NSImage alloc] initWithData:data];
     if (icon) {
-        [[self class] _resizeImage:icon];
-        [[self _icons] setObject:icon forKey:_private->URL];
+        [[WebIconDatabase sharedIconDatabase] _setIcon:icon forIconURL:_private->URL];
         [_private->delegate iconLoader:self receivedPageIcon:icon];
         [icon release];
     }
diff --git a/WebKit/WebKit.exp b/WebKit/WebKit.exp
index ea6af54..097e7c2 100644
--- a/WebKit/WebKit.exp
+++ b/WebKit/WebKit.exp
@@ -14,6 +14,7 @@
 .objc_class_name_WebHistory
 .objc_class_name_WebHistoryItem
 .objc_class_name_WebIconLoader
+.objc_class_name_WebIconDatabase
 .objc_class_name_WebKitStatistics
 .objc_class_name_WebLoadProgress
 .objc_class_name_WebPreferences
@@ -29,3 +30,7 @@ _WebContextMenuElementStringKey
 _WebContextMenuElementImageKey
 _WebContextMenuElementFrameKey
 _WebHistoryEntriesChangedNotification
+_WebIconDidChangeNotification
+_WebIconSmallSize
+_WebIconMediumSize
+
diff --git a/WebKit/WebKit.pbproj/project.pbxproj b/WebKit/WebKit.pbproj/project.pbxproj
index 48b3e5c..4882dd5 100644
--- a/WebKit/WebKit.pbproj/project.pbxproj
+++ b/WebKit/WebKit.pbproj/project.pbxproj
@@ -269,6 +269,8 @@
 				F5E7B24703025CE801A80180,
 				F501251D0302EA04018635CE,
 				F560BEBE030DAF4401C1A526,
+				F528E3EC031E91AD01CA2ACA,
+				F528E3EE031E91AD01CA2ACA,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -356,6 +358,7 @@
 				F5E7B24803025CE801A80180,
 				F501251E0302EA04018635CE,
 				F560BEBF030DAF4401C1A526,
+				F528E3ED031E91AD01CA2ACA,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -423,6 +426,9 @@
 				F5FBAB9002B88CBF01FF6074,
 				3944607A020F50ED0ECA1767,
 				3944607B020F50ED0ECA1767,
+				F528E3E9031E91AD01CA2ACA,
+				F528E3EB031E91AD01CA2ACA,
+				F528E3EA031E91AD01CA2ACA,
 				F5934C8802E894F50197FBCF,
 				F5934C8902E894F50197FBCF,
 				2568C72C0174912D0ECA149E,
@@ -1555,6 +1561,45 @@
 			settings = {
 			};
 		};
+		F528E3E9031E91AD01CA2ACA = {
+			isa = PBXFileReference;
+			path = WebIconDatabase.h;
+			refType = 4;
+		};
+		F528E3EA031E91AD01CA2ACA = {
+			isa = PBXFileReference;
+			path = WebIconDatabase.m;
+			refType = 4;
+		};
+		F528E3EB031E91AD01CA2ACA = {
+			isa = PBXFileReference;
+			path = WebIconDatabasePrivate.h;
+			refType = 4;
+		};
+		F528E3EC031E91AD01CA2ACA = {
+			fileRef = F528E3E9031E91AD01CA2ACA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Public,
+				);
+			};
+		};
+		F528E3ED031E91AD01CA2ACA = {
+			fileRef = F528E3EA031E91AD01CA2ACA;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F528E3EE031E91AD01CA2ACA = {
+			fileRef = F528E3EB031E91AD01CA2ACA;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+					Private,
+				);
+			};
+		};
 		F52BD8BA02DF4FBD018635CA = {
 			fileRef = F8216299029F4FB501000131;
 			isa = PBXBuildFile;
diff --git a/WebKit/WebView.subproj/WebDataSourcePrivate.m b/WebKit/WebView.subproj/WebDataSourcePrivate.m
index e3f0e45..2b85125 100644
--- a/WebKit/WebView.subproj/WebDataSourcePrivate.m
+++ b/WebKit/WebView.subproj/WebDataSourcePrivate.m
@@ -14,6 +14,8 @@
 #import <WebKit/WebHTMLRepresentation.h>
 #import <WebKit/WebHTMLViewPrivate.h>
 #import <WebKit/WebPreferences.h>
+#import <WebKit/WebIconDatabase.h>
+#import <WebKit/WebIconDatabasePrivate.h>
 #import <WebKit/WebIconLoader.h>
 #import <WebKit/WebImageRepresentation.h>
 #import <WebKit/WebLocationChangeHandler.h>
@@ -444,9 +446,10 @@
     [[[[self webFrame] webView] documentView] dataSourceUpdated:self];
 }
 
-- (void)iconLoader:(WebIconLoader *)iconLoader receivedPageIcon:(NSImage *)image;
+- (void)iconLoader:(WebIconLoader *)iconLoader receivedPageIcon:(NSImage *)icon;
 {
-    [[_private->controller locationChangeHandler] receivedPageIcon:image fromURL:[iconLoader URL] forDataSource:self];
+    [[WebIconDatabase sharedIconDatabase] _setIconURL:[iconLoader URL] forSiteURL:[self URL]];
+    [[_private->controller locationChangeHandler] receivedPageIcon:icon fromURL:[iconLoader URL] forDataSource:self];
 }
 
 - (void)_loadIcon
@@ -455,23 +458,26 @@
 
     if([self isMainDocument] && !_private->mainDocumentError){
         
-        // If no icon URL has been set using the LINK tag, use the icon at the server's root directory
-        // If it is file URL, return its icon provided by NSWorkspace.
-        if(_private->iconURL == nil){
-            NSURL *dataSourceURL = [self URL];
-    
-            if([dataSourceURL isFileURL]){
-                NSImage *icon = [WebIconLoader iconForFileAtPath:[dataSourceURL path]];
-                [[_private->controller locationChangeHandler] receivedPageIcon:icon fromURL:nil forDataSource:self];
-            } else {
+        NSURL *dataSourceURL = [self URL];
+
+        NSImage *icon = [[WebIconDatabase sharedIconDatabase] iconForSiteURL:dataSourceURL withSize:NSMakeSize(0,0)];
+
+        if(icon){
+            // Return the icon immediately if the db already has it
+            [[_private->controller locationChangeHandler] receivedPageIcon:icon fromURL:nil forDataSource:self];
+        }else{
+            
+            if(!_private->iconURL){
+                // No icon URL from the LINK tag so try the server's root
                 _private->iconURL = [[NSURL _web_URLWithString:@"/favicon.ico" relativeToURL:dataSourceURL] retain];
             }
-        }
 
-        if(_private->iconURL != nil){
-            _private->iconLoader = [[WebIconLoader alloc] initWithURL:_private->iconURL];
-            [_private->iconLoader setDelegate:self];
-            [_private->iconLoader startLoading];
+            if(_private->iconURL != nil){
+                // Load it
+                _private->iconLoader = [[WebIconLoader alloc] initWithURL:_private->iconURL];
+                [_private->iconLoader setDelegate:self];
+                [_private->iconLoader startLoading];
+            }
         }
     }
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list