Convert log-content component to js

This commit is contained in:
Piotr Sarnacki 2015-12-30 10:36:08 +01:00
parent 7f74787b91
commit f6b95a9a9a
2 changed files with 227 additions and 157 deletions

View File

@ -1,157 +0,0 @@
`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 = (options) ->
options ||= {}
@beforeScroll = options.beforeScroll
this
Log.Scroll.prototype = $.extend new Log.Listener,
insert: (log, data, pos) ->
@tryScroll() if @numbers
true
tryScroll: ->
if element = $("#log p:visible.highlight:first")
if @beforeScroll
@beforeScroll()
$('#main').scrollTop(0)
$('html, body').scrollTop(element.offset()?.top - (window.innerHeight / 3)) # weird, html works in chrome, body in firefox
Log.Limit = (max_lines, limitedLogCallback) ->
@max_lines = max_lines || 1000
@limitedLogCallback = limitedLogCallback || (->)
this
Log.Limit.prototype = Log.extend new Log.Listener,
count: 0,
insert: (log, node, pos) ->
if node.type == 'paragraph' && !node.hidden
@count += 1
if @limited
@limitedLogCallback()
return @count
Object.defineProperty Log.Limit.prototype, 'limited',
get: ->
@count >= @max_lines
LogContentComponent = Ember.Component.extend
popup: Ember.inject.service()
currentUserBinding: 'auth.currentUser'
didInsertElement: ->
console.log 'log view: did insert' if Log.DEBUG
@_super.apply this, arguments
@createEngine()
willDestroyElement: ->
console.log 'log view: will destroy' if Log.DEBUG
@teardownLog()
teardownLog: (log) ->
if log || log = @get('log')
parts = log.get('parts')
parts.removeArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
parts.destroy()
log.notifyPropertyChange('parts')
@lineSelector?.willDestroy()
if logElement = this.$('#log')
logElement.empty()
createEngine: (log) ->
if log || log = @get('log')
if logElement = this.$('#log')
logElement.empty()
log.onClear =>
@teardownLog()
@createEngine()
@scroll = new Log.Scroll beforeScroll: =>
@unfoldHighlight()
@limit = new Log.Limit Log.LIMIT, =>
@set('limited', true)
@engine = Log.create(listeners: [@scroll, @limit])
@engine.limit = @limit
@logFolder = new LogFolder(@$('#log'))
@lineSelector = new LinesSelector(@$('#log'), @scroll, @logFolder)
@observeParts(log)
didUpdateAttrs: (changes) ->
@_super.apply(this, arguments)
return unless changes.oldAttrs
if changes.newAttrs.job.value && changes.oldAttrs.job.value &&
changes.newAttrs.job.value != changes.oldAttrs.job.value
@teardownLog(changes.oldAttrs.job.value.get('log'))
@createEngine(changes.newAttrs.job.value.get('log'))
unfoldHighlight: ->
@lineSelector.unfoldLines()
observeParts: (log) ->
if log || log = @get('log')
parts = log.get('parts')
parts.addArrayObserver(@, didChange: 'partsDidChange', willChange: 'noop')
parts = parts.slice(0)
@partsDidChange(parts, 0, null, parts.length)
partsDidChange: (parts, start, _, added) ->
console.log 'log view: parts did change' if Log.DEBUG
return unless @get('state') == 'inDOM'
for part, i in parts.slice(start, start + added)
# console.log "limit in log view: #{@get('limited')}"
break if @engine?.limit?.limited
@engine.set(part.number, part.content)
plainTextLogUrl: (->
if id = @get('log.job.id')
url = plainTextLogUrl(id)
if config.pro
url += "&access_token=#{@get('job.log.token')}"
url
).property('job.log.id', 'job.log.token')
hasPermission: (->
if permissions = @get('currentUser.permissions')
permissions.contains parseInt(@get('job.repo.id'))
).property('currentUser.permissions.length', 'job.repo.id')
canRemoveLog: (->
if job = @get('job')
job.get('canRemoveLog') && @get('hasPermission')
).property('job.canRemoveLog', 'hasPermission')
showToTop: (->
@get('log.hasContent') && @get('job.canRemoveLog')
).property('log.hasContent', 'job.canRemoveLog')
showTailing: Ember.computed.alias('showToTop')
actions:
toTop: () ->
Travis.tailing.stop()
$(window).scrollTop(0)
toggleTailing: ->
Travis.tailing.toggle()
@engine.autoCloseFold = !Travis.tailing.isActive()
event.preventDefault()
removeLogPopup: ->
if @get('canRemoveLog')
@get('popup').open('remove-log-popup')
return false
noop: -> # TODO required?
`export default LogContentComponent`

View File

@ -0,0 +1,227 @@
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 false;
},
removeLogPopup() {
if (this.get('canRemoveLog')) {
this.get('popup').open('remove-log-popup');
return false;
}
}
},
noop() {}
});