/** * Author: Timothy Prepscius * License: BSD + keep my name in the code! */ #import "MailTableCell.h" #import "ConversationViewController.h" #include "mailiverse/utilities/Log.h" #include "MailData.h" @interface MailTableCell () { MailDataPtr data; bool watchingEvents; int observeStack; int kObservingContentSizeChangesContext; bool webViewWasInitialized; bool initialized; bool initializedDisplayPart3; float zoom; float contentHeight; } @end @implementation MailTableCell const int MailTableCell_ContentOffsetTop = 57; const int MailTableCell_ContentOffsetBottom = 40; const int MailTableCell_ContentNonContent = MailTableCell_ContentOffsetTop + MailTableCell_ContentOffsetBottom; @synthesize delegate; @synthesize fullView; @synthesize fullAuthors; @synthesize fullDate; @synthesize fullRecipients; @synthesize fullHtml; @synthesize fullImages; @synthesize fullActions; @synthesize draftActions; @synthesize touchArea; - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { self->watchingEvents = false; self->observeStack = 0; self->initialized = true; self->webViewWasInitialized = false; self->initializedDisplayPart3 = false; } return self; } - (void)dealloc { [self stopObservingContentSizeChangesInWebView]; LogDebug(ui::MailTableCell, "dealloc"); } -(BOOL)webView:(UIWebView *)_webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { LogDebug(ui::MailTableCell, "webView:shouldStartLoadWithRequest " << [[request URL] absoluteString].UTF8String << " " << (int)navigationType); NSString *url = [[request URL] absoluteString]; static NSString *urlPrefix = @"native://"; if ([url hasPrefix:urlPrefix]) { [self recalculateWebViewSizeAndZoom]; return NO; } if (navigationType == UIWebViewNavigationTypeLinkClicked) { [[UIApplication sharedApplication] openURL:[request URL]]; return NO; } return YES; } - (void) layoutSubviews { LogDebug(ui::MailTableCell, "layoutSubviews before super: sf.size.height " << self.frame.size.height << " sf.size.width " << self.frame.size.width); CGRect sf = self.frame; CGRect vf = fullHtml.frame; vf.origin.y = MailTableCell_ContentOffsetTop; vf.size.height = sf.size.height - (MailTableCell_ContentNonContent); fullHtml.frame = vf; [super layoutSubviews]; } - (void)onHeightChange:(int)height { if (height != data->height) { LogDebug(ui::MailTableCell, "propagating height change " << height); data->height = height; ConversationViewController *parent = (ConversationViewController *)delegate; // [parent performSelectorOnMainThread:@selector(onHeightChange:) withObject:self waitUntilDone:false]; [parent onHeightChange:self]; } } - (void)onContentHeightChange { LogDebug(ui::MailTableCell, "calculated final height " << (contentHeight + MailTableCell_ContentNonContent)); [self onHeightChange:(contentHeight + MailTableCell_ContentNonContent)]; } - (void)recalculateWebViewSizeAndZoom { // [self performSelectorOnMainThread:@selector(doRecalculateWebViewSizeAndZoom) withObject:nil waitUntilDone:false]; [self doRecalculateWebViewSizeAndZoom]; } - (void)doRecalculateWebViewSizeAndZoom { // have the webview calculate the new height CGRect webViewFrame = fullHtml.frame; float oldHeight= webViewFrame.size.height; webViewFrame.size.height = 1; fullHtml.frame = webViewFrame; CGSize fittingSize = [fullHtml sizeThatFits:CGSizeZero]; webViewFrame.size.height = oldHeight; fullHtml.frame = webViewFrame; float height = fittingSize.height // (int)webView.scrollView.contentSize.height // [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] integerValue] // [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight"] integerValue] // [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('__fakeBody__').clientHeight"] integerValue] ; float width = getWebViewScrollView(fullHtml).contentSize.width // [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollWidth"] integerValue] // [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('__fakeBody__').clientWidth"] integerValue] ; float webViewWidth = webViewFrame.size.width; LogDebug (ui::MailTableCell, "width " << width << " height " << height); if (width > webViewWidth) { zoom = webViewWidth / width; height = zoom * height; width = webViewWidth; LogDebug (ui::MailTableCell, "webViewDidFinishLoad zooming to " << zoom); } else { zoom = 1.0f; } contentHeight = height; [self hackSetWebViewZoom]; [self onContentHeightChange]; } - (void)hackClearWebView { LogDebug(ui::MailTableCell, "hackClearWebView"); // [[NSURLCache sharedURLCache] removeAllCachedResponses]; // [webView stringByEvaluatingJavaScriptFromString:@"var body=document.getElementsByTagName('body')[0];body.style.backgroundColor=(body.style.backgroundColor=='')?'white':'';"]; // [webView stringByEvaluatingJavaScriptFromString:@"document.open();document.close();"]; // [html stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML = \"\";"]; } - (void)initializeDisplayPart1 { fullAuthors.textColor = getColorForIndex(data->color); fullAuthors.text = data->author; fullRecipients.text = data->recipients; fullDate.text = data->date; [fullImages initToggle]; [fullImages setState:false]; } - (void)initializeDisplayPart2 { NSString *string = nil; bool isHtml = false; if (data->html) { isHtml = true; NSString *str = data->html; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern: @"(<[\\s\\S]*?img[\\s\\S]*?)src=([\\s\\S]*?>)" options:0 error:NULL]; string = [regex stringByReplacingMatchesInString:str options:0 range:NSMakeRange(0, [str length]) withTemplate:@"$1src='http://localhost/unloadable' fakesrc='http://localhost/unloadable' realsrc=$2"]; } else if (data->text) { string = data->text; } if (string) { int deviceWidth = fullHtml.frame.size.width; LogDebug(ui::MailTableCell::deviceWidth, "using deviceWidth " << deviceWidth); bool isPhone = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone); NSString *html = [NSString stringWithFormat: @"" "
" " " " " " " "" "" // "