mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
@@ -85,6 +85,12 @@ export interface LinkMatcherOptions {
|
||||
* false if invalid.
|
||||
*/
|
||||
validationCallback?: LinkMatcherValidationCallback;
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+25
-2
@@ -5,12 +5,15 @@ import jsdom = require('jsdom');
|
||||
import { assert } from 'chai';
|
||||
import { ITerminal, ILinkifier } from './Interfaces';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { LinkMatcher } from './Types';
|
||||
|
||||
class TestLinkifier extends Linkifier {
|
||||
constructor(document: Document, rows: HTMLElement[]) {
|
||||
Linkifier.TIME_BEFORE_LINKIFY = 0;
|
||||
super(document, rows);
|
||||
}
|
||||
|
||||
public get linkMatchers(): LinkMatcher[] { return this._linkMatchers; }
|
||||
}
|
||||
|
||||
describe('Linkifier', () => {
|
||||
@@ -19,14 +22,14 @@ describe('Linkifier', () => {
|
||||
|
||||
let container: HTMLElement;
|
||||
let rows: HTMLElement[];
|
||||
let linkifier: ILinkifier;
|
||||
let linkifier: TestLinkifier;
|
||||
|
||||
beforeEach(done => {
|
||||
rows = [];
|
||||
jsdom.env('', (err, w) => {
|
||||
window = w;
|
||||
document = window.document;
|
||||
linkifier = new Linkifier(document, rows);
|
||||
linkifier = new TestLinkifier(document, rows);
|
||||
container = document.createElement('div');
|
||||
document.body.appendChild(container);
|
||||
done();
|
||||
@@ -73,4 +76,24 @@ describe('Linkifier', () => {
|
||||
setTimeout(() => done(), 10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('priority', () => {
|
||||
it('should order the list from highest priority to lowest #1', () => {
|
||||
const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 1 });
|
||||
const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: -1 });
|
||||
assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [aId, 0, bId]);
|
||||
});
|
||||
|
||||
it('should order the list from highest priority to lowest #2', () => {
|
||||
const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: -1 });
|
||||
const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 1 });
|
||||
assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [bId, 0, aId]);
|
||||
});
|
||||
|
||||
it('should order items of equal priority in the order they are added', () => {
|
||||
const aId = linkifier.registerLinkMatcher(/a/, () => {}, { priority: 0 });
|
||||
const bId = linkifier.registerLinkMatcher(/b/, () => {}, { priority: 0 });
|
||||
assert.deepEqual(linkifier.linkMatchers.map(lm => lm.id), [0, aId, bId]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+32
-13
@@ -3,15 +3,7 @@
|
||||
*/
|
||||
|
||||
import { LinkMatcherOptions } from './Interfaces';
|
||||
import { LinkMatcherHandler, LinkMatcherValidationCallback } from './Types';
|
||||
|
||||
type LinkMatcher = {
|
||||
id: number,
|
||||
regex: RegExp,
|
||||
handler: LinkMatcherHandler,
|
||||
matchIndex?: number,
|
||||
validationCallback?: LinkMatcherValidationCallback;
|
||||
};
|
||||
import { LinkMatcher, LinkMatcherHandler, LinkMatcherValidationCallback } from './Types';
|
||||
|
||||
const INVALID_LINK_CLASS = 'xterm-invalid-link';
|
||||
|
||||
@@ -50,10 +42,11 @@ export class Linkifier {
|
||||
*/
|
||||
protected static TIME_BEFORE_LINKIFY = 200;
|
||||
|
||||
protected _linkMatchers: LinkMatcher[];
|
||||
|
||||
private _document: Document;
|
||||
private _rows: HTMLElement[];
|
||||
private _rowTimeoutIds: number[];
|
||||
private _linkMatchers: LinkMatcher[];
|
||||
private _nextLinkMatcherId = HYPERTEXT_LINK_MATCHER_ID;
|
||||
|
||||
constructor(document: Document, rows: HTMLElement[]) {
|
||||
@@ -105,12 +98,39 @@ export class Linkifier {
|
||||
regex,
|
||||
handler,
|
||||
matchIndex: options.matchIndex,
|
||||
validationCallback: options.validationCallback
|
||||
validationCallback: options.validationCallback,
|
||||
priority: options.priority || 0
|
||||
};
|
||||
this._linkMatchers.push(matcher);
|
||||
this._addLinkMatcherToList(matcher);
|
||||
return matcher.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a link matcher to the list in the correct position based on the
|
||||
* priority of each link matcher. New link matchers of equal priority are
|
||||
* considered after older link matchers.
|
||||
* @param matcher The link matcher to be added.
|
||||
*/
|
||||
private _addLinkMatcherToList(matcher: LinkMatcher): void {
|
||||
if (this._linkMatchers.length === 0) {
|
||||
this._linkMatchers.push(matcher);
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = this._linkMatchers.length - 1; i >= 0; i--) {
|
||||
if (matcher.priority === this._linkMatchers[i].priority) {
|
||||
this._linkMatchers.splice(i + 1, 0, matcher);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (matcher.priority > this._linkMatchers[0].priority) {
|
||||
this._linkMatchers.splice(0, 0, matcher);
|
||||
} else {
|
||||
this._linkMatchers.push(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregisters a link matcher if it has been registered.
|
||||
* @param {number} matcherId The link matcher's ID (returned after register)
|
||||
@@ -137,7 +157,6 @@ export class Linkifier {
|
||||
return;
|
||||
}
|
||||
const text = row.textContent;
|
||||
// TODO: Onl execute handler if isValid
|
||||
for (let i = 0; i < this._linkMatchers.length; i++) {
|
||||
const matcher = this._linkMatchers[i];
|
||||
const uri = this._findLinkMatch(text, matcher.regex, matcher.matchIndex);
|
||||
|
||||
@@ -2,5 +2,13 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
export type LinkMatcher = {
|
||||
id: number,
|
||||
regex: RegExp,
|
||||
handler: LinkMatcherHandler,
|
||||
matchIndex?: number,
|
||||
validationCallback?: LinkMatcherValidationCallback,
|
||||
priority?: number
|
||||
};
|
||||
export type LinkMatcherHandler = (uri: string) => void;
|
||||
export type LinkMatcherValidationCallback = (uri: string, callback: (isValid: boolean) => void) => void;
|
||||
|
||||
Reference in New Issue
Block a user