gitweb: Colorize 'blame_incremental' view during processing
This requires using 3 colors, not only two, to choose a color that is different from colors of up to 2 neighbors. gitweb.js selects the least used color, if more than one color is possible. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jakub Narebski committed
Sep 1, 2009 at 13:39 UTC
e206d62a922d80f2d00427ddfb93435adbf1cc59
2 files changed
+110
-3
gitweb/gitweb.css
+5
@@ -257,6 +257,11 @@ tr.no-previous td.linenr {
257
font-weight: bold;
258
}
259
260
+/* for 'blame_incremental', during processing */
261
+tr.color1 { background-color: #f6fff6; }
262
+tr.color2 { background-color: #f6f6ff; }
263
+tr.color3 { background-color: #fff6f6; }
264
+
265
td {
266
padding: 2px 5px;
267
font-size: 100%;
gitweb/gitweb.js
+105
-3
@@ -210,6 +210,101 @@ function errorInfo(str) {
210
}
211
}
212
213
+/* ............................................................ */
214
+/* coloring rows during blame_data (git blame --incremental) run */
215
+
216
+/**
217
+ * used to extract N from 'colorN', where N is a number,
218
+ * @constant
219
+ */
220
+var colorRe = /\bcolor([0-9]*)\b/;
221
+
222
+/**
223
+ * return N if <tr class="colorN">, otherwise return null
224
+ * (some browsers require CSS class names to begin with letter)
225
+ *
226
+ * @param {HTMLElement} tr: table row element to check
227
+ * @param {String} tr.className: 'class' attribute of tr element
228
+ * @returns {Number|null} N if tr.className == 'colorN', otherwise null
229
+ *
230
+ * @globals colorRe
231
+ */
232
+function getColorNo(tr) {
233
+ if (!tr) {
234
+ return null;
235
+ }
236
+ var className = tr.className;
237
+ if (className) {
238
+ var match = colorRe.exec(className);
239
+ if (match) {
240
+ return parseInt(match[1], 10);
241
+ }
242
+ }
243
+ return null;
244
+}
245
+
246
+var colorsFreq = [0, 0, 0];
247
+/**
248
+ * return one of given possible colors (curently least used one)
249
+ * example: chooseColorNoFrom(2, 3) returns 2 or 3
250
+ *
251
+ * @param {Number[]} arguments: one or more numbers
252
+ * assumes that 1 <= arguments[i] <= colorsFreq.length
253
+ * @returns {Number} Least used color number from arguments
254
+ * @globals colorsFreq
255
+ */
256
+function chooseColorNoFrom() {
257
+ // choose the color which is least used
258
+ var colorNo = arguments[0];
259
+ for (var i = 1; i < arguments.length; i++) {
260
+ if (colorsFreq[arguments[i]-1] < colorsFreq[colorNo-1]) {
261
+ colorNo = arguments[i];
262
+ }
263
+ }
264
+ colorsFreq[colorNo-1]++;
265
+ return colorNo;
266
+}
267
+
268
+/**
269
+ * given two neigbour <tr> elements, find color which would be different
270
+ * from color of both of neighbours; used to 3-color blame table
271
+ *
272
+ * @param {HTMLElement} tr_prev
273
+ * @param {HTMLElement} tr_next
274
+ * @returns {Number} color number N such that
275
+ * colorN != tr_prev.className && colorN != tr_next.className
276
+ */
277
+function findColorNo(tr_prev, tr_next) {
278
+ var color_prev = getColorNo(tr_prev);
279
+ var color_next = getColorNo(tr_next);
280
+
281
+
282
+ // neither of neighbours has color set
283
+ // THEN we can use any of 3 possible colors
284
+ if (!color_prev && !color_next) {
285
+ return chooseColorNoFrom(1,2,3);
286
+ }
287
+
288
+ // either both neighbours have the same color,
289
+ // or only one of neighbours have color set
290
+ // THEN we can use any color except given
291
+ var color;
292
+ if (color_prev === color_next) {
293
+ color = color_prev; // = color_next;
294
+ } else if (!color_prev) {
295
+ color = color_next;
296
+ } else if (!color_next) {
297
+ color = color_prev;
298
+ }
299
+ if (color) {
300
+ return chooseColorNoFrom((color % 3) + 1, ((color+1) % 3) + 1);
301
+ }
302
+
303
+ // neighbours have different colors
304
+ // THEN there is only one color left
305
+ return (3 - ((color_prev + color_next) % 3));
306
+}
307
+
308
/* ............................................................ */
309
/* coloring rows like 'blame' after 'blame_data' finishes */
310
@@ -224,8 +319,6 @@ function isStartOfGroup(tr) {
319
return tr.firstChild.className === 'sha1';
320
}
321
227
-var colorRe = /(?:light|dark)/;
228
-
322
/**
323
* change colors to use zebra coloring (2 colors) instead of 3 colors
324
* concatenate neighbour commit groups belonging to the same commit
@@ -391,6 +484,12 @@ function handleLine(commit, group) {
484
formatDateISOLocal(commit.authorTime, commit.authorTimezone);
485
}
486
487
+ // color depends on group of lines, not only on blamed commit
488
+ var colorNo = findColorNo(
489
+ document.getElementById('l'+(resline-1)),
490
+ document.getElementById('l'+(resline+group.numlines))
491
+ );
492
+
493
// loop over lines in commit group
494
for (var i = 0; i < group.numlines; i++, resline++) {
495
var tr = document.getElementById('l'+resline);
@@ -409,7 +508,10 @@ function handleLine(commit, group) {
508
var a_linenr = td_sha1.nextSibling.firstChild;
509
510
/* <tr id="l123" class=""> */
412
- var tr_class = 'light'; // or tr.className
511
+ var tr_class = '';
512
+ if (colorNo !== null) {
513
+ tr_class = 'color'+colorNo;
514
+ }
515
if (commit.boundary) {
516
tr_class += ' boundary';
517
}