##// END OF EJS Templates
hgweb: remove unused colorPart() from mercurial.js...
av6 -
r26867:ad443e8d default
parent child Browse files
Show More
@@ -1,443 +1,431
1 1 // mercurial.js - JavaScript utility functions
2 2 //
3 3 // Rendering of branch DAGs on the client side
4 4 // Display of elapsed time
5 5 // Show or hide diffstat
6 6 //
7 7 // Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
8 8 // Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
9 9 //
10 10 // derived from code written by Scott James Remnant <scott@ubuntu.com>
11 11 // Copyright 2005 Canonical Ltd.
12 12 //
13 13 // This software may be used and distributed according to the terms
14 14 // of the GNU General Public License, incorporated herein by reference.
15 15
16 16 var colors = [
17 17 [ 1.0, 0.0, 0.0 ],
18 18 [ 1.0, 1.0, 0.0 ],
19 19 [ 0.0, 1.0, 0.0 ],
20 20 [ 0.0, 1.0, 1.0 ],
21 21 [ 0.0, 0.0, 1.0 ],
22 22 [ 1.0, 0.0, 1.0 ]
23 23 ];
24 24
25 25 function Graph() {
26 26
27 27 this.canvas = document.getElementById('graph');
28 28 if (window.G_vmlCanvasManager) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
29 29 this.ctx = this.canvas.getContext('2d');
30 30 this.ctx.strokeStyle = 'rgb(0, 0, 0)';
31 31 this.ctx.fillStyle = 'rgb(0, 0, 0)';
32 32 this.cur = [0, 0];
33 33 this.line_width = 3;
34 34 this.bg = [0, 4];
35 35 this.cell = [2, 0];
36 36 this.columns = 0;
37 37 this.revlink = '';
38 38
39 39 this.reset = function() {
40 40 this.bg = [0, 4];
41 41 this.cell = [2, 0];
42 42 this.columns = 0;
43 43 document.getElementById('nodebgs').innerHTML = '';
44 44 document.getElementById('graphnodes').innerHTML = '';
45 45 }
46 46
47 47 this.scale = function(height) {
48 48 this.bg_height = height;
49 49 this.box_size = Math.floor(this.bg_height / 1.2);
50 50 this.cell_height = this.box_size;
51 51 }
52 52
53 function colorPart(num) {
54 num *= 255
55 num = num < 0 ? 0 : num;
56 num = num > 255 ? 255 : num;
57 var digits = Math.round(num).toString(16);
58 if (num < 16) {
59 return '0' + digits;
60 } else {
61 return digits;
62 }
63 }
64
65 53 this.setColor = function(color, bg, fg) {
66 54
67 55 // Set the colour.
68 56 //
69 57 // If color is a string, expect an hexadecimal RGB
70 58 // value and apply it unchanged. If color is a number,
71 59 // pick a distinct colour based on an internal wheel;
72 60 // the bg parameter provides the value that should be
73 61 // assigned to the 'zero' colours and the fg parameter
74 62 // provides the multiplier that should be applied to
75 63 // the foreground colours.
76 64 var s;
77 65 if(typeof color == "string") {
78 66 s = "#" + color;
79 67 } else { //typeof color == "number"
80 68 color %= colors.length;
81 69 var red = (colors[color][0] * fg) || bg;
82 70 var green = (colors[color][1] * fg) || bg;
83 71 var blue = (colors[color][2] * fg) || bg;
84 72 red = Math.round(red * 255);
85 73 green = Math.round(green * 255);
86 74 blue = Math.round(blue * 255);
87 75 s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
88 76 }
89 77 this.ctx.strokeStyle = s;
90 78 this.ctx.fillStyle = s;
91 79 return s;
92 80
93 81 }
94 82
95 83 this.edge = function(x0, y0, x1, y1, color, width) {
96 84
97 85 this.setColor(color, 0.0, 0.65);
98 86 if(width >= 0)
99 87 this.ctx.lineWidth = width;
100 88 this.ctx.beginPath();
101 89 this.ctx.moveTo(x0, y0);
102 90 this.ctx.lineTo(x1, y1);
103 91 this.ctx.stroke();
104 92
105 93 }
106 94
107 95 this.render = function(data) {
108 96
109 97 var backgrounds = '';
110 98 var nodedata = '';
111 99
112 100 for (var i in data) {
113 101
114 102 var parity = i % 2;
115 103 this.cell[1] += this.bg_height;
116 104 this.bg[1] += this.bg_height;
117 105
118 106 var cur = data[i];
119 107 var node = cur[1];
120 108 var edges = cur[2];
121 109 var fold = false;
122 110
123 111 var prevWidth = this.ctx.lineWidth;
124 112 for (var j in edges) {
125 113
126 114 line = edges[j];
127 115 start = line[0];
128 116 end = line[1];
129 117 color = line[2];
130 118 var width = line[3];
131 119 if(width < 0)
132 120 width = prevWidth;
133 121 var branchcolor = line[4];
134 122 if(branchcolor)
135 123 color = branchcolor;
136 124
137 125 if (end > this.columns || start > this.columns) {
138 126 this.columns += 1;
139 127 }
140 128
141 129 if (start == this.columns && start > end) {
142 130 var fold = true;
143 131 }
144 132
145 133 x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
146 134 y0 = this.bg[1] - this.bg_height / 2;
147 135 x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
148 136 y1 = this.bg[1] + this.bg_height / 2;
149 137
150 138 this.edge(x0, y0, x1, y1, color, width);
151 139
152 140 }
153 141 this.ctx.lineWidth = prevWidth;
154 142
155 143 // Draw the revision node in the right column
156 144
157 145 column = node[0]
158 146 color = node[1]
159 147
160 148 radius = this.box_size / 8;
161 149 x = this.cell[0] + this.box_size * column + this.box_size / 2;
162 150 y = this.bg[1] - this.bg_height / 2;
163 151 var add = this.vertex(x, y, color, parity, cur);
164 152 backgrounds += add[0];
165 153 nodedata += add[1];
166 154
167 155 if (fold) this.columns -= 1;
168 156
169 157 }
170 158
171 159 document.getElementById('nodebgs').innerHTML += backgrounds;
172 160 document.getElementById('graphnodes').innerHTML += nodedata;
173 161
174 162 }
175 163
176 164 }
177 165
178 166
179 167 function process_dates(parentSelector){
180 168
181 169 // derived from code from mercurial/templatefilter.py
182 170
183 171 var scales = {
184 172 'year': 365 * 24 * 60 * 60,
185 173 'month': 30 * 24 * 60 * 60,
186 174 'week': 7 * 24 * 60 * 60,
187 175 'day': 24 * 60 * 60,
188 176 'hour': 60 * 60,
189 177 'minute': 60,
190 178 'second': 1
191 179 };
192 180
193 181 function format(count, string){
194 182 var ret = count + ' ' + string;
195 183 if (count > 1){
196 184 ret = ret + 's';
197 185 }
198 186 return ret;
199 187 }
200 188
201 189 function shortdate(date){
202 190 var ret = date.getFullYear() + '-';
203 191 // getMonth() gives a 0-11 result
204 192 var month = date.getMonth() + 1;
205 193 if (month <= 9){
206 194 ret += '0' + month;
207 195 } else {
208 196 ret += month;
209 197 }
210 198 ret += '-';
211 199 var day = date.getDate();
212 200 if (day <= 9){
213 201 ret += '0' + day;
214 202 } else {
215 203 ret += day;
216 204 }
217 205 return ret;
218 206 }
219 207
220 208 function age(datestr){
221 209 var now = new Date();
222 210 var once = new Date(datestr);
223 211 if (isNaN(once.getTime())){
224 212 // parsing error
225 213 return datestr;
226 214 }
227 215
228 216 var delta = Math.floor((now.getTime() - once.getTime()) / 1000);
229 217
230 218 var future = false;
231 219 if (delta < 0){
232 220 future = true;
233 221 delta = -delta;
234 222 if (delta > (30 * scales.year)){
235 223 return "in the distant future";
236 224 }
237 225 }
238 226
239 227 if (delta > (2 * scales.year)){
240 228 return shortdate(once);
241 229 }
242 230
243 231 for (unit in scales){
244 232 var s = scales[unit];
245 233 var n = Math.floor(delta / s);
246 234 if ((n >= 2) || (s == 1)){
247 235 if (future){
248 236 return format(n, unit) + ' from now';
249 237 } else {
250 238 return format(n, unit) + ' ago';
251 239 }
252 240 }
253 241 }
254 242 }
255 243
256 244 var nodes = document.querySelectorAll((parentSelector || '') + ' .age');
257 245 var dateclass = new RegExp('\\bdate\\b');
258 246 for (var i=0; i<nodes.length; ++i){
259 247 var node = nodes[i];
260 248 var classes = node.className;
261 249 var agevalue = age(node.textContent);
262 250 if (dateclass.test(classes)){
263 251 // We want both: date + (age)
264 252 node.textContent += ' ('+agevalue+')';
265 253 } else {
266 254 node.title = node.textContent;
267 255 node.textContent = agevalue;
268 256 }
269 257 }
270 258 }
271 259
272 260 function toggleDiffstat() {
273 261 var curdetails = document.getElementById('diffstatdetails').style.display;
274 262 var curexpand = curdetails == 'none' ? 'inline' : 'none';
275 263 document.getElementById('diffstatdetails').style.display = curexpand;
276 264 document.getElementById('diffstatexpand').style.display = curdetails;
277 265 }
278 266
279 267 function toggleLinewrap() {
280 268 function getLinewrap() {
281 269 var nodes = document.getElementsByClassName('sourcelines');
282 270 // if there are no such nodes, error is thrown here
283 271 return nodes[0].classList.contains('wrap');
284 272 }
285 273
286 274 function setLinewrap(enable) {
287 275 var nodes = document.getElementsByClassName('sourcelines');
288 276 for (var i = 0; i < nodes.length; i++) {
289 277 if (enable) {
290 278 nodes[i].classList.add('wrap');
291 279 } else {
292 280 nodes[i].classList.remove('wrap');
293 281 }
294 282 }
295 283
296 284 var links = document.getElementsByClassName('linewraplink');
297 285 for (var i = 0; i < links.length; i++) {
298 286 links[i].innerHTML = enable ? 'on' : 'off';
299 287 }
300 288 }
301 289
302 290 setLinewrap(!getLinewrap());
303 291 }
304 292
305 293 function format(str, replacements) {
306 294 return str.replace(/%(\w+)%/g, function(match, p1) {
307 295 return String(replacements[p1]);
308 296 });
309 297 }
310 298
311 299 function makeRequest(url, method, onstart, onsuccess, onerror, oncomplete) {
312 300 xfr = new XMLHttpRequest();
313 301 xfr.onreadystatechange = function() {
314 302 if (xfr.readyState === 4) {
315 303 try {
316 304 if (xfr.status === 200) {
317 305 onsuccess(xfr.responseText);
318 306 } else {
319 307 throw 'server error';
320 308 }
321 309 } catch (e) {
322 310 onerror(e);
323 311 } finally {
324 312 oncomplete();
325 313 }
326 314 }
327 315 };
328 316
329 317 xfr.open(method, url);
330 318 xfr.overrideMimeType("text/xhtml; charset=" + document.characterSet.toLowerCase());
331 319 xfr.send();
332 320 onstart();
333 321 return xfr;
334 322 }
335 323
336 324 function removeByClassName(className) {
337 325 var nodes = document.getElementsByClassName(className);
338 326 while (nodes.length) {
339 327 nodes[0].parentNode.removeChild(nodes[0]);
340 328 }
341 329 }
342 330
343 331 function docFromHTML(html) {
344 332 var doc = document.implementation.createHTMLDocument('');
345 333 doc.documentElement.innerHTML = html;
346 334 return doc;
347 335 }
348 336
349 337 function appendFormatHTML(element, formatStr, replacements) {
350 338 element.insertAdjacentHTML('beforeend', format(formatStr, replacements));
351 339 }
352 340
353 341 function ajaxScrollInit(urlFormat,
354 342 nextPageVar,
355 343 nextPageVarGet,
356 344 containerSelector,
357 345 messageFormat,
358 346 mode) {
359 347 updateInitiated = false;
360 348 container = document.querySelector(containerSelector);
361 349
362 350 function scrollHandler() {
363 351 if (updateInitiated) {
364 352 return;
365 353 }
366 354
367 355 var scrollHeight = document.documentElement.scrollHeight;
368 356 var clientHeight = document.documentElement.clientHeight;
369 357 var scrollTop = document.body.scrollTop
370 358 || document.documentElement.scrollTop;
371 359
372 360 if (scrollHeight - (scrollTop + clientHeight) < 50) {
373 361 updateInitiated = true;
374 362 removeByClassName('scroll-loading-error');
375 363 container.lastElementChild.classList.add('scroll-separator');
376 364
377 365 if (!nextPageVar) {
378 366 var message = {
379 367 'class': 'scroll-loading-info',
380 368 text: 'No more entries'
381 369 };
382 370 appendFormatHTML(container, messageFormat, message);
383 371 return;
384 372 }
385 373
386 374 makeRequest(
387 375 format(urlFormat, {next: nextPageVar}),
388 376 'GET',
389 377 function onstart() {
390 378 var message = {
391 379 'class': 'scroll-loading',
392 380 text: 'Loading...'
393 381 };
394 382 appendFormatHTML(container, messageFormat, message);
395 383 },
396 384 function onsuccess(htmlText) {
397 385 if (mode == 'graph') {
398 386 var addHeight = htmlText.match(/^\s*<canvas id="graph".*height="(\d+)"><\/canvas>$/m)[1];
399 387 addHeight = parseInt(addHeight);
400 388 graph.canvas.height = addHeight;
401 389
402 390 var dataStr = htmlText.match(/^\s*var data = (.*);$/m)[1];
403 391 var data = JSON.parse(dataStr);
404 392 if (data.length < nextPageVar) {
405 393 nextPageVar = undefined;
406 394 }
407 395 graph.reset();
408 396 graph.render(data);
409 397 } else {
410 398 var doc = docFromHTML(htmlText);
411 399 var nodes = doc.querySelector(containerSelector).children;
412 400 var curClass = 'c' + Date.now();
413 401 while (nodes.length) {
414 402 var node = nodes[0];
415 403 node = document.adoptNode(node);
416 404 node.classList.add(curClass);
417 405 container.appendChild(node);
418 406 }
419 407 process_dates('.' + curClass);
420 408 }
421 409
422 410 nextPageVar = nextPageVarGet(htmlText, nextPageVar);
423 411 },
424 412 function onerror(errorText) {
425 413 var message = {
426 414 'class': 'scroll-loading-error',
427 415 text: 'Error: ' + errorText
428 416 };
429 417 appendFormatHTML(container, messageFormat, message);
430 418 },
431 419 function oncomplete() {
432 420 removeByClassName('scroll-loading');
433 421 updateInitiated = false;
434 422 scrollHandler();
435 423 }
436 424 );
437 425 }
438 426 }
439 427
440 428 window.addEventListener('scroll', scrollHandler);
441 429 window.addEventListener('resize', scrollHandler);
442 430 scrollHandler();
443 431 }
General Comments 0
You need to be logged in to leave comments. Login now