mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge remote-tracking branch 'upstream/master' into 441_windows_support
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
FROM node:6.9
|
||||
MAINTAINER Paris Kasidiaris <paris@sourcelair.com>
|
||||
|
||||
# Install cpio, used for building
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends cpio \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
||||
- [**Microsoft Visual Studio Code**](http://code.visualstudio.com/): Modern, versatile and powerful open source code editor that provides an integrated terminal based on xterm.js
|
||||
- [**ttyd**](https://github.com/tsl0922/ttyd): A command-line tool for sharing terminal over the web, with fully-featured terminal emulation based on xterm.js
|
||||
- [**Katacoda**](https://www.katacoda.com/): Katacoda is an Interactive Learning Platform for software developers, covering the latest Cloud Native technologies.
|
||||
- [**Eclipse Che**](http://www.eclipse.org/che): Developer workspace server, cloud IDE, and Eclipse next-generation IDE.
|
||||
- [**Codenvy**](http://www.codenvy.com): Cloud workspaces for development teams.
|
||||
|
||||
|
||||
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it in our list.
|
||||
@@ -117,6 +119,14 @@ Visit https://lair.io/sourcelair/xterm and follow the instructions. All developm
|
||||
|
||||
[Download Visual Studio Code](http://code.visualstudio.com/Download), clone xterm.js and you are all set.
|
||||
|
||||
#### [Eclipse Che](http://www.eclipse.org/che)
|
||||
|
||||
You can start Eclipse Che with `docker run eclipse/che start`.
|
||||
|
||||
#### [Codenvy](http://www.codenvy.io)
|
||||
|
||||
You can create a trial account or install an enterprise version with `docker run codenvy/cli start`.
|
||||
|
||||
## License Agreement
|
||||
|
||||
If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work.
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# $BUILD_DIR should default to "build"
|
||||
BUILD_DIR=${BUILD_DIR:=build}
|
||||
|
||||
# Create the build directory
|
||||
mkdir -p $BUILD_DIR
|
||||
|
||||
|
||||
# Clean lib/* to prevent confusion if files were deleted in src/
|
||||
rm -rf lib/*
|
||||
|
||||
# Build all TypeScript files (including tests) to lib/
|
||||
tsc
|
||||
|
||||
# Concat all xterm.js files into a single file and output as a UMD to $BUILD_DIR/xterm.js
|
||||
browserify ./lib/xterm.js --standalone Terminal --debug --outfile ./$BUILD_DIR/xterm.js
|
||||
cat ./$BUILD_DIR/xterm.js | exorcist ./$BUILD_DIR/xterm.js.map -b ./$BUILD_DIR > ./$BUILD_DIR/xterm.temp.js
|
||||
rm ./$BUILD_DIR/xterm.js
|
||||
mv ./$BUILD_DIR/xterm.temp.js ./$BUILD_DIR/xterm.js
|
||||
|
||||
# Resolve the chain of sourcemaps so that ./$BUILD_DIR/xterm.js.map points at ./src
|
||||
sorcery -i $BUILD_DIR/xterm.js
|
||||
|
||||
# Copy all CSS files from src/ to $BUILD_DIR/ and lib/
|
||||
cd src
|
||||
find . -name '*.css' | cpio -pdm ../$BUILD_DIR
|
||||
find . -name '*.css' | cpio -pdm ../lib
|
||||
cd ..
|
||||
|
||||
# Copy addons from lib/ to $BUILD_DIR/
|
||||
cd lib/addons
|
||||
find . -name '*.js' | cpio -pdm ../../$BUILD_DIR/addons
|
||||
cd ../..
|
||||
+1
-1
@@ -21,7 +21,7 @@ CURRENT_BOWER_JSON_VERSION=$(cat bower.json \
|
||||
|
||||
# Build xterm.js into `dist`
|
||||
export BUILD_DIR=dist
|
||||
./bin/build
|
||||
npm run build
|
||||
|
||||
# Update AUTHORS file
|
||||
sh bin/generate-authors
|
||||
|
||||
+6
-1
@@ -16,7 +16,12 @@
|
||||
<div id="terminal-container"></div>
|
||||
<div>
|
||||
<h2>Options</h2>
|
||||
<label><input type="checkbox" id="option-cursor-blink"> cursorBlink</label>
|
||||
<p>
|
||||
<label><input type="checkbox" id="option-cursor-blink"> cursorBlink</label>
|
||||
</p>
|
||||
<p>
|
||||
<label>Scrollback <input type="number" id="option-scrollback" value="1000" /></label>
|
||||
</p>
|
||||
<div>
|
||||
<h3>Size</h3>
|
||||
<div>
|
||||
|
||||
+7
-3
@@ -8,7 +8,8 @@ var term,
|
||||
|
||||
var terminalContainer = document.getElementById('terminal-container'),
|
||||
optionElements = {
|
||||
cursorBlink: document.querySelector('#option-cursor-blink')
|
||||
cursorBlink: document.querySelector('#option-cursor-blink'),
|
||||
scrollback: document.querySelector('#option-scrollback')
|
||||
},
|
||||
colsElement = document.getElementById('cols'),
|
||||
rowsElement = document.getElementById('rows');
|
||||
@@ -28,6 +29,9 @@ colsElement.addEventListener('change', setTerminalSize);
|
||||
rowsElement.addEventListener('change', setTerminalSize);
|
||||
|
||||
optionElements.cursorBlink.addEventListener('change', createTerminal);
|
||||
optionElements.scrollback.addEventListener('change', function () {
|
||||
terminal.setOption('scrollback', parseInt(optionElements.scrollback.value, 10));
|
||||
});
|
||||
|
||||
createTerminal();
|
||||
|
||||
@@ -37,7 +41,8 @@ function createTerminal() {
|
||||
terminalContainer.removeChild(terminalContainer.children[0]);
|
||||
}
|
||||
term = new Terminal({
|
||||
cursorBlink: optionElements.cursorBlink.checked
|
||||
cursorBlink: optionElements.cursorBlink.checked,
|
||||
scrollback: parseInt(optionElements.scrollback.value, 10)
|
||||
});
|
||||
term.on('resize', function (size) {
|
||||
if (!pid) {
|
||||
@@ -78,7 +83,6 @@ function createTerminal() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function runRealTerminal() {
|
||||
term.attach(socket);
|
||||
term._initialized = true;
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
const browserify = require('browserify');
|
||||
const buffer = require('vinyl-buffer');
|
||||
const fs = require('fs-extra');
|
||||
const gulp = require('gulp');
|
||||
const merge = require('merge-stream');
|
||||
const sorcery = require('sorcery');
|
||||
const source = require('vinyl-source-stream');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const ts = require('gulp-typescript');
|
||||
const tsify = require('tsify');
|
||||
|
||||
|
||||
let buildDir = process.env.BUILD_DIR || 'build';
|
||||
|
||||
|
||||
/**
|
||||
* Compile TypeScript sources to JavaScript files and create a source map file for each TypeScript
|
||||
* file compiled.
|
||||
*/
|
||||
gulp.task('tsc', function () {
|
||||
// Remove the lib/ directory to prevent confusion if files were deleted in src/
|
||||
fs.emptyDirSync('lib');
|
||||
|
||||
// Build all TypeScript files (including tests) to lib/, based on the configuration defined in
|
||||
// `tsconfig.json`.
|
||||
let tsProject = ts.createProject('tsconfig.json');
|
||||
let tsResult = tsProject.src().pipe(sourcemaps.init()).pipe(tsProject());
|
||||
let tsc = tsResult.js.pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: ''})).pipe(gulp.dest('lib'));
|
||||
|
||||
// Copy all addons from src/ to lib/
|
||||
let copyAddons = gulp.src('src/addons/**/*').pipe(gulp.dest('lib/addons'));
|
||||
|
||||
// Copy stylesheets from src/ to lib/
|
||||
let copyStylesheets = gulp.src('src/**/*.css').pipe(gulp.dest('lib'));
|
||||
|
||||
return merge(tsc, copyAddons, copyStylesheets);
|
||||
});
|
||||
|
||||
/**
|
||||
* Bundle JavaScript files produced by the `tsc` task, into a single file named `xterm.js` with
|
||||
* Browserify.
|
||||
*/
|
||||
gulp.task('browserify', ['tsc'], function() {
|
||||
// Ensure that the build directory exists
|
||||
fs.ensureDirSync(buildDir);
|
||||
|
||||
let browserifyOptions = {
|
||||
basedir: buildDir,
|
||||
debug: true,
|
||||
entries: ['../lib/xterm.js'],
|
||||
standalone: 'Terminal',
|
||||
cache: {},
|
||||
packageCache: {}
|
||||
};
|
||||
let bundleStream = browserify(browserifyOptions)
|
||||
.plugin(tsify)
|
||||
.bundle()
|
||||
.pipe(source('xterm.js'))
|
||||
.pipe(buffer())
|
||||
.pipe(sourcemaps.init({loadMaps: true, sourceRoot: '..'}))
|
||||
.pipe(sourcemaps.write('./'))
|
||||
.pipe(gulp.dest(buildDir));
|
||||
|
||||
// Copy all add-ons from lib/ to buildDir
|
||||
let copyAddons = gulp.src('lib/addons/**/*').pipe(gulp.dest(`${buildDir}/addons`));
|
||||
|
||||
// Copy stylesheets from src/ to lib/
|
||||
let copyStylesheets = gulp.src('lib/**/*.css').pipe(gulp.dest(buildDir));
|
||||
|
||||
return merge(bundleStream, copyAddons, copyStylesheets);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Use `sorcery` to resolve the source map chain and point back to the TypeScript files.
|
||||
* (Without this task the source maps produced for the JavaScript bundle points into the
|
||||
* compiled JavaScript files in lib/).
|
||||
*/
|
||||
gulp.task('sorcery', ['browserify'], function () {
|
||||
var chain = sorcery.loadSync(`${buildDir}/xterm.js`);
|
||||
var map = chain.apply();
|
||||
chain.writeSync();
|
||||
});
|
||||
|
||||
gulp.task('build', ['sorcery']);
|
||||
|
||||
gulp.task('default', ['build']);
|
||||
+11
-3
@@ -38,18 +38,26 @@
|
||||
"browserify": "^13.1.0",
|
||||
"chai": "3.5.0",
|
||||
"docdash": "0.4.0",
|
||||
"exorcist": "^0.4.0",
|
||||
"express": "4.13.4",
|
||||
"express-ws": "2.0.0-rc.1",
|
||||
"fs-extra": "^1.0.0",
|
||||
"glob": "^7.0.5",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-cli": "^1.2.2",
|
||||
"gulp-sourcemaps": "1.9.1",
|
||||
"gulp-typescript": "^3.1.3",
|
||||
"jsdoc": "3.4.3",
|
||||
"merge-stream": "^1.0.1",
|
||||
"mocha": "2.5.3",
|
||||
"node-pty": "^0.4.1",
|
||||
"nodemon": "1.10.2",
|
||||
"sleep": "^3.0.1",
|
||||
"sorcery": "^0.10.0",
|
||||
"tsify": "^3.0.0",
|
||||
"tslint": "^4.0.2",
|
||||
"typescript": "^2.0.3"
|
||||
"typescript": "^2.0.3",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "npm run build",
|
||||
@@ -58,7 +66,7 @@
|
||||
"lint": "tslint src/**/*.ts",
|
||||
"test": "mocha --recursive ./lib",
|
||||
"build:docs": "jsdoc -c jsdoc.json",
|
||||
"build": "./bin/build",
|
||||
"build": "gulp build",
|
||||
"prepublish": "npm run build"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* C0 control codes
|
||||
* See = https://en.wikipedia.org/wiki/C0_and_C1_control_codes
|
||||
*/
|
||||
export namespace C0 {
|
||||
/** Null (Caret = ^@, C = \0) */
|
||||
export const NUL = '\x00';
|
||||
/** Start of Heading (Caret = ^A) */
|
||||
export const SOH = '\x01';
|
||||
/** Start of Text (Caret = ^B) */
|
||||
export const STX = '\x02';
|
||||
/** End of Text (Caret = ^C) */
|
||||
export const ETX = '\x03';
|
||||
/** End of Transmission (Caret = ^D) */
|
||||
export const EOT = '\x04';
|
||||
/** Enquiry (Caret = ^E) */
|
||||
export const ENQ = '\x05';
|
||||
/** Acknowledge (Caret = ^F) */
|
||||
export const ACK = '\x06';
|
||||
/** Bell (Caret = ^G, C = \a) */
|
||||
export const BEL = '\x07';
|
||||
/** Backspace (Caret = ^H, C = \b) */
|
||||
export const BS = '\x08';
|
||||
/** Character Tabulation, Horizontal Tabulation (Caret = ^I, C = \t) */
|
||||
export const HT = '\x09';
|
||||
/** Line Feed (Caret = ^J, C = \n) */
|
||||
export const LF = '\x0a';
|
||||
/** Line Tabulation, Vertical Tabulation (Caret = ^K, C = \v) */
|
||||
export const VT = '\x0b';
|
||||
/** Form Feed (Caret = ^L, C = \f) */
|
||||
export const FF = '\x0c';
|
||||
/** Carriage Return (Caret = ^M, C = \r) */
|
||||
export const CR = '\x0d';
|
||||
/** Shift Out (Caret = ^N) */
|
||||
export const SO = '\x0e';
|
||||
/** Shift In (Caret = ^O) */
|
||||
export const SI = '\x0f';
|
||||
/** Data Link Escape (Caret = ^P) */
|
||||
export const DLE = '\x10';
|
||||
/** Device Control One (XON) (Caret = ^Q) */
|
||||
export const DC1 = '\x11';
|
||||
/** Device Control Two (Caret = ^R) */
|
||||
export const DC2 = '\x12';
|
||||
/** Device Control Three (XOFF) (Caret = ^S) */
|
||||
export const DC3 = '\x13';
|
||||
/** Device Control Four (Caret = ^T) */
|
||||
export const DC4 = '\x14';
|
||||
/** Negative Acknowledge (Caret = ^U) */
|
||||
export const NAK = '\x15';
|
||||
/** Synchronous Idle (Caret = ^V) */
|
||||
export const SYN = '\x16';
|
||||
/** End of Transmission Block (Caret = ^W) */
|
||||
export const ETB = '\x17';
|
||||
/** Cancel (Caret = ^X) */
|
||||
export const CAN = '\x18';
|
||||
/** End of Medium (Caret = ^Y) */
|
||||
export const EM = '\x19';
|
||||
/** Substitute (Caret = ^Z) */
|
||||
export const SUB = '\x1a';
|
||||
/** Escape (Caret = ^[, C = \e) */
|
||||
export const ESC = '\x1b';
|
||||
/** File Separator (Caret = ^\) */
|
||||
export const FS = '\x1c';
|
||||
/** Group Separator (Caret = ^]) */
|
||||
export const GS = '\x1d';
|
||||
/** Record Separator (Caret = ^^) */
|
||||
export const RS = '\x1e';
|
||||
/** Unit Separator (Caret = ^_) */
|
||||
export const US = '\x1f';
|
||||
/** Space */
|
||||
export const SP = '\x20';
|
||||
/** Delete (Caret = ^?) */
|
||||
export const DEL = '\x7f';
|
||||
};
|
||||
+3
-1
@@ -11,7 +11,9 @@ export class EventEmitter {
|
||||
private _events: {[type: string]: ListenerType[]};
|
||||
|
||||
constructor() {
|
||||
this._events = {};
|
||||
// Restore the previous events if available, this will happen if the
|
||||
// constructor is called multiple times on the same object (terminal reset).
|
||||
this._events = this._events || {};
|
||||
}
|
||||
|
||||
public on(type, listener): void {
|
||||
|
||||
+10
-16
@@ -2,11 +2,11 @@ import { assert } from 'chai';
|
||||
import { Viewport } from './Viewport';
|
||||
|
||||
describe('Viewport', () => {
|
||||
var terminal;
|
||||
var viewportElement;
|
||||
var charMeasureElement;
|
||||
var viewport;
|
||||
var scrollAreaElement;
|
||||
let terminal;
|
||||
let viewportElement;
|
||||
let charMeasure;
|
||||
let viewport;
|
||||
let scrollAreaElement;
|
||||
|
||||
const CHARACTER_HEIGHT = 10;
|
||||
|
||||
@@ -34,21 +34,17 @@ describe('Viewport', () => {
|
||||
height: 0
|
||||
}
|
||||
};
|
||||
charMeasureElement = {
|
||||
getBoundingClientRect: () => {
|
||||
return { width: null, height: CHARACTER_HEIGHT };
|
||||
}
|
||||
charMeasure = {
|
||||
height: CHARACTER_HEIGHT
|
||||
};
|
||||
viewport = new Viewport(terminal, viewportElement, scrollAreaElement, charMeasureElement);
|
||||
viewport = new Viewport(terminal, viewportElement, scrollAreaElement, charMeasure);
|
||||
});
|
||||
|
||||
describe('refresh', () => {
|
||||
it('should set the line-height of the terminal', () => {
|
||||
assert.equal(viewportElement.style.lineHeight, CHARACTER_HEIGHT + 'px');
|
||||
assert.equal(terminal.rowContainer.style.lineHeight, CHARACTER_HEIGHT + 'px');
|
||||
charMeasureElement.getBoundingClientRect = () => {
|
||||
return { width: null, height: 1 };
|
||||
};
|
||||
charMeasure.height = 1;
|
||||
viewport.refresh();
|
||||
assert.equal(viewportElement.style.lineHeight, '1px');
|
||||
assert.equal(terminal.rowContainer.style.lineHeight, '1px');
|
||||
@@ -59,9 +55,7 @@ describe('Viewport', () => {
|
||||
terminal.rows = 1;
|
||||
viewport.refresh();
|
||||
assert.equal(viewportElement.style.height, 1 * CHARACTER_HEIGHT + 'px');
|
||||
charMeasureElement.getBoundingClientRect = () => {
|
||||
return { width: null, height: 20 };
|
||||
};
|
||||
charMeasure.height = 20;
|
||||
viewport.refresh();
|
||||
assert.equal(viewportElement.style.height, 20 + 'px');
|
||||
});
|
||||
|
||||
+17
-18
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import { ITerminal } from './Interfaces';
|
||||
import { CharMeasure } from './utils/CharMeasure';
|
||||
|
||||
/**
|
||||
* Represents the viewport of a terminal, the visible area within the larger buffer of output.
|
||||
@@ -24,7 +25,7 @@ export class Viewport {
|
||||
private terminal: ITerminal,
|
||||
private viewportElement: HTMLElement,
|
||||
private scrollArea: HTMLElement,
|
||||
private charMeasureElement: HTMLElement
|
||||
private charMeasure: CharMeasure
|
||||
) {
|
||||
this.currentRowHeight = 0;
|
||||
this.lastRecordedBufferLength = 0;
|
||||
@@ -43,21 +44,20 @@ export class Viewport {
|
||||
* @param charSize A character size measurement bounding rect object, if it doesn't exist it will
|
||||
* be created.
|
||||
*/
|
||||
private refresh(charSize?: ClientRect): void {
|
||||
var size = charSize || this.charMeasureElement.getBoundingClientRect();
|
||||
if (size.height > 0) {
|
||||
var rowHeightChanged = size.height !== this.currentRowHeight;
|
||||
private refresh(): void {
|
||||
if (this.charMeasure.height > 0) {
|
||||
const rowHeightChanged = this.charMeasure.height !== this.currentRowHeight;
|
||||
if (rowHeightChanged) {
|
||||
this.currentRowHeight = size.height;
|
||||
this.viewportElement.style.lineHeight = size.height + 'px';
|
||||
this.terminal.rowContainer.style.lineHeight = size.height + 'px';
|
||||
this.currentRowHeight = this.charMeasure.height;
|
||||
this.viewportElement.style.lineHeight = this.charMeasure.height + 'px';
|
||||
this.terminal.rowContainer.style.lineHeight = this.charMeasure.height + 'px';
|
||||
}
|
||||
var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;
|
||||
const viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows;
|
||||
if (rowHeightChanged || viewportHeightChanged) {
|
||||
this.lastRecordedViewportHeight = this.terminal.rows;
|
||||
this.viewportElement.style.height = size.height * this.terminal.rows + 'px';
|
||||
this.viewportElement.style.height = this.charMeasure.height * this.terminal.rows + 'px';
|
||||
}
|
||||
this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px';
|
||||
this.scrollArea.style.height = (this.charMeasure.height * this.lastRecordedBufferLength) + 'px';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,14 +74,13 @@ export class Viewport {
|
||||
this.refresh();
|
||||
} else {
|
||||
// If size has changed, refresh viewport
|
||||
var size = this.charMeasureElement.getBoundingClientRect();
|
||||
if (size.height !== this.currentRowHeight) {
|
||||
this.refresh(size);
|
||||
if (this.charMeasure.height !== this.currentRowHeight) {
|
||||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// Sync scrollTop
|
||||
var scrollTop = this.terminal.ydisp * this.currentRowHeight;
|
||||
const scrollTop = this.terminal.ydisp * this.currentRowHeight;
|
||||
if (this.viewportElement.scrollTop !== scrollTop) {
|
||||
this.viewportElement.scrollTop = scrollTop;
|
||||
}
|
||||
@@ -93,8 +92,8 @@ export class Viewport {
|
||||
* @param ev The scroll event.
|
||||
*/
|
||||
private onScroll(ev: Event) {
|
||||
var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);
|
||||
var diff = newRow - this.terminal.ydisp;
|
||||
const newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight);
|
||||
const diff = newRow - this.terminal.ydisp;
|
||||
this.terminal.scrollDisp(diff, true);
|
||||
}
|
||||
|
||||
@@ -110,7 +109,7 @@ export class Viewport {
|
||||
return;
|
||||
}
|
||||
// Fallback to WheelEvent.DOM_DELTA_PIXEL
|
||||
var multiplier = 1;
|
||||
let multiplier = 1;
|
||||
if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) {
|
||||
multiplier = this.currentRowHeight;
|
||||
} else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
|
||||
|
||||
@@ -92,7 +92,11 @@ describe('xterm output comparison', function() {
|
||||
var from_pty = pty_write_read(in_file);
|
||||
// uncomment this to get log from terminal
|
||||
//console.log = function(){};
|
||||
xterm.write(from_pty);
|
||||
|
||||
// Perform a synchronous .write(data)
|
||||
xterm.writeBuffer.push(from_pty);
|
||||
xterm.innerWrite();
|
||||
|
||||
var from_emulator = terminalToString(xterm);
|
||||
console.log = CONSOLE_LOG;
|
||||
var expected = fs.readFileSync(filename.split('.')[0] + '.text', 'utf8');
|
||||
|
||||
@@ -14,6 +14,15 @@ describe('xterm.js', function() {
|
||||
xterm.compositionHelper = {
|
||||
keydown: function(){ return true; }
|
||||
};
|
||||
// Force synchronous refreshes
|
||||
xterm.queueRefresh = function(start, end) {
|
||||
xterm.refresh(start, end);
|
||||
};
|
||||
// Force synchronous writes
|
||||
xterm.write = function(data) {
|
||||
xterm.writeBuffer.push(data);
|
||||
xterm.innerWrite();
|
||||
};
|
||||
});
|
||||
|
||||
describe('getOption', function() {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Attributes and methods to help with identifying the current browser and platform.
|
||||
* @module xterm/utils/Browser
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { contains } from './Generic.js';
|
||||
|
||||
let isNode = (typeof navigator == 'undefined') ? true : false;
|
||||
let userAgent = (isNode) ? 'node' : navigator.userAgent;
|
||||
let platform = (isNode) ? 'node' : navigator.platform;
|
||||
|
||||
export let isFirefox = !!~userAgent.indexOf('Firefox');
|
||||
export let isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');
|
||||
|
||||
// Find the users platform. We use this to interpret the meta key
|
||||
// and ISO third level shifts.
|
||||
// http://stackoverflow.com/q/19877924/577598
|
||||
export let isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);
|
||||
export let isIpad = platform === 'iPad';
|
||||
export let isIphone = platform === 'iPhone';
|
||||
export let isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Attributes and methods to help with identifying the current browser and platform.
|
||||
* @module xterm/utils/Browser
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { contains } from './Generic';
|
||||
|
||||
const isNode = (typeof navigator === 'undefined') ? true : false;
|
||||
const userAgent = (isNode) ? 'node' : navigator.userAgent;
|
||||
const platform = (isNode) ? 'node' : navigator.platform;
|
||||
|
||||
export const isFirefox = !!~userAgent.indexOf('Firefox');
|
||||
export const isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident');
|
||||
|
||||
// Find the users platform. We use this to interpret the meta key
|
||||
// and ISO third level shifts.
|
||||
// http://stackoverflow.com/q/19877924/577598
|
||||
export const isMac = contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform);
|
||||
export const isIpad = platform === 'iPad';
|
||||
export const isIphone = platform === 'iPhone';
|
||||
export const isMSWindows = contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform);
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @module xterm/utils/CharMeasure
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { EventEmitter } from '../EventEmitter.js';
|
||||
|
||||
/**
|
||||
* Utility class that measures the size of a character.
|
||||
*/
|
||||
export class CharMeasure extends EventEmitter {
|
||||
private _parentElement: HTMLElement;
|
||||
private _measureElement: HTMLElement;
|
||||
private _width: number;
|
||||
private _height: number;
|
||||
|
||||
constructor(parentElement: HTMLElement) {
|
||||
super();
|
||||
this._parentElement = parentElement;
|
||||
}
|
||||
|
||||
public get width(): number {
|
||||
return this._width;
|
||||
}
|
||||
|
||||
public get height(): number {
|
||||
return this._height;
|
||||
}
|
||||
|
||||
public measure(): void {
|
||||
if (!this._measureElement) {
|
||||
this._measureElement = document.createElement('span');
|
||||
this._measureElement.style.position = 'absolute';
|
||||
this._measureElement.style.top = '0';
|
||||
this._measureElement.style.left = '-9999em';
|
||||
this._measureElement.textContent = 'W';
|
||||
this._parentElement.appendChild(this._measureElement);
|
||||
// Perform _doMeasure async if the element was just attached as sometimes
|
||||
// getBoundingClientRect does not return accurate values without this.
|
||||
setTimeout(() => this._doMeasure(), 0);
|
||||
} else {
|
||||
this._doMeasure();
|
||||
}
|
||||
}
|
||||
|
||||
private _doMeasure(): void {
|
||||
const oldWidth = this._width;
|
||||
const oldHeight = this._height;
|
||||
const geometry = this._measureElement.getBoundingClientRect();
|
||||
|
||||
if (this._width !== geometry.width || this._height !== geometry.height) {
|
||||
this._width = geometry.width;
|
||||
this._height = geometry.height;
|
||||
this.emit('charsizechanged');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,6 @@
|
||||
* @param {Array} array The array to search for the given element.
|
||||
* @param {Object} el The element to look for into the array
|
||||
*/
|
||||
export let contains = function(arr, el) {
|
||||
export function contains(arr: any[], el: any) {
|
||||
return arr.indexOf(el) >= 0;
|
||||
};
|
||||
@@ -116,6 +116,10 @@
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.terminal .xterm-wide-char {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.terminal .xterm-rows {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
+1218
-1066
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user