Merge branch 'master' into ctrl-alt-sequences

This commit is contained in:
Saad Malik
2018-01-26 13:38:48 -08:00
committed by GitHub
48 changed files with 775 additions and 763 deletions
+1 -5
View File
@@ -19,10 +19,6 @@ fixtures/typings-test/*.js
# Directories needed for code coverage
/coverage/
# Keep legacy files out of the repo, this can be removed when we merge v3 into master
# Keep bundled code out of Git
dist/
src/utils/TestUtils.ts
src/xterm.js
# Keep the demo builds out of Git
demo/dist/
+4
View File
@@ -166,6 +166,10 @@ Xterm.js is maintained by [SourceLair](https://www.sourcelair.com/) and a few ex
To contribute either code, documentation or issues to xterm.js please read the [Contributing document](CONTRIBUTING.md) beforehand. The development of xterm.js does not require any special tool. All you need is an editor that supports JavaScript/TypeScript and a browser. You will need Node.js installed locally to get all the features working in the demo.
### Code structure
`src/` is roughly split up into areas of functionality such as `renderer/` that handles all rendering and `utils/` which provides general utility functions. The `shared/` folder contains code that can be used from either the main thread or a web worker thread, all code inside a `shared/` folder should only ever import other code from a `shared/` folder to minimize the amount of code run what launching a web worker.
## 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
View File
@@ -159,6 +159,7 @@ namespace methods_core {
t.setOption('cursorBlink', true);
t.setOption('debug', true);
t.setOption('disableStdin', true);
t.setOption('enableBold', true);
t.setOption('fontWeight', 'normal');
t.setOption('fontWeight', 'bold');
t.setOption('fontWeightBold', 'normal');
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "xterm",
"description": "Full xterm terminal, in your browser",
"version": "3.0.0",
"version": "3.1.0-master",
"ignore": [
"demo",
"test",
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import { assert } from 'chai';
import { ITerminal } from './Interfaces';
import { ITerminal } from './Types';
import { Buffer } from './Buffer';
import { CircularList } from './utils/CircularList';
import { MockTerminal } from './utils/TestUtils.test';
+5 -9
View File
@@ -3,9 +3,8 @@
* @license MIT
*/
import { ITerminal, IBuffer } from './Interfaces';
import { CircularList } from './utils/CircularList';
import { LineData, CharData } from './Types';
import { LineData, CharData, ITerminal, IBuffer } from './Types';
export const CHAR_DATA_ATTR_INDEX = 0;
export const CHAR_DATA_CHAR_INDEX = 1;
@@ -177,16 +176,13 @@ export class Buffer implements IBuffer {
}
// Make sure that the cursor stays on screen
if (this.y >= newRows) {
this.y = newRows - 1;
}
this.x = Math.min(this.x, newCols - 1);
this.y = Math.min(this.y, newRows - 1);
if (addToY) {
this.y += addToY;
}
if (this.x >= newCols) {
this.x = newCols - 1;
}
this.savedY = Math.min(this.savedY, newRows - 1);
this.savedX = Math.min(this.savedX, newCols - 1);
this.scrollTop = 0;
}
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import { assert } from 'chai';
import { ITerminal } from './Interfaces';
import { ITerminal } from './Types';
import { BufferSet } from './BufferSet';
import { Buffer } from './Buffer';
import { MockTerminal } from './utils/TestUtils.test';
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { ITerminal, IBufferSet } from './Interfaces';
import { ITerminal, IBufferSet } from './Types';
import { Buffer } from './Buffer';
import { EventEmitter } from './EventEmitter';
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { ICharset } from './Interfaces';
import { ICharset } from './Types';
/**
* The character sets supported by the terminal. These enable several languages
+1 -1
View File
@@ -3,7 +3,7 @@
* @license MIT
*/
import { ITerminal } from './Interfaces';
import { ITerminal } from './Types';
interface IPosition {
start: number;
-12
View File
@@ -13,18 +13,6 @@ describe('EventEmitter', () => {
eventEmitter = new EventEmitter();
});
describe('once', () => {
it('should trigger the listener only once', () => {
let count = 0;
const listener = () => count++;
eventEmitter.once('test', listener);
eventEmitter.emit('test');
assert.equal(count, 1);
eventEmitter.emit('test');
assert.equal(count, 1);
});
});
describe('emit', () => {
it('should emit events to listeners', () => {
let count1 = 0;
+6 -16
View File
@@ -3,10 +3,10 @@
* @license MIT
*/
import { IEventEmitter, IListenerType } from './Interfaces';
import { IEventEmitter } from 'xterm';
export class EventEmitter implements IEventEmitter {
private _events: {[type: string]: IListenerType[]};
private _events: {[type: string]: ((...args: any[]) => void)[]};
constructor() {
// Restore the previous events if available, this will happen if the
@@ -14,12 +14,12 @@ export class EventEmitter implements IEventEmitter {
this._events = this._events || {};
}
public on(type: string, listener: IListenerType): void {
public on(type: string, listener: ((...args: any[]) => void)): void {
this._events[type] = this._events[type] || [];
this._events[type].push(listener);
}
public off(type: string, listener: IListenerType): void {
public off(type: string, listener: ((...args: any[]) => void)): void {
if (!this._events[type]) {
return;
}
@@ -28,7 +28,7 @@ export class EventEmitter implements IEventEmitter {
let i = obj.length;
while (i--) {
if (obj[i] === listener || obj[i].listener === listener) {
if (obj[i] === listener) {
obj.splice(i, 1);
return;
}
@@ -41,16 +41,6 @@ export class EventEmitter implements IEventEmitter {
}
}
public once(type: string, listener: IListenerType): void {
function on(): void {
let args = Array.prototype.slice.call(arguments);
this.off(type, on);
listener.apply(this, args);
}
(<any>on).listener = listener;
this.on(type, on);
}
public emit(type: string, ...args: any[]): void {
if (!this._events[type]) {
return;
@@ -61,7 +51,7 @@ export class EventEmitter implements IEventEmitter {
}
}
public listeners(type: string): IListenerType[] {
public listeners(type: string): ((...args: any[]) => void)[] {
return this._events[type] || [];
}
+1 -2
View File
@@ -4,10 +4,9 @@
* @license MIT
*/
import { IInputHandler, ITerminal, IInputHandlingTerminal } from './Interfaces';
import { CharData, IInputHandler, IInputHandlingTerminal, ITerminal } from './Types';
import { C0 } from './EscapeSequences';
import { DEFAULT_CHARSET } from './Charsets';
import { CharData } from './Types';
import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer';
import { FLAGS } from './renderer/Types';
import { wcwidth } from './CharWidth';
-376
View File
@@ -1,376 +0,0 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { ICharset, ILinkMatcherOptions } from './Interfaces';
import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData, FontWeight } from './Types';
import { IColorSet, IRenderer } from './renderer/Interfaces';
import { IMouseZoneManager } from './input/Interfaces';
export interface IBrowser {
isNode: boolean;
userAgent: string;
platform: string;
isFirefox: boolean;
isMSIE: boolean;
isMac: boolean;
isIpad: boolean;
isIphone: boolean;
isMSWindows: boolean;
}
export interface IBufferAccessor {
buffer: IBuffer;
}
export interface IElementAccessor {
element: HTMLElement;
}
export interface ILinkifierAccessor {
linkifier: ILinkifier;
}
export interface ITerminal extends ILinkifierAccessor, IBufferAccessor, IElementAccessor, IEventEmitter {
selectionManager: ISelectionManager;
charMeasure: ICharMeasure;
textarea: HTMLTextAreaElement;
renderer: IRenderer;
rows: number;
cols: number;
browser: IBrowser;
writeBuffer: string[];
cursorHidden: boolean;
cursorState: number;
defAttr: number;
options: ITerminalOptions;
buffers: IBufferSet;
isFocused: boolean;
mouseHelper: IMouseHelper;
bracketedPasteMode: boolean;
/**
* Emit the 'data' event and populate the given data.
* @param data The data to populate in the event.
*/
handler(data: string): void;
scrollLines(disp: number, suppressScrollEvent?: boolean): void;
cancel(ev: Event, force?: boolean): boolean | void;
log(text: string): void;
reset(): void;
showCursor(): void;
blankLine(cur?: boolean, isWrapped?: boolean, cols?: number): LineData;
refresh(start: number, end: number): void;
}
/**
* This interface encapsulates everything needed from the Terminal by the
* InputHandler. This cleanly separates the large amount of methods needed by
* InputHandler cleanly from the ITerminal interface.
*/
export interface IInputHandlingTerminal extends IEventEmitter {
element: HTMLElement;
options: ITerminalOptions;
cols: number;
rows: number;
charset: ICharset;
gcharset: number;
glevel: number;
charsets: ICharset[];
applicationKeypad: boolean;
applicationCursor: boolean;
originMode: boolean;
insertMode: boolean;
wraparoundMode: boolean;
bracketedPasteMode: boolean;
defAttr: number;
curAttr: number;
prefix: string;
savedCols: number;
x10Mouse: boolean;
vt200Mouse: boolean;
normalMouse: boolean;
mouseEvents: boolean;
sendFocus: boolean;
utfMouse: boolean;
sgrMouse: boolean;
urxvtMouse: boolean;
cursorHidden: boolean;
buffers: IBufferSet;
buffer: IBuffer;
viewport: IViewport;
selectionManager: ISelectionManager;
bell(): void;
focus(): void;
convertEol: boolean;
updateRange(y: number): void;
scroll(isWrapped?: boolean): void;
setgLevel(g: number): void;
eraseAttr(): number;
eraseRight(x: number, y: number): void;
eraseLine(y: number): void;
eraseLeft(x: number, y: number): void;
blankLine(cur?: boolean, isWrapped?: boolean): LineData;
is(term: string): boolean;
send(data: string): void;
setgCharset(g: number, charset: ICharset): void;
resize(x: number, y: number): void;
log(text: string, data?: any): void;
reset(): void;
showCursor(): void;
refresh(start: number, end: number): void;
matchColor(r1: number, g1: number, b1: number): number;
error(text: string, data?: any): void;
setOption(key: string, value: any): void;
}
export interface ITerminalOptions {
bellSound?: string;
bellStyle?: string;
cancelEvents?: boolean;
cols?: number;
convertEol?: boolean;
cursorBlink?: boolean;
cursorStyle?: string;
debug?: boolean;
disableStdin?: boolean;
fontSize?: number;
fontFamily?: string;
fontWeight?: FontWeight;
fontWeightBold?: FontWeight;
handler?: (data: string) => void;
letterSpacing?: number;
lineHeight?: number;
macOptionIsMeta?: boolean;
rows?: number;
screenKeys?: boolean;
scrollback?: number;
tabStopWidth?: number;
termName?: string;
theme?: ITheme;
useFlowControl?: boolean;
}
export interface IBuffer {
lines: ICircularList<LineData>;
ydisp: number;
ybase: number;
y: number;
x: number;
tabs: any;
scrollBottom: number;
scrollTop: number;
savedY: number;
savedX: number;
isCursorInViewport: boolean;
translateBufferLineToString(lineIndex: number, trimRight: boolean, startCol?: number, endCol?: number): string;
nextStop(x?: number): number;
prevStop(x?: number): number;
}
export interface IBufferSet extends IEventEmitter {
alt: IBuffer;
normal: IBuffer;
active: IBuffer;
activateNormalBuffer(): void;
activateAltBuffer(): void;
}
export interface IMouseHelper {
getCoords(event: {pageX: number, pageY: number}, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number, isSelection?: boolean): [number, number];
getRawByteCoords(event: MouseEvent, element: HTMLElement, charMeasure: ICharMeasure, lineHeight: number, colCount: number, rowCount: number): { x: number, y: number };
}
export interface IViewport {
syncScrollArea(): void;
onWheel(ev: WheelEvent): void;
onTouchStart(ev: TouchEvent): void;
onTouchMove(ev: TouchEvent): void;
onThemeChanged(colors: IColorSet): void;
}
export interface ISelectionManager {
selectionText: string;
selectionStart: [number, number];
selectionEnd: [number, number];
disable(): void;
enable(): void;
setSelection(row: number, col: number, length: number): void;
}
export interface ICompositionHelper {
compositionstart(): void;
compositionupdate(ev: CompositionEvent): void;
compositionend(): void;
updateCompositionElements(dontRecurse?: boolean): void;
keydown(ev: KeyboardEvent): boolean;
}
export interface ICharMeasure {
width: number;
height: number;
measure(options: ITerminalOptions): void;
}
export interface ILinkifier extends IEventEmitter {
attachToDom(mouseZoneManager: IMouseZoneManager): void;
linkifyRows(start: number, end: number): void;
setHypertextLinkHandler(handler: LinkMatcherHandler): void;
setHypertextValidationCallback(callback: LinkMatcherValidationCallback): void;
registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number;
deregisterLinkMatcher(matcherId: number): boolean;
}
export interface ICircularList<T> extends IEventEmitter {
length: number;
maxLength: number;
forEach: (callbackfn: (value: T, index: number) => void) => void;
get(index: number): T;
set(index: number, value: T): void;
push(value: T): void;
pop(): T;
splice(start: number, deleteCount: number, ...items: T[]): void;
trimStart(count: number): void;
shiftElements(start: number, count: number, offset: number): void;
}
export interface IEventEmitter {
on(type: string, listener: IListenerType): void;
off(type: string, listener: IListenerType): void;
emit(type: string, data?: any): void;
}
export interface IListenerType {
(data?: any): void;
listener?: (data?: any) => void;
}
export interface ILinkMatcherOptions {
/**
* The index of the link from the regex.match(text) call. This defaults to 0
* (for regular expressions without capture groups).
*/
matchIndex?: number;
/**
* A callback that validates an individual link, returning true if valid and
* false if invalid.
*/
validationCallback?: LinkMatcherValidationCallback;
/**
* A callback that fires when the mouse hovers over a link.
*/
tooltipCallback?: LinkMatcherHandler;
/**
* A callback that fires when the mouse leaves a link that was hovered.
*/
leaveCallback?: () => void;
/**
* The priority of the link matcher, this defines the order in which the link
* matcher is evaluated relative to others, from highest to lowest. The
* default value is 0.
*/
priority?: number;
}
/**
* Handles actions generated by the parser.
*/
export interface IInputHandler {
addChar(char: string, code: number): void;
/** C0 BEL */ bell(): void;
/** C0 LF */ lineFeed(): void;
/** C0 CR */ carriageReturn(): void;
/** C0 BS */ backspace(): void;
/** C0 HT */ tab(): void;
/** C0 SO */ shiftOut(): void;
/** C0 SI */ shiftIn(): void;
/** CSI @ */ insertChars(params?: number[]): void;
/** CSI A */ cursorUp(params?: number[]): void;
/** CSI B */ cursorDown(params?: number[]): void;
/** CSI C */ cursorForward(params?: number[]): void;
/** CSI D */ cursorBackward(params?: number[]): void;
/** CSI E */ cursorNextLine(params?: number[]): void;
/** CSI F */ cursorPrecedingLine(params?: number[]): void;
/** CSI G */ cursorCharAbsolute(params?: number[]): void;
/** CSI H */ cursorPosition(params?: number[]): void;
/** CSI I */ cursorForwardTab(params?: number[]): void;
/** CSI J */ eraseInDisplay(params?: number[]): void;
/** CSI K */ eraseInLine(params?: number[]): void;
/** CSI L */ insertLines(params?: number[]): void;
/** CSI M */ deleteLines(params?: number[]): void;
/** CSI P */ deleteChars(params?: number[]): void;
/** CSI S */ scrollUp(params?: number[]): void;
/** CSI T */ scrollDown(params?: number[]): void;
/** CSI X */ eraseChars(params?: number[]): void;
/** CSI Z */ cursorBackwardTab(params?: number[]): void;
/** CSI ` */ charPosAbsolute(params?: number[]): void;
/** CSI a */ HPositionRelative(params?: number[]): void;
/** CSI b */ repeatPrecedingCharacter(params?: number[]): void;
/** CSI c */ sendDeviceAttributes(params?: number[]): void;
/** CSI d */ linePosAbsolute(params?: number[]): void;
/** CSI e */ VPositionRelative(params?: number[]): void;
/** CSI f */ HVPosition(params?: number[]): void;
/** CSI g */ tabClear(params?: number[]): void;
/** CSI h */ setMode(params?: number[]): void;
/** CSI l */ resetMode(params?: number[]): void;
/** CSI m */ charAttributes(params?: number[]): void;
/** CSI n */ deviceStatus(params?: number[]): void;
/** CSI p */ softReset(params?: number[]): void;
/** CSI q */ setCursorStyle(params?: number[]): void;
/** CSI r */ setScrollRegion(params?: number[]): void;
/** CSI s */ saveCursor(params?: number[]): void;
/** CSI u */ restoreCursor(params?: number[]): void;
}
export interface ITheme {
foreground?: string;
background?: string;
cursor?: string;
cursorAccent?: string;
selection?: string;
black?: string;
red?: string;
green?: string;
yellow?: string;
blue?: string;
magenta?: string;
cyan?: string;
white?: string;
brightBlack?: string;
brightRed?: string;
brightGreen?: string;
brightYellow?: string;
brightBlue?: string;
brightMagenta?: string;
brightCyan?: string;
brightWhite?: string;
}
export interface ILinkMatcher {
id: number;
regex: RegExp;
handler: LinkMatcherHandler;
hoverTooltipCallback?: LinkMatcherHandler;
hoverLeaveCallback?: () => void;
matchIndex?: number;
validationCallback?: LinkMatcherValidationCallback;
priority?: number;
}
export interface ICharset {
[key: string]: string;
}
export interface ILinkHoverEvent {
x: number;
y: number;
length: number;
}
+2 -3
View File
@@ -4,10 +4,9 @@
*/
import { assert } from 'chai';
import { ITerminal, ILinkifier, ILinkMatcher, IBuffer, IBufferAccessor, IElementAccessor } from './Interfaces';
import { IMouseZoneManager, IMouseZone } from './input/Types';
import { ILinkMatcher, LineData, ITerminal, ILinkifier, IBuffer, IBufferAccessor, IElementAccessor } from './Types';
import { Linkifier } from './Linkifier';
import { LineData } from './Types';
import { IMouseZoneManager, IMouseZone } from './input/Interfaces';
import { MockBuffer } from './utils/TestUtils.test';
import { CircularList } from './utils/CircularList';
+2 -3
View File
@@ -3,9 +3,8 @@
* @license MIT
*/
import { ILinkHoverEvent, ILinkMatcher, ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Interfaces';
import { LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEventTypes } from './Types';
import { IMouseZoneManager } from './input/Interfaces';
import { IMouseZoneManager } from './input/Types';
import { ILinkHoverEvent, ILinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback, LineData, LinkHoverEventTypes, ILinkMatcherOptions, ITerminal, IBufferAccessor, ILinkifier, IElementAccessor } from './Types';
import { MouseZone } from './input/MouseZoneManager';
import { EventEmitter } from './EventEmitter';
+1 -1
View File
@@ -5,7 +5,7 @@
*/
import { C0 } from './EscapeSequences';
import { IInputHandler } from './Interfaces';
import { IInputHandler } from './Types';
import { CHARSETS, DEFAULT_CHARSET } from './Charsets';
const normalStateHandler: {[key: string]: (parser: Parser, handler: IInputHandler) => void} = {};
+1 -2
View File
@@ -5,14 +5,13 @@
import jsdom = require('jsdom');
import { assert } from 'chai';
import { ITerminal, ICircularList, IBuffer } from './Interfaces';
import { CharMeasure } from './utils/CharMeasure';
import { CircularList } from './utils/CircularList';
import { SelectionManager } from './SelectionManager';
import { SelectionModel } from './SelectionModel';
import { BufferSet } from './BufferSet';
import { LineData, CharData, ITerminal, ICircularList, IBuffer } from './Types';
import { MockTerminal } from './utils/TestUtils.test';
import { LineData, CharData } from './Types';
class TestMockTerminal extends MockTerminal {
emit(event: string, data: any): void {}
+3 -4
View File
@@ -3,14 +3,13 @@
* @license MIT
*/
import { ITerminal, ICircularList, ISelectionManager, IBuffer, LineData, CharData } from './Types';
import { MouseHelper } from './utils/MouseHelper';
import * as Browser from './utils/Browser';
import * as Browser from './shared/utils/Browser';
import { CharMeasure } from './utils/CharMeasure';
import { CircularList } from './utils/CircularList';
import { EventEmitter } from './EventEmitter';
import { ITerminal, ICircularList, ISelectionManager, IBuffer, IListenerType } from './Interfaces';
import { SelectionModel } from './SelectionModel';
import { LineData, CharData } from './Types';
import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from './Buffer';
/**
@@ -95,7 +94,7 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
private _mouseMoveListener: EventListener;
private _mouseUpListener: EventListener;
private _trimListener: IListenerType;
private _trimListener: (...args: any[]) => void;
constructor(
private _terminal: ITerminal,
+1 -1
View File
@@ -4,7 +4,7 @@
*/
import { assert } from 'chai';
import { ITerminal } from './Interfaces';
import { ITerminal } from './Types';
import { SelectionModel } from './SelectionModel';
import { BufferSet } from './BufferSet';
import { MockTerminal } from './utils/TestUtils.test';

Some files were not shown because too many files have changed in this diff Show More