From 2b2a4e33d2693923b46834ca3072b69d7348f790 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Fri, 4 Mar 2011 15:56:31 -0800 Subject: When possible, use MFMailComposeViewController for _openMailToURL:. --- CyteKit/MFMailComposeViewController-MailToURL.h | 50 +++++++++++ CyteKit/MFMailComposeViewController-MailToURL.mm | 108 +++++++++++++++++++++++ CyteKit/WebViewController.h | 2 + CyteKit/WebViewController.mm | 24 ++++- 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 CyteKit/MFMailComposeViewController-MailToURL.h create mode 100644 CyteKit/MFMailComposeViewController-MailToURL.mm diff --git a/CyteKit/MFMailComposeViewController-MailToURL.h b/CyteKit/MFMailComposeViewController-MailToURL.h new file mode 100644 index 0000000..6496fef --- /dev/null +++ b/CyteKit/MFMailComposeViewController-MailToURL.h @@ -0,0 +1,50 @@ +/* Cydia - iPhone UIKit Front-End for Debian APT + * Copyright (C) 2008-2011 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + +#ifndef CyteKit_MFMailComposeViewController_MailToURL_H +#define CyteKit_MFMailComposeViewController_MailToURL_H + +#include +#include + +@interface MFMailComposeViewController (CyteMailToURL) +- (void) setMailToURL:(NSURL *)url; +@end + +#endif//CyteKit_MFMailComposeViewController_MailToURL_H diff --git a/CyteKit/MFMailComposeViewController-MailToURL.mm b/CyteKit/MFMailComposeViewController-MailToURL.mm new file mode 100644 index 0000000..ed6b9eb --- /dev/null +++ b/CyteKit/MFMailComposeViewController-MailToURL.mm @@ -0,0 +1,108 @@ +/* Cydia - iPhone UIKit Front-End for Debian APT + * Copyright (C) 2008-2011 Jay Freeman (saurik) +*/ + +/* Modified BSD License {{{ */ +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* }}} */ + +#include "CyteKit/MFMailComposeViewController-MailToURL.h" + +#include +#include + +static void $MFMailComposeViewController$setMailToURL$(MFMailComposeViewController *self, SEL _cmd, NSURL *url) { + NSString *scheme([url scheme]); + + if (scheme == nil || ![[scheme lowercaseString] isEqualToString:@"mailto"]) + [NSException raise:NSInvalidArgumentException format:@"-[MFMailComposeViewController setMailToURL:] - non-mailto: URL"]; + + NSString *href([url absoluteString]); + NSRange question([href rangeOfString:@"?"]); + + NSMutableArray *to([NSMutableArray arrayWithCapacity:1]); + + NSString *target, *query; + if (question.location == NSNotFound) { + target = [href substringFromIndex:7]; + query = nil; + } else { + target = [href substringWithRange:NSMakeRange(7, question.location - 7)]; + query = [href substringFromIndex:(question.location + 1)]; + } + + if ([target length] != 0) + [to addObject:target]; + + if (query != nil && [query length] != 0) { + NSMutableArray *cc([NSMutableArray arrayWithCapacity:1]); + NSMutableArray *bcc([NSMutableArray arrayWithCapacity:1]); + + for (NSString *assign in [query componentsSeparatedByString:@"&"]) { + NSRange equal([assign rangeOfString:@"="]); + if (equal.location == NSNotFound) + continue; + + NSString *name([assign substringToIndex:equal.location]); + NSString *value([assign substringFromIndex:(equal.location + 1)]); + value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + + if (false); + else if ([name isEqualToString:@"attachment"]) { + if (NSData *data = [NSData dataWithContentsOfFile:value]) + [self addAttachmentData:data mimeType:@"application/octet-stream" fileName:[value lastPathComponent]]; + } else if ([name isEqualToString:@"bcc"]) + [bcc addObject:value]; + else if ([name isEqualToString:@"body"]) + [self setMessageBody:value isHTML:NO]; + else if ([name isEqualToString:@"cc"]) + [cc addObject:value]; + else if ([name isEqualToString:@"subject"]) + [self setSubject:value]; + else if ([name isEqualToString:@"to"]) + [to addObject:value]; + } + + [self setCcRecipients:cc]; + [self setBccRecipients:bcc]; + } + + [self setToRecipients:to]; +} + +__attribute__((__constructor__)) static void MFMailComposeViewController_CyteMailToURL() { + dlopen("/System/Library/Frameworks/MessageUI.framework/MessageUI", RTLD_GLOBAL | RTLD_LAZY); + if (Class MFMailComposeViewController = objc_getClass("MFMailComposeViewController")) + class_addMethod(MFMailComposeViewController, @selector(setMailToURL:), (IMP) $MFMailComposeViewController$setMailToURL$, "v12@0:4@8"); +} diff --git a/CyteKit/WebViewController.h b/CyteKit/WebViewController.h index c1ec1ee..89ebe61 100644 --- a/CyteKit/WebViewController.h +++ b/CyteKit/WebViewController.h @@ -44,6 +44,7 @@ #include "CyteKit/WebView.h" #include +#include #include @@ -58,6 +59,7 @@ @interface CyteWebViewController : CyteViewController < CyteWebViewDelegate, + MFMailComposeViewControllerDelegate, UIWebViewDelegate > { _transient CyteWebView *webview_; diff --git a/CyteKit/WebViewController.mm b/CyteKit/WebViewController.mm index e6f7e45..78da1c5 100644 --- a/CyteKit/WebViewController.mm +++ b/CyteKit/WebViewController.mm @@ -1,6 +1,8 @@ #include "CyteKit/UCPlatform.h" +#include "CyteKit/WebViewController.h" + +#include "CyteKit/MFMailComposeViewController-MailToURL.h" -#include #include "iPhonePrivate.h" #include "CyteKit/Localize.h" @@ -31,6 +33,9 @@ extern NSString * const kCAFilterNearest; #define lprintf(args...) fprintf(stderr, args) +// XXX: centralize these special class things to some file or mechanism? +static Class $MFMailComposeViewController; + template static inline void CYRelease(Type_ &value) { if (value != nil) { @@ -126,6 +131,9 @@ float CYScrollViewDecelerationRateNormal; + (void) _initialize { [WebPreferences _setInitialDefaultTextEncodingToSystemEncoding]; + dlopen("/System/Library/Frameworks/MessageUI.framework/MessageUI", RTLD_GLOBAL | RTLD_LAZY); + $MFMailComposeViewController = objc_getClass("MFMailComposeViewController"); + if (float *_UIScrollViewDecelerationRateNormal = reinterpret_cast(dlsym(RTLD_DEFAULT, "UIScrollViewDecelerationRateNormal"))) CYScrollViewDecelerationRateNormal = *_UIScrollViewDecelerationRateNormal; else // XXX: this actually might be fast on some older systems: we should look into this @@ -285,7 +293,21 @@ float CYScrollViewDecelerationRateNormal; [self _setViewportWidth]; } +- (void) mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error { + [self dismissModalViewControllerAnimated:YES]; +} + - (void) _openMailToURL:(NSURL *)url { + if ($MFMailComposeViewController != nil && [$MFMailComposeViewController canSendMail]) { + MFMailComposeViewController *controller([[[$MFMailComposeViewController alloc] init] autorelease]); + [controller setMailComposeDelegate:self]; + + [controller setMailToURL:url]; + + [self presentModalViewController:controller animated:YES]; + return; + } + UIApplication *app([UIApplication sharedApplication]); if ([app respondsToSelector:@selector(openURL:asPanel:)]) [app openURL:url asPanel:YES]; -- cgit v1.2.3