29
/* ............................................................ */
30
/* utility/helper functions (and variables) */
31
32
-var xhr; // XMLHttpRequest object
32
var projectUrl; // partial query + separator ('?' or ';')
33
34
// 'commits' is an associative map. It maps SHA1s to Commit objects.
430
var curCommit = new Commit();
431
var curGroup = {};
432
434
-var pollTimer = null;
435
-
433
/**
434
* Parse output from 'git blame --incremental [...]', received via
435
* XMLHttpRequest from server (blamedataUrl), and call handleLine
530
* Handle XMLHttpRequest errors
531
*
532
* @param {XMLHttpRequest} xhr: XMLHttpRequest object
533
+ * @param {Number} [xhr.pollTimer] ID of the timeout to clear
534
*
537
- * @globals pollTimer, commits
535
+ * @globals commits
536
*/
537
function handleError(xhr) {
538
errorInfo('Server error: ' +
539
xhr.status + ' - ' + (xhr.statusText || 'Error contacting server'));
540
543
- clearInterval(pollTimer);
541
+ if (typeof xhr.pollTimer === "number") {
542
+ clearTimeout(xhr.pollTimer);
543
+ delete xhr.pollTimer;
544
+ }
545
commits = {}; // free memory
546
}
547
548
/**
549
* Called after XMLHttpRequest finishes (loads)
550
*
550
- * @param {XMLHttpRequest} xhr: XMLHttpRequest object (unused)
551
+ * @param {XMLHttpRequest} xhr: XMLHttpRequest object
552
+ * @param {Number} [xhr.pollTimer] ID of the timeout to clear
553
*
552
- * @globals pollTimer, commits
554
+ * @globals commits
555
*/
556
function responseLoaded(xhr) {
555
- clearInterval(pollTimer);
557
+ if (typeof xhr.pollTimer === "number") {
558
+ clearTimeout(xhr.pollTimer);
559
+ delete xhr.pollTimer;
560
+ }
561
562
fixColorsAndGroups();
563
writeTimeInterval();
568
* handler for XMLHttpRequest onreadystatechange event
569
* @see startBlame
570
*
566
- * @globals xhr
571
+ * @param {XMLHttpRequest} xhr: XMLHttpRequest object
572
+ * @param {Number} xhr.prevDataLength: previous value of xhr.responseText.length
573
+ * @param {Number} xhr.nextReadPos: start of unread part of xhr.responseText
574
+ * @param {Number} [xhr.pollTimer] ID of the timeout (to reset or cancel)
575
+ * @param {Boolean} fromTimer: if handler was called from timer
576
*/
568
-function handleResponse() {
577
+function handleResponse(xhr, fromTimer) {
578
579
/*
580
* xhr.readyState
623
// did we finish work?
624
if (xhr.readyState === 4) {
625
responseLoaded(xhr);
626
+ return;
627
+ }
628
+
629
+ // if we get from timer, we have to restart it
630
+ // otherwise onreadystatechange gives us partial response, timer not needed
631
+ if (fromTimer) {
632
+ setTimeout(function () {
633
+ handleResponse(xhr, true);
634
+ }, 1000);
635
+
636
+ } else if (typeof xhr.pollTimer === "number") {
637
+ clearTimeout(xhr.pollTimer);
638
+ delete xhr.pollTimer;
639
}
640
}
641
651
* Called from 'blame_incremental' view after loading table with
652
* file contents, a base for blame view.
653
*
632
- * @globals xhr, t0, projectUrl, div_progress_bar, totalLines, pollTimer
654
+ * @globals t0, projectUrl, div_progress_bar, totalLines
655
*/
656
function startBlame(blamedataUrl, bUrl) {
657
636
- xhr = createRequestObject();
658
+ var xhr = createRequestObject();
659
if (!xhr) {
660
errorInfo('ERROR: XMLHttpRequest not supported');
661
return;
674
xhr.prevDataLength = -1; // used to detect if we have new data
675
xhr.nextReadPos = 0; // where unread part of response starts
676
655
- xhr.onreadystatechange = handleResponse;
656
- //xhr.onreadystatechange = function () { handleResponse(xhr); };
677
+ xhr.onreadystatechange = function () {
678
+ handleResponse(xhr, false);
679
+ };
680
681
xhr.open('GET', blamedataUrl);
682
xhr.setRequestHeader('Accept', 'text/plain');
684
685
// not all browsers call onreadystatechange event on each server flush
686
// poll response using timer every second to handle this issue
664
- pollTimer = setInterval(xhr.onreadystatechange, 1000);
687
+ xhr.pollTimer = setTimeout(function () {
688
+ handleResponse(xhr, true);
689
+ }, 1000);
690
}
691
692
/* end of blame_incremental.js */