Skip to content

Commit

Permalink
Merge branch 'master' into no_confusing
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar authored Aug 24, 2023
2 parents 2fe082b + 2835976 commit f9dc26d
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 78 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
"warn",
{ "ignoreArrowShorthand": true }
],
"@typescript-eslint/no-useless-constructor": "warn",
"@typescript-eslint/prefer-namespace-keyword": "warn",
"@typescript-eslint/type-annotation-spacing": "warn",
"@typescript-eslint/quotes": [
Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"files.associations": {
".eslintrc.json.typings": "jsonc"
},
"typescript.preferences.importModuleSpecifier": "non-relative",
"typescript.preferences.quoteStyle": "single",
"mochaExplorer.envPath": ".mocha.env",
Expand Down
2 changes: 0 additions & 2 deletions addons/xterm-addon-fit/src/FitAddon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ const MINIMUM_ROWS = 1;
export class FitAddon implements ITerminalAddon {
private _terminal: Terminal | undefined;

constructor() {}

public activate(terminal: Terminal): void {
this._terminal = terminal;
}
Expand Down
2 changes: 0 additions & 2 deletions addons/xterm-addon-serialize/src/SerializeAddon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,6 @@ class StringSerializeHandler extends BaseSerializeHandler {
export class SerializeAddon implements ITerminalAddon {
private _terminal: Terminal | undefined;

constructor() { }

public activate(terminal: Terminal): void {
this._terminal = terminal;
}
Expand Down
55 changes: 29 additions & 26 deletions demo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ let socket;
let pid;
let autoResize: boolean = true;

type AddonType = 'attach' | 'canvas' | 'fit' | 'image' | 'search' | 'serialize' | 'unicode11' | 'web-links' | 'webgl' | 'ligatures';
type AddonType = 'attach' | 'canvas' | 'fit' | 'image' | 'search' | 'serialize' | 'unicode11' | 'webLinks' | 'webgl' | 'ligatures';

interface IDemoAddon<T extends AddonType> {
name: T;
Expand All @@ -71,7 +71,7 @@ interface IDemoAddon<T extends AddonType> {
T extends 'image' ? typeof ImageAddon :
T extends 'search' ? typeof SearchAddon :
T extends 'serialize' ? typeof SerializeAddon :
T extends 'web-links' ? typeof WebLinksAddon :
T extends 'webLinks' ? typeof WebLinksAddon :
T extends 'unicode11' ? typeof Unicode11Addon :
T extends 'ligatures' ? typeof LigaturesAddon :
typeof WebglAddon
Expand All @@ -83,7 +83,7 @@ interface IDemoAddon<T extends AddonType> {
T extends 'image' ? ImageAddon :
T extends 'search' ? SearchAddon :
T extends 'serialize' ? SerializeAddon :
T extends 'web-links' ? WebLinksAddon :
T extends 'webLinks' ? WebLinksAddon :
T extends 'webgl' ? WebglAddon :
T extends 'unicode11' ? typeof Unicode11Addon :
T extends 'ligatures' ? typeof LigaturesAddon :
Expand All @@ -98,7 +98,7 @@ const addons: { [T in AddonType]: IDemoAddon<T> } = {
image: { name: 'image', ctor: ImageAddon, canChange: true },
search: { name: 'search', ctor: SearchAddon, canChange: true },
serialize: { name: 'serialize', ctor: SerializeAddon, canChange: true },
'web-links': { name: 'web-links', ctor: WebLinksAddon, canChange: true },
webLinks: { name: 'webLinks', ctor: WebLinksAddon, canChange: true },
webgl: { name: 'webgl', ctor: WebglAddon, canChange: true },
unicode11: { name: 'unicode11', ctor: Unicode11Addon, canChange: true },
ligatures: { name: 'ligatures', ctor: LigaturesAddon, canChange: true }
Expand Down Expand Up @@ -170,7 +170,7 @@ const disposeRecreateButtonHandler: () => void = () => {
addons.serialize.instance = undefined;
addons.unicode11.instance = undefined;
addons.ligatures.instance = undefined;
addons['web-links'].instance = undefined;
addons.webLinks.instance = undefined;
addons.webgl.instance = undefined;
document.getElementById('dispose').innerHTML = 'Recreate Terminal';
} else {
Expand Down Expand Up @@ -272,13 +272,13 @@ function createTerminal(): void {
} catch (e) {
console.warn(e);
}
addons['web-links'].instance = new WebLinksAddon();
addons.webLinks.instance = new WebLinksAddon();
typedTerm.loadAddon(addons.fit.instance);
typedTerm.loadAddon(addons.image.instance);
typedTerm.loadAddon(addons.search.instance);
typedTerm.loadAddon(addons.serialize.instance);
typedTerm.loadAddon(addons.unicode11.instance);
typedTerm.loadAddon(addons['web-links'].instance);
typedTerm.loadAddon(addons.webLinks.instance);

window.term = term; // Expose `term` to window for debugging purposes
term.onResize((size: { cols: number, rows: number }) => {
Expand Down Expand Up @@ -418,10 +418,13 @@ function initOptions(term: TerminalType): void {
'cancelEvents',
'convertEol',
'termName',
'cols', 'rows', // subsumed by "size" (cols_rows) option
'cols', 'rows', // subsumed by "size" (colsRows) option
// Complex option
'linkHandler',
'logger',
'theme',
'windowOptions'
'windowOptions',
'windowsPty'
];
const stringOptions = {
cursorStyle: ['block', 'underline', 'bar'],
Expand All @@ -433,7 +436,7 @@ function initOptions(term: TerminalType): void {
logLevel: ['trace', 'debug', 'info', 'warn', 'error', 'off'],
theme: ['default', 'xtermjs', 'sapphire', 'light'],
wordSeparator: null,
cols_rows: null
colsRows: null
};
const options = Object.getOwnPropertyNames(term.options);
const booleanOptions = [];
Expand Down Expand Up @@ -466,7 +469,7 @@ function initOptions(term: TerminalType): void {
});
html += '</div><div class="option-group">';
Object.keys(stringOptions).forEach(o => {
if (o === 'cols_rows') {
if (o === 'colsRows') {
html += `<div class="option"><label>size (<var>cols</var><code>x</code><var>rows</var> or <code>auto</code>) <input id="opt-${o}" type="text" value="auto"/></label></div>`;
} else if (stringOptions[o]) {
const selectedOption = o === 'theme' ? 'xtermjs' : term.options[o];
Expand Down Expand Up @@ -511,8 +514,8 @@ function initOptions(term: TerminalType): void {
addDomListener(input, 'change', () => {
console.log('change', o, input.value);
let value: any = input.value;
if (o === 'cols_rows') {
let m = input.value.match(/^([0-9]+)x([0-9]+)$/);
if (o === 'colsRows') {
const m = input.value.match(/^([0-9]+)x([0-9]+)$/);
if (m) {
autoResize = false;
term.resize(parseInt(m[1]), parseInt(m[2]));
Expand Down Expand Up @@ -1275,29 +1278,29 @@ function initImageAddonExposed(): void {
const ctorOptionsElement = document.querySelector<HTMLTextAreaElement>('#image-options');
ctorOptionsElement.value = JSON.stringify(DEFAULT_OPTIONS, null, 2);

const sixel_demo = (url: string) => () => fetch(url)
const sixelDemo = (url: string) => () => fetch(url)
.then(resp => resp.arrayBuffer())
.then(buffer => {
term.write('\r\n');
term.write(new Uint8Array(buffer));
});

const iip_demo = (url: string) => () => fetch(url)
.then(resp => resp.arrayBuffer())
.then(buffer => {
const data = new Uint8Array(buffer);
let sdata = '';
for (let i = 0; i < data.length; ++i) sdata += String.fromCharCode(data[i]);
term.write('\r\n');
term.write(`\x1b]1337;File=inline=1;size=${data.length}:${btoa(sdata)}\x1b\\`);
});
const iipDemo = (url: string) => () => fetch(url)
.then(resp => resp.arrayBuffer())
.then(buffer => {
const data = new Uint8Array(buffer);
let sdata = '';
for (let i = 0; i < data.length; ++i) sdata += String.fromCharCode(data[i]);
term.write('\r\n');
term.write(`\x1b]1337;File=inline=1;size=${data.length}:${btoa(sdata)}\x1b\\`);
});

document.getElementById('image-demo1').addEventListener('click',
sixel_demo('https://raw.githubusercontent.com/saitoha/libsixel/master/images/snake.six'));
sixelDemo('https://raw.githubusercontent.com/saitoha/libsixel/master/images/snake.six'));
document.getElementById('image-demo2').addEventListener('click',
sixel_demo('https://raw.githubusercontent.com/jerch/node-sixel/master/testfiles/test2.sixel'));
sixelDemo('https://raw.githubusercontent.com/jerch/node-sixel/master/testfiles/test2.sixel'));
document.getElementById('image-demo3').addEventListener('click',
iip_demo('https://raw.githubusercontent.com/jerch/node-sixel/master/palette.png'));
iipDemo('https://raw.githubusercontent.com/jerch/node-sixel/master/palette.png'));

// demo for image retrieval API
term.element.addEventListener('click', (ev: MouseEvent) => {
Expand Down
78 changes: 48 additions & 30 deletions demo/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@
* demo to the public as is would introduce security risks for the host.
**/

var express = require('express');
var expressWs = require('express-ws');
var os = require('os');
var pty = require('node-pty');
// @ts-check

// Whether to use binary transport.
const express = require('express');
const expressWs = require('express-ws');
const os = require('os');
const pty = require('node-pty');

/** Whether to use binary transport. */
const USE_BINARY = os.platform() !== "win32";

function startServer() {
var app = express();
expressWs(app);
const app = express();
const appWs = expressWs(app).app;

var terminals = {},
unsentOutput = {},
temporaryDisposable = {};
const terminals = {};
const unsentOutput = {};
const temporaryDisposable = {};

app.use('/xterm.css', express.static(__dirname + '/../css/xterm.css'));
app.get('/logo.png', (req, res) => {
Expand All @@ -41,18 +43,30 @@ function startServer() {
app.use('/src', express.static(__dirname + '/src'));

app.post('/terminals', (req, res) => {
const env = Object.assign({}, process.env);
/** @type {{ [key: string]: string }} */
const env = {};
for (const k of Object.keys(process.env)) {
const v = process.env[k];
if (v) {
env[k] = v;
}
}
// const env = Object.assign({}, process.env);
env['COLORTERM'] = 'truecolor';
var cols = parseInt(req.query.cols),
rows = parseInt(req.query.rows),
term = pty.spawn(process.platform === 'win32' ? 'pwsh.exe' : 'bash', [], {
name: 'xterm-256color',
cols: cols || 80,
rows: rows || 24,
cwd: process.platform === 'win32' ? undefined : env.PWD,
env: env,
encoding: USE_BINARY ? null : 'utf8'
});
if (typeof req.query.cols !== 'string' || typeof req.query.rows !== 'string') {
console.error({ req });
throw new Error('Unexpected query args');
}
const cols = parseInt(req.query.cols);
const rows = parseInt(req.query.rows);
const term = pty.spawn(process.platform === 'win32' ? 'pwsh.exe' : 'bash', [], {
name: 'xterm-256color',
cols: cols ?? 80,
rows: rows ?? 24,
cwd: process.platform === 'win32' ? undefined : env.PWD,
env,
encoding: USE_BINARY ? null : 'utf8'
});

console.log('Created terminal with PID: ' + term.pid);
terminals[term.pid] = term;
Expand All @@ -65,18 +79,22 @@ function startServer() {
});

app.post('/terminals/:pid/size', (req, res) => {
var pid = parseInt(req.params.pid),
cols = parseInt(req.query.cols),
rows = parseInt(req.query.rows),
term = terminals[pid];
if (typeof req.query.cols !== 'string' || typeof req.query.rows !== 'string') {
console.error({ req });
throw new Error('Unexpected query args');
}
const pid = parseInt(req.params.pid);
const cols = parseInt(req.query.cols);
const rows = parseInt(req.query.rows);
const term = terminals[pid];

term.resize(cols, rows);
console.log('Resized terminal ' + pid + ' to ' + cols + ' cols and ' + rows + ' rows.');
res.end();
});

app.ws('/terminals/:pid', function (ws, req) {
var term = terminals[parseInt(req.params.pid)];
appWs.ws('/terminals/:pid', function (ws, req) {
const term = terminals[parseInt(req.params.pid)];
console.log('Connected to terminal ' + term.pid);
temporaryDisposable[term.pid].dispose();
delete temporaryDisposable[term.pid];
Expand Down Expand Up @@ -160,11 +178,11 @@ function startServer() {
});
});

var port = process.env.PORT || 3000,
host = os.platform() === 'win32' ? '127.0.0.1' : '0.0.0.0';
const port = parseInt(process.env.PORT ?? '3000');
const host = os.platform() === 'win32' ? '127.0.0.1' : '0.0.0.0';

console.log('App listening to http://127.0.0.1:' + port);
app.listen(port, host);
app.listen(port, host, 0);
}

module.exports = startServer;
13 changes: 8 additions & 5 deletions demo/start.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/**
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
* @license MIT
*
* This file is the entry point for browserify.
*/

// @ts-check

const path = require('path');
const webpack = require('webpack');
const startServer = require('./server.js');
Expand All @@ -20,6 +20,8 @@ startServer();
* For production builds see `webpack.config.js` in the root directory. If that is built the demo
* can use that by switching out which `Terminal` is imported in `client.ts`, this is useful for
* validating that the packaged version works correctly.
*
* @type {import('webpack').Configuration}
*/
const clientConfig = {
entry: path.resolve(__dirname, 'client.ts'),
Expand Down Expand Up @@ -69,12 +71,13 @@ const clientConfig = {
const compiler = webpack(clientConfig);

compiler.watch({
// Example watchOptions
aggregateTimeout: 300,
poll: undefined
}, (err, stats) => {
// Print watch/build result here...
console.log(stats.toString({
if (err) {
console.error(err);
}
console.log(stats?.toString({
colors: true
}));
});
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
"@types/chai": "^4.2.22",
"@types/debug": "^4.1.7",
"@types/deep-equal": "^1.0.1",
"@types/express": "4",
"@types/express-ws": "^3.0.1",
"@types/glob": "^7.2.0",
"@types/jsdom": "^16.2.13",
"@types/mocha": "^9.0.0",
Expand Down
4 changes: 0 additions & 4 deletions src/browser/Linkifier2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ import { MockBufferService } from 'common/TestUtils.test';
import { ILink } from 'browser/Types';

class TestLinkifier2 extends Linkifier2 {
constructor(bufferService: IBufferService) {
super(bufferService);
}

public set currentLink(link: any) {
this._currentLink = link;
}
Expand Down
3 changes: 0 additions & 3 deletions src/common/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ export abstract class Disposable implements IDisposable {
protected _disposables: IDisposable[] = [];
protected _isDisposed: boolean = false;

constructor() {
}

/**
* Disposes the object, triggering the `dispose` method on all registered IDisposables.
*/
Expand Down
3 changes: 0 additions & 3 deletions src/common/public/AddonManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ export interface ILoadedAddon {
export class AddonManager implements IDisposable {
protected _addons: ILoadedAddon[] = [];

constructor() {
}

public dispose(): void {
for (let i = this._addons.length - 1; i >= 0; i--) {
this._addons[i].instance.dispose();
Expand Down
5 changes: 4 additions & 1 deletion webpack.config.headless.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ const path = require('path');
* from tsc (via `yarn watch` or `yarn prebuild`) which are put into `out/` and webpacks them into a
* production mode umd library module in `lib-headless/`. The aliases are used fix up the absolute
* paths output by tsc (because of `baseUrl` and `paths` in `tsconfig.json`.
*
* @type {import('webpack').Configuration}
*/
module.exports = {
const config = {
entry: './out/headless/public/Terminal.js',
devtool: 'source-map',
module: {
Expand Down Expand Up @@ -41,3 +43,4 @@ module.exports = {
},
mode: 'production'
};
module.exports = config;
Loading

0 comments on commit f9dc26d

Please sign in to comment.