Add xterm.js 2.1.0 and a wrapper class to the asset pipeline
This commit is contained in:
parent
dcddd0f374
commit
7c2e16d053
6 changed files with 4596 additions and 0 deletions
62
app/assets/javascripts/terminal/terminal.js.es6
Normal file
62
app/assets/javascripts/terminal/terminal.js.es6
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* global Terminal */
|
||||
|
||||
(() => {
|
||||
class GLTerminal {
|
||||
|
||||
constructor(options) {
|
||||
this.options = options || {};
|
||||
|
||||
this.options.cursorBlink = options.cursorBlink || true;
|
||||
this.options.screenKeys = options.screenKeys || true;
|
||||
this.container = document.querySelector(options.selector);
|
||||
|
||||
this.setSocketUrl();
|
||||
this.createTerminal();
|
||||
$(window).off('resize.terminal').on('resize.terminal', () => {
|
||||
this.terminal.fit();
|
||||
});
|
||||
}
|
||||
|
||||
setSocketUrl() {
|
||||
const { protocol, hostname, port } = window.location;
|
||||
const wsProtocol = protocol === 'https:' ? 'wss://' : 'ws://';
|
||||
const path = this.container.dataset.projectPath;
|
||||
|
||||
this.socketUrl = `${wsProtocol}${hostname}:${port}${path}`;
|
||||
}
|
||||
|
||||
createTerminal() {
|
||||
this.terminal = new Terminal(this.options);
|
||||
this.socket = new WebSocket(this.socketUrl, ['terminal.gitlab.com']);
|
||||
this.socket.binaryType = 'arraybuffer';
|
||||
|
||||
this.terminal.open(this.container);
|
||||
this.socket.onopen = () => { this.runTerminal(); };
|
||||
this.socket.onerror = () => { this.handleSocketFailure(); };
|
||||
}
|
||||
|
||||
runTerminal() {
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
const encoder = new TextEncoder('utf-8');
|
||||
|
||||
this.terminal.on('data', (data) => {
|
||||
this.socket.send(encoder.encode(data));
|
||||
});
|
||||
|
||||
this.socket.addEventListener('message', (ev) => {
|
||||
this.terminal.write(decoder.decode(ev.data));
|
||||
});
|
||||
|
||||
this.isTerminalInitialized = true;
|
||||
this.terminal.fit();
|
||||
}
|
||||
|
||||
handleSocketFailure() {
|
||||
this.terminal.write('\r\nConnection failure');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.gl = window.gl || {};
|
||||
gl.Terminal = GLTerminal;
|
||||
})();
|
5
app/assets/javascripts/terminal/terminal_bundle.js.es6
Normal file
5
app/assets/javascripts/terminal/terminal_bundle.js.es6
Normal file
|
@ -0,0 +1,5 @@
|
|||
//= require xterm/xterm.js
|
||||
//= require xterm/fit.js
|
||||
//= require ./terminal.js
|
||||
|
||||
$(() => new gl.Terminal({ selector: '#terminal' }));
|
|
@ -89,6 +89,7 @@ module Gitlab
|
|||
config.assets.precompile << "mailers/*.css"
|
||||
config.assets.precompile << "katex.css"
|
||||
config.assets.precompile << "katex.js"
|
||||
config.assets.precompile << "xterm/xterm.css"
|
||||
config.assets.precompile << "graphs/graphs_bundle.js"
|
||||
config.assets.precompile << "users/users_bundle.js"
|
||||
config.assets.precompile << "network/network_bundle.js"
|
||||
|
@ -102,6 +103,7 @@ module Gitlab
|
|||
config.assets.precompile << "environments/environments_bundle.js"
|
||||
config.assets.precompile << "blob_edit/blob_edit_bundle.js"
|
||||
config.assets.precompile << "snippet/snippet_bundle.js"
|
||||
config.assets.precompile << "terminal/terminal_bundle.js"
|
||||
config.assets.precompile << "lib/utils/*.js"
|
||||
config.assets.precompile << "lib/*.js"
|
||||
config.assets.precompile << "u2f.js"
|
||||
|
|
86
vendor/assets/javascripts/xterm/fit.js
vendored
Normal file
86
vendor/assets/javascripts/xterm/fit.js
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Fit terminal columns and rows to the dimensions of its
|
||||
* DOM element.
|
||||
*
|
||||
* Approach:
|
||||
* - Rows: Truncate the division of the terminal parent element height
|
||||
* by the terminal row height
|
||||
*
|
||||
* - Columns: Truncate the division of the terminal parent element width by
|
||||
* the terminal character width (apply display: inline at the
|
||||
* terminal row and truncate its width with the current number
|
||||
* of columns)
|
||||
*/
|
||||
(function (fit) {
|
||||
if (typeof exports === 'object' && typeof module === 'object') {
|
||||
/*
|
||||
* CommonJS environment
|
||||
*/
|
||||
module.exports = fit(require('../../xterm'));
|
||||
} else if (typeof define == 'function') {
|
||||
/*
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], fit);
|
||||
} else {
|
||||
/*
|
||||
* Plain browser environment
|
||||
*/
|
||||
fit(window.Terminal);
|
||||
}
|
||||
})(function (Xterm) {
|
||||
/**
|
||||
* This module provides methods for fitting a terminal's size to a parent container.
|
||||
*
|
||||
* @module xterm/addons/fit/fit
|
||||
*/
|
||||
var exports = {};
|
||||
|
||||
exports.proposeGeometry = function (term) {
|
||||
var parentElementStyle = window.getComputedStyle(term.element.parentElement),
|
||||
parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
|
||||
parentElementWidth = parseInt(parentElementStyle.getPropertyValue('width')),
|
||||
elementStyle = window.getComputedStyle(term.element),
|
||||
elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
|
||||
elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')),
|
||||
availableHeight = parentElementHeight - elementPaddingVer,
|
||||
availableWidth = parentElementWidth - elementPaddingHor,
|
||||
container = term.rowContainer,
|
||||
subjectRow = term.rowContainer.firstElementChild,
|
||||
contentBuffer = subjectRow.innerHTML,
|
||||
characterHeight,
|
||||
rows,
|
||||
characterWidth,
|
||||
cols,
|
||||
geometry;
|
||||
|
||||
subjectRow.style.display = 'inline';
|
||||
subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace
|
||||
characterWidth = subjectRow.getBoundingClientRect().width;
|
||||
subjectRow.style.display = ''; // Revert style before calculating height, since they differ.
|
||||
characterHeight = parseInt(subjectRow.offsetHeight);
|
||||
subjectRow.innerHTML = contentBuffer;
|
||||
|
||||
rows = parseInt(availableHeight / characterHeight);
|
||||
cols = parseInt(availableWidth / characterWidth) - 1;
|
||||
|
||||
geometry = {cols: cols, rows: rows};
|
||||
return geometry;
|
||||
};
|
||||
|
||||
exports.fit = function (term) {
|
||||
var geometry = exports.proposeGeometry(term);
|
||||
|
||||
term.resize(geometry.cols, geometry.rows);
|
||||
};
|
||||
|
||||
Xterm.prototype.proposeGeometry = function () {
|
||||
return exports.proposeGeometry(this);
|
||||
};
|
||||
|
||||
Xterm.prototype.fit = function () {
|
||||
return exports.fit(this);
|
||||
};
|
||||
|
||||
return exports;
|
||||
});
|
2235
vendor/assets/javascripts/xterm/xterm.js
vendored
Normal file
2235
vendor/assets/javascripts/xterm/xterm.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
2206
vendor/assets/stylesheets/xterm/xterm.css
vendored
Normal file
2206
vendor/assets/stylesheets/xterm/xterm.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue