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
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