Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add SerializeAddon #2298

Merged
merged 10 commits into from
Aug 2, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions addons/xterm-addon-serialize/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
lib
node_modules
5 changes: 5 additions & 0 deletions addons/xterm-addon-serialize/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/*.api.js
**/*.api.ts
tsconfig.json
.yarnrc
webpack.config.js
20 changes: 20 additions & 0 deletions addons/xterm-addon-serialize/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "xterm-addon-serialize",
"version": "0.1.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
},
"main": "lib/xterm-addon-serialize.js",
"types": "typings/xterm-addon-serialize.d.ts",
"license": "MIT",
"scripts": {
"build": "../../node_modules/.bin/tsc -p src",
"prepackage": "npm run build",
"package": "../../node_modules/.bin/webpack",
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^3.14.0"
}
}
134 changes: 134 additions & 0 deletions addons/xterm-addon-serialize/src/SerializeAddon.api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/

import * as puppeteer from 'puppeteer';
import * as util from 'util';
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';

const APP = 'http://127.0.0.1:3000/test';

let browser: puppeteer.Browser;
let page: puppeteer.Page;
const width = 800;
const height = 600;

describe('SerializeAddon', () => {
before(async function (): Promise<any> {
this.timeout(20000);
browser = await puppeteer.launch({
headless: process.argv.indexOf('--headless') !== -1,
slowMo: 80,
args: [`--window-size=${width},${height}`]
});
page = (await browser.pages())[0];
await page.setViewport({ width, height });
});

after(async () => {
await browser.close();
});

beforeEach(async function (): Promise<any> {
this.timeout(20000);
await page.goto(APP);
});

it('empty content', async function (): Promise<any> {
this.timeout(20000);
const rows = 10;
const cols = 10;
const blankline = ' '.repeat(cols);
const lines = newArray<string>(blankline, rows);

await openTerminal({ rows: rows, cols: cols, rendererType: 'dom' });
await page.evaluate(`
window.serializeAddon = new SerializeAddon();
window.term.loadAddon(window.serializeAddon);
`);

assert.equal(await page.evaluate(`serializeAddon.serialize();`), lines.join('\r\n'));
});

it('digits content', async function (): Promise<any> {
this.timeout(20000);
const rows = 10;
const cols = 10;
const digitsLine = digitsString(cols);
const lines = newArray<string>(digitsLine, rows);

await openTerminal({ rows: rows, cols: cols, rendererType: 'dom' });
await page.evaluate(`
window.serializeAddon = new SerializeAddon();
window.term.loadAddon(window.serializeAddon);
window.term.write(${util.inspect(lines.join('\r\n'))});
`);

assert.equal(await page.evaluate(`serializeAddon.serialize();`), lines.join('\r\n'));
});

it('serialize n rows of content', async function (): Promise<any> {
this.timeout(20000);
const rows = 10;
const halfRows = rows >> 1;
const cols = 10;
const lines = newArray<string>((index: number) => digitsString(cols, index), rows);

await openTerminal({ rows: rows, cols: cols, rendererType: 'dom' });
await page.evaluate(`
window.serializeAddon = new SerializeAddon();
window.term.loadAddon(window.serializeAddon);
window.term.write(${util.inspect(lines.join('\r\n'))});
`);

assert.equal(await page.evaluate(`serializeAddon.serialize(${halfRows});`), lines.slice(0, halfRows).join('\r\n'));
});

it('serialize 0 rows of content', async function (): Promise<any> {
this.timeout(20000);
const rows = 10;
const cols = 10;
const lines = newArray<string>((index: number) => digitsString(cols, index), rows);

await openTerminal({ rows: rows, cols: cols, rendererType: 'dom' });
await page.evaluate(`
window.serializeAddon = new SerializeAddon();
window.term.loadAddon(window.serializeAddon);
window.term.write(${util.inspect(lines.join('\r\n'))});
`);

assert.equal(await page.evaluate(`serializeAddon.serialize(0);`), '');
});
});

async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}

function newArray<T>(initial: T | ((index: number) => T), count: number): T[] {
const array: T[] = new Array<T>(count);
for (let i = 0; i < array.length; i++) {
if (typeof initial === 'function') {
array[i] = (<(index: number) => T>initial)(i);
} else {
array[i] = <T>initial;
}
}
return array;
}

function digitsString(length: number, from: number = 0): string {
let s = '';
for (let i = 0; i < length; i++) {
s += (from++) % 10;
}
return s;
}
42 changes: 42 additions & 0 deletions addons/xterm-addon-serialize/src/SerializeAddon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/

import { Terminal, ITerminalAddon } from 'xterm';

