Merge branch 'maint'
[gitweb.git] / gitweb / static / js / blame_incremental.js
index 27955ecd3786a1dee447e91d0f7ff4bb0bfcb189..db6eb505846aedfaca1cdbaf6f4d399d049de777 100644 (file)
@@ -29,7 +29,6 @@
 /* ............................................................ */
 /* utility/helper functions (and variables) */
 
-var xhr;        // XMLHttpRequest object
 var projectUrl; // partial query + separator ('?' or ';')
 
 // 'commits' is an associative map. It maps SHA1s to Commit objects.
@@ -431,8 +430,6 @@ var endRe  = /^END ?([^ ]*) ?(.*)/;
 var curCommit = new Commit();
 var curGroup  = {};
 
-var pollTimer = null;
-
 /**
  * Parse output from 'git blame --incremental [...]', received via
  * XMLHttpRequest from server (blamedataUrl), and call handleLine
@@ -533,26 +530,34 @@ function processData(unprocessed, nextReadPos) {
  * Handle XMLHttpRequest errors
  *
  * @param {XMLHttpRequest} xhr: XMLHttpRequest object
+ * @param {Number} [xhr.pollTimer] ID of the timeout to clear
  *
- * @globals pollTimer, commits
+ * @globals commits
  */
 function handleError(xhr) {
        errorInfo('Server error: ' +
                xhr.status + ' - ' + (xhr.statusText || 'Error contacting server'));
 
-       clearInterval(pollTimer);
+       if (typeof xhr.pollTimer === "number") {
+               clearTimeout(xhr.pollTimer);
+               delete xhr.pollTimer;
+       }
        commits = {}; // free memory
 }
 
 /**
  * Called after XMLHttpRequest finishes (loads)
  *
- * @param {XMLHttpRequest} xhr: XMLHttpRequest object (unused)
+ * @param {XMLHttpRequest} xhr: XMLHttpRequest object
+ * @param {Number} [xhr.pollTimer] ID of the timeout to clear
  *
- * @globals pollTimer, commits
+ * @globals commits
  */
 function responseLoaded(xhr) {
-       clearInterval(pollTimer);
+       if (typeof xhr.pollTimer === "number") {
+               clearTimeout(xhr.pollTimer);
+               delete xhr.pollTimer;
+       }
 
        fixColorsAndGroups();
        writeTimeInterval();
@@ -563,9 +568,13 @@ function responseLoaded(xhr) {
  * handler for XMLHttpRequest onreadystatechange event
  * @see startBlame
  *
- * @globals xhr
+ * @param {XMLHttpRequest} xhr: XMLHttpRequest object
+ * @param {Number} xhr.prevDataLength: previous value of xhr.responseText.length
+ * @param {Number} xhr.nextReadPos: start of unread part of xhr.responseText
+ * @param {Number} [xhr.pollTimer] ID of the timeout (to reset or cancel)
+ * @param {Boolean} fromTimer: if handler was called from timer
  */
-function handleResponse() {
+function handleResponse(xhr, fromTimer) {
 
        /*
         * xhr.readyState
@@ -614,6 +623,19 @@ function handleResponse() {
        // did we finish work?
        if (xhr.readyState === 4) {
                responseLoaded(xhr);
+               return;
+       }
+
+       // if we get from timer, we have to restart it
+       // otherwise onreadystatechange gives us partial response, timer not needed
+       if (fromTimer) {
+               setTimeout(function () {
+                       handleResponse(xhr, true);
+               }, 1000);
+
+       } else if (typeof xhr.pollTimer === "number") {
+               clearTimeout(xhr.pollTimer);
+               delete xhr.pollTimer;
        }
 }
 
@@ -629,11 +651,11 @@ function handleResponse() {
  * Called from 'blame_incremental' view after loading table with
  * file contents, a base for blame view.
  *
- * @globals xhr, t0, projectUrl, div_progress_bar, totalLines, pollTimer
+ * @globals t0, projectUrl, div_progress_bar, totalLines
 */
 function startBlame(blamedataUrl, bUrl) {
 
-       xhr = createRequestObject();
+       var xhr = createRequestObject();
        if (!xhr) {
                errorInfo('ERROR: XMLHttpRequest not supported');
                return;
@@ -652,8 +674,9 @@ function startBlame(blamedataUrl, bUrl) {
        xhr.prevDataLength = -1;  // used to detect if we have new data
        xhr.nextReadPos = 0;      // where unread part of response starts
 
-       xhr.onreadystatechange = handleResponse;
-       //xhr.onreadystatechange = function () { handleResponse(xhr); };
+       xhr.onreadystatechange = function () {
+               handleResponse(xhr, false);
+       };
 
        xhr.open('GET', blamedataUrl);
        xhr.setRequestHeader('Accept', 'text/plain');
@@ -661,7 +684,9 @@ function startBlame(blamedataUrl, bUrl) {
 
        // not all browsers call onreadystatechange event on each server flush
        // poll response using timer every second to handle this issue
-       pollTimer = setInterval(xhr.onreadystatechange, 1000);
+       xhr.pollTimer = setTimeout(function () {
+               handleResponse(xhr, true);
+       }, 1000);
 }
 
 /* end of blame_incremental.js */