From: Jay Freeman (saurik) Date: Tue, 1 Mar 2011 22:05:13 +0000 (-0800) Subject: Simplify all of these new filenames. X-Git-Tag: v1.1.0%b1~88 X-Git-Url: https://git.saurik.com/cydia.git/commitdiff_plain/d458596e0138c5094097a45442828cbc087be403 Simplify all of these new filenames. --- diff --git a/CyteKit/CyteLocalize.h b/CyteKit/CyteLocalize.h deleted file mode 100644 index a06bb0a9..00000000 --- a/CyteKit/CyteLocalize.h +++ /dev/null @@ -1,51 +0,0 @@ -/* 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_CyteLocalize_H -#define CyteKit_CyteLocalize_H - -#include - -static inline NSString *UCLocalizeEx(NSString *key, NSString *value = nil) { - return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; -} - -#define UCLocalize(key) UCLocalizeEx(@ key) - -#endif//CyteKit_CyteLocalize_H diff --git a/CyteKit/CyteViewController.h b/CyteKit/CyteViewController.h deleted file mode 100644 index fb5d202c..00000000 --- a/CyteKit/CyteViewController.h +++ /dev/null @@ -1,84 +0,0 @@ -/* 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_CyteViewController_H -#define CyteKit_CyteViewController_H - -#include - -#include - -@interface UIViewController (Cydia) -- (BOOL) hasLoaded; -- (void) reloadData; -- (void) unloadData; -@end - -@interface CYViewController : UIViewController { - _transient id delegate_; - BOOL loaded_; -} - -// The default implementation of this method is essentially a no-op, -// but calling the superclass implementation is *required*. -- (void) reloadData; - -- (void) unloadData; - -// This URL is used to save the state of the view controller. Return -// nil if you cannot or should not save the URL for this page. -- (NSURL *) navigationURL; - -// By default, this delegate is unused. However, it's provided here in case -// you need some kind of delegate in a subclass. -- (void) setDelegate:(id)delegate; -- (id) delegate; - -// Override this in subclasses if you manage the "has seen first load" state yourself. -- (BOOL) hasLoaded; - -// This is called when the view managed by the view controller is released. -// That is not always when the controller itself is released: it also can -// happen when more memory is needed by the system or whenever the controller -// just happens not to be visible. -- (void) releaseSubviews; - -@end - -#endif//CyteKit_CyteViewController_H diff --git a/CyteKit/CyteViewController.mm b/CyteKit/CyteViewController.mm deleted file mode 100644 index 73e1630b..00000000 --- a/CyteKit/CyteViewController.mm +++ /dev/null @@ -1,122 +0,0 @@ -/* 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/CyteViewController.h" - -#include -#include - -extern bool IsWildcat_; - -@implementation UIViewController (Cydia) - -- (BOOL) hasLoaded { - return YES; -} - -- (void) reloadData { -} - -- (void) unloadData { - if (UIViewController *modal = [self modalViewController]) - [modal unloadData]; -} - -@end - -@implementation CYViewController - -- (void) setDelegate:(id)delegate { - delegate_ = delegate; -} - -- (id) delegate { - return delegate_; -} - -- (void) viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - // Load on first appearance. We don't need to set the loaded flag here - // because it is set for us the first time -reloadData is called. - if (![self hasLoaded]) - [self reloadData]; -} - -- (BOOL) hasLoaded { - return loaded_; -} - -- (void) releaseSubviews { - // Do nothing. -} - -- (void) setView:(UIView *)view { - // Nasty hack for 2.x-compatibility. In 3.0+, we can and - // should just override -viewDidUnload instead. - if (view == nil) - [self releaseSubviews]; - - [super setView:view]; -} - -- (void) reloadData { - [super reloadData]; - - // This is called automatically on the first appearance of a controller, - // or any other time it needs to reload the information shown. However (!), - // this is not called by any tab bar or navigation controller's -reloadData - // method unless this controller returns YES from -hadLoaded. - loaded_ = YES; -} - -- (void) unloadData { - loaded_ = NO; - [super unloadData]; -} - -- (NSURL *) navigationURL { - return nil; -} - -- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { - return IsWildcat_ || orientation == UIInterfaceOrientationPortrait; -} - -@end diff --git a/CyteKit/CyteWebView.h b/CyteKit/CyteWebView.h deleted file mode 100644 index 91878b7e..00000000 --- a/CyteKit/CyteWebView.h +++ /dev/null @@ -1,80 +0,0 @@ -/* 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_CydiaBrowser_H -#define CyteKit_CydiaBrowser_H - -#include - -#include -#include -#include -#include -#include - -#include - -@protocol CyteWebViewDelegate -- (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message; -- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener; -- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener; -- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; -- (void) webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame; -- (void) webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame; -- (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame; -- (void) webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame; -- (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame; -- (NSURLRequest *) webView:(WebView *)view resource:(id)resource willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source; -- (void) webViewClose:(WebView *)view; -- (bool) webView:(WebView *)view shouldRunJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame; -- (bool) webView:(WebView *)view shouldRunJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame; -- (bool) webView:(WebView *)view shouldRunJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(WebFrame *)frame; -- (void) webViewUpdateViewSettings:(UIWebView *)view; -@end - -@interface CyteWebView : UIWebView { -} - -- (id) delegate; -- (void) dispatchEvent:(NSString *)event; -- (void) reloadFromOrigin; - -@end - -#endif//CyteKit_CydiaBrowser_H diff --git a/CyteKit/CyteWebView.mm b/CyteKit/CyteWebView.mm deleted file mode 100644 index 03a32540..00000000 --- a/CyteKit/CyteWebView.mm +++ /dev/null @@ -1,368 +0,0 @@ -/* 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/CyteWebView.h" -#include "CyteKit/WebThreadLocked.hpp" - -#include - -#include "iPhonePrivate.h" - -// CYWebPolicyDecision* {{{ -enum CYWebPolicyDecision { - CYWebPolicyDecisionUnknown, - CYWebPolicyDecisionDownload, - CYWebPolicyDecisionIgnore, - CYWebPolicyDecisionUse, -}; - -@interface CYWebPolicyDecisionMediator : NSObject < - WebPolicyDecisionListener -> { - id listener_; - CYWebPolicyDecision decision_; -} - -- (id) initWithListener:(id)listener; - -- (CYWebPolicyDecision) decision; -- (bool) decided; -- (bool) decide; - -@end - -@implementation CYWebPolicyDecisionMediator - -- (id) initWithListener:(id)listener { - if ((self = [super init]) != nil) { - listener_ = listener; - } return self; -} - -- (CYWebPolicyDecision) decision { - return decision_; -} - -- (bool) decided { - return decision_ != CYWebPolicyDecisionUnknown; -} - -- (bool) decide { - switch (decision_) { - case CYWebPolicyDecisionUnknown: - default: - NSLog(@"CYWebPolicyDecisionUnknown"); - return false; - - case CYWebPolicyDecisionDownload: [listener_ download]; break; - case CYWebPolicyDecisionIgnore: [listener_ ignore]; break; - case CYWebPolicyDecisionUse: [listener_ use]; break; - } - - return true; -} - -- (void) download { - decision_ = CYWebPolicyDecisionDownload; -} - -- (void) ignore { - decision_ = CYWebPolicyDecisionIgnore; -} - -- (void) use { - decision_ = CYWebPolicyDecisionUse; -} - -@end -// }}} - -@implementation CyteWebView : UIWebView - -#if ShowInternals -#include "CyteKit/UCInternal.h" -#endif - -- (id) initWithFrame:(CGRect)frame { - if ((self = [super initWithFrame:frame]) != nil) { - } return self; -} - -- (void) dealloc { - [super dealloc]; -} - -- (id) delegate { - return (id) [super delegate]; -} - -/*- (WebView *) webView:(WebView *)view createWebViewWithRequest:(NSURLRequest *)request { - id delegate([self delegate]); - WebView *created(nil); - if (created == nil && [delegate respondsToSelector:@selector(webView:createWebViewWithRequest:)]) - created = [delegate webView:view createWebViewWithRequest:request]; - if (created == nil && [UIWebView instancesRespondToSelector:@selector(webView:createWebViewWithRequest:)]) - created = [super webView:view createWebViewWithRequest:request]; - return created; -}*/ - -// webView:addMessageToConsole: (X.Xx) {{{ -static void $UIWebViewWebViewDelegate$webView$addMessageToConsole$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSDictionary *message) { - UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); - if ([uiWebView respondsToSelector:@selector(webView:addMessageToConsole:)]) - [uiWebView webView:view addMessageToConsole:message]; -} - -- (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:addMessageToConsole:)]) - [delegate webView:view addMessageToConsole:message]; - if ([UIWebView instancesRespondToSelector:@selector(webView:addMessageToConsole:)]) - [super webView:view addMessageToConsole:message]; -} -// }}} -// webView:decidePolicyForNavigationAction:request:frame:decisionListener: (2.0+) {{{ -- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - id delegate([self delegate]); - CYWebPolicyDecisionMediator *mediator([[[CYWebPolicyDecisionMediator alloc] initWithListener:listener] autorelease]); - if (![mediator decided] && [delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) - [delegate webView:view decidePolicyForNavigationAction:action request:request frame:frame decisionListener:mediator]; - if (![mediator decided] && [UIWebView instancesRespondToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) - [super webView:view decidePolicyForNavigationAction:action request:request frame:frame decisionListener:mediator]; - [mediator decide]; -} -// }}} -// webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener: (3.0+) {{{ -static void $UIWebViewWebViewDelegate$webView$decidePolicyForNewWindowAction$request$newFrameName$decisionListener$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSDictionary *action, NSURLRequest *request, NSString *frame, id listener) { - UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); - if ([uiWebView respondsToSelector:@selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:)]) - [uiWebView webView:view decidePolicyForNewWindowAction:action request:request newFrameName:frame decisionListener:listener]; -} - -- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id)listener { - id delegate([self delegate]); - CYWebPolicyDecisionMediator *mediator([[[CYWebPolicyDecisionMediator alloc] initWithListener:listener] autorelease]); - if (![mediator decided] && [delegate respondsToSelector:@selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:)]) - [delegate webView:view decidePolicyForNewWindowAction:action request:request newFrameName:frame decisionListener:mediator]; - if (![mediator decided] && [UIWebView instancesRespondToSelector:@selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:)]) - [super webView:view decidePolicyForNewWindowAction:action request:request newFrameName:frame decisionListener:mediator]; - [mediator decide]; -} -// }}} -// webView:didClearWindowObject:forFrame: (3.2+) {{{ -static void $UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, WebScriptObject *window, WebFrame *frame) { - UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); - if ([uiWebView respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)]) - [uiWebView webView:view didClearWindowObject:window forFrame:frame]; -} - -- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)]) - [delegate webView:view didClearWindowObject:window forFrame:frame]; - if ([UIWebView instancesRespondToSelector:@selector(webView:didClearWindowObject:forFrame:)]) - [super webView:view didClearWindowObject:window forFrame:frame]; -} -// }}} -// webView:didFailLoadWithError:forFrame: (2.0+) {{{ -- (void) webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) - [delegate webView:view didFailLoadWithError:error forFrame:frame]; - if ([UIWebView instancesRespondToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) - [super webView:view didFailLoadWithError:error forFrame:frame]; -} -// }}} -// webView:didFailProvisionalLoadWithError:forFrame: (2.0+) {{{ -- (void) webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:didFailProvisionalLoadWithError:forFrame:)]) - [delegate webView:view didFailProvisionalLoadWithError:error forFrame:frame]; - if ([UIWebView instancesRespondToSelector:@selector(webView:didFailProvisionalLoadWithError:forFrame:)]) - [super webView:view didFailProvisionalLoadWithError:error forFrame:frame]; -} -// }}} -// webView:didFinishLoadForFrame: (2.0+) {{{ -- (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) - [delegate webView:view didFinishLoadForFrame:frame]; - if ([UIWebView instancesRespondToSelector:@selector(webView:didFinishLoadForFrame:)]) - [super webView:view didFinishLoadForFrame:frame]; -} -// }}} -// webView:didReceiveTitle:forFrame: (3.2+) {{{ -static void $UIWebViewWebViewDelegate$webView$didReceiveTitle$forFrame$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSString *title, WebFrame *frame) { - UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); - if ([uiWebView respondsToSelector:@selector(webView:didReceiveTitle:forFrame:)]) - [uiWebView webView:view didReceiveTitle:title forFrame:frame]; -} - -- (void) webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:didReceiveTitle:forFrame:)]) - [delegate webView:view didReceiveTitle:title forFrame:frame]; - if ([UIWebView instancesRespondToSelector:@selector(webView:didReceiveTitle:forFrame:)]) - [super webView:view didReceiveTitle:title forFrame:frame]; -} -// }}} -// webView:didStartProvisionalLoadForFrame: (2.0+) {{{ -- (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webView:didStartProvisionalLoadForFrame:)]) - [delegate webView:view didStartProvisionalLoadForFrame:frame]; - if ([UIWebView instancesRespondToSelector:@selector(webView:didStartProvisionalLoadForFrame:)]) - [super webView:view didStartProvisionalLoadForFrame:frame]; -} -// }}} -// webView:resource:willSendRequest:redirectResponse:fromDataSource: (3.2+) {{{ -static NSURLRequest *$UIWebViewWebViewDelegate$webView$resource$willSendRequest$redirectResponse$fromDataSource$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, id identifier, NSURLRequest *request, NSURLResponse *response, WebDataSource *source) { - UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); - if ([uiWebView respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) - request = [uiWebView webView:view resource:identifier willSendRequest:request redirectResponse:response fromDataSource:source]; - return request; -} - -- (NSURLRequest *) webView:(WebView *)view resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source { - id delegate([self delegate]); - if ([UIWebView instancesRespondToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) - request = [super webView:view resource:identifier willSendRequest:request redirectResponse:response fromDataSource:source]; - if ([delegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) - request = [delegate webView:view resource:identifier willSendRequest:request redirectResponse:response fromDataSource:source]; - return request; -} -// }}} -// webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame: (2.1+) {{{ -- (void) webView:(WebView *)view runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([UIWebView instancesRespondToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:)]) - if ( - ![delegate respondsToSelector:@selector(webView:shouldRunJavaScriptAlertPanelWithMessage:initiatedByFrame:)] || - [delegate webView:view shouldRunJavaScriptAlertPanelWithMessage:message initiatedByFrame:frame] - ) - [super webView:view runJavaScriptAlertPanelWithMessage:message initiatedByFrame:frame]; -} -// }}} -// webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame: (2.1+) {{{ -- (BOOL) webView:(WebView *)view runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([UIWebView instancesRespondToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:)]) - if ( - ![delegate respondsToSelector:@selector(webView:shouldRunJavaScriptConfirmPanelWithMessage:initiatedByFrame:)] || - [delegate webView:view shouldRunJavaScriptConfirmPanelWithMessage:message initiatedByFrame:frame] - ) - return [super webView:view runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:frame]; - return NO; -} -// }}} -// webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame: (2.1+) {{{ -- (NSString *) webView:(WebView *)view runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(WebFrame *)frame { - id delegate([self delegate]); - if ([UIWebView instancesRespondToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)]) - if ( - ![delegate respondsToSelector:@selector(webView:shouldRunJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)] || - [delegate webView:view shouldRunJavaScriptTextInputPanelWithPrompt:prompt defaultText:text initiatedByFrame:frame] - ) - return [super webView:view runJavaScriptTextInputPanelWithPrompt:prompt defaultText:text initiatedByFrame:frame]; - return nil; -} -// }}} -// webViewClose: (3.2+) {{{ -static void $UIWebViewWebViewDelegate$webViewClose$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view) { - UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); - if ([uiWebView respondsToSelector:@selector(webViewClose:)]) - [uiWebView webViewClose:view]; -} - -- (void) webViewClose:(WebView *)view { - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webViewClose:)]) - [delegate webViewClose:view]; - if ([UIWebView instancesRespondToSelector:@selector(webViewClose:)]) - [super webViewClose:view]; -} -// }}} - -- (void) _updateViewSettings { - [super _updateViewSettings]; - - id delegate([self delegate]); - if ([delegate respondsToSelector:@selector(webViewUpdateViewSettings:)]) - [delegate webViewUpdateViewSettings:self]; -} - -- (void) dispatchEvent:(NSString *)event { - WebThreadLocked lock; - - NSString *script([NSString stringWithFormat:@ - "(function() {" - "var event = this.document.createEvent('Events');" - "event.initEvent('%@', false, false);" - "this.document.dispatchEvent(event);" - "})();" - , event]); - - NSMutableArray *frames([NSMutableArray arrayWithObjects: - [[[self _documentView] webView] mainFrame] - , nil]); - - while (WebFrame *frame = [frames lastObject]) { - WebScriptObject *object([frame windowObject]); - [object evaluateWebScript:script]; - [frames removeLastObject]; - [frames addObjectsFromArray:[frame childFrames]]; - } -} - -- (void) reloadFromOrigin { - [[[self _documentView] webView] reloadFromOrigin:nil]; -} - -+ (void) initialize { - if (Class $UIWebViewWebViewDelegate = objc_getClass("UIWebViewWebViewDelegate")) { - class_addMethod($UIWebViewWebViewDelegate, @selector(webView:addMessageToConsole:), (IMP) &$UIWebViewWebViewDelegate$webView$addMessageToConsole$, "v16@0:4@8@12"); - class_addMethod($UIWebViewWebViewDelegate, @selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:), (IMP) &$UIWebViewWebViewDelegate$webView$decidePolicyForNewWindowAction$request$newFrameName$decisionListener$, "v28@0:4@8@12@16@20@24"); - class_addMethod($UIWebViewWebViewDelegate, @selector(webView:didClearWindowObject:forFrame:), (IMP) &$UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$, "v20@0:4@8@12@16"); - class_addMethod($UIWebViewWebViewDelegate, @selector(webView:didReceiveTitle:forFrame:), (IMP) &$UIWebViewWebViewDelegate$webView$didReceiveTitle$forFrame$, "v20@0:4@8@12@16"); - class_addMethod($UIWebViewWebViewDelegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), (IMP) &$UIWebViewWebViewDelegate$webView$resource$willSendRequest$redirectResponse$fromDataSource$, "@28@0:4@8@12@16@20@24"); - class_addMethod($UIWebViewWebViewDelegate, @selector(webViewClose:), (IMP) &$UIWebViewWebViewDelegate$webViewClose$, "v12@0:4@8"); - } -} - -@end diff --git a/CyteKit/CyteWebViewController.h b/CyteKit/CyteWebViewController.h deleted file mode 100644 index 5b91747e..00000000 --- a/CyteKit/CyteWebViewController.h +++ /dev/null @@ -1,139 +0,0 @@ -/* 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_CyteWebViewController_H -#define CyteKit_CyteWebViewController_H - -#include "CyteKit/CyteViewController.h" -#include "CyteKit/CyteWebView.h" - -#include - -#include - -@class IndirectDelegate; - -@protocol CyteWebViewControllerDelegate -- (void) retainNetworkActivityIndicator; -- (void) releaseNetworkActivityIndicator; -- (CYViewController *) pageForURL:(NSURL *)url forExternal:(BOOL)external; -- (void) unloadData; -@end - -@interface CyteWebViewController : CYViewController < - CyteWebViewDelegate, - UIWebViewDelegate -> { - _transient CyteWebView *webview_; - _transient UIScrollView *scroller_; - - UIActivityIndicatorView *indicator_; - IndirectDelegate *indirect_; - NSURLAuthenticationChallenge *challenge_; - - bool error_; - _H request_; - - _transient NSNumber *sensitive_; - - NSString *title_; - NSMutableSet *loading_; - - // XXX: NSString * or UIImage * - _H custom_; - _H style_; - - _H function_; - - float width_; - Class class_; - - UIBarButtonItem *reloaditem_; - UIBarButtonItem *loadingitem_; - - bool visible_; - bool hidesNavigationBar_; - bool allowsNavigationAction_; -} - -+ (void) _initialize; - -- (void) setURL:(NSURL *)url; - -- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy; -- (void) loadURL:(NSURL *)url; - -- (void) loadRequest:(NSURLRequest *)request; -- (bool) isLoading; - -- (void) reloadURLWithCache:(BOOL)cache; -- (void) reloadURL; - -- (id) init; -- (id) initWithURL:(NSURL *)url; -- (id) initWithWidth:(float)width; -- (id) initWithWidth:(float)width ofClass:(Class)_class; - -- (void) callFunction:(WebScriptObject *)function; - -- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; -- (NSURLRequest *) webView:(WebView *)view resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source; - -+ (float) defaultWidth; - -- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function; -- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function; -- (void) setHidesNavigationBar:(bool)value; - -- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button; -- (void) customButtonClicked; -- (void) applyRightButton; - -- (void) _didStartLoading; -- (void) _didFinishLoading; - -- (void) close; - -- (void) dispatchEvent:(NSString *)event; - -- (void) setViewportWidthOnMainThread:(float)value; - -@end - -#endif//CyteKit_CyteWebViewController_H diff --git a/CyteKit/CyteWebViewController.mm b/CyteKit/CyteWebViewController.mm deleted file mode 100644 index cd43c947..00000000 --- a/CyteKit/CyteWebViewController.mm +++ /dev/null @@ -1,935 +0,0 @@ -#include "CyteKit/UCPlatform.h" - -#include -#include "iPhonePrivate.h" - -#include "CyteKit/CyteLocalize.h" -#include "CyteKit/CyteWebViewController.h" -#include "CyteKit/PerlCompatibleRegEx.hpp" -#include "CyteKit/WebThreadLocked.hpp" - -//#include -// XXX: fix the minimum requirement -extern NSString * const kCAFilterNearest; - -#include - -#include - -#include -#include -#include -#include -#include - -#define ForSaurik 0 -#define DefaultTimeout_ 120.0 - -#define ShowInternals 0 -#define LogBrowser 0 -#define LogMessages 0 - -#define lprintf(args...) fprintf(stderr, args) - -template -static inline void CYRelease(Type_ &value) { - if (value != nil) { - [value release]; - value = nil; - } -} - -float CYScrollViewDecelerationRateNormal; - -@interface WebView (Apple) -- (void) _setLayoutInterval:(float)interval; -- (void) _setAllowsMessaging:(BOOL)allows; -@end - -@interface WebPreferences (Apple) -+ (void) _setInitialDefaultTextEncodingToSystemEncoding; -- (void) _setLayoutInterval:(NSInteger)interval; -- (void) setOfflineWebApplicationCacheEnabled:(BOOL)enabled; -@end - -/* Indirect Delegate {{{ */ -@interface IndirectDelegate : NSObject { - _transient volatile id delegate_; -} - -- (void) setDelegate:(id)delegate; -- (id) initWithDelegate:(id)delegate; -@end - -@implementation IndirectDelegate - -- (void) setDelegate:(id)delegate { - delegate_ = delegate; -} - -- (id) initWithDelegate:(id)delegate { - delegate_ = delegate; - return self; -} - -- (IMP) methodForSelector:(SEL)sel { - if (IMP method = [super methodForSelector:sel]) - return method; - fprintf(stderr, "methodForSelector:[%s] == NULL\n", sel_getName(sel)); - return NULL; -} - -- (BOOL) respondsToSelector:(SEL)sel { - if ([super respondsToSelector:sel]) - return YES; - - // XXX: WebThreadCreateNSInvocation returns nil - -#if ShowInternals - fprintf(stderr, "[%s]R?%s\n", class_getName(self->isa), sel_getName(sel)); -#endif - - return delegate_ == nil ? NO : [delegate_ respondsToSelector:sel]; -} - -- (NSMethodSignature *) methodSignatureForSelector:(SEL)sel { - if (NSMethodSignature *method = [super methodSignatureForSelector:sel]) - return method; - -#if ShowInternals - fprintf(stderr, "[%s]S?%s\n", class_getName(self->isa), sel_getName(sel)); -#endif - - if (delegate_ != nil) - if (NSMethodSignature *sig = [delegate_ methodSignatureForSelector:sel]) - return sig; - - // XXX: I fucking hate Apple so very very bad - return [NSMethodSignature signatureWithObjCTypes:"v@:"]; -} - -- (void) forwardInvocation:(NSInvocation *)inv { - SEL sel = [inv selector]; - if (delegate_ != nil && [delegate_ respondsToSelector:sel]) - [inv invokeWithTarget:delegate_]; -} - -@end -/* }}} */ - -@implementation CyteWebViewController - -#if ShowInternals -#include "CyteKit/UCInternal.h" -#endif - -+ (void) _initialize { - [WebPreferences _setInitialDefaultTextEncodingToSystemEncoding]; - - 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 - CYScrollViewDecelerationRateNormal = 0.998; -} - -- (void) dealloc { -#if LogBrowser - NSLog(@"[CyteWebViewController dealloc]"); -#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]; -} - -- (NSURL *) URLWithURL:(NSURL *)url { - return url; -} - -- (NSURLRequest *) requestWithURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - return [NSURLRequest - requestWithURL:[self URLWithURL:url] - cachePolicy:policy - timeoutInterval:DefaultTimeout_ - ]; -} - -- (void) setURL:(NSURL *)url { - _assert(request_ == nil); - request_ = [self requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; -} - -- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - [self loadRequest:[self requestWithURL:url cachePolicy:policy]]; -} - -- (void) loadURL:(NSURL *)url { - [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; -} - -- (void) loadRequest:(NSURLRequest *)request { -#if LogBrowser - NSLog(@"loadRequest:%@", request); -#endif - - error_ = false; - - WebThreadLocked lock; - [webview_ loadRequest:request]; -} - -- (void) reloadURLWithCache:(BOOL)cache { - if (request_ == nil) - return; - - NSMutableURLRequest *request([request_ mutableCopy]); - [request setCachePolicy:(cache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData)]; - - request_ = request; - - if ([request_ HTTPBody] == nil && [request_ HTTPBodyStream] == nil) - [self loadRequest:request_]; - else { - UIAlertView *alert = [[[UIAlertView alloc] - initWithTitle:UCLocalize("RESUBMIT_FORM") - message:nil - delegate:self - cancelButtonTitle:UCLocalize("CANCEL") - otherButtonTitles: - UCLocalize("SUBMIT"), - nil - ] autorelease]; - - [alert setContext:@"submit"]; - [alert show]; - } -} - -- (void) reloadURL { - [self reloadURLWithCache:YES]; -} - -- (void) reloadData { - [super reloadData]; - [self reloadURLWithCache:YES]; -} - -- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { - custom_ = button; - style_ = style; - function_ = function; - - [self performSelectorOnMainThread:@selector(applyRightButton) withObject:nil waitUntilDone:NO]; -} - -- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { - custom_ = button; - style_ = style; - function_ = function; - - [self performSelectorOnMainThread:@selector(applyRightButton) withObject:nil waitUntilDone:NO]; -} - -- (void) removeButton { - custom_ = [NSNull null]; - [self performSelectorOnMainThread:@selector(applyRightButton) withObject:nil waitUntilDone:NO]; -} - -- (void) scrollToBottomAnimated:(NSNumber *)animated { - CGSize size([scroller_ contentSize]); - CGPoint offset([scroller_ contentOffset]); - CGRect frame([scroller_ frame]); - - if (size.height - offset.y < frame.size.height + 20.f) { - CGRect rect = {{0, size.height-1}, {size.width, 1}}; - [scroller_ scrollRectToVisible:rect animated:[animated boolValue]]; - } -} - -- (void) _setViewportWidth { - [[webview_ _documentView] setViewportSize:CGSizeMake(width_, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; -} - -- (void) setViewportWidth:(float)width { - width_ = width != 0 ? width : [[self class] defaultWidth]; - [self _setViewportWidth]; -} - -- (void) _setViewportWidthOnMainThread:(NSNumber *)width { - [self setViewportWidth:[width floatValue]]; -} - -- (void) setViewportWidthOnMainThread:(float)width { - [self performSelectorOnMainThread:@selector(_setViewportWidthOnMainThread:) withObject:[NSNumber numberWithFloat:width] waitUntilDone:NO]; -} - -- (void) webViewUpdateViewSettings:(UIWebView *)view { - [self _setViewportWidth]; -} - -- (void) _openMailToURL:(NSURL *)url { - [[UIApplication sharedApplication] openURL:url];// asPanel:YES]; -} - -- (bool) _allowJavaScriptPanel { - return true; -} - -- (bool) allowsNavigationAction { - return allowsNavigationAction_; -} - -- (void) setAllowsNavigationAction:(bool)value { - allowsNavigationAction_ = value; -} - -- (void) setAllowsNavigationActionByNumber:(NSNumber *)value { - [self setAllowsNavigationAction:[value boolValue]]; -} - -- (void) popViewControllerWithNumber:(NSNumber *)value { - UINavigationController *navigation([self navigationController]); - if ([navigation topViewController] == self) - [navigation popViewControllerAnimated:[value boolValue]]; -} - -- (void) _didFailWithError:(NSError *)error forFrame:(WebFrame *)frame { - [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]]; - [self _didFinishLoading]; - - if ([error code] == NSURLErrorCancelled) - return; - - if ([frame parentFrame] == nil) { - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", - [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString], - [[error localizedDescription] stringByAddingPercentEscapes] - ]]]; - - error_ = true; - } -} - -- (void) pushRequest:(NSURLRequest *)request asPop:(bool)pop { - NSURL *url([request URL]); - - // XXX: filter to internal usage? - CYViewController *page([delegate_ pageForURL:url forExternal:NO]); - - if (page == nil) { - CyteWebViewController *browser([[[class_ alloc] init] autorelease]); - [browser loadRequest:request]; - page = browser; - } - - [page setDelegate:delegate_]; - - if (!pop) { - [[self navigationItem] setTitle:title_]; - - [[self navigationController] pushViewController:page animated:YES]; - } else { - UINavigationController *navigation([[[UINavigationController alloc] initWithRootViewController:page] autorelease]); - - [navigation setDelegate:delegate_]; - - [[page navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] - initWithTitle:UCLocalize("CLOSE") - style:UIBarButtonItemStylePlain - target:page - action:@selector(close) - ] autorelease]]; - - [[self navigationController] presentModalViewController:navigation animated:YES]; - - [delegate_ unloadData]; - } -} - -// 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$"); - if (NSString *data = [message objectForKey:@"message"]) - if (irritating(data)) - return; - - NSLog(@"addMessageToConsole:%@", message); -#endif -} - -- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { -#if LogBrowser - NSLog(@"decidePolicyForNavigationAction:%@ request:%@ frame:%@", action, request, frame); -#endif - - if ([frame parentFrame] == nil) { - if (!error_) { - NSURL *url(request == nil ? nil : [request URL]); - - if (request_ == nil || [self allowsNavigationAction] || [[request_ URL] isEqual:url]) - request_ = request; - else { - if (url != nil) - [self pushRequest:request asPop:NO]; - [listener ignore]; - } - } - } -} - -- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id)listener { -#if LogBrowser - NSLog(@"decidePolicyForNewWindowAction:%@ request:%@ newFrameName:%@", action, request, frame); -#endif - - NSURL *url([request URL]); - if (url == nil) - return; - - if ([frame isEqualToString:@"_open"]) - [delegate_ openURL:url]; - else { - NSString *scheme([[url scheme] lowercaseString]); - if ([scheme isEqualToString:@"mailto"]) - [self _openMailToURL:url]; - else - [self pushRequest:request asPop:[frame isEqualToString:@"_popup"]]; - } - - [listener ignore]; -} - -- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { -} - -- (void) webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { -#if LogBrowser - NSLog(@"didFailLoadWithError:%@ forFrame:%@", error, frame); -#endif - - [self _didFailWithError:error forFrame:frame]; -} - -- (void) webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { -#if LogBrowser - NSLog(@"didFailProvisionalLoadWithError:%@ forFrame:%@", error, frame); -#endif - - [self _didFailWithError:error forFrame:frame]; -} - -- (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame { - [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]]; - - if ([frame parentFrame] == nil) { - if (DOMDocument *document = [frame DOMDocument]) - if (DOMNodeList *bodies = [document getElementsByTagName:@"body"]) - for (DOMHTMLBodyElement *body in (id) bodies) { - DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]); - - UIColor *uic(nil); - - if (DOMCSSPrimitiveValue *color = static_cast([style getPropertyCSSValue:@"background-color"])) { - if ([color primitiveType] == DOM_CSS_RGBCOLOR) { - DOMRGBColor *rgb([color getRGBColorValue]); - - float red([[rgb red] getFloatValue:DOM_CSS_NUMBER]); - float green([[rgb green] getFloatValue:DOM_CSS_NUMBER]); - float blue([[rgb blue] getFloatValue:DOM_CSS_NUMBER]); - float alpha([[rgb alpha] getFloatValue:DOM_CSS_NUMBER]); - - if (red == 0xc7 && green == 0xce && blue == 0xd5) - uic = [UIColor pinStripeColor]; - else if (alpha != 0) - uic = [UIColor - colorWithRed:(red / 255) - green:(green / 255) - blue:(blue / 255) - alpha:alpha - ]; - } - } - - [scroller_ setBackgroundColor:(uic ?: [UIColor clearColor])]; - break; - } - } - - [self _didFinishLoading]; -} - -- (void) webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - if (title_ != nil) - [title_ autorelease]; - title_ = [title retain]; - - [[self navigationItem] setTitle:title_]; -} - -- (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame { - [loading_ addObject:[NSValue valueWithNonretainedObject:frame]]; - - if ([frame parentFrame] == nil) { - CYRelease(title_); - custom_ = nil; - style_ = nil; - function_ = nil; - - [self setHidesNavigationBar:NO]; - - // XXX: do we still need to do this? - [[self navigationItem] setTitle:nil]; - } - - [self _didStartLoading]; -} - -- (NSURLRequest *) webView:(WebView *)view resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source { -#if LogBrowser - NSLog(@"resource:%@ willSendRequest:%@ redirectResponse:%@ fromDataSource:%@", identifier, request, response, source); -#endif - - return request; -} - -- (bool) webView:(WebView *)view shouldRunJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - return [self _allowJavaScriptPanel]; -} - -- (bool) webView:(WebView *)view shouldRunJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - return [self _allowJavaScriptPanel]; -} - -- (bool) webView:(WebView *)view shouldRunJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(WebFrame *)frame { - return [self _allowJavaScriptPanel]; -} - -- (void) webViewClose:(WebView *)view { - [self close]; -} -// }}} - -- (void) close { - [[self navigationController] dismissModalViewControllerAnimated:YES]; -} - -- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button { - NSString *context([alert context]); - - if ([context isEqualToString:@"sensitive"]) { - switch (button) { - case 1: - sensitive_ = [NSNumber numberWithBool:YES]; - break; - - case 2: - sensitive_ = [NSNumber numberWithBool:NO]; - break; - } - - [alert dismissWithClickedButtonIndex:-1 animated:YES]; - } else if ([context isEqualToString:@"challenge"]) { - id sender([challenge_ sender]); - - switch (button) { - case 1: { - NSString *username([[alert textFieldAtIndex:0] text]); - NSString *password([[alert textFieldAtIndex:1] text]); - - NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]); - - [sender useCredential:credential forAuthenticationChallenge:challenge_]; - } break; - - case 2: - [sender cancelAuthenticationChallenge:challenge_]; - break; - - _nodefault - } - - [challenge_ release]; - challenge_ = nil; - - [alert dismissWithClickedButtonIndex:-1 animated:YES]; - } else if ([context isEqualToString:@"submit"]) { - if (button == [alert cancelButtonIndex]) { - } else if (button == [alert firstOtherButtonIndex]) { - if (request_ != nil) { - WebThreadLocked lock; - [webview_ loadRequest:request_]; - } - } - - [alert dismissWithClickedButtonIndex:-1 animated:YES]; - } -} - -- (UIBarButtonItemStyle) rightButtonStyle { - if (style_ == nil) normal: - return UIBarButtonItemStylePlain; - else if ([style_ isEqualToString:@"Normal"]) - return UIBarButtonItemStylePlain; - else if ([style_ isEqualToString:@"Highlighted"]) - return UIBarButtonItemStyleDone; - else goto normal; -} - -- (UIBarButtonItem *) customButton { - return custom_ == [NSNull null] ? nil : [[[UIBarButtonItem alloc] - initWithTitle:static_cast(custom_.operator NSObject *()) - style:[self rightButtonStyle] - target:self - action:@selector(customButtonClicked) - ] autorelease]; -} - -- (UIBarButtonItem *) rightButton { - return reloaditem_; -} - -- (void) applyLoadingTitle { - [[self navigationItem] setTitle:UCLocalize("LOADING")]; -} - -- (void) layoutRightButton { - [[loadingitem_ view] addSubview:indicator_]; - [[loadingitem_ view] bringSubviewToFront:indicator_]; -} - -- (void) applyRightButton { - if ([self isLoading]) { - [[self navigationItem] setRightBarButtonItem:loadingitem_ animated:YES]; - [self performSelector:@selector(layoutRightButton) withObject:nil afterDelay:0]; - - [indicator_ startAnimating]; - [self applyLoadingTitle]; - } else { - [indicator_ stopAnimating]; - - [[self navigationItem] setRightBarButtonItem:( - custom_ != nil ? [self customButton] : [self rightButton] - ) animated:YES]; - } -} - -- (void) didStartLoading { - // Overridden in subclasses. -} - -- (void) _didStartLoading { - [self applyRightButton]; - - if ([loading_ count] != 1) - return; - - [delegate_ retainNetworkActivityIndicator]; - [self didStartLoading]; -} - -- (void) didFinishLoading { - // Overridden in subclasses. -} - -- (void) _didFinishLoading { - if ([loading_ count] != 0) - return; - - [self applyRightButton]; - [[self navigationItem] setTitle:title_]; - - [delegate_ releaseNetworkActivityIndicator]; - [self didFinishLoading]; -} - -- (bool) isLoading { - return [loading_ count] != 0; -} - -- (id) initWithWidth:(float)width ofClass:(Class)_class { - if ((self = [super init]) != nil) { - allowsNavigationAction_ = true; - - class_ = _class; - loading_ = [[NSMutableSet alloc] initWithCapacity:5]; - - indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; - - CGRect bounds([[self view] bounds]); - - webview_ = [[[CyteWebView alloc] initWithFrame:bounds] autorelease]; - [webview_ setDelegate:self]; - [self setView:webview_]; - - if ([webview_ respondsToSelector:@selector(setDataDetectorTypes:)]) - [webview_ setDataDetectorTypes:UIDataDetectorTypeAutomatic]; - else - [webview_ setDetectsPhoneNumbers:NO]; - - [webview_ setScalesPageToFit:YES]; - - UIWebDocumentView *document([webview_ _documentView]); - - // XXX: I think this improves scrolling; the hardcoded-ness sucks - [document setTileSize:CGSizeMake(320, 500)]; - - [document setBackgroundColor:[UIColor clearColor]]; - - // XXX: this is terribly (too?) expensive - [document setDrawsBackground:NO]; - - WebView *webview([document webView]); - WebPreferences *preferences([webview preferences]); - - // XXX: I have no clue if I actually /want/ this modification - if ([webview respondsToSelector:@selector(_setLayoutInterval:)]) - [webview _setLayoutInterval:0]; - else if ([preferences respondsToSelector:@selector(_setLayoutInterval:)]) - [preferences _setLayoutInterval:0]; - - [preferences setCacheModel:WebCacheModelDocumentBrowser]; - [preferences setOfflineWebApplicationCacheEnabled:YES]; - -#if LogMessages - if ([document respondsToSelector:@selector(setAllowsMessaging:)]) - [document setAllowsMessaging:YES]; - if ([webview respondsToSelector:@selector(_setAllowsMessaging:)]) - [webview _setAllowsMessaging:YES]; -#endif - - if ([webview_ respondsToSelector:@selector(_scrollView)]) { - scroller_ = [webview_ _scrollView]; - - [scroller_ setDirectionalLockEnabled:YES]; - [scroller_ setDecelerationRate:CYScrollViewDecelerationRateNormal]; - [scroller_ setDelaysContentTouches:NO]; - - [scroller_ setCanCancelContentTouches:YES]; - } else if ([webview_ respondsToSelector:@selector(_scroller)]) { - UIScroller *scroller([webview_ _scroller]); - scroller_ = (UIScrollView *) scroller; - - [scroller setDirectionalScrolling:YES]; - // XXX: we might be better off /not/ setting this on older systems - [scroller setScrollDecelerationFactor:CYScrollViewDecelerationRateNormal]; /* 0.989324 */ - [scroller setScrollHysteresis:0]; /* 8 */ - - [scroller setThumbDetectionEnabled:NO]; - - // use NO with UIApplicationUseLegacyEvents(YES) - [scroller setEventMode:YES]; - - // XXX: this is handled by setBounces, right? - //[scroller setAllowsRubberBanding:YES]; - } - - [scroller_ setFixedBackgroundPattern:YES]; - [scroller_ setBackgroundColor:[UIColor clearColor]]; - [scroller_ setClipsSubviews:YES]; - - [scroller_ setBounces:YES]; - [scroller_ setScrollingEnabled:YES]; - [scroller_ setShowBackgroundShadow:NO]; - - [self setViewportWidth:width]; - - reloaditem_ = [[UIBarButtonItem alloc] - initWithTitle:UCLocalize("RELOAD") - style:[self rightButtonStyle] - target:self - action:@selector(reloadButtonClicked) - ]; - - loadingitem_ = [[UIBarButtonItem alloc] - initWithTitle:@" " - style:UIBarButtonItemStylePlain - target:self - action:@selector(reloadButtonClicked) - ]; - - indicator_ = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - [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]; - - [table setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; - [webview_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; - [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; - } return self; -} - -- (id) initWithWidth:(float)width { - return [self initWithWidth:width ofClass:[self class]]; -} - -- (id) init { - return [self initWithWidth:0]; -} - -- (id) initWithURL:(NSURL *)url { - if ((self = [self init]) != nil) { - [self setURL:url]; - } return self; -} - -- (void) callFunction:(WebScriptObject *)function { - WebThreadLocked lock; - - WebView *webview([[webview_ _documentView] webView]); - WebFrame *frame([webview mainFrame]); - WebPreferences *preferences([webview preferences]); - - bool maybe([preferences javaScriptCanOpenWindowsAutomatically]); - [preferences setJavaScriptCanOpenWindowsAutomatically:NO]; - - /*id _private(MSHookIvar(webview, "_private")); - WebCore::Page *page(_private == nil ? NULL : MSHookIvar(_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]); - JSObjectCallAsFunction(context, object, NULL, 0, NULL, NULL); - - /*if (settings != NULL) - settings->setJavaScriptCanOpenWindowsAutomatically(no);*/ - - [preferences setJavaScriptCanOpenWindowsAutomatically:maybe]; -} - -- (void) reloadButtonClicked { - [self reloadURLWithCache:YES]; -} - -- (void) _customButtonClicked { - [self reloadButtonClicked]; -} - -- (void) customButtonClicked { -#if !AlwaysReload - if (function_ != nil) - [self callFunction:function_]; - else -#endif - [self _customButtonClicked]; -} - -+ (float) defaultWidth { - return 980; -} - -- (void) setNavigationBarStyle:(NSString *)name { - UIBarStyle style; - if ([name isEqualToString:@"Black"]) - style = UIBarStyleBlack; - else - style = UIBarStyleDefault; - - [[[self navigationController] navigationBar] setBarStyle:style]; -} - -- (void) setNavigationBarTintColor:(UIColor *)color { - [[[self navigationController] navigationBar] setTintColor:color]; -} - -- (void) setBadgeValue:(id)value { - [[[self navigationController] tabBarItem] setBadgeValue:value]; -} - -- (void) setHidesBackButton:(bool)value { - [[self navigationItem] setHidesBackButton:value]; -} - -- (void) setHidesBackButtonByNumber:(NSNumber *)value { - [self setHidesBackButton:[value boolValue]]; -} - -- (void) dispatchEvent:(NSString *)event { - [webview_ dispatchEvent:event]; -} - -- (bool) hidesNavigationBar { - return hidesNavigationBar_; -} - -- (void) _setHidesNavigationBar:(bool)value animated:(bool)animated { - if (visible_) - [[self navigationController] setNavigationBarHidden:(value && [self hidesNavigationBar]) animated:animated]; -} - -- (void) setHidesNavigationBar:(bool)value { - if (hidesNavigationBar_ != value) { - hidesNavigationBar_ = value; - [self _setHidesNavigationBar:YES animated:YES]; - } -} - -- (void) setHidesNavigationBarByNumber:(NSNumber *)value { - [self setHidesNavigationBar:[value boolValue]]; -} - -- (void) viewWillAppear:(BOOL)animated { - visible_ = true; - - if ([self hidesNavigationBar]) - [self _setHidesNavigationBar:YES animated:animated]; - - [self dispatchEvent:@"CydiaViewWillAppear"]; - [super viewWillAppear:animated]; -} - -- (void) viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - [self dispatchEvent:@"CydiaViewDidAppear"]; -} - -- (void) viewWillDisappear:(BOOL)animated { - [self dispatchEvent:@"CydiaViewWillDisappear"]; - [super viewWillDisappear:animated]; - - if ([self hidesNavigationBar]) - [self _setHidesNavigationBar:NO animated:animated]; - - visible_ = false; -} - -- (void) viewDidDisappear:(BOOL)animated { - [super viewDidDisappear:animated]; - [self dispatchEvent:@"CydiaViewDidDisappear"]; -} - -@end diff --git a/CyteKit/Localize.h b/CyteKit/Localize.h new file mode 100644 index 00000000..19b81e61 --- /dev/null +++ b/CyteKit/Localize.h @@ -0,0 +1,51 @@ +/* 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_Localize_H +#define CyteKit_Localize_H + +#include + +static inline NSString *UCLocalizeEx(NSString *key, NSString *value = nil) { + return [[NSBundle mainBundle] localizedStringForKey:key value:value table:nil]; +} + +#define UCLocalize(key) UCLocalizeEx(@ key) + +#endif//CyteKit_Localize_H diff --git a/CyteKit/NSString-Cyte.h b/CyteKit/NSString-Cyte.h deleted file mode 100644 index a5955c4d..00000000 --- a/CyteKit/NSString-Cyte.h +++ /dev/null @@ -1,50 +0,0 @@ -/* 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_NSString_Cydia_H -#define CyteKit_NSString_Cydia_H - -#include - -@interface NSString (Cyte) -+ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length; -+ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length; -@end - -#endif//CyteKit_NSString_Cydia_H diff --git a/CyteKit/NSString-Cyte.mm b/CyteKit/NSString-Cyte.mm deleted file mode 100644 index 6ab4c869..00000000 --- a/CyteKit/NSString-Cyte.mm +++ /dev/null @@ -1,52 +0,0 @@ -/* 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/NSString-Cyte.h" - -@implementation NSString (Cyte) - -+ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length { - return [[[NSString alloc] initWithBytesNoCopy:const_cast(bytes) length:length encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease]; -} - -+ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length { - return [[[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding] autorelease]; -} - -@end diff --git a/CyteKit/PerlCompatibleRegEx.hpp b/CyteKit/PerlCompatibleRegEx.hpp index 3bd5e765..cbbe068a 100644 --- a/CyteKit/PerlCompatibleRegEx.hpp +++ b/CyteKit/PerlCompatibleRegEx.hpp @@ -42,7 +42,7 @@ #include -#include "CyteKit/NSString-Cyte.h" +#include "CyteKit/stringWithUTF8Bytes.h" class Pcre { private: diff --git a/CyteKit/ViewController.h b/CyteKit/ViewController.h new file mode 100644 index 00000000..1cf1a509 --- /dev/null +++ b/CyteKit/ViewController.h @@ -0,0 +1,84 @@ +/* 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_ViewController_H +#define CyteKit_ViewController_H + +#include + +#include + +@interface UIViewController (Cydia) +- (BOOL) hasLoaded; +- (void) reloadData; +- (void) unloadData; +@end + +@interface CYViewController : UIViewController { + _transient id delegate_; + BOOL loaded_; +} + +// The default implementation of this method is essentially a no-op, +// but calling the superclass implementation is *required*. +- (void) reloadData; + +- (void) unloadData; + +// This URL is used to save the state of the view controller. Return +// nil if you cannot or should not save the URL for this page. +- (NSURL *) navigationURL; + +// By default, this delegate is unused. However, it's provided here in case +// you need some kind of delegate in a subclass. +- (void) setDelegate:(id)delegate; +- (id) delegate; + +// Override this in subclasses if you manage the "has seen first load" state yourself. +- (BOOL) hasLoaded; + +// This is called when the view managed by the view controller is released. +// That is not always when the controller itself is released: it also can +// happen when more memory is needed by the system or whenever the controller +// just happens not to be visible. +- (void) releaseSubviews; + +@end + +#endif//CyteKit_ViewController_H diff --git a/CyteKit/ViewController.mm b/CyteKit/ViewController.mm new file mode 100644 index 00000000..ae69468c --- /dev/null +++ b/CyteKit/ViewController.mm @@ -0,0 +1,122 @@ +/* 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/ViewController.h" + +#include +#include + +extern bool IsWildcat_; + +@implementation UIViewController (Cydia) + +- (BOOL) hasLoaded { + return YES; +} + +- (void) reloadData { +} + +- (void) unloadData { + if (UIViewController *modal = [self modalViewController]) + [modal unloadData]; +} + +@end + +@implementation CYViewController + +- (void) setDelegate:(id)delegate { + delegate_ = delegate; +} + +- (id) delegate { + return delegate_; +} + +- (void) viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + // Load on first appearance. We don't need to set the loaded flag here + // because it is set for us the first time -reloadData is called. + if (![self hasLoaded]) + [self reloadData]; +} + +- (BOOL) hasLoaded { + return loaded_; +} + +- (void) releaseSubviews { + // Do nothing. +} + +- (void) setView:(UIView *)view { + // Nasty hack for 2.x-compatibility. In 3.0+, we can and + // should just override -viewDidUnload instead. + if (view == nil) + [self releaseSubviews]; + + [super setView:view]; +} + +- (void) reloadData { + [super reloadData]; + + // This is called automatically on the first appearance of a controller, + // or any other time it needs to reload the information shown. However (!), + // this is not called by any tab bar or navigation controller's -reloadData + // method unless this controller returns YES from -hadLoaded. + loaded_ = YES; +} + +- (void) unloadData { + loaded_ = NO; + [super unloadData]; +} + +- (NSURL *) navigationURL { + return nil; +} + +- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { + return IsWildcat_ || orientation == UIInterfaceOrientationPortrait; +} + +@end diff --git a/CyteKit/WebView.h b/CyteKit/WebView.h new file mode 100644 index 00000000..91878b7e --- /dev/null +++ b/CyteKit/WebView.h @@ -0,0 +1,80 @@ +/* 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_CydiaBrowser_H +#define CyteKit_CydiaBrowser_H + +#include + +#include +#include +#include +#include +#include + +#include + +@protocol CyteWebViewDelegate +- (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message; +- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener; +- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener; +- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; +- (void) webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame; +- (void) webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame; +- (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame; +- (void) webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame; +- (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame; +- (NSURLRequest *) webView:(WebView *)view resource:(id)resource willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source; +- (void) webViewClose:(WebView *)view; +- (bool) webView:(WebView *)view shouldRunJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame; +- (bool) webView:(WebView *)view shouldRunJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame; +- (bool) webView:(WebView *)view shouldRunJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(WebFrame *)frame; +- (void) webViewUpdateViewSettings:(UIWebView *)view; +@end + +@interface CyteWebView : UIWebView { +} + +- (id) delegate; +- (void) dispatchEvent:(NSString *)event; +- (void) reloadFromOrigin; + +@end + +#endif//CyteKit_CydiaBrowser_H diff --git a/CyteKit/WebView.mm b/CyteKit/WebView.mm new file mode 100644 index 00000000..8fd362f6 --- /dev/null +++ b/CyteKit/WebView.mm @@ -0,0 +1,368 @@ +/* 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/WebView.h" +#include "CyteKit/WebThreadLocked.hpp" + +#include + +#include "iPhonePrivate.h" + +// CYWebPolicyDecision* {{{ +enum CYWebPolicyDecision { + CYWebPolicyDecisionUnknown, + CYWebPolicyDecisionDownload, + CYWebPolicyDecisionIgnore, + CYWebPolicyDecisionUse, +}; + +@interface CYWebPolicyDecisionMediator : NSObject < + WebPolicyDecisionListener +> { + id listener_; + CYWebPolicyDecision decision_; +} + +- (id) initWithListener:(id)listener; + +- (CYWebPolicyDecision) decision; +- (bool) decided; +- (bool) decide; + +@end + +@implementation CYWebPolicyDecisionMediator + +- (id) initWithListener:(id)listener { + if ((self = [super init]) != nil) { + listener_ = listener; + } return self; +} + +- (CYWebPolicyDecision) decision { + return decision_; +} + +- (bool) decided { + return decision_ != CYWebPolicyDecisionUnknown; +} + +- (bool) decide { + switch (decision_) { + case CYWebPolicyDecisionUnknown: + default: + NSLog(@"CYWebPolicyDecisionUnknown"); + return false; + + case CYWebPolicyDecisionDownload: [listener_ download]; break; + case CYWebPolicyDecisionIgnore: [listener_ ignore]; break; + case CYWebPolicyDecisionUse: [listener_ use]; break; + } + + return true; +} + +- (void) download { + decision_ = CYWebPolicyDecisionDownload; +} + +- (void) ignore { + decision_ = CYWebPolicyDecisionIgnore; +} + +- (void) use { + decision_ = CYWebPolicyDecisionUse; +} + +@end +// }}} + +@implementation CyteWebView : UIWebView + +#if ShowInternals +#include "CyteKit/UCInternal.h" +#endif + +- (id) initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame]) != nil) { + } return self; +} + +- (void) dealloc { + [super dealloc]; +} + +- (id) delegate { + return (id) [super delegate]; +} + +/*- (WebView *) webView:(WebView *)view createWebViewWithRequest:(NSURLRequest *)request { + id delegate([self delegate]); + WebView *created(nil); + if (created == nil && [delegate respondsToSelector:@selector(webView:createWebViewWithRequest:)]) + created = [delegate webView:view createWebViewWithRequest:request]; + if (created == nil && [UIWebView instancesRespondToSelector:@selector(webView:createWebViewWithRequest:)]) + created = [super webView:view createWebViewWithRequest:request]; + return created; +}*/ + +// webView:addMessageToConsole: (X.Xx) {{{ +static void $UIWebViewWebViewDelegate$webView$addMessageToConsole$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSDictionary *message) { + UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); + if ([uiWebView respondsToSelector:@selector(webView:addMessageToConsole:)]) + [uiWebView webView:view addMessageToConsole:message]; +} + +- (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:addMessageToConsole:)]) + [delegate webView:view addMessageToConsole:message]; + if ([UIWebView instancesRespondToSelector:@selector(webView:addMessageToConsole:)]) + [super webView:view addMessageToConsole:message]; +} +// }}} +// webView:decidePolicyForNavigationAction:request:frame:decisionListener: (2.0+) {{{ +- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { + id delegate([self delegate]); + CYWebPolicyDecisionMediator *mediator([[[CYWebPolicyDecisionMediator alloc] initWithListener:listener] autorelease]); + if (![mediator decided] && [delegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) + [delegate webView:view decidePolicyForNavigationAction:action request:request frame:frame decisionListener:mediator]; + if (![mediator decided] && [UIWebView instancesRespondToSelector:@selector(webView:decidePolicyForNavigationAction:request:frame:decisionListener:)]) + [super webView:view decidePolicyForNavigationAction:action request:request frame:frame decisionListener:mediator]; + [mediator decide]; +} +// }}} +// webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener: (3.0+) {{{ +static void $UIWebViewWebViewDelegate$webView$decidePolicyForNewWindowAction$request$newFrameName$decisionListener$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSDictionary *action, NSURLRequest *request, NSString *frame, id listener) { + UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); + if ([uiWebView respondsToSelector:@selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:)]) + [uiWebView webView:view decidePolicyForNewWindowAction:action request:request newFrameName:frame decisionListener:listener]; +} + +- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id)listener { + id delegate([self delegate]); + CYWebPolicyDecisionMediator *mediator([[[CYWebPolicyDecisionMediator alloc] initWithListener:listener] autorelease]); + if (![mediator decided] && [delegate respondsToSelector:@selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:)]) + [delegate webView:view decidePolicyForNewWindowAction:action request:request newFrameName:frame decisionListener:mediator]; + if (![mediator decided] && [UIWebView instancesRespondToSelector:@selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:)]) + [super webView:view decidePolicyForNewWindowAction:action request:request newFrameName:frame decisionListener:mediator]; + [mediator decide]; +} +// }}} +// webView:didClearWindowObject:forFrame: (3.2+) {{{ +static void $UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, WebScriptObject *window, WebFrame *frame) { + UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); + if ([uiWebView respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)]) + [uiWebView webView:view didClearWindowObject:window forFrame:frame]; +} + +- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)]) + [delegate webView:view didClearWindowObject:window forFrame:frame]; + if ([UIWebView instancesRespondToSelector:@selector(webView:didClearWindowObject:forFrame:)]) + [super webView:view didClearWindowObject:window forFrame:frame]; +} +// }}} +// webView:didFailLoadWithError:forFrame: (2.0+) {{{ +- (void) webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) + [delegate webView:view didFailLoadWithError:error forFrame:frame]; + if ([UIWebView instancesRespondToSelector:@selector(webView:didFailLoadWithError:forFrame:)]) + [super webView:view didFailLoadWithError:error forFrame:frame]; +} +// }}} +// webView:didFailProvisionalLoadWithError:forFrame: (2.0+) {{{ +- (void) webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:didFailProvisionalLoadWithError:forFrame:)]) + [delegate webView:view didFailProvisionalLoadWithError:error forFrame:frame]; + if ([UIWebView instancesRespondToSelector:@selector(webView:didFailProvisionalLoadWithError:forFrame:)]) + [super webView:view didFailProvisionalLoadWithError:error forFrame:frame]; +} +// }}} +// webView:didFinishLoadForFrame: (2.0+) {{{ +- (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)]) + [delegate webView:view didFinishLoadForFrame:frame]; + if ([UIWebView instancesRespondToSelector:@selector(webView:didFinishLoadForFrame:)]) + [super webView:view didFinishLoadForFrame:frame]; +} +// }}} +// webView:didReceiveTitle:forFrame: (3.2+) {{{ +static void $UIWebViewWebViewDelegate$webView$didReceiveTitle$forFrame$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSString *title, WebFrame *frame) { + UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); + if ([uiWebView respondsToSelector:@selector(webView:didReceiveTitle:forFrame:)]) + [uiWebView webView:view didReceiveTitle:title forFrame:frame]; +} + +- (void) webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:didReceiveTitle:forFrame:)]) + [delegate webView:view didReceiveTitle:title forFrame:frame]; + if ([UIWebView instancesRespondToSelector:@selector(webView:didReceiveTitle:forFrame:)]) + [super webView:view didReceiveTitle:title forFrame:frame]; +} +// }}} +// webView:didStartProvisionalLoadForFrame: (2.0+) {{{ +- (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webView:didStartProvisionalLoadForFrame:)]) + [delegate webView:view didStartProvisionalLoadForFrame:frame]; + if ([UIWebView instancesRespondToSelector:@selector(webView:didStartProvisionalLoadForFrame:)]) + [super webView:view didStartProvisionalLoadForFrame:frame]; +} +// }}} +// webView:resource:willSendRequest:redirectResponse:fromDataSource: (3.2+) {{{ +static NSURLRequest *$UIWebViewWebViewDelegate$webView$resource$willSendRequest$redirectResponse$fromDataSource$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, id identifier, NSURLRequest *request, NSURLResponse *response, WebDataSource *source) { + UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); + if ([uiWebView respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) + request = [uiWebView webView:view resource:identifier willSendRequest:request redirectResponse:response fromDataSource:source]; + return request; +} + +- (NSURLRequest *) webView:(WebView *)view resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source { + id delegate([self delegate]); + if ([UIWebView instancesRespondToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) + request = [super webView:view resource:identifier willSendRequest:request redirectResponse:response fromDataSource:source]; + if ([delegate respondsToSelector:@selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:)]) + request = [delegate webView:view resource:identifier willSendRequest:request redirectResponse:response fromDataSource:source]; + return request; +} +// }}} +// webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame: (2.1+) {{{ +- (void) webView:(WebView *)view runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([UIWebView instancesRespondToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:)]) + if ( + ![delegate respondsToSelector:@selector(webView:shouldRunJavaScriptAlertPanelWithMessage:initiatedByFrame:)] || + [delegate webView:view shouldRunJavaScriptAlertPanelWithMessage:message initiatedByFrame:frame] + ) + [super webView:view runJavaScriptAlertPanelWithMessage:message initiatedByFrame:frame]; +} +// }}} +// webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame: (2.1+) {{{ +- (BOOL) webView:(WebView *)view runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([UIWebView instancesRespondToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:)]) + if ( + ![delegate respondsToSelector:@selector(webView:shouldRunJavaScriptConfirmPanelWithMessage:initiatedByFrame:)] || + [delegate webView:view shouldRunJavaScriptConfirmPanelWithMessage:message initiatedByFrame:frame] + ) + return [super webView:view runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:frame]; + return NO; +} +// }}} +// webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame: (2.1+) {{{ +- (NSString *) webView:(WebView *)view runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(WebFrame *)frame { + id delegate([self delegate]); + if ([UIWebView instancesRespondToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)]) + if ( + ![delegate respondsToSelector:@selector(webView:shouldRunJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:)] || + [delegate webView:view shouldRunJavaScriptTextInputPanelWithPrompt:prompt defaultText:text initiatedByFrame:frame] + ) + return [super webView:view runJavaScriptTextInputPanelWithPrompt:prompt defaultText:text initiatedByFrame:frame]; + return nil; +} +// }}} +// webViewClose: (3.2+) {{{ +static void $UIWebViewWebViewDelegate$webViewClose$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view) { + UIWebView *uiWebView(MSHookIvar(self, "uiWebView")); + if ([uiWebView respondsToSelector:@selector(webViewClose:)]) + [uiWebView webViewClose:view]; +} + +- (void) webViewClose:(WebView *)view { + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webViewClose:)]) + [delegate webViewClose:view]; + if ([UIWebView instancesRespondToSelector:@selector(webViewClose:)]) + [super webViewClose:view]; +} +// }}} + +- (void) _updateViewSettings { + [super _updateViewSettings]; + + id delegate([self delegate]); + if ([delegate respondsToSelector:@selector(webViewUpdateViewSettings:)]) + [delegate webViewUpdateViewSettings:self]; +} + +- (void) dispatchEvent:(NSString *)event { + WebThreadLocked lock; + + NSString *script([NSString stringWithFormat:@ + "(function() {" + "var event = this.document.createEvent('Events');" + "event.initEvent('%@', false, false);" + "this.document.dispatchEvent(event);" + "})();" + , event]); + + NSMutableArray *frames([NSMutableArray arrayWithObjects: + [[[self _documentView] webView] mainFrame] + , nil]); + + while (WebFrame *frame = [frames lastObject]) { + WebScriptObject *object([frame windowObject]); + [object evaluateWebScript:script]; + [frames removeLastObject]; + [frames addObjectsFromArray:[frame childFrames]]; + } +} + +- (void) reloadFromOrigin { + [[[self _documentView] webView] reloadFromOrigin:nil]; +} + ++ (void) initialize { + if (Class $UIWebViewWebViewDelegate = objc_getClass("UIWebViewWebViewDelegate")) { + class_addMethod($UIWebViewWebViewDelegate, @selector(webView:addMessageToConsole:), (IMP) &$UIWebViewWebViewDelegate$webView$addMessageToConsole$, "v16@0:4@8@12"); + class_addMethod($UIWebViewWebViewDelegate, @selector(webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:), (IMP) &$UIWebViewWebViewDelegate$webView$decidePolicyForNewWindowAction$request$newFrameName$decisionListener$, "v28@0:4@8@12@16@20@24"); + class_addMethod($UIWebViewWebViewDelegate, @selector(webView:didClearWindowObject:forFrame:), (IMP) &$UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$, "v20@0:4@8@12@16"); + class_addMethod($UIWebViewWebViewDelegate, @selector(webView:didReceiveTitle:forFrame:), (IMP) &$UIWebViewWebViewDelegate$webView$didReceiveTitle$forFrame$, "v20@0:4@8@12@16"); + class_addMethod($UIWebViewWebViewDelegate, @selector(webView:resource:willSendRequest:redirectResponse:fromDataSource:), (IMP) &$UIWebViewWebViewDelegate$webView$resource$willSendRequest$redirectResponse$fromDataSource$, "@28@0:4@8@12@16@20@24"); + class_addMethod($UIWebViewWebViewDelegate, @selector(webViewClose:), (IMP) &$UIWebViewWebViewDelegate$webViewClose$, "v12@0:4@8"); + } +} + +@end diff --git a/CyteKit/WebViewController.h b/CyteKit/WebViewController.h new file mode 100644 index 00000000..4c144196 --- /dev/null +++ b/CyteKit/WebViewController.h @@ -0,0 +1,139 @@ +/* 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_WebViewController_H +#define CyteKit_WebViewController_H + +#include "CyteKit/ViewController.h" +#include "CyteKit/WebView.h" + +#include + +#include + +@class IndirectDelegate; + +@protocol CyteWebViewControllerDelegate +- (void) retainNetworkActivityIndicator; +- (void) releaseNetworkActivityIndicator; +- (CYViewController *) pageForURL:(NSURL *)url forExternal:(BOOL)external; +- (void) unloadData; +@end + +@interface CyteWebViewController : CYViewController < + CyteWebViewDelegate, + UIWebViewDelegate +> { + _transient CyteWebView *webview_; + _transient UIScrollView *scroller_; + + UIActivityIndicatorView *indicator_; + IndirectDelegate *indirect_; + NSURLAuthenticationChallenge *challenge_; + + bool error_; + _H request_; + + _transient NSNumber *sensitive_; + + NSString *title_; + NSMutableSet *loading_; + + // XXX: NSString * or UIImage * + _H custom_; + _H style_; + + _H function_; + + float width_; + Class class_; + + UIBarButtonItem *reloaditem_; + UIBarButtonItem *loadingitem_; + + bool visible_; + bool hidesNavigationBar_; + bool allowsNavigationAction_; +} + ++ (void) _initialize; + +- (void) setURL:(NSURL *)url; + +- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy; +- (void) loadURL:(NSURL *)url; + +- (void) loadRequest:(NSURLRequest *)request; +- (bool) isLoading; + +- (void) reloadURLWithCache:(BOOL)cache; +- (void) reloadURL; + +- (id) init; +- (id) initWithURL:(NSURL *)url; +- (id) initWithWidth:(float)width; +- (id) initWithWidth:(float)width ofClass:(Class)_class; + +- (void) callFunction:(WebScriptObject *)function; + +- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; +- (NSURLRequest *) webView:(WebView *)view resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source; + ++ (float) defaultWidth; + +- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function; +- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function; +- (void) setHidesNavigationBar:(bool)value; + +- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button; +- (void) customButtonClicked; +- (void) applyRightButton; + +- (void) _didStartLoading; +- (void) _didFinishLoading; + +- (void) close; + +- (void) dispatchEvent:(NSString *)event; + +- (void) setViewportWidthOnMainThread:(float)value; + +@end + +#endif//CyteKit_WebViewController_H diff --git a/CyteKit/WebViewController.mm b/CyteKit/WebViewController.mm new file mode 100644 index 00000000..860955e1 --- /dev/null +++ b/CyteKit/WebViewController.mm @@ -0,0 +1,935 @@ +#include "CyteKit/UCPlatform.h" + +#include +#include "iPhonePrivate.h" + +#include "CyteKit/Localize.h" +#include "CyteKit/WebViewController.h" +#include "CyteKit/PerlCompatibleRegEx.hpp" +#include "CyteKit/WebThreadLocked.hpp" + +//#include +// XXX: fix the minimum requirement +extern NSString * const kCAFilterNearest; + +#include + +#include + +#include +#include +#include +#include +#include + +#define ForSaurik 0 +#define DefaultTimeout_ 120.0 + +#define ShowInternals 0 +#define LogBrowser 0 +#define LogMessages 0 + +#define lprintf(args...) fprintf(stderr, args) + +template +static inline void CYRelease(Type_ &value) { + if (value != nil) { + [value release]; + value = nil; + } +} + +float CYScrollViewDecelerationRateNormal; + +@interface WebView (Apple) +- (void) _setLayoutInterval:(float)interval; +- (void) _setAllowsMessaging:(BOOL)allows; +@end + +@interface WebPreferences (Apple) ++ (void) _setInitialDefaultTextEncodingToSystemEncoding; +- (void) _setLayoutInterval:(NSInteger)interval; +- (void) setOfflineWebApplicationCacheEnabled:(BOOL)enabled; +@end + +/* Indirect Delegate {{{ */ +@interface IndirectDelegate : NSObject { + _transient volatile id delegate_; +} + +- (void) setDelegate:(id)delegate; +- (id) initWithDelegate:(id)delegate; +@end + +@implementation IndirectDelegate + +- (void) setDelegate:(id)delegate { + delegate_ = delegate; +} + +- (id) initWithDelegate:(id)delegate { + delegate_ = delegate; + return self; +} + +- (IMP) methodForSelector:(SEL)sel { + if (IMP method = [super methodForSelector:sel]) + return method; + fprintf(stderr, "methodForSelector:[%s] == NULL\n", sel_getName(sel)); + return NULL; +} + +- (BOOL) respondsToSelector:(SEL)sel { + if ([super respondsToSelector:sel]) + return YES; + + // XXX: WebThreadCreateNSInvocation returns nil + +#if ShowInternals + fprintf(stderr, "[%s]R?%s\n", class_getName(self->isa), sel_getName(sel)); +#endif + + return delegate_ == nil ? NO : [delegate_ respondsToSelector:sel]; +} + +- (NSMethodSignature *) methodSignatureForSelector:(SEL)sel { + if (NSMethodSignature *method = [super methodSignatureForSelector:sel]) + return method; + +#if ShowInternals + fprintf(stderr, "[%s]S?%s\n", class_getName(self->isa), sel_getName(sel)); +#endif + + if (delegate_ != nil) + if (NSMethodSignature *sig = [delegate_ methodSignatureForSelector:sel]) + return sig; + + // XXX: I fucking hate Apple so very very bad + return [NSMethodSignature signatureWithObjCTypes:"v@:"]; +} + +- (void) forwardInvocation:(NSInvocation *)inv { + SEL sel = [inv selector]; + if (delegate_ != nil && [delegate_ respondsToSelector:sel]) + [inv invokeWithTarget:delegate_]; +} + +@end +/* }}} */ + +@implementation CyteWebViewController + +#if ShowInternals +#include "CyteKit/UCInternal.h" +#endif + ++ (void) _initialize { + [WebPreferences _setInitialDefaultTextEncodingToSystemEncoding]; + + 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 + CYScrollViewDecelerationRateNormal = 0.998; +} + +- (void) dealloc { +#if LogBrowser + NSLog(@"[CyteWebViewController dealloc]"); +#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]; +} + +- (NSURL *) URLWithURL:(NSURL *)url { + return url; +} + +- (NSURLRequest *) requestWithURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { + return [NSURLRequest + requestWithURL:[self URLWithURL:url] + cachePolicy:policy + timeoutInterval:DefaultTimeout_ + ]; +} + +- (void) setURL:(NSURL *)url { + _assert(request_ == nil); + request_ = [self requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; +} + +- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { + [self loadRequest:[self requestWithURL:url cachePolicy:policy]]; +} + +- (void) loadURL:(NSURL *)url { + [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; +} + +- (void) loadRequest:(NSURLRequest *)request { +#if LogBrowser + NSLog(@"loadRequest:%@", request); +#endif + + error_ = false; + + WebThreadLocked lock; + [webview_ loadRequest:request]; +} + +- (void) reloadURLWithCache:(BOOL)cache { + if (request_ == nil) + return; + + NSMutableURLRequest *request([request_ mutableCopy]); + [request setCachePolicy:(cache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData)]; + + request_ = request; + + if ([request_ HTTPBody] == nil && [request_ HTTPBodyStream] == nil) + [self loadRequest:request_]; + else { + UIAlertView *alert = [[[UIAlertView alloc] + initWithTitle:UCLocalize("RESUBMIT_FORM") + message:nil + delegate:self + cancelButtonTitle:UCLocalize("CANCEL") + otherButtonTitles: + UCLocalize("SUBMIT"), + nil + ] autorelease]; + + [alert setContext:@"submit"]; + [alert show]; + } +} + +- (void) reloadURL { + [self reloadURLWithCache:YES]; +} + +- (void) reloadData { + [super reloadData]; + [self reloadURLWithCache:YES]; +} + +- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { + custom_ = button; + style_ = style; + function_ = function; + + [self performSelectorOnMainThread:@selector(applyRightButton) withObject:nil waitUntilDone:NO]; +} + +- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { + custom_ = button; + style_ = style; + function_ = function; + + [self performSelectorOnMainThread:@selector(applyRightButton) withObject:nil waitUntilDone:NO]; +} + +- (void) removeButton { + custom_ = [NSNull null]; + [self performSelectorOnMainThread:@selector(applyRightButton) withObject:nil waitUntilDone:NO]; +} + +- (void) scrollToBottomAnimated:(NSNumber *)animated { + CGSize size([scroller_ contentSize]); + CGPoint offset([scroller_ contentOffset]); + CGRect frame([scroller_ frame]); + + if (size.height - offset.y < frame.size.height + 20.f) { + CGRect rect = {{0, size.height-1}, {size.width, 1}}; + [scroller_ scrollRectToVisible:rect animated:[animated boolValue]]; + } +} + +- (void) _setViewportWidth { + [[webview_ _documentView] setViewportSize:CGSizeMake(width_, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; +} + +- (void) setViewportWidth:(float)width { + width_ = width != 0 ? width : [[self class] defaultWidth]; + [self _setViewportWidth]; +} + +- (void) _setViewportWidthOnMainThread:(NSNumber *)width { + [self setViewportWidth:[width floatValue]]; +} + +- (void) setViewportWidthOnMainThread:(float)width { + [self performSelectorOnMainThread:@selector(_setViewportWidthOnMainThread:) withObject:[NSNumber numberWithFloat:width] waitUntilDone:NO]; +} + +- (void) webViewUpdateViewSettings:(UIWebView *)view { + [self _setViewportWidth]; +} + +- (void) _openMailToURL:(NSURL *)url { + [[UIApplication sharedApplication] openURL:url];// asPanel:YES]; +} + +- (bool) _allowJavaScriptPanel { + return true; +} + +- (bool) allowsNavigationAction { + return allowsNavigationAction_; +} + +- (void) setAllowsNavigationAction:(bool)value { + allowsNavigationAction_ = value; +} + +- (void) setAllowsNavigationActionByNumber:(NSNumber *)value { + [self setAllowsNavigationAction:[value boolValue]]; +} + +- (void) popViewControllerWithNumber:(NSNumber *)value { + UINavigationController *navigation([self navigationController]); + if ([navigation topViewController] == self) + [navigation popViewControllerAnimated:[value boolValue]]; +} + +- (void) _didFailWithError:(NSError *)error forFrame:(WebFrame *)frame { + [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]]; + [self _didFinishLoading]; + + if ([error code] == NSURLErrorCancelled) + return; + + if ([frame parentFrame] == nil) { + [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", + [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString], + [[error localizedDescription] stringByAddingPercentEscapes] + ]]]; + + error_ = true; + } +} + +- (void) pushRequest:(NSURLRequest *)request asPop:(bool)pop { + NSURL *url([request URL]); + + // XXX: filter to internal usage? + CYViewController *page([delegate_ pageForURL:url forExternal:NO]); + + if (page == nil) { + CyteWebViewController *browser([[[class_ alloc] init] autorelease]); + [browser loadRequest:request]; + page = browser; + } + + [page setDelegate:delegate_]; + + if (!pop) { + [[self navigationItem] setTitle:title_]; + + [[self navigationController] pushViewController:page animated:YES]; + } else { + UINavigationController *navigation([[[UINavigationController alloc] initWithRootViewController:page] autorelease]); + + [navigation setDelegate:delegate_]; + + [[page navigationItem] setLeftBarButtonItem:[[[UIBarButtonItem alloc] + initWithTitle:UCLocalize("CLOSE") + style:UIBarButtonItemStylePlain + target:page + action:@selector(close) + ] autorelease]]; + + [[self navigationController] presentModalViewController:navigation animated:YES]; + + [delegate_ unloadData]; + } +} + +// 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$"); + if (NSString *data = [message objectForKey:@"message"]) + if (irritating(data)) + return; + + NSLog(@"addMessageToConsole:%@", message); +#endif +} + +- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { +#if LogBrowser + NSLog(@"decidePolicyForNavigationAction:%@ request:%@ frame:%@", action, request, frame); +#endif + + if ([frame parentFrame] == nil) { + if (!error_) { + NSURL *url(request == nil ? nil : [request URL]); + + if (request_ == nil || [self allowsNavigationAction] || [[request_ URL] isEqual:url]) + request_ = request; + else { + if (url != nil) + [self pushRequest:request asPop:NO]; + [listener ignore]; + } + } + } +} + +- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id)listener { +#if LogBrowser + NSLog(@"decidePolicyForNewWindowAction:%@ request:%@ newFrameName:%@", action, request, frame); +#endif + + NSURL *url([request URL]); + if (url == nil) + return; + + if ([frame isEqualToString:@"_open"]) + [delegate_ openURL:url]; + else { + NSString *scheme([[url scheme] lowercaseString]); + if ([scheme isEqualToString:@"mailto"]) + [self _openMailToURL:url]; + else + [self pushRequest:request asPop:[frame isEqualToString:@"_popup"]]; + } + + [listener ignore]; +} + +- (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { +} + +- (void) webView:(WebView *)view didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { +#if LogBrowser + NSLog(@"didFailLoadWithError:%@ forFrame:%@", error, frame); +#endif + + [self _didFailWithError:error forFrame:frame]; +} + +- (void) webView:(WebView *)view didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { +#if LogBrowser + NSLog(@"didFailProvisionalLoadWithError:%@ forFrame:%@", error, frame); +#endif + + [self _didFailWithError:error forFrame:frame]; +} + +- (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame { + [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]]; + + if ([frame parentFrame] == nil) { + if (DOMDocument *document = [frame DOMDocument]) + if (DOMNodeList *bodies = [document getElementsByTagName:@"body"]) + for (DOMHTMLBodyElement *body in (id) bodies) { + DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]); + + UIColor *uic(nil); + + if (DOMCSSPrimitiveValue *color = static_cast([style getPropertyCSSValue:@"background-color"])) { + if ([color primitiveType] == DOM_CSS_RGBCOLOR) { + DOMRGBColor *rgb([color getRGBColorValue]); + + float red([[rgb red] getFloatValue:DOM_CSS_NUMBER]); + float green([[rgb green] getFloatValue:DOM_CSS_NUMBER]); + float blue([[rgb blue] getFloatValue:DOM_CSS_NUMBER]); + float alpha([[rgb alpha] getFloatValue:DOM_CSS_NUMBER]); + + if (red == 0xc7 && green == 0xce && blue == 0xd5) + uic = [UIColor pinStripeColor]; + else if (alpha != 0) + uic = [UIColor + colorWithRed:(red / 255) + green:(green / 255) + blue:(blue / 255) + alpha:alpha + ]; + } + } + + [scroller_ setBackgroundColor:(uic ?: [UIColor clearColor])]; + break; + } + } + + [self _didFinishLoading]; +} + +- (void) webView:(WebView *)view didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { + if ([frame parentFrame] != nil) + return; + + if (title_ != nil) + [title_ autorelease]; + title_ = [title retain]; + + [[self navigationItem] setTitle:title_]; +} + +- (void) webView:(WebView *)view didStartProvisionalLoadForFrame:(WebFrame *)frame { + [loading_ addObject:[NSValue valueWithNonretainedObject:frame]]; + + if ([frame parentFrame] == nil) { + CYRelease(title_); + custom_ = nil; + style_ = nil; + function_ = nil; + + [self setHidesNavigationBar:NO]; + + // XXX: do we still need to do this? + [[self navigationItem] setTitle:nil]; + } + + [self _didStartLoading]; +} + +- (NSURLRequest *) webView:(WebView *)view resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)source { +#if LogBrowser + NSLog(@"resource:%@ willSendRequest:%@ redirectResponse:%@ fromDataSource:%@", identifier, request, response, source); +#endif + + return request; +} + +- (bool) webView:(WebView *)view shouldRunJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + return [self _allowJavaScriptPanel]; +} + +- (bool) webView:(WebView *)view shouldRunJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + return [self _allowJavaScriptPanel]; +} + +- (bool) webView:(WebView *)view shouldRunJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(WebFrame *)frame { + return [self _allowJavaScriptPanel]; +} + +- (void) webViewClose:(WebView *)view { + [self close]; +} +// }}} + +- (void) close { + [[self navigationController] dismissModalViewControllerAnimated:YES]; +} + +- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button { + NSString *context([alert context]); + + if ([context isEqualToString:@"sensitive"]) { + switch (button) { + case 1: + sensitive_ = [NSNumber numberWithBool:YES]; + break; + + case 2: + sensitive_ = [NSNumber numberWithBool:NO]; + break; + } + + [alert dismissWithClickedButtonIndex:-1 animated:YES]; + } else if ([context isEqualToString:@"challenge"]) { + id sender([challenge_ sender]); + + switch (button) { + case 1: { + NSString *username([[alert textFieldAtIndex:0] text]); + NSString *password([[alert textFieldAtIndex:1] text]); + + NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]); + + [sender useCredential:credential forAuthenticationChallenge:challenge_]; + } break; + + case 2: + [sender cancelAuthenticationChallenge:challenge_]; + break; + + _nodefault + } + + [challenge_ release]; + challenge_ = nil; + + [alert dismissWithClickedButtonIndex:-1 animated:YES]; + } else if ([context isEqualToString:@"submit"]) { + if (button == [alert cancelButtonIndex]) { + } else if (button == [alert firstOtherButtonIndex]) { + if (request_ != nil) { + WebThreadLocked lock; + [webview_ loadRequest:request_]; + } + } + + [alert dismissWithClickedButtonIndex:-1 animated:YES]; + } +} + +- (UIBarButtonItemStyle) rightButtonStyle { + if (style_ == nil) normal: + return UIBarButtonItemStylePlain; + else if ([style_ isEqualToString:@"Normal"]) + return UIBarButtonItemStylePlain; + else if ([style_ isEqualToString:@"Highlighted"]) + return UIBarButtonItemStyleDone; + else goto normal; +} + +- (UIBarButtonItem *) customButton { + return custom_ == [NSNull null] ? nil : [[[UIBarButtonItem alloc] + initWithTitle:static_cast(custom_.operator NSObject *()) + style:[self rightButtonStyle] + target:self + action:@selector(customButtonClicked) + ] autorelease]; +} + +- (UIBarButtonItem *) rightButton { + return reloaditem_; +} + +- (void) applyLoadingTitle { + [[self navigationItem] setTitle:UCLocalize("LOADING")]; +} + +- (void) layoutRightButton { + [[loadingitem_ view] addSubview:indicator_]; + [[loadingitem_ view] bringSubviewToFront:indicator_]; +} + +- (void) applyRightButton { + if ([self isLoading]) { + [[self navigationItem] setRightBarButtonItem:loadingitem_ animated:YES]; + [self performSelector:@selector(layoutRightButton) withObject:nil afterDelay:0]; + + [indicator_ startAnimating]; + [self applyLoadingTitle]; + } else { + [indicator_ stopAnimating]; + + [[self navigationItem] setRightBarButtonItem:( + custom_ != nil ? [self customButton] : [self rightButton] + ) animated:YES]; + } +} + +- (void) didStartLoading { + // Overridden in subclasses. +} + +- (void) _didStartLoading { + [self applyRightButton]; + + if ([loading_ count] != 1) + return; + + [delegate_ retainNetworkActivityIndicator]; + [self didStartLoading]; +} + +- (void) didFinishLoading { + // Overridden in subclasses. +} + +- (void) _didFinishLoading { + if ([loading_ count] != 0) + return; + + [self applyRightButton]; + [[self navigationItem] setTitle:title_]; + + [delegate_ releaseNetworkActivityIndicator]; + [self didFinishLoading]; +} + +- (bool) isLoading { + return [loading_ count] != 0; +} + +- (id) initWithWidth:(float)width ofClass:(Class)_class { + if ((self = [super init]) != nil) { + allowsNavigationAction_ = true; + + class_ = _class; + loading_ = [[NSMutableSet alloc] initWithCapacity:5]; + + indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; + + CGRect bounds([[self view] bounds]); + + webview_ = [[[CyteWebView alloc] initWithFrame:bounds] autorelease]; + [webview_ setDelegate:self]; + [self setView:webview_]; + + if ([webview_ respondsToSelector:@selector(setDataDetectorTypes:)]) + [webview_ setDataDetectorTypes:UIDataDetectorTypeAutomatic]; + else + [webview_ setDetectsPhoneNumbers:NO]; + + [webview_ setScalesPageToFit:YES]; + + UIWebDocumentView *document([webview_ _documentView]); + + // XXX: I think this improves scrolling; the hardcoded-ness sucks + [document setTileSize:CGSizeMake(320, 500)]; + + [document setBackgroundColor:[UIColor clearColor]]; + + // XXX: this is terribly (too?) expensive + [document setDrawsBackground:NO]; + + WebView *webview([document webView]); + WebPreferences *preferences([webview preferences]); + + // XXX: I have no clue if I actually /want/ this modification + if ([webview respondsToSelector:@selector(_setLayoutInterval:)]) + [webview _setLayoutInterval:0]; + else if ([preferences respondsToSelector:@selector(_setLayoutInterval:)]) + [preferences _setLayoutInterval:0]; + + [preferences setCacheModel:WebCacheModelDocumentBrowser]; + [preferences setOfflineWebApplicationCacheEnabled:YES]; + +#if LogMessages + if ([document respondsToSelector:@selector(setAllowsMessaging:)]) + [document setAllowsMessaging:YES]; + if ([webview respondsToSelector:@selector(_setAllowsMessaging:)]) + [webview _setAllowsMessaging:YES]; +#endif + + if ([webview_ respondsToSelector:@selector(_scrollView)]) { + scroller_ = [webview_ _scrollView]; + + [scroller_ setDirectionalLockEnabled:YES]; + [scroller_ setDecelerationRate:CYScrollViewDecelerationRateNormal]; + [scroller_ setDelaysContentTouches:NO]; + + [scroller_ setCanCancelContentTouches:YES]; + } else if ([webview_ respondsToSelector:@selector(_scroller)]) { + UIScroller *scroller([webview_ _scroller]); + scroller_ = (UIScrollView *) scroller; + + [scroller setDirectionalScrolling:YES]; + // XXX: we might be better off /not/ setting this on older systems + [scroller setScrollDecelerationFactor:CYScrollViewDecelerationRateNormal]; /* 0.989324 */ + [scroller setScrollHysteresis:0]; /* 8 */ + + [scroller setThumbDetectionEnabled:NO]; + + // use NO with UIApplicationUseLegacyEvents(YES) + [scroller setEventMode:YES]; + + // XXX: this is handled by setBounces, right? + //[scroller setAllowsRubberBanding:YES]; + } + + [scroller_ setFixedBackgroundPattern:YES]; + [scroller_ setBackgroundColor:[UIColor clearColor]]; + [scroller_ setClipsSubviews:YES]; + + [scroller_ setBounces:YES]; + [scroller_ setScrollingEnabled:YES]; + [scroller_ setShowBackgroundShadow:NO]; + + [self setViewportWidth:width]; + + reloaditem_ = [[UIBarButtonItem alloc] + initWithTitle:UCLocalize("RELOAD") + style:[self rightButtonStyle] + target:self + action:@selector(reloadButtonClicked) + ]; + + loadingitem_ = [[UIBarButtonItem alloc] + initWithTitle:@" " + style:UIBarButtonItemStylePlain + target:self + action:@selector(reloadButtonClicked) + ]; + + indicator_ = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + [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]; + + [table setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; + [webview_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; + [indicator_ setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin]; + } return self; +} + +- (id) initWithWidth:(float)width { + return [self initWithWidth:width ofClass:[self class]]; +} + +- (id) init { + return [self initWithWidth:0]; +} + +- (id) initWithURL:(NSURL *)url { + if ((self = [self init]) != nil) { + [self setURL:url]; + } return self; +} + +- (void) callFunction:(WebScriptObject *)function { + WebThreadLocked lock; + + WebView *webview([[webview_ _documentView] webView]); + WebFrame *frame([webview mainFrame]); + WebPreferences *preferences([webview preferences]); + + bool maybe([preferences javaScriptCanOpenWindowsAutomatically]); + [preferences setJavaScriptCanOpenWindowsAutomatically:NO]; + + /*id _private(MSHookIvar(webview, "_private")); + WebCore::Page *page(_private == nil ? NULL : MSHookIvar(_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]); + JSObjectCallAsFunction(context, object, NULL, 0, NULL, NULL); + + /*if (settings != NULL) + settings->setJavaScriptCanOpenWindowsAutomatically(no);*/ + + [preferences setJavaScriptCanOpenWindowsAutomatically:maybe]; +} + +- (void) reloadButtonClicked { + [self reloadURLWithCache:YES]; +} + +- (void) _customButtonClicked { + [self reloadButtonClicked]; +} + +- (void) customButtonClicked { +#if !AlwaysReload + if (function_ != nil) + [self callFunction:function_]; + else +#endif + [self _customButtonClicked]; +} + ++ (float) defaultWidth { + return 980; +} + +- (void) setNavigationBarStyle:(NSString *)name { + UIBarStyle style; + if ([name isEqualToString:@"Black"]) + style = UIBarStyleBlack; + else + style = UIBarStyleDefault; + + [[[self navigationController] navigationBar] setBarStyle:style]; +} + +- (void) setNavigationBarTintColor:(UIColor *)color { + [[[self navigationController] navigationBar] setTintColor:color]; +} + +- (void) setBadgeValue:(id)value { + [[[self navigationController] tabBarItem] setBadgeValue:value]; +} + +- (void) setHidesBackButton:(bool)value { + [[self navigationItem] setHidesBackButton:value]; +} + +- (void) setHidesBackButtonByNumber:(NSNumber *)value { + [self setHidesBackButton:[value boolValue]]; +} + +- (void) dispatchEvent:(NSString *)event { + [webview_ dispatchEvent:event]; +} + +- (bool) hidesNavigationBar { + return hidesNavigationBar_; +} + +- (void) _setHidesNavigationBar:(bool)value animated:(bool)animated { + if (visible_) + [[self navigationController] setNavigationBarHidden:(value && [self hidesNavigationBar]) animated:animated]; +} + +- (void) setHidesNavigationBar:(bool)value { + if (hidesNavigationBar_ != value) { + hidesNavigationBar_ = value; + [self _setHidesNavigationBar:YES animated:YES]; + } +} + +- (void) setHidesNavigationBarByNumber:(NSNumber *)value { + [self setHidesNavigationBar:[value boolValue]]; +} + +- (void) viewWillAppear:(BOOL)animated { + visible_ = true; + + if ([self hidesNavigationBar]) + [self _setHidesNavigationBar:YES animated:animated]; + + [self dispatchEvent:@"CydiaViewWillAppear"]; + [super viewWillAppear:animated]; +} + +- (void) viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self dispatchEvent:@"CydiaViewDidAppear"]; +} + +- (void) viewWillDisappear:(BOOL)animated { + [self dispatchEvent:@"CydiaViewWillDisappear"]; + [super viewWillDisappear:animated]; + + if ([self hidesNavigationBar]) + [self _setHidesNavigationBar:NO animated:animated]; + + visible_ = false; +} + +- (void) viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + [self dispatchEvent:@"CydiaViewDidDisappear"]; +} + +@end diff --git a/CyteKit/stringWithUTF8Bytes.h b/CyteKit/stringWithUTF8Bytes.h new file mode 100644 index 00000000..94f472d4 --- /dev/null +++ b/CyteKit/stringWithUTF8Bytes.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_stringWithUTF8Bytes_H +#define CyteKit_stringWithUTF8Bytes_H + +#include + +@interface NSString (Cyte) ++ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length; ++ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length; +@end + +#endif//CyteKit_stringWithUTF8Bytes_H diff --git a/CyteKit/stringWithUTF8Bytes.mm b/CyteKit/stringWithUTF8Bytes.mm new file mode 100644 index 00000000..4e51902a --- /dev/null +++ b/CyteKit/stringWithUTF8Bytes.mm @@ -0,0 +1,52 @@ +/* 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/stringWithUTF8Bytes.h" + +@implementation NSString (Cyte) + ++ (NSString *) stringWithUTF8BytesNoCopy:(const char *)bytes length:(int)length { + return [[[NSString alloc] initWithBytesNoCopy:const_cast(bytes) length:length encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease]; +} + ++ (NSString *) stringWithUTF8Bytes:(const char *)bytes length:(int)length { + return [[[NSString alloc] initWithBytes:bytes length:length encoding:NSUTF8StringEncoding] autorelease]; +} + +@end diff --git a/Menes/Menes.h b/Menes/Menes.h index 8c0540ea..19b16b06 100644 --- a/Menes/Menes.h +++ b/Menes/Menes.h @@ -40,6 +40,6 @@ #ifndef Menes_Menes_H #define Menes_Menes_H -#include "Menes/NSObject-MenesYieldToSelector.h" +#include "Menes/yieldToSelector.h" #endif//Menes_Menes_H diff --git a/Menes/NSObject-MenesYieldToSelector.h b/Menes/NSObject-MenesYieldToSelector.h deleted file mode 100644 index e0ebd56a..00000000 --- a/Menes/NSObject-MenesYieldToSelector.h +++ /dev/null @@ -1,50 +0,0 @@ -/* 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 Menes_NSObject_MenesYieldToSelector_H -#define Menes_NSObject_MenesYieldToSelector_H - -#include - -@interface NSObject (MenesYieldToSelector) -- (id) yieldToSelector:(SEL)selector withObject:(id)object; -- (id) yieldToSelector:(SEL)selector; -@end - -#endif//Menes_NSObject_MenesYieldToSelector_H diff --git a/Menes/NSObject-MenesYieldToSelector.mm b/Menes/NSObject-MenesYieldToSelector.mm deleted file mode 100644 index 5967781e..00000000 --- a/Menes/NSObject-MenesYieldToSelector.mm +++ /dev/null @@ -1,103 +0,0 @@ -/* 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 "Menes/NSObject-MenesYieldToSelector.h" - -@implementation NSObject (MenesYieldToSelector) - -- (void) doNothing { -} - -- (void) _yieldToContext:(NSMutableArray *)context { - NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); - - SEL selector(reinterpret_cast([[context objectAtIndex:0] pointerValue])); - id object([[context objectAtIndex:1] nonretainedObjectValue]); - volatile bool &stopped(*reinterpret_cast([[context objectAtIndex:2] pointerValue])); - - /* XXX: deal with exceptions */ - id value([self performSelector:selector withObject:object]); - - NSMethodSignature *signature([self methodSignatureForSelector:selector]); - [context removeAllObjects]; - if ([signature methodReturnLength] != 0 && value != nil) - [context addObject:value]; - - stopped = true; - - [self - performSelectorOnMainThread:@selector(doNothing) - withObject:nil - waitUntilDone:NO - ]; - - [pool release]; -} - -- (id) yieldToSelector:(SEL)selector withObject:(id)object { - volatile bool stopped(false); - - NSMutableArray *context([NSMutableArray arrayWithObjects: - [NSValue valueWithPointer:selector], - [NSValue valueWithNonretainedObject:object], - [NSValue valueWithPointer:const_cast(&stopped)], - nil]); - - NSThread *thread([[[NSThread alloc] - initWithTarget:self - selector:@selector(_yieldToContext:) - object:context - ] autorelease]); - - [thread start]; - - NSRunLoop *loop([NSRunLoop currentRunLoop]); - NSDate *future([NSDate distantFuture]); - NSString *mode([loop currentMode] ?: NSDefaultRunLoopMode); - - while (!stopped && [loop runMode:mode beforeDate:future]); - - return [context count] == 0 ? nil : [context objectAtIndex:0]; -} - -- (id) yieldToSelector:(SEL)selector { - return [self yieldToSelector:selector withObject:nil]; -} - -@end diff --git a/Menes/yieldToSelector.h b/Menes/yieldToSelector.h new file mode 100644 index 00000000..0d07a066 --- /dev/null +++ b/Menes/yieldToSelector.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 Menes_yieldToSelector_H +#define Menes_yieldToSelector_H + +#include + +@interface NSObject (MenesYieldToSelector) +- (id) yieldToSelector:(SEL)selector withObject:(id)object; +- (id) yieldToSelector:(SEL)selector; +@end + +#endif//Menes_yieldToSelector_H diff --git a/Menes/yieldToSelector.mm b/Menes/yieldToSelector.mm new file mode 100644 index 00000000..e168313d --- /dev/null +++ b/Menes/yieldToSelector.mm @@ -0,0 +1,103 @@ +/* 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 "Menes/yieldToSelector.h" + +@implementation NSObject (MenesYieldToSelector) + +- (void) doNothing { +} + +- (void) _yieldToContext:(NSMutableArray *)context { + NSAutoreleasePool *pool([[NSAutoreleasePool alloc] init]); + + SEL selector(reinterpret_cast([[context objectAtIndex:0] pointerValue])); + id object([[context objectAtIndex:1] nonretainedObjectValue]); + volatile bool &stopped(*reinterpret_cast([[context objectAtIndex:2] pointerValue])); + + /* XXX: deal with exceptions */ + id value([self performSelector:selector withObject:object]); + + NSMethodSignature *signature([self methodSignatureForSelector:selector]); + [context removeAllObjects]; + if ([signature methodReturnLength] != 0 && value != nil) + [context addObject:value]; + + stopped = true; + + [self + performSelectorOnMainThread:@selector(doNothing) + withObject:nil + waitUntilDone:NO + ]; + + [pool release]; +} + +- (id) yieldToSelector:(SEL)selector withObject:(id)object { + volatile bool stopped(false); + + NSMutableArray *context([NSMutableArray arrayWithObjects: + [NSValue valueWithPointer:selector], + [NSValue valueWithNonretainedObject:object], + [NSValue valueWithPointer:const_cast(&stopped)], + nil]); + + NSThread *thread([[[NSThread alloc] + initWithTarget:self + selector:@selector(_yieldToContext:) + object:context + ] autorelease]); + + [thread start]; + + NSRunLoop *loop([NSRunLoop currentRunLoop]); + NSDate *future([NSDate distantFuture]); + NSString *mode([loop currentMode] ?: NSDefaultRunLoopMode); + + while (!stopped && [loop runMode:mode beforeDate:future]); + + return [context count] == 0 ? nil : [context objectAtIndex:0]; +} + +- (id) yieldToSelector:(SEL)selector { + return [self yieldToSelector:selector withObject:nil]; +} + +@end diff --git a/MobileCydia.mm b/MobileCydia.mm index cb646f98..5c657a86 100644 --- a/MobileCydia.mm +++ b/MobileCydia.mm @@ -42,7 +42,7 @@ /* #include Directives {{{ */ #include "CyteKit/UCPlatform.h" -#include "CyteKit/CyteLocalize.h" +#include "CyteKit/Localize.h" #include #include @@ -120,10 +120,10 @@ extern "C" { #include -#include "CyteKit/CyteWebViewController.h" -#include "CyteKit/NSString-Cyte.h" #include "CyteKit/PerlCompatibleRegEx.hpp" #include "CyteKit/WebScriptObject-Cyte.h" +#include "CyteKit/WebViewController.h" +#include "CyteKit/stringWithUTF8Bytes.h" #include "Menes/Menes.h"