git-object-browser 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +17 -0
- data/htdocs/{css → common/css}/angular-ui.min.css +0 -0
- data/htdocs/{css → common/css}/bootstrap-responsive.css +0 -0
- data/htdocs/{css → common/css}/bootstrap-responsive.min.css +0 -0
- data/htdocs/{css → common/css}/bootstrap.css +0 -0
- data/htdocs/{css → common/css}/bootstrap.min.css +0 -0
- data/htdocs/{css → common/css}/font-awesome-ie7.css +0 -0
- data/htdocs/{css → common/css}/font-awesome.css +0 -0
- data/htdocs/{css → common/css}/main.css +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.eot +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.svg +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.ttf +0 -0
- data/htdocs/{font → common/font}/fontawesome-webfont.woff +0 -0
- data/htdocs/{img → common/img}/glyphicons-halflings-white.png +0 -0
- data/htdocs/{img → common/img}/glyphicons-halflings.png +0 -0
- data/htdocs/common/js/main.js +495 -0
- data/htdocs/{js → common/js}/vendor/angular-bootstrap-prettify.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-bootstrap.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-cookies.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-loader.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-resource.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-sanitize.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-ui-ieshiv.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular-ui.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular.js +0 -0
- data/htdocs/{js → common/js}/vendor/angular.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/bootstrap.js +0 -0
- data/htdocs/{js → common/js}/vendor/bootstrap.min.js +0 -0
- data/htdocs/{js → common/js}/vendor/html5shiv.js +0 -0
- data/htdocs/{js → common/js}/vendor/jquery-1.8.2.min.js +0 -0
- data/htdocs/{templates → common/templates}/directory.html +2 -2
- data/htdocs/common/templates/error.html +6 -0
- data/htdocs/{templates → common/templates}/file.html +0 -0
- data/htdocs/{templates → common/templates}/git.html +0 -0
- data/htdocs/{templates → common/templates}/index.html +1 -1
- data/htdocs/{templates → common/templates}/index_entry.html +0 -0
- data/htdocs/{templates → common/templates}/info_refs.html +2 -2
- data/htdocs/{templates → common/templates}/loading.html +0 -0
- data/htdocs/{templates → common/templates}/notfound.html +1 -2
- data/htdocs/{templates → common/templates}/object.html +1 -1
- data/htdocs/{templates → common/templates}/objects.html +3 -3
- data/htdocs/{templates → common/templates}/pack_file.html +1 -1
- data/htdocs/common/templates/pack_index.html +39 -0
- data/htdocs/{templates → common/templates}/packed_object.html +4 -4
- data/htdocs/{templates → common/templates}/packed_refs.html +2 -2
- data/htdocs/{templates → common/templates}/ref.html +0 -0
- data/htdocs/common/templates/reflog.html +29 -0
- data/htdocs/config.js +6 -0
- data/htdocs/default.js +7 -0
- data/htdocs/index.html +52 -20
- data/lib/git-object-browser.rb +12 -4
- data/lib/git-object-browser/dumper/directories_dumper.rb +42 -0
- data/lib/git-object-browser/dumper/index_dumper.rb +20 -7
- data/lib/git-object-browser/dumper/info_refs_dumper.rb +37 -0
- data/lib/git-object-browser/dumper/main.rb +188 -81
- data/lib/git-object-browser/dumper/objects_dumper.rb +46 -0
- data/lib/git-object-browser/dumper/pack_indexes_dumper.rb +85 -0
- data/lib/git-object-browser/dumper/packed_objects_dumper.rb +36 -0
- data/lib/git-object-browser/dumper/packed_refs_dumper.rb +37 -0
- data/lib/git-object-browser/dumper/plain_files_dumper.rb +74 -0
- data/lib/git-object-browser/dumper/refs_dumper.rb +46 -0
- data/lib/git-object-browser/main.rb +22 -6
- data/lib/git-object-browser/models/directory.rb +5 -3
- data/lib/git-object-browser/models/git_date.rb +26 -0
- data/lib/git-object-browser/models/git_object.rb +1 -1
- data/lib/git-object-browser/models/pack_file.rb +1 -1
- data/lib/git-object-browser/models/pack_index.rb +139 -25
- data/lib/git-object-browser/models/packed_object.rb +1 -1
- data/lib/git-object-browser/models/reflog.rb +54 -0
- data/lib/git-object-browser/models/wrapped_object.rb +40 -0
- data/lib/git-object-browser/server/git_servlet.rb +130 -100
- data/lib/git-object-browser/server/main.rb +1 -1
- data/lib/git-object-browser/version.rb +1 -1
- metadata +62 -50
- data/htdocs/js/main.js +0 -285
- data/htdocs/templates/pack_index.html +0 -37
- data/lib/git-object-browser/dumper/object_dumper.rb +0 -20
- data/lib/git-object-browser/dumper/pack_index_dumper.rb +0 -21
- data/lib/git-object-browser/dumper/packed_object_dumper.rb +0 -19
data/README.md
CHANGED
@@ -9,6 +9,23 @@ Browse git raw objects.
|
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
|
+
To browse .git directory:
|
13
|
+
|
14
|
+
$ git object-browser ./path/to/project
|
15
|
+
$ open http://localhost:8080/#/.git
|
16
|
+
|
17
|
+
To dump .git directory (dump HTML/JSON/JS app):
|
18
|
+
|
19
|
+
$ git object-browser --dump path/to/dump/dir path/to/project
|
20
|
+
$ ${any_http_server} --port 8080 path/to/dump/dir
|
21
|
+
$ open http://localhost:8080/#/step1/.git/
|
22
|
+
|
23
|
+
To dump .git step by step:
|
24
|
+
|
25
|
+
$ git object-browser --dump path/to/dump/dir --next path/to/project
|
26
|
+
|
27
|
+
this command shows .git diff between previous step and current step.
|
28
|
+
|
12
29
|
## Contributing
|
13
30
|
|
14
31
|
1. Fork it
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,495 @@
|
|
1
|
+
function routingConfig(steps) {
|
2
|
+
return function($routeProvider) {
|
3
|
+
$routeProvider = angular.extend($routeProvider, {
|
4
|
+
|
5
|
+
// AngularJS doesn't support regular expressions in routes.
|
6
|
+
// http://stackoverflow.com/questions/12685085/angularjs-route-how-to-match-star-as-a-path
|
7
|
+
'whenPath': function(path, depth, route) {
|
8
|
+
for (var i = 1; i <= depth; i++) {
|
9
|
+
path += '/:path' + i;
|
10
|
+
this.when(path, route);
|
11
|
+
}
|
12
|
+
return this;
|
13
|
+
}
|
14
|
+
});
|
15
|
+
if (steps.length > 0) {
|
16
|
+
$routeProvider.
|
17
|
+
whenPath('/:basedir/.git', 10, {controller:GitCtrl, templateUrl:'common/templates/git.html'}).
|
18
|
+
otherwise({redirectTo:'/' + steps[0].name + '/.git/'});
|
19
|
+
} else {
|
20
|
+
$routeProvider.
|
21
|
+
whenPath('/.git', 10, {controller:GitCtrl, templateUrl:'common/templates/git.html'}).
|
22
|
+
otherwise({redirectTo:'/.git/'});
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
angular.module('GitObjectBrowser', ['ngResource'])
|
28
|
+
.config(routingConfig(config.steps))
|
29
|
+
|
30
|
+
.directive('scrollBottom', function() {
|
31
|
+
return function(scope, elm, attr) {
|
32
|
+
var rawDomElement = elm[0];
|
33
|
+
angular.element(window).unbind('scroll');
|
34
|
+
angular.element(window).bind('scroll', function() {
|
35
|
+
if (! scope.scrollBottomEnabled) return;
|
36
|
+
|
37
|
+
var rectObject = rawDomElement.getBoundingClientRect();
|
38
|
+
if (rectObject.bottom - window.innerHeight < 50) {
|
39
|
+
scope.$apply(attr.scrollBottom);
|
40
|
+
}
|
41
|
+
});
|
42
|
+
};
|
43
|
+
})
|
44
|
+
|
45
|
+
.directive('entryIcon', function($parse) {
|
46
|
+
return function(scope, element, attrs) {
|
47
|
+
var icons = {
|
48
|
+
'directory': 'icon-folder-open',
|
49
|
+
'ref': 'icon-map-marker',
|
50
|
+
'reflog': 'icon-file',
|
51
|
+
'info_refs': 'icon-map-marker',
|
52
|
+
'packed_refs': 'icon-map-marker',
|
53
|
+
'index': 'icon-list',
|
54
|
+
'file': 'icon-file',
|
55
|
+
'object': 'icon-comment',
|
56
|
+
'blob': 'icon-file',
|
57
|
+
'tree': 'icon-folder-open',
|
58
|
+
'commit': 'icon-ok',
|
59
|
+
'tag': 'icon-tag',
|
60
|
+
'ofs_delta': 'icon-arrow-up',
|
61
|
+
'ref_delta': 'icon-arrow-down'
|
62
|
+
};
|
63
|
+
|
64
|
+
var entryType = ($parse(attrs.entryIcon))(scope);
|
65
|
+
element.addClass(icons[entryType]);
|
66
|
+
}
|
67
|
+
})
|
68
|
+
|
69
|
+
.directive('modeIcon', function($parse) {
|
70
|
+
return function(scope, element, attrs) {
|
71
|
+
var mode = ($parse(attrs.modeIcon))(scope);
|
72
|
+
var iconClass;
|
73
|
+
if (120000 <= mode) {
|
74
|
+
iconClass = 'icon-share-alt';
|
75
|
+
} else if (100000 <= mode) {
|
76
|
+
iconClass = 'icon-file';
|
77
|
+
} else {
|
78
|
+
iconClass = 'icon-folder-open';
|
79
|
+
}
|
80
|
+
element.addClass(iconClass);
|
81
|
+
}
|
82
|
+
})
|
83
|
+
|
84
|
+
.directive('refHref', function($parse, $rootScope) {
|
85
|
+
return function(scope, element, attrs) {
|
86
|
+
var entry = ($parse(attrs.refHref))(scope);
|
87
|
+
var href = "";
|
88
|
+
var sha1 = null;
|
89
|
+
|
90
|
+
if (typeof(entry) == 'string') {
|
91
|
+
sha1 = entry;
|
92
|
+
} else if (entry && entry.sha1) {
|
93
|
+
sha1 = entry.sha1;
|
94
|
+
}
|
95
|
+
|
96
|
+
if (sha1 !== null) {
|
97
|
+
href = '#' + $rootScope.basedir + '/.git/objects/' + sha1.substr(0, 2) + '/' + sha1.substr(2);
|
98
|
+
} else if (entry && entry.ref) {
|
99
|
+
href = '#' + $rootScope.basedir + '/.git/' + entry.ref;
|
100
|
+
}
|
101
|
+
|
102
|
+
element.attr('href', href);
|
103
|
+
}
|
104
|
+
})
|
105
|
+
|
106
|
+
.filter('unixtime', function($filter) {
|
107
|
+
return function(input, format) {
|
108
|
+
return ($filter('date'))(input * 1000, format);
|
109
|
+
}
|
110
|
+
});
|
111
|
+
|
112
|
+
function GitCtrl($scope, $location, $routeParams, $rootScope, $resource, $http) {
|
113
|
+
if (! $rootScope.diffCache) $rootScope.diffCache = {};
|
114
|
+
if (! $rootScope.noteCache) $rootScope.noteCache = {};
|
115
|
+
|
116
|
+
// reset scrollBottom event handler
|
117
|
+
angular.element(window).unbind('scroll');
|
118
|
+
|
119
|
+
var objectTable = function(entries) {
|
120
|
+
var rows = [];
|
121
|
+
var hash = {};
|
122
|
+
|
123
|
+
angular.forEach(entries, function(entry) {
|
124
|
+
hash[entry.basename] = entry;
|
125
|
+
})
|
126
|
+
|
127
|
+
var hex = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
|
128
|
+
for (var i = 0; i < 16; i++) {
|
129
|
+
var cols = [];
|
130
|
+
for (var j = 0; j < 16; j++) {
|
131
|
+
if (hash[hex[i] + hex[j]]) {
|
132
|
+
cols[j] = hash[hex[i] + hex[j]];
|
133
|
+
} else {
|
134
|
+
cols[j] = {'basename': hex[i] + hex[j], 'type': 'empty'};
|
135
|
+
}
|
136
|
+
}
|
137
|
+
rows[i] = cols;
|
138
|
+
}
|
139
|
+
return rows;
|
140
|
+
}
|
141
|
+
|
142
|
+
var findIndexEntry = function(sha1) {
|
143
|
+
var entries = $scope.object.entries;
|
144
|
+
var entry = null;
|
145
|
+
angular.forEach(entries, function(value) {
|
146
|
+
if (value.sha1 == sha1) {
|
147
|
+
entry = value;
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
});
|
151
|
+
return entry;
|
152
|
+
};
|
153
|
+
|
154
|
+
var indexEntryKeys = function(version) {
|
155
|
+
var keys = [
|
156
|
+
'ctime',
|
157
|
+
'cnano',
|
158
|
+
'mtime',
|
159
|
+
'mnano',
|
160
|
+
'dev',
|
161
|
+
'ino',
|
162
|
+
'object_type',
|
163
|
+
'unix_permission',
|
164
|
+
'uid',
|
165
|
+
'gid',
|
166
|
+
'size',
|
167
|
+
'sha1',
|
168
|
+
'assume_valid_flag',
|
169
|
+
'extended_flag',
|
170
|
+
'stage',
|
171
|
+
'name_length'
|
172
|
+
]
|
173
|
+
if (version > 2) {
|
174
|
+
keys = keys.concat([
|
175
|
+
'skip_worktree',
|
176
|
+
'intent_to_add',
|
177
|
+
]);
|
178
|
+
}
|
179
|
+
keys.push('path')
|
180
|
+
|
181
|
+
return keys;
|
182
|
+
};
|
183
|
+
|
184
|
+
var resourceLoaded = function(json) {
|
185
|
+
$scope.workingdir = json.workingdir;
|
186
|
+
$scope.root = json.root;
|
187
|
+
$scope.gitPath = json.path;
|
188
|
+
if (json.path == "") {
|
189
|
+
$scope.path = ".git";
|
190
|
+
} else {
|
191
|
+
$scope.path = ".git/" + json.path;
|
192
|
+
}
|
193
|
+
$scope.object = json.object;
|
194
|
+
$scope.keys = indexEntryKeys($scope.object.version);
|
195
|
+
var template;
|
196
|
+
if (json.path == "objects") {
|
197
|
+
template = "objects";
|
198
|
+
$scope.objectTable = objectTable($scope.object.entries);
|
199
|
+
loadDiffData();
|
200
|
+
} else if (json.type == "index" && $routeParams.sha1) {
|
201
|
+
template = "index_entry";
|
202
|
+
$scope.entry = findIndexEntry($routeParams.sha1);
|
203
|
+
} else if (json.type == "packed_refs" && $routeParams.ref) {
|
204
|
+
template = json.type;
|
205
|
+
var entries = [];
|
206
|
+
angular.forEach($scope.object.entries, function(entry) {
|
207
|
+
if (entry.ref == $routeParams.ref) {
|
208
|
+
entries.push(entry);
|
209
|
+
$scope.limited = true;
|
210
|
+
}
|
211
|
+
});
|
212
|
+
$scope.object.entries = entries;
|
213
|
+
} else if (json.type == "packed_object") {
|
214
|
+
template = json.type;
|
215
|
+
$scope.unpacked = json.unpacked;
|
216
|
+
} else if (json.type == "directory") {
|
217
|
+
template = json.type;
|
218
|
+
loadDiffData();
|
219
|
+
} else {
|
220
|
+
template = json.type;
|
221
|
+
}
|
222
|
+
|
223
|
+
$scope.template = 'common/templates/' + template + '.html';
|
224
|
+
};
|
225
|
+
|
226
|
+
var loadNote = function() {
|
227
|
+
if (! config.loadNote) return;
|
228
|
+
var basedir, url;
|
229
|
+
if ($rootScope.basedir) {
|
230
|
+
basedir = $rootScope.basedir;
|
231
|
+
url = 'notes' + basedir + '.html';
|
232
|
+
} else {
|
233
|
+
basedir = '';
|
234
|
+
url = 'note.html';
|
235
|
+
}
|
236
|
+
if ($rootScope.noteCache[basedir] !== undefined) {
|
237
|
+
$rootScope.note = $rootScope.noteCache[basedir];
|
238
|
+
return;
|
239
|
+
}
|
240
|
+
$http.get(url)
|
241
|
+
.success(function(data) {
|
242
|
+
$rootScope.noteCache[basedir] = data;
|
243
|
+
$rootScope.note = data;
|
244
|
+
}).error(function() {
|
245
|
+
$rootScope.noteCache[basedir] = '';
|
246
|
+
$rootScope.note = null;
|
247
|
+
});
|
248
|
+
};
|
249
|
+
|
250
|
+
var loadDiffData = function() {
|
251
|
+
if (! config.loadDiff) return;
|
252
|
+
var stepPath = $rootScope.basedir;
|
253
|
+
if (! stepPath) return;
|
254
|
+
|
255
|
+
$scope.diff = {}
|
256
|
+
var base = '.git/';
|
257
|
+
if ($scope.object.path !== '') {
|
258
|
+
base = base + $scope.object.path + '/';
|
259
|
+
}
|
260
|
+
angular.forEach($scope.object.entries, function(entry) {
|
261
|
+
$scope.diff[base + entry.basename] = null;
|
262
|
+
});
|
263
|
+
|
264
|
+
var cache = $rootScope.diffCache[stepPath];
|
265
|
+
if (cache) {
|
266
|
+
diffDataLoaded(cache);
|
267
|
+
return
|
268
|
+
}
|
269
|
+
$http.get('json' + stepPath + '/_diff.json').success(function(diffData) {
|
270
|
+
$rootScope.diffCache[stepPath] = diffData;
|
271
|
+
diffDataLoaded(diffData);
|
272
|
+
}).error(function() {
|
273
|
+
$rootScope.diffCache[stepPath] = [];
|
274
|
+
});
|
275
|
+
};
|
276
|
+
|
277
|
+
var diffDataLoaded = function(data) {
|
278
|
+
var newDiffData = {}
|
279
|
+
angular.forEach($scope.diff, function(value, key) {
|
280
|
+
newDiffData[key] = isDiffEntry(data, key);
|
281
|
+
});
|
282
|
+
$scope.diff = newDiffData;
|
283
|
+
}
|
284
|
+
|
285
|
+
var isDiffEntry = function(data, key) {
|
286
|
+
for(var i = 0; i < data.length; i++) {
|
287
|
+
if (('.git/' + data[i]).indexOf(key) === 0) {
|
288
|
+
return '#fee';
|
289
|
+
}
|
290
|
+
}
|
291
|
+
return null;
|
292
|
+
}
|
293
|
+
|
294
|
+
$scope.resourceError = function(path) {
|
295
|
+
return function(data, status, headers, config) {
|
296
|
+
if (status == 404) {
|
297
|
+
resourceNotFound(path);
|
298
|
+
} else {
|
299
|
+
$scope.status = status;
|
300
|
+
$scope.path = path;
|
301
|
+
$scope.template = 'common/templates/error.html';
|
302
|
+
}
|
303
|
+
};
|
304
|
+
};
|
305
|
+
|
306
|
+
var packedObjectFinder = function(sha1) {
|
307
|
+
var indexes = [];
|
308
|
+
|
309
|
+
var find = function() {
|
310
|
+
$http.get('json' + $rootScope.basedir + '/objects/pack.json')
|
311
|
+
.success(startLoadPackDigest)
|
312
|
+
.error(showNotFound);
|
313
|
+
};
|
314
|
+
|
315
|
+
var startLoadPackDigest = function(json) {
|
316
|
+
angular.forEach(json.object.entries, function(entry) {
|
317
|
+
if (entry.basename.match(/\.idx$/)) {
|
318
|
+
indexes.push(entry);
|
319
|
+
}
|
320
|
+
});
|
321
|
+
loadPackDigest();
|
322
|
+
};
|
323
|
+
|
324
|
+
var loadPackDigest = function() {
|
325
|
+
if (indexes.length == 0) {
|
326
|
+
showNotFound();
|
327
|
+
return;
|
328
|
+
}
|
329
|
+
var entry = indexes.shift();
|
330
|
+
$http.get('json' + $rootScope.basedir + '/objects/pack/' + entry.basename + '.json')
|
331
|
+
.success(findPackObject)
|
332
|
+
.error(showNotFound);
|
333
|
+
};
|
334
|
+
|
335
|
+
var findPackObject = function(json) {
|
336
|
+
var i = 0;
|
337
|
+
angular.forEach(json.object.entries, function(digestSha1) {
|
338
|
+
if (sha1 <= digestSha1) {
|
339
|
+
return;
|
340
|
+
}
|
341
|
+
i++;
|
342
|
+
});
|
343
|
+
|
344
|
+
if (i == 0) {
|
345
|
+
loadPackDigest();
|
346
|
+
return;
|
347
|
+
}
|
348
|
+
|
349
|
+
$http.get('json' + $rootScope.basedir + '/' + json.path + '/sha1/' + i + '.json')
|
350
|
+
.success(loadPagedIndex)
|
351
|
+
.error(showNotFound);
|
352
|
+
};
|
353
|
+
|
354
|
+
var loadPagedIndex = function(json) {
|
355
|
+
var found = false;
|
356
|
+
angular.forEach(json.object.entries, function(entry) {
|
357
|
+
if (entry.sha1 == sha1) {
|
358
|
+
var path = json.path.replace(/.idx$/, '.pack');
|
359
|
+
found = true;
|
360
|
+
$routeParams.offset = entry.offset;
|
361
|
+
loadJson([$rootScope.basedir, path]);
|
362
|
+
}
|
363
|
+
});
|
364
|
+
if (! found) loadPackDigest();
|
365
|
+
}
|
366
|
+
|
367
|
+
find();
|
368
|
+
};
|
369
|
+
|
370
|
+
var resourceNotFound = function(path) {
|
371
|
+
$scope.path = path;
|
372
|
+
if (path.match(/^json\/[^\/]+\/objects\/([0-9a-f]{2})\/([0-9a-f]{38})\.json$/)) {
|
373
|
+
packedObjectFinder(RegExp.$1 + RegExp.$2);
|
374
|
+
} else if (path.match(/^json\/[^\/]+\/(refs\/.+)\.json$/)) {
|
375
|
+
$routeParams.ref = RegExp.$1;
|
376
|
+
loadJson([$rootScope.basedir, 'packed-refs'])
|
377
|
+
} else {
|
378
|
+
$scope.template = 'common/templates/notfound.html';
|
379
|
+
}
|
380
|
+
};
|
381
|
+
|
382
|
+
var showNotFound = function() {
|
383
|
+
$scope.template = 'common/templates/notfound.html';
|
384
|
+
}
|
385
|
+
|
386
|
+
// ['', '/.git/xxx'] or
|
387
|
+
// ['/basedir', '/.git/xxx']
|
388
|
+
var buildPath = function() {
|
389
|
+
var path = '';
|
390
|
+
var basedir = '';
|
391
|
+
if ($routeParams['basedir'] !== undefined) {
|
392
|
+
basedir = '/' + $routeParams['basedir'];
|
393
|
+
}
|
394
|
+
for (var i = 1; i <= 10; i++) {
|
395
|
+
if ($routeParams['path' + i]) {
|
396
|
+
if (i > 1) path += '/';
|
397
|
+
path += $routeParams['path' + i];
|
398
|
+
}
|
399
|
+
}
|
400
|
+
return [basedir, path];
|
401
|
+
}
|
402
|
+
|
403
|
+
var loadJson = function(path) {
|
404
|
+
$rootScope.basedir = path[0];
|
405
|
+
$scope.template = 'common/templates/loading.html';
|
406
|
+
|
407
|
+
if (path[1].match(/^objects\/pack\/pack-[0-9a-f]{40}\.pack$/) && $routeParams.offset) {
|
408
|
+
var offset = '0000' + $routeParams.offset;
|
409
|
+
path = 'json' + path[0] + '/' + path[1]
|
410
|
+
+ '/' + offset.slice(-2)
|
411
|
+
+ '/' + offset.slice(-4, -2)
|
412
|
+
+ '/' + $routeParams.offset + '.json';
|
413
|
+
} else if (path[1].match(/^objects\/pack\/pack-[0-9a-f]{40}\.idx$/)) {
|
414
|
+
var order = $routeParams.order == 'offset' ? 'offset' : 'sha1';
|
415
|
+
var page = $routeParams.page || 1;
|
416
|
+
path = 'json' + path[0] + '/' + path[1] + '/' + order + '/' + page + '.json';
|
417
|
+
} else {
|
418
|
+
if (path[1] == '') path[1] = '_git';
|
419
|
+
path = 'json' + path[0] + '/' + path[1] + '.json';
|
420
|
+
}
|
421
|
+
$http.get(path).success(resourceLoaded).error($scope.resourceError(path));
|
422
|
+
};
|
423
|
+
|
424
|
+
loadJson(buildPath());
|
425
|
+
loadNote();
|
426
|
+
}
|
427
|
+
|
428
|
+
function PackFileCtrl($scope, $location, $routeParams) {
|
429
|
+
$scope.indexUrl = $scope.path.replace(/.pack$/, '.idx');
|
430
|
+
}
|
431
|
+
|
432
|
+
function PackIndexCtrl($scope, $location, $routeParams, $rootScope, $resource, $http) {
|
433
|
+
|
434
|
+
$scope.packUrl = $scope.path.replace(/.idx$/, '.pack');
|
435
|
+
$scope.lastPage = 1;
|
436
|
+
$scope.scrollBottomEnabled = true;
|
437
|
+
|
438
|
+
var resourceLoaded = function(json) {
|
439
|
+
$scope.object.entries = $scope.object.entries.concat(json.object.entries);
|
440
|
+
var last_page = Math.ceil(json.entry_count / json.per_page);
|
441
|
+
$scope.scrollBottomEnabled = (json.page < last_page);
|
442
|
+
$scope.loading = false;
|
443
|
+
}
|
444
|
+
|
445
|
+
$scope.loadNextPage = function() {
|
446
|
+
$scope.lastPage += 1;
|
447
|
+
|
448
|
+
var order = $routeParams.order == 'offset' ? 'offset' : 'sha1';
|
449
|
+
var path = 'json' + $rootScope.basedir + '/' + $scope.gitPath + '/' + order + '/' + $scope.lastPage + '.json';
|
450
|
+
|
451
|
+
$http.get(path).success(resourceLoaded).error($scope.resourceError(path));
|
452
|
+
};
|
453
|
+
|
454
|
+
$scope.scrollBottom = function() {
|
455
|
+
$scope.scrollBottomEnabled = false;
|
456
|
+
$scope.loading = true;
|
457
|
+
$scope.loadNextPage();
|
458
|
+
}
|
459
|
+
|
460
|
+
}
|
461
|
+
|
462
|
+
function MenuCtrl($scope, $location, $routeParams) {
|
463
|
+
$scope.steps = config.steps;
|
464
|
+
|
465
|
+
$scope.stepPrev = function() {
|
466
|
+
var idx = getStepIndex();
|
467
|
+
if (idx.index > 0) {
|
468
|
+
$location.path('/' + $scope.steps[idx.index - 1].name + '/' + idx.file);
|
469
|
+
}
|
470
|
+
}
|
471
|
+
|
472
|
+
$scope.stepNext = function() {
|
473
|
+
var idx = getStepIndex();
|
474
|
+
if (idx.index < $scope.steps.length - 1) {
|
475
|
+
$location.path('/' + $scope.steps[idx.index + 1].name + '/' + idx.file);
|
476
|
+
}
|
477
|
+
}
|
478
|
+
|
479
|
+
var getStepIndex = function() {
|
480
|
+
var path = $location.path();
|
481
|
+
if (! path.match(/\/([^\/]+)\/(.+)/)) return null;
|
482
|
+
|
483
|
+
var stepName = RegExp.$1;
|
484
|
+
var file = RegExp.$2;
|
485
|
+
var obj = { stepName: stepName, file: file, index: 0 };
|
486
|
+
|
487
|
+
for (var i = 0; i < $scope.steps.length; i++) {
|
488
|
+
if (stepName == $scope.steps[i].name) {
|
489
|
+
obj.index = i;
|
490
|
+
return obj;
|
491
|
+
}
|
492
|
+
}
|
493
|
+
return obj;
|
494
|
+
}
|
495
|
+
}
|