diff --git a/static/js/services/angular-poll-channel.js b/static/js/services/angular-poll-channel.js index adba49757..f4028a65f 100644 --- a/static/js/services/angular-poll-channel.js +++ b/static/js/services/angular-poll-channel.js @@ -1,7 +1,8 @@ /** * Specialized class for conducting an HTTP poll, while properly preventing multiple calls. */ -angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', function(ApiService, $timeout) { +angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', 'DocumentVisibilityService', + function(ApiService, $timeout, DocumentVisibilityService) { var _PollChannel = function(scope, requester, opt_sleeptime) { this.scope_ = scope; this.requester_ = requester; @@ -50,6 +51,12 @@ angular.module('quay').factory('AngularPollChannel', ['ApiService', '$timeout', _PollChannel.prototype.call_ = function() { if (this.working) { return; } + // If the document is currently hidden, skip the call. + if (DocumentVisibilityService.isHidden()) { + this.setupTimer_(); + return; + } + var that = this; this.working = true; this.scope_.$apply(function() { diff --git a/static/js/services/document-visibility-service.js b/static/js/services/document-visibility-service.js new file mode 100644 index 000000000..f56ecc633 --- /dev/null +++ b/static/js/services/document-visibility-service.js @@ -0,0 +1,60 @@ +/** + * Helper service which fires off events when the document's visibility changes, as well as allowing + * other Angular code to query the state of the document's visibility directly. + */ +angular.module('quay').constant('CORE_EVENT', { + DOC_VISIBILITY_CHANGE: 'core.event.doc_visibility_change' +}); + +angular.module('quay').factory('DocumentVisibilityService', ['$rootScope', '$document', 'CORE_EVENT', + function($rootScope, $document, CORE_EVENT) { + var document = $document[0], + features, + detectedFeature; + + function broadcastChangeEvent() { + $rootScope.$broadcast(CORE_EVENT.DOC_VISIBILITY_CHANGE, + document[detectedFeature.propertyName]); + } + + features = { + standard: { + eventName: 'visibilitychange', + propertyName: 'hidden' + }, + moz: { + eventName: 'mozvisibilitychange', + propertyName: 'mozHidden' + }, + ms: { + eventName: 'msvisibilitychange', + propertyName: 'msHidden' + }, + webkit: { + eventName: 'webkitvisibilitychange', + propertyName: 'webkitHidden' + } + }; + + Object.keys(features).some(function(feature) { + if (document[features[feature].propertyName] !== undefined) { + detectedFeature = features[feature]; + return true; + } + }); + + if (detectedFeature) { + $document.on(detectedFeature.eventName, broadcastChangeEvent); + } + + return { + /** + * Is the window currently hidden or not. + */ + isHidden: function() { + if (detectedFeature) { + return document[detectedFeature.propertyName]; + } + } + }; +}]); \ No newline at end of file