Merge remote-tracking branch 'ups/master' into 553_find_api

This commit is contained in:
Daniel Imms
2017-07-08 23:07:57 -07:00
20 changed files with 12813 additions and 203 deletions
+1 -1
View File
@@ -1 +1 @@
* text=auto eol=lf
* text=auto
+7
View File
@@ -1,11 +1,15 @@
List of xterm.js contributors. Updated before every release.
Aleksandr Andrienko <aandrienko@codenvy.com>
Aleksandr Andriienko <oandriie@redhat.com>
Alessandro Nadalin <alessandro.nadalin@gmail.com>
Alexander Olsson <noseglid@gmail.com>
Alexey Kontsevoy <alexey@gravitational.com>
Anish Athalye <me@anishathalye.com>
Antonis Kalipetis <akalipetis@sourcelair.com>
Anton Skshidlevsky <meefik@gmail.com>
Anton Yurovskykh <anton.yurovskykh@gmail.com>
Artem Arbatskiy <artyom.arbatskiy@gmail.com>
Austin Robertson <austinrobertson@gmail.com>
ayapi <colors.aya@gmail.com>
Ben Hall <ben@benhall.me.uk>
@@ -15,6 +19,7 @@ Bob Reid <bobreid@Bobs-MacBook-Pro.local>
bottleofwater <nison.mael+bottleofwater@gmail.com>
Brian Mock <brian@mockbrian.com>
Carson Anderson <carson@betterservers.com>
CHaBou <chabup@delean.fr>
Christian Budde Christensen <budde377@gmail.com>
Christopher Jeffrey <chjjeffrey@gmail.com>
coderaiser <mnemonic.enemy@gmail.com>
@@ -29,6 +34,7 @@ hiro-su <h.sugipon@gmail.com>
Ian Lewis <ianlewis@google.com>
imoses <ido@twiggle.com>
InDieTasten <indietasten@gmail.com>
irokas <akasidiari@inf.uth.gr>
Jean Bruenn <himself@jeanbruenn.info>
Jeremy Danyow <jedanyow@microsoft.com>
Jörg Breitbart <jerch@rockborn.de>
@@ -40,6 +46,7 @@ Martin Wang <jiahaow@ca.ibm.com>
Michael Irwin <mikesir87@gmail.com>
Mikko Karvonen <mikko.karvonen@arm.com>
Nicolas Ramz <nicolas.ramz@gmail.com>
Oleksandr Andriienko <oandriie@redhat.com>
Paris Kasidiaris <pariskasidiaris@gmail.com>
Paris Kasidiaris <paris@sourcelair.com>
runarberg <runar@greenqloud.com>
+2 -1
View File
@@ -37,6 +37,7 @@ Xterm.js is used in several world-class applications to provide great terminal e
- [**Terminal for Atom**](https://github.com/jsmecham/atom-terminal-tab): A simple terminal for the Atom text editor.
- [**Eclipse Orion**](https://orionhub.org): A modern, open source software development environment that runs in the cloud. Code, deploy and run in the cloud.
- [**Gravitational Teleport**](https://github.com/gravitational/teleport): Gravitational Teleport is a modern SSH server for remotely accessing clusters of Linux servers via SSH or HTTPS.
- [**Hexlet**](https://en.hexlet.io): Practical programming courses (JavaScript, PHP, Unix, databases, functional programming). A steady path from the first line of code to the first job.
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.
@@ -134,6 +135,6 @@ To contribute either code, documentation or issues to xterm.js please read the [
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.
Copyright (c) 2014-2016, SourceLair, Private Company ([www.sourcelair.com](https://www.sourcelair.com/home)) (MIT License)
Copyright (c) 2014-2017, SourceLair, Private Company ([www.sourcelair.com](https://www.sourcelair.com/home)) (MIT License)
Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "xterm.js",
"version": "2.7.0",
"version": "2.8.1",
"ignore": ["demo", "test", ".gitignore"],
"main": [
"dist/xterm.js",
+1
View File
@@ -5,6 +5,7 @@
<link rel="stylesheet" href="/build/xterm.css" />
<link rel="stylesheet" href="/build/addons/fullscreen/fullscreen.css" />
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.1.1/es6-promise.auto.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fetch/1.0.0/fetch.min.js"></script>
<script src="/build/xterm.js" ></script>
<script src="/build/addons/attach/attach.js" ></script>
+22
View File
@@ -41,6 +41,9 @@
font-family: courier-new, courier, monospace;
font-feature-settings: "liga" 0;
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.terminal.focus,
@@ -180,6 +183,25 @@
left: -9999em;
}
.terminal.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.terminal .xterm-selection {
position: absolute;
top: 0;
left: 0;
z-index: 1;
opacity: 0.3;
pointer-events: none;
}
.terminal .xterm-selection div {
position: absolute;
background-color: #fff;
}
/*
* Determine default colors for xterm.js
*/
+758 -118
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -56,7 +56,7 @@ gulp.task('browserify', ['tsc'], function() {
let browserifyOptions = {
basedir: buildDir,
debug: true,
entries: [`../${outDir}/xterm.js`],
entries: [`${outDir}/xterm.js`],
standalone: 'Terminal',
cache: {},
packageCache: {}
+11892
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "xterm",
"description": "Full xterm terminal, in your browser",
"version": "2.7.0",
"version": "2.8.1",
"ignore": [
"demo",
"test",
@@ -36,7 +36,7 @@
],
"devDependencies": {
"@types/chai": "^3.4.34",
"@types/jsdom": "^2.0.30",
"@types/jsdom": "^11.0.1",
"@types/mocha": "^2.2.33",
"@types/node": "^6.0.41",
"browserify": "^13.1.0",
@@ -54,7 +54,7 @@
"gulp-sourcemaps": "1.9.1",
"gulp-typescript": "^3.1.3",
"jsdoc": "3.4.3",
"jsdom": "^9.11.0",
"jsdom": "^11.1.0",
"merge-stream": "^1.0.1",
"node-pty": "^0.4.1",
"nodemon": "1.10.2",
+5
View File
@@ -56,8 +56,13 @@ export class InputHandler implements IInputHandler {
this._terminal.x = 0;
this._terminal.y++;
if (this._terminal.y > this._terminal.scrollBottom) {
// Insert a new line, scroll and mark as a wrapped line
this._terminal.y--;
this._terminal.scroll(true);
} else {
// The line already exists (eg. the initial viewport), mark it as a
// wrapped line
this._terminal.lines.get(this._terminal.y).isWrapped = true;
}
} else {
if (ch_width === 2) // FIXME: check for xterm behavior
+6 -7
View File
@@ -17,6 +17,7 @@ class TestLinkifier extends Linkifier {
}
describe('Linkifier', () => {
let dom: jsdom.JSDOM;
let window: Window;
let document: Document;
@@ -24,13 +25,11 @@ describe('Linkifier', () => {
let rows: HTMLElement[];
let linkifier: TestLinkifier;
beforeEach(done => {
jsdom.env('', (err, w) => {
window = w;
document = window.document;
linkifier = new TestLinkifier();
done();
});
beforeEach(() => {
dom = new jsdom.JSDOM('');
window = dom.window;
document = window.document;
linkifier = new TestLinkifier();
});
function addRow(html: string) {
+2 -1
View File
@@ -200,7 +200,8 @@ export class Renderer {
}
currentElement = this._spanElementObjectPool.acquire();
if (data === -1) {
currentElement.classList.add('reverse-video', 'terminal-cursor');
currentElement.classList.add('reverse-video');
currentElement.classList.add('terminal-cursor');
} else {
let bg = data & 0x1ff;
let fg = (data >> 9) & 0x1ff;
+24 -33
View File
@@ -31,6 +31,7 @@ class TestSelectionManager extends SelectionManager {
}
describe('SelectionManager', () => {
let dom: jsdom.JSDOM;
let window: Window;
let document: Document;
@@ -39,15 +40,13 @@ describe('SelectionManager', () => {
let rowContainer: HTMLElement;
let selectionManager: TestSelectionManager;
beforeEach(done => {
jsdom.env('', (err, w) => {
window = w;
document = window.document;
buffer = new CircularList<any>(100);
terminal = <any>{ cols: 80, rows: 2 };
selectionManager = new TestSelectionManager(terminal, buffer, rowContainer, null);
done();
});
beforeEach(() => {
dom = new jsdom.JSDOM('');
window = dom.window;
document = window.document;
buffer = new CircularList<any>(100);
terminal = <any>{ cols: 80, rows: 2 };
selectionManager = new TestSelectionManager(terminal, buffer, rowContainer, null);
});
function stringToRow(text: string): [number, string, number][] {
@@ -143,46 +142,38 @@ describe('SelectionManager', () => {
assert.equal(selectionManager.selectionText, 'foo');
});
it('should select up to non-path characters that are commonly adjacent to paths', () => {
buffer.push(stringToRow(':ab:(cd)[ef]{gh}\'ij"'));
buffer.push(stringToRow('(cd)[ef]{gh}\'ij"'));
selectionManager.selectWordAt([0, 0]);
assert.equal(selectionManager.selectionText, ':ab');
selectionManager.selectWordAt([1, 0]);
assert.equal(selectionManager.selectionText, 'ab');
selectionManager.selectWordAt([2, 0]);
assert.equal(selectionManager.selectionText, 'ab');
selectionManager.selectWordAt([3, 0]);
assert.equal(selectionManager.selectionText, 'ab:');
selectionManager.selectWordAt([4, 0]);
assert.equal(selectionManager.selectionText, '(cd');
selectionManager.selectWordAt([5, 0]);
selectionManager.selectWordAt([1, 0]);
assert.equal(selectionManager.selectionText, 'cd');
selectionManager.selectWordAt([6, 0]);
selectionManager.selectWordAt([2, 0]);
assert.equal(selectionManager.selectionText, 'cd');
selectionManager.selectWordAt([7, 0]);
selectionManager.selectWordAt([3, 0]);
assert.equal(selectionManager.selectionText, 'cd)');
selectionManager.selectWordAt([8, 0]);
selectionManager.selectWordAt([4, 0]);
assert.equal(selectionManager.selectionText, '[ef');
selectionManager.selectWordAt([9, 0]);
selectionManager.selectWordAt([5, 0]);
assert.equal(selectionManager.selectionText, 'ef');
selectionManager.selectWordAt([10, 0]);
selectionManager.selectWordAt([6, 0]);
assert.equal(selectionManager.selectionText, 'ef');
selectionManager.selectWordAt([11, 0]);
selectionManager.selectWordAt([7, 0]);
assert.equal(selectionManager.selectionText, 'ef]');
selectionManager.selectWordAt([12, 0]);
selectionManager.selectWordAt([8, 0]);
assert.equal(selectionManager.selectionText, '{gh');
selectionManager.selectWordAt([13, 0]);
selectionManager.selectWordAt([9, 0]);
assert.equal(selectionManager.selectionText, 'gh');
selectionManager.selectWordAt([14, 0]);
selectionManager.selectWordAt([10, 0]);
assert.equal(selectionManager.selectionText, 'gh');
selectionManager.selectWordAt([15, 0]);
selectionManager.selectWordAt([11, 0]);
assert.equal(selectionManager.selectionText, 'gh}');
selectionManager.selectWordAt([16, 0]);
selectionManager.selectWordAt([12, 0]);
assert.equal(selectionManager.selectionText, '\'ij');
selectionManager.selectWordAt([17, 0]);
selectionManager.selectWordAt([13, 0]);
assert.equal(selectionManager.selectionText, 'ij');
selectionManager.selectWordAt([18, 0]);
selectionManager.selectWordAt([14, 0]);
assert.equal(selectionManager.selectionText, 'ij');
selectionManager.selectWordAt([19, 0]);
selectionManager.selectWordAt([15, 0]);
assert.equal(selectionManager.selectionText, 'ij"');
});
});
+3 -2
View File
@@ -43,7 +43,7 @@ const CLEAR_MOUSE_DISTANCE = 10;
* A string containing all characters that are considered word separated by the
* double click to select work logic.
*/
const WORD_SEPARATORS = ' ()[]{}:\'"';
const WORD_SEPARATORS = ' ()[]{}\'"';
// TODO: Move these constants elsewhere, they belong in a buffer or buffer
// data/line class.
@@ -179,6 +179,7 @@ export class SelectionManager extends EventEmitter {
*/
public setBuffer(buffer: CircularList<any>): void {
this._buffer = buffer;
this.clearSelection();
}
public get selectionStart(): [number, number] { return this._model.finalSelectionStart; }
@@ -237,7 +238,7 @@ export class SelectionManager extends EventEmitter {
// and joining the array into a multi-line string.
const formattedResult = result.map(line => {
return line.replace(ALL_NON_BREAKING_SPACE_REGEX, ' ');
}).join('\n');
}).join(Browser.isMSWindows ? '\r\n' : '\n');
return formattedResult;
}
+23
View File
@@ -13,6 +13,7 @@ export class Viewport {
private currentRowHeight: number;
private lastRecordedBufferLength: number;
private lastRecordedViewportHeight: number;
private lastTouchY: number;
/**
* Creates a new Viewport.
@@ -121,4 +122,26 @@ export class Viewport {
// Prevent the page from scrolling when the terminal scrolls
ev.preventDefault();
};
/**
* Handles the touchstart event, recording the touch occurred.
* @param ev The touch event.
*/
public onTouchStart(ev: TouchEvent) {
this.lastTouchY = ev.touches[0].pageY;
};
/**
* Handles the touchmove event, scrolling the viewport if the position shifted.
* @param ev The touch event.
*/
public onTouchMove(ev: TouchEvent) {
let deltaY = this.lastTouchY - ev.touches[0].pageY;
this.lastTouchY = ev.touches[0].pageY;
if (deltaY === 0) {
return;
}
this.viewportElement.scrollTop += deltaY;
ev.preventDefault();
};
}
+5
View File
@@ -55,6 +55,11 @@ describe('xterm.js', function() {
it('should throw when setting a non-existant option', function() {
assert.throws(xterm.setOption.bind(xterm, 'fake', true));
});
it('should not allow scrollback less than number of rows', function() {
let setOptionCall = xterm.setOption.bind(xterm, 'scrollback', xterm.rows - 1);
assert.equal(setOptionCall(), false);
});
});
describe('clear', function() {
+8 -10
View File
@@ -7,21 +7,19 @@ import { ICharMeasure, ITerminal } from '../Interfaces';
import { CharMeasure } from './CharMeasure';
describe('CharMeasure', () => {
let dom: jsdom.JSDOM;
let window: Window;
let document: Document;
let container: HTMLElement;
let charMeasure: ICharMeasure;
beforeEach(done => {
jsdom.env('', (err, w) => {
window = w;
document = window.document;
container = document.createElement('div');
document.body.appendChild(container);
charMeasure = new CharMeasure(document, container);
done();
});
beforeEach(() => {
dom = new jsdom.JSDOM('');
window = dom.window;
document = window.document;
container = document.createElement('div');
document.body.appendChild(container);
charMeasure = new CharMeasure(document, container);
});
describe('measure', () => {
+48 -24
View File
@@ -420,6 +420,15 @@ Terminal.prototype.setOption = function(key, value) {
}
switch (key) {
case 'scrollback':
if (value < this.rows) {
let msg = 'Setting the scrollback value less than the number of rows ';
msg += `(${this.rows}) is not allowed.`;
console.warn(msg);
return false;
}
if (this.options[key] !== value) {
if (this.lines.length > value) {
const amountToTrim = this.lines.length - value;
@@ -653,7 +662,6 @@ Terminal.prototype.open = function(parent, focus) {
this.element.classList.add('xterm-theme-' + this.theme);
this.setCursorBlinking(this.options.cursorBlink);
this.element.style.height;
this.element.setAttribute('tabindex', 0);
this.viewportElement = document.createElement('div');
@@ -1088,6 +1096,18 @@ Terminal.prototype.bindMouse = function() {
self.viewport.onWheel(ev);
return self.cancel(ev);
});
on(el, 'touchstart', function(ev) {
if (self.mouseEvents) return;
self.viewport.onTouchStart(ev);
return self.cancel(ev);
});
on(el, 'touchmove', function(ev) {
if (self.mouseEvents) return;
self.viewport.onTouchMove(ev);
return self.cancel(ev);
});
};
/**
@@ -1128,7 +1148,7 @@ Terminal.prototype.queueLinkification = function(start, end) {
this.linkifier.linkifyRow(i);
}
}
}
};
/**
* Display the cursor element
@@ -1239,25 +1259,25 @@ Terminal.prototype.scrollDisp = function(disp, suppressScrollEvent) {
*/
Terminal.prototype.scrollPages = function(pageCount) {
this.scrollDisp(pageCount * (this.rows - 1));
}
};
/**
* Scrolls the display of the terminal to the top.
*/
Terminal.prototype.scrollToTop = function() {
this.scrollDisp(-this.ydisp);
}
};
/**
* Scrolls the display of the terminal to the bottom.
*/
Terminal.prototype.scrollToBottom = function() {
this.scrollDisp(this.ybase - this.ydisp);
}
};
/**
* Writes text to the terminal.
* @param {string} text The text to write to the terminal.
* @param {string} data The text to write to the terminal.
*/
Terminal.prototype.write = function(data) {
this.writeBuffer.push(data);
@@ -1281,7 +1301,7 @@ Terminal.prototype.write = function(data) {
self.innerWrite();
});
}
}
};
Terminal.prototype.innerWrite = function() {
var writeBatch = this.writeBuffer.splice(0, WRITE_BATCH_SIZE);
@@ -1323,7 +1343,7 @@ Terminal.prototype.innerWrite = function() {
/**
* Writes text to the terminal, followed by a break line character (\n).
* @param {string} text The text to write to the terminal.
* @param {string} data The text to write to the terminal.
*/
Terminal.prototype.writeln = function(data) {
this.write(data + '\r\n');
@@ -1339,25 +1359,25 @@ Terminal.prototype.attachCustomKeydownHandler = function(customKeydownHandler) {
let message = 'attachCustomKeydownHandler() is DEPRECATED and will be removed soon. Please use attachCustomKeyEventHandler() instead.';
console.warn(message);
this.attachCustomKeyEventHandler(customKeydownHandler);
}
};
/**
* Attaches a custom key event handler which is run before keys are processed, giving consumers of
* xterm.js ultimate control as to what keys should be processed by the terminal and what keys
* should not.
* @param {function} customKeypressHandler The custom KeyboardEvent handler to attach. This is a
* @param {function} customKeyEventHandler The custom KeyboardEvent handler to attach. This is a
* function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent
* the default action. The function returns whether the event should be processed by xterm.js.
*/
Terminal.prototype.attachCustomKeyEventHandler = function(customKeyEventHandler) {
this.customKeyEventHandler = customKeyEventHandler;
}
};
/**
* Attaches a http(s) link handler, forcing web links to behave differently to
* regular <a> tags. This will trigger a refresh as links potentially need to be
* reconstructed. Calling this with null will remove the handler.
* @param {LinkHandler} handler The handler callback function.
* @param {LinkMatcherHandler} handler The handler callback function.
*/
Terminal.prototype.setHypertextLinkHandler = function(handler) {
if (!this.linkifier) {
@@ -1366,7 +1386,7 @@ Terminal.prototype.setHypertextLinkHandler = function(handler) {
this.linkifier.setHypertextLinkHandler(handler);
// Refresh to force links to refresh
this.refresh(0, this.rows - 1);
}
};
/**
* Attaches a validation callback for hypertext links. This is useful to use
@@ -1374,14 +1394,14 @@ Terminal.prototype.setHypertextLinkHandler = function(handler) {
* @param {LinkMatcherValidationCallback} callback The callback to use, this can
* be cleared with null.
*/
Terminal.prototype.setHypertextValidationCallback = function(handler) {
Terminal.prototype.setHypertextValidationCallback = function(callback) {
if (!this.linkifier) {
throw new Error('Cannot attach a hypertext validation callback before Terminal.open is called');
}
this.linkifier.setHypertextValidationCallback(handler);
this.linkifier.setHypertextValidationCallback(callback);
// Refresh to force links to refresh
this.refresh(0, this.rows - 1);
}
};
/**
* Registers a link matcher, allowing custom link patterns to be matched and
@@ -1389,7 +1409,7 @@ Terminal.prototype.setHypertextValidationCallback = function(handler) {
* @param {RegExp} regex The regular expression to search for, specifically
* this searches the textContent of the rows. You will want to use \s to match
* a space ' ' character for example.
* @param {LinkHandler} handler The callback when the link is called.
* @param {LinkMatcherHandler} handler The callback when the link is called.
* @param {LinkMatcherOptions} [options] Options for the link matcher.
* @return {number} The ID of the new matcher, this can be used to deregister.
*/
@@ -1399,7 +1419,7 @@ Terminal.prototype.registerLinkMatcher = function(regex, handler, options) {
this.refresh(0, this.rows - 1);
return matcherId;
}
}
};
/**
* Deregisters a link matcher if it has been registered.
@@ -1411,14 +1431,14 @@ Terminal.prototype.deregisterLinkMatcher = function(matcherId) {
this.refresh(0, this.rows - 1);
}
}
}
};
/**
* Gets whether the terminal has an active selection.
*/
Terminal.prototype.hasSelection = function() {
return this.selectionManager.hasSelection;
}
};
/**
* Gets the terminal's current selection, this is useful for implementing copy
@@ -1426,21 +1446,21 @@ Terminal.prototype.hasSelection = function() {
*/
Terminal.prototype.getSelection = function() {
return this.selectionManager.selectionText;
}
};
/**
* Clears the current terminal selection.
*/
Terminal.prototype.clearSelection = function() {
this.selectionManager.clearSelection();
}
};
/**
* Selects all text within the terminal.
*/
Terminal.prototype.selectAll = function() {
this.selectionManager.selectAll();
}
};
/**
* Handle a keydown event
@@ -1908,6 +1928,10 @@ Terminal.prototype.resize = function(x, y) {
return;
}
if (y > this.getOption('scrollback')) {
this.setOption('scrollback', y)
}
var line
, el
, i
@@ -1949,7 +1973,7 @@ Terminal.prototype.resize = function(x, y) {
// There is room above the buffer and there are no empty elements below the line,
// scroll up
this.ybase--;
addToY++
addToY++;
if (this.ydisp > 0) {
// Viewport is at the top of the buffer, must increase downwards
this.ydisp--;