Merge pull request #2857 from Tyriar/decoration_customizations

Allow embedders to customize link decorations independently
This commit is contained in:
Daniel Imms
2020-04-19 04:24:50 -07:00
committed by GitHub
4 changed files with 74 additions and 27 deletions
+10 -2
View File
@@ -10,6 +10,14 @@ import { MockBufferService } from 'common/TestUtils.test';
import { ILink } from 'browser/Types';
class TestLinkifier2 extends Linkifier2 {
protected _currentLinkState = {
decorations: {
underline: true,
pointerCursor: true
},
isHovered: true
};
constructor(bufferService: IBufferService) {
super(bufferService);
}
@@ -47,7 +55,7 @@ describe('Linkifier2', () => {
activate: () => { }
};
it('onLinkHover event range is correct', done => {
it('onShowLinkUnderline event range is correct', done => {
linkifier.onShowLinkUnderline(e => {
assert.equal(link.range.start.x - 1, e.x1);
assert.equal(link.range.start.y - 1, e.y1);
@@ -60,7 +68,7 @@ describe('Linkifier2', () => {
linkifier.linkHover({ classList: { add: () => { } } } as any, link, {} as any);
});
it('onLinkLeave event range is correct', done => {
it('onHideLinkUnderline event range is correct', done => {
linkifier.onHideLinkUnderline(e => {
assert.equal(link.range.start.x - 1, e.x1);
assert.equal(link.range.start.y - 1, e.y1);
+39 -21
View File
@@ -3,14 +3,14 @@
* @license MIT
*/
import { ILinkifier2, ILinkProvider, IBufferCellPosition, ILink, ILinkifierEvent } from './Types';
import { ILinkifier2, ILinkProvider, IBufferCellPosition, ILink, ILinkifierEvent, ILinkDecorations } from './Types';
import { IDisposable } from 'common/Types';
import { IMouseService, IRenderService } from './services/Services';
import { IBufferService } from 'common/services/Services';
import { EventEmitter, IEvent } from 'common/EventEmitter';
interface ILinkState {
hideDecorations: boolean;
decorations: ILinkDecorations;
isHovered: boolean;
}
@@ -20,7 +20,7 @@ export class Linkifier2 implements ILinkifier2 {
private _renderService: IRenderService | undefined;
private _linkProviders: ILinkProvider[] = [];
private _currentLink: ILink | undefined;
private _currentLinkState: ILinkState | undefined;
protected _currentLinkState: ILinkState | undefined;
private _lastMouseEvent: MouseEvent | undefined;
private _linkCacheDisposables: IDisposable[] = [];
private _lastBufferCell: IBufferCellPosition | undefined;
@@ -199,21 +199,35 @@ export class Linkifier2 implements ILinkifier2 {
if (this._linkAtPosition(link, position)) {
this._currentLink = link;
this._currentLinkState = {
hideDecorations: link.hideDecorations || false,
decorations: {
underline: link.decorations === undefined ? true : link.decorations.underline,
pointerCursor: link.decorations === undefined ? true : link.decorations.pointerCursor
},
isHovered: true
};
this._linkHover(this._element, link, this._lastMouseEvent);
// Add listener for tracking hideDecorations changes
Object.defineProperties(link, {
hideDecorations: {
get: () => this._currentLinkState?.hideDecorations,
// Add listener for tracking decorations changes
link.decorations = {} as ILinkDecorations;
Object.defineProperties(link.decorations, {
pointerCursor: {
get: () => this._currentLinkState?.decorations.pointerCursor,
set: v => {
if (this._currentLinkState && this._currentLinkState.hideDecorations !== v) {
this._currentLinkState.hideDecorations = v;
if (this._currentLinkState?.isHovered) {
this._fireUnderlineEvent(link, !v);
this._element?.classList.toggle('xterm-cursor-pointer', !v);
if (this._currentLinkState && this._currentLinkState?.decorations.pointerCursor !== v) {
this._currentLinkState.decorations.pointerCursor = v;
if (this._currentLinkState.isHovered) {
this._element?.classList.toggle('xterm-cursor-pointer', v);
}
}
}
},
underline: {
get: () => this._currentLinkState?.decorations.underline,
set: v => {
if (this._currentLinkState && this._currentLinkState?.decorations.underline !== v) {
this._currentLinkState.decorations.underline = v;
if (this._currentLinkState.isHovered) {
this._fireUnderlineEvent(link, v);
}
}
}
@@ -230,12 +244,14 @@ export class Linkifier2 implements ILinkifier2 {
}
protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void {
if (!link.hideDecorations) {
this._fireUnderlineEvent(link, true);
element.classList.add('xterm-cursor-pointer');
}
if (this._currentLinkState) {
this._currentLinkState.isHovered = true;
if (this._currentLinkState.decorations.underline) {
this._fireUnderlineEvent(link, true);
}
if (this._currentLinkState.decorations.pointerCursor) {
element.classList.add('xterm-cursor-pointer');
}
}
if (link.hover) {
@@ -252,12 +268,14 @@ export class Linkifier2 implements ILinkifier2 {
}
protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void {
if (!link.hideDecorations) {
this._fireUnderlineEvent(link, false);
element.classList.remove('xterm-cursor-pointer');
}
if (this._currentLinkState) {
this._currentLinkState.isHovered = false;
if (this._currentLinkState.decorations.underline) {
this._fireUnderlineEvent(link, false);
}
if (this._currentLinkState.decorations.pointerCursor) {
element.classList.remove('xterm-cursor-pointer');
}
}
if (link.leave) {
+6 -1
View File
@@ -172,12 +172,17 @@ interface ILinkProvider {
interface ILink {
range: IBufferRange;
text: string;
hideDecorations?: boolean;
decorations?: ILinkDecorations;
activate(event: MouseEvent, text: string): void;
hover?(event: MouseEvent, text: string): void;
leave?(event: MouseEvent, text: string): void;
}
interface ILinkDecorations {
pointerCursor: boolean;
underline: boolean;
}
interface IBufferRange {
start: IBufferCellPosition;
end: IBufferCellPosition;
+19 -3
View File
@@ -1121,10 +1121,11 @@ declare module 'xterm' {
text: string;
/**
* Whether to hide the underline and cursor styles, this property is tracked and changes made
* after the link is provided will trigger changes.
* What link decorations to show when hovering the link, this property is tracked and changes
* made after the link is provided will trigger changes. If not set, all decroations will be
* enabled.
*/
hideDecorations?: boolean;
decorations?: ILinkDecorations;
/**
* Calls when the link is activated.
@@ -1150,6 +1151,21 @@ declare module 'xterm' {
leave?(event: MouseEvent, text: string): void;
}
/**
* A set of decorations that can be applied to links.
*/
interface ILinkDecorations {
/**
* Whether the cursor is set to pointer.
*/
pointerCursor: boolean;
/**
* Whether the underline is visible
*/
underline: boolean;
}
/**
* A range within a buffer.
*/