Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hover and leave callbacks for linkprovider #3233

Merged

Conversation

marvinthepa
Copy link
Contributor

Fixes #3056.

I guess this needs another breaking change when LinkMatchers are removed, to replace the ILinkMatcherOptions argument to the WebLinksAddon constructor with something not referring to LinkMatchers..

@@ -53,7 +53,7 @@ export class WebLinksAddon implements ITerminalAddon {
this._terminal = terminal;

if (this._useLinkProvider && 'registerLinkProvider' in this._terminal) {
this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, strictUrlRegex, this._handler));
this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, strictUrlRegex, this._handler, this._options));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better if we has link provider-specific options:

export interface ILinkProviderOptions {
  hover?(event: MouseEvent, text: string): void;
  leave?(event: MouseEvent, text: string): void;
}

...

private _options: ILinkMatcherOptions | ILinkProviderOptions = {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private _options: ILinkMatcherOptions | ILinkProviderOptions = {}

Do you want to allow both types as arguments on WebLinksAddon?
I am afraid my knowledge of typescript is not sufficient to get that to compile.

Or do you want to allow both as argument to WebLinksProvider?

As a suggestion, I will push an alternative that I could get working:
Converting from ILinkMatcherOptions to ILinkProviderOptions in WebLinksAddon.activate.
If you do not like that I am afraid I will need a little help.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think TS would fuss about this because all properties on both interfaces are optional, so essentially any object matches the interface, it should however provide nice intellisense when something is using the API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see the problem you were hitting now, I'll push a fix using a cast as it should be safe to do that since the interfaces only have optional props.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think TS would fuss about this because all properties on both interfaces are optional, so essentially any object matches the interface, it should however provide nice intellisense when something is using the API.

It did fuss about it in my experience 🙁.

E.g.:

  constructor(
    private _handler: (event: MouseEvent, uri: string) => void = handleLink,
    private _options: ILinkMatcherOptions | ILinkProviderOptions = {},
    private _useLinkProvider: boolean = false
  ) {
    this._options.matchIndex = 1; //  Property 'matchIndex' does not exist on type 'ILinkProviderOptions'.ts(2339)
  }

I will try to solve this in a different way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marvinthepa yeah that's what I ended up seeing, you can check the change I just pushed for an alright workaround

addons/xterm-addon-web-links/src/WebLinkProvider.ts Outdated Show resolved Hide resolved
addons/xterm-addon-web-links/src/WebLinkProvider.ts Outdated Show resolved Hide resolved
addons/xterm-addon-web-links/src/WebLinkProvider.ts Outdated Show resolved Hide resolved
@Tyriar Tyriar added this to the 4.11.0 milestone Feb 2, 2021
@marvinthepa marvinthepa force-pushed the 3056_hover_callback_link_providers branch from 5a965b1 to d08f2de Compare February 2, 2021 21:56
Comment on lines 56 to 59
const options = {
hover: this._options.tooltipCallback,
leave: this._options.leaveCallback
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When linkmatchers are removed, this can go and the ILinkMatcherOptions argument can be replaced by ILinkProviderOptions..

@marvinthepa marvinthepa force-pushed the 3056_hover_callback_link_providers branch from d08f2de to eec804d Compare February 3, 2021 09:25
@Tyriar Tyriar enabled auto-merge February 3, 2021 13:29
}

public activate(terminal: Terminal): void {
this._terminal = terminal;

if (this._useLinkProvider && 'registerLinkProvider' in this._terminal) {
this._linkProvider = this._terminal.registerLinkProvider(new WebLinkProvider(this._terminal, strictUrlRegex, this._handler));
const options = this._options as ILinkProviderOptions;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marvinthepa normally using as is bad, but it doesn't matter much here since the objects are definitely compatible.

} else {
// TODO: This should be removed eventually
this._linkMatcherId = (this._terminal as Terminal).registerLinkMatcher(strictUrlRegex, this._handler, this._options);
const options = this._options as ILinkMatcherOptions;
options.matchIndex = 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this here to avoid setting it when the object gets used for a link provider

@Tyriar Tyriar merged commit 2936f80 into xtermjs:master Feb 3, 2021
Comment on lines 56 to 60
const options = {
hover: this._options.tooltipCallback,
leave: this._options.leaveCallback
};
const options = this._options as ILinkProviderOptions;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew there was something about TS that I didn't know.

However, this will break clients that pass their callbacks as tooltipCallback and leaveCallback (instead of hover and leave, and then switch _useLinkProvider to true. Shouldn't there be at least a warning in this case?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine like this since link matchers should be going away soon.

TS wasn't as clever as I thought it was by not narrowing the options type when you enter in hover, which makes sense now that I think about it:

image

If people are confused about the API in the meantime, they can go into the types to view the definition and/or look at the object type in intellisense:

image

Passing the object as ILinkProviderOptions makes it act nicely:

image

I personally don't think it's worth adding warnings since link matchers are deprecated and it's such a simple addon API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add hover callback for LinkProviders
3 participants