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