| | 125 | } |
| | 126 | } |
| | 127 | |
| | 128 | , addCommitterRecentCommits : function () { |
| | 129 | if (location.pathname.match(/wiki\/Committers\/([^\/]+)/)) { |
| | 130 | var author = RegExp.$1; |
| | 131 | $.get(TracUtils.TRAC_BASE + "/log/?limit=100&mode=stop_on_copy&format=changelog", {}, function (data) { |
| | 132 | var parser = new ChageLogParser(ChageLogParser.Trac); |
| | 133 | var log = parser.parse(data); |
| | 134 | var div = $("<div class='recent-commits'><h2>Recent Commits</h2></div>"); |
| | 135 | var n = 0; |
| | 136 | for (var i = 0; i < log.length; i++) { |
| | 137 | var item = log[i]; |
| | 138 | if (item.author == author) { |
| | 139 | // why not have inject function. |
| | 140 | var t = {}; $.each(item.paths, function (_, i) { |
| | 141 | t[i.path.split("/").slice(0, 3).join("/")] = true; |
| | 142 | }); |
| | 143 | item.paths = []; |
| | 144 | for (var j in t) if (t.hasOwnProperty(j)) item.paths.push(j); |
| | 145 | $("<div class='commit'></div>") |
| | 146 | .append( |
| | 147 | $("<a class='revision'>["+item.revision+"]</a>") |
| | 148 | .attr("href", TracUtils.TRAC_BASE + "/changeset/" + item.revision) |
| | 149 | ) |
| | 150 | .append(" ") |
| | 151 | .append("<span class='path'>" + item.paths.join(", ") +"</span>") |
| | 152 | .append("<div class='message'>"+ item.message +"</div>") |
| | 153 | .appendTo(div); |
| | 154 | n++; |
| | 155 | if (n > 5) break; |
| | 156 | } |
| | 157 | } |
| | 158 | if (n == 0) div.append("<span class='none'>none...</span>"); |
| | 159 | $("#searchable").append(div); |
| | 160 | }); |
| 210 | | $(function () { |
| 211 | | TracUtils.installAll(); |
| 212 | | }); |
| 213 | | |
| | 251 | |
| | 252 | /* |
| | 253 | * Copied lib |
| | 254 | */ |
| | 255 | |
| | 256 | function ChageLogParser (callback) { |
| | 257 | this.initialize.apply(this, arguments); |
| | 258 | } |
| | 259 | |
| | 260 | ChageLogParser.prototype = { |
| | 261 | initialize : function (callback) { |
| | 262 | if (!callback) callback = function (title, body) { |
| | 263 | return ({ |
| | 264 | title: title, |
| | 265 | body : body |
| | 266 | }) |
| | 267 | }; |
| | 268 | this.callback = callback; |
| | 269 | }, |
| | 270 | |
| | 271 | parse : function (str) { |
| | 272 | var ret = [], cur = null; |
| | 273 | var lines = str.split(/\n/); |
| | 274 | for (var i = 0; i < lines.length; i++) { |
| | 275 | var line = lines[i]; |
| | 276 | if (line.indexOf("\t") == 0) { |
| | 277 | cur.body.push(line.substring(1)); |
| | 278 | } else |
| | 279 | if (line.indexOf("#") == 0) { |
| | 280 | continue; // skip comment |
| | 281 | } else |
| | 282 | if (line.length == 0) { |
| | 283 | continue; |
| | 284 | } else { |
| | 285 | if (cur) ret.push(this.callback(cur.title, cur.body)); |
| | 286 | cur = { |
| | 287 | title : line, |
| | 288 | body : [] |
| | 289 | }; |
| | 290 | } |
| | 291 | } |
| | 292 | if (cur) ret.push(this.callback(cur.title, cur.body)); |
| | 293 | return ret; |
| | 294 | } |
| | 295 | }; |
| | 296 | ChageLogParser.Trac = function (title, body) { |
| | 297 | var m = title.match(/(\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d):(\d\d) ([^\s]+) \[(\d+)\]/); |
| | 298 | var d = new Date(+m[3] + 2000, +m[1] - 1, +m[2], +m[4], +m[5], +m[6]); |
| | 299 | var author = m[7], revision = +m[8]; |
| | 300 | |
| | 301 | var paths = [], message = []; |
| | 302 | for (var i = 0; i < body.length; i++) { |
| | 303 | if (body[i].indexOf("*") == 0) { |
| | 304 | var m = body[i].match(/^\* ([^\s]+) \(([^\)]+)\)/); |
| | 305 | if (m) { |
| | 306 | paths.push({ action : m[2], path : m[1]}); |
| | 307 | } else { |
| | 308 | message.push(body[i]); |
| | 309 | } |
| | 310 | } else { |
| | 311 | message.push(body[i]); |
| | 312 | } |
| | 313 | } |
| | 314 | |
| | 315 | return { |
| | 316 | date : d, |
| | 317 | author : author, |
| | 318 | revision : revision, |
| | 319 | message : message.join("\n"), |
| | 320 | paths : paths |
| | 321 | } |
| | 322 | }; |