Revision: 26755
          http://sourceforge.net/p/bibdesk/svn/26755
Author:   hofman
Date:     2021-08-28 19:13:30 +0000 (Sat, 28 Aug 2021)
Log Message:
-----------
Let the webview download the favicon, asynchronously

Modified Paths:
--------------
    trunk/bibdesk/BDSKWebView.h
    trunk/bibdesk/BDSKWebView.m

Modified: trunk/bibdesk/BDSKWebView.h
===================================================================
--- trunk/bibdesk/BDSKWebView.h 2021-08-28 18:33:12 UTC (rev 26754)
+++ trunk/bibdesk/BDSKWebView.h 2021-08-28 19:13:30 UTC (rev 26755)
@@ -48,11 +48,12 @@
     BDSKWebMenuItemTagAddBookmark
 };
 
-@class BDSKWebDelegate;
+@class BDSKWebDelegate, BDSKDownload;
 @protocol BDSKWebViewDelegate, BDSKWebViewNavigationDelegate;
 
 @interface BDSKWebView : WebView {
     BDSKWebDelegate *webDelegate;
+    BDSKDownload *faviconDownload;
 }
 
 @property (nonatomic, assign) id<BDSKWebViewDelegate> delegate;

Modified: trunk/bibdesk/BDSKWebView.m
===================================================================
--- trunk/bibdesk/BDSKWebView.m 2021-08-28 18:33:12 UTC (rev 26754)
+++ trunk/bibdesk/BDSKWebView.m 2021-08-28 19:13:30 UTC (rev 26755)
@@ -48,12 +48,14 @@
 #import "NSArray_BDSKExtensions.h"
 #import "BDSKRuntime.h"
 #import "DOMNode_BDSKExtensions.h"
+#import "BDSKDownloader.h"
 
 
 @interface BDSKWebDelegate : NSObject <WebFrameLoadDelegate, 
WebPolicyDelegate, WebUIDelegate, WebEditingDelegate> {
     id <BDSKWebViewDelegate> delegate;
     id <BDSKWebViewNavigationDelegate> navigationDelegate;
-    NSUndoManager *undoManager;    
+    NSUndoManager *undoManager;
+    BDSKDownload *faviconDownload;
 }
 
 @property (nonatomic, assign) id<BDSKWebViewDelegate> delegate;
@@ -73,6 +75,9 @@
 
 #pragma mark -
 
+@interface BDSKWebView () <BDSKDownloaderDelegate>
+@end
+
 @implementation BDSKWebView
 
 @dynamic delegate, navigationDelegate, URL;
@@ -92,6 +97,8 @@
 }
 
 - (void)dealloc {
+    [faviconDownload cancel];
+    BDSKDESTROY(faviconDownload);
     [webDelegate setDelegate:nil];
     [webDelegate setNavigationDelegate:nil];
     [self setFrameLoadDelegate:nil];
@@ -163,6 +170,74 @@
         [[NSWorkspace sharedWorkspace] openURLWithDefaultApp:theURL];
 }
 
+#pragma mark Favicon
+
+- (void)downloadFavicon {
+    NSMutableArray *favicons = [NSMutableArray array];
+    WebFrame *frame = [self mainFrame];
+    NSURL *frameURL = [[[frame dataSource] request] URL];
+    NSArray *nodes = [[frame DOMDocument] 
nodesForXPath:@"/html/head/link[@rel='icon' or @rel='shortcut icon']"];
+    for (DOMElement *node in nodes) {
+        NSURL *url = [NSURL URLWithString:[node getAttribute:@"href"] 
relativeToURL:frameURL];
+        NSArray *sizes = [[node getAttribute:@"sizes"] 
componentsSeparatedByString:@" "];
+        BOOL foundSize = NO;
+        for (NSString *sizeString in sizes) {
+            NSArray *widthAndHeight = [sizeString 
componentsSeparatedByString:@"x"];
+            if ([sizes count] == 2) {
+                [favicons addObject:[NSDictionary 
dictionaryWithObjectsAndKeys:url, @"url", [NSNumber numberWithInteger:[[sizes 
firstObject] integerValue]], @"width", [NSNumber numberWithInteger:[[sizes 
lastObject] integerValue]], @"height", nil]];
+                foundSize = YES;
+            }
+        }
+        if (foundSize = NO)
+            [favicons addObject:[NSDictionary 
dictionaryWithObjectsAndKeys:url, @"url", nil]];
+    }
+    if ([favicons count] == 0) {
+        NSURL *url = [NSURL URLWithString:@"favicon.ico" 
relativeToURL:frameURL];
+        [favicons addObject:[NSDictionary dictionaryWithObjectsAndKeys:url, 
@"url", nil]];
+    }
+    [favicons sortUsingComparator:^(id obj1, id obj2){ return [[obj1 
valueForKey:@"width"] compare:[obj2 valueForKey:@"width"]]; }];
+    NSInteger size = 16 * (NSInteger)[[frame webView] 
convertSizeToBacking:NSMakeSize(1.0, 1.0)].width;
+    NSURL *faviconURL = nil;
+    for (NSDictionary *info in favicons) {
+        NSInteger width = [[info valueForKey:@"width"] integerValue];
+        if (width >= size) {
+            faviconURL = [info valueForKey:@"url"];
+            break;
+        }
+    }
+    if (faviconURL == nil)
+        faviconURL = [[favicons lastObject] valueForKey:@"url"];
+    if (faviconURL == nil)
+        return;
+    
+    if (faviconDownload) {
+        [faviconDownload cancel];
+        [faviconDownload release];
+    }
+    NSURLRequest *request = [NSURLRequest requestWithURL:faviconURL];
+    faviconDownload = [[[BDSKDownloader sharedDownloader] 
startDataDownloadWithRequest:request delegate:self] retain];
+}
+
+- (void)stopFaviconDownload {
+    [faviconDownload cancel];
+    BDSKDESTROY(faviconDownload);
+}
+
+- (void)downloader:(BDSKDownloader *)downloader download:(BDSKDownload 
*)download didCompleteWithError:(NSError *)error {
+    if (faviconDownload != download)
+        return;
+    [[download retain] autorelease];
+    BDSKDESTROY(faviconDownload);
+    if (error)
+        return;
+    NSData *data = [download data];
+    if (data) {
+        NSImage *favicon = [[[NSImage alloc] initWithData:data] autorelease];
+        if (favicon && [[self frameLoadDelegate] 
respondsToSelector:@selector(webView:didReceiveIcon:forFrame:)])
+            [[self frameLoadDelegate] webView:self didReceiveIcon:favicon 
forFrame:[self mainFrame]];
+    }
+}
+
 @end
 
 #pragma mark -
