nci/static/js/app/components/terminal/terminal.js

132 lines
3.3 KiB
JavaScript
Raw Normal View History

2015-05-07 21:55:40 +00:00
'use strict';
define([
2015-06-14 15:24:03 +00:00
'underscore',
2015-05-07 21:55:40 +00:00
'react',
'reflux',
2015-05-10 16:53:33 +00:00
'app/stores/terminal',
2015-12-17 19:41:51 +00:00
'app/stores/build',
2015-06-14 15:24:03 +00:00
'ansi_up',
2015-12-17 19:41:51 +00:00
'templates/app/components/terminal/terminal'
], function(
_,
React,
Reflux,
terminalStore,
buildStore,
ansiUp,
template
) {
2015-05-07 21:55:40 +00:00
var Component = React.createClass({
mixins: [Reflux.ListenerMixin],
2015-12-02 21:27:09 +00:00
2015-11-18 20:14:46 +00:00
shouldScrollBottom: true,
2015-12-02 21:27:09 +00:00
data: [],
2015-11-29 20:29:39 +00:00
linesCount: 0,
2015-12-02 21:27:09 +00:00
2015-05-07 21:55:40 +00:00
componentDidMount: function() {
2015-05-10 16:53:33 +00:00
this.listenTo(terminalStore, this.updateItems);
2015-12-02 21:27:09 +00:00
var node = document.getElementsByClassName('terminal')[0];
this.initialScrollPosition = node.getBoundingClientRect().top;
2015-12-17 19:41:51 +00:00
if (this.props.showPreloader) {
this.getTerminal().insertAdjacentHTML('afterend',
'<img src="/images/preloader.gif" class="terminal_preloader"/>'
);
this.listenTo(buildStore, function(build) {
if (build.completed) {
this.removePreloader();
}
});
}
2015-12-02 18:57:44 +00:00
2015-12-03 17:21:41 +00:00
window.onscroll = this.onScroll;
2015-12-02 21:27:09 +00:00
},
2015-12-17 19:41:51 +00:00
removePreloader: function() {
var preloader = document.getElementsByClassName(
'terminal_preloader'
)[0];
preloader.parentNode.removeChild(preloader);
},
2015-12-02 21:27:09 +00:00
componentWillUnmount: function() {
2015-12-03 17:21:41 +00:00
window.onscroll = null;
2015-05-07 21:55:40 +00:00
},
2015-11-29 20:29:39 +00:00
prepareRow: function(row) {
return ansiUp.ansi_to_html(row.replace('\r', ''));
},
2015-11-18 20:14:46 +00:00
prepareOutput: function(output) {
2015-11-29 20:29:39 +00:00
var self = this;
2015-11-18 20:14:46 +00:00
return output.map(function(row) {
2015-11-29 20:29:39 +00:00
return self.prepareRow(row);
2015-11-18 20:14:46 +00:00
});
2015-06-14 15:24:03 +00:00
},
2015-12-03 17:21:41 +00:00
getTerminal: function() {
return document.getElementsByClassName('terminal')[0];
},
getBody: function() {
return document.getElementsByTagName('body')[0];
},
2015-12-02 18:57:44 +00:00
onScroll: function() {
2015-12-03 17:21:41 +00:00
var node = this.getTerminal(),
body = this.getBody();
this.shouldScrollBottom = window.innerHeight + body.scrollTop >=
node.offsetHeight + this.initialScrollPosition;
2015-06-14 15:24:03 +00:00
},
2015-12-02 18:57:44 +00:00
ensureScrollPosition: function() {
2015-11-18 20:14:46 +00:00
if (this.shouldScrollBottom) {
2015-12-03 17:21:41 +00:00
var node = this.getTerminal(),
body = this.getBody();
body.scrollTop = this.initialScrollPosition + node.offsetHeight;
2015-11-18 20:14:46 +00:00
}
2015-07-08 20:37:31 +00:00
},
2015-11-29 20:29:39 +00:00
makeCodeLineContent: function(line) {
return '<span class="code-line_counter">' + '</span>' +
'<div class="code-line_body">' + this.prepareRow(line) + '</div>';
},
makeCodeLine: function(line, index) {
return '<div class="code-line" data-number="' + index + '">' +
this.makeCodeLineContent(line) + '</div>';
},
2015-12-02 18:57:44 +00:00
renderBuffer: _.throttle(function() {
var data = this.data,
currentLinesCount = data.length,
2015-12-03 17:21:41 +00:00
terminal = document.getElementsByClassName('terminal_code')[0],
rows = terminal.childNodes;
2015-11-29 20:29:39 +00:00
2015-12-02 18:57:44 +00:00
if (rows.length) {
// replace our last node
var index = this.linesCount - 1;
2015-12-03 17:21:41 +00:00
rows[index].innerHTML = this.makeCodeLineContent(data[index]);
2015-12-02 18:57:44 +00:00
}
2015-11-29 20:29:39 +00:00
2015-12-02 18:57:44 +00:00
var self = this;
2015-12-03 17:21:41 +00:00
terminal.insertAdjacentHTML('beforeend',
2015-12-02 18:57:44 +00:00
_(data.slice(this.linesCount)).map(function(line, index) {
return self.makeCodeLine(line, self.linesCount + index);
}).join('')
);
2015-11-29 20:29:39 +00:00
2015-12-02 18:57:44 +00:00
this.linesCount = currentLinesCount;
this.ensureScrollPosition();
}, 100),
updateItems: function(build) {
// listen just our console update
if (build.buildId === this.props.build) {
this.data = build.data;
this.renderBuffer();
2015-05-10 16:53:33 +00:00
}
2015-12-17 19:41:51 +00:00
if (this.props.showPreloader && build.buildCompleted) {
this.removePreloader();
}
2015-05-07 21:55:40 +00:00
},
2015-11-29 20:29:39 +00:00
shouldComponentUpdate: function() {
return false;
},
2015-12-03 17:21:41 +00:00
render: template
2015-05-07 21:55:40 +00:00
});
return Component;
});