228 lines
5.9 KiB
JavaScript
228 lines
5.9 KiB
JavaScript
import Ember from 'ember';
|
|
import LinesSelector from 'travis/utils/lines-selector';
|
|
import LogFolder from 'travis/utils/log-folder';
|
|
import config from 'travis/config/environment';
|
|
import { plainTextLog as plainTextLogUrl } from 'travis/utils/urls';
|
|
|
|
Log.DEBUG = false;
|
|
|
|
Log.LIMIT = 10000;
|
|
|
|
Log.Scroll = function(options) {
|
|
options = options || {};
|
|
this.beforeScroll = options.beforeScroll;
|
|
return this;
|
|
};
|
|
|
|
Log.Scroll.prototype = $.extend(new Log.Listener(), {
|
|
insert: function(log, data, pos) {
|
|
if (this.numbers) {
|
|
this.tryScroll();
|
|
}
|
|
return true;
|
|
},
|
|
tryScroll: function() {
|
|
var element, ref;
|
|
if (element = $("#log p:visible.highlight:first")) {
|
|
if (this.beforeScroll) {
|
|
this.beforeScroll();
|
|
}
|
|
$('#main').scrollTop(0);
|
|
return $('html, body').scrollTop(((ref = element.offset()) != null ? ref.top : void 0) - (window.innerHeight / 3));
|
|
}
|
|
}
|
|
});
|
|
|
|
Log.Limit = function(max_lines, limitedLogCallback) {
|
|
this.max_lines = max_lines || 1000;
|
|
this.limitedLogCallback = limitedLogCallback || (function() {});
|
|
return this;
|
|
};
|
|
|
|
Log.Limit.prototype = Log.extend(new Log.Listener(), {
|
|
count: 0,
|
|
insert: function(log, node, pos) {
|
|
if (node.type === 'paragraph' && !node.hidden) {
|
|
this.count += 1;
|
|
if (this.limited) {
|
|
this.limitedLogCallback();
|
|
}
|
|
return this.count;
|
|
}
|
|
}
|
|
});
|
|
|
|
Object.defineProperty(Log.Limit.prototype, 'limited', {
|
|
get: function() {
|
|
return this.count >= this.max_lines;
|
|
}
|
|
});
|
|
|
|
export default Ember.Component.extend({
|
|
popup: Ember.inject.service(),
|
|
currentUserBinding: 'auth.currentUser',
|
|
|
|
didInsertElement() {
|
|
if (Log.DEBUG) {
|
|
console.log('log view: did insert');
|
|
}
|
|
this._super.apply(this, arguments);
|
|
return this.createEngine();
|
|
},
|
|
|
|
willDestroyElement() {
|
|
if (Log.DEBUG) {
|
|
console.log('log view: will destroy');
|
|
}
|
|
return this.teardownLog();
|
|
},
|
|
|
|
teardownLog(log) {
|
|
var logElement, parts, ref;
|
|
if (log || (log = this.get('log'))) {
|
|
parts = log.get('parts');
|
|
parts.removeArrayObserver(this, {
|
|
didChange: 'partsDidChange',
|
|
willChange: 'noop'
|
|
});
|
|
parts.destroy();
|
|
log.notifyPropertyChange('parts');
|
|
if ((ref = this.lineSelector) != null) {
|
|
ref.willDestroy();
|
|
}
|
|
if (logElement = this.$('#log')) {
|
|
return logElement.empty();
|
|
}
|
|
}
|
|
},
|
|
|
|
createEngine(log) {
|
|
var logElement;
|
|
if (log || (log = this.get('log'))) {
|
|
if (logElement = this.$('#log')) {
|
|
logElement.empty();
|
|
}
|
|
log.onClear(() => {
|
|
this.teardownLog();
|
|
return this.createEngine();
|
|
});
|
|
this.scroll = new Log.Scroll({
|
|
beforeScroll: () => {
|
|
return this.unfoldHighlight();
|
|
}
|
|
});
|
|
this.limit = new Log.Limit(Log.LIMIT, () => {
|
|
return this.set('limited', true);
|
|
});
|
|
this.engine = Log.create({
|
|
listeners: [this.scroll, this.limit]
|
|
});
|
|
this.engine.limit = this.limit;
|
|
this.logFolder = new LogFolder(this.$('#log'));
|
|
this.lineSelector = new LinesSelector(this.$('#log'), this.scroll, this.logFolder);
|
|
return this.observeParts(log);
|
|
}
|
|
},
|
|
|
|
didUpdateAttrs(changes) {
|
|
this._super.apply(this, arguments);
|
|
if (!changes.oldAttrs) {
|
|
return;
|
|
}
|
|
if (changes.newAttrs.job.value && changes.oldAttrs.job.value && changes.newAttrs.job.value !== changes.oldAttrs.job.value) {
|
|
this.teardownLog(changes.oldAttrs.job.value.get('log'));
|
|
return this.createEngine(changes.newAttrs.job.value.get('log'));
|
|
}
|
|
},
|
|
|
|
unfoldHighlight() {
|
|
return this.lineSelector.unfoldLines();
|
|
},
|
|
|
|
observeParts(log) {
|
|
var parts;
|
|
if (log || (log = this.get('log'))) {
|
|
parts = log.get('parts');
|
|
parts.addArrayObserver(this, {
|
|
didChange: 'partsDidChange',
|
|
willChange: 'noop'
|
|
});
|
|
parts = parts.slice(0);
|
|
return this.partsDidChange(parts, 0, null, parts.length);
|
|
}
|
|
},
|
|
|
|
partsDidChange(parts, start, _, added) {
|
|
var i, j, len, part, ref, ref1, ref2, results;
|
|
if (Log.DEBUG) {
|
|
console.log('log view: parts did change');
|
|
}
|
|
if (this.get('state') !== 'inDOM') {
|
|
return;
|
|
}
|
|
ref = parts.slice(start, start + added);
|
|
results = [];
|
|
for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
|
part = ref[i];
|
|
if ((ref1 = this.engine) != null ? (ref2 = ref1.limit) != null ? ref2.limited : void 0 : void 0) {
|
|
break;
|
|
}
|
|
results.push(this.engine.set(part.number, part.content));
|
|
}
|
|
return results;
|
|
},
|
|
|
|
plainTextLogUrl: function() {
|
|
var id, url;
|
|
if (id = this.get('log.job.id')) {
|
|
url = plainTextLogUrl(id);
|
|
if (config.pro) {
|
|
url += "&access_token=" + (this.get('job.log.token'));
|
|
}
|
|
return url;
|
|
}
|
|
}.property('job.log.id', 'job.log.token'),
|
|
|
|
hasPermission: function() {
|
|
var permissions;
|
|
if (permissions = this.get('currentUser.permissions')) {
|
|
return permissions.contains(parseInt(this.get('job.repo.id')));
|
|
}
|
|
}.property('currentUser.permissions.length', 'job.repo.id'),
|
|
|
|
canRemoveLog: function() {
|
|
var job;
|
|
if (job = this.get('job')) {
|
|
return job.get('canRemoveLog') && this.get('hasPermission');
|
|
}
|
|
}.property('job.canRemoveLog', 'hasPermission'),
|
|
|
|
showToTop: function() {
|
|
return this.get('log.hasContent') && this.get('job.canRemoveLog');
|
|
}.property('log.hasContent', 'job.canRemoveLog'),
|
|
|
|
showTailing: Ember.computed.alias('showToTop'),
|
|
|
|
actions: {
|
|
toTop() {
|
|
Travis.tailing.stop();
|
|
return $(window).scrollTop(0);
|
|
},
|
|
|
|
toggleTailing() {
|
|
Travis.tailing.toggle();
|
|
this.engine.autoCloseFold = !Travis.tailing.isActive();
|
|
return event.preventDefault();
|
|
},
|
|
|
|
removeLogPopup() {
|
|
if (this.get('canRemoveLog')) {
|
|
this.get('popup').open('remove-log-popup');
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
|
|
noop() {}
|
|
});
|