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);