export class SerializeAddon implements ITerminalAddon {
private _terminal: Terminal | undefined;

constructor() { }

public activate(terminal: Terminal): void {
this._terminal = terminal;
}

public serialize(rows?: number): string {
if (!this._terminal) {
return '';
Tyriar marked this conversation as resolved.
Show resolved Hide resolved
}
const buffer = this._terminal.buffer;
const length = Math.max(0, Math.min((rows === undefined ? buffer.length : rows), buffer.length));
Tyriar marked this conversation as resolved.
Show resolved Hide resolved
let data = '';
Tyriar marked this conversation as resolved.
Show resolved Hide resolved

for (let i = 0; i < length; i++) {
const line = buffer.getLine(i);
const last = i === length - 1;
if (line) {
data += line.translateToString();
}
if (!last) {
data += '\r\n';
}
}

return data;
}

public dispose(): void {
if (this._terminal !== undefined) { }
Tyriar marked this conversation as resolved.
Show resolved Hide resolved
}
}
19 changes: 19 additions & 0 deletions addons/xterm-addon-serialize/src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"lib": [
"dom",
"es2015"
],
"rootDir": ".",
"outDir": "../out",
"sourceMap": true,
"removeComments": true,
"strict": true
},
"include": [
"./**/*",
"../../../typings/xterm.d.ts"
]
}
30 changes: 30 additions & 0 deletions addons/xterm-addon-serialize/typings/xterm-addon-serialize.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/


import { Terminal, ITerminalAddon } from 'xterm';

declare module 'xterm-addon-serialize' {
/**
* An xterm.js addon that enables web links.
*/
export class SerializeAddon implements ITerminalAddon {

constructor();

/**
* Activates the addon
* @param terminal The terminal the addon is being loaded in.
*/
public activate(terminal: Terminal): void;

public serialize(rows?: number): string;
Tyriar marked this conversation as resolved.
Show resolved Hide resolved

/**
* Disposes the addon.
*/
public dispose(): void;
}
}
31 changes: 31 additions & 0 deletions addons/xterm-addon-serialize/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/

const path = require('path');

const addonName = 'SerializeAddon';
const mainFile = 'xterm-addon-serialize.js';

module.exports = {
entry: `./out/${addonName}.js`,
devtool: 'source-map',
module: {
rules: [
{
test: /\.js$/,
use: ["source-map-loader"],
enforce: "pre",
exclude: /node_modules/
}
]
},
output: {
filename: mainFile,
path: path.resolve('./lib'),
library: addonName,
libraryTarget: 'umd'
},
mode: 'production'
};
3 changes: 3 additions & 0 deletions demo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { FitAddon } from '../addons/xterm-addon-fit/out/FitAddon';
import { SearchAddon, ISearchOptions } from '../addons/xterm-addon-search/out/SearchAddon';
import { WebLinksAddon } from '../addons/xterm-addon-web-links/out/WebLinksAddon';
import { WebglAddon } from '../addons/xterm-addon-webgl/out/WebglAddon';
import { SerializeAddon } from '../addons/xterm-addon-serialize/out/SerializeAddon';

// Use webpacked version (yarn package)
// import { Terminal } from '../lib/xterm';
Expand All @@ -35,6 +36,7 @@ export interface IWindowWithTerminal extends Window {
SearchAddon?: typeof SearchAddon;
WebLinksAddon?: typeof WebLinksAddon;
WebglAddon?: typeof WebglAddon;
SerializeAddon?: typeof SerializeAddon;
}
declare let window: IWindowWithTerminal;

Expand Down Expand Up @@ -88,6 +90,7 @@ if (document.location.pathname === '/test') {
window.SearchAddon = SearchAddon;
window.WebLinksAddon = WebLinksAddon;
window.WebglAddon = WebglAddon;
window.SerializeAddon = SerializeAddon;
} else {
createTerminal();
document.getElementById('dispose').addEventListener('click', disposeRecreateButtonHandler);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"test": "npm run test-unit",
"posttest": "npm run lint",
"test-api": "mocha \"**/*.api.js\"",
"test-addons": "mocha \"**/*.test.js\"",
Tyriar marked this conversation as resolved.
Show resolved Hide resolved
"test-unit": "node ./bin/test.js",
"build": "tsc -b ./tsconfig.all.json",
"prepare": "npm run build",
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
{ "path": "./addons/xterm-addon-fit/src" },
{ "path": "./addons/xterm-addon-search/src" },
{ "path": "./addons/xterm-addon-web-links/src" },
{ "path": "./addons/xterm-addon-webgl/src" }
{ "path": "./addons/xterm-addon-webgl/src" },
{ "path": "./addons/xterm-addon-serialize/src" }
]
}