]> git.saurik.com Git - cydia.git/blobdiff - CyteKit/WebViewController.mm
Add output filename parameter to pngcrush.sh.
[cydia.git] / CyteKit / WebViewController.mm
index b954b8ea9821b95b0aea6cf37eee417471bff1e6..496d8b21edca6c47e30048701e4533c23e23a8fc 100644 (file)
@@ -1,6 +1,8 @@
 #include "CyteKit/UCPlatform.h"
+#include "CyteKit/WebViewController.h"
+
+#include "CyteKit/MFMailComposeViewController-MailToURL.h"
 
-#include <UIKit/UIKit.h>
 #include "iPhonePrivate.h"
 
 #include "CyteKit/Localize.h"
@@ -14,6 +16,7 @@ extern NSString * const kCAFilterNearest;
 
 #include <WebCore/WebCoreThread.h>
 
+#include <WebKit/WebKitErrors.h>
 #include <WebKit/WebPreferences.h>
 
 #include <WebKit/DOMCSSPrimitiveValue.h>
@@ -31,13 +34,8 @@ extern NSString * const kCAFilterNearest;
 
 #define lprintf(args...) fprintf(stderr, args)
 
-template <typename Type_>
-static inline void CYRelease(Type_ &value) {
-    if (value != nil) {
-        [value release];
-        value = nil;
-    }
-}
+// XXX: centralize these special class things to some file or mechanism?
+static Class $MFMailComposeViewController;
 
 float CYScrollViewDecelerationRateNormal;
 
@@ -126,6 +124,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<float *>(dlsym(RTLD_DEFAULT, "UIScrollViewDecelerationRateNormal")))
         CYScrollViewDecelerationRateNormal = *_UIScrollViewDecelerationRateNormal;
     else // XXX: this actually might be fast on some older systems: we should look into this
@@ -138,24 +139,10 @@ float CYScrollViewDecelerationRateNormal;
 #endif
 
     [webview_ setDelegate:nil];
-
     [indirect_ setDelegate:nil];
-    [indirect_ release];
-
-    if (challenge_ != nil)
-        [challenge_ release];
-
-    if (title_ != nil)
-        [title_ release];
 
     if ([loading_ count] != 0)
         [delegate_ releaseNetworkActivityIndicator];
-    [loading_ release];
-
-    [reloaditem_ release];
-    [loadingitem_ release];
-
-    [indicator_ release];
 
     [super dealloc];
 }
@@ -285,8 +272,26 @@ float CYScrollViewDecelerationRateNormal;
     [self _setViewportWidth];
 }
 
+- (void) mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
+    [self dismissModalViewControllerAnimated:YES];
+}
+
 - (void) _openMailToURL:(NSURL *)url {
-    [[UIApplication sharedApplication] openURL:url];// asPanel:YES];
+    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];
+    else
+        [app openURL:url];
 }
 
 - (bool) _allowJavaScriptPanel {
@@ -315,9 +320,16 @@ float CYScrollViewDecelerationRateNormal;
     [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]];
     [self _didFinishLoading];
 
-    if ([error code] == NSURLErrorCancelled)
+    if ([[error domain] isEqualToString:NSURLErrorDomain] && [error code] == NSURLErrorCancelled)
         return;
 
+    if ([[error domain] isEqualToString:WebKitErrorDomain] && [error code] == WebKitErrorFrameLoadInterruptedByPolicyChange) {
+        request_ = (id) stage2_;
+        stage1_ = nil;
+        stage2_ = nil;
+        return;
+    }
+
     if ([frame parentFrame] == nil) {
         [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@",
             [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString],
@@ -358,16 +370,20 @@ float CYScrollViewDecelerationRateNormal;
             action:@selector(close)
         ] autorelease]];
 
-        [[self navigationController] presentModalViewController:navigation animated:YES];
-
         [delegate_ unloadData];
