Merge remote-tracking branch 'upstream/master' into 361_circular_list_scrollback

This commit is contained in:
Daniel Imms
2016-12-21 15:43:18 -08:00
17 changed files with 192 additions and 47 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
node_modules/
*.swp
.lock-wscript
out/
lib/
Makefile.gyp
*.Makefile
*.target.gyp.mk
+16
View File
@@ -0,0 +1,16 @@
node_modules/
*.swp
.lock-wscript
lib/*.test.js
lib/*.test.js.map
lib/test/
Makefile.gyp
*.Makefile
*.target.gyp.mk
*.node
example/*.log
docs/
npm-debug.log
/.idea/
.env
build/
+6 -1
View File
@@ -2,7 +2,11 @@ language: node_js
node_js:
- 6
env:
- CXX=g++-4.8
global:
- CXX=g++-4.8
matrix:
- NPM_COMMAND=lint
- NPM_COMMAND=test
addons:
apt:
sources:
@@ -11,3 +15,4 @@ addons:
- g++-4.8
notifications:
email: false
script: npm run $NPM_COMMAND
+3
View File
@@ -8,7 +8,9 @@ Anton Yurovskykh <anton.yurovskykh@gmail.com>
Austin Robertson <austinrobertson@gmail.com>
ayapi <colors.aya@gmail.com>
Benjamin Fischer <benjamin.fischer@rwth-aachen.de>
bottleofwater <nison.mael+bottleofwater@gmail.com>
Carson Anderson <carson@betterservers.com>
Christian Budde Christensen <budde377@gmail.com>
Christopher Jeffrey <chjjeffrey@gmail.com>
Daniel Imms <daimms@microsoft.com>
Daniel Risacher <drisacher@gmail.com>
@@ -20,6 +22,7 @@ Ian Lewis <ianlewis@google.com>
imoses <ido@twiggle.com>
Jean Bruenn <himself@jeanbruenn.info>
Jörg Breitbart <jerch@rockborn.de>
Maël Nison <nison.mael@gmail.com>
Mikko Karvonen <mikko.karvonen@arm.com>
Paris Kasidiaris <pariskasidiaris@gmail.com>
Paris Kasidiaris <paris@sourcelair.com>
+22
View File
@@ -52,6 +52,28 @@ npm start
Then open http://0.0.0.0:3000 in a web browser (use http://127.0.0.1:3000 if running under Windows).
## Getting Started
To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to the head of your html page. Then create a `<div id="terminal"></div>` onto which xterm can attach itself.
```html
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="bower_components/xterm.js/dist/xterm.css" />
<script src="bower_components/xterm.js/dist/xterm.js"></script>
</head>
<body>
<div id="terminal"></div>
<script>
var term = new Terminal();
term.open(document.getElementById('#terminal'));
term.write('Hello from \033[1;3;31mxterm.js\033[0m $ ')
</script>
</body>
</html>
```
Finally instantiate the `Terminal` object and then call the `open` function with the DOM object of the `div`.
## Addons
Addons are JavaScript modules that attach functions to the `Terminal` prototype to extend its functionality. There are a handful available in the main repository in the `dist/addons` directory, you can even write your own (though they may break when the internals of xterm.js change across versions).
+8 -7
View File
@@ -9,14 +9,14 @@ BUILD_DIR=${BUILD_DIR:=build}
mkdir -p $BUILD_DIR
# Clean out/* to prevent confusion if files were deleted in src/
rm -rf out/*
# Clean lib/* to prevent confusion if files were deleted in src/
rm -rf lib/*
# Build all TypeScript files (including tests) to out/
# 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 ./out/xterm.js --standalone Terminal --debug --outfile ./$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
@@ -24,12 +24,13 @@ 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/
# 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 out/ to $BUILD_DIR/
cd out/addons
# Copy addons from lib/ to $BUILD_DIR/
cd lib/addons
find . -name '*.js' | cpio -pdm ../../$BUILD_DIR/addons
cd ../..
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "xterm.js",
"version": "2.2.1",
"version": "2.2.3",
"ignore": ["demo", "test", ".gitignore"],
"main": [
"dist/xterm.js",
+2 -2
View File
@@ -32,7 +32,7 @@
})(function (Xterm) {
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;
var parentElementStyle = window.getComputedStyle(term.element.parentElement), parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), 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;
@@ -40,7 +40,7 @@
characterHeight = parseInt(subjectRow.offsetHeight);
subjectRow.innerHTML = contentBuffer;
rows = parseInt(availableHeight / characterHeight);
cols = parseInt(availableWidth / characterWidth) - 1;
cols = parseInt(availableWidth / characterWidth);
geometry = { cols: cols, rows: rows };
return geometry;
};
+8 -5
View File
@@ -451,15 +451,15 @@ exports.pasteHandler = pasteHandler;
* area, then bring the terminal's input below the cursor, in order to
* trigger the event on the textarea and allow-right click paste, without
* caring about disappearing selection.
* @param {ClipboardEvent} ev The original paste event to be handled
* @param {MouseEvent} ev The original right click event to be handled
* @param {Terminal} term The terminal on which to apply the handled paste event
*/
function rightClickHandler(ev, term) {
var s = document.getSelection(), selectedText = prepareTextForClipboard(s.toString()), clickIsOnSelection = false, x = ev.clientX, y = ev.clientY;
if (s.rangeCount) {
var r = s.getRangeAt(0), cr = r.getClientRects(), i = void 0, rect = void 0;
for (i = 0; i < cr.length; i++) {
rect = cr[i];
var r = s.getRangeAt(0), cr = r.getClientRects();
for (var i = 0; i < cr.length; i++) {
var rect = cr[i];
clickIsOnSelection = ((x > rect.left) && (x < rect.right) &&
(y > rect.top) && (y < rect.bottom));
if (clickIsOnSelection) {
@@ -894,6 +894,9 @@ Terminal.prototype.initGlobal = function () {
on(this.textarea, 'paste', function (ev) {
Clipboard_js_1.pasteHandler.call(this, ev, term);
});
on(this.element, 'paste', function (ev) {
Clipboard_js_1.pasteHandler.call(this, ev, term);
});
function rightClickHandlerWrapper(ev) {
Clipboard_js_1.rightClickHandler.call(this, ev, term);
}
@@ -1211,7 +1214,7 @@ Terminal.prototype.bindMouse = function () {
pos.x -= 32;
pos.y -= 32;
self.send('\x1b[<'
+ ((button & 3) === 3 ? button & ~3 : button)
+ (((button & 3) === 3 ? button & ~3 : button) - 32)
+ ';'
+ pos.x
+ ';'
+1 -1
View File
File diff suppressed because one or more lines are too long
+29 -4
View File
@@ -1,14 +1,36 @@
{
"name": "xterm",
"version": "2.2.1",
"version": "2.2.3",
"ignore": [
"demo",
"test",
".gitignore"
],
"main": "dist/xterm.js",
"main": "lib/xterm.js",
"repository": "https://github.com/sourcelair/xterm.js",
"license": "MIT",
"files": [
"dist/*.css",
"dist/**/*.css",
"dist/*.js",
"dist/*.js.map",
"dist/**/*.js",
"dist/**/*.js.map",
"lib/*.css",
"lib/**/*.css",
"lib/*.js",
"lib/*.js.map",
"lib/**/*.js",
"lib/**/*.js.map",
"src/*.css",
"src/**/*.css",
"src/*.js",
"src/*.js.map",
"src/*.ts",
"src/**/*.js",
"src/**/*.js.map",
"src/**/*.ts"
],
"devDependencies": {
"@types/chai": "^3.4.34",
"@types/mocha": "^2.2.33",
@@ -26,12 +48,15 @@
"pty.js": "0.3.1",
"sleep": "^3.0.1",
"sorcery": "^0.10.0",
"tslint": "^4.0.2",
"typescript": "^2.0.3"
},
"scripts": {
"start": "nodemon --watch src --watch addons --watch demo --exec bash -c './bin/build && node demo/app'",
"test": "./bin/build && mocha --recursive ./out",
"lint": "tslint src/**/*.ts",
"test": "mocha --recursive ./lib",
"build:docs": "jsdoc -c jsdoc.json",
"build": "./bin/build"
"build": "./bin/build",
"prepublish": "npm run build"
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ import * as Clipboard from './Clipboard';
describe('evaluateCopiedTextProcessing', function () {
it('should strip trailing whitespaces and replace nbsps with spaces', function () {
var nonBreakingSpace = String.fromCharCode(160),
let nonBreakingSpace = String.fromCharCode(160),
copiedText = 'echo' + nonBreakingSpace + 'hello' + nonBreakingSpace,
processedText = Clipboard.prepareTextForClipboard(copiedText);
+8 -15
View File
@@ -7,13 +7,6 @@
import { ITerminal } from '../Interfaces';
// We are extending the ClipboardEvent interface, since TypeScript has not declared the
// clientX and clientY properties that we use.
interface IClipboardEvent extends ClipboardEvent {
clientX: number;
clientY: number;
}
interface IWindow extends Window {
clipboardData?: {
getData(format: string): string;
@@ -49,7 +42,7 @@ export function prepareTextForClipboard(text: string): string {
* Binds copy functionality to the given terminal.
* @param {ClipboardEvent} ev The original copy event to be handled
*/
export function copyHandler(ev: IClipboardEvent, term: ITerminal) {
export function copyHandler(ev: ClipboardEvent, term: ITerminal) {
// We cast `window` to `any` type, because TypeScript has not declared the `clipboardData`
// property that we use below for Internet Explorer.
let copiedText = window.getSelection().toString(),
@@ -69,7 +62,7 @@ export function copyHandler(ev: IClipboardEvent, term: ITerminal) {
* @param {ClipboardEvent} ev The original paste event to be handled
* @param {Terminal} term The terminal on which to apply the handled paste event
*/
export function pasteHandler(ev: IClipboardEvent, term: ITerminal) {
export function pasteHandler(ev: ClipboardEvent, term: ITerminal) {
ev.stopPropagation();
let text: string;
@@ -103,10 +96,10 @@ export function pasteHandler(ev: IClipboardEvent, term: ITerminal) {
* area, then bring the terminal's input below the cursor, in order to
* trigger the event on the textarea and allow-right click paste, without
* caring about disappearing selection.
* @param {ClipboardEvent} ev The original paste event to be handled
* @param {MouseEvent} ev The original right click event to be handled
* @param {Terminal} term The terminal on which to apply the handled paste event
*/
export function rightClickHandler(ev: IClipboardEvent, term: ITerminal) {
export function rightClickHandler(ev: MouseEvent, term: ITerminal) {
let s = document.getSelection(),
selectedText = prepareTextForClipboard(s.toString()),
clickIsOnSelection = false,
@@ -115,11 +108,11 @@ export function rightClickHandler(ev: IClipboardEvent, term: ITerminal) {
if (s.rangeCount) {
let r = s.getRangeAt(0),
cr = r.getClientRects(),
i, rect;
cr = r.getClientRects();
for (let i = 0; i < cr.length; i++) {
let rect = cr[i];
for (i=0; i<cr.length; i++) {
rect = cr[i];
clickIsOnSelection = (
(x > rect.left) && (x < rect.right) &&
(y > rect.top) && (y < rect.bottom)
+25 -6
View File
@@ -286,14 +286,33 @@ describe('xterm.js', function() {
it('should return \\x1b[5B for ctrl+down', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B
});
// Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
// http://unix.stackexchange.com/a/108106
it('should return \\x1b[5D for alt+left', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
describe('On non-macOS platforms', function() {
beforeEach(function() {
xterm.browser.isMac = false;
});
// Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100
// http://unix.stackexchange.com/a/108106
it('should return \\x1b[5D for alt+left', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D
});
it('should return \\x1b[5C for alt+right', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
});
});
it('should return \\x1b[5C for alt+right', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C
describe('On macOS platforms', function() {
beforeEach(function() {
xterm.browser.isMac = true;
});
it('should return \\x1bb for alt+left', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1bb'); // CSI 5 D
});
it('should return \\x1bf for alt+right', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1bf'); // CSI 5 C
});
});
it('should return \\x1b[5A for alt+up', function() {
assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A
});
+7 -2
View File
@@ -434,6 +434,9 @@ Terminal.prototype.initGlobal = function() {
on(this.textarea, 'paste', function (ev) {
pasteHandler.call(this, ev, term);
});
on(this.element, 'paste', function (ev) {
pasteHandler.call(this, ev, term);
});
function rightClickHandlerWrapper (ev) {
rightClickHandler.call(this, ev, term);
@@ -2486,8 +2489,9 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) {
result.key = '\x1b[1;' + (modifiers + 1) + 'D';
// HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards
// http://unix.stackexchange.com/a/108106
// macOS uses different escape sequences than linux
if (result.key == '\x1b[1;3D') {
result.key = '\x1b[1;5D';
result.key = (this.browser.isMac) ? '\x1bb' : '\x1b[1;5D';
}
} else if (this.applicationCursor) {
result.key = '\x1bOD';
@@ -2501,8 +2505,9 @@ Terminal.prototype.evaluateKeyEscapeSequence = function(ev) {
result.key = '\x1b[1;' + (modifiers + 1) + 'C';
// HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward
// http://unix.stackexchange.com/a/108106
// macOS uses different escape sequences than linux
if (result.key == '\x1b[1;3C') {
result.key = '\x1b[1;5C';
result.key = (this.browser.isMac) ? '\x1bf' : '\x1b[1;5C';
}
} else if (this.applicationCursor) {
result.key = '\x1bOC';
+1 -1
View File
@@ -4,7 +4,7 @@
"target": "es5",
"rootDir": "src",
"allowJs": true,
"outDir": "out",
"outDir": "lib",
"sourceMap": true
},
"exclude": [
+53
View File
@@ -0,0 +1,53 @@
{
"rules": {
"class-name": true,
"comment-format": [
true,
"check-space"
],
"indent": [
true,
"spaces"
],
"eofline": true,
"no-eval": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"no-var-keyword": true,
"quotemark": [
true,
"single"
],
"semicolon": [
true,
"always"
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [
true,
"ban-keywords"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
]
}
}