Port addons to new applyAddon API and TypeScript
This commit is contained in:
+15
-23
@@ -44,39 +44,31 @@ gulp.task('tsc', function () {
|
||||
tsResult.dts.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(outDir))
|
||||
);
|
||||
|
||||
fs.emptyDirSync(`${outDir}/addons/attach`);
|
||||
fs.emptyDirSync(`${outDir}/addons/search`);
|
||||
fs.emptyDirSync(`${outDir}/addons/winptyCompat`);
|
||||
let addons = ['attach', 'fit', 'fullscreen', 'search', 'terminado', 'winptyCompat', 'zmodem'];
|
||||
let addonStreams = addons.map(function(addon) {
|
||||
fs.emptyDirSync(`${outDir}/addons/${addon}`);
|
||||
|
||||
let tsProjectAttachAddon = ts.createProject('./src/addons/attach/tsconfig.json');
|
||||
let tsResultAttachAddon = tsProjectAttachAddon.src().pipe(sourcemaps.init()).pipe(tsProjectAttachAddon());
|
||||
let tscAttachAddon = tsResultAttachAddon.js
|
||||
.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''}))
|
||||
.pipe(gulp.dest(`${outDir}/addons/attach`));
|
||||
let tsProjectAddon = ts.createProject(`./src/addons/${addon}/tsconfig.json`);
|
||||
let tsResultAddon = tsProjectAddon.src().pipe(sourcemaps.init()).pipe(tsProjectAddon());
|
||||
let tscAddon = tsResultAddon.js
|
||||
.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''}))
|
||||
.pipe(gulp.dest(`${outDir}/addons/${addon}`));
|
||||
|
||||
let tsProjectSearchAddon = ts.createProject('./src/addons/search/tsconfig.json');
|
||||
let tsResultSearchAddon = tsProjectSearchAddon.src().pipe(sourcemaps.init()).pipe(tsProjectSearchAddon());
|
||||
let tscSearchAddon = tsResultSearchAddon.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(`${outDir}/addons/search`));
|
||||
|
||||
let tsProjectWinptyCompatAddon = ts.createProject('./src/addons/winptyCompat/tsconfig.json');
|
||||
let tsResultWinptyCompatAddon = tsProjectWinptyCompatAddon.src().pipe(sourcemaps.init()).pipe(tsProjectWinptyCompatAddon());
|
||||
let tscWinptyCompatAddon = tsResultWinptyCompatAddon.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest(`${outDir}/addons/winptyCompat`));
|
||||
return tscAddon;
|
||||
});
|
||||
|
||||
// Copy all addons from ${srcDir}/ to ${outDir}/
|
||||
let copyAddons = gulp.src([
|
||||
`${srcDir}/addons/**/*`,
|
||||
`!${srcDir}/addons/attach`,
|
||||
`!${srcDir}/addons/attach/**`,
|
||||
`!${srcDir}/addons/search`,
|
||||
`!${srcDir}/addons/search/**`,
|
||||
`!${srcDir}/addons/winptyCompat`,
|
||||
`!${srcDir}/addons/winptyCompat/**`
|
||||
`${srcDir}/addons/**/**`
|
||||
]).pipe(gulp.dest(`${outDir}/addons`));
|
||||
|
||||
// Copy stylesheets from ${srcDir}/ to ${outDir}/
|
||||
let copyStylesheets = gulp.src(`${srcDir}/**/*.css`).pipe(gulp.dest(outDir));
|
||||
|
||||
return merge(tsc, tscSearchAddon, tscWinptyCompatAddon, copyAddons, copyStylesheets);
|
||||
// Join all streams into a single array
|
||||
let streams = [tsc].concat(addonStreams).concat([copyAddons, copyStylesheets]);
|
||||
|
||||
return merge.apply(this, streams);
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -685,7 +685,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
||||
* @param addon The addon to apply.
|
||||
*/
|
||||
public static applyAddon(addon: any): void {
|
||||
addon.default(Terminal);
|
||||
addon.apply(Terminal);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* Implements the attach method, that attaches the terminal to a WebSocket stream.
|
||||
*/
|
||||
|
||||
(function (attach) {
|
||||
if (typeof exports === 'object' && typeof module === 'object') {
|
||||
/*
|
||||
* CommonJS environment
|
||||
*/
|
||||
module.exports = attach(require('../../Terminal').Terminal);
|
||||
} else if (typeof define == 'function') {
|
||||
/*
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], attach);
|
||||
} else {
|
||||
/*
|
||||
* Plain browser environment
|
||||
*/
|
||||
attach(window.Terminal);
|
||||
}
|
||||
})(function (Terminal) {
|
||||
'use strict';
|
||||
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* Attaches the given terminal to the given socket.
|
||||
*
|
||||
* @param {Terminal} term - The terminal to be attached to the given socket.
|
||||
* @param {WebSocket} socket - The socket to attach the current terminal.
|
||||
* @param {boolean} bidirectional - Whether the terminal should send data
|
||||
* to the socket as well.
|
||||
* @param {boolean} buffered - Whether the rendering of incoming data
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
exports.attach = function (term, socket, bidirectional, buffered) {
|
||||
bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
|
||||
term.socket = socket;
|
||||
|
||||
term._flushBuffer = function () {
|
||||
term.write(term._attachSocketBuffer);
|
||||
term._attachSocketBuffer = null;
|
||||
};
|
||||
|
||||
term._pushToBuffer = function (data) {
|
||||
if (term._attachSocketBuffer) {
|
||||
term._attachSocketBuffer += data;
|
||||
} else {
|
||||
term._attachSocketBuffer = data;
|
||||
setTimeout(term._flushBuffer, 10);
|
||||
}
|
||||
};
|
||||
|
||||
var myTextDecoder;
|
||||
|
||||
term._getMessage = function (ev) {
|
||||
var str;
|
||||
if (typeof ev.data === "object") {
|
||||
if (ev.data instanceof ArrayBuffer) {
|
||||
if (!myTextDecoder) {
|
||||
myTextDecoder = new TextDecoder();
|
||||
}
|
||||
|
||||
str = myTextDecoder.decode( ev.data );
|
||||
}
|
||||
else {
|
||||
throw "TODO: handle Blob?";
|
||||
}
|
||||
}
|
||||
|
||||
if (buffered) {
|
||||
term._pushToBuffer(str || ev.data);
|
||||
} else {
|
||||
term.write(str || ev.data);
|
||||
}
|
||||
};
|
||||
|
||||
term._sendData = function (data) {
|
||||
socket.send(data);
|
||||
};
|
||||
|
||||
socket.addEventListener('message', term._getMessage);
|
||||
|
||||
if (bidirectional) {
|
||||
term.on('data', term._sendData);
|
||||
}
|
||||
|
||||
socket.addEventListener('close', term.detach.bind(term, socket));
|
||||
socket.addEventListener('error', term.detach.bind(term, socket));
|
||||
};
|
||||
|
||||
/**
|
||||
* Detaches the given terminal from the given socket
|
||||
*
|
||||
* @param {Terminal} term - The terminal to be detached from the given socket.
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
exports.detach = function (term, socket) {
|
||||
term.off('data', term._sendData);
|
||||
|
||||
socket = (typeof socket == 'undefined') ? term.socket : socket;
|
||||
|
||||
if (socket) {
|
||||
socket.removeEventListener('message', term._getMessage);
|
||||
}
|
||||
|
||||
delete term.socket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attaches the current terminal to the given socket
|
||||
*
|
||||
* @param {WebSocket} socket - The socket to attach the current terminal.
|
||||
* @param {boolean} bidirectional - Whether the terminal should send data
|
||||
* to the socket as well.
|
||||
* @param {boolean} buffered - Whether the rendering of incoming data
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
Terminal.prototype.attach = function (socket, bidirectional, buffered) {
|
||||
return exports.attach(this, socket, bidirectional, buffered);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detaches the current terminal from the given socket.
|
||||
*
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
Terminal.prototype.detach = function (socket) {
|
||||
return exports.detach(this, socket);
|
||||
};
|
||||
|
||||
return exports;
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
|
||||
import * as attach from './attach'
|
||||
|
||||
class MockTerminal {}
|
||||
|
||||
describe('attach addon', () => {
|
||||
describe('apply', () => {
|
||||
it('should do register the `attach` and `detach` methods', () => {
|
||||
attach.apply(MockTerminal);
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.attach, 'function');
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.detach, 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -16,16 +16,16 @@
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
function attach (term, socket, bidirectional, buffered) {
|
||||
function attach(term, socket, bidirectional, buffered) {
|
||||
bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
|
||||
term.socket = socket;
|
||||
|
||||
term._flushBuffer = function () {
|
||||
term._flushBuffer = function() {
|
||||
term.write(term._attachSocketBuffer);
|
||||
term._attachSocketBuffer = null;
|
||||
};
|
||||
|
||||
term._pushToBuffer = function (data) {
|
||||
term._pushToBuffer = function(data) {
|
||||
if (term._attachSocketBuffer) {
|
||||
term._attachSocketBuffer += data;
|
||||
} else {
|
||||
@@ -36,7 +36,7 @@ function attach (term, socket, bidirectional, buffered) {
|
||||
|
||||
var myTextDecoder;
|
||||
|
||||
term._getMessage = function (ev) {
|
||||
term._getMessage = function(ev) {
|
||||
var str;
|
||||
if (typeof ev.data === "object") {
|
||||
if (ev.data instanceof ArrayBuffer) {
|
||||
@@ -58,7 +58,7 @@ function attach (term, socket, bidirectional, buffered) {
|
||||
}
|
||||
};
|
||||
|
||||
term._sendData = function (data) {
|
||||
term._sendData = function(data) {
|
||||
socket.send(data);
|
||||
};
|
||||
|
||||
@@ -79,7 +79,7 @@ function attach (term, socket, bidirectional, buffered) {
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
function detach (term, socket) {
|
||||
function detach(term, socket) {
|
||||
term.off('data', term._sendData);
|
||||
|
||||
socket = (typeof socket == 'undefined') ? term.socket : socket;
|
||||
@@ -92,7 +92,7 @@ function detach (term, socket) {
|
||||
};
|
||||
|
||||
|
||||
export default function applyOn(terminalConstructor) {
|
||||
export function apply(terminalConstructor) {
|
||||
/**
|
||||
* Attaches the current terminal to the given socket
|
||||
*
|
||||
@@ -103,7 +103,7 @@ export default function applyOn(terminalConstructor) {
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
terminalConstructor.prototype.attach = function (socket, bidirectional, buffered) {
|
||||
terminalConstructor.prototype.attach = function(socket, bidirectional, buffered) {
|
||||
return exports.attach(this, socket, bidirectional, buffered);
|
||||
};
|
||||
|
||||
@@ -113,7 +113,7 @@ export default function applyOn(terminalConstructor) {
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
terminalConstructor.prototype.detach = function (socket) {
|
||||
terminalConstructor.prototype.detach = function(socket) {
|
||||
return exports.detach(this, socket);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* 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('../../Terminal').Terminal);
|
||||
} else if (typeof define == 'function') {
|
||||
/*
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], fit);
|
||||
} else {
|
||||
/*
|
||||
* Plain browser environment
|
||||
*/
|
||||
fit(window.Terminal);
|
||||
}
|
||||
})(function (Terminal) {
|
||||
var exports = {};
|
||||
|
||||
exports.proposeGeometry = function (term) {
|
||||
if (!term.element.parentElement) {
|
||||
return null;
|
||||
}
|
||||
var parentElementStyle = window.getComputedStyle(term.element.parentElement);
|
||||
var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
|
||||
var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17);
|
||||
var elementStyle = window.getComputedStyle(term.element);
|
||||
var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom'));
|
||||
var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left'));
|
||||
var availableHeight = parentElementHeight - elementPaddingVer;
|
||||
var availableWidth = parentElementWidth - elementPaddingHor;
|
||||
var geometry = {
|
||||
cols: Math.floor(availableWidth / term.charMeasure.width),
|
||||
rows: Math.floor(availableHeight / Math.floor(term.charMeasure.height * term.getOption('lineHeight')))
|
||||
};
|
||||
|
||||
return geometry;
|
||||
};
|
||||
|
||||
exports.fit = function (term) {
|
||||
// Wrap fit in a setTimeout as charMeasure needs time to get initialized
|
||||
// after calling Terminal.open
|
||||
setTimeout(function () {
|
||||
var geometry = exports.proposeGeometry(term);
|
||||
|
||||
if (geometry) {
|
||||
// Force a full render
|
||||
if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
|
||||
term.renderer.clear();
|
||||
term.resize(geometry.cols, geometry.rows);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
Terminal.prototype.proposeGeometry = function () {
|
||||
return exports.proposeGeometry(this);
|
||||
};
|
||||
|
||||
Terminal.prototype.fit = function () {
|
||||
return exports.fit(this);
|
||||
};
|
||||
|
||||
return exports;
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
|
||||
import * as fit from './fit'
|
||||
|
||||
class MockTerminal {}
|
||||
|
||||
describe('fit addon', () => {
|
||||
describe('apply', () => {
|
||||
it('should do register the `proposeGeometry` and `fit` methods', () => {
|
||||
fit.apply(MockTerminal);
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.proposeGeometry, 'function');
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.fit, 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* 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 proposeGeometry(term) {
|
||||
if (!term.element.parentElement) {
|
||||
return null;
|
||||
}
|
||||
var parentElementStyle = window.getComputedStyle(term.element.parentElement);
|
||||
var parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
|
||||
var parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17);
|
||||
var elementStyle = window.getComputedStyle(term.element);
|
||||
var elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom'));
|
||||
var elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left'));
|
||||
var availableHeight = parentElementHeight - elementPaddingVer;
|
||||
var availableWidth = parentElementWidth - elementPaddingHor;
|
||||
var geometry = {
|
||||
cols: Math.floor(availableWidth / term.charMeasure.width),
|
||||
rows: Math.floor(availableHeight / Math.floor(term.charMeasure.height * term.getOption('lineHeight')))
|
||||
};
|
||||
|
||||
return geometry;
|
||||
};
|
||||
|
||||
function fit(term) {
|
||||
// Wrap fit in a setTimeout as charMeasure needs time to get initialized
|
||||
// after calling Terminal.open
|
||||
setTimeout(function () {
|
||||
var geometry = exports.proposeGeometry(term);
|
||||
|
||||
if (geometry) {
|
||||
// Force a full render
|
||||
if (term.rows !== geometry.rows || term.cols !== geometry.cols) {
|
||||
term.renderer.clear();
|
||||
term.resize(geometry.cols, geometry.rows);
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
export function apply(terminalConstructor) {
|
||||
terminalConstructor.prototype.proposeGeometry = function () {
|
||||
return proposeGeometry(this);
|
||||
};
|
||||
|
||||
terminalConstructor.prototype.fit = function () {
|
||||
return fit(this);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"rootDir": ".",
|
||||
"outDir": "../../../lib/addons/fit/",
|
||||
"sourceMap": true,
|
||||
"removeComments": true
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
(function (fullscreen) {
|
||||
if (typeof exports === 'object' && typeof module === 'object') {
|
||||
/*
|
||||
* CommonJS environment
|
||||
*/
|
||||
module.exports = fullscreen(require('../../Terminal').Terminal);
|
||||
} else if (typeof define == 'function') {
|
||||
/*
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], fullscreen);
|
||||
} else {
|
||||
/*
|
||||
* Plain browser environment
|
||||
*/
|
||||
fullscreen(window.Terminal);
|
||||
}
|
||||
})(function (Terminal) {
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* Toggle the given terminal's fullscreen mode.
|
||||
* @param {Terminal} term - The terminal to toggle full screen mode
|
||||
* @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false)
|
||||
*/
|
||||
exports.toggleFullScreen = function (term, fullscreen) {
|
||||
var fn;
|
||||
|
||||
if (typeof fullscreen == 'undefined') {
|
||||
fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add';
|
||||
} else if (!fullscreen) {
|
||||
fn = 'remove';
|
||||
} else {
|
||||
fn = 'add';
|
||||
}
|
||||
|
||||
term.element.classList[fn]('fullscreen');
|
||||
};
|
||||
|
||||
Terminal.prototype.toggleFullscreen = function (fullscreen) {
|
||||
exports.toggleFullScreen(this, fullscreen);
|
||||
};
|
||||
|
||||
return exports;
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
|
||||
import * as fullscreen from './fullscreen'
|
||||
|
||||
class MockTerminal {}
|
||||
|
||||
describe('fullscreen addon', () => {
|
||||
describe('apply', () => {
|
||||
it('should do register the `toggleFullscreen` method', () => {
|
||||
fullscreen.apply(MockTerminal);
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.toggleFullScreen, 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/**
|
||||
* Toggle the given terminal's fullscreen mode.
|
||||
* @param {Terminal} term - The terminal to toggle full screen mode
|
||||
* @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false)
|
||||
*/
|
||||
function toggleFullScreen(term, fullscreen) {
|
||||
var fn;
|
||||
|
||||
if (typeof fullscreen == 'undefined') {
|
||||
fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add';
|
||||
} else if (!fullscreen) {
|
||||
fn = 'remove';
|
||||
} else {
|
||||
fn = 'add';
|
||||
}
|
||||
|
||||
term.element.classList[fn]('fullscreen');
|
||||
};
|
||||
|
||||
export function apply(terminalConstructor) {
|
||||
terminalConstructor.prototype.toggleFullScreen = function (fullscreen) {
|
||||
return toggleFullScreen(this, fullscreen);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"rootDir": ".",
|
||||
"outDir": "../../../lib/addons/fullscreen/",
|
||||
"sourceMap": true,
|
||||
"removeComments": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "xterm.search",
|
||||
"main": "search.js",
|
||||
"private": true
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2016 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* This module provides methods for attaching a terminal to a terminado
|
||||
* WebSocket stream.
|
||||
*/
|
||||
|
||||
(function (attach) {
|
||||
if (typeof exports === 'object' && typeof module === 'object') {
|
||||
/*
|
||||
* CommonJS environment
|
||||
*/
|
||||
module.exports = attach(require('../../Terminal').Terminal);
|
||||
} else if (typeof define == 'function') {
|
||||
/*
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], attach);
|
||||
} else {
|
||||
/*
|
||||
* Plain browser environment
|
||||
*/
|
||||
attach(window.Terminal);
|
||||
}
|
||||
})(function (Terminal) {
|
||||
'use strict';
|
||||
|
||||
var exports = {};
|
||||
|
||||
/**
|
||||
* Attaches the given terminal to the given socket.
|
||||
*
|
||||
* @param {Terminal} term - The terminal to be attached to the given socket.
|
||||
* @param {WebSocket} socket - The socket to attach the current terminal.
|
||||
* @param {boolean} bidirectional - Whether the terminal should send data
|
||||
* to the socket as well.
|
||||
* @param {boolean} buffered - Whether the rendering of incoming data
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
exports.terminadoAttach = function (term, socket, bidirectional, buffered) {
|
||||
bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
|
||||
term.socket = socket;
|
||||
|
||||
term._flushBuffer = function () {
|
||||
term.write(term._attachSocketBuffer);
|
||||
term._attachSocketBuffer = null;
|
||||
};
|
||||
|
||||
term._pushToBuffer = function (data) {
|
||||
if (term._attachSocketBuffer) {
|
||||
term._attachSocketBuffer += data;
|
||||
} else {
|
||||
term._attachSocketBuffer = data;
|
||||
setTimeout(term._flushBuffer, 10);
|
||||
}
|
||||
};
|
||||
|
||||
term._getMessage = function (ev) {
|
||||
var data = JSON.parse(ev.data)
|
||||
if( data[0] == "stdout" ) {
|
||||
if (buffered) {
|
||||
term._pushToBuffer(data[1]);
|
||||
} else {
|
||||
term.write(data[1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
term._sendData = function (data) {
|
||||
socket.send(JSON.stringify(['stdin', data]));
|
||||
};
|
||||
|
||||
term._setSize = function (size) {
|
||||
socket.send(JSON.stringify(['set_size', size.rows, size.cols]));
|
||||
};
|
||||
|
||||
socket.addEventListener('message', term._getMessage);
|
||||
|
||||
if (bidirectional) {
|
||||
term.on('data', term._sendData);
|
||||
}
|
||||
term.on('resize', term._setSize);
|
||||
|
||||
socket.addEventListener('close', term.terminadoDetach.bind(term, socket));
|
||||
socket.addEventListener('error', term.terminadoDetach.bind(term, socket));
|
||||
};
|
||||
|
||||
/**
|
||||
* Detaches the given terminal from the given socket
|
||||
*
|
||||
* @param {Xterm} term - The terminal to be detached from the given socket.
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
exports.terminadoDetach = function (term, socket) {
|
||||
term.off('data', term._sendData);
|
||||
|
||||
socket = (typeof socket == 'undefined') ? term.socket : socket;
|
||||
|
||||
if (socket) {
|
||||
socket.removeEventListener('message', term._getMessage);
|
||||
}
|
||||
|
||||
delete term.socket;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attaches the current terminal to the given socket
|
||||
*
|
||||
* @param {WebSocket} socket - The socket to attach the current terminal.
|
||||
* @param {boolean} bidirectional - Whether the terminal should send data
|
||||
* to the socket as well.
|
||||
* @param {boolean} buffered - Whether the rendering of incoming data
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
Terminal.prototype.terminadoAttach = function (socket, bidirectional, buffered) {
|
||||
return exports.terminadoAttach(this, socket, bidirectional, buffered);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detaches the current terminal from the given socket.
|
||||
*
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
Terminal.prototype.terminadoDetach = function (socket) {
|
||||
return exports.terminadoDetach(this, socket);
|
||||
};
|
||||
|
||||
return exports;
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
|
||||
import * as terminado from './terminado'
|
||||
|
||||
class MockTerminal {}
|
||||
|
||||
describe('terminado addon', () => {
|
||||
describe('apply', () => {
|
||||
it('should do register the `terminadoAttach` and `terminadoDetach` methods', () => {
|
||||
terminado.apply(MockTerminal);
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.terminadoAttach, 'function');
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.terminadoDetach, 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2016 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*
|
||||
* This module provides methods for attaching a terminal to a terminado
|
||||
* WebSocket stream.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Attaches the given terminal to the given socket.
|
||||
*
|
||||
* @param {Terminal} term - The terminal to be attached to the given socket.
|
||||
* @param {WebSocket} socket - The socket to attach the current terminal.
|
||||
* @param {boolean} bidirectional - Whether the terminal should send data
|
||||
* to the socket as well.
|
||||
* @param {boolean} buffered - Whether the rendering of incoming data
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
function terminadoAttach(term, socket, bidirectional, buffered) {
|
||||
bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional;
|
||||
term.socket = socket;
|
||||
|
||||
term._flushBuffer = function() {
|
||||
term.write(term._attachSocketBuffer);
|
||||
term._attachSocketBuffer = null;
|
||||
};
|
||||
|
||||
term._pushToBuffer = function(data) {
|
||||
if (term._attachSocketBuffer) {
|
||||
term._attachSocketBuffer += data;
|
||||
} else {
|
||||
term._attachSocketBuffer = data;
|
||||
setTimeout(term._flushBuffer, 10);
|
||||
}
|
||||
};
|
||||
|
||||
term._getMessage = function(ev) {
|
||||
var data = JSON.parse(ev.data)
|
||||
if( data[0] == "stdout" ) {
|
||||
if (buffered) {
|
||||
term._pushToBuffer(data[1]);
|
||||
} else {
|
||||
term.write(data[1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
term._sendData = function(data) {
|
||||
socket.send(JSON.stringify(['stdin', data]));
|
||||
};
|
||||
|
||||
term._setSize = function(size) {
|
||||
socket.send(JSON.stringify(['set_size', size.rows, size.cols]));
|
||||
};
|
||||
|
||||
socket.addEventListener('message', term._getMessage);
|
||||
|
||||
if (bidirectional) {
|
||||
term.on('data', term._sendData);
|
||||
}
|
||||
term.on('resize', term._setSize);
|
||||
|
||||
socket.addEventListener('close', term.terminadoDetach.bind(term, socket));
|
||||
socket.addEventListener('error', term.terminadoDetach.bind(term, socket));
|
||||
};
|
||||
|
||||
/**
|
||||
* Detaches the given terminal from the given socket
|
||||
*
|
||||
* @param {Xterm} term - The terminal to be detached from the given socket.
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
function terminadoDetach(term, socket) {
|
||||
term.off('data', term._sendData);
|
||||
|
||||
socket = (typeof socket == 'undefined') ? term.socket : socket;
|
||||
|
||||
if (socket) {
|
||||
socket.removeEventListener('message', term._getMessage);
|
||||
}
|
||||
|
||||
delete term.socket;
|
||||
};
|
||||
|
||||
export function apply(terminalConstructor) {
|
||||
/**
|
||||
* Attaches the current terminal to the given socket
|
||||
*
|
||||
* @param {WebSocket} socket - The socket to attach the current terminal.
|
||||
* @param {boolean} bidirectional - Whether the terminal should send data
|
||||
* to the socket as well.
|
||||
* @param {boolean} buffered - Whether the rendering of incoming data
|
||||
* should happen instantly or at a maximum
|
||||
* frequency of 1 rendering per 10ms.
|
||||
*/
|
||||
terminalConstructor.prototype.terminadoAttach = function(socket, bidirectional, buffered) {
|
||||
return terminadoAttach(this, socket, bidirectional, buffered);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detaches the current terminal from the given socket.
|
||||
*
|
||||
* @param {WebSocket} socket - The socket from which to detach the current
|
||||
* terminal.
|
||||
*/
|
||||
terminalConstructor.prototype.terminadoDetach = function(socket) {
|
||||
return terminadoDetach(this, socket);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"rootDir": ".",
|
||||
"outDir": "../../../lib/addons/terminado/",
|
||||
"sourceMap": true,
|
||||
"removeComments": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "xterm.winptyCompat",
|
||||
"main": "winptyCompat.js",
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
|
||||
import * as winptyCompat from './winptyCompat'
|
||||
|
||||
class MockTerminal {}
|
||||
|
||||
describe('winptyCompat addon', () => {
|
||||
describe('apply', () => {
|
||||
it('should do register the `winptyCompatInit` method', () => {
|
||||
winptyCompat.apply(MockTerminal);
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.winptyCompatInit, 'function');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,28 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
declare var exports: any;
|
||||
declare var define: any;
|
||||
|
||||
(function (addon) {
|
||||
if (typeof window !== 'undefined' && 'Terminal' in window) {
|
||||
/**
|
||||
* Plain browser environment
|
||||
*/
|
||||
addon((<any>window).Terminal);
|
||||
} else if (typeof exports === 'object' && typeof module === 'object') {
|
||||
/**
|
||||
* CommonJS environment
|
||||
*/
|
||||
module.exports = addon(require('../../Terminal').Terminal);
|
||||
} else if (typeof define === 'function') {
|
||||
/**
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], addon);
|
||||
}
|
||||
})((Terminal: any) => {
|
||||
Terminal.prototype.winptyCompatInit = function(): void {
|
||||
export function apply(terminalConstructor) {
|
||||
terminalConstructor.prototype.winptyCompatInit = function(): void {
|
||||
// Don't do anything when the platform is not Windows
|
||||
const isWindows = ['Windows', 'Win16', 'Win32', 'WinCE'].indexOf(navigator.platform) >= 0;
|
||||
if (!isWindows) {
|
||||
@@ -50,4 +30,4 @@ declare var define: any;
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "xterm.zmodem",
|
||||
"main": "zmodem.js",
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"rootDir": ".",
|
||||
"outDir": "../../../lib/addons/zmodem/",
|
||||
"sourceMap": true,
|
||||
"removeComments": true
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Allow xterm.js to handle ZMODEM uploads and downloads.
|
||||
*
|
||||
* This addon is a wrapper around zmodem.js. It adds the following to the
|
||||
* Terminal class:
|
||||
*
|
||||
* - function `zmodemAttach(<WebSocket>, <Object>)` - creates a Zmodem.Sentry
|
||||
* on the passed WebSocket object. The Object passed is optional and
|
||||
* can contain:
|
||||
* - noTerminalWriteOutsideSession: Suppress writes from the Sentry
|
||||
* object to the Terminal while there is no active Session. This
|
||||
* is necessary for compatibility with, for example, the
|
||||
* `attach.js` addon.
|
||||
*
|
||||
* - event `zmodemDetect` - fired on Zmodem.Sentry’s `on_detect` callback.
|
||||
* Passes the zmodem.js Detection object.
|
||||
*
|
||||
* - event `zmodemRetract` - fired on Zmodem.Sentry’s `on_retract` callback.
|
||||
*
|
||||
* You’ll need to provide logic to handle uploads and downloads.
|
||||
* See zmodem.js’s documentation for more details.
|
||||
*
|
||||
* **IMPORTANT:** After you confirm() a zmodem.js Detection, if you have
|
||||
* used the `attach` or `terminado` addons, you’ll need to suspend their
|
||||
* operation for the duration of the ZMODEM session. (The demo does this
|
||||
* via `detach()` and a re-`attach()`.)
|
||||
*/
|
||||
(function (addon) {
|
||||
if (typeof exports === 'object' && typeof module === 'object') {
|
||||
/*
|
||||
* CommonJS environment
|
||||
*/
|
||||
module.exports = addon(require('../../Terminal').Terminal);
|
||||
} else if (typeof define == 'function') {
|
||||
/*
|
||||
* Require.js is available
|
||||
*/
|
||||
define(['../../xterm'], addon);
|
||||
} else {
|
||||
/*
|
||||
* Plain browser environment
|
||||
*/
|
||||
addon(window.Terminal);
|
||||
}
|
||||
})(function _zmodemAddon(Terminal) {
|
||||
Object.assign(
|
||||
Terminal.prototype,
|
||||
{
|
||||
zmodemAttach: function zmodemAttach(ws, opts) {
|
||||
var term = this;
|
||||
|
||||
if (!opts) opts = {};
|
||||
|
||||
var senderFunc = function _ws_sender_func(octets) {
|
||||
ws.send( new Uint8Array(octets) );
|
||||
};
|
||||
|
||||
var zsentry;
|
||||
|
||||
function _shouldWrite() {
|
||||
return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession;
|
||||
}
|
||||
|
||||
zsentry = new Zmodem.Sentry( {
|
||||
to_terminal: function _to_terminal(octets) {
|
||||
if (_shouldWrite()) {
|
||||
term.write(
|
||||
String.fromCharCode.apply(String, octets)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
sender: senderFunc,
|
||||
|
||||
on_retract: function _on_retract() {
|
||||
term.emit("zmodemRetract");
|
||||
},
|
||||
|
||||
on_detect: function _on_detect(detection) {
|
||||
term.emit("zmodemDetect", detection);
|
||||
},
|
||||
} );
|
||||
|
||||
function handleWSMessage(evt) {
|
||||
|
||||
//In testing with xterm.js’s demo the first message was
|
||||
//always text even if the rest were binary. While that
|
||||
//may be specific to xterm.js’s demo, ultimately we
|
||||
//should reject anything that isn’t binary.
|
||||
if (typeof evt.data === "string") {
|
||||
if (_shouldWrite()) {
|
||||
term.write(evt.data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
zsentry.consume(evt.data);
|
||||
}
|
||||
}
|
||||
|
||||
ws.binaryType = "arraybuffer";
|
||||
ws.addEventListener("message", handleWSMessage);
|
||||
},
|
||||
|
||||
zmodemBrowser: Zmodem.Browser,
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
|
||||
import * as zmodem from './zmodem'
|
||||
|
||||
class MockTerminal {}
|
||||
|
||||
describe('zmodem addon', () => {
|
||||
describe('apply', () => {
|
||||
it('should do register the `zmodemAttach` method and `zmodemBrowser` attribute', () => {
|
||||
zmodem.apply(MockTerminal);
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.zmodemAttach, 'function');
|
||||
assert.equal(typeof (<any>MockTerminal).prototype.zmodemBrowser, 'object');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
*
|
||||
* Allow xterm.js to handle ZMODEM uploads and downloads.
|
||||
*
|
||||
* This addon is a wrapper around zmodem.js. It adds the following to the
|
||||
* Terminal class:
|
||||
*
|
||||
* - function `zmodemAttach(<WebSocket>, <Object>)` - creates a Zmodem.Sentry
|
||||
* on the passed WebSocket object. The Object passed is optional and
|
||||
* can contain:
|
||||
* - noTerminalWriteOutsideSession: Suppress writes from the Sentry
|
||||
* object to the Terminal while there is no active Session. This
|
||||
* is necessary for compatibility with, for example, the
|
||||
* `attach.js` addon.
|
||||
*
|
||||
* - event `zmodemDetect` - fired on Zmodem.Sentry’s `on_detect` callback.
|
||||
* Passes the zmodem.js Detection object.
|
||||
*
|
||||
* - event `zmodemRetract` - fired on Zmodem.Sentry’s `on_retract` callback.
|
||||
*
|
||||
* You’ll need to provide logic to handle uploads and downloads.
|
||||
* See zmodem.js’s documentation for more details.
|
||||
*
|
||||
* **IMPORTANT:** After you confirm() a zmodem.js Detection, if you have
|
||||
* used the `attach` or `terminado` addons, you’ll need to suspend their
|
||||
* operation for the duration of the ZMODEM session. (The demo does this
|
||||
* via `detach()` and a re-`attach()`.)
|
||||
*/
|
||||
|
||||
export function apply(terminalConstructor) {
|
||||
let Zmodem = (typeof window == 'object') ? (<any>window).ZModem : {Browser: null}; // Nullify browser for tests
|
||||
|
||||
terminalConstructor.prototype.zmodemAttach = function(ws, opts) {
|
||||
var term = this;
|
||||
|
||||
if (!opts) opts = {};
|
||||
|
||||
var senderFunc = function _ws_sender_func(octets) {
|
||||
ws.send( new Uint8Array(octets) );
|
||||
};
|
||||
|
||||
var zsentry;
|
||||
|
||||
function _shouldWrite() {
|
||||
return !!zsentry.get_confirmed_session() || !opts.noTerminalWriteOutsideSession;
|
||||
}
|
||||
|
||||
zsentry = new Zmodem.Sentry( {
|
||||
to_terminal: function _to_terminal(octets) {
|
||||
if (_shouldWrite()) {
|
||||
term.write(
|
||||
String.fromCharCode.apply(String, octets)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
sender: senderFunc,
|
||||
|
||||
on_retract: function _on_retract() {
|
||||
term.emit('zmodemRetract');
|
||||
},
|
||||
|
||||
on_detect: function _on_detect(detection) {
|
||||
term.emit('zmodemDetect', detection);
|
||||
},
|
||||
} );
|
||||
|
||||
function handleWSMessage(evt) {
|
||||
|
||||
//In testing with xterm.js’s demo the first message was
|
||||
//always text even if the rest were binary. While that
|
||||
//may be specific to xterm.js’s demo, ultimately we
|
||||
//should reject anything that isn’t binary.
|
||||
if (typeof evt.data === 'string') {
|
||||
if (_shouldWrite()) {
|
||||
term.write(evt.data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
zsentry.consume(evt.data);
|
||||
}
|
||||
}
|
||||
|
||||
ws.binaryType = 'arraybuffer';
|
||||
ws.addEventListener('message', handleWSMessage);
|
||||
}
|
||||
|
||||
terminalConstructor.prototype.zmodemBrowser = Zmodem.Browser
|
||||
}
|
||||
Reference in New Issue
Block a user