+
+        [[self navigationController] presentModalViewController:navigation animated:YES];
     }
 }
 
 // CyteWebViewDelegate {{{
 - (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message {
 #if LogMessages
-    static Pcre irritating("^(?:The page at .* displayed insecure content from .*\\.|Unsafe JavaScript attempt to access frame with URL .* from frame with URL .*\\. Domains, protocols and ports must match\\.)\\n$");
+    static Pcre irritating("^(?"
+        ":" "The page at .* displayed insecure content from .*\\."
+        "|" "Unsafe JavaScript attempt to access frame with URL .* from frame with URL .*\\. Domains, protocols and ports must match\\."
+    ")\\n$");
+
     if (NSString *data = [message objectForKey:@"message"])
         if (irritating(data))
             return;
@@ -385,9 +401,7 @@ float CYScrollViewDecelerationRateNormal;
         if (!error_) {
             NSURL *url(request == nil ? nil : [request URL]);
 
-            if (request_ == nil || [self allowsNavigationAction] || [[request_ URL] isEqual:url])
-                request_ = request;
-            else {
+            if (request_ != nil && ![[request_ URL] isEqual:url] && ![self allowsNavigationAction]) {
                 if (url != nil)
                     [self pushRequest:request asPop:NO];
                 [listener ignore];
@@ -396,6 +410,15 @@ float CYScrollViewDecelerationRateNormal;
     }
 }
 
+- (void) webView:(WebView *)view didDecidePolicy:(CYWebPolicyDecision)decision forNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame {
+    if ([frame parentFrame] == nil)
+        if (decision == CYWebPolicyDecisionUse)
+            if (!error_) {
+                stage1_ = (id) request_;
+                request_ = request;
+            }
+}
+
 - (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
 #if LogBrowser
     NSLog(@"decidePolicyForNewWindowAction:%@ request:%@ newFrameName:%@", action, request, frame);
@@ -441,6 +464,9 @@ float CYScrollViewDecelerationRateNormal;
     [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]];
 
     if ([frame parentFrame] == nil) {
+        stage1_ = nil;
+        stage2_ = nil;
+
         if (DOMDocument *document = [frame DOMDocument])
             if (DOMNodeList<NSFastEnumeration> *bodies = [document getElementsByTagName:@"body"])
                 for (DOMHTMLBodyElement *body in (id) bodies) {
@@ -481,22 +507,27 @@ float CYScrollViewDecelerationRateNormal;
     if ([frame parentFrame] != nil)
         return;
 
-    if (title_ != nil)
-        [title_ autorelease];
-    title_ = [title retain];
+    title_ = title;
 
     [[self navigationItem] setTitle:title_];
 }
 
 - (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame {
+#if LogBrowser
+    NSLog(@"didStartProvisionalLoadForFrame:%@", frame);
+#endif
+
     [loading_ addObject:[NSValue valueWithNonretainedObject:frame]];
 
     if ([frame parentFrame] == nil) {
-        CYRelease(title_);
+        title_ = nil;
         custom_ = nil;
         style_ = nil;
         function_ = nil;
 
+        stage2_ = (id) stage1_;
+        stage1_ = nil;
+
         [self setHidesNavigationBar:NO];
 
         // XXX: do we still need to do this?
@@ -570,7 +601,6 @@ float CYScrollViewDecelerationRateNormal;
             _nodefault
         }
 
-        [challenge_ release];
         challenge_ = nil;
 
         [alert dismissWithClickedButtonIndex:-1 animated:YES];
@@ -598,7 +628,12 @@ float CYScrollViewDecelerationRateNormal;
 }
 
 - (UIBarButtonItem *) customButton {
-    return custom_ == [NSNull null] ? nil : [[[UIBarButtonItem alloc]
+    if (custom_ == nil)
+        return nil;
+    else if (custom_ == [NSNull null])
+        return (UIBarButtonItem *) [NSNull null];
+
+    return [[[UIBarButtonItem alloc]
         initWithTitle:static_cast<NSString *>(custom_.operator NSObject *())
         style:[self rightButtonStyle]
         target:self
@@ -606,6 +641,27 @@ float CYScrollViewDecelerationRateNormal;
     ] autorelease];
 }
 
+- (UIBarButtonItem *) leftButton {
+    UINavigationItem *item([self navigationItem]);
+    if ([item backBarButtonItem] != nil && ![item hidesBackButton])
+        return nil;
+
+    if (UINavigationController *navigation = [self navigationController])
+        if ([[navigation parentViewController] modalViewController] == navigation)
+            return [[[UIBarButtonItem alloc]
+                initWithTitle:UCLocalize("CLOSE")
+                style:UIBarButtonItemStylePlain
+                target:self
+                action:@selector(close)
+            ] autorelease];
+
+    return nil;
+}
+
+- (void) applyLeftButton {
+    [[self navigationItem] setLeftBarButtonItem:[self leftButton]];
+}
+
 - (UIBarButtonItem *) rightButton {
     return reloaditem_;
 }
@@ -629,9 +685,13 @@ float CYScrollViewDecelerationRateNormal;
     } else {
         [indicator_ stopAnimating];
 
-        [[self navigationItem] setRightBarButtonItem:(
-            custom_ != nil ? [self customButton] : [self rightButton]
-        ) animated:YES];
+        UIBarButtonItem *button([self customButton]);
+        if (button == nil)
+            button = [self rightButton];
+        else if (button == (UIBarButtonItem *) [NSNull null])
+            button = nil;
+
+        [[self navigationItem] setRightBarButtonItem:button];
     }
 }
 
@@ -673,9 +733,9 @@ float CYScrollViewDecelerationRateNormal;
         allowsNavigationAction_ = true;
 
         class_ = _class;
-        loading_ = [[NSMutableSet alloc] initWithCapacity:5];
+        loading_ = [NSMutableSet setWithCapacity:5];
 
-        indirect_ = [[IndirectDelegate alloc] initWithDelegate:self];
+        indirect_ = [[[IndirectDelegate alloc] initWithDelegate:self] autorelease];
 
         CGRect bounds([[self view] bounds]);
 
@@ -710,6 +770,7 @@ float CYScrollViewDecelerationRateNormal;
             [preferences _setLayoutInterval:0];
 
         [preferences setCacheModel:WebCacheModelDocumentBrowser];
+        [preferences setJavaScriptCanOpenWindowsAutomatically:YES];
         [preferences setOfflineWebApplicationCacheEnabled:YES];
 
 #if LogMessages
@@ -755,26 +816,29 @@ float CYScrollViewDecelerationRateNormal;
 
         [self setViewportWidth:width];
 
-        reloaditem_ = [[UIBarButtonItem alloc]
+        reloaditem_ = [[[UIBarButtonItem alloc]
             initWithTitle:UCLocalize("RELOAD")
             style:[self rightButtonStyle]
             target:self
             action:@selector(reloadButtonClicked)
-        ];
+        ] autorelease];
 
-        loadingitem_ = [[UIBarButtonItem alloc]
+        loadingitem_ = [[[UIBarButtonItem alloc]
             initWithTitle:@" "
             style:UIBarButtonItemStylePlain
             target:self
             action:@selector(reloadButtonClicked)
-        ];
+        ] autorelease];
 
-        indicator_ = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 
+        indicator_ = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
         [indicator_ setFrame:CGRectMake(15, 5, [indicator_ frame].size.width, [indicator_ frame].size.height)];
 
         UITableView *table([[[UITableView alloc] initWithFrame:bounds style:UITableViewStyleGrouped] autorelease]);
         [webview_ insertSubview:table atIndex:0];
 
+        [self applyLeftButton];
+        [self applyRightButton];
+
         [table setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
         [webview_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
         [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
@@ -800,35 +864,10 @@ float CYScrollViewDecelerationRateNormal;
 
     WebView *webview([[webview_ _documentView] webView]);
     WebFrame *frame([webview mainFrame]);
-    WebPreferences *preferences([webview preferences]);
-
-    bool maybe([preferences javaScriptCanOpenWindowsAutomatically]);
-    [preferences setJavaScriptCanOpenWindowsAutomatically:NO];
-
-    /*id _private(MSHookIvar<id>(webview, "_private"));
-    WebCore::Page *page(_private == nil ? NULL : MSHookIvar<WebCore::Page *>(_private, "page"));
-    WebCore::Settings *settings(page == NULL ? NULL : page->settings());
 
-    bool no;
-    if (settings == NULL)
-        no = 0;
-    else {
-        no = settings->JavaScriptCanOpenWindowsAutomatically();
-        settings->setJavaScriptCanOpenWindowsAutomatically(true);
-    }*/
-
-    if (UIWindow *window = [[self view] window])
-        if (UIResponder *responder = [window firstResponder])
-            [responder resignFirstResponder];
-
-    JSObjectRef object([function JSObject]);
     JSGlobalContextRef context([frame globalContext]);
+    JSObjectRef object([function JSObject]);
     JSObjectCallAsFunction(context, object, NULL, 0, NULL, NULL);
-
-    /*if (settings != NULL)
-        settings->setJavaScriptCanOpenWindowsAutomatically(no);*/
-
-    [preferences setJavaScriptCanOpenWindowsAutomatically:maybe];
 }
 
 - (void) reloadButtonClicked {
@@ -872,6 +911,7 @@ float CYScrollViewDecelerationRateNormal;
 
 - (void) setHidesBackButton:(bool)value {
     [[self navigationItem] setHidesBackButton:value];
+    [self applyLeftButton];
 }
 
 - (void) setHidesBackButtonByNumber:(NSNumber *)value {