2929/* ............................................................ */
3030/* utility/helper functions (and variables) */
3131
32- var xhr ; // XMLHttpRequest object
3332var projectUrl ; // partial query + separator ('?' or ';')
3433
3534// 'commits' is an associative map. It maps SHA1s to Commit objects.
@@ -420,8 +419,6 @@ function handleLine(commit, group) {
420419
421420// ----------------------------------------------------------------------
422421
423- var inProgress = false ; // are we processing response
424-
425422/**#@+
426423 * @constant
427424 */
@@ -433,8 +430,6 @@ var endRe = /^END ?([^ ]*) ?(.*)/;
433430var curCommit = new Commit ( ) ;
434431var curGroup = { } ;
435432
436- var pollTimer = null ;
437-
438433/**
439434 * Parse output from 'git blame --incremental [...]', received via
440435 * XMLHttpRequest from server (blamedataUrl), and call handleLine
@@ -535,43 +530,51 @@ function processData(unprocessed, nextReadPos) {
535530 * Handle XMLHttpRequest errors
536531 *
537532 * @param {XMLHttpRequest } xhr: XMLHttpRequest object
533+ * @param {Number } [xhr.pollTimer] ID of the timeout to clear
538534 *
539- * @globals pollTimer, commits, inProgress
535+ * @globals commits
540536 */
541537function handleError ( xhr ) {
542538 errorInfo ( 'Server error: ' +
543539 xhr . status + ' - ' + ( xhr . statusText || 'Error contacting server' ) ) ;
544540
545- clearInterval ( pollTimer ) ;
541+ if ( typeof xhr . pollTimer === "number" ) {
542+ clearTimeout ( xhr . pollTimer ) ;
543+ delete xhr . pollTimer ;
544+ }
546545 commits = { } ; // free memory
547-
548- inProgress = false ;
549546}
550547
551548/**
552549 * Called after XMLHttpRequest finishes (loads)
553550 *
554- * @param {XMLHttpRequest } xhr: XMLHttpRequest object (unused)
551+ * @param {XMLHttpRequest } xhr: XMLHttpRequest object
552+ * @param {Number } [xhr.pollTimer] ID of the timeout to clear
555553 *
556- * @globals pollTimer, commits, inProgress
554+ * @globals commits
557555 */
558556function responseLoaded ( xhr ) {
559- clearInterval ( pollTimer ) ;
557+ if ( typeof xhr . pollTimer === "number" ) {
558+ clearTimeout ( xhr . pollTimer ) ;
559+ delete xhr . pollTimer ;
560+ }
560561
561562 fixColorsAndGroups ( ) ;
562563 writeTimeInterval ( ) ;
563564 commits = { } ; // free memory
564-
565- inProgress = false ;
566565}
567566
568567/**
569568 * handler for XMLHttpRequest onreadystatechange event
570569 * @see startBlame
571570 *
572- * @globals xhr, inProgress
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
573576 */
574- function handleResponse ( ) {
577+ function handleResponse ( xhr , fromTimer ) {
575578
576579 /*
577580 * xhr.readyState
@@ -609,32 +612,31 @@ function handleResponse() {
609612 return ;
610613 }
611614
612- // in case we were called before finished processing
613- if ( inProgress ) {
614- return ;
615- } else {
616- inProgress = true ;
617- }
618615
619616 // extract new whole (complete) lines, and process them
620- while ( xhr . prevDataLength !== xhr . responseText . length ) {
621- if ( xhr . readyState === 4 &&
622- xhr . prevDataLength === xhr . responseText . length ) {
623- break ;
624- }
625-
617+ if ( xhr . prevDataLength !== xhr . responseText . length ) {
626618 xhr . prevDataLength = xhr . responseText . length ;
627619 var unprocessed = xhr . responseText . substring ( xhr . nextReadPos ) ;
628620 xhr . nextReadPos = processData ( unprocessed , xhr . nextReadPos ) ;
629- } // end while
621+ }
630622
631623 // did we finish work?
632- if ( xhr . readyState === 4 &&
633- xhr . prevDataLength === xhr . responseText . length ) {
624+ if ( xhr . readyState === 4 ) {
634625 responseLoaded ( xhr ) ;
626+ return ;
635627 }
636628
637- inProgress = false ;
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+ }
638640}
639641
640642// ============================================================
@@ -649,11 +651,11 @@ function handleResponse() {
649651 * Called from 'blame_incremental' view after loading table with
650652 * file contents, a base for blame view.
651653 *
652- * @globals xhr, t0, projectUrl, div_progress_bar, totalLines, pollTimer
654+ * @globals t0, projectUrl, div_progress_bar, totalLines
653655*/
654656function startBlame ( blamedataUrl , bUrl ) {
655657
656- xhr = createRequestObject ( ) ;
658+ var xhr = createRequestObject ( ) ;
657659 if ( ! xhr ) {
658660 errorInfo ( 'ERROR: XMLHttpRequest not supported' ) ;
659661 return ;
@@ -672,16 +674,19 @@ function startBlame(blamedataUrl, bUrl) {
672674 xhr . prevDataLength = - 1 ; // used to detect if we have new data
673675 xhr . nextReadPos = 0 ; // where unread part of response starts
674676
675- xhr . onreadystatechange = handleResponse ;
676- //xhr.onreadystatechange = function () { handleResponse(xhr); };
677+ xhr . onreadystatechange = function ( ) {
678+ handleResponse ( xhr , false ) ;
679+ } ;
677680
678681 xhr . open ( 'GET' , blamedataUrl ) ;
679682 xhr . setRequestHeader ( 'Accept' , 'text/plain' ) ;
680683 xhr . send ( null ) ;
681684
682685 // not all browsers call onreadystatechange event on each server flush
683686 // poll response using timer every second to handle this issue
684- pollTimer = setInterval ( xhr . onreadystatechange , 1000 ) ;
687+ xhr . pollTimer = setTimeout ( function ( ) {
688+ handleResponse ( xhr , true ) ;
689+ } , 1000 ) ;
685690}
686691
687692/* end of blame_incremental.js */
0 commit comments