GitX version 0.5
[GitX.git] / PBWebController.m
blob3ad0176f2df3e78aa1c90d5ded6a686e53c92ba4
1 //
2 //  PBWebController.m
3 //  GitX
4 //
5 //  Created by Pieter de Bie on 08-10-08.
6 //  Copyright 2008 __MyCompanyName__. All rights reserved.
7 //
9 #import "PBWebController.h"
10 #import "PBGitRepository.h"
11 #import "PBGitXProtocol.h"
13 #include <SystemConfiguration/SCNetworkReachability.h>
15 @implementation PBWebController
17 @synthesize startFile, repository;
19 - (void) awakeFromNib
21         NSString *path = [NSString stringWithFormat:@"html/views/%@", startFile];
22         NSString* file = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:path];
23         NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:file]];
24         callbacks = [NSMapTable mapTableWithKeyOptions:(NSPointerFunctionsObjectPointerPersonality|NSPointerFunctionsStrongMemory) valueOptions:(NSPointerFunctionsObjectPointerPersonality|NSPointerFunctionsStrongMemory)];
26         finishedLoading = NO;
27         [view setUIDelegate:self];
28         [view setFrameLoadDelegate:self];
29         [view setResourceLoadDelegate:self];
30         [[view mainFrame] loadRequest:request];
33 - (WebScriptObject *) script
35         return [view windowScriptObject];
38 # pragma mark Delegate methods
40 - (void) webView:(id) v didFinishLoadForFrame:(id) frame
42         id script = [view windowScriptObject];
43         [script setValue: self forKey:@"Controller"];
45         finishedLoading = YES;
46         if ([self respondsToSelector:@selector(didLoad)])
47                 [self performSelector:@selector(didLoad)];
50 - (void)webView:(WebView *)webView addMessageToConsole:(NSDictionary *)dictionary
52         NSLog(@"Error from webkit: %@", dictionary);
55 - (NSURLRequest *)webView:(WebView *)sender
56                  resource:(id)identifier
57           willSendRequest:(NSURLRequest *)request
58          redirectResponse:(NSURLResponse *)redirectResponse
59            fromDataSource:(WebDataSource *)dataSource
61         if (!self.repository)
62                 return request;
64         // TODO: Change this to canInitWithRequest
65         if ([[[request URL] scheme] isEqualToString:@"GitX"]) {
66                 NSMutableURLRequest *newRequest = [request mutableCopy];
67                 [newRequest setRepository:self.repository];
68                 return newRequest;
69         }
71         return request;
75 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
77         return NO;
80 + (BOOL)isKeyExcludedFromWebScript:(const char *)name {
81         return NO;
84 #pragma mark Functions to be used from JavaScript
86 - (void) log: (NSString*) logMessage
88         NSLog(@"%@", logMessage);
91 - (BOOL) isReachable:(NSString *)hostname
93         SCNetworkConnectionFlags flags;
94         if (!SCNetworkCheckReachabilityByName([hostname cStringUsingEncoding:NSASCIIStringEncoding], &flags))
95                 return FALSE;
97         // If a connection is required, then it's not reachable
98         if (flags & (kSCNetworkFlagsConnectionRequired | kSCNetworkFlagsConnectionAutomatic | kSCNetworkFlagsInterventionRequired))
99                 return FALSE;
101         return flags > 0;
104 #pragma mark Using async function from JS
106 - (void) runCommand:(WebScriptObject *)arguments inRepository:(PBGitRepository *)repo callBack:(WebScriptObject *)callBack
108         // The JS bridge does not handle JS Arrays, even though the docs say it does. So, we convert it ourselves.
109         int length = [[arguments valueForKey:@"length"] intValue];
110         NSMutableArray *realArguments = [NSMutableArray arrayWithCapacity:length];
111         int i = 0;
112         for (i = 0; i < length; i++)
113                 [realArguments addObject:[arguments webScriptValueAtIndex:i]];
115         NSFileHandle *handle = [repo handleInWorkDirForArguments:realArguments];
116         [callbacks setObject:callBack forKey:handle];
117         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(JSRunCommandDone:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; 
118         [handle readToEndOfFileInBackgroundAndNotify];
121 - (void) callSelector:(NSString *)selectorString onObject:(id)object callBack:(WebScriptObject *)callBack
123         NSArray *arguments = [NSArray arrayWithObjects:selectorString, object, nil];
124         NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runInThread:) object:arguments];
125         [callbacks setObject:callBack forKey:thread];
126         [thread start];
129 - (void) runInThread:(NSArray *)arguments
131         SEL selector = NSSelectorFromString([arguments objectAtIndex:0]);
132         id object = [arguments objectAtIndex:1];
133         id ret = [object performSelector:selector];
134         NSArray *returnArray = [NSArray arrayWithObjects:[NSThread currentThread], ret, nil];
135         [self performSelectorOnMainThread:@selector(threadFinished:) withObject:returnArray waitUntilDone:NO];
139 - (void) returnCallBackForObject:(id)object withData:(id)data
141         WebScriptObject *a = [callbacks objectForKey: object];
142         if (!a) {
143                 NSLog(@"Could not find a callback for object: %@", object);
144                 return;
145         }
147         [callbacks removeObjectForKey:object];
148         [a callWebScriptMethod:@"call" withArguments:[NSArray arrayWithObjects:@"", data, nil]];
151 - (void) threadFinished:(NSArray *)arguments
153         [self returnCallBackForObject:[arguments objectAtIndex:0] withData:[arguments objectAtIndex:1]];
156 - (void) JSRunCommandDone:(NSNotification *)notification
158         NSString *data = [[NSString alloc] initWithData:[[notification userInfo] valueForKey:NSFileHandleNotificationDataItem] encoding:NSUTF8StringEncoding];
159         [self returnCallBackForObject:[notification object] withData:data];
162 @end