@@ -172,6 +247,8 @@
 @synthesize delegate, navigationDelegate;
 
 - (void)dealloc {
+    [faviconDownload cancel];
+    BDSKDESTROY(faviconDownload);
     delegate = nil;
     navigationDelegate = nil;
     BDSKDESTROY(undoManager);
@@ -203,47 +280,6 @@
         return [super respondsToSelector:aSelector];
 }
 
-#pragma mark Favicon
-
-- (NSImage *)faviconForFrame:(WebFrame *)frame {
-    NSMutableArray *favicons = [NSMutableArray array];
-    NSURL *frameURL = [[[frame dataSource] request] URL];
-    NSArray *nodes = [[frame DOMDocument] 
nodesForXPath:@"/html/head/link[@rel='icon' or @rel='shortcut icon']"];
-    for (DOMElement *node in nodes) {
-        NSURL *url = [NSURL URLWithString:[node getAttribute:@"href"] 
relativeToURL:frameURL];
-        NSArray *sizes = [[node getAttribute:@"sizes"] 
componentsSeparatedByString:@" "];
-        BOOL foundSize = NO;
-        for (NSString *sizeString in sizes) {
-            NSArray *widthAndHeight = [sizeString 
componentsSeparatedByString:@"x"];
-            if ([sizes count] == 2) {
-                [favicons addObject:[NSDictionary 
dictionaryWithObjectsAndKeys:url, @"url", [NSNumber numberWithInteger:[[sizes 
firstObject] integerValue]], @"width", [NSNumber numberWithInteger:[[sizes 
lastObject] integerValue]], @"height", nil]];
-                foundSize = YES;
-            }
-        }
-        if (foundSize = NO)
-            [favicons addObject:[NSDictionary 
dictionaryWithObjectsAndKeys:url, @"url", nil]];
-    }
-    if ([favicons count] == 0) {
-        NSURL *url = [NSURL URLWithString:@"favicon.ico" 
relativeToURL:frameURL];
-        [favicons addObject:[NSDictionary dictionaryWithObjectsAndKeys:url, 
@"url", nil]];
-    }
-    [favicons sortUsingComparator:^(id obj1, id obj2){ return [[obj1 
valueForKey:@"width"] compare:[obj2 valueForKey:@"width"]]; }];
-    NSInteger size = 16 * (NSInteger)[[frame webView] 
convertSizeToBacking:NSMakeSize(1.0, 1.0)].width;
-    NSURL *faviconURL = nil;
-    for (NSDictionary *info in favicons) {
-        NSInteger width = [[info valueForKey:@"width"] integerValue];
-        if (width >= size) {
-            faviconURL = [info valueForKey:@"url"];
-            break;
-        }
-    }
-    if (faviconURL == nil)
-        faviconURL = [[favicons lastObject] valueForKey:@"url"];
-    if (faviconURL)
-        return [[[NSImage alloc] initWithContentsOfURL:faviconURL] 
autorelease];
-    return nil;
-}
-
 #pragma mark Delegate forward
 
 - (void)webView:(WebView *)sender setURL:(NSURL *)aURL {
@@ -270,6 +306,8 @@
 
 - (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame 
*)frame{
     if (frame == [sender mainFrame]) {
+        if ([sender respondsToSelector:@selector(stopFaviconDownload)])
+           [(BDSKWebView *)sender stopFaviconDownload];
         [self webView:sender setIcon:nil];
         [self webView:sender setTitle:[NSLocalizedString(@"Loading", 
@"Placeholder web group label") stringByAppendingEllipsis]];
     }
@@ -292,9 +330,10 @@
             NSURL *url = [[[frame dataSource] request] URL];
             title = [url isFileURL] ? [[url path] lastPathComponent] : [[url 
absoluteString] stringByRemovingPercentEncoding];
         }
-        NSImage *favicon = RUNNING_BEFORE(10_13) ? [sender mainFrameIcon] : 
[self faviconForFrame:frame];
-        if (favicon)
-            [self webView:sender setIcon:favicon];
+        if (RUNNING_BEFORE(10_13))
+            [self webView:sender setIcon:[sender mainFrameIcon]];
+         else if ([sender respondsToSelector:@selector(downloadFavicon)])
+             [(BDSKWebView *)sender downloadFavicon];
         [self webView:sender setTitle:title];
     }
     [self webView:sender setLoading:[sender isLoading]];

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.



_______________________________________________
Bibdesk-commit mailing list
Bibdesk-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit

Reply via email to