Fix issues with link state
- Scrolling will now clear the link renderer - Refreshing a single line will now recalculate only that line Fixes #959 Fixes #960
This commit is contained in:
+23
-8
@@ -49,11 +49,16 @@ export class Linkifier extends EventEmitter implements ILinkifier {
|
|||||||
private _mouseZoneManager: IMouseZoneManager;
|
private _mouseZoneManager: IMouseZoneManager;
|
||||||
private _rowsTimeoutId: number;
|
private _rowsTimeoutId: number;
|
||||||
private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;
|
private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;
|
||||||
|
private _rowsToLinkify: {start: number, end: number};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected _terminal: IBufferAccessor & IElementAccessor
|
protected _terminal: IBufferAccessor & IElementAccessor
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
this._rowsToLinkify = {
|
||||||
|
start: null,
|
||||||
|
end: null
|
||||||
|
};
|
||||||
this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });
|
this.registerLinkMatcher(strictUrlRegex, null, { matchIndex: 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,25 +81,35 @@ export class Linkifier extends EventEmitter implements ILinkifier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear out any existing links
|
// Increase range to linkify
|
||||||
this._mouseZoneManager.clearAll();
|
if (!this._rowsToLinkify.start) {
|
||||||
|
this._rowsToLinkify.start = start;
|
||||||
|
this._rowsToLinkify.end = end;
|
||||||
|
} else {
|
||||||
|
this._rowsToLinkify.start = this._rowsToLinkify.start < start ? this._rowsToLinkify.start : start;
|
||||||
|
this._rowsToLinkify.end = this._rowsToLinkify.end < end ? this._rowsToLinkify.end : end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear out any existing links on this row range
|
||||||
|
this._mouseZoneManager.clearAll(start, end);
|
||||||
|
|
||||||
|
// Restart timer
|
||||||
if (this._rowsTimeoutId) {
|
if (this._rowsTimeoutId) {
|
||||||
clearTimeout(this._rowsTimeoutId);
|
clearTimeout(this._rowsTimeoutId);
|
||||||
}
|
}
|
||||||
this._rowsTimeoutId = setTimeout(this._linkifyRows.bind(this, start, end), Linkifier.TIME_BEFORE_LINKIFY);
|
this._rowsTimeoutId = <number><any>setTimeout(() => this._linkifyRows(), Linkifier.TIME_BEFORE_LINKIFY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linkifies
|
* Linkifies the rows requested.
|
||||||
* @param start The row to start at.
|
|
||||||
* @param end The row to end at.
|
|
||||||
*/
|
*/
|
||||||
private _linkifyRows(start: number, end: number): void {
|
private _linkifyRows(): void {
|
||||||
this._rowsTimeoutId = null;
|
this._rowsTimeoutId = null;
|
||||||
for (let i = start; i <= end; i++) {
|
for (let i = this._rowsToLinkify.start; i <= this._rowsToLinkify.end; i++) {
|
||||||
this._linkifyRow(i);
|
this._linkifyRow(i);
|
||||||
}
|
}
|
||||||
|
this._rowsToLinkify.start = null;
|
||||||
|
this._rowsToLinkify.end = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+6
-2
@@ -48,8 +48,11 @@ import { MouseZoneManager } from './input/MouseZoneManager';
|
|||||||
import { initialize as initializeCharAtlas } from './renderer/CharAtlas';
|
import { initialize as initializeCharAtlas } from './renderer/CharAtlas';
|
||||||
import { IRenderer } from './renderer/Interfaces';
|
import { IRenderer } from './renderer/Interfaces';
|
||||||
|
|
||||||
// Declare for RequireJS in loadAddon
|
// Declares required for loadAddon
|
||||||
|
declare var exports: any;
|
||||||
|
declare var module: any;
|
||||||
declare var define: any;
|
declare var define: any;
|
||||||
|
declare var require: any;
|
||||||
|
|
||||||
// Let it work inside Node.js for automated testing purposes.
|
// Let it work inside Node.js for automated testing purposes.
|
||||||
const document = (typeof window !== 'undefined') ? window.document : null;
|
const document = (typeof window !== 'undefined') ? window.document : null;
|
||||||
@@ -588,6 +591,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
this.syncBellSound();
|
this.syncBellSound();
|
||||||
|
|
||||||
this._mouseZoneManager = new MouseZoneManager(this);
|
this._mouseZoneManager = new MouseZoneManager(this);
|
||||||
|
this.on('scroll', () => this._mouseZoneManager.clearAll());
|
||||||
this.linkifier.attachToDom(this._mouseZoneManager);
|
this.linkifier.attachToDom(this._mouseZoneManager);
|
||||||
|
|
||||||
// Create the container that will hold helpers like the textarea for
|
// Create the container that will hold helpers like the textarea for
|
||||||
@@ -1034,7 +1038,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
|||||||
*/
|
*/
|
||||||
private queueLinkification(start: number, end: number): void {
|
private queueLinkification(start: number, end: number): void {
|
||||||
if (this.linkifier) {
|
if (this.linkifier) {
|
||||||
this.linkifier.linkifyRows(0, this.rows);
|
this.linkifier.linkifyRows(start, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
export interface IMouseZoneManager {
|
export interface IMouseZoneManager {
|
||||||
add(zone: IMouseZone): void;
|
add(zone: IMouseZone): void;
|
||||||
clearAll(): void;
|
clearAll(start?: number, end?: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMouseZone {
|
export interface IMouseZone {
|
||||||
|
|||||||
@@ -44,9 +44,28 @@ export class MouseZoneManager implements IMouseZoneManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public clearAll(): void {
|
public clearAll(start?: number, end?: number): void {
|
||||||
this._zones.length = 0;
|
// Exit if there's nothing to clear
|
||||||
this._deactivate();
|
if (this._zones.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate through zones and clear them out if they're within the range
|
||||||
|
for (let i = 0; i < this._zones.length; i++) {
|
||||||
|
const zone = this._zones[i];
|
||||||
|
if (zone.y >= start && zone.y <= end) {
|
||||||
|
if (this._currentZone && this._currentZone === zone) {
|
||||||
|
this._currentZone.leaveCallback();
|
||||||
|
this._currentZone = null;
|
||||||
|
}
|
||||||
|
this._zones.splice(i--, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deactivate the mouse zone manager if all the zones have been removed
|
||||||
|
if (this._zones.length === 0) {
|
||||||
|
this._deactivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _activate(): void {
|
private _activate(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user