mercurial/templates/static/mercurial.js
changeset 14046 b24e5a708fad
child 14571 17c0cb1045e5
equal deleted inserted replaced
14045:1c38777f7b8a 14046:b24e5a708fad
       
     1 // mercurial.js - JavaScript utility functions
       
     2 //
       
     3 // Rendering of branch DAGs on the client side
       
     4 // Display of elapsed time
       
     5 //
       
     6 // Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
       
     7 // Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
       
     8 //
       
     9 // derived from code written by Scott James Remnant <scott@ubuntu.com>
       
    10 // Copyright 2005 Canonical Ltd.
       
    11 //
       
    12 // This software may be used and distributed according to the terms
       
    13 // of the GNU General Public License, incorporated herein by reference.
       
    14 
       
    15 var colors = [
       
    16 	[ 1.0, 0.0, 0.0 ],
       
    17 	[ 1.0, 1.0, 0.0 ],
       
    18 	[ 0.0, 1.0, 0.0 ],
       
    19 	[ 0.0, 1.0, 1.0 ],
       
    20 	[ 0.0, 0.0, 1.0 ],
       
    21 	[ 1.0, 0.0, 1.0 ]
       
    22 ];
       
    23 
       
    24 function Graph() {
       
    25 	
       
    26 	this.canvas = document.getElementById('graph');
       
    27 	if (navigator.userAgent.indexOf('MSIE') >= 0) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
       
    28 	this.ctx = this.canvas.getContext('2d');
       
    29 	this.ctx.strokeStyle = 'rgb(0, 0, 0)';
       
    30 	this.ctx.fillStyle = 'rgb(0, 0, 0)';
       
    31 	this.cur = [0, 0];
       
    32 	this.line_width = 3;
       
    33 	this.bg = [0, 4];
       
    34 	this.cell = [2, 0];
       
    35 	this.columns = 0;
       
    36 	this.revlink = '';
       
    37 	
       
    38 	this.scale = function(height) {
       
    39 		this.bg_height = height;
       
    40 		this.box_size = Math.floor(this.bg_height / 1.2);
       
    41 		this.cell_height = this.box_size;
       
    42 	}
       
    43 	
       
    44 	function colorPart(num) {
       
    45 		num *= 255
       
    46 		num = num < 0 ? 0 : num;
       
    47 		num = num > 255 ? 255 : num;
       
    48 		var digits = Math.round(num).toString(16);
       
    49 		if (num < 16) {
       
    50 			return '0' + digits;
       
    51 		} else {
       
    52 			return digits;
       
    53 		}
       
    54 	}
       
    55 
       
    56 	this.setColor = function(color, bg, fg) {
       
    57 		
       
    58 		// Set the colour.
       
    59 		//
       
    60 		// Picks a distinct colour based on an internal wheel; the bg
       
    61 		// parameter provides the value that should be assigned to the 'zero'
       
    62 		// colours and the fg parameter provides the multiplier that should be
       
    63 		// applied to the foreground colours.
       
    64 		
       
    65 		color %= colors.length;
       
    66 		var red = (colors[color][0] * fg) || bg;
       
    67 		var green = (colors[color][1] * fg) || bg;
       
    68 		var blue = (colors[color][2] * fg) || bg;
       
    69 		red = Math.round(red * 255);
       
    70 		green = Math.round(green * 255);
       
    71 		blue = Math.round(blue * 255);
       
    72 		var s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
       
    73 		this.ctx.strokeStyle = s;
       
    74 		this.ctx.fillStyle = s;
       
    75 		return s;
       
    76 		
       
    77 	}
       
    78 
       
    79 	this.render = function(data) {
       
    80 		
       
    81 		var backgrounds = '';
       
    82 		var nodedata = '';
       
    83 		
       
    84 		for (var i in data) {
       
    85 			
       
    86 			var parity = i % 2;
       
    87 			this.cell[1] += this.bg_height;
       
    88 			this.bg[1] += this.bg_height;
       
    89 			
       
    90 			var cur = data[i];
       
    91 			var node = cur[1];
       
    92 			var edges = cur[2];
       
    93 			var fold = false;
       
    94 			
       
    95 			for (var j in edges) {
       
    96 				
       
    97 				line = edges[j];
       
    98 				start = line[0];
       
    99 				end = line[1];
       
   100 				color = line[2];
       
   101 
       
   102 				if (end > this.columns || start > this.columns) {
       
   103 					this.columns += 1;
       
   104 				}
       
   105 				
       
   106 				if (start == this.columns && start > end) {
       
   107 					var fold = true;
       
   108 				}
       
   109 				
       
   110 				x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
       
   111 				y0 = this.bg[1] - this.bg_height / 2;
       
   112 				x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
       
   113 				y1 = this.bg[1] + this.bg_height / 2;
       
   114 				
       
   115 				this.edge(x0, y0, x1, y1, color);
       
   116 				
       
   117 			}
       
   118 			
       
   119 			// Draw the revision node in the right column
       
   120 			
       
   121 			column = node[0]
       
   122 			color = node[1]
       
   123 			
       
   124 			radius = this.box_size / 8;
       
   125 			x = this.cell[0] + this.box_size * column + this.box_size / 2;
       
   126 			y = this.bg[1] - this.bg_height / 2;
       
   127 			var add = this.vertex(x, y, color, parity, cur);
       
   128 			backgrounds += add[0];
       
   129 			nodedata += add[1];
       
   130 			
       
   131 			if (fold) this.columns -= 1;
       
   132 			
       
   133 		}
       
   134 		
       
   135 		document.getElementById('nodebgs').innerHTML += backgrounds;
       
   136 		document.getElementById('graphnodes').innerHTML += nodedata;
       
   137 		
       
   138 	}
       
   139 
       
   140 }
       
   141 
       
   142 
       
   143 process_dates = (function(document, RegExp, Math, isNaN, Date, _false, _true){
       
   144 
       
   145 	// derived from code from mercurial/templatefilter.py
       
   146 
       
   147 	var scales = {
       
   148 		'year':  365 * 24 * 60 * 60,
       
   149 		'month':  30 * 24 * 60 * 60,
       
   150 		'week':    7 * 24 * 60 * 60,
       
   151 		'day':    24 * 60 * 60,
       
   152 		'hour':   60 * 60,
       
   153 		'minute': 60,
       
   154 		'second': 1
       
   155 	};
       
   156 
       
   157 	function format(count, string){
       
   158 		var ret = count + ' ' + string;
       
   159 		if (count > 1){
       
   160 			ret = ret + 's';
       
   161 		}
       
   162 		return ret;
       
   163 	}
       
   164 
       
   165 	function age(datestr){
       
   166 		var now = new Date();
       
   167 		var once = new Date(datestr);
       
   168 
       
   169 		if (isNaN(once.getTime())){
       
   170 			// parsing error
       
   171 			return datestr;
       
   172 		}
       
   173 
       
   174 		var delta = Math.floor((now.getTime() - once.getTime()) / 1000);
       
   175 
       
   176 		var future = _false;
       
   177 		if (delta < 0){
       
   178 			future = _true;
       
   179 			delta = -delta;
       
   180 			if (delta > (30 * scales.year)){
       
   181 				return "in the distant future";
       
   182 			}
       
   183 		}
       
   184 
       
   185 		if (delta > (2 * scales.year)){
       
   186 			return once.getFullYear() + '-' + once.getMonth() + '-' + once.getDate();
       
   187 		}
       
   188 
       
   189 		for (unit in scales){
       
   190 			var s = scales[unit];
       
   191 			var n = Math.floor(delta / s);
       
   192 			if ((n >= 2) || (s == 1)){
       
   193 				if (future){
       
   194 					return format(n, unit) + ' from now';
       
   195 				} else {
       
   196 					return format(n, unit) + ' ago';
       
   197 				}
       
   198 			}
       
   199 		}
       
   200 	}
       
   201 
       
   202 	return function(){
       
   203 		var nodes = document.getElementsByTagName('*');
       
   204 		var ageclass = new RegExp('\\bage\\b');
       
   205 		var dateclass = new RegExp('\\bdate\\b');
       
   206 		for (var i=0; i<nodes.length; ++i){
       
   207 			var node = nodes[i];
       
   208 			var classes = node.className;
       
   209 			if (ageclass.test(classes)){
       
   210 				var agevalue = age(node.textContent);
       
   211 				if (dateclass.test(classes)){
       
   212 					// We want both: date + (age)
       
   213 					node.textContent += ' ('+agevalue+')';
       
   214 				} else {
       
   215 					node.textContent = agevalue;
       
   216 				}
       
   217 			}
       
   218 		}
       
   219 	}
       
   220 })(document, RegExp, Math, isNaN, Date, false, true)