1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
// GETs the given url, and schedules the callback to be invoked with the
// response body when it arrives.
//
// In case of problems the callback is invoked with an Error() argument,
// containing the error message.
// TODO: This is ugly, but how else to asynchronously deliver an exceptional
// condition?
//
// Args:
// url: the url to GET
// callback: the function to be invoked with the body or Error as an argument
function getTextAsync(url, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState !== 4)
return;
if (request.status === 200) {
var type = request.getResponseHeader("Content-Type");
if (type.match(/^text/))
callback(request.responseText);
else
// TODO: i18nize
callback(Error('Non-text response received'));
} else {
if (request.statusText == "")
// TODO: i18nize
callback(Error("Unknown error"));
else
callback(Error(request.statusText));
}
};
request.open("GET", url);
request.send(null);
}
// Calculate the number of additions and removals in a diff text.
// Args:
// diff: the text of the diff, optionally including the diff header (i.e. the
// ---/+++ or other lines)
// Returns:
// an array of two elements: number of added lines, number of removed lines.
// On error a null is returned instead of the array
function diffstat(diff) {
if (diff == null)
return null;
var first_hunk_offset = diff.indexOf("\n@@");
var diff_text;
if (first_hunk_offset > 0) {
// Skip the ---/+++ in diff header.
diff_text = diff.substring(first_hunk_offset);
} else {
diff_text = diff;
}
var changes = diff_text.match(/\n[+-]/g);
if (changes == null) {
return null;
}
function count_adds(i, str) { return str == "\n+" ? i + 1 : i }
function count_dels(i, str) { return str == "\n-" ? i + 1 : i }
var additions = changes.reduce(count_adds, 0);
var removals = changes.reduce(count_dels, 0);
return [additions, removals];
}
// Returns an HTML element presenting the given diff text or error object.
//
// Args:
// diff_or_error: the diff text to pass to diffstat() or an error message
// Returns:
// an HTML element, containing information about the argument
function diffstat_pretty(diff_or_error) {
var topspan = document.createElement('span');
topspan.setAttribute('style', 'font-family: monospace');
if (diff_or_error instanceof Error) {
var ret;
ret = document.createElement('span');
ret.setAttribute('title', diff_or_error.message);
ret.innerHTML = ':-(';
topspan.appendChild(ret);
} else {
var counts = diffstat(diff_or_error);
if (counts == null) {
var ret;
ret = document.createElement('span');
ret.setAttribute('title', 'parse error');
ret.innerHTML = ':-(';
topspan.appendChild(ret);
} else {
var ret;
ret = document.createElement('span');
ret.setAttribute('style', 'color: green');
ret.innerHTML = '+' + counts[0];
topspan.appendChild(ret);
// ret = document.createElement('br');
ret = document.createTextNode('/');
topspan.appendChild(ret);
ret = document.createElement('span');
ret.setAttribute('style', 'color: red');
ret.innerHTML = '-' + counts[1];
topspan.appendChild(ret);
}
}
return topspan;
}
|