#include "iPhonePrivate.h"
+#include "CyteKit/IndirectDelegate.h"
#include "CyteKit/Localize.h"
#include "CyteKit/WebViewController.h"
#include "CyteKit/PerlCompatibleRegEx.hpp"
#include <WebCore/WebCoreThread.h>
-#include <WebKit/WebKitErrors.h>
-#include <WebKit/WebPreferences.h>
+#import <WebKit/WebKitErrors.h>
+#import <WebKit/WebPreferences.h>
#include <WebKit/DOMCSSPrimitiveValue.h>
#include <WebKit/DOMCSSStyleDeclaration.h>
- (void) _setAllowsMessaging:(BOOL)allows;
@end
-@interface WebPreferences (Apple)
-+ (void) _setInitialDefaultTextEncodingToSystemEncoding;
-- (void) _setLayoutInterval:(NSInteger)interval;
-- (void) setOfflineWebApplicationCacheEnabled:(BOOL)enabled;
-@end
-
@implementation WebFrame (Cydia)
- (NSString *) description {
@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 {
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];
}
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 {
}
- (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 {
}
- (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)
}
}
-- (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]);
- (void) webView:(WebView *)view decidePolicyForNavigationAction:(NSDictionary *)action request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
#if LogBrowser
- NSLog(@"decidePolicyForNavigationAction:%@ request:%@ frame:%@", action, request, frame);
+ NSLog(@"decidePolicyForNavigationAction:%@ request:%@ %@ frame:%@", action, request, [request allHTTPHeaderFields], frame);
#endif
if ([frame parentFrame] == nil) {
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];
}
}
request_ = request;
}
-- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)frame decisionListener:(id<WebPolicyDecisionListener>)listener {
+- (void) webView:(WebView *)view decidePolicyForNewWindowAction:(NSDictionary *)action request:(NSURLRequest *)request newFrameName:(NSString *)name decisionListener:(id<WebPolicyDecisionListener>)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];
}
- (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 ([loading_ count] != 1)
return;
- [delegate_ retainNetworkActivityIndicator];
+ if ([self retainsNetworkActivityIndicator])
+ [delegate_ retainNetworkActivityIndicator];
+
[self didStartLoading];
}
[self applyRightButton];
[[self navigationItem] setTitle:title_];
- [delegate_ releaseNetworkActivityIndicator];
+ if ([self retainsNetworkActivityIndicator])
+ [delegate_ releaseNetworkActivityIndicator];
+
[self didFinishLoading];
}
webview_ = nil;
scroller_ = nil;
+ [self releaseNetworkActivityIndicator];
+
[super releaseSubviews];
}
} return self;
}
+- (id) initWithRequest:(NSURLRequest *)request {
+ if ((self = [self init]) != nil) {
+ [self setRequest:request];
+ } return self;
+}
+
- (void) callFunction:(WebScriptObject *)function {
WebThreadLocked lock;
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];
}