var popupBox = null;

var blameElt;
var mouseElt;

var prevRev;
var prevContent;

var pendingReq;

function updateBlamePopup() {
  if (popupBox) {
    pending_req = null;
    popupBox.remove();
    popupBox = null;
  }

  if (!blameElt) {
    return;
  }

  var rev = blameElt.dataset.rev;
  var link = blameElt.dataset.link;
  var strip = blameElt.dataset.strip;

  function showPopup(content) {
    content += '<br><a href="' + link + '">Show annotated diff</a>';

    var parent = blameElt.parentNode;
    var height = blameElt.getBoundingClientRect().height;

    popupBox = document.createElement("div");
    popupBox.id = "blame-popup";
    popupBox.innerHTML = content;
    popupBox.className = "blame-popup";
    parent.appendChild(popupBox);

    $(popupBox).on("mouseenter", blameHoverHandler);
    $(popupBox).on("mouseleave", blameHoverHandler);
  }

  function reqListener() {
    if (!pendingReq) {
      return;
    }
    pendingReq = null;

    var response = JSON.parse(this.responseText);
    var content = response.header;
    showPopup(content);

    prevRev = rev;
    prevContent = content;
  }

  if (prevRev == rev) {
    showPopup(prevContent);
  } else if (!pendingReq) {
    var req = new XMLHttpRequest();
    pendingReq = req;
    req.addEventListener("load", reqListener);
    req.open("GET", "/mozilla-central/commit-info/" + rev);
    req.send();
  }
}

function blameHoverHandler(event) {
  if ($('#context-menu').length) {
    return;
  }

  if (event.type == "mouseleave") {
    mouseElt = null;

    setTimeout(function() {
      if (!mouseElt) {
        blameElt = null;
        updateBlamePopup();
      }
    }, 100);
  } else {
    var elt = event.target;
    while (elt && elt instanceof Element) {
      if (elt.hasAttribute("data-rev")) {
        mouseElt = elt;
        break;
      }
      if (elt.id == "blame-popup") {
        mouseElt = blameElt;
        return;
      }
      elt = elt.parentNode;
      if (!elt || !(elt instanceof Element)) {
        return;
      }
    }

    blameElt = mouseElt;
    updateBlamePopup();
  }
}

$(".blame-strip").on("mouseenter", blameHoverHandler);
$(".blame-strip").on("mouseleave", blameHoverHandler);


@@ -79,25 +79,8 @@
 t;%0A%0A
-var pendingReq;%0A%0A
 func
@@ -127,32 +127,8 @@
 ) %7B%0A
-    pending_req = null;%0A
     
@@ -214,19 +214,19 @@
 %0A%0A  var 
-rev
+elt
  = blame
@@ -220,32 +220,49 @@
 r elt = blameElt
+;%0A  var rev = elt
 .dataset.rev;%0A  
@@ -272,22 +272,17 @@
  link = 
-blameE
+e
 lt.datas
@@ -304,22 +304,17 @@
 strip = 
-blameE
+e
 lt.datas
@@ -352,24 +352,72 @@
 (content) %7B%0A
+    if (blameElt != elt) %7B%0A      return;%0A    %7D%0A%0A
     content 
@@ -901,75 +901,8 @@
 ) %7B%0A
-    if (!pendingReq) %7B%0A      return;%0A    %7D%0A    pendingReq = null;%0A%0A
     
@@ -1122,25 +1122,8 @@
 else
- if (!pendingReq)
  %7B%0A 
@@ -1161,30 +1161,8 @@
 ();%0A
-    pendingReq = req;%0A
     
@@ -1846,24 +1846,28 @@
 rentNode;%0A  
+  %7D%0A
     if (!elt
@@ -1901,34 +1901,32 @@
 t)) %7B%0A      
-  
 return;%0A
       %7D%0A    
@@ -1909,32 +1909,24 @@
     return;%0A
-      %7D%0A
     %7D%0A%0A    b

Fix blame popup