From 9e863d037742346e6dbe201ab60a10e819c5fd31 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 23 Apr 2018 11:52:42 -0700 Subject: [PATCH 01/28] Add no else return tslint rule --- package.json | 1 + src/CompositionHelper.ts | 7 +++---- src/handlers/AltClickHandler.ts | 15 ++++++--------- tslint.json | 9 ++++++++- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 49ccc387..d4a06f82 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "npm-run-all": "^4.1.2", "sorcery": "^0.10.0", "tslint": "^5.9.1", + "tslint-consistent-codestyle": "^1.13.0", "typescript": "~2.7.1", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0", diff --git a/src/CompositionHelper.ts b/src/CompositionHelper.ts index 389cb782..b721b7f1 100644 --- a/src/CompositionHelper.ts +++ b/src/CompositionHelper.ts @@ -92,11 +92,10 @@ export class CompositionHelper { } else if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) { // Continue composing if the keyCode is a modifier key return false; - } else { - // Finish composition immediately. This is mainly here for the case where enter is - // pressed and the handler needs to be triggered before the command is executed. - this._finalizeComposition(false); } + // Finish composition immediately. This is mainly here for the case where enter is + // pressed and the handler needs to be triggered before the command is executed. + this._finalizeComposition(false); } if (ev.keyCode === 229) { diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index f77637ea..221a993f 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -73,12 +73,11 @@ export class AltClickHandler { private _resetStartingRow(): string { if (this._moveToRequestedRow().length === 0) { return ''; - } else { - return repeat(this._bufferLine( - this._startCol, this._startRow, this._startCol, - this._startRow - this._wrappedRowsForRow(this._startRow), false - ).length, this._sequence(Direction.Left)); } + return repeat(this._bufferLine( + this._startCol, this._startRow, this._startCol, + this._startRow - this._wrappedRowsForRow(this._startRow), false + ).length, this._sequence(Direction.Left)); } /** @@ -180,9 +179,8 @@ export class AltClickHandler { (this._startCol >= this._endCol && startRow < this._endRow)) { // down/left or same y/left return Direction.Right; - } else { - return Direction.Left; } + return Direction.Left; } /** @@ -191,9 +189,8 @@ export class AltClickHandler { private _verticalDirection(): Direction { if (this._startRow > this._endRow) { return Direction.Up; - } else { - return Direction.Down; } + return Direction.Down; } /** diff --git a/tslint.json b/tslint.json index d42fda71..5cd44ecf 100644 --- a/tslint.json +++ b/tslint.json @@ -1,4 +1,7 @@ { + "rulesDirectory": [ + "tslint-consistent-codestyle" + ], "rules": { "array-type": [ true, @@ -86,6 +89,10 @@ "check-type", "check-type-operator", "check-preblock" - ] + ], + + "no-else-after-return": { + "options": "allow-else-if" + } } } From 9942dc384dd0435a36a66d52076788d2fe88fee0 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 23 Apr 2018 17:17:21 -0700 Subject: [PATCH 02/28] Enforce upper case for public const/enum members Fixes #1406 --- package.json | 1 + src/AccessibilityManager.ts | 20 ++++++++++---------- src/handlers/AltClickHandler.ts | 22 +++++++++++----------- tslint.json | 6 ++++++ 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 49ccc387..d4a06f82 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "npm-run-all": "^4.1.2", "sorcery": "^0.10.0", "tslint": "^5.9.1", + "tslint-consistent-codestyle": "^1.13.0", "typescript": "~2.7.1", "vinyl-buffer": "^1.0.0", "vinyl-source-stream": "^1.1.0", diff --git a/src/AccessibilityManager.ts b/src/AccessibilityManager.ts index 5a1f4770..4d1c689e 100644 --- a/src/AccessibilityManager.ts +++ b/src/AccessibilityManager.ts @@ -13,8 +13,8 @@ import { IDisposable } from 'xterm'; const MAX_ROWS_TO_READ = 20; enum BoundaryPosition { - Top, - Bottom + TOP, + BOTTOM } export class AccessibilityManager implements IDisposable { @@ -54,8 +54,8 @@ export class AccessibilityManager implements IDisposable { this._rowContainer.appendChild(this._rowElements[i]); } - this._topBoundaryFocusListener = e => this._onBoundaryFocus(e, BoundaryPosition.Top); - this._bottomBoundaryFocusListener = e => this._onBoundaryFocus(e, BoundaryPosition.Bottom); + this._topBoundaryFocusListener = e => this._onBoundaryFocus(e, BoundaryPosition.TOP); + this._bottomBoundaryFocusListener = e => this._onBoundaryFocus(e, BoundaryPosition.BOTTOM); this._rowElements[0].addEventListener('focus', this._topBoundaryFocusListener); this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener); @@ -101,11 +101,11 @@ export class AccessibilityManager implements IDisposable { private _onBoundaryFocus(e: FocusEvent, position: BoundaryPosition): void { const boundaryElement = e.target; - const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.Top ? 1 : this._rowElements.length - 2]; + const beforeBoundaryElement = this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2]; // Don't scroll if the buffer top has reached the end in that direction const posInSet = boundaryElement.getAttribute('aria-posinset'); - const lastRowPos = position === BoundaryPosition.Top ? '1' : `${this._terminal.buffer.lines.length}`; + const lastRowPos = position === BoundaryPosition.TOP ? '1' : `${this._terminal.buffer.lines.length}`; if (posInSet === lastRowPos) { return; } @@ -119,7 +119,7 @@ export class AccessibilityManager implements IDisposable { // Remove old boundary element from array let topBoundaryElement: HTMLElement; let bottomBoundaryElement: HTMLElement; - if (position === BoundaryPosition.Top) { + if (position === BoundaryPosition.TOP) { topBoundaryElement = boundaryElement; bottomBoundaryElement = this._rowElements.pop()!; this._rowContainer.removeChild(bottomBoundaryElement); @@ -134,7 +134,7 @@ export class AccessibilityManager implements IDisposable { bottomBoundaryElement.removeEventListener('focus', this._bottomBoundaryFocusListener); // Add new element to array/DOM - if (position === BoundaryPosition.Top) { + if (position === BoundaryPosition.TOP) { const newElement = this._createAccessibilityTreeNode(); this._rowElements.unshift(newElement); this._rowContainer.insertAdjacentElement('afterbegin', newElement); @@ -149,10 +149,10 @@ export class AccessibilityManager implements IDisposable { this._rowElements[this._rowElements.length - 1].addEventListener('focus', this._bottomBoundaryFocusListener); // Scroll up - this._terminal.scrollLines(position === BoundaryPosition.Top ? -1 : 1); + this._terminal.scrollLines(position === BoundaryPosition.TOP ? -1 : 1); // Focus new boundary before element - this._rowElements[position === BoundaryPosition.Top ? 1 : this._rowElements.length - 2].focus(); + this._rowElements[position === BoundaryPosition.TOP ? 1 : this._rowElements.length - 2].focus(); // Prevent the standard behavior e.preventDefault(); diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index f77637ea..33808973 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -7,10 +7,10 @@ import { ITerminal, ICircularList, LineData } from '../Types'; import { C0 } from '../EscapeSequences'; enum Direction { - Up = 'A', - Down = 'B', - Right = 'C', - Left = 'D' + UP = 'A', + DOWN = 'B', + RIGHT = 'C', + LEFT = 'D' } export class AltClickHandler { @@ -77,7 +77,7 @@ export class AltClickHandler { return repeat(this._bufferLine( this._startCol, this._startRow, this._startCol, this._startRow - this._wrappedRowsForRow(this._startRow), false - ).length, this._sequence(Direction.Left)); + ).length, this._sequence(Direction.LEFT)); } } @@ -110,7 +110,7 @@ export class AltClickHandler { return repeat(this._bufferLine( this._startCol, startRow, this._endCol, endRow, - direction === Direction.Right + direction === Direction.RIGHT ).length, this._sequence(direction)); } @@ -133,7 +133,7 @@ export class AltClickHandler { let endRow = this._endRow - this._wrappedRowsForRow(this._endRow); for (let i = 0; i < Math.abs(startRow - endRow); i++) { - let direction = this._verticalDirection() === Direction.Up ? -1 : 1; + let direction = this._verticalDirection() === Direction.UP ? -1 : 1; if ((this._lines.get(startRow + (direction * i))).isWrapped) { wrappedRows++; @@ -179,9 +179,9 @@ export class AltClickHandler { startRow <= this._endRow) || // down/right or same y/right (this._startCol >= this._endCol && startRow < this._endRow)) { // down/left or same y/left - return Direction.Right; + return Direction.RIGHT; } else { - return Direction.Left; + return Direction.LEFT; } } @@ -190,9 +190,9 @@ export class AltClickHandler { */ private _verticalDirection(): Direction { if (this._startRow > this._endRow) { - return Direction.Up; + return Direction.UP; } else { - return Direction.Down; + return Direction.DOWN; } } diff --git a/tslint.json b/tslint.json index d42fda71..2ead68ed 100644 --- a/tslint.json +++ b/tslint.json @@ -1,4 +1,5 @@ { + "rulesDirectory": ["tslint-consistent-codestyle"], "rules": { "array-type": [ true, @@ -86,6 +87,11 @@ "check-type", "check-type-operator", "check-preblock" + ], + + "naming-convention": [ + true, + {"type": "property", "modifiers": ["public", "static", "const"], "format": "UPPER_CASE"} ] } } From fcde7be62ae6beae4f56eaa6fc7248484085bc0c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 23 Apr 2018 17:35:36 -0700 Subject: [PATCH 03/28] Enforce const enums Fixes #1408 --- src/AccessibilityManager.ts | 2 +- src/Parser.ts | 2 +- src/SelectionManager.ts | 2 +- src/Types.ts | 2 +- src/handlers/AltClickHandler.ts | 2 +- src/renderer/Types.ts | 2 +- tslint.json | 3 +++ 7 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/AccessibilityManager.ts b/src/AccessibilityManager.ts index 4d1c689e..a7e205e3 100644 --- a/src/AccessibilityManager.ts +++ b/src/AccessibilityManager.ts @@ -12,7 +12,7 @@ import { IDisposable } from 'xterm'; const MAX_ROWS_TO_READ = 20; -enum BoundaryPosition { +const enum BoundaryPosition { TOP, BOTTOM } diff --git a/src/Parser.ts b/src/Parser.ts index 21e5a612..372d8443 100644 --- a/src/Parser.ts +++ b/src/Parser.ts @@ -150,7 +150,7 @@ csiStateHandler['s'] = (handler, params) => handler.saveCursor(params); csiStateHandler['u'] = (handler, params) => handler.restoreCursor(params); csiStateHandler[C0.CAN] = (handler, params, prefix, postfix, parser) => parser.setState(ParserState.NORMAL); -export enum ParserState { +export const enum ParserState { NORMAL = 0, ESCAPED = 1, CSI_PARAM = 2, diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index a50203bd..93da887a 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -54,7 +54,7 @@ interface IWordPosition { /** * A selection mode, this drives how the selection behaves on mouse move. */ -enum SelectionMode { +const enum SelectionMode { NORMAL, WORD, LINE diff --git a/src/Types.ts b/src/Types.ts index 2442b027..15498ce1 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -17,7 +17,7 @@ export type LineData = CharData[]; export type LinkMatcherHandler = (event: MouseEvent, uri: string) => void; export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void; -export enum LinkHoverEventTypes { +export const enum LinkHoverEventTypes { HOVER = 'linkhover', TOOLTIP = 'linktooltip', LEAVE = 'linkleave' diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 33808973..ca31f02c 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -6,7 +6,7 @@ import { ITerminal, ICircularList, LineData } from '../Types'; import { C0 } from '../EscapeSequences'; -enum Direction { +const enum Direction { UP = 'A', DOWN = 'B', RIGHT = 'C', diff --git a/src/renderer/Types.ts b/src/renderer/Types.ts index 8c464bec..bd5b13eb 100644 --- a/src/renderer/Types.ts +++ b/src/renderer/Types.ts @@ -10,7 +10,7 @@ import { IColorSet } from '../shared/Types'; /** * Flags used to render terminal text properly. */ -export enum FLAGS { +export const enum FLAGS { BOLD = 1, UNDERLINE = 2, BLINK = 4, diff --git a/tslint.json b/tslint.json index 2ead68ed..dd259d63 100644 --- a/tslint.json +++ b/tslint.json @@ -92,6 +92,9 @@ "naming-convention": [ true, {"type": "property", "modifiers": ["public", "static", "const"], "format": "UPPER_CASE"} + ], + "prefer-const-enum": [ + true ] } } From a5a03c40f21ab4c473313453e09f9c353ff184c5 Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Tue, 24 Apr 2018 23:15:22 -0700 Subject: [PATCH 04/28] Batch background draws together to reduce draws Adjacent cells on the same row sharing the same background color will be drawn using the same `fillCells` call. This should make drawing an application with a solid or mostly solid background color (e.g. vim) faster. I set vim to draw the background color for a file, and started scrolling through it. Before, _drawBackground was taking around 6ms per frame. After this commit, it was taking around 0.5ms per frame. Based on prior experience, I'd expect these results to be more drastic for larger terminal windows. The demo's window is pretty small. --- src/renderer/BaseRenderLayer.ts | 2 +- src/renderer/TextRenderLayer.ts | 52 +++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index fbffd547..4200e112 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -26,7 +26,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { private _container: HTMLElement, id: string, zIndex: number, - private _alpha: boolean, + protected _alpha: boolean, protected _colors: IColorSet ) { this._canvas = document.createElement('canvas'); diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 58d0d790..6c9a72c5 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -128,18 +128,58 @@ export class TextRenderLayer extends BaseRenderLayer { } } + /** + * Draws the background for a specified range of columns. Tries to batch adjacent cells of the + * same color together to reduce draw calls. + */ private _drawBackground(terminal: ITerminal, firstRow: number, lastRow: number): void { + const ctx = this._ctx; + const cols = terminal.cols; + let startX: number = 0; + let startY: number = 0; + let prevFillStyle: string | null = null; + + ctx.save(); + this._forEachCell(terminal, firstRow, lastRow, (code, char, width, x, y, fg, bg, flags) => { // libvte and xterm both draw the background (but not foreground) of invisible characters, // so we should too. - const isDefaultBackground = bg >= 256; - if (!isDefaultBackground) { - this._ctx.save(); - this._ctx.fillStyle = (bg === INVERTED_DEFAULT_COLOR ? this._colors.foreground.css : this._colors.ansi[bg].css); - this.fillCells(x, y, width, 1); - this._ctx.restore(); + let nextFillStyle = null; // null represents default background color + if (bg === INVERTED_DEFAULT_COLOR) { + nextFillStyle = this._colors.foreground.css; + } else if (bg < 256) { + nextFillStyle = this._colors.ansi[bg].css; } + + if (prevFillStyle === null) { + // This is either the first iteration, or the default background was set. Either way, we + // don't need to draw anything. + startX = x; + startY = y; + } if (y !== startY) { + // our row changed, draw the previous row + ctx.fillStyle = prevFillStyle; + this.fillCells(startX, startY, cols - startX, 1); + startX = x; + startY = y; + } else if (prevFillStyle !== nextFillStyle) { + // our color changed, draw the previous characters in this row + ctx.fillStyle = prevFillStyle; + this.fillCells(startX, startY, x - startX, 1); + startX = x; + startY = y; + } + + prevFillStyle = nextFillStyle; }); + + // flush the last color we encountered + if (prevFillStyle !== null) { + ctx.fillStyle = prevFillStyle; + this.fillCells(startX, startY, cols - startX, 1); + } + + ctx.restore(); } private _drawForeground(terminal: ITerminal, firstRow: number, lastRow: number): void { From a61ba2e140affbc1a247a93204bdc2ed6bafe71f Mon Sep 17 00:00:00 2001 From: pro-src Date: Thu, 26 Apr 2018 09:18:18 -0500 Subject: [PATCH 05/28] closes #1361 --- .npmignore | 55 ++++++++++++++++++++++++++++++++++++++++------------ package.json | 27 -------------------------- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/.npmignore b/.npmignore index 63069bda..eeb46409 100644 --- a/.npmignore +++ b/.npmignore @@ -1,16 +1,47 @@ -node_modules/ -*.swp -.lock-wscript -lib/*.test.js -lib/*.test.js.map +# Blacklist - exclude everything except npm defaults such as LICENSE, etc +* +!*/ + +# Whitelist - entries to be included must be negated with "!" +!*.js +!*.json + +# Whitelist - dist/ +!dist/**/*.js +!dist/**/*.js.map + +!dist/**/*.css + +# Whitelist - lib/ +!lib/**/*.d.ts + +!lib/**/*.js +!lib/**/*.js.map + +!lib/**/*.css + +# Whitelist - src/ +!src/**/*.ts +!src/**/*.d.ts + +!src/**/*.js +!src/**/*.js.map + +!src/**/*.css + +# Whitelist - typings/ +!typings/*.d.ts + +# Blacklist - (normal behavior) these will override any whitelist +*.test.ts +*.test.d.ts +*.test.js +*.test.js.map lib/test/ -Makefile.gyp -*.Makefile -*.target.gyp.mk -*.node -example/*.log + docs/ -npm-debug.log /.idea/ -.env +.vscode/ build/ +fixtures/ +coverage/ diff --git a/package.json b/package.json index d4a06f82..4db430bc 100644 --- a/package.json +++ b/package.json @@ -11,33 +11,6 @@ "types": "typings/xterm.d.ts", "repository": "https://github.com/xtermjs/xterm.js", "license": "MIT", - "files": [ - "*.js", - "*.json", - "dist/*.css", - "dist/**/*.css", - "dist/*.js", - "dist/*.js.map", - "dist/**/*.js", - "dist/**/*.js.map", - "lib/*.css", - "lib/**/*.css", - "lib/*.d.ts", - "lib/*.js", - "lib/*.js.map", - "lib/**/*.d.ts", - "lib/**/*.js", - "lib/**/*.js.map", - "src/*.css", - "src/**/*.css", - "src/*.js", - "src/*.js.map", - "src/*.ts", - "src/**/*.js", - "src/**/*.js.map", - "src/**/*.ts", - "typings/*.d.ts" - ], "devDependencies": { "@types/chai": "^3.4.34", "@types/jsdom": "^11.0.1", From 994895af6de250d89d05365d7ef7213269c6f7c1 Mon Sep 17 00:00:00 2001 From: pro-src <34285059+pro-src@users.noreply.github.com> Date: Thu, 26 Apr 2018 11:53:20 -0500 Subject: [PATCH 06/28] Update README.md Replace the deprecated octal escapes with Unicode escapes. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Deprecated_octal --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 48a46fd9..50e954da 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t From 30b88113a879d05a79a9c52b60408f580ca62f30 Mon Sep 17 00:00:00 2001 From: pro-src Date: Thu, 26 Apr 2018 12:09:21 -0500 Subject: [PATCH 07/28] explicitly exclude demo --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index eeb46409..517ba0bd 100644 --- a/.npmignore +++ b/.npmignore @@ -45,3 +45,4 @@ docs/ build/ fixtures/ coverage/ +demo/ From 235982362c5f198c4cadc5ac846086189a1daf52 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 26 Apr 2018 17:28:07 -0400 Subject: [PATCH 08/28] Add support for italic rendering --- src/InputHandler.ts | 3 +++ src/renderer/BaseRenderLayer.ts | 17 +++++++++-------- src/renderer/TextRenderLayer.ts | 4 ++-- src/renderer/Types.ts | 3 ++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 4df3e695..7696324e 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -1263,6 +1263,9 @@ export class InputHandler implements IInputHandler { } else if (p === 1) { // bold text flags |= FLAGS.BOLD; + } else if (p === 3) { + // italic text + flags |= FLAGS.ITALIC; } else if (p === 4) { // underlined text flags |= FLAGS.UNDERLINE; diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index fbffd547..0fe3bfea 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -219,7 +219,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param color The color of the character. */ protected fillCharTrueColor(terminal: ITerminal, charData: CharData, x: number, y: number): void { - this._ctx.font = this._getFont(terminal, false); + this._ctx.font = this._getFont(terminal, false, false); this._ctx.textBaseline = 'top'; this._clipRow(terminal, y); this._ctx.fillText( @@ -242,7 +242,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { * This is used to validate whether a cached image can be used. * @param bold Whether the text is bold. */ - protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bg: number, bold: boolean, dim: boolean): void { + protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bg: number, bold: boolean, dim: boolean, italic: boolean): void { let colorIndex = 0; if (fg < 256) { colorIndex = fg + 2; @@ -259,7 +259,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { const isBasicColor = (colorIndex > 1 && fg < 16) && (fg < 8 || bold); const isDefaultColor = fg >= 256; const isDefaultBackground = bg >= 256; - if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground) { + if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !italic) { // ImageBitmap's draw about twice as fast as from a canvas const charAtlasCellWidth = this._scaledCharWidth + CHAR_ATLAS_CELL_SPACING; const charAtlasCellHeight = this._scaledCharHeight + CHAR_ATLAS_CELL_SPACING; @@ -287,7 +287,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { charAtlasCellWidth, this._scaledCharHeight); } else { - this._drawUncachedChar(terminal, char, width, fg, x, y, bold && terminal.options.enableBold, dim); + this._drawUncachedChar(terminal, char, width, fg, x, y, bold && terminal.options.enableBold, dim, italic); } // This draws the atlas (for debugging purposes) // this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); @@ -305,9 +305,9 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param x The column to draw at. * @param y The row to draw at. */ - private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number, bold: boolean, dim: boolean): void { + private _drawUncachedChar(terminal: ITerminal, char: string, width: number, fg: number, x: number, y: number, bold: boolean, dim: boolean, italic: boolean): void { this._ctx.save(); - this._ctx.font = this._getFont(terminal, bold); + this._ctx.font = this._getFont(terminal, bold, italic); this._ctx.textBaseline = 'top'; if (fg === INVERTED_DEFAULT_COLOR) { @@ -353,10 +353,11 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param terminal The terminal. * @param isBold If we should use the bold fontWeight. */ - protected _getFont(terminal: ITerminal, isBold: boolean): string { + protected _getFont(terminal: ITerminal, isBold: boolean, isItalic: boolean): string { const fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight; + const fontStyle = isItalic ? 'italic' : ''; - return `${fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + return `${fontWeight} ${fontStyle} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; } } diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 58d0d790..21e7e315 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -32,7 +32,7 @@ export class TextRenderLayer extends BaseRenderLayer { super.resize(terminal, dim); // Clear the character width cache if the font or width has changed - const terminalFont = this._getFont(terminal, false); + const terminalFont = this._getFont(terminal, false, false); if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) { this._characterWidth = dim.scaledCharWidth; this._characterFont = terminalFont; @@ -164,7 +164,7 @@ export class TextRenderLayer extends BaseRenderLayer { terminal, char, code, width, x, y, fg, bg, - !!(flags & FLAGS.BOLD), !!(flags & FLAGS.DIM) + !!(flags & FLAGS.BOLD), !!(flags & FLAGS.DIM), !!(flags & FLAGS.ITALIC) ); }); } diff --git a/src/renderer/Types.ts b/src/renderer/Types.ts index bd5b13eb..edecf8b0 100644 --- a/src/renderer/Types.ts +++ b/src/renderer/Types.ts @@ -16,7 +16,8 @@ export const enum FLAGS { BLINK = 4, INVERSE = 8, INVISIBLE = 16, - DIM = 32 + DIM = 32, + ITALIC = 64 } export interface IRenderer extends IEventEmitter { From 882d5a86d390f220545c42b302a2a2bb8318da2c Mon Sep 17 00:00:00 2001 From: pro-src <34285059+pro-src@users.noreply.github.com> Date: Fri, 27 Apr 2018 02:19:48 -0500 Subject: [PATCH 09/28] Update README.md - prefer hex escapes over octal --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50e954da..07baec5a 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ To start using xterm.js on your browser, add the `xterm.js` and `xterm.css` to t From 513847fd806b55719fb08a522d11f2ff5aab2216 Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Fri, 27 Apr 2018 20:47:55 -0700 Subject: [PATCH 10/28] Make BaseRenderLayer's _alpha private again This was accidentally left over from some earlier changes I was playing with. --- src/renderer/BaseRenderLayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 4200e112..fbffd547 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -26,7 +26,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { private _container: HTMLElement, id: string, zIndex: number, - protected _alpha: boolean, + private _alpha: boolean, protected _colors: IColorSet ) { this._canvas = document.createElement('canvas'); From a732952677bcb7fde78db7ee176d69e32b51e2ec Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 1 May 2018 11:50:06 -0700 Subject: [PATCH 11/28] Rearrange italic/bold to get _ctx.font validating --- src/renderer/BaseRenderLayer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 0fe3bfea..7a655163 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -357,7 +357,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { const fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight; const fontStyle = isItalic ? 'italic' : ''; - return `${fontWeight} ${fontStyle} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + return `${fontStyle} ${fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; } } From 9bcecd4e2e3dfb56e17133121174a968789aab64 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 4 May 2018 10:20:09 -0700 Subject: [PATCH 12/28] Run tslint on all of source (for good this time) --- package.json | 2 +- src/renderer/atlas/CharAtlas.ts | 15 +++++++-------- src/shared/atlas/CharAtlasGenerator.ts | 5 ++--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index d4a06f82..b0c36c54 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "scripts": { "start": "node demo/app", "start-zmodem": "node demo/zmodem/app", - "lint": "tslint src/*.ts src/**/*.ts src/addons/**/*.ts", + "lint": "tslint 'src/**/*.ts'", "test": "npm-run-all mocha lint", "mocha": "gulp test", "build:docs": "jsdoc -c jsdoc.json", diff --git a/src/renderer/atlas/CharAtlas.ts b/src/renderer/atlas/CharAtlas.ts index f516919f..db5c92f6 100644 --- a/src/renderer/atlas/CharAtlas.ts +++ b/src/renderer/atlas/CharAtlas.ts @@ -35,15 +35,14 @@ export function acquireCharAtlas(terminal: ITerminal, colors: IColorSet, scaledC if (ownedByIndex >= 0) { if (configEquals(entry.config, newConfig)) { return entry.bitmap; - } else { - // The configs differ, release the terminal from the entry - if (entry.ownedBy.length === 1) { - charAtlasCache.splice(i, 1); - } else { - entry.ownedBy.splice(ownedByIndex, 1); - } - break; } + // The configs differ, release the terminal from the entry + if (entry.ownedBy.length === 1) { + charAtlasCache.splice(i, 1); + } else { + entry.ownedBy.splice(ownedByIndex, 1); + } + break; } } diff --git a/src/shared/atlas/CharAtlasGenerator.ts b/src/shared/atlas/CharAtlasGenerator.ts index fc83c7ce..ee8bfcfa 100644 --- a/src/shared/atlas/CharAtlasGenerator.ts +++ b/src/shared/atlas/CharAtlasGenerator.ts @@ -91,10 +91,9 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number if (canvas instanceof HTMLCanvasElement) { // Just return the HTMLCanvas if it's a HTMLCanvasElement return canvas; - } else { - // Transfer to an ImageBitmap is this is an OffscreenCanvas - return new Promise(r => r(canvas.transferToImageBitmap())); } + // Transfer to an ImageBitmap is this is an OffscreenCanvas + return new Promise(r => r(canvas.transferToImageBitmap())); } const charAtlasImageData = ctx.getImageData(0, 0, canvas.width, canvas.height); From 41fd563144e58be506a1f9c069e8340ea8d72e1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Tue, 17 Apr 2018 11:24:21 +0100 Subject: [PATCH 13/28] Separate bright and bold --- src/renderer/BaseRenderLayer.ts | 4 ++-- src/renderer/TextRenderLayer.ts | 7 ------- src/shared/atlas/CharAtlasGenerator.ts | 22 +++++++++++++++++----- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 7a655163..a46bc391 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -245,7 +245,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bg: number, bold: boolean, dim: boolean, italic: boolean): void { let colorIndex = 0; if (fg < 256) { - colorIndex = fg + 2; + colorIndex = fg + 2 + (bold && terminal.options.enableBold ? 16 : 0); } else { // If default color and bold if (bold && terminal.options.enableBold) { @@ -273,7 +273,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { if (bold && !terminal.options.enableBold) { // Ignore default color as it's not touched above if (colorIndex > 1) { - colorIndex -= 8; + colorIndex -= 16; } } diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 8d8d6d4d..0dca11b2 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -116,13 +116,6 @@ export class TextRenderLayer extends BaseRenderLayer { } } - if (flags & FLAGS.BOLD) { - // Convert the FG color to the bold variant - if (fg < 8) { - fg += 8; - } - } - callback(code, char, width, x, y, fg, bg, flags); } } diff --git a/src/shared/atlas/CharAtlasGenerator.ts b/src/shared/atlas/CharAtlasGenerator.ts index fc83c7ce..ba9b0d27 100644 --- a/src/shared/atlas/CharAtlasGenerator.ts +++ b/src/shared/atlas/CharAtlasGenerator.ts @@ -27,7 +27,7 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number const cellHeight = config.scaledCharHeight + CHAR_ATLAS_CELL_SPACING; const canvas = canvasFactory( /*255 ascii chars*/255 * cellWidth, - (/*default+default bold*/2 + /*0-15*/16) * cellHeight + (/*default+default bold*/2 + /*0-15*/16 + /*0-15 bold*/16) * cellHeight ); const ctx = canvas.getContext('2d', {alpha: config.allowTransparency}); @@ -64,10 +64,6 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number // Colors 0-15 ctx.font = getFont(config.fontWeight, config); for (let colorIndex = 0; colorIndex < 16; colorIndex++) { - // colors 8-15 are bold - if (colorIndex === 8) { - ctx.font = getFont(config.fontWeightBold, config); - } const y = (colorIndex + 2) * cellHeight; // Draw ascii characters for (let i = 0; i < 256; i++) { @@ -80,6 +76,22 @@ export function generateCharAtlas(context: Window, canvasFactory: (width: number ctx.restore(); } } + + // Colors 0-15 bold + ctx.font = getFont(config.fontWeightBold, config); + for (let colorIndex = 0; colorIndex < 16; colorIndex++) { + const y = (colorIndex + 2 + 16) * cellHeight; + // Draw ascii characters + for (let i = 0; i < 256; i++) { + ctx.save(); + ctx.beginPath(); + ctx.rect(i * cellWidth, y, cellWidth, cellHeight); + ctx.clip(); + ctx.fillStyle = config.colors.ansi[colorIndex].css; + ctx.fillText(String.fromCharCode(i), i * cellWidth, y); + ctx.restore(); + } + } ctx.restore(); // Support is patchy for createImageBitmap at the moment, pass a canvas back From a23354f0181f357c002d2ffebd85390920cc775b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Fri, 20 Apr 2018 10:20:10 +0100 Subject: [PATCH 14/28] Fully use char atlas for bright & bold colors --- src/renderer/BaseRenderLayer.ts | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index a46bc391..5bc4f33b 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -243,23 +243,19 @@ export abstract class BaseRenderLayer implements IRenderLayer { * @param bold Whether the text is bold. */ protected drawChar(terminal: ITerminal, char: string, code: number, width: number, x: number, y: number, fg: number, bg: number, bold: boolean, dim: boolean, italic: boolean): void { - let colorIndex = 0; - if (fg < 256) { - colorIndex = fg + 2 + (bold && terminal.options.enableBold ? 16 : 0); - } else { - // If default color and bold - if (bold && terminal.options.enableBold) { - colorIndex = 1; - } - } const isAscii = code < 256; - // A color is basic if it is one of the standard normal or bold weight - // colors of the characters held in the char atlas. Note that this excludes - // the normal weight _light_ color characters. - const isBasicColor = (colorIndex > 1 && fg < 16) && (fg < 8 || bold); + // A color is basic if it is one of the 4 bit ANSI colors. + const isBasicColor = fg < 16; const isDefaultColor = fg >= 256; const isDefaultBackground = bg >= 256; if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !italic) { + let colorIndex: number; + if (isDefaultColor) { + colorIndex = (bold && terminal.options.enableBold ? 1 : 0); + } else { + colorIndex = 2 + fg + (bold && terminal.options.enableBold ? 16 : 0); + } + // ImageBitmap's draw about twice as fast as from a canvas const charAtlasCellWidth = this._scaledCharWidth + CHAR_ATLAS_CELL_SPACING; const charAtlasCellHeight = this._scaledCharHeight + CHAR_ATLAS_CELL_SPACING; @@ -269,14 +265,6 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._ctx.globalAlpha = DIM_OPACITY; } - // Draw the non-bold version of the same color if bold is not enabled - if (bold && !terminal.options.enableBold) { - // Ignore default color as it's not touched above - if (colorIndex > 1) { - colorIndex -= 16; - } - } - this._ctx.drawImage(this._charAtlas, code * charAtlasCellWidth, colorIndex * charAtlasCellHeight, From ce6139e604c8d23dd6e3be957f5bed6d7e30bc5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Fri, 20 Apr 2018 10:35:07 +0100 Subject: [PATCH 15/28] Add drawBoldTextInBrightColors option --- src/renderer/BaseRenderLayer.ts | 5 +++-- typings/xterm.d.ts | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 5bc4f33b..f80c6df0 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -248,12 +248,13 @@ export abstract class BaseRenderLayer implements IRenderLayer { const isBasicColor = fg < 16; const isDefaultColor = fg >= 256; const isDefaultBackground = bg >= 256; + const drawInBrightColor = (terminal.options.drawBoldTextInBrightColors !== false && bold && fg < 8); if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !italic) { let colorIndex: number; if (isDefaultColor) { colorIndex = (bold && terminal.options.enableBold ? 1 : 0); } else { - colorIndex = 2 + fg + (bold && terminal.options.enableBold ? 16 : 0); + colorIndex = 2 + fg + (bold && terminal.options.enableBold ? 16 : 0) + (drawInBrightColor ? 8 : 0); } // ImageBitmap's draw about twice as fast as from a canvas @@ -275,7 +276,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { charAtlasCellWidth, this._scaledCharHeight); } else { - this._drawUncachedChar(terminal, char, width, fg, x, y, bold && terminal.options.enableBold, dim, italic); + this._drawUncachedChar(terminal, char, width, fg + (drawInBrightColor ? 8 : 0), x, y, bold && terminal.options.enableBold, dim, italic); } // This draws the atlas (for debugging purposes) // this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 65d533de..3107589e 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -54,6 +54,11 @@ declare module 'xterm' { */ disableStdin?: boolean; + /** + * Whether to draw bold text in bright colors. The default is true. + */ + drawBoldTextInBrightColors?: boolean; + /** * Whether to enable the rendering of bold text. * From cfdec9ff904ad412fc30f7695e878a94f938fddd Mon Sep 17 00:00:00 2001 From: Ledion Bitincka Date: Tue, 8 May 2018 16:27:54 -0700 Subject: [PATCH 16/28] add diag.ai --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 07baec5a..2b0944e6 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,7 @@ computational environment for Jupyter, supporting interactive data science and s - [**FreeMAN**](https://github.com/matthew-matvei/freeman): A free, cross-platform file manager for power users - [**Fluent Terminal**](https://github.com/felixse/FluentTerminal): A terminal emulator based on UWP and web technologies. - [**Hyper**](https://hyper.is): A terminal built on web technologies +- [**Diag**](https://diag.ai): A better way to troubleshoot problems faster. Capture, share and reapply troubleshooting knowledge so you can focus on solving problems that matter. 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. From 9893338020cc66efb8180f8f4df6852a0880bfae Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Tue, 8 May 2018 18:34:23 -0700 Subject: [PATCH 17/28] Add drawBoldTextInBrightColors to DEFAULT_OPTIONS This lets term.setOption() work for drawBoldTextInBrightColors. --- src/Terminal.ts | 1 + src/renderer/BaseRenderLayer.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index ba1fff3d..05781b96 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -103,6 +103,7 @@ const DEFAULT_OPTIONS: ITerminalOptions = { cursorStyle: 'block', bellSound: DEFAULT_BELL_SOUND, bellStyle: 'none', + drawBoldTextInBrightColors: true, enableBold: true, fontFamily: 'courier-new, courier, monospace', fontSize: 15, diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index f80c6df0..ca848b73 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -248,7 +248,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { const isBasicColor = fg < 16; const isDefaultColor = fg >= 256; const isDefaultBackground = bg >= 256; - const drawInBrightColor = (terminal.options.drawBoldTextInBrightColors !== false && bold && fg < 8); + const drawInBrightColor = (terminal.options.drawBoldTextInBrightColors && bold && fg < 8); if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !italic) { let colorIndex: number; if (isDefaultColor) { From b162582e668398179d440aca8629a0f2b6cbfc6d Mon Sep 17 00:00:00 2001 From: npezza93 Date: Sat, 21 Apr 2018 08:52:12 -0400 Subject: [PATCH 18/28] Handle if getCoords returns null in the AltClickHandler Fixes #1397 --- src/handlers/AltClickHandler.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 85465272..6b980fe6 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -28,7 +28,7 @@ export class AltClickHandler { this._startCol = this._terminal.buffer.x; this._startRow = this._terminal.buffer.y; - [this._endCol, this._endRow] = this._terminal.mouseHelper.getCoords( + let coordinates = this._terminal.mouseHelper.getCoords( this._mouseEvent, this._terminal.element, this._terminal.charMeasure, @@ -36,7 +36,13 @@ export class AltClickHandler { this._terminal.cols, this._terminal.rows, false - ).map((coordinate: number) => { + ); + + if (!coordinates) { + return null; + } + + [this._endCol, this._endRow] = coordinates.map((coordinate: number) => { return coordinate - 1; }); } From 4edbd507e5717669ebe57c20657053fa9bae06c9 Mon Sep 17 00:00:00 2001 From: npezza93 Date: Wed, 9 May 2018 19:35:02 -0400 Subject: [PATCH 19/28] Check if endCol and endRow are present before handling an alt click --- src/handlers/AltClickHandler.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/handlers/AltClickHandler.ts b/src/handlers/AltClickHandler.ts index 6b980fe6..7f2e4f05 100644 --- a/src/handlers/AltClickHandler.ts +++ b/src/handlers/AltClickHandler.ts @@ -38,20 +38,18 @@ export class AltClickHandler { false ); - if (!coordinates) { - return null; + if (coordinates) { + [this._endCol, this._endRow] = coordinates.map((coordinate: number) => { + return coordinate - 1; + }); } - - [this._endCol, this._endRow] = coordinates.map((coordinate: number) => { - return coordinate - 1; - }); } /** * Writes the escape sequences of arrows to the terminal */ public move(): void { - if (this._mouseEvent.altKey) { + if (this._mouseEvent.altKey && this._endCol !== undefined && this._endRow !== undefined) { this._terminal.send(this._arrowSequences()); } } From 3971fc9b4e21c1030908da172886dc2f8253edfd Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Wed, 9 May 2018 20:34:55 -0700 Subject: [PATCH 20/28] Save and restore the ctx for cached characters Drawing dim colors sets the globalAlpha to 0.5, so we need to save/restore the ctx state. Otherwise, every time we draw some dim content, our display will get progressively dimmer. I tested this by running `echo '\u001b[2mfoo'` a few times in zsh. Fixes #1424 --- src/renderer/BaseRenderLayer.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index ca848b73..c2b65e16 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -250,6 +250,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { const isDefaultBackground = bg >= 256; const drawInBrightColor = (terminal.options.drawBoldTextInBrightColors && bold && fg < 8); if (this._charAtlas && isAscii && (isBasicColor || isDefaultColor) && isDefaultBackground && !italic) { + this._ctx.save(); // we may set globalAlpha, so we need to be able to restore let colorIndex: number; if (isDefaultColor) { colorIndex = (bold && terminal.options.enableBold ? 1 : 0); @@ -275,6 +276,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { y * this._scaledCellHeight + this._scaledCharTop, charAtlasCellWidth, this._scaledCharHeight); + this._ctx.restore(); } else { this._drawUncachedChar(terminal, char, width, fg + (drawInBrightColor ? 8 : 0), x, y, bold && terminal.options.enableBold, dim, italic); } From bce81f304ef284f42a2f9596d13adf3a1169955e Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Thu, 10 May 2018 16:11:25 +0800 Subject: [PATCH 21/28] Update how to use addons with Typescript --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 07baec5a..65f016c4 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,18 @@ The proposed way to load xterm.js is via the ES6 module syntax. import { Terminal } from 'xterm'; ``` -*Note: There are currently no typings for addons so you will need to upcast if using TypeScript, eg. `(xterm).fit()`.* +*Note: There are currently no typings for addons if they are accessed via extending Terminal prototype, so you will need to upcast if using TypeScript, eg. `(xterm).fit()`.* + +It is recommended to import addon function and enhance the terminal on demand. This would have better typing support and is friendly to treeshaking. E.g.: + +```typescript +import { Terminal } from 'xterm'; +import { fit } from 'xterm/lib/addons/fit/fit'; +const xterm = new Terminal(); + +// Fit the terminal when necessary: +fit(xterm); +``` ### Addons From ef4cda2cc635597f838078057b766225108c39cf Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Fri, 11 May 2018 11:20:02 +0800 Subject: [PATCH 22/28] revise importing addons in ts --- README.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 65f016c4..dc14f853 100644 --- a/README.md +++ b/README.md @@ -57,19 +57,6 @@ The proposed way to load xterm.js is via the ES6 module syntax. import { Terminal } from 'xterm'; ``` -*Note: There are currently no typings for addons if they are accessed via extending Terminal prototype, so you will need to upcast if using TypeScript, eg. `(xterm).fit()`.* - -It is recommended to import addon function and enhance the terminal on demand. This would have better typing support and is friendly to treeshaking. E.g.: - -```typescript -import { Terminal } from 'xterm'; -import { fit } from 'xterm/lib/addons/fit/fit'; -const xterm = new Terminal(); - -// Fit the terminal when necessary: -fit(xterm); -``` - ### Addons Addons are JavaScript modules that extend the `Terminal` prototype with new methods and attributes to provide additional functionality. There are a handful available in the main repository in the `src/addons` directory and you can even write your own, by using xterm.js' public API. @@ -87,6 +74,21 @@ var xterm = new Terminal(); // Instantiate the terminal xterm.fit(); // Use the `fit` method, provided by the `fit` addon ``` +#### Importing Addons in TypeScript + +There are currently no typings for addons if they are accessed via extending Terminal prototype, so you will need to upcast if using TypeScript, eg. `(xterm).fit()`. + +Alternatively, you can import addon function and enhance the terminal on demand. This would have better typing support and is friendly to treeshaking. E.g.: + +```typescript +import { Terminal } from 'xterm'; +import { fit } from 'xterm/lib/addons/fit/fit'; +const xterm = new Terminal(); + +// Fit the terminal when necessary: +fit(xterm); +``` + #### Third party addons There are also the following third party addons available: From 9c1bee300d0983440c0f40447d90619ec781164e Mon Sep 17 00:00:00 2001 From: pro-src Date: Thu, 10 May 2018 23:03:12 -0500 Subject: [PATCH 23/28] Fix tsc --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d4a06f82..ee03147b 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@types/chai": "^3.4.34", "@types/jsdom": "^11.0.1", "@types/mocha": "^2.2.33", - "@types/node": "^6.0.41", + "@types/node": "6.0.108", "@types/text-encoding": "0.0.32", "browserify": "^13.3.0", "chai": "3.5.0", From 210a312fbff4a06f83f033ffdd3464cb4d1073c9 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 11 May 2018 07:49:37 -0700 Subject: [PATCH 24/28] Remove ignore key from package.json --- package.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/package.json b/package.json index ce58b98f..d060b08d 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,6 @@ "name": "xterm", "description": "Full xterm terminal, in your browser", "version": "3.3.0", - "ignore": [ - "demo", - "test", - ".gitignore" - ], "main": "lib/Terminal.js", "types": "typings/xterm.d.ts", "repository": "https://github.com/xtermjs/xterm.js", @@ -61,6 +56,5 @@ "coveralls": "gulp coveralls", "webpack": "gulp webpack", "watch": "gulp watch" - }, - "dependencies": {} + } } From 0375e0064bef71efc10cbebe752ae61da4ca739e Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 11 May 2018 10:03:43 -0700 Subject: [PATCH 25/28] Fix link cursor CSS Ensure pointer overrides the default mouse events mode cursor. Fixes #1437 --- src/xterm.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index eec41a05..2fae4588 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -135,6 +135,10 @@ cursor: text; } +.xterm.xterm-cursor-pointer { + cursor: pointer !important; +} + .xterm .xterm-accessibility, .xterm .xterm-message { position: absolute; @@ -153,7 +157,3 @@ height: 1px; overflow: hidden; } - -.xterm-cursor-pointer { - cursor: pointer; -} From 9dfce63e5588bd64b3911870f1ecaa405c1c7715 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sat, 12 May 2018 07:44:30 -0700 Subject: [PATCH 26/28] Simplify cursor styles --- src/xterm.css | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/xterm.css b/src/xterm.css index 2fae4588..6e7d2f96 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -126,17 +126,17 @@ line-height: normal; } +.xterm { + cursor: text; +} + .xterm.enable-mouse-events { /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */ cursor: default; } -.xterm:not(.enable-mouse-events) { - cursor: text; -} - .xterm.xterm-cursor-pointer { - cursor: pointer !important; + cursor: pointer; } .xterm .xterm-accessibility, From 6e451f58b87d78010b0a08c91db500148953f331 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 14 May 2018 11:13:01 -0700 Subject: [PATCH 27/28] Update tagline --- demo/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/index.html b/demo/index.html index 760d5990..9c19ea83 100644 --- a/demo/index.html +++ b/demo/index.html @@ -9,7 +9,7 @@ -

