If we try to update icons while the webview doesn't have an accessible documentFrame (e.g. while it is still working on loading its initial HTML), try again after a second. This fixes icons which are part of the initial bolus of information presented by a webview that change shortly after it loads, which can most noticeably happen when restoring a chat using a webview with icons in its header but could also occur if a user icon changed as we opened a chat window.
authorEvan Schoenberg
Sun Nov 22 20:06:12 2009 -0600 (2009-11-22)
changeset 29399f11b96baf1d
parent 2938 3294410d095f
child 2940 58897a698d28
If we try to update icons while the webview doesn't have an accessible documentFrame (e.g. while it is still working on loading its initial HTML), try again after a second. This fixes icons which are part of the initial bolus of information presented by a webview that change shortly after it loads, which can most noticeably happen when restoring a chat using a webview with icons in its header but could also occur if a user icon changed as we opened a chat window.

Fixes #12696
Plugins/WebKit Message View/AIWebKitMessageViewController.m
Plugins/WebKit Message View/AIWebkitMessageViewStyle.m
     1.1 --- a/Plugins/WebKit Message View/AIWebKitMessageViewController.m	Sun Nov 22 16:57:25 2009 -0600
     1.2 +++ b/Plugins/WebKit Message View/AIWebKitMessageViewController.m	Sun Nov 22 20:06:12 2009 -0600
     1.3 @@ -1250,9 +1250,9 @@
     1.4  			webKitUserIcon = userIcon;
     1.5  		}
     1.6  
     1.7 -		oldWebKitUserIconPath = [objectIconPathDict objectForKey:iconSourceObject.internalObjectID];
     1.8 +		oldWebKitUserIconPath = [objectIconPathDict objectForKey:iconSourceObject.internalObjectID];		
     1.9  		webKitUserIconPath = [iconSourceObject valueForProperty:KEY_WEBKIT_USER_ICON];
    1.10 -
    1.11 +		
    1.12  		if (!webKitUserIconPath) {
    1.13  			/* If the image doesn't know a path to use, write it out and set it.
    1.14  			 *
    1.15 @@ -1266,8 +1266,10 @@
    1.16  													 atomically:YES]) {
    1.17  				[iconSourceObject setValue:webKitUserIconPath
    1.18  										   forProperty:KEY_WEBKIT_USER_ICON
    1.19 -										   notify:NO];				
    1.20 -			}			
    1.21 +										   notify:NO];
    1.22 +			} else {
    1.23 +				AILogWithSignature(@"Warning: Could not write out icon to %@", webKitUserIconPath);
    1.24 +			}
    1.25  		}
    1.26  
    1.27  		//Make sure it's known that this user has been handled
    1.28 @@ -1282,27 +1284,35 @@
    1.29  		
    1.30  		if (!webKitUserIconPath) webKitUserIconPath = @"";
    1.31  
    1.32 -		//Update existing images
    1.33 -		AILogWithSignature(@"Updating %@ to %@", oldWebKitUserIconPath, webKitUserIconPath);
    1.34 +		if ([webView mainFrameDocument]) {
    1.35 +			//Update existing images if the webView has loaded and has a main frame
    1.36 +			if (oldWebKitUserIconPath &&
    1.37 +				![oldWebKitUserIconPath isEqualToString:webKitUserIconPath]) {
    1.38 +				
    1.39 +				DOMNodeList  *images = [[webView mainFrameDocument] getElementsByTagName:@"img"];
    1.40 +				NSUInteger imagesCount = [images length];
    1.41  
    1.42 -		if (oldWebKitUserIconPath &&
    1.43 -			![oldWebKitUserIconPath isEqualToString:webKitUserIconPath]) {
    1.44 -			DOMNodeList  *images = [[webView mainFrameDocument] getElementsByTagName:@"img"];
    1.45 -			NSUInteger imagesCount = [images length];
    1.46 +				webKitUserIconPath = [[webKitUserIconPath copy] autorelease];
    1.47  
    1.48 -			webKitUserIconPath = [[webKitUserIconPath copy] autorelease];
    1.49 -
    1.50 -			for (NSInteger i = 0; i < imagesCount; i++) {
    1.51 -				DOMHTMLImageElement *img = (DOMHTMLImageElement *)[images item:i];
    1.52 -				NSString *currentSrc = [img getAttribute:@"src"];
    1.53 -				if (currentSrc && ([currentSrc rangeOfString:oldWebKitUserIconPath].location != NSNotFound)) {
    1.54 -					[img setSrc:webKitUserIconPath];
    1.55 +				for (NSInteger i = 0; i < imagesCount; i++) {
    1.56 +					DOMHTMLImageElement *img = (DOMHTMLImageElement *)[images item:i];
    1.57 +					NSString *currentSrc = [img getAttribute:@"src"];
    1.58 +					if (currentSrc && ([currentSrc rangeOfString:oldWebKitUserIconPath].location != NSNotFound)) {
    1.59 +						[img setSrc:webKitUserIconPath];
    1.60 +					}
    1.61  				}
    1.62  			}
    1.63 +			
    1.64 +			[objectIconPathDict setObject:webKitUserIconPath
    1.65 +								   forKey:iconSourceObject.internalObjectID];
    1.66 +		} else {
    1.67 +			/* Otherwise, try to again in a moment. We've already done the heavy lifting
    1.68 +			 * such as writing out the icon, so it's cheap to recurse.
    1.69 +			 */			
    1.70 +			[self performSelector:@selector(updateUserIconForObject:)
    1.71 +					   withObject:inObject
    1.72 +					   afterDelay:1];
    1.73  		}
    1.74 -
    1.75 -		[objectIconPathDict setObject:webKitUserIconPath
    1.76 -							   forKey:iconSourceObject.internalObjectID];
    1.77  	}
    1.78  }
    1.79  
     2.1 --- a/Plugins/WebKit Message View/AIWebkitMessageViewStyle.m	Sun Nov 22 16:57:25 2009 -0600
     2.2 +++ b/Plugins/WebKit Message View/AIWebkitMessageViewStyle.m	Sun Nov 22 20:06:12 2009 -0600
     2.3 @@ -1168,25 +1168,32 @@
     2.4  	
     2.5  	if (listObject) {
     2.6  		iconPath = [listObject valueForProperty:KEY_WEBKIT_USER_ICON];
     2.7 -		if (!iconPath) {
     2.8 +		if (!iconPath)
     2.9  			iconPath = [listObject valueForProperty:@"UserIconPath"];
    2.10 -		}
    2.11 +		
    2.12 +		/* We couldn't get an icon... but perhaps we can for a parent contact */
    2.13 +		if (!iconPath &&
    2.14 +			[listObject isKindOfClass:[AIListContact class]] &&
    2.15 +			([(AIListContact *)listObject parentContact] != listObject)) {
    2.16 +			iconPath = [[(AIListContact *)listObject parentContact] valueForProperty:KEY_WEBKIT_USER_ICON];
    2.17 +			if (!iconPath)
    2.18 +				iconPath = [[(AIListContact *)listObject parentContact] valueForProperty:@"UserIconPath"];			
    2.19 +		}		
    2.20  	}
    2.21  	[inString replaceKeyword:@"%incomingIconPath%"
    2.22  				  withString:(iconPath ? iconPath : @"incoming_icon.png")];
    2.23 -	
    2.24 +
    2.25  	AIListObject	*account = chat.account;
    2.26  	iconPath = nil;
    2.27  	
    2.28  	if (account) {
    2.29  		iconPath = [account valueForProperty:KEY_WEBKIT_USER_ICON];
    2.30 -		if (!iconPath) {
    2.31 +		if (!iconPath)
    2.32  			iconPath = [account valueForProperty:@"UserIconPath"];
    2.33 -		}
    2.34  	}
    2.35  	[inString replaceKeyword:@"%outgoingIconPath%"
    2.36  				  withString:(iconPath ? iconPath : @"outgoing_icon.png")];
    2.37 -	
    2.38 +
    2.39  	NSString *serviceIconPath = [AIServiceIcons pathForServiceIconForServiceID:account.service.serviceID
    2.40  																		  type:AIServiceIconLarge];
    2.41