diff --git a/changelog.html b/changelog.html index 5a916a6cfc896902e1b495b17ddbc99fc28aec03..8dcb0e9ae7bd80c50c0625c67ee24611298ae0be 100644 --- a/changelog.html +++ b/changelog.html @@ -58,6 +58,9 @@ Upcoming changes
  • Fix French translation (issue 13274) +
  • + Avoid doing AJAX updates if the page becomes invisible. + (pull 506)
  • Added a new extension point to listen to polling activities. (issue 14178) diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js index 6c2155982038871b94fa888e2cfef5de7fe62bd4..a5759ee88699016c0a671c43ef7f6325b4157292 100644 --- a/war/src/main/webapp/scripts/hudson-behavior.js +++ b/war/src/main/webapp/scripts/hudson-behavior.js @@ -36,6 +36,50 @@ function object(o) { return new F(); } +/** + * A function that returns false if the page is known to be invisible. + */ +var isPageVisible = (function(){ + // @see https://developer.mozilla.org/en/DOM/Using_the_Page_Visibility_API + // Set the name of the hidden property and the change event for visibility + var hidden, visibilityChange; + if (typeof document.hidden !== "undefined") { + hidden = "hidden"; + visibilityChange = "visibilitychange"; + } else if (typeof document.mozHidden !== "undefined") { + hidden = "mozHidden"; + visibilityChange = "mozvisibilitychange"; + } else if (typeof document.msHidden !== "undefined") { + hidden = "msHidden"; + visibilityChange = "msvisibilitychange"; + } else if (typeof document.webkitHidden !== "undefined") { + hidden = "webkitHidden"; + visibilityChange = "webkitvisibilitychange"; + } + + // By default, visibility set to true + var pageIsVisible = true; + + // If the page is hidden, prevent any polling + // if the page is shown, restore pollings + function onVisibilityChange() { + pageIsVisible = !document[hidden]; + } + + // Warn if the browser doesn't support addEventListener or the Page Visibility API + if (typeof document.addEventListener !== "undefined" && typeof hidden !== "undefined") { + // Init the value to the real state of the page + pageIsVisible = !document[hidden]; + + // Handle page visibility change + document.addEventListener(visibilityChange, onVisibilityChange, false); + } + + return function() { + return pageIsVisible; + } +})(); + // id generator var iota = 0; @@ -1439,26 +1483,33 @@ function expandTextArea(button,id) { // by using the contents fetched from the given URL. function refreshPart(id,url) { var f = function() { - new Ajax.Request(url, { - onSuccess: function(rsp) { - var hist = $(id); - var p = hist.up(); - var next = hist.next(); - p.removeChild(hist); + if(isPageVisible()) { + new Ajax.Request(url, { + onSuccess: function(rsp) { + var hist = $(id); + var p = hist.up(); + var next = hist.next(); + p.removeChild(hist); - var div = document.createElement('div'); - div.innerHTML = rsp.responseText; + var div = document.createElement('div'); + div.innerHTML = rsp.responseText; - var node = $(div).firstDescendant(); - p.insertBefore(node, next); + var node = $(div).firstDescendant(); + p.insertBefore(node, next); - Behaviour.applySubtree(node); - layoutUpdateCallback.call(); + Behaviour.applySubtree(node); + layoutUpdateCallback.call(); - if(isRunAsTest) return; - refreshPart(id,url); - } - }); + if(isRunAsTest) return; + refreshPart(id,url); + } + }); + } else { + // Reschedule + if(isRunAsTest) return; + refreshPart(id,url); + } + }; // if run as test, just do it once and do it now to make sure it's working, // but don't repeat. @@ -1534,35 +1585,40 @@ function updateBuildHistory(ajaxUrl,nBuild) { $('buildHistory').headers = ["n",nBuild]; function updateBuilds() { - var bh = $('buildHistory'); - if (bh.headers == null) { - // Yahoo.log("Missing headers in buildHistory element"); - } - new Ajax.Request(ajaxUrl, { - requestHeaders: bh.headers, - onSuccess: function(rsp) { - var rows = bh.rows; - - //delete rows with transitive data - while (rows.length > 2 && Element.hasClassName(rows[1], "transitive")) - Element.remove(rows[1]); - - // insert new rows - var div = document.createElement('div'); - div.innerHTML = rsp.responseText; - Behaviour.applySubtree(div); + if(isPageVisible()){ + var bh = $('buildHistory'); + if (bh.headers == null) { + // Yahoo.log("Missing headers in buildHistory element"); + } + new Ajax.Request(ajaxUrl, { + requestHeaders: bh.headers, + onSuccess: function(rsp) { + var rows = bh.rows; + + //delete rows with transitive data + while (rows.length > 2 && Element.hasClassName(rows[1], "transitive")) + Element.remove(rows[1]); + + // insert new rows + var div = document.createElement('div'); + div.innerHTML = rsp.responseText; + Behaviour.applySubtree(div); + + var pivot = rows[0]; + var newRows = $(div).firstDescendant().rows; + for (var i = newRows.length - 1; i >= 0; i--) { + pivot.parentNode.insertBefore(newRows[i], pivot.nextSibling); + } - var pivot = rows[0]; - var newRows = $(div).firstDescendant().rows; - for (var i = newRows.length - 1; i >= 0; i--) { - pivot.parentNode.insertBefore(newRows[i], pivot.nextSibling); + // next update + bh.headers = ["n",rsp.getResponseHeader("n")]; + window.setTimeout(updateBuilds, 5000); } - - // next update - bh.headers = ["n",rsp.getResponseHeader("n")]; - window.setTimeout(updateBuilds, 5000); - } - }); + }); + } else { + // Reschedule again + window.setTimeout(updateBuilds, 5000); + } } window.setTimeout(updateBuilds, 5000); }