##// END OF EJS Templates
hgweb: don't point graph links at tip hash where it doesn't make sense...
hgweb: don't point graph links at tip hash where it doesn't make sense Some pages, e.g. bookmarks, help and summary don't have a meaningful revision context: they always either show information about tip or about the whole repo (and not about any specific changeset). And error pages can just show hgweb error messages, not related to any repo or changeset. When monoblue style was added in 91b0ada2d94b, however, all graph links had tried to point at some hash, and on such pages as described above it didn't make sense. On error pages '{node|short}' is empty string anyway. Of course, it worked, but seeing such pages without revision context provide links with hashes is a bit confusing (unless you keep current tip hash in your head at all times) and wasn't consistent with other template styles, other pages in monoblue and even other links on the same page. Let's just link to '/graph', which is equal to '/graph/tip'.

File last commit:

r20973:55543ee5 default
r25525:bcc02516 default
Show More
mercurial.js
443 lines | 12.0 KiB | application/javascript | JavascriptLexer
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 // mercurial.js - JavaScript utility functions
//
// Rendering of branch DAGs on the client side
// Display of elapsed time
Steven Brown
paper, coal: display diffstat on the changeset page...
r14571 // Show or hide diffstat
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 //
// Copyright 2008 Dirkjan Ochtman <dirkjan AT ochtman DOT nl>
// Copyright 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
//
// derived from code written by Scott James Remnant <scott@ubuntu.com>
// Copyright 2005 Canonical Ltd.
//
// This software may be used and distributed according to the terms
// of the GNU General Public License, incorporated herein by reference.
var colors = [
[ 1.0, 0.0, 0.0 ],
[ 1.0, 1.0, 0.0 ],
[ 0.0, 1.0, 0.0 ],
[ 0.0, 1.0, 1.0 ],
[ 0.0, 0.0, 1.0 ],
[ 1.0, 0.0, 1.0 ]
];
function Graph() {
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 this.canvas = document.getElementById('graph');
Matt Mackall
hgweb: change IE canvas test (issue3639)...
r17694 if (window.G_vmlCanvasManager) this.canvas = window.G_vmlCanvasManager.initElement(this.canvas);
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 this.ctx = this.canvas.getContext('2d');
this.ctx.strokeStyle = 'rgb(0, 0, 0)';
this.ctx.fillStyle = 'rgb(0, 0, 0)';
this.cur = [0, 0];
this.line_width = 3;
this.bg = [0, 4];
this.cell = [2, 0];
this.columns = 0;
this.revlink = '';
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Alexander Plavin
hgweb: add reset javascript function to Graph...
r19780 this.reset = function() {
this.bg = [0, 4];
this.cell = [2, 0];
this.columns = 0;
document.getElementById('nodebgs').innerHTML = '';
document.getElementById('graphnodes').innerHTML = '';
}
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 this.scale = function(height) {
this.bg_height = height;
this.box_size = Math.floor(this.bg_height / 1.2);
this.cell_height = this.box_size;
}
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 function colorPart(num) {
num *= 255
num = num < 0 ? 0 : num;
num = num > 255 ? 255 : num;
var digits = Math.round(num).toString(16);
if (num < 16) {
return '0' + digits;
} else {
return digits;
}
}
this.setColor = function(color, bg, fg) {
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 // Set the colour.
//
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 // If color is a string, expect an hexadecimal RGB
// value and apply it unchanged. If color is a number,
// pick a distinct colour based on an internal wheel;
// the bg parameter provides the value that should be
// assigned to the 'zero' colours and the fg parameter
// provides the multiplier that should be applied to
// the foreground colours.
Constantine Linnick
graph: in hgrc specify line color for main branch...
r16130 var s;
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 if(typeof color == "string") {
s = "#" + color;
} else { //typeof color == "number"
Constantine Linnick
graph: in hgrc specify line color for main branch...
r16130 color %= colors.length;
var red = (colors[color][0] * fg) || bg;
var green = (colors[color][1] * fg) || bg;
var blue = (colors[color][2] * fg) || bg;
red = Math.round(red * 255);
green = Math.round(green * 255);
blue = Math.round(blue * 255);
s = 'rgb(' + red + ', ' + green + ', ' + blue + ')';
}
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 this.ctx.strokeStyle = s;
this.ctx.fillStyle = s;
return s;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 }
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 this.edge = function(x0, y0, x1, y1, color, width) {
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Patrick Mezard
templates: move Graph.edge() implementation in mercurial.js...
r16137 this.setColor(color, 0.0, 0.65);
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 if(width >= 0)
this.ctx.lineWidth = width;
Patrick Mezard
templates: move Graph.edge() implementation in mercurial.js...
r16137 this.ctx.beginPath();
this.ctx.moveTo(x0, y0);
this.ctx.lineTo(x1, y1);
this.ctx.stroke();
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Patrick Mezard
templates: move Graph.edge() implementation in mercurial.js...
r16137 }
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 this.render = function(data) {
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 var backgrounds = '';
var nodedata = '';
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 for (var i in data) {
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 var parity = i % 2;
this.cell[1] += this.bg_height;
this.bg[1] += this.bg_height;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 var cur = data[i];
var node = cur[1];
var edges = cur[2];
var fold = false;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 var prevWidth = this.ctx.lineWidth;
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 for (var j in edges) {
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 line = edges[j];
start = line[0];
end = line[1];
color = line[2];
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 var width = line[3];
if(width < 0)
width = prevWidth;
var branchcolor = line[4];
if(branchcolor)
color = branchcolor;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 if (end > this.columns || start > this.columns) {
this.columns += 1;
}
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 if (start == this.columns && start > end) {
var fold = true;
}
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 x0 = this.cell[0] + this.box_size * start + this.box_size / 2;
y0 = this.bg[1] - this.bg_height / 2;
x1 = this.cell[0] + this.box_size * end + this.box_size / 2;
y1 = this.bg[1] + this.bg_height / 2;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 this.edge(x0, y0, x1, y1, color, width);
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 }
Patrick Mezard
hgweb: refactor graph customization javascript...
r16138 this.ctx.lineWidth = prevWidth;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 // Draw the revision node in the right column
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 column = node[0]
color = node[1]
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 radius = this.box_size / 8;
x = this.cell[0] + this.box_size * column + this.box_size / 2;
y = this.bg[1] - this.bg_height / 2;
var add = this.vertex(x, y, color, parity, cur);
backgrounds += add[0];
nodedata += add[1];
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 if (fold) this.columns -= 1;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 }
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 document.getElementById('nodebgs').innerHTML += backgrounds;
document.getElementById('graphnodes').innerHTML += nodedata;
Kevin Bullock
hgweb: remove trailing whitespace in mercurial.js
r19530
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 }
}
Alexander Plavin
hgweb: add parentSelector argument to process_dates...
r19858 function process_dates(parentSelector){
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046
// derived from code from mercurial/templatefilter.py
var scales = {
'year': 365 * 24 * 60 * 60,
'month': 30 * 24 * 60 * 60,
'week': 7 * 24 * 60 * 60,
'day': 24 * 60 * 60,
'hour': 60 * 60,
'minute': 60,
'second': 1
};
function format(count, string){
var ret = count + ' ' + string;
if (count > 1){
ret = ret + 's';
}
Benoit Allard
web: Output a correct date in short format (issue2902)
r14881 return ret;
}
function shortdate(date){
var ret = date.getFullYear() + '-';
// getMonth() gives a 0-11 result
var month = date.getMonth() + 1;
if (month <= 9){
ret += '0' + month;
} else {
ret += month;
}
ret += '-';
var day = date.getDate();
if (day <= 9){
ret += '0' + day;
} else {
ret += day;
}
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 return ret;
}
Benoit Allard
web: Output a correct date in short format (issue2902)
r14881 function age(datestr){
var now = new Date();
var once = new Date(datestr);
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 if (isNaN(once.getTime())){
// parsing error
return datestr;
}
var delta = Math.floor((now.getTime() - once.getTime()) / 1000);
Alexander Plavin
hgweb: eliminate extra complexity in process_dates definition...
r19834 var future = false;
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 if (delta < 0){
Alexander Plavin
hgweb: eliminate extra complexity in process_dates definition...
r19834 future = true;
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 delta = -delta;
if (delta > (30 * scales.year)){
return "in the distant future";
}
}
if (delta > (2 * scales.year)){
Benoit Allard
web: Output a correct date in short format (issue2902)
r14881 return shortdate(once);
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 }
for (unit in scales){
var s = scales[unit];
var n = Math.floor(delta / s);
if ((n >= 2) || (s == 1)){
if (future){
return format(n, unit) + ' from now';
} else {
return format(n, unit) + ' ago';
}
}
}
}
Alexander Plavin
hgweb: add parentSelector argument to process_dates...
r19858 var nodes = document.querySelectorAll((parentSelector || '') + ' .age');
Alexander Plavin
hgweb: eliminate extra complexity in process_dates definition...
r19834 var dateclass = new RegExp('\\bdate\\b');
for (var i=0; i<nodes.length; ++i){
var node = nodes[i];
var classes = node.className;
Alexander Plavin
hgweb: optimize process_dates function...
r19857 var agevalue = age(node.textContent);
if (dateclass.test(classes)){
// We want both: date + (age)
node.textContent += ' ('+agevalue+')';
} else {
node.title = node.textContent;
node.textContent = agevalue;
Benoit Allard
web: Made elapsed time calculation dynamic (javascript)....
r14046 }
}
Alexander Plavin
hgweb: eliminate extra complexity in process_dates definition...
r19834 }
Steven Brown
paper, coal: display diffstat on the changeset page...
r14571
Alexander Plavin
hgweb: toggleDiffstat function instead of showDiffstat and hideDiffstat...
r19428 function toggleDiffstat() {
var curdetails = document.getElementById('diffstatdetails').style.display;
var curexpand = curdetails == 'none' ? 'inline' : 'none';
document.getElementById('diffstatdetails').style.display = curexpand;
document.getElementById('diffstatexpand').style.display = curdetails;
Steven Brown
paper, coal: display diffstat on the changeset page...
r14571 }
Alexander Plavin
hgweb: add line wrapping switch to file source view...
r19430
function toggleLinewrap() {
function getLinewrap() {
var nodes = document.getElementsByClassName('sourcelines');
// if there are no such nodes, error is thrown here
return nodes[0].classList.contains('wrap');
}
function setLinewrap(enable) {
var nodes = document.getElementsByClassName('sourcelines');
for (var i = 0; i < nodes.length; i++) {
if (enable) {
nodes[i].classList.add('wrap');
} else {
nodes[i].classList.remove('wrap');
}
}
var links = document.getElementsByClassName('linewraplink');
for (var i = 0; i < links.length; i++) {
links[i].innerHTML = enable ? 'on' : 'off';
}
}
setLinewrap(!getLinewrap());
}
Alexander Plavin
hgweb: add format javascript function...
r19739
function format(str, replacements) {
return str.replace(/%(\w+)%/g, function(match, p1) {
return String(replacements[p1]);
});
}
Alexander Plavin
hgweb: add makeRequest javascript function...
r19740
function makeRequest(url, method, onstart, onsuccess, onerror, oncomplete) {
xfr = new XMLHttpRequest();
xfr.onreadystatechange = function() {
if (xfr.readyState === 4) {
try {
if (xfr.status === 200) {
onsuccess(xfr.responseText);
} else {
throw 'server error';
}
} catch (e) {
onerror(e);
} finally {
oncomplete();
}
}
};
xfr.open(method, url);
Wei, Elson
hgweb: override the charset attribute in the http request...
r20973 xfr.overrideMimeType("text/xhtml; charset=" + document.characterSet.toLowerCase());
Alexander Plavin
hgweb: add makeRequest javascript function...
r19740 xfr.send();
onstart();
return xfr;
}
Alexander Plavin
hgweb: add docFromHTML javascript function...
r19741
Alexander Plavin
hgweb: add removeByClassName javascript function...
r19742 function removeByClassName(className) {
var nodes = document.getElementsByClassName(className);
while (nodes.length) {
nodes[0].parentNode.removeChild(nodes[0]);
}
}
Alexander Plavin
hgweb: add docFromHTML javascript function...
r19741 function docFromHTML(html) {
var doc = document.implementation.createHTMLDocument('');
doc.documentElement.innerHTML = html;
return doc;
}
Alexander Plavin
hgweb: add appendFormatHTML javascript function...
r19743
function appendFormatHTML(element, formatStr, replacements) {
element.insertAdjacentHTML('beforeend', format(formatStr, replacements));
}
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746
function ajaxScrollInit(urlFormat,
Alexander Plavin
hgweb: make infinite scroll handling more generic and extensible...
r19781 nextPageVar,
nextPageVarGet,
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 containerSelector,
Alexander Plavin
hgweb: add graph mode of ajax response processing...
r19782 messageFormat,
mode) {
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 updateInitiated = false;
container = document.querySelector(containerSelector);
function scrollHandler() {
if (updateInitiated) {
return;
}
var scrollHeight = document.documentElement.scrollHeight;
var clientHeight = document.documentElement.clientHeight;
var scrollTop = document.body.scrollTop
|| document.documentElement.scrollTop;
if (scrollHeight - (scrollTop + clientHeight) < 50) {
updateInitiated = true;
Alexander Plavin
hgweb: show message when an error occured during ajax loading
r19756 removeByClassName('scroll-loading-error');
Alexander Plavin
hgweb: add CSS class to the last entry on a page...
r19760 container.lastElementChild.classList.add('scroll-separator');
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746
Alexander Plavin
hgweb: make infinite scroll handling more generic and extensible...
r19781 if (!nextPageVar) {
Alexander Plavin
hgweb: show a message when there are no more entries in the list
r19754 var message = {
class: 'scroll-loading-info',
text: 'No more entries'
};
appendFormatHTML(container, messageFormat, message);
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 return;
}
makeRequest(
Alexander Plavin
hgweb: make infinite scroll handling more generic and extensible...
r19781 format(urlFormat, {next: nextPageVar}),
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 'GET',
function onstart() {
Alexander Plavin
hgweb: show loading indicator while an ajax request is in process
r19755 var message = {
class: 'scroll-loading',
text: 'Loading...'
};
appendFormatHTML(container, messageFormat, message);
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 },
function onsuccess(htmlText) {
Alexander Plavin
hgweb: add graph mode of ajax response processing...
r19782 if (mode == 'graph') {
Takumi IINO
hgweb: fix regexp for other styles like monoblue...
r20252 var addHeight = htmlText.match(/^\s*<canvas id="graph".*height="(\d+)"><\/canvas>$/m)[1];
Alexander Plavin
hgweb: add graph mode of ajax response processing...
r19782 addHeight = parseInt(addHeight);
graph.canvas.height = addHeight;
var dataStr = htmlText.match(/^\s*var data = (.*);$/m)[1];
Takumi IINO
hgweb: add missing semicolon
r19957 var data = JSON.parse(dataStr);
Alexander Plavin
hgweb: fix unstoppable loading of graph when no more results...
r19907 if (data.length < nextPageVar) {
nextPageVar = undefined;
}
Alexander Plavin
hgweb: add graph mode of ajax response processing...
r19782 graph.reset();
graph.render(data);
} else {
var doc = docFromHTML(htmlText);
var nodes = doc.querySelector(containerSelector).children;
Alexander Plavin
hgweb: call process_dates with a specified selector in ajax scroll...
r19859 var curClass = 'c' + Date.now();
Alexander Plavin
hgweb: add graph mode of ajax response processing...
r19782 while (nodes.length) {
var node = nodes[0];
node = document.adoptNode(node);
Alexander Plavin
hgweb: call process_dates with a specified selector in ajax scroll...
r19859 node.classList.add(curClass);
Alexander Plavin
hgweb: add graph mode of ajax response processing...
r19782 container.appendChild(node);
}
Alexander Plavin
hgweb: call process_dates with a specified selector in ajax scroll...
r19859 process_dates('.' + curClass);
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 }
Alexander Plavin
hgweb: fix unstoppable loading of graph when no more results...
r19907
nextPageVar = nextPageVarGet(htmlText, nextPageVar);
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 },
function onerror(errorText) {
Alexander Plavin
hgweb: show message when an error occured during ajax loading
r19756 var message = {
class: 'scroll-loading-error',
text: 'Error: ' + errorText
};
appendFormatHTML(container, messageFormat, message);
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 },
function oncomplete() {
Alexander Plavin
hgweb: show loading indicator while an ajax request is in process
r19755 removeByClassName('scroll-loading');
Alexander Plavin
hgweb: add ajaxScrollInit function, which does the ajax requests and processing...
r19746 updateInitiated = false;
scrollHandler();
}
);
}
}
window.addEventListener('scroll', scrollHandler);
window.addEventListener('resize', scrollHandler);
scrollHandler();
}