X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/5a5c1e4bab8fcfdab5b6ee3046be06b0bc3df8f9..7afcea1c7f36f0c4ee9c4d4b53618df39073d851:/UICaboodle/BrowserView.m diff --git a/UICaboodle/BrowserView.m b/UICaboodle/BrowserView.m index 08165235..0f95a049 100644 --- a/UICaboodle/BrowserView.m +++ b/UICaboodle/BrowserView.m @@ -71,12 +71,20 @@ } + (NSString *) webScriptNameForSelector:(SEL)selector { - if (selector == @selector(getPackageById:)) + if (selector == @selector(close)) + return @"close"; + else if (selector == @selector(getPackageById:)) return @"getPackageById"; + else if (selector == @selector(setAutoPopup:)) + return @"setAutoPopup"; else if (selector == @selector(setButtonImage:withStyle:toFunction:)) return @"setButtonImage"; else if (selector == @selector(setButtonTitle:withStyle:toFunction:)) return @"setButtonTitle"; + else if (selector == @selector(setPopupHook:)) + return @"setPopupHook"; + else if (selector == @selector(setViewportWidth:)) + return @"setViewportWidth"; else if (selector == @selector(supports:)) return @"supports"; else if (selector == @selector(du:)) @@ -155,6 +163,14 @@ return value; } +- (void) close { + [indirect_ close]; +} + +- (void) setAutoPopup:(BOOL)popup { + [indirect_ setAutoPopup:popup]; +} + - (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { [indirect_ setButtonImage:button withStyle:style toFunction:function]; } @@ -163,6 +179,14 @@ [indirect_ setButtonTitle:button withStyle:style toFunction:function]; } +- (void) setPopupHook:(id)function { + [indirect_ setPopupHook:function]; +} + +- (void) setViewportWidth:(float)width { + [indirect_ setViewportWidth:width]; +} + @end /* }}} */ @@ -173,7 +197,9 @@ #endif - (void) dealloc { - NSLog(@"deallocating WebView"); +#if LogBrowser + NSLog(@"[BrowserView dealloc]"); +#endif if (challenge_ != nil) [challenge_ release]; @@ -194,6 +220,8 @@ [webview_ setDelegate:nil]; [webview_ setGestureDelegate:nil]; + [webview_ setFormEditingDelegate:nil]; + [webview_ setInteractionDelegate:nil]; //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; @@ -219,6 +247,8 @@ [style_ release]; if (function_ != nil) [function_ release]; + if (closer_ != nil) + [closer_ release]; [scroller_ release]; [indicator_ release]; @@ -289,8 +319,44 @@ return webview_; } +- (void) _fixScroller { + CGRect bounds([webview_ documentBounds]); +#if LogBrowser + NSLog(@"_fs:(%f,%f+%f,%f)", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); +#endif + + float extra; + if (!editing_) + extra = 0; + else { + UIFormAssistant *assistant([UIFormAssistant sharedFormAssistant]); + CGRect peripheral([assistant peripheralFrame]); +#if LogBrowser + NSLog(@"per:%f", peripheral.size.height); +#endif + extra = peripheral.size.height; + } + + CGRect subrect([scroller_ frame]); + subrect.size.height -= extra; + [scroller_ setScrollerIndicatorSubrect:subrect]; + + NSSize visible(NSMakeSize(subrect.size.width, subrect.size.height)); + [webview_ setValue:[NSValue valueWithSize:visible] forGestureAttribute:UIGestureAttributeVisibleSize]; + + CGSize size(size_); + size.height += extra; + [scroller_ setContentSize:size]; + + [scroller_ releaseRubberBandIfNecessary]; +} + - (void) view:(UIView *)sender didSetFrame:(CGRect)frame { - [scroller_ setContentSize:frame.size]; + size_ = frame.size; +#if LogBrowser + NSLog(@"dsf:(%f,%f+%f,%f)", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); +#endif + [self _fixScroller]; } - (void) view:(UIView *)sender didSetFrame:(CGRect)frame oldFrame:(CGRect)old { @@ -303,7 +369,27 @@ [book_ pushPage:page]; } -- (BOOL) getSpecial:(NSURL *)url { +- (void) _pushPage { + if (pushed_) + return; + [self autorelease]; + pushed_ = true; + [book_ pushPage:self]; +} + +- (void) swapPage:(RVPage *)page { + [page setDelegate:delegate_]; + if (pushed_) + [book_ swapPage:page]; + else + [book_ pushPage:page]; +} + +- (BOOL) getSpecial:(NSURL *)url swap:(BOOL)swap { +#if LogBrowser + NSLog(@"getSpecial:%@", url); +#endif + NSString *href([url absoluteString]); NSString *scheme([[url scheme] lowercaseString]); @@ -319,14 +405,27 @@ return false; if (page != nil) - [self pushPage:page]; + if (swap) + [self swapPage:page]; + else + [self pushPage:page]; return true; } - (void) webViewShow:(WebView *)sender { + /* XXX: this is where I cry myself to sleep */ +} + +- (bool) _allowJavaScriptPanel { + return true; } - (void) webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + if (![self _allowJavaScriptPanel]) + return; + + [self retain]; + UIActionSheet *sheet = [[[UIActionSheet alloc] initWithTitle:nil buttons:[NSArray arrayWithObjects:@"OK", nil] @@ -340,11 +439,14 @@ } - (BOOL) webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame { + if (![self _allowJavaScriptPanel]) + return NO; + UIActionSheet *sheet = [[[UIActionSheet alloc] initWithTitle:nil buttons:[NSArray arrayWithObjects:@"OK", @"Cancel", nil] defaultButtonIndex:0 - delegate:self + delegate:indirect_ context:@"confirm" ] autorelease]; @@ -362,6 +464,16 @@ return [confirm boolValue]; } +- (void) setAutoPopup:(BOOL)popup { + popup_ = popup; +} + +- (void) setPopupHook:(id)function { + if (closer_ != nil) + [closer_ autorelease]; + closer_ = function == nil ? nil : [function retain]; +} + - (void) setButtonImage:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { if (button_ != nil) [button_ autorelease]; @@ -374,6 +486,8 @@ if (function_ != nil) [function_ autorelease]; function_ = function == nil ? nil : [function retain]; + + [self reloadButtons]; } - (void) setButtonTitle:(NSString *)button withStyle:(NSString *)style toFunction:(id)function { @@ -388,12 +502,31 @@ if (function_ != nil) [function_ autorelease]; function_ = function == nil ? nil : [function retain]; + + [self reloadButtons]; +} + +- (void) webView:(WebView *)sender willBeginEditingFormElement:(id)element { + editing_ = true; +} + +- (void) webView:(WebView *)sender didBeginEditingFormElement:(id)element { + [self _fixScroller]; +} + +- (void) webViewDidEndEditingFormElements:(WebView *)sender { + editing_ = false; + [self _fixScroller]; } - (void) webViewClose:(WebView *)sender { [book_ close]; } +- (void) close { + [book_ close]; +} + - (void) webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { [window setValue:cydia_ forKey:@"cydia"]; } @@ -403,11 +536,13 @@ } - (void) webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener { +#if LogBrowser NSLog(@"nwa:%@", name); +#endif if (NSURL *url = [request URL]) { if (name == nil) unknown: { - if (![self getSpecial:url]) { + if (![self getSpecial:url swap:NO]) { NSString *scheme([[url scheme] lowercaseString]); if ([scheme isEqualToString:@"mailto"]) [delegate_ openMailToURL:url]; @@ -417,10 +552,11 @@ [delegate_ openURL:url]; else if ([name isEqualToString:@"_popup"]) { RVBook *book([[[RVPopUpBook alloc] initWithFrame:[delegate_ popUpBounds]] autorelease]); + [book setHook:indirect_]; RVPage *page([delegate_ pageForURL:url hasTag:NULL]); if (page == nil) { - /* XXX: call createWebViewWithRequest instead */ + /* XXX: call createWebViewWithRequest instead? */ [self setBackButtonTitle:title_]; @@ -441,13 +577,15 @@ [listener use]; } -- (void) webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener { +- (void) webView:(WebView *)sender 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]) + + WebView *webview([webview_ webView]); + if (frame == [webview mainFrame]) [UIApp openURL:[request URL]]; } } @@ -465,15 +603,19 @@ if (request_ != nil) [request_ autorelease]; request_ = [request retain]; -#if ForSaurik +#if LogBrowser NSLog(@"dpn:%@", request_); #endif } [listener use]; + + WebView *webview([webview_ webView]); + if (frame == [webview mainFrame]) + [self _pushPage]; return; } -#if ForSaurik +#if LogBrowser else NSLog(@"nav:%@:%@", url, [action description]); #endif @@ -490,7 +632,10 @@ int store(_not(int)); if (NSURL *itms = [url itmsURL:&store]) { +#if LogBrowser NSLog(@"itms#%@#%u#%@", url, store, itms); +#endif + if ( store == 1 && [capability containsObject:@"com.apple.MobileStore"] || store == 2 && [capability containsObject:@"com.apple.AppStore"] @@ -512,7 +657,7 @@ goto ignore; } - if ([self getSpecial:url]) + if ([self getSpecial:url swap:YES]) goto ignore; else if ([WebView _canHandleRequest:request]) goto use; @@ -526,19 +671,13 @@ //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"]) + if ([context isEqualToString:@"alert"]) { + [self autorelease]; [sheet dismiss]; - else if ([context isEqualToString:@"confirm"]) { + } else if ([context isEqualToString:@"confirm"]) { switch (button) { case 1: confirm_ = [NSNumber numberWithBool:YES]; @@ -636,26 +775,48 @@ } - (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 *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request windowFeatures:(NSDictionary *)features { -#if ForSaurik - NSLog(@"cwv:%@ (%@)", request, title_); +//- (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request userGesture:(BOOL)gesture { +#if LogBrowser + NSLog(@"cwv:%@ (%@): %@", request, title_, features == nil ? @"{}" : [features description]); + //NSLog(@"cwv:%@ (%@): %@", request, title_, gesture ? @"Yes" : @"No"); #endif - BrowserView *browser = [[[BrowserView alloc] initWithBook:book_] autorelease]; - [self pushPage:browser]; - [browser loadRequest:request]; + NSNumber *value([features objectForKey:@"width"]); + float width(value == nil ? 0 : [value floatValue]); + + RVBook *book(!popup_ ? book_ : [[[RVPopUpBook alloc] initWithFrame:[delegate_ popUpBounds]] autorelease]); + + /* XXX: deal with cydia:// pages */ + BrowserView *browser([[[BrowserView alloc] initWithBook:book forWidth:width] autorelease]); + + if (features != nil && popup_) { + [book setDelegate:delegate_]; + [book setHook:indirect_]; + [browser setDelegate:delegate_]; + + [browser loadRequest:request]; + + [book setPage:browser]; + [book_ pushBook:book]; + } else if (request == nil) { + [self setBackButtonTitle:title_]; + [browser setDelegate:delegate_]; + [browser retain]; + } else { + [self pushPage:browser]; + [browser loadRequest:request]; + } + return [browser webView]; } - (WebView *) webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request { return [self webView:sender createWebViewWithRequest:request windowFeatures:nil]; + //return [self webView:sender createWebViewWithRequest:request userGesture:YES]; } - (void) webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame { @@ -670,6 +831,8 @@ if ([frame parentFrame] != nil) return; + [webview_ resignFirstResponder]; + reloading_ = false; loading_ = true; [self reloadButtons]; @@ -694,9 +857,15 @@ function_ = nil; } + if (closer_ != nil) { + [closer_ release]; + closer_ = nil; + } + [book_ reloadTitleForPage:self]; [scroller_ scrollPointVisibleAtTopLeft:CGPointZero]; + [scroller_ setZoomScale:1 duration:0]; CGRect webrect = [scroller_ bounds]; webrect.size.height = 0; @@ -710,12 +879,12 @@ } } -- (bool) _loading { +- (bool) isLoading { return loading_; } - (void) reloadButtons { - if ([self _loading]) + if ([self isLoading]) [indicator_ startAnimation]; else [indicator_ stopAnimation]; @@ -735,6 +904,7 @@ } - (void) webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame { + [self _pushPage]; return [webview_ webView:sender didCommitLoadForFrame:frame]; } @@ -806,14 +976,20 @@ } - (void) webView:(WebView *)sender addMessageToConsole:(NSDictionary *)dictionary { -#if ForSaurik +#if LogBrowser || ForSaurik lprintf("Console:%s\n", [[dictionary description] UTF8String]); #endif } -- (id) initWithBook:(RVBook *)book { +- (void) setViewportWidth:(float)width { + width_ = width ? width != 0 : [[self class] defaultWidth]; + [webview_ setViewportSize:CGSizeMake(width_, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; +} + +- (id) initWithBook:(RVBook *)book forWidth:(float)width { if ((self = [super initWithBook:book]) != nil) { loading_ = false; + popup_ = false; struct CGRect bounds = [self bounds]; @@ -866,12 +1042,13 @@ [webview_ setAutoresizes:YES]; [webview_ setMinimumScale:0.25f forDocumentTypes:0x10]; + [webview_ setMaximumScale:5.00f forDocumentTypes:0x10]; [webview_ setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:0x10]; - [webview_ setViewportSize:CGSizeMake(980, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; + //[webview_ setViewportSize:CGSizeMake(980, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x10]; [webview_ setViewportSize:CGSizeMake(320, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x2]; - [webview_ setMinimumScale:1.0f forDocumentTypes:0x8]; + [webview_ setMinimumScale:1.00f forDocumentTypes:0x8]; [webview_ setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:0x8]; [webview_ setViewportSize:CGSizeMake(320, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:0x8]; @@ -884,14 +1061,20 @@ [webview_ setValue:[NSNumber numberWithBool:YES] forGestureAttribute:UIGestureAttributeUpdatesScroller]; [webview_ setSmoothsFonts:YES]; - + [webview_ setAllowsImageSheet:YES]; [webview _setUsesLoaderCache:YES]; - [webview setGroupName:@"Cydia"]; + + [webview setGroupName:@"CydiaGroup"]; [webview _setLayoutInterval:0]; } + [self setViewportWidth:width]; + [webview_ setDelegate:self]; [webview_ setGestureDelegate:self]; + [webview_ setFormEditingDelegate:self]; + [webview_ setInteractionDelegate:self]; + [scroller_ addSubview:webview_]; //NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; @@ -906,8 +1089,12 @@ [package installed] ]; + if (Product_ != nil) + application = [NSString stringWithFormat:@"%@ Version/%@", application, Product_]; if (Build_ != nil) - application = [NSString stringWithFormat:@"Mobile/%@ %@", Build_, application]; + application = [NSString stringWithFormat:@"%@ Mobile/%@", application, Build_]; + if (Safari_ != nil) + application = [NSString stringWithFormat:@"%@ Safari/%@", application, Safari_]; /* XXX: lookup application directory? */ /*if (NSDictionary *safari = [NSDictionary dictionaryWithContentsOfFile:@"/Applications/MobileSafari.app/Info.plist"]) @@ -930,46 +1117,62 @@ } return self; } +- (id) initWithBook:(RVBook *)book { + return [self initWithBook:book forWidth:0]; +} + - (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); - } +- (void) callFunction:(WebScriptObject *)function { + WebView *webview([webview_ webView]); + WebFrame *frame([webview mainFrame]); - [delegate_ clearFirstResponder]; - JSObjectRef function([function_ JSObject]); - JSGlobalContextRef context([frame globalContext]); - JSObjectCallAsFunction(context, function, NULL, 0, NULL, NULL); + id _private(MSHookIvar(webview, "_private")); + WebCore::Page *page(_private == nil ? NULL : MSHookIvar(_private, "page")); + WebCore::Settings *settings(page == NULL ? NULL : page->settings()); - if (settings != NULL) - settings->setJavaScriptCanOpenWindowsAutomatically(no); + bool no; + if (settings == NULL) + no = 0; + else { + no = settings->JavaScriptCanOpenWindowsAutomatically(); + settings->setJavaScriptCanOpenWindowsAutomatically(true); } + + [delegate_ clearFirstResponder]; + JSObjectRef object([function JSObject]); + JSGlobalContextRef context([frame globalContext]); + JSObjectCallAsFunction(context, object, NULL, 0, NULL, NULL); + + if (settings != NULL) + settings->setJavaScriptCanOpenWindowsAutomatically(no); +} + +- (void) didCloseBook:(RVBook *)book { + if (closer_ != nil) + [self callFunction:closer_]; +} + +- (void) __rightButtonClicked { + reloading_ = true; + [self reloadURL]; +} + +- (void) _rightButtonClicked { + if (function_ == nil) + [self __rightButtonClicked]; + else + [self callFunction:function_]; } - (id) _rightButtonTitle { - return button_ != nil ? button_ : @"Reload"; + return @"Reload"; } - (id) rightButtonTitle { - return [self _loading] ? @"" : [self _rightButtonTitle]; + return [self isLoading] ? @"" : button_ != nil ? button_ : [self _rightButtonTitle]; } - (UINavigationButtonStyle) rightButtonStyle { @@ -1008,4 +1211,8 @@ pushed_ = pushed; } ++ (float) defaultWidth { + return 980; +} + @end