- (void)_clearDictionaries;
- (void)_createFileDatabase;
- (void)_loadIconDictionaries;
-- (void)_updateFileDatabase;
-- (void)_forgetIconForIconURLString:(NSString *)iconURLString;
-- (NSMutableDictionary *)_iconsForIconURLString:(NSString *)iconURL;
- (NSImage *)_iconForFileURL:(NSString *)fileURL withSize:(NSSize)size;
-- (void)_retainIconForIconURLString:(NSString *)iconURL;
-- (void)_releaseIconForIconURLString:(NSString *)iconURL;
-- (void)_retainOriginalIconsOnDisk;
-- (void)_releaseOriginalIconsOnDisk;
- (void)_resetCachedWebPreferences:(NSNotification *)notification;
-- (int)_totalRetainCountForIconURLString:(NSString *)iconURLString;
- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons;
- (NSMutableDictionary *)_iconsBySplittingRepresentationsOfIcon:(NSImage *)icon;
- (NSImage *)_iconFromDictionary:(NSMutableDictionary *)icons forSize:(NSSize)size cache:(BOOL)cache;
[self _createFileDatabase];
[self _loadIconDictionaries];
- _isClosing = NO;
-
#ifdef ICONDEBUG
_private->databaseBridge = [WebIconDatabaseBridge sharedBridgeInstance];
if (_private->databaseBridge) {
}
[self _convertToWebCoreFormat];
-#else
- _private->databaseBridge = nil;
#endif
-
+
_private->iconURLToIcons = [[NSMutableDictionary alloc] init];
_private->iconURLToExtraRetainCount = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
_private->pageURLToRetainCount = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
// FIXME - Once the new iconDB is the only game in town, we need to remove any of the WebFileDatabase code
// that is threaded and expects certain files to exist - certain files we rip right out from underneath it
// in the _convertToWebCoreFormat method
-#ifndef ICONDEBUG
- // 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];
-#endif
return self;
}
if (!URL || ![self _isEnabled])
return [self defaultIconWithSize:size];
+ // <rdar://problem/4697934> - Move the handling of FileURLs to WebCore and implement in ObjC++
if ([URL _webkit_isFileURL])
return [self _iconForFileURL:URL withSize:size];
#ifdef ICONDEBUG
NSImage* image = [_private->databaseBridge iconForPageURL:URL withSize:size];
-
- // FIXME - We currently don't embed the default icon in the new WebCore IconDB, so we'll return the old version of it;
return image ? image : [self defaultIconWithSize:size];
#endif
-
- NSString *iconURLString = [_private->pageURLToIconURL objectForKey:URL];
- if (!iconURLString)
- // Don't have it
- return [self defaultIconWithSize:size];
-
- NSMutableDictionary *icons = [self _iconsForIconURLString:iconURLString];
-
- if (!icons) {
- if (![_private->iconURLsWithNoIcons containsObject:iconURLString]) {
- // We used to have this icon, but don't have it anymore for some reason. (Bug? Deleted from
- // disk behind our back?). Forget that we ever had it so it will be re-fetched next time.
- LOG_ERROR("WebIconDatabase used to contain %@, but the icon file is missing. Now forgetting that we ever knew about this icon.", iconURLString);
- [self _forgetIconForIconURLString:iconURLString];
- }
- return [self defaultIconWithSize:size];
- }
-
- return [self _iconFromDictionary:icons forSize:size cache:cache];
}
- (NSImage *)iconForURL:(NSString *)URL withSize:(NSSize)size
NSString* iconurl = [_private->databaseBridge iconURLForPageURL:URL];
return iconurl;
#endif
-
- return URL ? [_private->pageURLToIconURL objectForKey:URL] : nil;
}
- (NSImage *)defaultIconWithSize:(NSSize)size
#ifdef ICONDEBUG
return [_private->databaseBridge defaultIconWithSize:size];
#endif
-
- if (!_private->defaultIcons) {
- NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:@"url_icon" ofType:@"tiff"];
- if (path) {
- NSImage *icon = [[NSImage alloc] initByReferencingFile:path];
- _private->defaultIcons = [[NSMutableDictionary dictionaryWithObject:icon
- forKey:[NSValue valueWithSize:[icon size]]] retain];
- [icon release];
- }
- }
-
- return [self _iconFromDictionary:_private->defaultIcons forSize:size cache:YES];
}
- (void)retainIconForURL:(NSString *)URL
[_private->databaseBridge retainIconForURL:URL];
return;
#endif
-
- WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, URL);
- CFDictionarySetValue(_private->pageURLToRetainCount, URL, (void *)(retainCount + 1));
-
}
- (void)releaseIconForURL:(NSString *)pageURL
ASSERT(pageURL);
if (![self _isEnabled])
return;
-
+
#ifdef ICONDEBUG
[_private->databaseBridge releaseIconForURL:pageURL];
return;
#endif
-
- WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, pageURL);
-
- if (retainCount <= 0) {
- LOG_ERROR("The icon for %@ was released more times than it was retained.", pageURL);
- return;
- }
-
- WebNSUInteger newRetainCount = retainCount - 1;
-
- if (newRetainCount == 0) {
- // Forget association between this page URL and a retain count
- CFDictionaryRemoveValue(_private->pageURLToRetainCount, pageURL);
-
- // If there's a known iconURL for this page URL, we need to do more cleanup
- NSString *iconURL = [_private->pageURLToIconURL objectForKey:pageURL];
- if (iconURL != nil) {
- // If there are no other retainers of this icon, forget it entirely
- if ([self _totalRetainCountForIconURLString:iconURL] == 0) {
- [self _forgetIconForIconURLString:iconURL];
- } else {
- // There's at least one other retainer of this icon, so we need to forget the
- // two-way links between this page URL and the icon URL, without blowing away
- // the icon entirely.
- id pageURLs = [_private->iconURLToPageURLs objectForKey:iconURL];
- if ([pageURLs isKindOfClass:[NSMutableSet class]]) {
- ASSERT([pageURLs containsObject:pageURL]);
- [pageURLs removeObject:pageURL];
-
- // Maybe this was the last page URL mapped to this icon URL
- if ([(NSMutableSet *)pageURLs count] == 0) {
- [_private->iconURLToPageURLs removeObjectForKey:iconURL];
- }
- } else {
- // Only one page URL was associated with this icon URL; it must have been us
- ASSERT([pageURLs isKindOfClass:[NSString class]]);
- ASSERT([pageURLs isEqualToString:pageURL]);
- [_private->iconURLToPageURLs removeObjectForKey:pageURL];
- }
-
- // Remove iconURL from this dictionary last, since this might be the last
- // reference and we need to use it as a key for _private->iconURLToPageURLs above.
- [_private->pageURLToIconURL removeObjectForKey:pageURL];
- }
- }
- } else {
- CFDictionarySetValue(_private->pageURLToRetainCount, pageURL, (void *)newRetainCount);
- }
-}
-
-- (void)delayDatabaseCleanup
-{
- if (![self _isEnabled]) {
- return;
- }
-
- if(_private->didCleanup){
- LOG_ERROR("delayDatabaseCleanup cannot be called after cleanup has begun");
- return;
- }
-
- _private->cleanupCount++;
-}
-
-- (void)allowDatabaseCleanup
-{
- if (![self _isEnabled]) {
- return;
- }
-
- if(_private->didCleanup){
- LOG_ERROR("allowDatabaseCleanup cannot be called after cleanup has begun");
- return;
- }
-
- _private->cleanupCount--;
-
- if(_private->cleanupCount == 0 && _private->waitingToCleanup){
- [self _releaseOriginalIconsOnDisk];
- }
}
-
@end
- (void)removeAllIcons
{
- NSArray *keys = [(NSDictionary *)_private->iconURLToPageURLs allKeys];
- unsigned count = [keys count];
- for (unsigned i = 0; i < count; i++)
- [self _forgetIconForIconURLString:[keys objectAtIndex:i]];
-
- // Delete entire file database immediately. This has at least three advantages over waiting for
- // _updateFileDatabase to execute:
- // (1) _updateFileDatabase won't execute until an icon has been added
- // (2) this is faster
- // (3) this deletes all the on-disk hierarchy (especially useful if due to past problems there are
- // some stale files in that hierarchy)
- [_private->fileDatabase removeAllObjects];
- [_private->iconsToEraseWithURLs removeAllObjects];
- [_private->iconsToSaveWithURLs removeAllObjects];
- [_private->iconURLsBoundDuringPrivateBrowsing removeAllObjects];
- [_private->pageURLsBoundDuringPrivateBrowsing removeAllObjects];
- [self _clearDictionaries];
- [[NSNotificationCenter defaultCenter] postNotificationName:WebIconDatabaseDidRemoveAllIconsNotification
- object:self
- userInfo:nil];
+ // FIXME - <rdar://problem/4678414>
+ // Need to create a bridge method that calls through to WebCore and performs a wipe of the DB there
}
+
- (BOOL)isIconExpiredForIconURL:(NSString *)iconURL
{
return [_private->databaseBridge isIconExpiredForIconURL:iconURL];
return (_private->fileDatabase != nil);
}
-- (void)_setIcon:(NSImage *)icon forIconURL:(NSString *)iconURL
+- (void)_setIconData:(NSData *)data forIconURL:(NSString *)iconURL
{
- ASSERT(icon);
+ ASSERT(data);
ASSERT(iconURL);
- ASSERT([self _isEnabled]);
-
- NSMutableDictionary *icons = [self _iconsBySplittingRepresentationsOfIcon:icon];
-
- if (!icons)
- return;
-
- [_private->iconURLToIcons setObject:icons forKey:iconURL];
-
- // Don't update any icon information on disk during private browsing. Remember which icons have been
- // affected during private browsing so we can forget this information when private browsing is turned off.
- if (_private->privateBrowsingEnabled)
- [_private->iconURLsBoundDuringPrivateBrowsing addObject:iconURL];
-
- [self _retainIconForIconURLString:iconURL];
+ ASSERT([self _isEnabled]);
- // Release the newly created icon much like an autorelease.
- // This gives the client enough time to retain it.
- // FIXME: Should use an actual autorelease here using a proxy object instead.
- [self performSelector:@selector(_releaseIconForIconURLString:) withObject:iconURL afterDelay:0];
+ [_private->databaseBridge _setIconData:data forIconURL:iconURL];
}
- (void)_setHaveNoIconForIconURL:(NSString *)iconURL
[_private->databaseBridge _setHaveNoIconForIconURL:iconURL];
return;
#endif
-
- [_private->iconURLsWithNoIcons addObject:iconURL];
-
- // Don't update any icon information on disk during private browsing. Remember which icons have been
- // affected during private browsing so we can forget this information when private browsing is turned off.
- if (_private->privateBrowsingEnabled)
- [_private->iconURLsBoundDuringPrivateBrowsing addObject:iconURL];
-
- [self _retainIconForIconURLString:iconURL];
-
- // Release the newly created icon much like an autorelease.
- // This gives the client enough time to retain it.
- // FIXME: Should use an actual autorelease here using a proxy object instead.
- [self performSelector:@selector(_releaseIconForIconURLString:) withObject:iconURL afterDelay:0];
}
ASSERT(iconURL);
ASSERT(URL);
ASSERT([self _isEnabled]);
- ASSERT(_private->pageURLToIconURL);
#ifdef ICONDEBUG
- [_private->databaseBridge _setIconURL:iconURL forPageURL:URL];
- [self _sendNotificationForURL:URL];
- return;
-#endif
-
- if ([[_private->pageURLToIconURL objectForKey:URL] isEqualToString:iconURL]) {
- // Don't do any work if the icon URL is already bound to the site URL
- return;
- }
-
- // Keep track of which entries in pageURLToIconURL were created during private browsing so that they can be skipped
- // when saving to disk.
- if (_private->privateBrowsingEnabled)
- [_private->pageURLsBoundDuringPrivateBrowsing addObject:URL];
-
- [_private->pageURLToIconURL setObject:iconURL forKey:URL];
- [_private->iconURLToPageURLs _web_setObjectUsingSetIfNecessary:URL forKey:iconURL];
-
- if ([_private->iconURLsWithNoIcons containsObject:iconURL]) {
+ // FIXME - The following comment is a holdover from the old icon DB, which handled missing icons
+ // differently than the new db. It would return early if the icon is in the negative cache,
+ // avoiding the notification. We should explore and see if a similar optimization can take place-
// If the icon is in the negative cache (ie, there is no icon), avoid the
// work of delivering a notification for it or saving it to disk. This is a significant
// win on the iBench HTML test.
- // This return must occur after the dictionary set calls above, so the icon record
- // is properly retained. Otherwise, we'll forget that the site had no icon, and
- // inefficiently request its icon again.
- return;
- }
+ // FIXME - The following comment is also a holdover - if the iconURL->pageURL mapping was already the
+ // same, the notification would again be avoided - we should try to do this, too.
+ // Don't do any work if the icon URL is already bound to the site URL
+
+ // A possible solution for both of these is to have the bridge method return a BOOL saying "Yes, notify" or
+ // "no, don't bother notifying"
+ [_private->databaseBridge _setIconURL:iconURL forPageURL:URL];
[self _sendNotificationForURL:URL];
- [self _updateFileDatabase];
+ return;
+#endif
}
- (BOOL)_hasEntryForIconURL:(NSString *)iconURL;
ASSERT([self _isEnabled]);
#ifdef ICONDEBUG
- BOOL result = [_private->databaseBridge _hasEntryForIconURL:iconURL];
- if (result)
- LOG(IconDatabase, "NewDB has icon for IconURL %@", iconURL);
- else
- LOG(IconDatabase, "NewDB has NO icon for IconURL %@", iconURL);
- return result;
+ return [_private->databaseBridge _hasEntryForIconURL:iconURL];
#endif
-
- return (([_private->iconURLToIcons objectForKey:iconURL] ||
- [_private->iconURLsWithNoIcons containsObject:iconURL] ||
- [_private->iconsOnDiskWithURLs containsObject:iconURL]) &&
- [self _totalRetainCountForIconURLString:iconURL] > 0);
}
- (void)_sendNotificationForURL:(NSString *)URL
_private->originalIconsOnDiskWithURLs = [iconsOnDiskWithURLs copy];
}
-// Only called by _setIconURL:forKey:
-- (void)_updateFileDatabase
-{
- if (_private->cleanupCount != 0)
- return;
- WebFileDatabase *fileDB = _private->fileDatabase;
- if (!fileDB) {
- LOG_ERROR("Couldn't update file database because it didn't exist");
- return;
- }
-
- [fileDB setObject:[NSNumber numberWithInt:WebIconDatabaseCurrentVersion] forKey:WebIconDatabaseVersionKey];
-
- // Erase icons that have been released that are on disk.
- // Must remove icons before writing them to disk or else we could potentially remove the newly written ones.
- NSEnumerator *enumerator = [_private->iconsToEraseWithURLs objectEnumerator];
- NSString *iconURLString;
-
- while ((iconURLString = [enumerator nextObject]) != nil) {
- [fileDB removeObjectForKey:iconURLString];
- [_private->iconsOnDiskWithURLs removeObject:iconURLString];
- }
-
- // Save icons that have been retained that are not already on disk
- enumerator = [_private->iconsToSaveWithURLs objectEnumerator];
-
- while ((iconURLString = [enumerator nextObject]) != nil) {
- NSMutableDictionary *icons = [_private->iconURLToIcons objectForKey:iconURLString];
- if (icons) {
- // Save the 16 x 16 size icons as this is the only size that Safari uses.
- // If we ever use larger sizes, we should save the largest size so icons look better when scaling up.
- // This also works around the problem with cnet's blank 32x32 icon (3105486).
- NSImage *icon = [icons objectForKey:[NSValue valueWithSize:NSMakeSize(16,16)]];
- if (!icon) {
- // In case there is no 16 x 16 size.
- icon = [self _largestIconFromDictionary:icons];
- }
- NSData *iconData = [icon TIFFRepresentation];
- if (iconData) {
- //NSLog(@"Writing icon: %@", iconURLString);
- [fileDB setObject:iconData forKey:iconURLString];
- [_private->iconsOnDiskWithURLs addObject:iconURLString];
- }
- } else if ([_private->iconURLsWithNoIcons containsObject:iconURLString]) {
- [fileDB setObject:[NSNull null] forKey:iconURLString];
- [_private->iconsOnDiskWithURLs addObject:iconURLString];
- }
- }
-
- [_private->iconsToEraseWithURLs removeAllObjects];
- [_private->iconsToSaveWithURLs removeAllObjects];
-
- // Save the icon dictionaries to disk, after removing any values created during private browsing.
- // Even if we weren't modifying the dictionary we'd still want to use a copy so that WebFileDatabase
- // doesn't look at the original from a different thread. (We used to think this would fix 3566336
- // but that bug's progeny are still alive and kicking.)
- NSMutableDictionary *pageURLToIconURLCopy = [_private->pageURLToIconURL mutableCopy];
- [pageURLToIconURLCopy removeObjectsForKeys:[_private->pageURLsBoundDuringPrivateBrowsing allObjects]];
- [fileDB setObject:pageURLToIconURLCopy forKey:WebURLToIconURLKey];
- [pageURLToIconURLCopy release];
-}
- (void)_applicationWillTerminate:(NSNotification *)notification
{
- // Should only cause a write if user quit before 3 seconds after the last _updateFileDatabase
- [_private->fileDatabase sync];
-
#ifdef ICONDEBUG
[_private->databaseBridge closeSharedDatabase];
[_private->databaseBridge release];
_private->databaseBridge = nil;
#endif
- _isClosing = YES;
-}
-
-- (int)_totalRetainCountForIconURLString:(NSString *)iconURLString
-{
- // Add up the retain counts for each associated page, plus the retain counts not associated
- // with any page, which are stored in _private->iconURLToExtraRetainCount
- WebNSUInteger result = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->iconURLToExtraRetainCount, iconURLString);
-
- id URLStrings = [_private->iconURLToPageURLs objectForKey:iconURLString];
- if (URLStrings != nil) {
- if ([URLStrings isKindOfClass:[NSMutableSet class]]) {
- NSEnumerator *e = [(NSMutableSet *)URLStrings objectEnumerator];
- NSString *URLString;
- while ((URLString = [e nextObject]) != nil) {
- ASSERT([URLString isKindOfClass:[NSString class]]);
- result += (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, URLString);
- }
- } else {
- ASSERT([URLStrings isKindOfClass:[NSString class]]);
- result += (WebNSUInteger)(void *)CFDictionaryGetValue(_private->pageURLToRetainCount, URLStrings);
- }
- }
-
- return result;
}
-- (NSMutableDictionary *)_iconsForIconURLString:(NSString *)iconURLString
-{
- ASSERT(iconURLString);
-
- if ([_private->iconURLsWithNoIcons containsObject:iconURLString])
- return nil;
-
- NSMutableDictionary *icons = [_private->iconURLToIcons objectForKey:iconURLString];
-
- if (icons)
- return icons;
-
- // Not in memory, check disk
- if(![_private->iconsOnDiskWithURLs containsObject:iconURLString])
- return nil;
-
-#if !LOG_DISABLED
- double start = CFAbsoluteTimeGetCurrent();
-#endif
- NSData *iconData = [_private->fileDatabase objectForKey:iconURLString];
-
- if ([iconData isKindOfClass:[NSNull class]]) {
- [_private->iconURLsWithNoIcons addObject:iconURLString];
- return nil;
- }
-
- if (iconData) {
- NS_DURING
- NSImage *icon = [[NSImage alloc] initWithData:iconData];
- icons = [self _iconsBySplittingRepresentationsOfIcon:icon];
- if (icons) {
-#if !LOG_DISABLED
- double duration = CFAbsoluteTimeGetCurrent() - start;
- LOG(Timing, "loading and creating icon %@ took %f seconds", iconURLString, duration);
-#endif
- [_private->iconURLToIcons setObject:icons forKey:iconURLString];
- }
- NS_HANDLER
- icons = nil;
- NS_ENDHANDLER
- }
-
- return icons;
-}
- (NSImage *)_iconForFileURL:(NSString *)file withSize:(NSSize)size
{
return icon;
}
-- (void)_retainIconForIconURLString:(NSString *)iconURLString
-{
- ASSERT(iconURLString);
-
- WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->iconURLToExtraRetainCount, iconURLString);
- WebNSUInteger newRetainCount = retainCount + 1;
-
- CFDictionarySetValue(_private->iconURLToExtraRetainCount, iconURLString, (void *)newRetainCount);
-
- if (newRetainCount == 1 && !_private->privateBrowsingEnabled) {
-
- // Either we know nothing about this icon and need to save it to disk, or we were planning to remove it
- // from disk (as set up in _forgetIconForIconURLString:) and should stop that process.
- if ([_private->iconsOnDiskWithURLs containsObject:iconURLString]) {
- ASSERT(![_private->iconsToSaveWithURLs containsObject:iconURLString]);
- [_private->iconsToEraseWithURLs removeObject:iconURLString];
- } else {
- ASSERT(![_private->iconsToEraseWithURLs containsObject:iconURLString]);
- [_private->iconsToSaveWithURLs addObject:iconURLString];
- }
- }
-}
-
-- (void)_forgetIconForIconURLString:(NSString *)iconURLString
-{
- ASSERT_ARG(iconURLString, iconURLString != nil);
- if([_private->iconsOnDiskWithURLs containsObject:iconURLString]){
- [_private->iconsToEraseWithURLs addObject:iconURLString];
- [_private->iconsToSaveWithURLs removeObject:iconURLString];
- }
-
- // Remove the icon's images
- [_private->iconURLToIcons removeObjectForKey:iconURLString];
-
- // Remove negative cache item for icon, if any
- [_private->iconURLsWithNoIcons removeObject:iconURLString];
-
- // Remove the icon's associated site URLs, if any
- [iconURLString retain];
- id URLs = [_private->iconURLToPageURLs objectForKey:iconURLString];
- if (URLs != nil) {
- if ([URLs isKindOfClass:[NSMutableSet class]])
- [_private->pageURLToIconURL removeObjectsForKeys:[URLs allObjects]];
- else {
- ASSERT([URLs isKindOfClass:[NSString class]]);
- [_private->pageURLToIconURL removeObjectForKey:URLs];
- }
- }
- [_private->iconURLToPageURLs removeObjectForKey:iconURLString];
- CFDictionaryRemoveValue(_private->iconURLToExtraRetainCount, iconURLString);
- [iconURLString release];
-}
-
-- (void)_releaseIconForIconURLString:(NSString *)iconURLString
-{
- ASSERT(iconURLString);
-
- if (![self _isEnabled])
- return;
-
- WebNSUInteger retainCount = (WebNSUInteger)(void *)CFDictionaryGetValue(_private->iconURLToExtraRetainCount, iconURLString);
-
- // This error used to be an ASSERT() that was causing the build bot to fail. The build bot was getting itself into a reproducible
- // situation of having an icon for 127.0.0.1:8000/favicon.ico registered in the database but not finding the file for it. This situation
- // triggers a call to _forgetIconForIconURL which dumps everything about the icon - including the retain count. A later call to releaseIconForURL
- // would then ASSERT and crash the test as the retain count had be internally reset to zero
- // The reason the build bot was getting into this situation is not yet understood but the cause of the ASSERT is - and the condition was already
- // handled gracefully in release builds. Therefore we're changing it to a LOG_ERROR with the understanding that the sqlite icon database will not
- // have this issue due to its entirely different nature
- if (retainCount <= 0) {
- if (!_isClosing)
- LOG_ERROR("Trying to release an icon whose retain-count is already non-positive");
- return;
- }
-
- WebNSUInteger newRetainCount = retainCount - 1;
- if (newRetainCount == 0) {
- CFDictionaryRemoveValue(_private->iconURLToExtraRetainCount, iconURLString);
- if ([self _totalRetainCountForIconURLString:iconURLString] == 0) {
- [self _forgetIconForIconURLString:iconURLString];
- }
- } else {
- CFDictionarySetValue(_private->iconURLToExtraRetainCount, iconURLString, (void *)newRetainCount);
- }
-}
-
-- (void)_retainOriginalIconsOnDisk
-{
- NSEnumerator *enumerator = [_private->originalIconsOnDiskWithURLs objectEnumerator];;
- NSString *iconURLString;
- while ((iconURLString = [enumerator nextObject]) != nil) {
- [self _retainIconForIconURLString:iconURLString];
- }
-}
-
-- (void)_releaseOriginalIconsOnDisk
-{
- if (_private->cleanupCount > 0) {
- _private->waitingToCleanup = YES;
- return;
- }
-
- NSEnumerator *enumerator = [_private->originalIconsOnDiskWithURLs objectEnumerator];
- NSString *iconURLString;
- while ((iconURLString = [enumerator nextObject]) != nil) {
- [self _releaseIconForIconURLString:iconURLString];
- }
-
- [_private->originalIconsOnDiskWithURLs release];
- _private->originalIconsOnDiskWithURLs = nil;
-
- _private->didCleanup = YES;
-}
-
- (void)_resetCachedWebPreferences:(NSNotification *)notification
{
BOOL privateBrowsingEnabledNow = [[WebPreferences standardPreferences] privateBrowsingEnabled];
[_private->databaseBridge setPrivateBrowsingEnabled:privateBrowsingEnabledNow];
return;
#endif
-
- if (privateBrowsingEnabledNow == _private->privateBrowsingEnabled)
- return;
-
- _private->privateBrowsingEnabled = privateBrowsingEnabledNow;
-
- // When private browsing is turned off, forget everything we learned while it was on
- if (!_private->privateBrowsingEnabled) {
- // Forget all of the icons whose existence we learned of during private browsing.
- NSEnumerator *iconEnumerator = [_private->iconURLsBoundDuringPrivateBrowsing objectEnumerator];
- NSString *iconURLString;
- while ((iconURLString = [iconEnumerator nextObject]) != nil)
- [self _forgetIconForIconURLString:iconURLString];
-
- // Forget the relationships between page and icon that we learned during private browsing.
- NSEnumerator *pageEnumerator = [_private->pageURLsBoundDuringPrivateBrowsing objectEnumerator];
- NSString *pageURLString;
- while ((pageURLString = [pageEnumerator nextObject]) != nil) {
- [_private->pageURLToIconURL removeObjectForKey:pageURLString];
- // Tell clients that these pages' icons have changed (to generic). The notification is named
- // WebIconDatabaseDidAddIconNotification but it really means just "did change icon".
- [self _sendNotificationForURL:pageURLString];
- }
-
- [_private->iconURLsBoundDuringPrivateBrowsing removeAllObjects];
- [_private->pageURLsBoundDuringPrivateBrowsing removeAllObjects];
- }
}
- (NSImage *)_largestIconFromDictionary:(NSMutableDictionary *)icons