##// END OF EJS Templates
comments: fixed reply-to from email links.
milka -
r4575:bd6d4156 stable
parent child Browse files
Show More
@@ -1,716 +1,716 b''
1 1 // # Copyright (C) 2010-2020 RhodeCode GmbH
2 2 // #
3 3 // # This program is free software: you can redistribute it and/or modify
4 4 // # it under the terms of the GNU Affero General Public License, version 3
5 5 // # (only), as published by the Free Software Foundation.
6 6 // #
7 7 // # This program is distributed in the hope that it will be useful,
8 8 // # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 // # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 // # GNU General Public License for more details.
11 11 // #
12 12 // # You should have received a copy of the GNU Affero General Public License
13 13 // # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 // #
15 15 // # This program is dual-licensed. If you wish to learn more about the
16 16 // # RhodeCode Enterprise Edition, including its added features, Support services,
17 17 // # and proprietary license terms, please see https://rhodecode.com/licenses/
18 18
19 19 /**
20 20 RhodeCode JS Files
21 21 **/
22 22
23 23 if (typeof console == "undefined" || typeof console.log == "undefined"){
24 24 console = { log: function() {} }
25 25 }
26 26
27 27 // TODO: move the following function to submodules
28 28
29 29 /**
30 30 * show more
31 31 */
32 32 var show_more_event = function(){
33 33 $('table .show_more').click(function(e) {
34 34 var cid = e.target.id.substring(1);
35 35 var button = $(this);
36 36 if (button.hasClass('open')) {
37 37 $('#'+cid).hide();
38 38 button.removeClass('open');
39 39 } else {
40 40 $('#'+cid).show();
41 41 button.addClass('open one');
42 42 }
43 43 });
44 44 };
45 45
46 46 var compare_radio_buttons = function(repo_name, compare_ref_type){
47 47 $('#compare_action').on('click', function(e){
48 48 e.preventDefault();
49 49
50 50 var source = $('input[name=compare_source]:checked').val();
51 51 var target = $('input[name=compare_target]:checked').val();
52 52 if(source && target){
53 53 var url_data = {
54 54 repo_name: repo_name,
55 55 source_ref: source,
56 56 source_ref_type: compare_ref_type,
57 57 target_ref: target,
58 58 target_ref_type: compare_ref_type,
59 59 merge: 1
60 60 };
61 61 window.location = pyroutes.url('repo_compare', url_data);
62 62 }
63 63 });
64 64 $('.compare-radio-button').on('click', function(e){
65 65 var source = $('input[name=compare_source]:checked').val();
66 66 var target = $('input[name=compare_target]:checked').val();
67 67 if(source && target){
68 68 $('#compare_action').removeAttr("disabled");
69 69 $('#compare_action').removeClass("disabled");
70 70 }
71 71 })
72 72 };
73 73
74 74 var showRepoSize = function(target, repo_name, commit_id, callback) {
75 75 var container = $('#' + target);
76 76 var url = pyroutes.url('repo_stats',
77 77 {"repo_name": repo_name, "commit_id": commit_id});
78 78
79 79 container.show();
80 80 if (!container.hasClass('loaded')) {
81 81 $.ajax({url: url})
82 82 .complete(function (data) {
83 83 var responseJSON = data.responseJSON;
84 84 container.addClass('loaded');
85 85 container.html(responseJSON.size);
86 86 callback(responseJSON.code_stats)
87 87 })
88 88 .fail(function (data) {
89 89 console.log('failed to load repo stats');
90 90 });
91 91 }
92 92
93 93 };
94 94
95 95 var showRepoStats = function(target, data){
96 96 var container = $('#' + target);
97 97
98 98 if (container.hasClass('loaded')) {
99 99 return
100 100 }
101 101
102 102 var total = 0;
103 103 var no_data = true;
104 104 var tbl = document.createElement('table');
105 105 tbl.setAttribute('class', 'trending_language_tbl rctable');
106 106
107 107 $.each(data, function(key, val){
108 108 total += val.count;
109 109 });
110 110
111 111 var sortedStats = [];
112 112 for (var obj in data){
113 113 sortedStats.push([obj, data[obj]])
114 114 }
115 115 var sortedData = sortedStats.sort(function (a, b) {
116 116 return b[1].count - a[1].count
117 117 });
118 118 var cnt = 0;
119 119 $.each(sortedData, function(idx, val){
120 120 cnt += 1;
121 121 no_data = false;
122 122
123 123 var tr = document.createElement('tr');
124 124
125 125 var key = val[0];
126 126 var obj = {"desc": val[1].desc, "count": val[1].count};
127 127
128 128 // meta language names
129 129 var td1 = document.createElement('td');
130 130 var trending_language_label = document.createElement('div');
131 131 trending_language_label.innerHTML = obj.desc;
132 132 td1.appendChild(trending_language_label);
133 133
134 134 // extensions
135 135 var td2 = document.createElement('td');
136 136 var extension = document.createElement('div');
137 137 extension.innerHTML = ".{0}".format(key)
138 138 td2.appendChild(extension);
139 139
140 140 // number of files
141 141 var td3 = document.createElement('td');
142 142 var file_count = document.createElement('div');
143 143 var percentage_num = Math.round((obj.count / total * 100), 2);
144 144 var label = _ngettext('file', 'files', obj.count);
145 145 file_count.innerHTML = "{0} {1} ({2}%)".format(obj.count, label, percentage_num) ;
146 146 td3.appendChild(file_count);
147 147
148 148 // percentage
149 149 var td4 = document.createElement('td');
150 150 td4.setAttribute("class", 'trending_language');
151 151
152 152 var percentage = document.createElement('div');
153 153 percentage.setAttribute('class', 'lang-bar');
154 154 percentage.innerHTML = "&nbsp;";
155 155 percentage.style.width = percentage_num + '%';
156 156 td4.appendChild(percentage);
157 157
158 158 tr.appendChild(td1);
159 159 tr.appendChild(td2);
160 160 tr.appendChild(td3);
161 161 tr.appendChild(td4);
162 162 tbl.appendChild(tr);
163 163
164 164 });
165 165
166 166 $(container).html(tbl);
167 167 $(container).addClass('loaded');
168 168
169 169 $('#code_stats_show_more').on('click', function (e) {
170 170 e.preventDefault();
171 171 $('.stats_hidden').each(function (idx) {
172 172 $(this).css("display", "");
173 173 });
174 174 $('#code_stats_show_more').hide();
175 175 });
176 176
177 177 };
178 178
179 179 // returns a node from given html;
180 180 var fromHTML = function(html){
181 181 var _html = document.createElement('element');
182 182 _html.innerHTML = html;
183 183 return _html;
184 184 };
185 185
186 186 // Toggle Collapsable Content
187 187 function collapsableContent() {
188 188
189 189 $('.collapsable-content').not('.no-hide').hide();
190 190
191 191 $('.btn-collapse').unbind(); //in case we've been here before
192 192 $('.btn-collapse').click(function() {
193 193 var button = $(this);
194 194 var togglename = $(this).data("toggle");
195 195 $('.collapsable-content[data-toggle='+togglename+']').toggle();
196 196 if ($(this).html()=="Show Less")
197 197 $(this).html("Show More");
198 198 else
199 199 $(this).html("Show Less");
200 200 });
201 201 };
202 202
203 203 var timeagoActivate = function() {
204 204 $("time.timeago").timeago();
205 205 };
206 206
207 207
208 208 var clipboardActivate = function() {
209 209 /*
210 210 *
211 211 * <i class="tooltip icon-plus clipboard-action" data-clipboard-text="${commit.raw_id}" title="${_('Copy the full commit id')}"></i>
212 212 * */
213 213 var clipboard = new ClipboardJS('.clipboard-action');
214 214
215 215 clipboard.on('success', function(e) {
216 216 var callback = function () {
217 217 $(e.trigger).animate({'opacity': 1.00}, 200)
218 218 };
219 219 $(e.trigger).animate({'opacity': 0.15}, 200, callback);
220 220 e.clearSelection();
221 221 });
222 222 };
223 223
224 224 var tooltipActivate = function () {
225 225 var delay = 50;
226 226 var animation = 'fade';
227 227 var theme = 'tooltipster-shadow';
228 228 var debug = false;
229 229
230 230 $('.tooltip').tooltipster({
231 231 debug: debug,
232 232 theme: theme,
233 233 animation: animation,
234 234 delay: delay,
235 235 contentCloning: true,
236 236 contentAsHTML: true,
237 237
238 238 functionBefore: function (instance, helper) {
239 239 var $origin = $(helper.origin);
240 240 var data = '<div style="white-space: pre-wrap">{0}</div>'.format(instance.content());
241 241 instance.content(data);
242 242 }
243 243 });
244 244 var hovercardCache = {};
245 245
246 246 var loadHoverCard = function (url, altHovercard, callback) {
247 247 var id = url;
248 248
249 249 if (hovercardCache[id] !== undefined) {
250 250 callback(hovercardCache[id]);
251 251 return true;
252 252 }
253 253
254 254 hovercardCache[id] = undefined;
255 255 $.get(url, function (data) {
256 256 hovercardCache[id] = data;
257 257 callback(hovercardCache[id]);
258 258 return true;
259 259 }).fail(function (data, textStatus, errorThrown) {
260 260
261 261 if (parseInt(data.status) === 404) {
262 262 var msg = "<p>{0}</p>".format(altHovercard || "No Data exists for this hovercard");
263 263 } else {
264 264 var msg = "<p class='error-message'>Error while fetching hovercard.\nError code {0} ({1}).</p>".format(data.status,data.statusText);
265 265 }
266 266 callback(msg);
267 267 return false
268 268 });
269 269 };
270 270
271 271 $('.tooltip-hovercard').tooltipster({
272 272 debug: debug,
273 273 theme: theme,
274 274 animation: animation,
275 275 delay: delay,
276 276 interactive: true,
277 277 contentCloning: true,
278 278
279 279 trigger: 'custom',
280 280 triggerOpen: {
281 281 mouseenter: true,
282 282 },
283 283 triggerClose: {
284 284 mouseleave: true,
285 285 originClick: true,
286 286 touchleave: true
287 287 },
288 288 content: _gettext('Loading...'),
289 289 contentAsHTML: true,
290 290 updateAnimation: null,
291 291
292 292 functionBefore: function (instance, helper) {
293 293
294 294 var $origin = $(helper.origin);
295 295
296 296 // we set a variable so the data is only loaded once via Ajax, not every time the tooltip opens
297 297 if ($origin.data('loaded') !== true) {
298 298 var hovercardUrl = $origin.data('hovercardUrl');
299 299 var altHovercard = $origin.data('hovercardAlt');
300 300
301 301 if (hovercardUrl !== undefined && hovercardUrl !== "") {
302 302 var urlLoad = true;
303 303 if (hovercardUrl.substr(0, 12) === 'pyroutes.url') {
304 304 hovercardUrl = eval(hovercardUrl)
305 305 } else if (hovercardUrl.substr(0, 11) === 'javascript:') {
306 306 var jsFunc = hovercardUrl.substr(11);
307 307 urlLoad = false;
308 308 loaded = true;
309 309 instance.content(eval(jsFunc))
310 310 }
311 311
312 312 if (urlLoad) {
313 313 var loaded = loadHoverCard(hovercardUrl, altHovercard, function (data) {
314 314 instance.content(data);
315 315 })
316 316 }
317 317
318 318 } else {
319 319 if ($origin.data('hovercardAltHtml')) {
320 320 var data = atob($origin.data('hovercardAltHtml'));
321 321 } else {
322 322 var data = '<div style="white-space: pre-wrap">{0}</div>'.format(altHovercard)
323 323 }
324 324 var loaded = true;
325 325 instance.content(data);
326 326 }
327 327
328 328 // to remember that the data has been loaded
329 329 $origin.data('loaded', loaded);
330 330 }
331 331 }
332 332 })
333 333 };
334 334
335 335 // Formatting values in a Select2 dropdown of commit references
336 336 var formatSelect2SelectionRefs = function(commit_ref){
337 337 var tmpl = '';
338 338 if (!commit_ref.text || commit_ref.type === 'sha'){
339 339 return commit_ref.text;
340 340 }
341 341 if (commit_ref.type === 'branch'){
342 342 tmpl = tmpl.concat('<i class="icon-branch"></i> ');
343 343 } else if (commit_ref.type === 'tag'){
344 344 tmpl = tmpl.concat('<i class="icon-tag"></i> ');
345 345 } else if (commit_ref.type === 'book'){
346 346 tmpl = tmpl.concat('<i class="icon-bookmark"></i> ');
347 347 }
348 348 return tmpl.concat(escapeHtml(commit_ref.text));
349 349 };
350 350
351 351 // takes a given html element and scrolls it down offset pixels
352 352 function offsetScroll(element, offset) {
353 353 setTimeout(function() {
354 354 var location = element.offset().top;
355 355 // some browsers use body, some use html
356 356 $('html, body').animate({ scrollTop: (location - offset) });
357 357 }, 100);
358 358 }
359 359
360 360 // scroll an element `percent`% from the top of page in `time` ms
361 361 function scrollToElement(element, percent, time) {
362 362 percent = (percent === undefined ? 25 : percent);
363 363 time = (time === undefined ? 100 : time);
364 364
365 365 var $element = $(element);
366 366 if ($element.length == 0) {
367 367 throw('Cannot scroll to {0}'.format(element))
368 368 }
369 369 var elOffset = $element.offset().top;
370 370 var elHeight = $element.height();
371 371 var windowHeight = $(window).height();
372 372 var offset = elOffset;
373 373 if (elHeight < windowHeight) {
374 374 offset = elOffset - ((windowHeight / (100 / percent)) - (elHeight / 2));
375 375 }
376 376 setTimeout(function() {
377 377 $('html, body').animate({ scrollTop: offset});
378 378 }, time);
379 379 }
380 380
381 381 /**
382 382 * global hooks after DOM is loaded
383 383 */
384 384 $(document).ready(function() {
385 385 firefoxAnchorFix();
386 386
387 387 $('.navigation a.menulink').on('click', function(e){
388 388 var menuitem = $(this).parent('li');
389 389 if (menuitem.hasClass('open')) {
390 390 menuitem.removeClass('open');
391 391 } else {
392 392 menuitem.addClass('open');
393 393 $(document).on('click', function(event) {
394 394 if (!$(event.target).closest(menuitem).length) {
395 395 menuitem.removeClass('open');
396 396 }
397 397 });
398 398 }
399 399 });
400 400
401 401 $('body').on('click', '.cb-lineno a', function(event) {
402 402 function sortNumber(a,b) {
403 403 return a - b;
404 404 }
405 405
406 406 var lineNo = $(this).data('lineNo');
407 407 var lineName = $(this).attr('name');
408 408
409 409 if (lineNo) {
410 410 var prevLine = $('.cb-line-selected a').data('lineNo');
411 411
412 412 // on shift, we do a range selection, if we got previous line
413 413 if (event.shiftKey && prevLine !== undefined) {
414 414 var prevLine = parseInt(prevLine);
415 415 var nextLine = parseInt(lineNo);
416 416 var pos = [prevLine, nextLine].sort(sortNumber);
417 417 var anchor = '#L{0}-{1}'.format(pos[0], pos[1]);
418 418
419 419 // single click
420 420 } else {
421 421 var nextLine = parseInt(lineNo);
422 422 var pos = [nextLine, nextLine];
423 423 var anchor = '#L{0}'.format(pos[0]);
424 424
425 425 }
426 426 // highlight
427 427 var range = [];
428 428 for (var i = pos[0]; i <= pos[1]; i++) {
429 429 range.push(i);
430 430 }
431 431 // clear old selected lines
432 432 $('.cb-line-selected').removeClass('cb-line-selected');
433 433
434 434 $.each(range, function (i, lineNo) {
435 435 var line_td = $('td.cb-lineno#L' + lineNo);
436 436
437 437 if (line_td.length) {
438 438 line_td.addClass('cb-line-selected'); // line number td
439 439 line_td.prev().addClass('cb-line-selected'); // line data
440 440 line_td.next().addClass('cb-line-selected'); // line content
441 441 }
442 442 });
443 443
444 444 } else if (lineName !== undefined) { // lineName only occurs in diffs
445 445 // clear old selected lines
446 446 $('td.cb-line-selected').removeClass('cb-line-selected');
447 447 var anchor = '#{0}'.format(lineName);
448 448 var diffmode = templateContext.session_attrs.diffmode || "sideside";
449 449
450 450 if (diffmode === "unified") {
451 451 $(this).closest('tr').find('td').addClass('cb-line-selected');
452 452 } else {
453 453 var activeTd = $(this).closest('td');
454 454 activeTd.addClass('cb-line-selected');
455 455 activeTd.next('td').addClass('cb-line-selected');
456 456 }
457 457
458 458 }
459 459
460 460 // Replace URL without jumping to it if browser supports.
461 461 // Default otherwise
462 462 if (history.pushState && anchor !== undefined) {
463 463 var new_location = location.href.rstrip('#');
464 464 if (location.hash) {
465 465 // location without hash
466 466 new_location = new_location.replace(location.hash, "");
467 467 }
468 468
469 469 // Make new anchor url
470 470 new_location = new_location + anchor;
471 471 history.pushState(true, document.title, new_location);
472 472
473 473 return false;
474 474 }
475 475
476 476 });
477 477
478 478 $('.collapse_file').on('click', function(e) {
479 479 e.stopPropagation();
480 480 if ($(e.target).is('a')) { return; }
481 481 var node = $(e.delegateTarget).first();
482 482 var icon = $($(node.children().first()).children().first());
483 483 var id = node.attr('fid');
484 484 var target = $('#'+id);
485 485 var tr = $('#tr_'+id);
486 486 var diff = $('#diff_'+id);
487 487 if(node.hasClass('expand_file')){
488 488 node.removeClass('expand_file');
489 489 icon.removeClass('expand_file_icon');
490 490 node.addClass('collapse_file');
491 491 icon.addClass('collapse_file_icon');
492 492 diff.show();
493 493 tr.show();
494 494 target.show();
495 495 } else {
496 496 node.removeClass('collapse_file');
497 497 icon.removeClass('collapse_file_icon');
498 498 node.addClass('expand_file');
499 499 icon.addClass('expand_file_icon');
500 500 diff.hide();
501 501 tr.hide();
502 502 target.hide();
503 503 }
504 504 });
505 505
506 506 $('#expand_all_files').click(function() {
507 507 $('.expand_file').each(function() {
508 508 var node = $(this);
509 509 var icon = $($(node.children().first()).children().first());
510 510 var id = $(this).attr('fid');
511 511 var target = $('#'+id);
512 512 var tr = $('#tr_'+id);
513 513 var diff = $('#diff_'+id);
514 514 node.removeClass('expand_file');
515 515 icon.removeClass('expand_file_icon');
516 516 node.addClass('collapse_file');
517 517 icon.addClass('collapse_file_icon');
518 518 diff.show();
519 519 tr.show();
520 520 target.show();
521 521 });
522 522 });
523 523
524 524 $('#collapse_all_files').click(function() {
525 525 $('.collapse_file').each(function() {
526 526 var node = $(this);
527 527 var icon = $($(node.children().first()).children().first());
528 528 var id = $(this).attr('fid');
529 529 var target = $('#'+id);
530 530 var tr = $('#tr_'+id);
531 531 var diff = $('#diff_'+id);
532 532 node.removeClass('collapse_file');
533 533 icon.removeClass('collapse_file_icon');
534 534 node.addClass('expand_file');
535 535 icon.addClass('expand_file_icon');
536 536 diff.hide();
537 537 tr.hide();
538 538 target.hide();
539 539 });
540 540 });
541 541
542 542 // Mouse over behavior for comments and line selection
543 543
544 544 // Select the line that comes from the url anchor
545 545 // At the time of development, Chrome didn't seem to support jquery's :target
546 546 // element, so I had to scroll manually
547 547
548 548 if (location.hash) {
549 549 var result = splitDelimitedHash(location.hash);
550 550
551 551 var loc = result.loc;
552 552
553 553 if (loc.length > 1) {
554 554
555 555 var highlightable_line_tds = [];
556 556
557 557 // source code line format
558 558 var page_highlights = loc.substring(loc.indexOf('#') + 1).split('L');
559 559
560 560 // multi-line HL, for files
561 561 if (page_highlights.length > 1) {
562 562 var highlight_ranges = page_highlights[1].split(",");
563 563 var h_lines = [];
564 564 for (var pos in highlight_ranges) {
565 565 var _range = highlight_ranges[pos].split('-');
566 566 if (_range.length === 2) {
567 567 var start = parseInt(_range[0]);
568 568 var end = parseInt(_range[1]);
569 569 if (start < end) {
570 570 for (var i = start; i <= end; i++) {
571 571 h_lines.push(i);
572 572 }
573 573 }
574 574 } else {
575 575 h_lines.push(parseInt(highlight_ranges[pos]));
576 576 }
577 577 }
578 578 for (pos in h_lines) {
579 579 var line_td = $('td.cb-lineno#L' + h_lines[pos]);
580 580 if (line_td.length) {
581 581 highlightable_line_tds.push(line_td);
582 582 }
583 583 }
584 584 }
585 585
586 586 // now check a direct id reference of line in diff / pull-request page)
587 587 if ($(loc).length > 0 && $(loc).hasClass('cb-lineno')) {
588 588 highlightable_line_tds.push($(loc));
589 589 }
590 590
591 591 // mark diff lines as selected
592 592 $.each(highlightable_line_tds, function (i, $td) {
593 593 $td.addClass('cb-line-selected'); // line number td
594 594 $td.prev().addClass('cb-line-selected'); // line data
595 595 $td.next().addClass('cb-line-selected'); // line content
596 596 });
597 597
598 598 if (highlightable_line_tds.length > 0) {
599 599 var $first_line_td = highlightable_line_tds[0];
600 600 scrollToElement($first_line_td);
601 601 $.Topic('/ui/plugins/code/anchor_focus').prepareOrPublish({
602 602 td: $first_line_td,
603 603 remainder: result.remainder
604 604 });
605 605 } else {
606 606 // case for direct anchor to comments
607 607 var $line = $(loc);
608 608
609 609 if ($line.hasClass('comment-general')) {
610 610 $line.show();
611 611 } else if ($line.hasClass('comment-inline')) {
612 612 $line.show();
613 613 var $cb = $line.closest('.cb');
614 614 $cb.removeClass('cb-collapsed')
615 615 }
616 616 if ($line.length > 0) {
617 617 $line.addClass('comment-selected-hl');
618 618 offsetScroll($line, 70);
619 619 }
620 620 if (!$line.hasClass('comment-outdated') && result.remainder === '/ReplyToComment') {
621 $line.nextAll('.cb-comment-add-button').trigger('click');
621 $line.parent().find('.cb-comment-add-button').trigger('click');
622 622 }
623 623 }
624 624
625 625 }
626 626 }
627 627 collapsableContent();
628 628 });
629 629
630 630 var feedLifetimeOptions = function(query, initialData){
631 631 var data = {results: []};
632 632 var isQuery = typeof query.term !== 'undefined';
633 633
634 634 var section = _gettext('Lifetime');
635 635 var children = [];
636 636
637 637 //filter results
638 638 $.each(initialData.results, function(idx, value) {
639 639
640 640 if (!isQuery || query.term.length === 0 || value.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) {
641 641 children.push({
642 642 'id': this.id,
643 643 'text': this.text
644 644 })
645 645 }
646 646
647 647 });
648 648 data.results.push({
649 649 'text': section,
650 650 'children': children
651 651 });
652 652
653 653 if (isQuery) {
654 654
655 655 var now = moment.utc();
656 656
657 657 var parseQuery = function(entry, now){
658 658 var fmt = 'DD/MM/YYYY H:mm';
659 659 var parsed = moment.utc(entry, fmt);
660 660 var diffInMin = parsed.diff(now, 'minutes');
661 661
662 662 if (diffInMin > 0){
663 663 return {
664 664 id: diffInMin,
665 665 text: parsed.format(fmt)
666 666 }
667 667 } else {
668 668 return {
669 669 id: undefined,
670 670 text: parsed.format('DD/MM/YYYY') + ' ' + _gettext('date not in future')
671 671 }
672 672 }
673 673
674 674
675 675 };
676 676
677 677 data.results.push({
678 678 'text': _gettext('Specified expiration date'),
679 679 'children': [{
680 680 'id': parseQuery(query.term, now).id,
681 681 'text': parseQuery(query.term, now).text
682 682 }]
683 683 });
684 684 }
685 685
686 686 query.callback(data);
687 687 };
688 688
689 689 /*
690 690 * Retrievew via templateContext.session_attrs.key
691 691 * */
692 692 var storeUserSessionAttr = function (key, val) {
693 693
694 694 var postData = {
695 695 'key': key,
696 696 'val': val,
697 697 'csrf_token': CSRF_TOKEN
698 698 };
699 699
700 700 var success = function(o) {
701 701 return true
702 702 };
703 703
704 704 ajaxPOST(pyroutes.url('store_user_session_value'), postData, success);
705 705 return false;
706 706 };
707 707
708 708
709 709 var getUserSessionAttr = function(key) {
710 710 var storeKey = templateContext.session_attrs;
711 711 var val = storeKey[key]
712 712 if (val !== undefined) {
713 713 return JSON.parse(val)
714 714 }
715 715 return null
716 716 }
General Comments 0
You need to be logged in to leave comments. Login now