travis-web/app/components/log-content.js
2016-01-04 13:15:15 +01:00

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() {}
});