9
9
#import " PBWebHistoryController.h"
10
10
#import " PBGitDefaults.h"
11
11
#import " PBGitSHA.h"
12
+ #import " GLFileView.h"
13
+ #import < CommonCrypto/CommonDigest.h>
12
14
13
15
@implementation PBWebHistoryController
14
16
@@ -26,7 +28,7 @@ - (void)closeView
26
28
{
27
29
[[self script ] setValue: nil forKey: @" commit" ];
28
30
[historyController removeObserver: self forKeyPath: @" webCommit" ];
29
-
31
+
30
32
[super closeView ];
31
33
}
32
34
@@ -48,31 +50,17 @@ - (void) changeContentTo: (PBGitCommit *) content
48
50
{
49
51
if (content == nil || !finishedLoading)
50
52
return ;
51
-
52
- // The sha is the same, but refs may have changed.. reload it lazy
53
- if ([currentSha isEqual: [content sha ]])
54
- {
55
- [[self script ] callWebScriptMethod: @" reload" withArguments: nil ];
56
- return ;
57
- }
58
-
59
- NSArray *arguments = [NSArray arrayWithObjects: content, [[[historyController repository ] headRef ] simpleRef ], nil ];
60
- id scriptResult = [[self script ] callWebScriptMethod: @" loadCommit" withArguments: arguments];
61
- if (!scriptResult) {
62
- // the web view is not really ready for scripting???
63
- [self performSelector: _cmd withObject: content afterDelay: 0.05 ];
64
- return ;
65
- }
53
+
66
54
currentSha = [content sha ];
67
-
55
+
68
56
// Now we load the extended details. We used to do this in a separate thread,
69
57
// but this caused some funny behaviour because NSTask's and NSThread's don't really
70
58
// like each other. Instead, just do it async.
71
-
72
- NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects: @" show" , @" --pretty=raw " , @" -M " , @" --no-color " , [currentSha string ], nil ];
59
+
60
+ NSMutableArray *taskArguments = [NSMutableArray arrayWithObjects: @" show" , @" --summary " , @" --pretty=raw " , [currentSha string ], nil ];
73
61
if (![PBGitDefaults showWhitespaceDifferences ])
74
62
[taskArguments insertObject: @" -w" atIndex: 1 ];
75
-
63
+
76
64
NSFileHandle *handle = [repository handleForArguments: taskArguments];
77
65
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter ];
78
66
// Remove notification, in case we have another one running
@@ -84,25 +72,122 @@ - (void) changeContentTo: (PBGitCommit *) content
84
72
- (void )commitDetailsLoaded : (NSNotification *)notification
85
73
{
86
74
[[NSNotificationCenter defaultCenter ] removeObserver: self name: NSFileHandleReadToEndOfFileCompletionNotification object: nil ];
87
-
75
+
88
76
NSData *data = [[notification userInfo ] valueForKey: NSFileHandleNotificationDataItem ];
89
77
if (!data)
90
78
return ;
91
-
79
+
92
80
NSString *details = [[NSString alloc ] initWithData: data encoding: NSUTF8StringEncoding];
93
81
if (!details)
94
82
details = [[NSString alloc ] initWithData: data encoding: NSISOLatin1StringEncoding];
95
-
83
+
96
84
if (!details)
97
85
return ;
86
+
87
+
88
+ NSMutableString *refs=[NSMutableString string ];
89
+ NSArray *refsA=[historyController.webCommit refs ];
90
+ NSString *currentRef=[[[historyController repository ] headRef ] simpleRef ];
91
+ NSString *style=@" " ;
92
+ int r=0 ;
93
+ for (r=0 ;r<[refsA count ];r++){
94
+ PBGitRef *ref=[refsA objectAtIndex: r];
95
+ if ([currentRef isEqualToString: [ref ref ]]){
96
+ style=[NSString stringWithFormat: @" currentBranch refs %@ " ,[ref type ]];
97
+ }else {
98
+ style=[NSString stringWithFormat: @" refs %@ " ,[ref type ]];
99
+ }
100
+ [refs appendString: [NSString stringWithFormat: @" <span class='%@ '>%@ </span>" ,style,[ref shortName ]]];
101
+ }
102
+
103
+ // Header
104
+ NSString *header=[self parseHeader: details withRefs: refs];
105
+
106
+ // File list
107
+ NSString *dt=[repository outputInWorkdirForArguments: [NSArray arrayWithObjects: @" diff-tree" , @" -r" , @" -C90%" , @" -M90%" , [currentSha string ], nil ]];
108
+ NSString *fileList=[GLFileView parseDiffTree: dt];
109
+
110
+ // Diffs list
111
+ NSString *d=[repository outputInWorkdirForArguments: [NSArray arrayWithObjects: @" diff-tree" , @" --cc" , @" -C90%" , @" -M90%" , [currentSha string ], nil ]];
112
+ NSString *diffs=[GLFileView parseDiff: d];
113
+
114
+ NSString *html=[NSString stringWithFormat: @" %@%@%@ " ,header,fileList,diffs];
115
+
116
+ [[view windowScriptObject ] callWebScriptMethod: @" showDiff" withArguments: [NSArray arrayWithObject: html]];
117
+
118
+ #if 1
119
+ NSString *dom=[[[[view mainFrame ] DOMDocument ] documentElement ] outerHTML ];
120
+ NSString *tmpFile=@" ~/tmp/test2.html" ;
121
+ [dom writeToFile: [tmpFile stringByExpandingTildeInPath ] atomically: true encoding: NSUTF8StringEncoding error: nil ];
122
+ #endif
123
+ }
124
+
125
+ - (NSString *)parseHeader : (NSString *)txt withRefs : (NSString *)badges
126
+ {
127
+ NSArray *lines = [txt componentsSeparatedByString: @" \n " ];
128
+ NSString *line;
129
+ NSString *last_mail=@" " ;
130
+ NSMutableString *auths=[NSMutableString string ];
131
+ NSMutableString *refs=[NSMutableString string ];
132
+ NSMutableString *subject=[NSMutableString string ];
133
+ BOOL subj=FALSE ;
134
+
135
+ int i;
136
+ for (i=0 ; i<[lines count ]; i++) {
137
+ line=[lines objectAtIndex: i];
138
+ if ([line length ]==0 ){
139
+ if (!subj){
140
+ subj=TRUE ;
141
+ }else {
142
+ i=[lines count ];
143
+ }
144
+ }else {
145
+ if (subj) {
146
+ [subject appendString: [NSString stringWithFormat: @" %@ <br/>" ,[line stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet ]]]];
147
+ }else {
148
+ NSArray *comps=[line componentsSeparatedByString: @" " ];
149
+ if ([comps count ]==2 ){
150
+ [refs appendString: [NSString stringWithFormat: @" <tr><td>%@ </td><td><a href='' onclick='selectCommit(this.innerHTML); return false;'>%@ </a></td></tr>" ,[comps objectAtIndex: 0 ],[comps objectAtIndex: 1 ]]];
151
+ }else if ([comps count ]>2 ){
152
+ NSRange r_email_i = [line rangeOfString: @" <" ];
153
+ NSRange r_email_e = [line rangeOfString: @" >" ];
154
+ NSRange r_name_i = [line rangeOfString: @" " ];
155
+
156
+ NSString *rol=[line substringToIndex: r_name_i.location];
157
+ NSString *name=[line substringWithRange: NSMakeRange (r_name_i.location,(r_email_i.location-r_name_i.location))];
158
+ NSString *email=[line substringWithRange: NSMakeRange (r_email_i.location+1 ,((r_email_e.location-1 )-r_email_i.location))];
159
+ NSString *time=[line substringFromIndex: r_email_e.location+2 ];
160
+
161
+ if (![email isEqualToString: last_mail]){
162
+ [auths appendString: [NSString stringWithFormat: @" <div class='user %@ clearfix'>" ,rol]];
163
+ if ([self isFeatureEnabled: @" gravatar" ]){
164
+ NSString *hash=[self someMethodThatReturnsSomeHashForSomeString: email];
165
+ [auths appendString: [NSString stringWithFormat: @" <img class='avatar' src='http://www.gravatar.com/avatar/%@ ?d=wavatar&s=30'/>" ,hash]];
166
+ }
167
+ [auths appendString: [NSString stringWithFormat: @" <p class='name'>%@ <span class='rol'>(%@ )</span></p>" ,name,rol]];
168
+ [auths appendString: [NSString stringWithFormat: @" <p class='time'>%@ </p></div>" ,time]];
169
+ }
170
+ last_mail=email;
171
+ }
172
+ }
173
+ }
174
+ }
175
+
176
+ return [NSString stringWithFormat: @" <div id='header' class='clearfix'><table class='references'>%@ </table><p class='subject'>%@ </p>%@ <div id='badges'>%@ </div></div>" ,refs,subject,auths,badges];
177
+ }
98
178
99
- NSRange range = [details rangeOfString: @" diff --git" ];
100
- NSString *commitDetails=[details substringToIndex: range.location];
101
- NSString *diffs=[details substringFromIndex: range.location];
102
- NSString *pd=[GLFileView parseDiff: diffs];
179
+ - (NSString *) someMethodThatReturnsSomeHashForSomeString : (NSString *)concat {
180
+ const char *concat_str = [concat UTF8String ];
181
+ unsigned char result[CC_MD5_DIGEST_LENGTH];
182
+ CC_MD5 (concat_str, strlen (concat_str), result);
183
+
184
+ NSMutableString *hash = [NSMutableString string ];
185
+
186
+ int i;
187
+ for (i = 0 ; i < 16 ; i++)
188
+ [hash appendFormat: @" %02x " , result[i]];
103
189
104
- [[view windowScriptObject ] callWebScriptMethod: @" loadCommitDetails" withArguments: [NSArray arrayWithObject: commitDetails]];
105
- [[view windowScriptObject ] callWebScriptMethod: @" newStyle" withArguments: [NSArray arrayWithObject: pd]];
190
+ return hash;
106
191
}
107
192
108
193
- (void )selectCommit : (NSString *)sha
@@ -126,10 +211,10 @@ - (void) copySource
126
211
127
212
- (NSArray *) webView : (WebView *)sender
128
213
contextMenuItemsForElement : (NSDictionary *)element
129
- defaultMenuItems : (NSArray *)defaultMenuItems
214
+ defaultMenuItems : (NSArray *)defaultMenuItems
130
215
{
131
216
DOMNode *node = [element valueForKey: @" WebElementDOMNode" ];
132
-
217
+
133
218
while (node) {
134
219
// Every ref has a class name of 'refs' and some other class. We check on that to see if we pressed on a ref.
135
220
if ([[node className ] hasPrefix: @" refs " ]) {
@@ -144,27 +229,27 @@ - (NSArray *) webView:(WebView *)sender
144
229
}
145
230
if ([node hasAttributes ] && [[node attributes ] getNamedItem: @" representedFile" ])
146
231
return [historyController menuItemsForPaths: [NSArray arrayWithObject: [[[node attributes ] getNamedItem: @" representedFile" ] value ]]];
147
- else if ([[node class ] isEqual: [DOMHTMLImageElement class ]]) {
148
- // Copy Image is the only menu item that makes sense here since we don't need
232
+ else if ([[node class ] isEqual: [DOMHTMLImageElement class ]]) {
233
+ // Copy Image is the only menu item that makes sense here since we don't need
149
234
// to download the image or open it in a new window (besides with the
150
235
// current implementation these two entries can crash GitX anyway)
151
236
for (NSMenuItem *item in defaultMenuItems)
152
237
if ([item tag ] == WebMenuItemTagCopyImageToClipboard )
153
238
return [NSArray arrayWithObject: item];
154
239
return nil ;
155
- }
156
-
240
+ }
241
+
157
242
node = [node parentNode ];
158
243
}
159
-
244
+
160
245
return defaultMenuItems;
161
246
}
162
247
163
248
164
249
// Open external links in the default browser
165
250
- (void )webView : (WebView *)sender decidePolicyForNewWindowAction : (NSDictionary *)actionInformation
166
- request : (NSURLRequest *)request
167
- newFrameName : (NSString *)frameName
251
+ request : (NSURLRequest *)request
252
+ newFrameName : (NSString *)frameName
168
253
decisionListener : (id < WebPolicyDecisionListener >)listener
169
254
{
170
255
[[NSWorkspace sharedWorkspace ] openURL: [request URL ]];
0 commit comments