X-Git-Url: https://git.saurik.com/cydia.git/blobdiff_plain/db698f4255693ec8276ec4bb16c48ad69b64e458..07d0e88e46b7e041b64dc2aaeae3f415a9437e5e:/CyteKit/WebViewController.mm diff --git a/CyteKit/WebViewController.mm b/CyteKit/WebViewController.mm index 7cb59797..5d152139 100644 --- a/CyteKit/WebViewController.mm +++ b/CyteKit/WebViewController.mm @@ -5,6 +5,7 @@ #include "iPhonePrivate.h" +#include "CyteKit/IndirectDelegate.h" #include "CyteKit/Localize.h" #include "CyteKit/WebViewController.h" #include "CyteKit/PerlCompatibleRegEx.hpp" @@ -16,8 +17,8 @@ extern NSString * const kCAFilterNearest; #include -#include -#include +#import +#import #include #include @@ -47,12 +48,6 @@ float CYScrollViewDecelerationRateNormal; - (void) _setAllowsMessaging:(BOOL)allows; @end -@interface WebPreferences (Apple) -+ (void) _setInitialDefaultTextEncodingToSystemEncoding; -- (void) _setLayoutInterval:(NSInteger)interval; -- (void) setOfflineWebApplicationCacheEnabled:(BOOL)enabled; -@end - @implementation WebFrame (Cydia) - (NSString *) description { @@ -62,16 +57,12 @@ float CYScrollViewDecelerationRateNormal; @end /* Indirect Delegate {{{ */ -@interface IndirectDelegate : NSObject { - _transient volatile id delegate_; -} - -- (void) setDelegate:(id)delegate; -- (id) initWithDelegate:(id)delegate; -@end - @implementation IndirectDelegate +- (id) delegate { + return delegate_; +} + - (void) setDelegate:(id)delegate { delegate_ = delegate; } @@ -144,13 +135,25 @@ float CYScrollViewDecelerationRateNormal; CYScrollViewDecelerationRateNormal = 0.998; } +- (bool) retainsNetworkActivityIndicator { + return true; +} + +- (void) releaseNetworkActivityIndicator { + if ([loading_ count] != 0) { + [loading_ removeAllObjects]; + + if ([self retainsNetworkActivityIndicator]) + [delegate_ releaseNetworkActivityIndicator]; + } +} + - (void) dealloc { #if LogBrowser NSLog(@"[CyteWebViewController dealloc]"); #endif - if ([loading_ count] != 0) - [delegate_ releaseNetworkActivityIndicator]; + [self releaseNetworkActivityIndicator]; [super dealloc]; } @@ -167,12 +170,16 @@ float CYScrollViewDecelerationRateNormal; return url; } -- (NSURLRequest *) requestWithURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - return [NSURLRequest +- (NSURLRequest *) requestWithURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy referrer:(NSString *)referrer { + NSMutableURLRequest *request([NSMutableURLRequest requestWithURL:[self URLWithURL:url] cachePolicy:policy timeoutInterval:DefaultTimeout_ - ]; + ]); + + [request setValue:referrer forHTTPHeaderField:@"Referer"]; + + return request; } - (void) setRequest:(NSURLRequest *)request { @@ -181,11 +188,15 @@ float CYScrollViewDecelerationRateNormal; } - (void) setURL:(NSURL *)url { - [self setRequest:[self requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]]; + [self setURL:url withReferrer:nil]; +} + +- (void) setURL:(NSURL *)url withReferrer:(NSString *)referrer { + [self setRequest:[self requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy referrer:referrer]]; } - (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { - [self loadRequest:[self requestWithURL:url cachePolicy:policy]]; + [self loadRequest:[self requestWithURL:url cachePolicy:policy referrer:nil]]; } - (void) loadURL:(NSURL *)url { @@ -213,7 +224,7 @@ float CYScrollViewDecelerationRateNormal; request_ = request; - if ([request_ HTTPBody] == nil && [request_ HTTPBodyStream] == nil) + if (cache || [request_ HTTPBody] == nil && [request_ HTTPBodyStream] == nil) [self loadRequest:request_]; else { UIAlertView *alert = [[[UIAlertView alloc] @@ -231,10 +242,6 @@ float CYScrollViewDecelerationRateNormal; } } -- (void) reloadURL { - [self reloadURLWithCache:YES]; -} - - (void) reloadData { [super reloadData]; @@ -347,7 +354,11 @@ float CYScrollViewDecelerationRateNormal; } - (void) _didFailWithError:(NSError *)error forFrame:(WebFrame *)frame { - [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]]; + NSValue *object([NSValue valueWithNonretainedObject:frame]); + if (![loading_ containsObject:object]) + return; + [loading_ removeObject:object]; + [self _didFinishLoading]; if ([[error domain] isEqualToString:NSURLErrorDomain] && [error code] == NSURLErrorCancelled) @@ -368,11 +379,20 @@ float CYScrollViewDecelerationRateNormal; } } -- (void) pushRequest:(NSURLRequest *)request asPop:(bool)pop { +- (void) pushRequest:(NSURLRequest *)request forAction:(NSDictionary *)action asPop:(bool)pop { + WebFrame *frame(nil); + if (NSDictionary *WebActionElement = [action objectForKey:@"WebActionElementKey"]) + frame = [WebActionElement objectForKey:@"WebElementFrame"]; + if (frame == nil) + frame = [[[[self webView] _documentView] webView] mainFrame]; + + WebDataSource *source([frame provisionalDataSource] ?: [frame dataSource]); + NSString *referrer([request valueForHTTPHeaderField:@"Referer"] ?: [[[source request] URL] absoluteString]); + NSURL *url([request URL]); // XXX: filter to internal usage? - CyteViewController *page([delegate_ pageForURL:url forExternal:NO]); + CyteViewController *page([delegate_ pageForURL:url forExternal:NO withReferrer:referrer]); if (page == nil) { CyteWebViewController *browser([[[class_ alloc] init] autorelease]); @@ -420,7 +440,7 @@ float CYScrollViewDecelerationRateNormal; - (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); + NSLog(@"decidePolicyForNavigationAction:%@ request:%@ %@ frame:%@", action, request, [request allHTTPHeaderFields], frame); #endif if ([frame parentFrame] == nil) { @@ -429,7 +449,7 @@ float CYScrollViewDecelerationRateNormal; if (request_ != nil && ![[request_ URL] isEqual:url] && ![self allowsNavigationAction]) { if (url != nil) - [self pushRequest:request asPop:NO]; + [self pushRequest:request forAction:action asPop:NO]; [listener ignore]; } } @@ -437,29 +457,45 @@ float CYScrollViewDecelerationRateNormal; } - (void) webView:(WebView *)view didDecidePolicy:(CYWebPolicyDecision)decision forNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame { - if ([frame parentFrame] == nil) - if (decision == CYWebPolicyDecisionUse) - if (!error_) - request_ = request; +#if LogBrowser + NSLog(@"didDecidePolicy:%u forNavigationAction:%@ request:%@ frame:%@", decision, action, request, [request allHTTPHeaderFields], frame); +#endif + + if ([frame parentFrame] == nil) { + switch (decision) { + case CYWebPolicyDecisionIgnore: + if ([[request_ URL] isEqual:[request URL]]) + request_ = nil; + break; + + case CYWebPolicyDecisionUse: + if (!error_) + request_ = request; + break; + + default: + break; + } + } } -- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id)listener { +- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id)listener { #if LogBrowser - NSLog(@"decidePolicyForNewWindowAction:%@ request:%@ newFrameName:%@", action, request, frame); + NSLog(@"decidePolicyForNewWindowAction:%@ request:%@ %@ newFrameName:%@", action, request, [request allHTTPHeaderFields], name); #endif NSURL *url([request URL]); if (url == nil) return; - if ([frame isEqualToString:@"_open"]) + if ([name 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"]]; + [self pushRequest:request forAction:action asPop:[name isEqualToString:@"_popup"]]; } [listener ignore]; @@ -495,11 +531,14 @@ float CYScrollViewDecelerationRateNormal; } - (void) webView:(WebView *)view didFinishLoadForFrame:(WebFrame *)frame { - [loading_ removeObject:[NSValue valueWithNonretainedObject:frame]]; + NSValue *object([NSValue valueWithNonretainedObject:frame]); + if (![loading_ containsObject:object]) + return; + [loading_ removeObject:object]; if ([frame parentFrame] == nil) { if (DOMDocument *document = [frame DOMDocument]) - if (DOMNodeList *bodies = [document getElementsByTagName:@"body"]) + if (DOMNodeList *bodies = [document getElementsByTagName:@"body"]) for (DOMHTMLBodyElement *body in (id) bodies) { DOMCSSStyleDeclaration *style([document getComputedStyle:body pseudoElement:nil]); @@ -595,7 +634,7 @@ float CYScrollViewDecelerationRateNormal; // }}} - (void) close { - [[[self navigationController] parentViewController] dismissModalViewControllerAnimated:YES]; + [[[self navigationController] parentOrPresentingViewController] dismissModalViewControllerAnimated:YES]; } - (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)button { @@ -662,7 +701,7 @@ float CYScrollViewDecelerationRateNormal; - (UIBarButtonItem *) customButton { if (custom_ == nil) return nil; - else if (custom_ == [NSNull null]) + else if ((/*clang:*/id) custom_ == [NSNull null]) return (UIBarButtonItem *) [NSNull null]; return [[[UIBarButtonItem alloc] @@ -679,7 +718,7 @@ float CYScrollViewDecelerationRateNormal; return nil; if (UINavigationController *navigation = [self navigationController]) - if ([[navigation parentViewController] modalViewController] == navigation) + if ([[navigation parentOrPresentingViewController] modalViewController] == navigation) return [[[UIBarButtonItem alloc] initWithTitle:UCLocalize("CLOSE") style:UIBarButtonItemStylePlain @@ -737,7 +776,9 @@ float CYScrollViewDecelerationRateNormal; if ([loading_ count] != 1) return; - [delegate_ retainNetworkActivityIndicator]; + if ([self retainsNetworkActivityIndicator]) + [delegate_ retainNetworkActivityIndicator]; + [self didStartLoading]; } @@ -752,7 +793,9 @@ float CYScrollViewDecelerationRateNormal; [self applyRightButton]; [[self navigationItem] setTitle:title_]; - [delegate_ releaseNetworkActivityIndicator]; + if ([self retainsNetworkActivityIndicator]) + [delegate_ releaseNetworkActivityIndicator]; + [self didFinishLoading]; } @@ -832,7 +875,9 @@ float CYScrollViewDecelerationRateNormal; [preferences setCacheModel:WebCacheModelDocumentBrowser]; [preferences setJavaScriptCanOpenWindowsAutomatically:YES]; - [preferences setOfflineWebApplicationCacheEnabled:YES]; + + if ([preferences respondsToSelector:@selector(setOfflineWebApplicationCacheEnabled:)]) + [preferences setOfflineWebApplicationCacheEnabled:YES]; if (NSString *agent = [self applicationNameForUserAgent]) [webview setApplicationNameForUserAgent:agent]; @@ -897,6 +942,8 @@ float CYScrollViewDecelerationRateNormal; webview_ = nil; scroller_ = nil; + [self releaseNetworkActivityIndicator]; + [super releaseSubviews]; } @@ -914,6 +961,12 @@ float CYScrollViewDecelerationRateNormal; } return self; } +- (id) initWithRequest:(NSURLRequest *)request { + if ((self = [self init]) != nil) { + [self setRequest:request]; + } return self; +} + - (void) callFunction:(WebScriptObject *)function { WebThreadLocked lock; @@ -926,7 +979,7 @@ float CYScrollViewDecelerationRateNormal; } - (void) reloadButtonClicked { - [self reloadURLWithCache:YES]; + [self reloadURLWithCache:NO]; } - (void) _customButtonClicked { @@ -1042,6 +1095,9 @@ float CYScrollViewDecelerationRateNormal; if ([self hidesNavigationBar]) [self _setHidesNavigationBar:YES animated:animated]; + // XXX: why isn't this evern called automatically? + [[self webView] setNeedsLayout]; + [self dispatchEvent:@"CydiaViewWillAppear"]; [super viewWillAppear:animated]; }