Merge branch 'master' into fix-crosshair

This commit is contained in:
peacefullatom
2018-08-27 12:04:23 +05:00
10 changed files with 43 additions and 23 deletions
+1
View File
@@ -169,6 +169,7 @@ computational environment for Jupyter, supporting interactive data science and s
- [**cPanel & WHM**](https://cpanel.com): The hosting platform of choice.
- [**Nutanix**](https://github.com/nutanix): Nutanix Enterprise Cloud uses xterm in the webssh functionality within Nutanix Calm, and is also looking to move our old noserial (termjs) functionality to xterm.js
- [**SSH Web Client**](https://github.com/roke22/PHP-SSH2-Web-Client): SSH Web Client with PHP.
- [**Shellvault**](https://www.shellvault.io): The cloud-based SSH terminal you can access from anywhere.
[And much more...](https://github.com/xtermjs/xterm.js/network/dependents)
+3 -3
View File
@@ -283,7 +283,7 @@ export class Buffer implements IBuffer {
* @param i The index to start setting up tab stops from.
*/
public setupTabStops(i?: number): void {
if (i != null) {
if (i !== null && i !== undefined) {
if (!this.tabs[i]) {
i = this.prevStop(i);
}
@@ -302,7 +302,7 @@ export class Buffer implements IBuffer {
* @param x The position to move the cursor to the previous tab stop.
*/
public prevStop(x?: number): number {
if (x == null) {
if (x === null || x === undefined) {
x = this.x;
}
while (!this.tabs[--x] && x > 0);
@@ -314,7 +314,7 @@ export class Buffer implements IBuffer {
* @param x The position to move the cursor one tab stop forward.
*/
public nextStop(x?: number): number {
if (x == null) {
if (x === null || x === undefined) {
x = this.x;
}
while (!this.tabs[++x] && x < this._terminal.cols);
+18 -10
View File
@@ -7,6 +7,7 @@ import { IMouseZoneManager } from './ui/Types';
import { ILinkHoverEvent, ILinkMatcher, LinkMatcherHandler, LinkHoverEventTypes, ILinkMatcherOptions, ILinkifier, ITerminal, LineData } from './Types';
import { MouseZone } from './ui/MouseZoneManager';
import { EventEmitter } from './EventEmitter';
import { CHAR_DATA_ATTR_INDEX } from './Buffer';
/**
* The Linkifier applies links to rows shortly after they have been refreshed.
@@ -24,7 +25,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
private _mouseZoneManager: IMouseZoneManager;
private _rowsTimeoutId: number;
private _nextLinkMatcherId = 0;
private _rowsToLinkify: {start: number, end: number};
private _rowsToLinkify: { start: number, end: number };
constructor(
protected _terminal: ITerminal
@@ -187,7 +188,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
let text = this._terminal.buffer.translateBufferLineToString(absoluteRowIndex, false);
let currentIndex = absoluteRowIndex + 1;
while (currentIndex < this._terminal.buffer.lines.length &&
(<any>this._terminal.buffer.lines.get(currentIndex)).isWrapped) {
(<any>this._terminal.buffer.lines.get(currentIndex)).isWrapped) {
text += this._terminal.buffer.translateBufferLineToString(currentIndex++, false);
}
@@ -216,6 +217,12 @@ export class Linkifier extends EventEmitter implements ILinkifier {
// Get index, match.index is for the outer match which includes negated chars
const index = text.indexOf(uri);
// Get cell color
const line = this._terminal.buffer.lines.get(this._terminal.buffer.ydisp + rowIndex);
const char = line[index];
const attr: number = char[CHAR_DATA_ATTR_INDEX];
const fg = (attr >> 9) & 0x1ff;
// Ensure the link is valid before registering
if (matcher.validationCallback) {
matcher.validationCallback(uri, isValid => {
@@ -224,11 +231,11 @@ export class Linkifier extends EventEmitter implements ILinkifier {
return;
}
if (isValid) {
this._addLink(offset + index, rowIndex, uri, matcher);
this._addLink(offset + index, rowIndex, uri, matcher, fg);
}
});
} else {
this._addLink(offset + index, rowIndex, uri, matcher);
this._addLink(offset + index, rowIndex, uri, matcher, fg);
}
// Recursively check for links in the rest of the text
@@ -245,8 +252,9 @@ export class Linkifier extends EventEmitter implements ILinkifier {
* @param y The row the link is on.
* @param uri The URI of the link.
* @param matcher The link matcher for the link.
* @param fg The link color for hover event.
*/
private _addLink(x: number, y: number, uri: string, matcher: ILinkMatcher): void {
private _addLink(x: number, y: number, uri: string, matcher: ILinkMatcher, fg: number): void {
const x1 = x % this._terminal.cols;
const y1 = y + Math.floor(x / this._terminal.cols);
let x2 = (x1 + uri.length) % this._terminal.cols;
@@ -268,17 +276,17 @@ export class Linkifier extends EventEmitter implements ILinkifier {
window.open(uri, '_blank');
},
e => {
this.emit(LinkHoverEventTypes.HOVER, this._createLinkHoverEvent(x1, y1, x2, y2));
this.emit(LinkHoverEventTypes.HOVER, this._createLinkHoverEvent(x1, y1, x2, y2, fg));
this._terminal.element.classList.add('xterm-cursor-pointer');
},
e => {
this.emit(LinkHoverEventTypes.TOOLTIP, this._createLinkHoverEvent(x1, y1, x2, y2));
this.emit(LinkHoverEventTypes.TOOLTIP, this._createLinkHoverEvent(x1, y1, x2, y2, fg));
if (matcher.hoverTooltipCallback) {
matcher.hoverTooltipCallback(e, uri);
}
},
() => {
this.emit(LinkHoverEventTypes.LEAVE, this._createLinkHoverEvent(x1, y1, x2, y2));
this.emit(LinkHoverEventTypes.LEAVE, this._createLinkHoverEvent(x1, y1, x2, y2, fg));
this._terminal.element.classList.remove('xterm-cursor-pointer');
if (matcher.hoverLeaveCallback) {
matcher.hoverLeaveCallback();
@@ -293,7 +301,7 @@ export class Linkifier extends EventEmitter implements ILinkifier {
));
}
private _createLinkHoverEvent(x1: number, y1: number, x2: number, y2: number): ILinkHoverEvent {
return { x1, y1, x2, y2, cols: this._terminal.cols };
private _createLinkHoverEvent(x1: number, y1: number, x2: number, y2: number, fg: number): ILinkHoverEvent {
return { x1, y1, x2, y2, cols: this._terminal.cols, fg };
}
}
+5 -5
View File
@@ -251,7 +251,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
private _setup(): void {
Object.keys(DEFAULT_OPTIONS).forEach((key) => {
if (this.options[key] == null) {
if (this.options[key] === null || this.options[key] === undefined) {
this.options[key] = DEFAULT_OPTIONS[key];
}
});
@@ -961,9 +961,9 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
// 1, and 2 - with 64 added
switch ((<any>ev).overrideType || ev.type) {
case 'mousedown':
button = ev.button != null
button = ev.button !== null && ev.button !== undefined
? +ev.button
: ev.which != null
: ev.which !== null && ev.which !== undefined
? ev.which - 1
: null;
@@ -1588,7 +1588,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
if (ev.charCode) {
key = ev.charCode;
} else if (ev.which == null) {
} else if (ev.which === null || ev.which === undefined) {
key = ev.keyCode;
} else if (ev.which !== 0 && ev.charCode !== 0) {
key = ev.which;
@@ -1933,7 +1933,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II
public matchColor(r1: number, g1: number, b1: number): number {
const hash = (r1 << 16) | (g1 << 8) | b1;
if (matchColorCache[hash] != null) {
if (matchColorCache[hash] !== null && matchColorCache[hash] !== undefined) {
return matchColorCache[hash];
}
+1
View File
@@ -204,6 +204,7 @@ export interface ILinkHoverEvent {
x2: number;
y2: number;
cols: number;
fg: number;
}
export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor {
+10 -1
View File
@@ -6,6 +6,7 @@
import { ILinkHoverEvent, ITerminal, ILinkifierAccessor, LinkHoverEventTypes } from '../Types';
import { IColorSet, IRenderDimensions } from './Types';
import { BaseRenderLayer } from './BaseRenderLayer';
import { INVERTED_DEFAULT_COLOR } from './atlas/Types';
export class LinkRenderLayer extends BaseRenderLayer {
private _state: ILinkHoverEvent = null;
@@ -39,7 +40,15 @@ export class LinkRenderLayer extends BaseRenderLayer {
}
private _onLinkHover(e: ILinkHoverEvent): void {
this._ctx.fillStyle = this._colors.foreground.css;
if (e.fg === INVERTED_DEFAULT_COLOR) {
this._ctx.fillStyle = this._colors.background.css;
} else if (e.fg < 256) {
// 256 color support
this._ctx.fillStyle = this._colors.ansi[e.fg].css;
} else {
this._ctx.fillStyle = this._colors.foreground.css;
}
if (e.y1 === e.y2) {
// Single line link
this.fillBottomLineAtCells(e.x1, e.y1, e.x2 - e.x1);
+1 -1
View File
@@ -94,7 +94,7 @@ export default class DynamicCharAtlas extends BaseCharAtlas {
): boolean {
const glyphKey = getGlyphCacheKey(glyph);
const cacheValue = this._cacheMap.get(glyphKey);
if (cacheValue != null) {
if (cacheValue !== null && cacheValue !== undefined) {
this._drawFromCache(ctx, cacheValue, x, y);
return true;
} else if (this._canCache(glyph) && this._drawToCacheCount < FRAME_CACHE_DRAW_LIMIT) {
+1 -1
View File
@@ -53,7 +53,7 @@ export default class StaticCharAtlas extends BaseCharAtlas {
y: number
): boolean {
// we're not warmed up yet
if (this._texture == null) {
if (this._texture === null || this._texture === undefined) {
return false;
}
+1 -1
View File
@@ -11,7 +11,7 @@ export class MouseHelper {
public static getCoordsRelativeToElement(event: {pageX: number, pageY: number}, element: HTMLElement): [number, number] {
// Ignore browsers that don't support MouseEvent.pageX
if (event.pageX == null) {
if (event.pageX === null || event.pageX === undefined) {
return null;
}
+2 -1
View File
@@ -111,6 +111,7 @@
"prefer-const-enum": [
true
],
"prefer-const": true
"prefer-const": true,
"triple-equals": true
}
}