From 2ac5a8da4970d82fbe67bdb9b4998e956ecd7943 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Wed, 31 Jan 2018 17:42:33 -0800 Subject: [PATCH 1/2] Allow support of modifiers with links Fixes #1021 --- src/Linkifier.ts | 7 +++++++ src/Types.ts | 8 ++++++++ src/input/MouseZoneManager.ts | 15 ++++++++------- src/input/Types.ts | 7 ++++--- typings/xterm.d.ts | 12 ++++++++++-- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/Linkifier.ts b/src/Linkifier.ts index da901a6e..a9617952 100644 --- a/src/Linkifier.ts +++ b/src/Linkifier.ts @@ -150,6 +150,7 @@ export class Linkifier extends EventEmitter implements ILinkifier { validationCallback: options.validationCallback, hoverTooltipCallback: options.tooltipCallback, hoverLeaveCallback: options.leaveCallback, + willLinkActivate: options.willLinkActivate, priority: options.priority || 0 }; this._addLinkMatcherToList(matcher); @@ -290,6 +291,12 @@ export class Linkifier extends EventEmitter implements ILinkifier { if (matcher.hoverLeaveCallback) { matcher.hoverLeaveCallback(); } + }, + e => { + if (matcher.willLinkActivate) { + return matcher.willLinkActivate(e, uri); + } + return true; } )); } diff --git a/src/Types.ts b/src/Types.ts index da3cc9d2..9dd7dda2 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -161,6 +161,7 @@ export interface ILinkMatcher { matchIndex?: number; validationCallback?: LinkMatcherValidationCallback; priority?: number; + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface ICharset { @@ -321,6 +322,13 @@ export interface ILinkMatcherOptions { * default value is 0. */ priority?: number; + /** + * A callback that fires when the mousedown and click events occur that + * determines whether a link will be activated upon click. This enables + * only activating a link when a certain modifier is held down, if not the + * mouse event will continue propagation (eg. double click to select word). + */ + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IBrowser { diff --git a/src/input/MouseZoneManager.ts b/src/input/MouseZoneManager.ts index 98377f36..79c02b5f 100644 --- a/src/input/MouseZoneManager.ts +++ b/src/input/MouseZoneManager.ts @@ -151,10 +151,10 @@ export class MouseZoneManager implements IMouseZoneManager { // components from handling the mouse event. const zone = this._findZoneEventAt(e); if (zone) { - // TODO: When link modifier support is added, the event should only be - // cancelled when the modifier is held (see #1021) - e.preventDefault(); - e.stopImmediatePropagation(); + if (zone.willLinkActivate(e)) { + e.preventDefault(); + e.stopImmediatePropagation(); + } } } @@ -189,9 +189,10 @@ export class MouseZone implements IMouseZone { public x2: number, public y: number, public clickCallback: (e: MouseEvent) => any, - public hoverCallback?: (e: MouseEvent) => any, - public tooltipCallback?: (e: MouseEvent) => any, - public leaveCallback?: () => void + public hoverCallback: (e: MouseEvent) => any, + public tooltipCallback: (e: MouseEvent) => any, + public leaveCallback: () => void, + public willLinkActivate: (e: MouseEvent) => boolean ) { } } diff --git a/src/input/Types.ts b/src/input/Types.ts index 21514a53..f1398464 100644 --- a/src/input/Types.ts +++ b/src/input/Types.ts @@ -13,7 +13,8 @@ export interface IMouseZone { x2: number; y: number; clickCallback: (e: MouseEvent) => any; - hoverCallback?: (e: MouseEvent) => any; - tooltipCallback?: (e: MouseEvent) => any; - leaveCallback?: () => any; + hoverCallback: (e: MouseEvent) => any | undefined; + tooltipCallback: (e: MouseEvent) => any | undefined; + leaveCallback: () => any | undefined; + willLinkActivate: (e: MouseEvent) => boolean; } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 0b35edf1..2f6b4cd8 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -174,8 +174,8 @@ declare module 'xterm' { matchIndex?: number; /** - * A callback that validates an individual link, returning true if valid and - * false if invalid. + * A callback that validates whether to create an individual link, pass + * whether the link is valid to the callback. */ validationCallback?: (uri: string, callback: (isValid: boolean) => void) => void; @@ -196,6 +196,14 @@ declare module 'xterm' { * default value is 0. */ priority?: number; + + /** + * A callback that fires when the mousedown and click events occur that + * determines whether a link will be activated upon click. This enables + * only activating a link when a certain modifier is held down, if not the + * mouse event will continue propagation (eg. double click to select word). + */ + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IEventEmitter { From 04ccb638b44b2b8fd5f4dbba1e8138cc8b500db7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 1 Feb 2018 11:28:56 -0800 Subject: [PATCH 2/2] Fix lint --- src/Types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Types.ts b/src/Types.ts index 9dd7dda2..c8433707 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -328,7 +328,7 @@ export interface ILinkMatcherOptions { * only activating a link when a certain modifier is held down, if not the * mouse event will continue propagation (eg. double click to select word). */ - willLinkActivate?: (event: MouseEvent, uri: string) => boolean; + willLinkActivate?: (event: MouseEvent, uri: string) => boolean; } export interface IBrowser {