Merge branch 'master' into 2028_handle_joined_cells
This commit is contained in:
Vendored
+51
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"presentation": {
|
||||
"echo": false,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "dedicated",
|
||||
"showReuseMessage": true
|
||||
},
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "test",
|
||||
"group": "test",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"group": "build",
|
||||
"isBackground": true,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"group": "vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "start",
|
||||
"group": "build",
|
||||
"isBackground": true,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"group": "vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Start demo",
|
||||
"dependsOn": ["npm: watch", "npm: start"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"isBackground": true,
|
||||
"problemMatcher": [],
|
||||
"presentation": {
|
||||
"group": "vscode"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+17
-8
@@ -11,9 +11,12 @@ const packageJson = require('../package.json');
|
||||
// Setup auth
|
||||
fs.writeFileSync(`${process.env['HOME']}/.npmrc`, `//registry.npmjs.org/:_authToken=${process.env['NPM_AUTH_TOKEN']}`);
|
||||
|
||||
// Get the version
|
||||
const tag = 'beta'
|
||||
const nextVersion = getNextVersion(tag);
|
||||
// Determine if this is a stable or beta release
|
||||
const publishedVersions = getPublishedVersions();
|
||||
const isStableRelease = publishedVersions.indexOf(packageJson.version) === -1;
|
||||
|
||||
// Get the next version
|
||||
let nextVersion = isStableRelease ? packageJson.version : getNextBetaVersion();
|
||||
console.log(`Publishing version: ${nextVersion}`);
|
||||
|
||||
// Set the version in package.json
|
||||
@@ -22,16 +25,19 @@ packageJson.version = nextVersion;
|
||||
fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2));
|
||||
|
||||
// Publish
|
||||
const result = cp.spawn('npm', ['publish', '--tag', tag], {
|
||||
stdio: 'inherit'
|
||||
});
|
||||
const args = ['publish'];
|
||||
if (!isStableRelease) {
|
||||
args.push('--tag', 'beta');
|
||||
}
|
||||
const result = cp.spawn('npm', args, { stdio: 'inherit' });
|
||||
result.on('exit', code => process.exit(code));
|
||||
|
||||
function getNextVersion(tag) {
|
||||
function getNextBetaVersion() {
|
||||
if (!/^[0-9]+\.[0-9]+\.[0-9]+$/.exec(packageJson.version)) {
|
||||
console.error('The package.json version must be of the form x.y.z');
|
||||
process.exit(1);
|
||||
}
|
||||
const tag = 'beta';
|
||||
const stableVersion = packageJson.version.split('.');
|
||||
const nextStableVersion = `${stableVersion[0]}.${parseInt(stableVersion[1]) + 1}.${stableVersion[2]}`;
|
||||
const publishedVersions = getPublishedVersions(nextStableVersion, tag);
|
||||
@@ -46,5 +52,8 @@ function getNextVersion(tag) {
|
||||
function getPublishedVersions(version, tag) {
|
||||
const versionsProcess = cp.spawnSync('npm', ['view', 'xterm', 'versions', '--json']);
|
||||
const versionsJson = JSON.parse(versionsProcess.stdout);
|
||||
return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}[0-9]+`)));
|
||||
if (tag) {
|
||||
return versionsJson.filter(v => !v.search(new RegExp(`${version}-${tag}[0-9]+`)));
|
||||
}
|
||||
return versionsJson;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ export class AccessibilityManager extends Disposable {
|
||||
this._refreshRowsDimensions();
|
||||
this._accessibilityTreeRoot.appendChild(this._rowContainer);
|
||||
|
||||
this._renderRowsDebouncer = new RenderDebouncer(this._terminal, this._renderRows.bind(this));
|
||||
this._renderRowsDebouncer = new RenderDebouncer(this._renderRows.bind(this));
|
||||
this._refreshRows();
|
||||
|
||||
this._liveRegion = document.createElement('div');
|
||||
@@ -239,7 +239,7 @@ export class AccessibilityManager extends Disposable {
|
||||
}
|
||||
|
||||
private _refreshRows(start?: number, end?: number): void {
|
||||
this._renderRowsDebouncer.refresh(start, end);
|
||||
this._renderRowsDebouncer.refresh(start, end, this._terminal.rows);
|
||||
}
|
||||
|
||||
private _renderRows(start: number, end: number): void {
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { assert, expect } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { Buffer, DEFAULT_ATTR_DATA } from './Buffer';
|
||||
import { CircularList } from './common/CircularList';
|
||||
import { MockTerminal, TestTerminal } from './ui/TestUtils.test';
|
||||
import { MockTerminal, TestTerminal } from './TestUtils.test';
|
||||
import { BufferLine, CellData } from './BufferLine';
|
||||
|
||||
const INIT_COLS = 80;
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { Buffer } from './Buffer';
|
||||
import { MockTerminal } from './ui/TestUtils.test';
|
||||
import { MockTerminal } from './TestUtils.test';
|
||||
|
||||
describe('BufferSet', () => {
|
||||
let terminal: ITerminal;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import jsdom = require('jsdom');
|
||||
import { ICharMeasure } from '../Types';
|
||||
import { ICharMeasure } from './Types';
|
||||
import { assert } from 'chai';
|
||||
import { CharMeasure } from './CharMeasure';
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ICharMeasure, ITerminalOptions } from '../Types';
|
||||
import { EventEmitter2, IEvent } from '../common/EventEmitter2';
|
||||
import { ICharMeasure, ITerminalOptions } from './Types';
|
||||
import { EventEmitter2, IEvent } from './common/EventEmitter2';
|
||||
|
||||
/**
|
||||
* Utility class that measures the size of a character. Measurements are done in
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { TestTerminal } from './ui/TestUtils.test';
|
||||
import { TestTerminal } from './TestUtils.test';
|
||||
import { assert } from 'chai';
|
||||
import { getStringCellWidth, wcwidth } from './CharWidth';
|
||||
import { IBuffer } from './Types';
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal, ISelectionManager } from '../Types';
|
||||
import { ITerminal, ISelectionManager } from './Types';
|
||||
|
||||
interface IWindow extends Window {
|
||||
clipboardData?: {
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { InputHandler } from './InputHandler';
|
||||
import { MockInputHandlingTerminal, TestTerminal } from './ui/TestUtils.test';
|
||||
import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test';
|
||||
import { DEFAULT_ATTR_DATA } from './Buffer';
|
||||
import { Terminal } from './Terminal';
|
||||
import { IBufferLine } from './Types';
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { IMouseZoneManager, IMouseZone } from './ui/Types';
|
||||
import { ILinkMatcher, ITerminal, IBufferLine } from './Types';
|
||||
import { IMouseZoneManager, IMouseZone, ILinkMatcher, ITerminal, IBufferLine } from './Types';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { MockBuffer, MockTerminal, TestTerminal } from './ui/TestUtils.test';
|
||||
import { MockBuffer, MockTerminal, TestTerminal } from './TestUtils.test';
|
||||
import { CircularList } from './common/CircularList';
|
||||
import { BufferLine, CellData } from './BufferLine';
|
||||
|
||||
|
||||
+2
-3
@@ -3,9 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IMouseZoneManager } from './ui/Types';
|
||||
import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, ITerminal, IBufferStringIteratorResult } from './Types';
|
||||
import { MouseZone } from './ui/MouseZoneManager';
|
||||
import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, ITerminal, IBufferStringIteratorResult, IMouseZoneManager } from './Types';
|
||||
import { MouseZone } from './MouseZoneManager';
|
||||
import { getStringCellWidth } from './CharWidth';
|
||||
import { EventEmitter2, IEvent } from './common/EventEmitter2';
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ICharMeasure, IMouseHelper } from '../Types';
|
||||
import { IRenderer } from '../renderer/Types';
|
||||
import { ICharMeasure, IMouseHelper } from './Types';
|
||||
import { IRenderer } from './renderer/Types';
|
||||
|
||||
export class MouseHelper implements IMouseHelper {
|
||||
constructor(private _renderer: IRenderer) {}
|
||||
@@ -3,10 +3,9 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminal } from '../Types';
|
||||
import { IMouseZoneManager, IMouseZone } from './Types';
|
||||
import { Disposable } from '../common/Lifecycle';
|
||||
import { addDisposableDomListener } from './Lifecycle';
|
||||
import { ITerminal, IMouseZoneManager, IMouseZone } from './Types';
|
||||
import { Disposable } from './common/Lifecycle';
|
||||
import { addDisposableDomListener } from './ui/Lifecycle';
|
||||
|
||||
const HOVER_DURATION = 500;
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { CharMeasure } from './ui/CharMeasure';
|
||||
import { CharMeasure } from './CharMeasure';
|
||||
import { SelectionManager, SelectionMode } from './SelectionManager';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { ITerminal, IBuffer, IBufferLine } from './Types';
|
||||
import { MockTerminal } from './ui/TestUtils.test';
|
||||
import { MockTerminal } from './TestUtils.test';
|
||||
import { BufferLine, CellData } from './BufferLine';
|
||||
|
||||
class TestMockTerminal extends MockTerminal {
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
*/
|
||||
|
||||
import { ITerminal, ISelectionManager, IBuffer, IBufferLine, ISelectionRedrawRequestEvent } from './Types';
|
||||
import { MouseHelper } from './ui/MouseHelper';
|
||||
import { MouseHelper } from './MouseHelper';
|
||||
import * as Browser from './common/Platform';
|
||||
import { CharMeasure } from './ui/CharMeasure';
|
||||
import { CharMeasure } from './CharMeasure';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { AltClickHandler } from './handlers/AltClickHandler';
|
||||
import { CellData } from './BufferLine';
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||
import { ITerminal } from './Types';
|
||||
import { SelectionModel } from './SelectionModel';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { MockTerminal } from './ui/TestUtils.test';
|
||||
import { MockTerminal } from './TestUtils.test';
|
||||
|
||||
class TestSelectionModel extends SelectionModel {
|
||||
constructor(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { assert, expect } from 'chai';
|
||||
import { Terminal } from './Terminal';
|
||||
import { MockViewport, MockCompositionHelper, MockRenderer } from './ui/TestUtils.test';
|
||||
import { MockViewport, MockCompositionHelper, MockRenderer } from './TestUtils.test';
|
||||
import { DEFAULT_ATTR_DATA } from './Buffer';
|
||||
import { CellData } from './BufferLine';
|
||||
|
||||
|
||||
+5
-6
@@ -21,27 +21,26 @@
|
||||
* http://linux.die.net/man/7/urxvt
|
||||
*/
|
||||
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData } from './Types';
|
||||
import { IMouseZoneManager } from './ui/Types';
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminalOptions, ITerminal, IBrowser, ILinkifier, ILinkMatcherOptions, CustomKeyEventHandler, LinkMatcherHandler, CharacterJoinerHandler, IBufferLine, IAttributeData, IMouseZoneManager } from './Types';
|
||||
import { IRenderer } from './renderer/Types';
|
||||
import { BufferSet } from './BufferSet';
|
||||
import { Buffer, MAX_BUFFER_SIZE, DEFAULT_ATTR_DATA } from './Buffer';
|
||||
import { CompositionHelper } from './CompositionHelper';
|
||||
import { EventEmitter } from './common/EventEmitter';
|
||||
import { Viewport } from './Viewport';
|
||||
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './ui/Clipboard';
|
||||
import { rightClickHandler, moveTextAreaUnderMouseCursor, pasteHandler, copyHandler } from './Clipboard';
|
||||
import { C0 } from './common/data/EscapeSequences';
|
||||
import { InputHandler } from './InputHandler';
|
||||
import { Renderer } from './renderer/Renderer';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { SelectionManager } from './SelectionManager';
|
||||
import { CharMeasure } from './ui/CharMeasure';
|
||||
import { CharMeasure } from './CharMeasure';
|
||||
import * as Browser from './common/Platform';
|
||||
import { addDisposableDomListener } from './ui/Lifecycle';
|
||||
import * as Strings from './Strings';
|
||||
import { MouseHelper } from './ui/MouseHelper';
|
||||
import { MouseHelper } from './MouseHelper';
|
||||
import { DEFAULT_BELL_SOUND, SoundManager } from './SoundManager';
|
||||
import { MouseZoneManager } from './ui/MouseZoneManager';
|
||||
import { MouseZoneManager } from './MouseZoneManager';
|
||||
import { AccessibilityManager } from './AccessibilityManager';
|
||||
import { ScreenDprMonitor } from './ui/ScreenDprMonitor';
|
||||
import { ITheme, IMarker, IDisposable } from 'xterm';
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../renderer/Types';
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler, IBufferLine, IBufferStringIterator, ICellData, IAttributeData } from '../Types';
|
||||
import { ICircularList, XtermListener } from '../common/Types';
|
||||
import { Buffer } from '../Buffer';
|
||||
import * as Browser from '../common/Platform';
|
||||
import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from './renderer/Types';
|
||||
import { IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ILinkifier, IMouseHelper, ILinkMatcherOptions, CharacterJoinerHandler, IBufferLine, IBufferStringIterator, ICellData, IAttributeData } from './Types';
|
||||
import { ICircularList, XtermListener } from './common/Types';
|
||||
import { Buffer } from './Buffer';
|
||||
import * as Browser from './common/Platform';
|
||||
import { ITheme, IDisposable, IMarker, IEvent } from 'xterm';
|
||||
import { Terminal } from '../Terminal';
|
||||
import { AttributeData } from '../BufferLine';
|
||||
import { Terminal } from './Terminal';
|
||||
import { AttributeData } from './BufferLine';
|
||||
|
||||
export class TestTerminal extends Terminal {
|
||||
writeSync(data: string): void {
|
||||
+17
-1
@@ -5,7 +5,6 @@
|
||||
|
||||
import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter, IDisposable } from 'xterm';
|
||||
import { IColorSet, IRenderer } from './renderer/Types';
|
||||
import { IMouseZoneManager } from './ui/Types';
|
||||
import { ICharset } from './core/Types';
|
||||
import { ICircularList } from './common/Types';
|
||||
import { IEvent } from './common/EventEmitter2';
|
||||
@@ -604,3 +603,20 @@ export interface IBufferLine {
|
||||
isCombined(index: number): number;
|
||||
getString(index: number): string;
|
||||
}
|
||||
|
||||
export interface IMouseZoneManager extends IDisposable {
|
||||
add(zone: IMouseZone): void;
|
||||
clearAll(start?: number, end?: number): void;
|
||||
}
|
||||
|
||||
export interface IMouseZone {
|
||||
x1: number;
|
||||
x2: number;
|
||||
y1: number;
|
||||
y2: number;
|
||||
clickCallback: (e: MouseEvent) => any;
|
||||
hoverCallback: (e: MouseEvent) => any | undefined;
|
||||
tooltipCallback: (e: MouseEvent) => any | undefined;
|
||||
leaveCallback: () => any | undefined;
|
||||
willLinkActivate: (e: MouseEvent) => boolean;
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
import { IColorSet } from './renderer/Types';
|
||||
import { ITerminal, IViewport } from './Types';
|
||||
import { CharMeasure } from './ui/CharMeasure';
|
||||
import { CharMeasure } from './CharMeasure';
|
||||
import { Disposable } from './common/Lifecycle';
|
||||
import { addDisposableDomListener } from './ui/Lifecycle';
|
||||
|
||||
|
||||
@@ -28,63 +28,159 @@ describe('webLinks addon', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow ~ character in URI path', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
describe('should allow simple URI path', () => {
|
||||
it('foo.com', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://foo.com/a~b#c~d?e~f ';
|
||||
const row = ' http://foo.com ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://foo.com/a~b#c~d?e~f');
|
||||
assert.equal(uri, 'http://foo.com');
|
||||
});
|
||||
|
||||
it('bar.io', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://bar.io ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://bar.io');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow : character in URI path', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
describe('should allow ~ character in URI path', () => {
|
||||
it('foo.com', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://foo.com/colon:test ';
|
||||
const row = ' http://foo.com/a~b#c~d?e~f ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://foo.com/colon:test');
|
||||
assert.equal(uri, 'http://foo.com/a~b#c~d?e~f');
|
||||
});
|
||||
|
||||
it('bar.io', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://bar.io/a~b#c~d?e~f ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://bar.io/a~b#c~d?e~f');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow : character at the end of a URI path', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
describe('should allow : character in URI path', () => {
|
||||
it('foo.com', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://foo.com/colon:test: ';
|
||||
const row = ' http://foo.com/colon:test ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://foo.com/colon:test');
|
||||
assert.equal(uri, 'http://foo.com/colon:test');
|
||||
});
|
||||
|
||||
it('bar.io', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://bar.io/colon:test ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://bar.io/colon:test');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow " character at the end of a URI enclosed with ""', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
describe('should not allow : character at the end of a URI path', () => {
|
||||
it('foo.com', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = '"http://foo.com/"';
|
||||
const row = ' http://foo.com/colon:test: ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://foo.com/');
|
||||
assert.equal(uri, 'http://foo.com/colon:test');
|
||||
});
|
||||
|
||||
it('bar.io', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = ' http://bar.io/colon:test: ';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://bar.io/colon:test');
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow \' character at the end of a URI enclosed with \'\'', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
describe('should not allow " character at the end of a URI enclosed with ""', () => {
|
||||
it('foo.com', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = '\'http://foo.com/\'';
|
||||
const row = '"http://foo.com/"';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://foo.com/');
|
||||
assert.equal(uri, 'http://foo.com/');
|
||||
});
|
||||
|
||||
it('bar.io', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = '"http://bar.io/"';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://bar.io/');
|
||||
});
|
||||
});
|
||||
|
||||
describe('should not allow \' character at the end of a URI enclosed with \'\'', () => {
|
||||
it('foo.com', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = '\'http://foo.com/\'';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://foo.com/');
|
||||
});
|
||||
|
||||
it('bar.io', () => {
|
||||
const term = new MockTerminal();
|
||||
webLinks.webLinksInit(<any>term);
|
||||
|
||||
const row = '\'http://bar.io/\'';
|
||||
|
||||
const match = row.match(term.regex);
|
||||
const uri = match[term.options.matchIndex];
|
||||
|
||||
assert.equal(uri, 'http://bar.io/');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,7 +14,8 @@ const ipClause = '((\\d{1,3}\\.){3}\\d{1,3})';
|
||||
const localHostClause = '(localhost)';
|
||||
const portClause = '(:\\d{1,5})';
|
||||
const hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + '|' + localHostClause + ')' + portClause + '?';
|
||||
const pathClause = '(\\/[\\/\\w\\.\\-%~:]*)*([^:"\'\\s])';
|
||||
const pathCharacterSet = '(\\/[\\/\\w\\.\\-%~:]*)*([^:"\'\\s])';
|
||||
const pathClause = '(' + pathCharacterSet + ')?';
|
||||
const queryStringHashFragmentCharacterSet = '[0-9\\w\\[\\]\\(\\)\\/\\?\\!#@$%&\'*+,:;~\\=\\.\\-]*';
|
||||
const queryStringClause = '(\\?' + queryStringHashFragmentCharacterSet + ')?';
|
||||
const hashFragmentClause = '(#' + queryStringHashFragmentCharacterSet + ')?';
|
||||
|
||||
@@ -30,7 +30,7 @@ export class Terminal implements ITerminalApi {
|
||||
public get textarea(): HTMLTextAreaElement { return this._core.textarea; }
|
||||
public get rows(): number { return this._core.rows; }
|
||||
public get cols(): number { return this._core.cols; }
|
||||
public get markers(): IMarker[] { return this._core.markers; }
|
||||
public get markers(): ReadonlyArray<IMarker> { return this._core.markers; }
|
||||
public blur(): void {
|
||||
this._core.blur();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { assert } from 'chai';
|
||||
|
||||
import { MockTerminal, MockBuffer } from '../ui/TestUtils.test';
|
||||
import { MockTerminal, MockBuffer } from '../TestUtils.test';
|
||||
import { CircularList } from '../common/CircularList';
|
||||
|
||||
import { ICharacterJoinerRegistry } from './Types';
|
||||
|
||||
@@ -68,7 +68,7 @@ export class Renderer extends Disposable implements IRenderer {
|
||||
this._updateDimensions();
|
||||
this.onOptionsChanged();
|
||||
|
||||
this._renderDebouncer = new RenderDebouncer(this._terminal, this._renderRows.bind(this));
|
||||
this._renderDebouncer = new RenderDebouncer(this._renderRows.bind(this));
|
||||
this._screenDprMonitor = new ScreenDprMonitor();
|
||||
this._screenDprMonitor.setListener(() => this.onWindowResize(window.devicePixelRatio));
|
||||
this.register(this._screenDprMonitor);
|
||||
@@ -194,7 +194,7 @@ export class Renderer extends Disposable implements IRenderer {
|
||||
this._needsFullRefresh = true;
|
||||
return;
|
||||
}
|
||||
this._renderDebouncer.refresh(start, end);
|
||||
this._renderDebouncer.refresh(start, end, this._terminal.rows);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -80,7 +80,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
};
|
||||
this._updateDimensions();
|
||||
|
||||
this._renderDebouncer = new RenderDebouncer(this._terminal, this._renderRows.bind(this));
|
||||
this._renderDebouncer = new RenderDebouncer(this._renderRows.bind(this));
|
||||
this._rowFactory = new DomRendererRowFactory(_terminal.options, document);
|
||||
|
||||
this._terminal.element.classList.add(TERMINAL_CLASS_PREFIX + this._terminalClass);
|
||||
@@ -174,9 +174,9 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
// Blink animation
|
||||
styles +=
|
||||
`@keyframes blink {` +
|
||||
` 0 % { opacity: 1.0; }` +
|
||||
` 0% { opacity: 1.0; }` +
|
||||
` 50% { opacity: 0.0; }` +
|
||||
` 100 % { opacity: 1.0; }` +
|
||||
` 100% { opacity: 1.0; }` +
|
||||
`}`;
|
||||
// Cursor
|
||||
styles +=
|
||||
@@ -340,7 +340,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
}
|
||||
|
||||
public refreshRows(start: number, end: number): void {
|
||||
this._renderDebouncer.refresh(start, end);
|
||||
this._renderDebouncer.refresh(start, end, this._terminal.rows);
|
||||
}
|
||||
|
||||
private _renderRows(start: number, end: number): void {
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@
|
||||
],
|
||||
"references": [
|
||||
{ "path": "./common" },
|
||||
{ "path": "./core" }
|
||||
{ "path": "./core" },
|
||||
{ "path": "./ui" }
|
||||
]
|
||||
}
|
||||
|
||||
+1
-3
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IDisposable } from 'xterm';
|
||||
import { IDisposable } from '../common/Types';
|
||||
|
||||
/**
|
||||
* Adds a disposable listener to a node in the DOM, returning the disposable.
|
||||
@@ -24,8 +24,6 @@ export function addDisposableDomListener(
|
||||
return;
|
||||
}
|
||||
node.removeEventListener(type, handler, useCapture);
|
||||
node = null;
|
||||
handler = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+28
-21
@@ -1,37 +1,39 @@
|
||||
import { ITerminal } from '../Types';
|
||||
import { IDisposable } from 'xterm';
|
||||
/**
|
||||
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IDisposable } from '../common/Types';
|
||||
|
||||
/**
|
||||
* Debounces calls to render terminal rows using animation frames.
|
||||
*/
|
||||
export class RenderDebouncer implements IDisposable {
|
||||
private _rowStart: number;
|
||||
private _rowEnd: number;
|
||||
private _animationFrame: number = null;
|
||||
private _rowStart: number | undefined;
|
||||
private _rowEnd: number | undefined;
|
||||
private _rowCount: number | undefined;
|
||||
private _animationFrame: number | undefined;
|
||||
|
||||
constructor(
|
||||
private _terminal: ITerminal,
|
||||
private _callback: (start: number, end: number) => void
|
||||
private _renderCallback: (start: number, end: number) => void
|
||||
) {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._animationFrame) {
|
||||
window.cancelAnimationFrame(this._animationFrame);
|
||||
this._animationFrame = null;
|
||||
this._animationFrame = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public refresh(rowStart: number, rowEnd: number): void {
|
||||
public refresh(rowStart: number, rowEnd: number, rowCount: number): void {
|
||||
this._rowCount = rowCount;
|
||||
// Get the min/max row start/end for the arg values
|
||||
rowStart = rowStart !== null && rowStart !== undefined ? rowStart : 0;
|
||||
rowEnd = rowEnd !== null && rowEnd !== undefined ? rowEnd : this._terminal.rows - 1;
|
||||
// Check whether the row start/end values have already been set
|
||||
const isRowStartSet = this._rowStart !== undefined && this._rowStart !== null;
|
||||
const isRowEndSet = this._rowEnd !== undefined && this._rowEnd !== null;
|
||||
rowStart = rowStart !== undefined ? rowStart : 0;
|
||||
rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1;
|
||||
// Set the properties to the updated values
|
||||
this._rowStart = isRowStartSet ? Math.min(this._rowStart, rowStart) : rowStart;
|
||||
this._rowEnd = isRowEndSet ? Math.max(this._rowEnd, rowEnd) : rowEnd;
|
||||
this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;
|
||||
this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;
|
||||
|
||||
if (this._animationFrame) {
|
||||
return;
|
||||
@@ -41,16 +43,21 @@ export class RenderDebouncer implements IDisposable {
|
||||
}
|
||||
|
||||
private _innerRefresh(): void {
|
||||
// Make sure values are set
|
||||
if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clamp values
|
||||
this._rowStart = Math.max(this._rowStart, 0);
|
||||
this._rowEnd = Math.min(this._rowEnd, this._terminal.rows - 1);
|
||||
this._rowEnd = Math.min(this._rowEnd, this._rowCount - 1);
|
||||
|
||||
// Run render callback
|
||||
this._callback(this._rowStart, this._rowEnd);
|
||||
this._renderCallback(this._rowStart, this._rowEnd);
|
||||
|
||||
// Reset debouncer
|
||||
this._rowStart = null;
|
||||
this._rowEnd = null;
|
||||
this._animationFrame = null;
|
||||
this._rowStart = undefined;
|
||||
this._rowEnd = undefined;
|
||||
this._animationFrame = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-10
@@ -18,10 +18,10 @@ export type ScreenDprListener = (newDevicePixelRatio?: number, oldDevicePixelRat
|
||||
* monitor with a different DPI.
|
||||
*/
|
||||
export class ScreenDprMonitor extends Disposable {
|
||||
private _currentDevicePixelRatio: number;
|
||||
private _outerListener: (this: MediaQueryList, ev: MediaQueryListEvent) => any;
|
||||
private _listener: ScreenDprListener;
|
||||
private _resolutionMediaMatchList: MediaQueryList;
|
||||
private _currentDevicePixelRatio: number = window.devicePixelRatio;
|
||||
private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;
|
||||
private _listener: ScreenDprListener | undefined;
|
||||
private _resolutionMediaMatchList: MediaQueryList | undefined;
|
||||
|
||||
public setListener(listener: ScreenDprListener): void {
|
||||
if (this._listener) {
|
||||
@@ -29,6 +29,9 @@ export class ScreenDprMonitor extends Disposable {
|
||||
}
|
||||
this._listener = listener;
|
||||
this._outerListener = () => {
|
||||
if (!this._listener) {
|
||||
return;
|
||||
}
|
||||
this._listener(window.devicePixelRatio, this._currentDevicePixelRatio);
|
||||
this._updateDpr();
|
||||
};
|
||||
@@ -41,10 +44,13 @@ export class ScreenDprMonitor extends Disposable {
|
||||
}
|
||||
|
||||
private _updateDpr(): void {
|
||||
// Clear listeners for old DPR
|
||||
if (this._resolutionMediaMatchList) {
|
||||
this._resolutionMediaMatchList.removeListener(this._outerListener);
|
||||
if (!this._resolutionMediaMatchList || !this._outerListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear listeners for old DPR
|
||||
this._resolutionMediaMatchList.removeListener(this._outerListener);
|
||||
|
||||
// Add listeners for new DPR
|
||||
this._currentDevicePixelRatio = window.devicePixelRatio;
|
||||
this._resolutionMediaMatchList = window.matchMedia(`screen and (resolution: ${window.devicePixelRatio}dppx)`);
|
||||
@@ -52,11 +58,12 @@ export class ScreenDprMonitor extends Disposable {
|
||||
}
|
||||
|
||||
public clearListener(): void {
|
||||
if (!this._listener) {
|
||||
if (!this._resolutionMediaMatchList || !this._listener || !this._outerListener) {
|
||||
return;
|
||||
}
|
||||
this._resolutionMediaMatchList.removeListener(this._outerListener);
|
||||
this._listener = null;
|
||||
this._outerListener = null;
|
||||
this._resolutionMediaMatchList = undefined;
|
||||
this._listener = undefined;
|
||||
this._outerListener = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IDisposable } from 'xterm';
|
||||
|
||||
export interface IMouseZoneManager extends IDisposable {
|
||||
add(zone: IMouseZone): void;
|
||||
clearAll(start?: number, end?: number): void;
|
||||
}
|
||||
|
||||
export interface IMouseZone {
|
||||
x1: number;
|
||||
x2: number;
|
||||
y1: number;
|
||||
y2: number;
|
||||
clickCallback: (e: MouseEvent) => any;
|
||||
hoverCallback: (e: MouseEvent) => any | undefined;
|
||||
tooltipCallback: (e: MouseEvent) => any | undefined;
|
||||
leaveCallback: () => any | undefined;
|
||||
willLinkActivate: (e: MouseEvent) => boolean;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"extends": "../tsconfig-library-base",
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"dom",
|
||||
"es5",
|
||||
],
|
||||
"outDir": "../../lib",
|
||||
"types": [
|
||||
"../../node_modules/@types/mocha"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"./Lifecycle.ts",
|
||||
"./RenderDebouncer.ts",
|
||||
"./ScreenDprMonitor.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../common" }
|
||||
]
|
||||
}
|
||||
Vendored
+1
-1
@@ -359,7 +359,7 @@ declare module 'xterm' {
|
||||
* (EXPERIMENTAL) Get all markers registered against the buffer. If the alt
|
||||
* buffer is active this will always return [].
|
||||
*/
|
||||
readonly markers: IMarker[];
|
||||
readonly markers: ReadonlyArray<IMarker>;
|
||||
|
||||
/**
|
||||
* Natural language strings that can be localized.
|
||||
|
||||
Reference in New Issue
Block a user