From bde2d79b2e825b71ae4f171cd74ed1f2ad1aa504 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Thu, 4 Dec 2008 07:17:49 +0000 Subject: [PATCH] Reorganized code and mostly finished ratings indicator. --- Cydia.app/Sections/Widgets.png | Bin 0 -> 9943 bytes Cydia.app/loading.html | 15 + Cydia.app/menes/indicator-c7ced5-4d4d70.gif | Bin 0 -> 1849 bytes Cydia.app/menes/menes.js | 12 +- Cydia.app/package.html | 1 + Cydia.app/package.js | 9 +- Cydia.mm | 873 +------------------- UICaboodle/BrowserView.h | 21 + UICaboodle/BrowserView.m | 824 ++++++++++++++++++ UICaboodle/Internals.h | 5 +- UICaboodle/RVBook.h | 7 +- UICaboodle/RVBook.mm | 43 +- UICaboodle/RVPage.h | 4 +- UICaboodle/RVPage.mm | 6 +- internals.h | 10 - makefile | 2 +- 16 files changed, 964 insertions(+), 868 deletions(-) create mode 100644 Cydia.app/Sections/Widgets.png create mode 100644 Cydia.app/loading.html create mode 100644 Cydia.app/menes/indicator-c7ced5-4d4d70.gif create mode 100644 UICaboodle/BrowserView.m delete mode 100644 internals.h diff --git a/Cydia.app/Sections/Widgets.png b/Cydia.app/Sections/Widgets.png new file mode 100644 index 0000000000000000000000000000000000000000..ca8c1efecc5a74254c4cf791a6409bb7a0c34a25 GIT binary patch literal 9943 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 V@zvTgYxMvC002ovPDHLkV1m=uEf)X) literal 0 HcmV?d00001 diff --git a/Cydia.app/loading.html b/Cydia.app/loading.html new file mode 100644 index 00000000..85cc4c5c --- /dev/null +++ b/Cydia.app/loading.html @@ -0,0 +1,15 @@ + + + Loading + + + + + +
+ +
+ Loading... +
+
+ diff --git a/Cydia.app/menes/indicator-c7ced5-4d4d70.gif b/Cydia.app/menes/indicator-c7ced5-4d4d70.gif new file mode 100644 index 0000000000000000000000000000000000000000..e41bb96b855f7851184452d9238e911553abef86 GIT binary patch literal 1849 zcmb8wdr(tX9tZI2z31lM+(&YVNJFGf2tkvOnD7cwta}qc5Re5b(DEpW7-}e#gvz5W zB6$hn4N_gK58SefA}t^~-L^!G%xbq|E3@wIbay+W9d<`sw+p-5S)J)V68_k~vVZLF z&ok%D`ONosesi+-?lJ7JKm;OxN08f}|9am(`{FOY7#z9qq5n=pV{cc_cyOiV&5>8C zJI=m0e{uTblG4_b?@kvKIBH+@b~wk7|EFUAO&4VCe=);Yn3c3$hiwR+js2G-qseMH zY&|G#wH-brwbWVK>KiQwx7%K?ZA4<90X`Mnr4HQ^LLzvpREnbf*gsC9nI`hKacC+h z#`oY(;EL$#P0I{+A=4Frf8wOCT#qz9e(C8@;RLt#p{&I1x>^*+|NNoJS($$BE`2NU zvWOAmjbH3cl1o}J4p8!Tbutjr6boF{aVW_{*n^-m74VWz%IG&zY1$ea&e9UH*f{Hs zflMR$sS);q(PsN0xwt>W63I)%`f^Qp?gDH zoEK*S2yDOcmFL*Yk+lO6ARn!kVK`-{l1=V1CxC$Nu4>Qcv6cFfx7*)3WjK>okrtNH z7NUH~1Sues%#x9Vb3GpSVp5ZO>bY@8;ZkH5+KEJp>*fRIRRiP^---epBn=0maztvW zYWZuOSaX40ZP-&L{%&Q*LVn>yR&oMLL4^x7$ygp;+y8dA%2ZaZ^&Lf7u3GMMb>uZU z(~M2wG3&W}nG(c!V#%B}*=H)z;AZ+>(V&)d&vt7BP~=SMgaE&F$qrKleZ>j?_(UTj z&ON$jpC<2IG%pt_PUuPZ!|^kc)e`LwQa(wm)WD+zm?A-2C9D6jS9?rld~NvX@g6#F zw6CYi*rC^t>%-I%ddu>aQ(zTgp7W@dN`HexB14ORb&KC;O&olRa8L{7! z_2eF0h>MdC+G&-5d;uygS8?dEa}Y+T7Ulgm~p^0(f% zJLf*R~{-k%;INyqois*O%a$AiE)r?30JrtPk|M234thrHUn$U-5$}wL+9A-Y_Tq zS^3$cv|F9x{M_L3Fb6V5%t7w-nu}d$i?hvdeNsrxEpT8oH*55iCD{eo;IM z25!0SIVq74FXh8{)`k(7P)OM;ie>G5v=1c(!*SFY$`|T!TX}0utLlIEXdw)YQ|Z6$y*IPrWrOp8Ipy)|6IlmOX4&`C8+=*M0-%4(59mKS{&aA#}eci))HRR9C|hD zn)-^%@`u!1E_7797jQ7iW9FiYr-Iat&Zj%01wHSqg1s-r>K2=fnFcYF(K0pkX(axK zoWfdLgnz|`6peyGx3Q43Z-yB>Ha-(!3waO-i&FFq9>lP=8XF49f;wF*>rsXussDCq zJLB+AQtE7!em@r?O^Od*^Qx)mrk*U;(}dj8uP+kiTj1Hiic7^sR6?$x3P}b diff --git a/Cydia.app/package.js b/Cydia.app/package.js index fc8e2181..bab0b2f9 100644 --- a/Cydia.app/package.js +++ b/Cydia.app/package.js @@ -49,8 +49,13 @@ $(function () { var rating = package.rating; if (rating == null) $(".rating").remove(); - else - $("#rating").src(rating); + else { + $.xhr(rating, 'GET', {}, null, { + success: function (value) { + document.getElementById("rating").contentWindow.document.write(value); + } + }); + } $("#settings").href("cydia://package-settings/" + idc); diff --git a/Cydia.mm b/Cydia.mm index 02311b1d..ac9df53a 100644 --- a/Cydia.mm +++ b/Cydia.mm @@ -52,26 +52,6 @@ // XXX: remove #import -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#import -#import - -#include -#include - -#import - #include #include @@ -277,7 +257,7 @@ extern NSString * const kCAFilterNearest; #define lprintf(args...) fprintf(stderr, args) -#define ForRelease 1 +#define ForRelease 0 #define ForSaurik (1 && !ForRelease) #define RecycleWebViews 0 #define AlwaysReload (1 && !ForRelease) @@ -617,6 +597,7 @@ static const float KeyboardTime_ = 0.3f; #define SpringBoard_ "/System/Library/LaunchDaemons/com.apple.SpringBoard.plist" #define SandboxTemplate_ "/usr/share/sandbox/SandboxTemplate.sb" +#define NotifyConfig_ "/etc/notify.conf" static CGColor Blue_; static CGColor Blueish_; @@ -2948,6 +2929,7 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { id delegate_; BOOL running_; SHA1SumValue springlist_; + SHA1SumValue notifyconf_; SHA1SumValue sandplate_; size_t received_; NSTimeInterval last_; @@ -3167,6 +3149,15 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { Finish_ = 4; } + if (Finish_ < 4) { + FileFd file(NotifyConfig_, FileFd::ReadOnly); + MMap mmap(file, MMap::ReadOnly); + SHA1Summation sha1; + sha1.Add(reinterpret_cast(mmap.Data()), mmap.Size()); + if (!(notifyconf_ == sha1.Result())) + Finish_ = 4; + } + if (Finish_ < 3) { FileFd file(SpringBoard_, FileFd::ReadOnly); MMap mmap(file, MMap::ReadOnly); @@ -3267,6 +3258,14 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { sandplate_ = sha1.Result(); } + { + FileFd file(NotifyConfig_, FileFd::ReadOnly); + MMap mmap(file, MMap::ReadOnly); + SHA1Summation sha1; + sha1.Add(reinterpret_cast(mmap.Data()), mmap.Size()); + notifyconf_ = sha1.Result(); + } + { FileFd file(SpringBoard_, FileFd::ReadOnly); MMap mmap(file, MMap::ReadOnly); @@ -4776,14 +4775,6 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -@interface WebView (Cydia) -- (void) setScriptDebugDelegate:(id)delegate; -- (void) _setFormDelegate:(id)delegate; -- (void) _setUIKitDelegate:(id)delegate; -- (void) setWebMailDelegate:(id)delegate; -- (void) _setLayoutInterval:(float)interval; -@end - /* Indirect Delegate {{{ */ @interface IndirectDelegate : NSProxy { _transient volatile id delegate_; @@ -4820,822 +4811,8 @@ bool DepSubstrate(const pkgCache::VerIterator &iterator) { @end /* }}} */ -/* Browser Implementation {{{ */ -@implementation BrowserView - -#if ForSaurik -#include "internals.h" -#endif - -- (void) dealloc { - if (challenge_ != nil) - [challenge_ release]; - - WebView *webview = [webview_ webView]; - [webview setFrameLoadDelegate:nil]; - [webview setResourceLoadDelegate:nil]; - [webview setUIDelegate:nil]; - [webview setScriptDebugDelegate:nil]; - [webview setPolicyDelegate:nil]; - - [webview setDownloadDelegate:nil]; - - [webview _setFormDelegate:nil]; - [webview _setUIKitDelegate:nil]; - [webview setWebMailDelegate:nil]; - [webview setEditingDelegate:nil]; - - [webview_ setDelegate:nil]; - [webview_ setGestureDelegate:nil]; - - //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - [webview close]; - -#if RecycleWebViews - [webview_ removeFromSuperview]; - [Documents_ addObject:[webview_ autorelease]]; -#else - [webview_ release]; -#endif - - [indirect_ setDelegate:nil]; - [indirect_ release]; - - [scroller_ setDelegate:nil]; - - if (button_ != nil) - [button_ release]; - if (style_ != nil) - [style_ release]; - if (function_ != nil) - [function_ release]; - - [scroller_ release]; - [indicator_ release]; - if (confirm_ != nil) - [confirm_ release]; - if (title_ != nil) - [title_ release]; - [super dealloc]; -} - -- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - [self loadRequest:[NSURLRequest - requestWithURL:url - cachePolicy:policy - timeoutInterval:30.0 - ]]; -} - -- (void) loadURL:(NSURL *)url { - [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; -} - -- (NSMutableURLRequest *) _addHeadersToRequest:(NSURLRequest *)request { - NSMutableURLRequest *copy = [request mutableCopy]; - - if (Machine_ != NULL) - [copy setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; - if (UniqueID_ != nil) - [copy setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; - - if (Role_ != nil) - [copy setValue:Role_ forHTTPHeaderField:@"X-Role"]; - - return copy; -} - -- (void) loadRequest:(NSURLRequest *)request { - pushed_ = true; - [webview_ loadRequest:request]; -} - -- (void) reloadURL { - NSLog(@"rlu:%@", request_); - if (request_ == nil) - return; - - if ([request_ HTTPBody] == nil && [request_ HTTPBodyStream] == nil) - [webview_ loadRequest:request_]; - else { - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:@"Are you sure you want to submit this form again?" - buttons:[NSArray arrayWithObjects:@"Cancel", @"Submit", nil] - defaultButtonIndex:0 - delegate:self - context:@"submit" - ] autorelease]; - - [sheet setNumberOfRows:1]; - [sheet popupAlertAnimated:YES]; - } -} - -- (WebView *) webView { - return [webview_ webView]; -} - -- (void) view:(UIView *)sender didSetFrame:(CGRect)frame { - [scroller_ setContentSize:frame.size]; -} - -- (void) view:(UIView *)sender didSetFrame:(CGRect)frame oldFrame:(CGRect)old { - [self view:sender didSetFrame:frame]; -} - -- (void) pushPage:(RVPage *)page { - [self setBackButtonTitle:title_]; - [page setDelegate:delegate_]; - [book_ pushPage:page]; -} - -- (BOOL) getSpecial:(NSURL *)url { - NSString *href([url absoluteString]); - NSString *scheme([[url scheme] lowercaseString]); - - RVPage *page = nil; - - if ([href hasPrefix:@"apptapp://package/"]) - page = [delegate_ pageForPackage:[href substringFromIndex:18]]; - else if ([scheme isEqualToString:@"cydia"]) { - page = [delegate_ pageForURL:url hasTag:NULL]; - if (page == nil) - return false; - } else if (![scheme isEqualToString:@"apptapp"]) - return false; - - if (page != nil) - [self pushPage:page]; - return true; -} - -- (void) webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:nil - buttons:[NSArray arrayWithObjects:@"OK", nil] - defaultButtonIndex:0 - delegate:self - context:@"alert" - ] autorelease]; - - [sheet setBodyText:message]; - [sheet popupAlertAnimated:YES]; -} - -- (BOOL) webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:nil - buttons:[NSArray arrayWithObjects:@"OK", @"Cancel", nil] - defaultButtonIndex:0 - delegate:self - context:@"confirm" - ] autorelease]; - - [sheet setNumberOfRows:1]; - [sheet setBodyText:message]; - [sheet popupAlertAnimated:YES]; - - NSRunLoop *loop([NSRunLoop currentRunLoop]); - NSDate *future([NSDate distantFuture]); - - while (confirm_ == nil && [loop runMode:NSDefaultRunLoopMode beforeDate:future]); - - NSNumber *confirm([confirm_ autorelease]); - confirm_ = nil; - return [confirm boolValue]; -} - -/* Web Scripting {{{ */ -+ (NSString *) webScriptNameForSelector:(SEL)selector { - if (selector == @selector(getPackageById:)) - return @"getPackageById"; - else if (selector == @selector(setButtonImage:withStyle:toFunction:)) - return @"setButtonImage"; - else if (selector == @selector(setButtonTitle:withStyle:toFunction:)) - return @"setButtonTitle"; - else if (selector == @selector(supports:)) - return @"supports"; - else - return nil; -} - -+ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { - return [self webScriptNameForSelector:selector] == nil; -} - -- (BOOL) supports:(NSString *)feature { - return [feature isEqualToString:@"window.open"]; -} - -- (Package *) getPackageById:(NSString *)id { - return [[Database sharedInstance] packageWithName:id]; -} - -- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { - if (button_ != nil) - [button_ autorelease]; - button_ = button == nil ? nil : [[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:button]]] retain]; - - if (style_ != nil) - [style_ autorelease]; - style_ = style == nil ? nil : [style retain]; - - if (function_ != nil) - [function_ autorelease]; - function_ = function == nil ? nil : [function retain]; -} - -- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { - if (button_ != nil) - [button_ autorelease]; - button_ = button == nil ? nil : [button retain]; - - if (style_ != nil) - [style_ autorelease]; - style_ = style == nil ? nil : [style retain]; - - if (function_ != nil) - [function_ autorelease]; - function_ = function == nil ? nil : [function retain]; -} -/* }}} */ - -- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { - [window setValue:self forKey:@"cydia"]; -} - -- (void) webView:(WebView *)sender unableToImplementPolicyWithError:(NSError *)error frame:(WebFrame *)frame { - NSLog(@"err:%@", error); -} - -- (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener { - if (NSURL *url = [request URL]) { - if (name != nil && [name isEqualToString:@"_open"]) - [delegate_ openURL:url]; - - NSLog(@"win:%@:%@", url, [action description]); - if (![self getSpecial:url]) { - NSString *scheme([[url scheme] lowercaseString]); - if ([scheme isEqualToString:@"mailto"]) - [delegate_ openMailToURL:url]; - else goto use; - } - - [listener ignore]; - } else use: - [listener use]; -} - -- (void) webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - if ([WebView canShowMIMEType:type]) - [listener use]; - else { - // XXX: handle more mime types! - [listener ignore]; - if (frame == [webView mainFrame]) - [UIApp openURL:[request URL]]; - } -} - -- (void) webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { - if (request == nil) ignore: { - [listener ignore]; - return; - } - - NSURL *url([request URL]); - - if (url == nil) use: { - if ([frame parentFrame] == nil) { - if (request_ != nil) - [request_ autorelease]; - request_ = [request retain]; - NSLog(@"dpn:%@", request_); - } - - [listener use]; - return; - } -#if ForSaurik - else NSLog(@"nav:%@:%@", url, [action description]); -#endif - - const NSArray *capability(reinterpret_cast(GSSystemGetCapability(kGSDisplayIdentifiersCapability))); - - if ( - [capability containsObject:@"com.apple.Maps"] && [url mapsURL] || - [capability containsObject:@"com.apple.youtube"] && [url youTubeURL] - ) { - open: - [UIApp openURL:url]; - goto ignore; - } - - int store(_not(int)); - if (NSURL *itms = [url itmsURL:&store]) { - NSLog(@"itms#%@#%u#%@", url, store, itms); - if ( - store == 1 && [capability containsObject:@"com.apple.MobileStore"] || - store == 2 && [capability containsObject:@"com.apple.AppStore"] - ) { - url = itms; - goto open; - } - } - - NSString *scheme([[url scheme] lowercaseString]); - - if ([scheme isEqualToString:@"tel"]) { - // XXX: intelligence - goto open; - } - - if ([scheme isEqualToString:@"mailto"]) { - [delegate_ openMailToURL:url]; - goto ignore; - } - - if ([self getSpecial:url]) - goto ignore; - else if ([WebView _canHandleRequest:request]) - goto use; - else if ([url isSpringboardHandledURL]) - goto open; - else - goto use; -} - -- (void) webView:(WebView *)sender setStatusText:(NSString *)text { - //lprintf("Status:%s\n", [text UTF8String]); -} - -- (void) _pushPage { - if (pushed_) - return; - pushed_ = true; - [book_ pushPage:self]; -} - -- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { - NSString *context([sheet context]); - - if ([context isEqualToString:@"alert"]) - [sheet dismiss]; - else if ([context isEqualToString:@"confirm"]) { - switch (button) { - case 1: - confirm_ = [NSNumber numberWithBool:YES]; - break; - - case 2: - confirm_ = [NSNumber numberWithBool:NO]; - break; - } - - [sheet dismiss]; - } else if ([context isEqualToString:@"challenge"]) { - id sender([challenge_ sender]); - - switch (button) { - case 1: { - NSString *username([[sheet textFieldAtIndex:0] text]); - NSString *password([[sheet textFieldAtIndex:1] text]); - - NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]); - - [sender useCredential:credential forAuthenticationChallenge:challenge_]; - } break; - - case 2: - [sender cancelAuthenticationChallenge:challenge_]; - break; - - default: - _assert(false); - } - - [challenge_ release]; - challenge_ = nil; - - [sheet dismiss]; - } else if ([context isEqualToString:@"submit"]) { - switch (button) { - case 1: - break; - - case 2: - if (request_ != nil) - [webview_ loadRequest:request_]; - break; - - default: - _assert(false); - } - - [sheet dismiss]; - } -} - -- (void) webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)source { - challenge_ = [challenge retain]; - - NSURLProtectionSpace *space([challenge protectionSpace]); - NSString *realm([space realm]); - if (realm == nil) - realm = @""; - - UIActionSheet *sheet = [[[UIActionSheet alloc] - initWithTitle:realm - buttons:[NSArray arrayWithObjects:@"Login", @"Cancel", nil] - defaultButtonIndex:0 - delegate:self - context:@"challenge" - ] autorelease]; - - [sheet setNumberOfRows:1]; - - [sheet addTextFieldWithValue:@"" label:@"username"]; - [sheet addTextFieldWithValue:@"" label:@"password"]; - - UITextField *username([sheet textFieldAtIndex:0]); { - UITextInputTraits *traits([username textInputTraits]); - [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; - [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; - [traits setKeyboardType:UIKeyboardTypeASCIICapable]; - [traits setReturnKeyType:UIReturnKeyNext]; - } - - UITextField *password([sheet textFieldAtIndex:1]); { - UITextInputTraits *traits([password textInputTraits]); - [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; - [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; - [traits setKeyboardType:UIKeyboardTypeASCIICapable]; - // XXX: UIReturnKeyDone - [traits setReturnKeyType:UIReturnKeyNext]; - [traits setSecureTextEntry:YES]; - } - - [sheet popupAlertAnimated:YES]; -} - -- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source { - NSURL *url = [request URL]; - if ([self getSpecial:url]) - return nil; - [self _pushPage]; - return [self _addHeadersToRequest:request]; -} - -- (WebView *) _createWebViewWithRequest:(NSURLRequest *)request pushed:(BOOL)pushed { - [self setBackButtonTitle:title_]; - - BrowserView *browser = [[[BrowserView alloc] initWithBook:book_] autorelease]; - [browser setDelegate:delegate_]; - - if (pushed) { - [browser loadRequest:request]; - [book_ pushPage:browser]; - } - - return [browser webView]; -} - -- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { - return [self _createWebViewWithRequest:request pushed:(request != nil)]; -} - -- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features { - return [self _createWebViewWithRequest:request pushed:YES]; -} - -- (void) webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - title_ = [title retain]; - [book_ reloadTitleForPage:self]; -} - -- (void) webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - - reloading_ = false; - loading_ = true; - [self reloadButtons]; - - if (title_ != nil) { - [title_ release]; - title_ = nil; - } - - if (button_ != nil) { - [button_ release]; - button_ = nil; - } - - if (style_ != nil) { - [style_ release]; - style_ = nil; - } - - if (function_ != nil) { - [function_ release]; - function_ = nil; - } - - [book_ reloadTitleForPage:self]; - - [scroller_ scrollPointVisibleAtTopLeft:CGPointZero]; - - CGRect webrect = [scroller_ bounds]; - webrect.size.height = 0; - [webview_ setFrame:webrect]; -} - -- (void) _finishLoading { - if (!reloading_) { - loading_ = false; - [self reloadButtons]; - } -} - -- (bool) _loading { - return loading_; -} - -- (void) reloadButtons { - if ([self _loading]) - [indicator_ startAnimation]; - else - [indicator_ stopAnimation]; - [super reloadButtons]; -} - -- (BOOL) webView:(WebView *)sender shouldScrollToPoint:(struct CGPoint)point forFrame:(WebFrame *)frame { - return [webview_ webView:sender shouldScrollToPoint:point forFrame:frame]; -} - -- (void) webView:(WebView *)sender didReceiveViewportArguments:(id)arguments forFrame:(WebFrame *)frame { - return [webview_ webView:sender didReceiveViewportArguments:arguments forFrame:frame]; -} - -- (void) webView:(WebView *)sender needsScrollNotifications:(id)notifications forFrame:(WebFrame *)frame { - return [webview_ webView:sender needsScrollNotifications:notifications forFrame:frame]; -} - -- (void) webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { - return [webview_ webView:sender didCommitLoadForFrame:frame]; -} - -- (void) webView:(WebView *)sender didReceiveDocTypeForFrame:(WebFrame *)frame { - return [webview_ webView:sender didReceiveDocTypeForFrame:frame]; -} - -- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { - if ([frame parentFrame] == nil) { - [self _finishLoading]; - if (DOMDocument *document = [frame DOMDocument]) - if (DOMNodeList *bodies = [document getElementsByTagName:@"body"]) - for (DOMHTMLBodyElement *body in bodies) { - DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]); - - bool colored(false); - - if (DOMCSSPrimitiveValue *color = static_cast([style getPropertyCSSValue:@"background-color"])) { - DOMRGBColor *rgb([color getRGBColorValue]); - - float alpha([[rgb alpha] getFloatValue:DOM_CSS_NUMBER]); - NSLog(@"alpha:%g", alpha); - - if (alpha != 0) { - colored = true; - - [scroller_ setBackgroundColor:[UIColor - colorWithRed:([[rgb red] getFloatValue:DOM_CSS_NUMBER] / 255) - green:([[rgb green] getFloatValue:DOM_CSS_NUMBER] / 255) - blue:([[rgb blue] getFloatValue:DOM_CSS_NUMBER] / 255) - alpha:alpha - ]]; - } - } - - if (!colored) - [scroller_ setBackgroundColor:[UIColor pinStripeColor]]; - break; - } - } - - return [webview_ webView:sender didFinishLoadForFrame:frame]; -} - -- (void) webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { - if ([frame parentFrame] != nil) - return; - [self _finishLoading]; - - [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", - [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString], - [[error localizedDescription] stringByAddingPercentEscapes] - ]]]; -} - -- (void) webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary { -#if ForSaurik - lprintf("Console:%s\n", [[dictionary description] UTF8String]); -#endif -} - -- (id) initWithBook:(RVBook *)book { - if ((self = [super initWithBook:book]) != nil) { - loading_ = false; - - struct CGRect bounds = [self bounds]; - - scroller_ = [[UIScroller alloc] initWithFrame:bounds]; - [self addSubview:scroller_]; - - [scroller_ setShowBackgroundShadow:NO]; - [scroller_ setFixedBackgroundPattern:YES]; - [scroller_ setBackgroundColor:[UIColor pinStripeColor]]; - - [scroller_ setScrollingEnabled:YES]; - [scroller_ setAdjustForContentSizeChange:YES]; - [scroller_ setClipsSubviews:YES]; - [scroller_ setAllowsRubberBanding:YES]; - [scroller_ setScrollDecelerationFactor:0.99]; - [scroller_ setDelegate:self]; - - CGRect webrect = [scroller_ bounds]; - webrect.size.height = 0; - - WebView *webview; - -#if RecycleWebViews - webview_ = [Documents_ lastObject]; - if (webview_ != nil) { - webview_ = [webview_ retain]; - webview = [webview_ webView]; - [Documents_ removeLastObject]; - [webview_ setFrame:webrect]; - } else { -#else - if (true) { -#endif - webview_ = [[UIWebDocumentView alloc] initWithFrame:webrect]; - webview = [webview_ webView]; - - // XXX: this is terribly (too?) expensive - //[webview_ setDrawsBackground:NO]; - [webview setPreferencesIdentifier:@"Cydia"]; - - [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)]; - - [webview_ setAllowsMessaging:YES]; - - [webview_ setTilingEnabled:YES]; - [webview_ setDrawsGrid:NO]; - [webview_ setLogsTilingChanges:NO]; - [webview_ setTileMinificationFilter:kCAFilterNearest]; - [webview_ setDetectsPhoneNumbers:NO]; - [webview_ setAutoresizes:YES]; - - [webview_ setMinimumScale:0.25f forDocumentTypes:0x10]; - [webview_ setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:0x10]; - [webview_ setViewportSize:CGSizeMake(980, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; - - [webview_ setViewportSize:CGSizeMake(320, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x2]; - - [webview_ setMinimumScale:1.0f forDocumentTypes:0x8]; - [webview_ setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:0x8]; - [webview_ setViewportSize:CGSizeMake(320, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x8]; - - [webview_ _setDocumentType:0x4]; - - [webview_ setZoomsFocusedFormControl:YES]; - [webview_ setContentsPosition:7]; - [webview_ setEnabledGestures:0xa]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeIsZoomRubberBandEnabled]; - [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeUpdatesScroller]; - - [webview_ setSmoothsFonts:YES]; - - [webview _setUsesLoaderCache:YES]; - [webview setGroupName:@"Cydia"]; - [webview _setLayoutInterval:0]; - } - - [webview_ setDelegate:self]; - [webview_ setGestureDelegate:self]; - [scroller_ addSubview:webview_]; - - //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - CGSize indsize = [UIProgressIndicator defaultSizeForStyle:UIProgressIndicatorStyleMediumWhite]; - indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectMake(281, 12, indsize.width, indsize.height)]; - [indicator_ setStyle:UIProgressIndicatorStyleMediumWhite]; - - Package *package([[Database sharedInstance] packageWithName:@"cydia"]); - NSString *application = package == nil ? @"Cydia" : [NSString - stringWithFormat:@"Cydia/%@", - [package installed] - ]; [webview setApplicationNameForUserAgent:application]; - - indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; - - [webview setFrameLoadDelegate:self]; - [webview setResourceLoadDelegate:indirect_]; - [webview setUIDelegate:self]; - [webview setScriptDebugDelegate:self]; - [webview setPolicyDelegate:self]; - - [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - [scroller_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; - } return self; -} - -- (void) didFinishGesturesInView:(UIView *)view forEvent:(id)event { - [webview_ redrawScaledDocument]; -} - -- (void) _rightButtonClicked { - if (function_ == nil) { - reloading_ = true; - [self reloadURL]; - } else { - WebView *webview([webview_ webView]); - WebFrame *frame([webview mainFrame]); - - 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); - } - - [delegate_ clearFirstResponder]; - JSObjectRef function([function_ JSObject]); - JSGlobalContextRef context([frame globalContext]); - JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL); - - if (settings != NULL) - settings->setJavaScriptCanOpenWindowsAutomatically(no); - } -} - -- (id) _rightButtonTitle { - return button_ != nil ? button_ : @"Reload"; -} - -- (id) rightButtonTitle { - return [self _loading] ? @"" : [self _rightButtonTitle]; -} - -- (UINavigationButtonStyle) rightButtonStyle { - if (style_ == nil) normal: - return UINavigationButtonStyleNormal; - else if ([style_ isEqualToString:@"Normal"]) - return UINavigationButtonStyleNormal; - else if ([style_ isEqualToString:@"Back"]) - return UINavigationButtonStyleBack; - else if ([style_ isEqualToString:@"Highlighted"]) - return UINavigationButtonStyleHighlighted; - else if ([style_ isEqualToString:@"Destructive"]) - return UINavigationButtonStyleDestructive; - else goto normal; -} - -- (NSString *) title { - return title_ == nil ? @"Loading" : title_; -} - -- (NSString *) backButtonTitle { - return @"Browser"; -} - -- (void) setPageActive:(BOOL)active { - if (!active) - [indicator_ removeFromSuperview]; - else - [[book_ navigationBar] addSubview:indicator_]; -} - -- (void) resetViewAnimated:(BOOL)animated { -} - -- (void) setPushed:(bool)pushed { - pushed_ = pushed; -} - -@end -/* }}} */ +#include /* Cydia Book {{{ */ @interface CYBook : RVBook < @@ -7810,8 +6987,12 @@ int main(int argc, char *argv[]) { _pooled /*AddPreferences(@"/Applications/Preferences.app/Settings-iPhone.plist"); AddPreferences(@"/Applications/Preferences.app/Settings-iPod.plist");*/ - if ((Indices_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/indices.plist"]) == NULL) - Indices_ = [[NSMutableDictionary alloc] init]; + /*if ((Indices_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/indices.plist"]) == NULL) + Indices_ = [[NSMutableDictionary alloc] init];*/ + + Indices_ = [NSMutableDictionary dictionaryWithObjectsAndKeys: + @"http://"/*"cache.saurik.com/"*/"cydia.saurik.com/server/rating/@P", @"Rating", + nil]; if ((Metadata_ = [[NSMutableDictionary alloc] initWithContentsOfFile:@"/var/lib/cydia/metadata.plist"]) == NULL) Metadata_ = [[NSMutableDictionary alloc] initWithCapacity:2]; diff --git a/UICaboodle/BrowserView.h b/UICaboodle/BrowserView.h index 88434a09..3dcdb931 100644 --- a/UICaboodle/BrowserView.h +++ b/UICaboodle/BrowserView.h @@ -1,5 +1,26 @@ #import "ResetView.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#import +#import + +#include +#include + +#import + @class NSMutableArray; @class NSString; @class NSURL; diff --git a/UICaboodle/BrowserView.m b/UICaboodle/BrowserView.m new file mode 100644 index 00000000..edaa2f2c --- /dev/null +++ b/UICaboodle/BrowserView.m @@ -0,0 +1,824 @@ +#include + +@interface WebView (Cydia) +- (void) setScriptDebugDelegate:(id)delegate; +- (void) _setFormDelegate:(id)delegate; +- (void) _setUIKitDelegate:(id)delegate; +- (void) setWebMailDelegate:(id)delegate; +- (void) _setLayoutInterval:(float)interval; +@end + +@implementation BrowserView + +#if ForSaurik +#include "Internals.h" +#endif + +- (void) dealloc { + if (challenge_ != nil) + [challenge_ release]; + + WebView *webview = [webview_ webView]; + [webview setFrameLoadDelegate:nil]; + [webview setResourceLoadDelegate:nil]; + [webview setUIDelegate:nil]; + [webview setScriptDebugDelegate:nil]; + [webview setPolicyDelegate:nil]; + + [webview setDownloadDelegate:nil]; + + [webview _setFormDelegate:nil]; + [webview _setUIKitDelegate:nil]; + [webview setWebMailDelegate:nil]; + [webview setEditingDelegate:nil]; + + [webview_ setDelegate:nil]; + [webview_ setGestureDelegate:nil]; + + //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + [webview close]; + +#if RecycleWebViews + [webview_ removeFromSuperview]; + [Documents_ addObject:[webview_ autorelease]]; +#else + [webview_ release]; +#endif + + [indirect_ setDelegate:nil]; + [indirect_ release]; + + [scroller_ setDelegate:nil]; + + if (button_ != nil) + [button_ release]; + if (style_ != nil) + [style_ release]; + if (function_ != nil) + [function_ release]; + + [scroller_ release]; + [indicator_ release]; + if (confirm_ != nil) + [confirm_ release]; + if (title_ != nil) + [title_ release]; + [super dealloc]; +} + +- (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { + [self loadRequest:[NSURLRequest + requestWithURL:url + cachePolicy:policy + timeoutInterval:30.0 + ]]; +} + +- (void) loadURL:(NSURL *)url { + [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; +} + +- (NSMutableURLRequest *) _addHeadersToRequest:(NSURLRequest *)request { + NSMutableURLRequest *copy = [request mutableCopy]; + + if (Machine_ != NULL) + [copy setValue:[NSString stringWithUTF8String:Machine_] forHTTPHeaderField:@"X-Machine"]; + if (UniqueID_ != nil) + [copy setValue:UniqueID_ forHTTPHeaderField:@"X-Unique-ID"]; + + if (Role_ != nil) + [copy setValue:Role_ forHTTPHeaderField:@"X-Role"]; + + return copy; +} + +- (void) loadRequest:(NSURLRequest *)request { + pushed_ = true; + [webview_ loadRequest:request]; +} + +- (void) reloadURL { + NSLog(@"rlu:%@", request_); + if (request_ == nil) + return; + + if ([request_ HTTPBody] == nil && [request_ HTTPBodyStream] == nil) + [webview_ loadRequest:request_]; + else { + UIActionSheet *sheet = [[[UIActionSheet alloc] + initWithTitle:@"Are you sure you want to submit this form again?" + buttons:[NSArray arrayWithObjects:@"Cancel", @"Submit", nil] + defaultButtonIndex:0 + delegate:self + context:@"submit" + ] autorelease]; + + [sheet setNumberOfRows:1]; + [sheet popupAlertAnimated:YES]; + } +} + +- (WebView *) webView { + return [webview_ webView]; +} + +- (void) view:(UIView *)sender didSetFrame:(CGRect)frame { + [scroller_ setContentSize:frame.size]; +} + +- (void) view:(UIView *)sender didSetFrame:(CGRect)frame oldFrame:(CGRect)old { + [self view:sender didSetFrame:frame]; +} + +- (void) pushPage:(RVPage *)page { + [self setBackButtonTitle:title_]; + [page setDelegate:delegate_]; + [book_ pushPage:page]; +} + +- (BOOL) getSpecial:(NSURL *)url { + NSString *href([url absoluteString]); + NSString *scheme([[url scheme] lowercaseString]); + + RVPage *page = nil; + + if ([href hasPrefix:@"apptapp://package/"]) + page = [delegate_ pageForPackage:[href substringFromIndex:18]]; + else if ([scheme isEqualToString:@"cydia"]) { + page = [delegate_ pageForURL:url hasTag:NULL]; + if (page == nil) + return false; + } else if (![scheme isEqualToString:@"apptapp"]) + return false; + + if (page != nil) + [self pushPage:page]; + return true; +} + +- (void) webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + UIActionSheet *sheet = [[[UIActionSheet alloc] + initWithTitle:nil + buttons:[NSArray arrayWithObjects:@"OK", nil] + defaultButtonIndex:0 + delegate:self + context:@"alert" + ] autorelease]; + + [sheet setBodyText:message]; + [sheet popupAlertAnimated:YES]; +} + +- (BOOL) webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + UIActionSheet *sheet = [[[UIActionSheet alloc] + initWithTitle:nil + buttons:[NSArray arrayWithObjects:@"OK", @"Cancel", nil] + defaultButtonIndex:0 + delegate:self + context:@"confirm" + ] autorelease]; + + [sheet setNumberOfRows:1]; + [sheet setBodyText:message]; + [sheet popupAlertAnimated:YES]; + + NSRunLoop *loop([NSRunLoop currentRunLoop]); + NSDate *future([NSDate distantFuture]); + + while (confirm_ == nil && [loop runMode:NSDefaultRunLoopMode beforeDate:future]); + + NSNumber *confirm([confirm_ autorelease]); + confirm_ = nil; + return [confirm boolValue]; +} + +/* Web Scripting {{{ */ ++ (NSString *) webScriptNameForSelector:(SEL)selector { + if (selector == @selector(getPackageById:)) + return @"getPackageById"; + else if (selector == @selector(setButtonImage:withStyle:toFunction:)) + return @"setButtonImage"; + else if (selector == @selector(setButtonTitle:withStyle:toFunction:)) + return @"setButtonTitle"; + else if (selector == @selector(supports:)) + return @"supports"; + else + return nil; +} + ++ (BOOL) isSelectorExcludedFromWebScript:(SEL)selector { + return [self webScriptNameForSelector:selector] == nil; +} + +- (BOOL) supports:(NSString *)feature { + return [feature isEqualToString:@"window.open"]; +} + +- (Package *) getPackageById:(NSString *)id { + return [[Database sharedInstance] packageWithName:id]; +} + +- (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { + if (button_ != nil) + [button_ autorelease]; + button_ = button == nil ? nil : [[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:button]]] retain]; + + if (style_ != nil) + [style_ autorelease]; + style_ = style == nil ? nil : [style retain]; + + if (function_ != nil) + [function_ autorelease]; + function_ = function == nil ? nil : [function retain]; +} + +- (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { + if (button_ != nil) + [button_ autorelease]; + button_ = button == nil ? nil : [button retain]; + + if (style_ != nil) + [style_ autorelease]; + style_ = style == nil ? nil : [style retain]; + + if (function_ != nil) + [function_ autorelease]; + function_ = function == nil ? nil : [function retain]; +} +/* }}} */ + +- (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { + [window setValue:self forKey:@"cydia"]; +} + +- (void) webView:(WebView *)sender unableToImplementPolicyWithError:(NSError *)error frame:(WebFrame *)frame { + NSLog(@"err:%@", error); +} + +- (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener { + if (NSURL *url = [request URL]) { + if (name != nil && [name isEqualToString:@"_open"]) + [delegate_ openURL:url]; + + NSLog(@"win:%@:%@", url, [action description]); + if (![self getSpecial:url]) { + NSString *scheme([[url scheme] lowercaseString]); + if ([scheme isEqualToString:@"mailto"]) + [delegate_ openMailToURL:url]; + else goto use; + } + + [listener ignore]; + } else use: + [listener use]; +} + +- (void) webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { + if ([WebView canShowMIMEType:type]) + [listener use]; + else { + // XXX: handle more mime types! + [listener ignore]; + if (frame == [webView mainFrame]) + [UIApp openURL:[request URL]]; + } +} + +- (void) webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { + if (request == nil) ignore: { + [listener ignore]; + return; + } + + NSURL *url([request URL]); + + if (url == nil) use: { + if ([frame parentFrame] == nil) { + if (request_ != nil) + [request_ autorelease]; + request_ = [request retain]; + NSLog(@"dpn:%@", request_); + } + + [listener use]; + return; + } +#if ForSaurik + else NSLog(@"nav:%@:%@", url, [action description]); +#endif + + const NSArray *capability(reinterpret_cast(GSSystemGetCapability(kGSDisplayIdentifiersCapability))); + + if ( + [capability containsObject:@"com.apple.Maps"] && [url mapsURL] || + [capability containsObject:@"com.apple.youtube"] && [url youTubeURL] + ) { + open: + [UIApp openURL:url]; + goto ignore; + } + + int store(_not(int)); + if (NSURL *itms = [url itmsURL:&store]) { + NSLog(@"itms#%@#%u#%@", url, store, itms); + if ( + store == 1 && [capability containsObject:@"com.apple.MobileStore"] || + store == 2 && [capability containsObject:@"com.apple.AppStore"] + ) { + url = itms; + goto open; + } + } + + NSString *scheme([[url scheme] lowercaseString]); + + if ([scheme isEqualToString:@"tel"]) { + // XXX: intelligence + goto open; + } + + if ([scheme isEqualToString:@"mailto"]) { + [delegate_ openMailToURL:url]; + goto ignore; + } + + if ([self getSpecial:url]) + goto ignore; + else if ([WebView _canHandleRequest:request]) + goto use; + else if ([url isSpringboardHandledURL]) + goto open; + else + goto use; +} + +- (void) webView:(WebView *)sender setStatusText:(NSString *)text { + //lprintf("Status:%s\n", [text UTF8String]); +} + +- (void) _pushPage { + if (pushed_) + return; + pushed_ = true; + [book_ pushPage:self]; +} + +- (void) alertSheet:(UIActionSheet *)sheet buttonClicked:(int)button { + NSString *context([sheet context]); + + if ([context isEqualToString:@"alert"]) + [sheet dismiss]; + else if ([context isEqualToString:@"confirm"]) { + switch (button) { + case 1: + confirm_ = [NSNumber numberWithBool:YES]; + break; + + case 2: + confirm_ = [NSNumber numberWithBool:NO]; + break; + } + + [sheet dismiss]; + } else if ([context isEqualToString:@"challenge"]) { + id sender([challenge_ sender]); + + switch (button) { + case 1: { + NSString *username([[sheet textFieldAtIndex:0] text]); + NSString *password([[sheet textFieldAtIndex:1] text]); + + NSURLCredential *credential([NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession]); + + [sender useCredential:credential forAuthenticationChallenge:challenge_]; + } break; + + case 2: + [sender cancelAuthenticationChallenge:challenge_]; + break; + + default: + _assert(false); + } + + [challenge_ release]; + challenge_ = nil; + + [sheet dismiss]; + } else if ([context isEqualToString:@"submit"]) { + switch (button) { + case 1: + break; + + case 2: + if (request_ != nil) + [webview_ loadRequest:request_]; + break; + + default: + _assert(false); + } + + [sheet dismiss]; + } +} + +- (void) webView:(WebView *)sender resource:(id)identifier didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge fromDataSource:(WebDataSource *)source { + challenge_ = [challenge retain]; + + NSURLProtectionSpace *space([challenge protectionSpace]); + NSString *realm([space realm]); + if (realm == nil) + realm = @""; + + UIActionSheet *sheet = [[[UIActionSheet alloc] + initWithTitle:realm + buttons:[NSArray arrayWithObjects:@"Login", @"Cancel", nil] + defaultButtonIndex:0 + delegate:self + context:@"challenge" + ] autorelease]; + + [sheet setNumberOfRows:1]; + + [sheet addTextFieldWithValue:@"" label:@"username"]; + [sheet addTextFieldWithValue:@"" label:@"password"]; + + UITextField *username([sheet textFieldAtIndex:0]); { + UITextInputTraits *traits([username textInputTraits]); + [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; + [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; + [traits setKeyboardType:UIKeyboardTypeASCIICapable]; + [traits setReturnKeyType:UIReturnKeyNext]; + } + + UITextField *password([sheet textFieldAtIndex:1]); { + UITextInputTraits *traits([password textInputTraits]); + [traits setAutocapitalizationType:UITextAutocapitalizationTypeNone]; + [traits setAutocorrectionType:UITextAutocorrectionTypeNo]; + [traits setKeyboardType:UIKeyboardTypeASCIICapable]; + // XXX: UIReturnKeyDone + [traits setReturnKeyType:UIReturnKeyNext]; + [traits setSecureTextEntry:YES]; + } + + [sheet popupAlertAnimated:YES]; +} + +- (NSURLRequest *) webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)source { + NSURL *url = [request URL]; + if ([self getSpecial:url]) + return nil; + [self _pushPage]; + return [self _addHeadersToRequest:request]; +} + +- (WebView *) _createWebViewWithRequest:(NSURLRequest *)request pushed:(BOOL)pushed { + [self setBackButtonTitle:title_]; + + BrowserView *browser = [[[BrowserView alloc] initWithBook:book_] autorelease]; + [browser setDelegate:delegate_]; + + if (pushed) { + [browser loadRequest:request]; + [book_ pushPage:browser]; + } + + return [browser webView]; +} + +- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { + return [self _createWebViewWithRequest:request pushed:(request != nil)]; +} + +- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features { + return [self _createWebViewWithRequest:request pushed:YES]; +} + +- (void) webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { + if ([frame parentFrame] != nil) + return; + + title_ = [title retain]; + [book_ reloadTitleForPage:self]; +} + +- (void) webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame { + if ([frame parentFrame] != nil) + return; + + reloading_ = false; + loading_ = true; + [self reloadButtons]; + + if (title_ != nil) { + [title_ release]; + title_ = nil; + } + + if (button_ != nil) { + [button_ release]; + button_ = nil; + } + + if (style_ != nil) { + [style_ release]; + style_ = nil; + } + + if (function_ != nil) { + [function_ release]; + function_ = nil; + } + + [book_ reloadTitleForPage:self]; + + [scroller_ scrollPointVisibleAtTopLeft:CGPointZero]; + + CGRect webrect = [scroller_ bounds]; + webrect.size.height = 0; + [webview_ setFrame:webrect]; +} + +- (void) _finishLoading { + if (!reloading_) { + loading_ = false; + [self reloadButtons]; + } +} + +- (bool) _loading { + return loading_; +} + +- (void) reloadButtons { + if ([self _loading]) + [indicator_ startAnimation]; + else + [indicator_ stopAnimation]; + [super reloadButtons]; +} + +- (BOOL) webView:(WebView *)sender shouldScrollToPoint:(struct CGPoint)point forFrame:(WebFrame *)frame { + return [webview_ webView:sender shouldScrollToPoint:point forFrame:frame]; +} + +- (void) webView:(WebView *)sender didReceiveViewportArguments:(id)arguments forFrame:(WebFrame *)frame { + return [webview_ webView:sender didReceiveViewportArguments:arguments forFrame:frame]; +} + +- (void) webView:(WebView *)sender needsScrollNotifications:(id)notifications forFrame:(WebFrame *)frame { + return [webview_ webView:sender needsScrollNotifications:notifications forFrame:frame]; +} + +- (void) webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { + return [webview_ webView:sender didCommitLoadForFrame:frame]; +} + +- (void) webView:(WebView *)sender didReceiveDocTypeForFrame:(WebFrame *)frame { + return [webview_ webView:sender didReceiveDocTypeForFrame:frame]; +} + +- (void) webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { + if ([frame parentFrame] == nil) { + [self _finishLoading]; + + if (DOMDocument *document = [frame DOMDocument]) + if (DOMNodeList *bodies = [document getElementsByTagName:@"body"]) + for (DOMHTMLBodyElement *body in bodies) { + DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]); + + bool colored(false); + + if (DOMCSSPrimitiveValue *color = static_cast([style getPropertyCSSValue:@"background-color"])) { + DOMRGBColor *rgb([color getRGBColorValue]); + + float alpha([[rgb alpha] getFloatValue:DOM_CSS_NUMBER]); + NSLog(@"alpha:%g", alpha); + + if (alpha != 0) { + colored = true; + + [scroller_ setBackgroundColor:[UIColor + colorWithRed:([[rgb red] getFloatValue:DOM_CSS_NUMBER] / 255) + green:([[rgb green] getFloatValue:DOM_CSS_NUMBER] / 255) + blue:([[rgb blue] getFloatValue:DOM_CSS_NUMBER] / 255) + alpha:alpha + ]]; + } + } + + if (!colored) + [scroller_ setBackgroundColor:[UIColor pinStripeColor]]; + break; + } + } + + return [webview_ webView:sender didFinishLoadForFrame:frame]; +} + +- (void) webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { + if ([frame parentFrame] != nil) + return; + [self _finishLoading]; + + [self loadURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", + [[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"error" ofType:@"html"]] absoluteString], + [[error localizedDescription] stringByAddingPercentEscapes] + ]]]; +} + +- (void) webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary { +#if ForSaurik + lprintf("Console:%s\n", [[dictionary description] UTF8String]); +#endif +} + +- (id) initWithBook:(RVBook *)book { + if ((self = [super initWithBook:book]) != nil) { + loading_ = false; + + struct CGRect bounds = [self bounds]; + + scroller_ = [[UIScroller alloc] initWithFrame:bounds]; + [self addSubview:scroller_]; + + [scroller_ setShowBackgroundShadow:NO]; + [scroller_ setFixedBackgroundPattern:YES]; + [scroller_ setBackgroundColor:[UIColor pinStripeColor]]; + + [scroller_ setScrollingEnabled:YES]; + [scroller_ setAdjustForContentSizeChange:YES]; + [scroller_ setClipsSubviews:YES]; + [scroller_ setAllowsRubberBanding:YES]; + [scroller_ setScrollDecelerationFactor:0.99]; + [scroller_ setDelegate:self]; + + CGRect webrect = [scroller_ bounds]; + webrect.size.height = 0; + + WebView *webview; + +#if RecycleWebViews + webview_ = [Documents_ lastObject]; + if (webview_ != nil) { + webview_ = [webview_ retain]; + webview = [webview_ webView]; + [Documents_ removeLastObject]; + [webview_ setFrame:webrect]; + } else { +#else + if (true) { +#endif + webview_ = [[UIWebDocumentView alloc] initWithFrame:webrect]; + webview = [webview_ webView]; + + // XXX: this is terribly (too?) expensive + //[webview_ setDrawsBackground:NO]; + [webview setPreferencesIdentifier:@"Cydia"]; + + [webview_ setTileSize:CGSizeMake(webrect.size.width, 500)]; + + [webview_ setAllowsMessaging:YES]; + + [webview_ setTilingEnabled:YES]; + [webview_ setDrawsGrid:NO]; + [webview_ setLogsTilingChanges:NO]; + [webview_ setTileMinificationFilter:kCAFilterNearest]; + [webview_ setDetectsPhoneNumbers:NO]; + [webview_ setAutoresizes:YES]; + + [webview_ setMinimumScale:0.25f forDocumentTypes:0x10]; + [webview_ setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:0x10]; + [webview_ setViewportSize:CGSizeMake(980, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; + + [webview_ setViewportSize:CGSizeMake(320, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x2]; + + [webview_ setMinimumScale:1.0f forDocumentTypes:0x8]; + [webview_ setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:0x8]; + [webview_ setViewportSize:CGSizeMake(320, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x8]; + + [webview_ _setDocumentType:0x4]; + + [webview_ setZoomsFocusedFormControl:YES]; + [webview_ setContentsPosition:7]; + [webview_ setEnabledGestures:0xa]; + [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeIsZoomRubberBandEnabled]; + [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeUpdatesScroller]; + + [webview_ setSmoothsFonts:YES]; + + [webview _setUsesLoaderCache:YES]; + [webview setGroupName:@"Cydia"]; + [webview _setLayoutInterval:0]; + } + + [webview_ setDelegate:self]; + [webview_ setGestureDelegate:self]; + [scroller_ addSubview:webview_]; + + //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + CGSize indsize = [UIProgressIndicator defaultSizeForStyle:UIProgressIndicatorStyleMediumWhite]; + indicator_ = [[UIProgressIndicator alloc] initWithFrame:CGRectMake(281, 12, indsize.width, indsize.height)]; + [indicator_ setStyle:UIProgressIndicatorStyleMediumWhite]; + + Package *package([[Database sharedInstance] packageWithName:@"cydia"]); + NSString *application = package == nil ? @"Cydia" : [NSString + stringWithFormat:@"Cydia/%@", + [package installed] + ]; [webview setApplicationNameForUserAgent:application]; + + indirect_ = [[IndirectDelegate alloc] initWithDelegate:self]; + + [webview setFrameLoadDelegate:self]; + [webview setResourceLoadDelegate:indirect_]; + [webview setUIDelegate:self]; + [webview setScriptDebugDelegate:self]; + [webview setPolicyDelegate:self]; + + [self setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + [scroller_ setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; + } return self; +} + +- (void) didFinishGesturesInView:(UIView *)view forEvent:(id)event { + [webview_ redrawScaledDocument]; +} + +- (void) _rightButtonClicked { + if (function_ == nil) { + reloading_ = true; + [self reloadURL]; + } else { + WebView *webview([webview_ webView]); + WebFrame *frame([webview mainFrame]); + + 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); + } + + [delegate_ clearFirstResponder]; + JSObjectRef function([function_ JSObject]); + JSGlobalContextRef context([frame globalContext]); + JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL); + + if (settings != NULL) + settings->setJavaScriptCanOpenWindowsAutomatically(no); + } +} + +- (id) _rightButtonTitle { + return button_ != nil ? button_ : @"Reload"; +} + +- (id) rightButtonTitle { + return [self _loading] ? @"" : [self _rightButtonTitle]; +} + +- (UINavigationButtonStyle) rightButtonStyle { + if (style_ == nil) normal: + return UINavigationButtonStyleNormal; + else if ([style_ isEqualToString:@"Normal"]) + return UINavigationButtonStyleNormal; + else if ([style_ isEqualToString:@"Back"]) + return UINavigationButtonStyleBack; + else if ([style_ isEqualToString:@"Highlighted"]) + return UINavigationButtonStyleHighlighted; + else if ([style_ isEqualToString:@"Destructive"]) + return UINavigationButtonStyleDestructive; + else goto normal; +} + +- (NSString *) title { + return title_ == nil ? @"Loading" : title_; +} + +- (NSString *) backButtonTitle { + return @"Browser"; +} + +- (void) setPageActive:(BOOL)active { + if (!active) + [indicator_ removeFromSuperview]; + else + [[book_ navigationBar] addSubview:indicator_]; +} + +- (void) resetViewAnimated:(BOOL)animated { +} + +- (void) setPushed:(bool)pushed { + pushed_ = pushed; +} + +@end diff --git a/UICaboodle/Internals.h b/UICaboodle/Internals.h index a34c29ff..62b46e26 100644 --- a/UICaboodle/Internals.h +++ b/UICaboodle/Internals.h @@ -4,6 +4,7 @@ } - (BOOL) respondsToSelector:(SEL)selector { - fprintf(stderr, "[%s]R-%s\n", class_getName(self->isa), sel_getName(selector)); - return [super respondsToSelector:selector]; + BOOL responds = [super respondsToSelector:selector]; + fprintf(stderr, "[%s]R%c%s\n", class_getName(self->isa), (responds ? '+' : '-'), sel_getName(selector)); + return responds; } diff --git a/UICaboodle/RVBook.h b/UICaboodle/RVBook.h index d1037b2c..88a51915 100644 --- a/UICaboodle/RVBook.h +++ b/UICaboodle/RVBook.h @@ -7,13 +7,18 @@ @class UINavigationBar; @class UITransitionView; +@protocol RVNavigationBarDelegate +@end + @protocol RVDelegate - (void) setPageActive:(BOOL)active with:(id)object; - (void) resetViewAnimated:(BOOL)animated with:(id)object; - (void) reloadDataWith:(id)object; @end -@interface RVBook : UIView { +@interface RVBook : UIView < + RVNavigationBarDelegate +> { NSMutableArray *pages_; UINavigationBar *navbar_; UITransitionView *transition_; diff --git a/UICaboodle/RVBook.mm b/UICaboodle/RVBook.mm index 708e66f3..a6f53181 100644 --- a/UICaboodle/RVBook.mm +++ b/UICaboodle/RVBook.mm @@ -18,6 +18,47 @@ #import "RVPage.h" +@interface NSObject (UICaboodleRVBook) +- (float) widthForButtonContents:(float)width; +@end + +@implementation NSObject (UICaboodleRVBook) + +- (float) widthForButtonContents:(float)width { + return width; +} + +@end + +@interface UIImage (UICaboodleRVBook) +- (float) widthForButtonContents:(float)width; +@end + +@implementation UIImage (UICaboodleRVBook) + +- (float) widthForButtonContents:(float)width { + return [self size].width + 8; +} + +@end + +@interface RVNavigationBar : UINavigationBar { +} + +- (id) createButtonWithContents:(id)contents width:(float)width barStyle:(int)barStyle buttonStyle:(int)style isRight:(BOOL)right; +@end + +@implementation RVNavigationBar + +- (id) createButtonWithContents:(id)contents width:(float)width barStyle:(int)barStyle buttonStyle:(int)style isRight:(BOOL)right { + float adjust = [contents widthForButtonContents:width]; + NSLog(@"cc:%@:%g:%g", contents, width, adjust); + width = adjust; + return [super createButtonWithContents:contents width:width barStyle:barStyle buttonStyle:style isRight:right]; +} + +@end + @implementation RVBook - (void) dealloc { @@ -59,7 +100,7 @@ CGSize navsize = [UINavigationBar defaultSize]; CGRect navrect = {{0, 0}, navsize}; - navbar_ = [[UINavigationBar alloc] initWithFrame:navrect]; + navbar_ = [[RVNavigationBar alloc] initWithFrame:navrect]; [self addSubview:navbar_]; [navbar_ setBarStyle:0]; diff --git a/UICaboodle/RVPage.h b/UICaboodle/RVPage.h index fa77df3a..fffc4c41 100644 --- a/UICaboodle/RVPage.h +++ b/UICaboodle/RVPage.h @@ -12,10 +12,12 @@ - (NSString *) title; - (NSString *) backButtonTitle; -- (NSString *) rightButtonTitle; +- (id) rightButtonTitle; - (NSString *) leftButtonTitle; - (UIView *) accessoryView; +- (UIImage *) rightButtonImage; + - (UINavigationButtonStyle) leftButtonStyle; - (UINavigationButtonStyle) rightButtonStyle; diff --git a/UICaboodle/RVPage.mm b/UICaboodle/RVPage.mm index 02135c13..77007558 100644 --- a/UICaboodle/RVPage.mm +++ b/UICaboodle/RVPage.mm @@ -20,7 +20,7 @@ return nil; } -- (NSString *) rightButtonTitle { +- (id) rightButtonTitle { return nil; } @@ -44,6 +44,10 @@ return nil; } +- (UIImage *) rightButtonImage { + return nil; +} + - (void) setPageActive:(BOOL)active { } diff --git a/internals.h b/internals.h deleted file mode 100644 index 62b46e26..00000000 --- a/internals.h +++ /dev/null @@ -1,10 +0,0 @@ -- (NSMethodSignature *) methodSignatureForSelector:(SEL)selector { - fprintf(stderr, "[%s]S-%s\n", class_getName(self->isa), sel_getName(selector)); - return [super methodSignatureForSelector:selector]; -} - -- (BOOL) respondsToSelector:(SEL)selector { - BOOL responds = [super respondsToSelector:selector]; - fprintf(stderr, "[%s]R%c%s\n", class_getName(self->isa), (responds ? '+' : '-'), sel_getName(selector)); - return responds; -} diff --git a/makefile b/makefile index fdff32dc..c93bab03 100644 --- a/makefile +++ b/makefile @@ -9,7 +9,7 @@ all: Cydia clean: rm -f Cydia -Cydia: Cydia.mm ../uicaboodle.m/*.mm ../mobilesubstrate/*.h *.h #makefile +Cydia: Cydia.mm ../uicaboodle.m/*.m ../uicaboodle.m/*.mm ../mobilesubstrate/*.h #makefile $(target)g++ -march=armv6 -mcpu=arm1176jzf-s -I../uicaboodle.m -I../mobilesubstrate -fobjc-call-cxx-cdtors -g0 -O2 -Wall -Werror -o $@ $(filter %.mm,$^) -framework UIKit -framework IOKit -framework CoreFoundation -framework Foundation -framework CoreGraphics -framework GraphicsServices -framework MessageUI -framework QuartzCore -framework JavaScriptCore -framework WebCore -framework WebKit -lobjc -lapt-pkg -lpcre -fobjc-exceptions -F"$${PKG_ROOT}"/System/Library/PrivateFrameworks -multiply_defined suppress sign: Cydia -- 2.45.2