xterm.js: xterm, in the browser

+

xterm.js: A terminal for the web

Actions

From 3acd1eaecc45e6842640742cdaf1b68274deb05f Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 14 May 2018 11:48:13 -0700 Subject: [PATCH 28/28] Update coveralls This broke after we moved the organization Fixes #1451 --- .travis.yml | 1 - README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c41ebf79..1f3c9079 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,4 +17,3 @@ env: notifications: email: false script: npm run $NPM_COMMAND -after_success: npm run coveralls diff --git a/README.md b/README.md index dc14f853..caa0eea7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # [![xterm.js logo](logo-full.png)](https://xtermjs.org) -[![xterm.js build status](https://api.travis-ci.org/xtermjs/xterm.js.svg)](https://travis-ci.org/xtermjs/xterm.js) [![Coverage Status](https://coveralls.io/repos/github/sourcelair/xterm.js/badge.svg)](https://coveralls.io/github/sourcelair/xterm.js) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/xterm/badge?style=rounded)](https://www.jsdelivr.com/package/npm/xterm) +[![xterm.js build status](https://api.travis-ci.org/xtermjs/xterm.js.svg)](https://travis-ci.org/xtermjs/xterm.js) [![Coverage Status](https://coveralls.io/repos/github/xtermjs/xterm.js/badge.svg?branch=master)](https://coveralls.io/github/xtermjs/xterm.js?branch=master) [![Gitter](https://badges.gitter.im/sourcelair/xterm.js.svg)](https://gitter.im/sourcelair/xterm.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/xterm/badge?style=rounded)](https://www.jsdelivr.com/package/npm/xterm) Xterm.js is a terminal front-end component written in JavaScript that works in the browser.