2 // PBWebGitController.m
5 // Created by Pieter de Bie on 14-06-08.
6 // Copyright 2008 __MyCompanyName__. All rights reserved.
9 #import "PBWebHistoryController.h"
10 #import "PBGitDefaults.h"
12 @implementation PBWebHistoryController
18 startFile = @"history";
19 repository = historyController.repository;
21 [historyController addObserver:self forKeyPath:@"webCommit" options:0 context:@"ChangedCommit"];
27 [self changeContentTo: historyController.webCommit];
30 - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
32 if ([(NSString *)context isEqualToString: @"ChangedCommit"])
33 [self changeContentTo: historyController.webCommit];
35 [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
38 - (void) changeContentTo: (PBGitCommit *) content
40 if (content == nil || !finishedLoading)
43 // The sha is the same, but refs may have changed.. reload it lazy
44 if ([currentSha isEqualToString: [content realSha]])
46 [[self script] callWebScriptMethod:@"reload" withArguments: nil];
49 currentSha = [content realSha];
51 NSArray *arguments = [NSArray arrayWithObjects:content, [[[historyController repository] headRef] simpleRef], nil];
52 [[self script] callWebScriptMethod:@"loadCommit" withArguments: arguments];
54 // Now we load the extended details. We used to do this in a separate thread,
55 // but this caused some funny behaviour because NSTask's and NSThread's don't really
56 // like each other. Instead, just do it async.
58 NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects:@"show", @"--pretty=raw", @"-M", @"--no-color", currentSha, nil];
59 if (![PBGitDefaults showWhitespaceDifferences])
60 [taskArguments insertObject:@"-w" atIndex:1];
62 NSFileHandle *handle = [repository handleForArguments:taskArguments];
63 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
64 // Remove notification, in case we have another one running
65 [nc removeObserver:self];
66 [nc addObserver:self selector:@selector(commitDetailsLoaded:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle];
67 [handle readToEndOfFileInBackgroundAndNotify];
70 - (void)commitDetailsLoaded:(NSNotification *)notification
72 NSData *data = [[notification userInfo] valueForKey:NSFileHandleNotificationDataItem];
76 NSString *details = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
78 details = [[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
83 [[view windowScriptObject] callWebScriptMethod:@"loadCommitDetails" withArguments:[NSArray arrayWithObject:details]];
86 - (void) selectCommit: (NSString*) sha
88 [historyController selectCommit:sha];
91 - (void) sendKey: (NSString*) key
93 id script = [view windowScriptObject];
94 [script callWebScriptMethod:@"handleKeyFromCocoa" withArguments: [NSArray arrayWithObject:key]];
99 NSString *source = [(DOMHTMLElement *)[[[view mainFrame] DOMDocument] documentElement] outerHTML];
100 NSPasteboard *a =[NSPasteboard generalPasteboard];
101 [a declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
102 [a setString:source forType: NSStringPboardType];
105 - (NSArray *) webView:(WebView *)sender
106 contextMenuItemsForElement:(NSDictionary *)element
107 defaultMenuItems:(NSArray *)defaultMenuItems
109 DOMNode *node = [element valueForKey:@"WebElementDOMNode"];
112 // Every ref has a class name of 'refs' and some other class. We check on that to see if we pressed on a ref.
113 if ([[node className] hasPrefix:@"refs "]) {
114 NSString *selectedRefString = [[[node childNodes] item:0] textContent];
115 for (PBGitRef *ref in historyController.webCommit.refs)
117 if ([[ref shortName] isEqualToString:selectedRefString])
118 return [contextMenuDelegate menuItemsForRef:ref commit:historyController.webCommit];
120 NSLog(@"Could not find selected ref!");
121 return defaultMenuItems;
123 if ([node hasAttributes] && [[node attributes] getNamedItem:@"representedFile"])
124 return [historyController menuItemsForPaths:[NSArray arrayWithObject:[[[node attributes] getNamedItem:@"representedFile"] value]]];
126 node = [node parentNode];
129 return defaultMenuItems;
133 // Open external links in the default browser
134 - (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation
135 request:(NSURLRequest *)request
136 newFrameName:(NSString *)frameName
137 decisionListener:(id < WebPolicyDecisionListener >)listener
139 [[NSWorkspace sharedWorkspace] openURL:[request URL]];
142 - getConfig:(NSString *)config
144 return [historyController valueForKeyPath:[@"repository.config." stringByAppendingString:config]];
149 [historyController removeObserver:self forKeyPath:@"webCommit"];
153 - (void) preferencesChanged
155 [[self script] callWebScriptMethod:@"enableFeatures" withArguments:nil];