From 094c94c0fb1390117d851eecfd91e6abb9169adc Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Sun, 28 Jun 2015 09:14:48 +0300 Subject: [PATCH] Add messaging when archived build logs loads fail. This code also checks for an ad blocker, and adjusts the message accordingly. Fixes #184 --- static/css/directives/ui/build-logs-view.css | 5 + static/directives/build-logs-view.html | 22 ++- static/js/directives/ui/build-logs-view.js | 17 +- static/js/services/util-service.js | 23 +++ static/lib/blockadblock.js | 186 +++++++++++++++++++ 5 files changed, 245 insertions(+), 8 deletions(-) create mode 100644 static/lib/blockadblock.js diff --git a/static/css/directives/ui/build-logs-view.css b/static/css/directives/ui/build-logs-view.css index 746a6c1d7..a6e17bca5 100644 --- a/static/css/directives/ui/build-logs-view.css +++ b/static/css/directives/ui/build-logs-view.css @@ -9,6 +9,11 @@ min-height: 100px; } +.build-logs-view .co-alert { + margin-bottom: 0px; + color: black !important; +} + .build-logs-view .no-logs { color: #8C8C8C; } diff --git a/static/directives/build-logs-view.html b/static/directives/build-logs-view.html index aa79cec8a..25c9f0c11 100644 --- a/static/directives/build-logs-view.html +++ b/static/directives/build-logs-view.html @@ -1,15 +1,27 @@
- + + Copy Logs + + + target="_blank" + ng-if="logEntries"> Download Logs - + + +
+ Loading of build logs failed, most likely due to an ad blocker. Please + disable filtering and refresh this page. +
+ +
+ Failed to log builds logs. Please reload and try again. +
(Waiting for build to start) diff --git a/static/js/directives/ui/build-logs-view.js b/static/js/directives/ui/build-logs-view.js index 0bc9fb350..478481d2e 100644 --- a/static/js/directives/ui/build-logs-view.js +++ b/static/js/directives/ui/build-logs-view.js @@ -14,7 +14,7 @@ angular.module('quay').directive('buildLogsView', function () { 'buildUpdated': '&buildUpdated' }, controller: function($scope, $element, $interval, $sanitize, ansi2html, AngularViewArray, - AngularPollChannel, ApiService, Restangular) { + AngularPollChannel, ApiService, Restangular, UtilService) { var result = $element.find('#copyButton').clipboardCopy(); if (!result) { @@ -26,6 +26,7 @@ angular.module('quay').directive('buildLogsView', function () { $scope.logStartIndex = 0; $scope.buildLogsText = ''; $scope.currentBuild = null; + $scope.loadError = null; var pollChannel = null; @@ -112,12 +113,22 @@ angular.module('quay').directive('buildLogsView', function () { ApiService.getRepoBuildLogsAsResource(params, true).withOptions(options).get(function(resp) { // If we get a logs url back, then we need to make another XHR request to retrieve the // data. - if (resp['logs_url']) { + var logsUrl = resp['logs_url']; + if (logsUrl) { $.ajax({ - url: resp['logs_url'], + url: logsUrl, }).done(function(r) { handleLogsData(r, callback); + }).error(function(xhr) { + if (xhr.status == 0) { + UtilService.isAdBlockEnabled(function(result) { + $scope.loadError = result ? 'blocked': 'request-failed'; + }); + } else { + $scope.loadError = 'request-failed'; + } }); + return; } diff --git a/static/js/services/util-service.js b/static/js/services/util-service.js index 9e33a659f..8a233de63 100644 --- a/static/js/services/util-service.js +++ b/static/js/services/util-service.js @@ -4,6 +4,29 @@ angular.module('quay').factory('UtilService', ['$sanitize', function($sanitize) { var utilService = {}; + var adBlockEnabled = null; + + utilService.isAdBlockEnabled = function(callback) { + if (adBlockEnabled !== null) { + callback(adBlockEnabled); + return; + } + + if(typeof blockAdBlock === 'undefined') { + callback(true); + return; + } + + var bab = new BlockAdBlock({ + checkOnLoad: false, + resetOnEnd: true + }); + + bab.onDetected(function() { adBlockEnabled = true; callback(true); }); + bab.onNotDetected(function() { adBlockEnabled = false; callback(false); }); + bab.check(); + }; + utilService.isEmailAddress = function(val) { var emailRegex = /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; return emailRegex.test(val); diff --git a/static/lib/blockadblock.js b/static/lib/blockadblock.js new file mode 100644 index 000000000..7bedffa33 --- /dev/null +++ b/static/lib/blockadblock.js @@ -0,0 +1,186 @@ +/* + * BlockAdBlock 3.1.1 + * Copyright (c) 2015 Valentin Allaire + * Released under the MIT license + * https://github.com/sitexw/BlockAdBlock + */ + +(function(window) { + var BlockAdBlock = function(options) { + this._options = { + checkOnLoad: false, + resetOnEnd: false, + loopCheckTime: 50, + loopMaxNumber: 5, + baitClass: 'pub_300x250 pub_300x250m pub_728x90 text-ad textAd text_ad text_ads text-ads text-ad-links', + baitStyle: 'width: 1px !important; height: 1px !important; position: absolute !important; left: -10000px !important; top: -1000px !important;' + }; + this._var = { + version: '3.1.1', + bait: null, + checking: false, + loop: null, + loopNumber: 0, + event: { detected: [], notDetected: [] } + }; + if(options !== undefined) { + this.setOption(options); + } + var self = this; + var eventCallback = function() { + setTimeout(function() { + if(self._options.checkOnLoad === true) { + if(self._var.bait === null) { + self._creatBait(); + } + setTimeout(function() { + self.check(); + }, 1); + } + }, 1); + }; + if(window.addEventListener !== undefined) { + window.addEventListener('load', eventCallback, false); + } else { + window.attachEvent('onload', eventCallback); + } + }; + BlockAdBlock.prototype._options = null; + BlockAdBlock.prototype._var = null; + BlockAdBlock.prototype._bait = null; + + BlockAdBlock.prototype.setOption = function(options, value) { + if(value !== undefined) { + var key = options; + options = {}; + options[key] = value; + } + for(var option in options) { + this._options[option] = options[option]; + } + return this; + }; + + BlockAdBlock.prototype._creatBait = function() { + var bait = document.createElement('div'); + bait.setAttribute('class', this._options.baitClass); + bait.setAttribute('style', this._options.baitStyle); + this._var.bait = window.document.body.appendChild(bait); + + this._var.bait.offsetParent; + this._var.bait.offsetHeight; + this._var.bait.offsetLeft; + this._var.bait.offsetTop; + this._var.bait.offsetWidth; + this._var.bait.clientHeight; + this._var.bait.clientWidth; + }; + BlockAdBlock.prototype._destroyBait = function() { + window.document.body.removeChild(this._var.bait); + this._var.bait = null; + }; + + BlockAdBlock.prototype.check = function(loop) { + if(loop === undefined) { + loop = true; + } + + if(this._var.checking === true) { + return false; + } + this._var.checking = true; + + if(this._var.bait === null) { + this._creatBait(); + } + + var self = this; + this._var.loopNumber = 0; + if(loop === true) { + this._var.loop = setInterval(function() { + self._checkBait(loop); + }, this._options.loopCheckTime); + } + this._checkBait(loop); + + return true; + }; + BlockAdBlock.prototype._checkBait = function(loop) { + var detected = false; + + if(this._var.bait === null) { + this._creatBait(); + } + + if(window.document.body.getAttribute('abp') !== null + || this._var.bait.offsetParent === null + || this._var.bait.offsetHeight == 0 + || this._var.bait.offsetLeft == 0 + || this._var.bait.offsetTop == 0 + || this._var.bait.offsetWidth == 0 + || this._var.bait.clientHeight == 0 + || this._var.bait.clientWidth == 0) { + detected = true; + } + if(window.getComputedStyle !== undefined) { + var baitTemp = window.getComputedStyle(this._var.bait, null); + if(baitTemp.getPropertyValue('display') == 'none' + || baitTemp.getPropertyValue('visibility') == 'hidden') { + detected = true; + } + } + + if(loop === true) { + this._var.loopNumber++; + if(this._var.loopNumber >= this._options.loopMaxNumber) { + clearInterval(this._var.loop); + this._var.loop = null; + this._var.loopNumber = 0; + } + } + + if(detected === true) { + if(loop === true) { + this._var.checking = false; + } + this._destroyBait(); + this.emitEvent(true); + } else if(this._var.loop === null || loop === false) { + if(loop === true) { + this._var.checking = false; + } + this._destroyBait(); + this.emitEvent(false); + } + }; + + BlockAdBlock.prototype.emitEvent = function(detected) { + var fns = this._var.event[(detected===true?'detected':'notDetected')]; + for(var i in fns) { + if(fns.hasOwnProperty(i)) { + fns[i](); + } + } + if(this._options.resetOnEnd === true) { + this.clearEvent(); + } + return this; + }; + BlockAdBlock.prototype.clearEvent = function() { + this._var.event.detected = []; + this._var.event.notDetected = []; + }; + + BlockAdBlock.prototype.on = function(detected, fn) { + this._var.event[(detected===true?'detected':'notDetected')].push(fn); + return this; + }; + BlockAdBlock.prototype.onDetected = function(fn) { + return this.on(true, fn); + }; + BlockAdBlock.prototype.onNotDetected = function(fn) { + return this.on(false, fn); + }; + + window.BlockAdBlock = BlockAdBlock; +})(window);