diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-03-23 14:04:55 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-03-23 14:15:18 -0500 |
commit | 8e36499326e969c7c34ecc537e589bd5ef5598a0 (patch) | |
tree | 7943cda837324847875d472d2ad68922c5019a50 /node_modules/xterm/src/browser/Linkifier2.ts | |
parent | 337fa04fe3686e0f0d236eef5df89179ee68f673 (diff) |
chore: removed node_modules from git
Diffstat (limited to 'node_modules/xterm/src/browser/Linkifier2.ts')
-rw-r--r-- | node_modules/xterm/src/browser/Linkifier2.ts | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/node_modules/xterm/src/browser/Linkifier2.ts b/node_modules/xterm/src/browser/Linkifier2.ts deleted file mode 100644 index 8954293..0000000 --- a/node_modules/xterm/src/browser/Linkifier2.ts +++ /dev/null @@ -1,392 +0,0 @@ -/** - * Copyright (c) 2019 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { ILinkifier2, ILinkProvider, IBufferCellPosition, ILink, ILinkifierEvent, ILinkDecorations, ILinkWithState } from 'browser/Types'; -import { IDisposable } from 'common/Types'; -import { IMouseService, IRenderService } from './services/Services'; -import { IBufferService } from 'common/services/Services'; -import { EventEmitter, IEvent } from 'common/EventEmitter'; -import { Disposable, getDisposeArrayDisposable, disposeArray } from 'common/Lifecycle'; -import { addDisposableDomListener } from 'browser/Lifecycle'; - -export class Linkifier2 extends Disposable implements ILinkifier2 { - private _element: HTMLElement | undefined; - private _mouseService: IMouseService | undefined; - private _renderService: IRenderService | undefined; - private _linkProviders: ILinkProvider[] = []; - public get currentLink(): ILinkWithState | undefined { return this._currentLink; } - protected _currentLink: ILinkWithState | undefined; - private _lastMouseEvent: MouseEvent | undefined; - private _linkCacheDisposables: IDisposable[] = []; - private _lastBufferCell: IBufferCellPosition | undefined; - private _isMouseOut: boolean = true; - private _activeProviderReplies: Map<Number, ILinkWithState[] | undefined> | undefined; - private _activeLine: number = -1; - - private _onShowLinkUnderline = this.register(new EventEmitter<ILinkifierEvent>()); - public get onShowLinkUnderline(): IEvent<ILinkifierEvent> { return this._onShowLinkUnderline.event; } - private _onHideLinkUnderline = this.register(new EventEmitter<ILinkifierEvent>()); - public get onHideLinkUnderline(): IEvent<ILinkifierEvent> { return this._onHideLinkUnderline.event; } - - constructor( - @IBufferService private readonly _bufferService: IBufferService - ) { - super(); - this.register(getDisposeArrayDisposable(this._linkCacheDisposables)); - } - - public registerLinkProvider(linkProvider: ILinkProvider): IDisposable { - this._linkProviders.push(linkProvider); - return { - dispose: () => { - // Remove the link provider from the list - const providerIndex = this._linkProviders.indexOf(linkProvider); - - if (providerIndex !== -1) { - this._linkProviders.splice(providerIndex, 1); - } - } - }; - } - - public attachToDom(element: HTMLElement, mouseService: IMouseService, renderService: IRenderService): void { - this._element = element; - this._mouseService = mouseService; - this._renderService = renderService; - - this.register(addDisposableDomListener(this._element, 'mouseleave', () => { - this._isMouseOut = true; - this._clearCurrentLink(); - })); - this.register(addDisposableDomListener(this._element, 'mousemove', this._onMouseMove.bind(this))); - this.register(addDisposableDomListener(this._element, 'click', this._onClick.bind(this))); - } - - private _onMouseMove(event: MouseEvent): void { - this._lastMouseEvent = event; - - if (!this._element || !this._mouseService) { - return; - } - - const position = this._positionFromMouseEvent(event, this._element, this._mouseService); - if (!position) { - return; - } - this._isMouseOut = false; - - // Ignore the event if it's an embedder created hover widget - const composedPath = event.composedPath() as HTMLElement[]; - for (let i = 0; i < composedPath.length; i++) { - const target = composedPath[i]; - // Hit Terminal.element, break and continue - if (target.classList.contains('xterm')) { - break; - } - // It's a hover, don't respect hover event - if (target.classList.contains('xterm-hover')) { - return; - } - } - - if (!this._lastBufferCell || (position.x !== this._lastBufferCell.x || position.y !== this._lastBufferCell.y)) { - this._onHover(position); - this._lastBufferCell = position; - } - } - - private _onHover(position: IBufferCellPosition): void { - // TODO: This currently does not cache link provider results across wrapped lines, activeLine should be something like `activeRange: {startY, endY}` - // Check if we need to clear the link - if (this._activeLine !== position.y) { - this._clearCurrentLink(); - this._askForLink(position, false); - return; - } - - // Check the if the link is in the mouse position - const isCurrentLinkInPosition = this._currentLink && this._linkAtPosition(this._currentLink.link, position); - if (!isCurrentLinkInPosition) { - this._clearCurrentLink(); - this._askForLink(position, true); - } - } - - private _askForLink(position: IBufferCellPosition, useLineCache: boolean): void { - if (!this._activeProviderReplies || !useLineCache) { - this._activeProviderReplies?.forEach(reply => { - reply?.forEach(linkWithState => { - if (linkWithState.link.dispose) { - linkWithState.link.dispose(); - } - }); - }); - this._activeProviderReplies = new Map(); - this._activeLine = position.y; - } - let linkProvided = false; - - // There is no link cached, so ask for one - this._linkProviders.forEach((linkProvider, i) => { - if (useLineCache) { - const existingReply = this._activeProviderReplies?.get(i); - // If there isn't a reply, the provider hasn't responded yet. - - // TODO: If there isn't a reply yet it means that the provider is still resolving. Ensuring - // provideLinks isn't triggered again saves ILink.hover firing twice though. This probably - // needs promises to get fixed - if (existingReply) { - linkProvided = this._checkLinkProviderResult(i, position, linkProvided); - } - } else { - linkProvider.provideLinks(position.y, (links: ILink[] | undefined) => { - if (this._isMouseOut) { - return; - } - const linksWithState: ILinkWithState[] | undefined = links?.map(link => ({ link })); - this._activeProviderReplies?.set(i, linksWithState); - linkProvided = this._checkLinkProviderResult(i, position, linkProvided); - - // If all providers have responded, remove lower priority links that intersect ranges of - // higher priority links - if (this._activeProviderReplies?.size === this._linkProviders.length) { - this._removeIntersectingLinks(position.y, this._activeProviderReplies); - } - }); - } - }); - } - - private _removeIntersectingLinks(y: number, replies: Map<Number, ILinkWithState[] | undefined>): void { - const occupiedCells = new Set<number>(); - for (let i = 0; i < replies.size; i++) { - const providerReply = replies.get(i); - if (!providerReply) { - continue; - } - for (let i = 0; i < providerReply.length; i++) { - const linkWithState = providerReply[i]; - const startX = linkWithState.link.range.start.y < y ? 0 : linkWithState.link.range.start.x; - const endX = linkWithState.link.range.end.y > y ? this._bufferService.cols : linkWithState.link.range.end.x; - for (let x = startX; x <= endX; x++) { - if (occupiedCells.has(x)) { - providerReply.splice(i--, 1); - break; - } - occupiedCells.add(x); - } - } - } - } - - private _checkLinkProviderResult(index: number, position: IBufferCellPosition, linkProvided: boolean): boolean { - if (!this._activeProviderReplies) { - return linkProvided; - } - - const links = this._activeProviderReplies.get(index); - - // Check if every provider before this one has come back undefined - let hasLinkBefore = false; - for (let j = 0; j < index; j++) { - if (!this._activeProviderReplies.has(j) || this._activeProviderReplies.get(j)) { - hasLinkBefore = true; - } - } - - // If all providers with higher priority came back undefined, then this provider's link for - // the position should be used - if (!hasLinkBefore && links) { - const linkAtPosition = links.find(link => this._linkAtPosition(link.link, position)); - if (linkAtPosition) { - linkProvided = true; - this._handleNewLink(linkAtPosition); - } - } - - // Check if all the providers have responded - if (this._activeProviderReplies.size === this._linkProviders.length && !linkProvided) { - // Respect the order of the link providers - for (let j = 0; j < this._activeProviderReplies.size; j++) { - const currentLink = this._activeProviderReplies.get(j)?.find(link => this._linkAtPosition(link.link, position)); - if (currentLink) { - linkProvided = true; - this._handleNewLink(currentLink); - break; - } - } - } - - return linkProvided; - } - - private _onClick(event: MouseEvent): void { - if (!this._element || !this._mouseService || !this._currentLink) { - return; - } - - const position = this._positionFromMouseEvent(event, this._element, this._mouseService); - - if (!position) { - return; - } - - if (this._linkAtPosition(this._currentLink.link, position)) { - this._currentLink.link.activate(event, this._currentLink.link.text); - } - } - - private _clearCurrentLink(startRow?: number, endRow?: number): void { - if (!this._element || !this._currentLink || !this._lastMouseEvent) { - return; - } - - // If we have a start and end row, check that the link is within it - if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) { - this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent); - this._currentLink = undefined; - disposeArray(this._linkCacheDisposables); - } - } - - private _handleNewLink(linkWithState: ILinkWithState): void { - if (!this._element || !this._lastMouseEvent || !this._mouseService) { - return; - } - - const position = this._positionFromMouseEvent(this._lastMouseEvent, this._element, this._mouseService); - - if (!position) { - return; - } - - // Trigger hover if the we have a link at the position - if (this._linkAtPosition(linkWithState.link, position)) { - this._currentLink = linkWithState; - this._currentLink.state = { - decorations: { - underline: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.underline, - pointerCursor: linkWithState.link.decorations === undefined ? true : linkWithState.link.decorations.pointerCursor - }, - isHovered: true - }; - this._linkHover(this._element, linkWithState.link, this._lastMouseEvent); - - // Add listener for tracking decorations changes - linkWithState.link.decorations = {} as ILinkDecorations; - Object.defineProperties(linkWithState.link.decorations, { - pointerCursor: { - get: () => this._currentLink?.state?.decorations.pointerCursor, - set: v => { - if (this._currentLink?.state && this._currentLink.state.decorations.pointerCursor !== v) { - this._currentLink.state.decorations.pointerCursor = v; - if (this._currentLink.state.isHovered) { - this._element?.classList.toggle('xterm-cursor-pointer', v); - } - } - } - }, - underline: { - get: () => this._currentLink?.state?.decorations.underline, - set: v => { - if (this._currentLink?.state && this._currentLink?.state?.decorations.underline !== v) { - this._currentLink.state.decorations.underline = v; - if (this._currentLink.state.isHovered) { - this._fireUnderlineEvent(linkWithState.link, v); - } - } - } - } - }); - - // Add listener for rerendering - if (this._renderService) { - this._linkCacheDisposables.push(this._renderService.onRenderedBufferChange(e => { - // When start is 0 a scroll most likely occurred, make sure links above the fold also get - // cleared. - const start = e.start === 0 ? 0 : e.start + 1 + this._bufferService.buffer.ydisp; - this._clearCurrentLink(start, e.end + 1 + this._bufferService.buffer.ydisp); - })); - } - } - } - - protected _linkHover(element: HTMLElement, link: ILink, event: MouseEvent): void { - if (this._currentLink?.state) { - this._currentLink.state.isHovered = true; - if (this._currentLink.state.decorations.underline) { - this._fireUnderlineEvent(link, true); - } - if (this._currentLink.state.decorations.pointerCursor) { - element.classList.add('xterm-cursor-pointer'); - } - } - - if (link.hover) { - link.hover(event, link.text); - } - } - - private _fireUnderlineEvent(link: ILink, showEvent: boolean): void { - const range = link.range; - const scrollOffset = this._bufferService.buffer.ydisp; - const event = this._createLinkUnderlineEvent(range.start.x - 1, range.start.y - scrollOffset - 1, range.end.x, range.end.y - scrollOffset - 1, undefined); - const emitter = showEvent ? this._onShowLinkUnderline : this._onHideLinkUnderline; - emitter.fire(event); - } - - protected _linkLeave(element: HTMLElement, link: ILink, event: MouseEvent): void { - if (this._currentLink?.state) { - this._currentLink.state.isHovered = false; - if (this._currentLink.state.decorations.underline) { - this._fireUnderlineEvent(link, false); - } - if (this._currentLink.state.decorations.pointerCursor) { - element.classList.remove('xterm-cursor-pointer'); - } - } - - if (link.leave) { - link.leave(event, link.text); - } - } - - /** - * Check if the buffer position is within the link - * @param link - * @param position - */ - private _linkAtPosition(link: ILink, position: IBufferCellPosition): boolean { - const sameLine = link.range.start.y === link.range.end.y; - const wrappedFromLeft = link.range.start.y < position.y; - const wrappedToRight = link.range.end.y > position.y; - - // If the start and end have the same y, then the position must be between start and end x - // If not, then handle each case seperately, depending on which way it wraps - return ((sameLine && link.range.start.x <= position.x && link.range.end.x >= position.x) || - (wrappedFromLeft && link.range.end.x >= position.x) || - (wrappedToRight && link.range.start.x <= position.x) || - (wrappedFromLeft && wrappedToRight)) && - link.range.start.y <= position.y && - link.range.end.y >= position.y; - } - - /** - * Get the buffer position from a mouse event - * @param event - */ - private _positionFromMouseEvent(event: MouseEvent, element: HTMLElement, mouseService: IMouseService): IBufferCellPosition | undefined { - const coords = mouseService.getCoords(event, element, this._bufferService.cols, this._bufferService.rows); - if (!coords) { - return; - } - - return { x: coords[0], y: coords[1] + this._bufferService.buffer.ydisp }; - } - - private _createLinkUnderlineEvent(x1: number, y1: number, x2: number, y2: number, fg: number | undefined): ILinkifierEvent { - return { x1, y1, x2, y2, cols: this._bufferService.cols, fg }; - } -} |