X-Git-Url: https://git.josue.xyz/?p=VSoRC%2F.git;a=blobdiff_plain;f=node_modules%2Fxterm%2Fsrc%2Fbrowser%2Frenderer%2FCharacterJoinerRegistry.ts;fp=node_modules%2Fxterm%2Fsrc%2Fbrowser%2Frenderer%2FCharacterJoinerRegistry.ts;h=0000000000000000000000000000000000000000;hp=5385b76b4231dc2f4c5fb7af36432994ea68e4c7;hb=5e96dd57ddd883604e87f62bdddcb111c63a6e1a;hpb=acb5f682a2b75b972710cabd81658f63071324b0 diff --git a/node_modules/xterm/src/browser/renderer/CharacterJoinerRegistry.ts b/node_modules/xterm/src/browser/renderer/CharacterJoinerRegistry.ts deleted file mode 100644 index 5385b76..0000000 --- a/node_modules/xterm/src/browser/renderer/CharacterJoinerRegistry.ts +++ /dev/null @@ -1,326 +0,0 @@ -/** - * Copyright (c) 2018 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { IBufferLine, ICellData, CharData } from 'common/Types'; -import { ICharacterJoinerRegistry, ICharacterJoiner } from 'browser/renderer/Types'; -import { AttributeData } from 'common/buffer/AttributeData'; -import { WHITESPACE_CELL_CHAR, Content } from 'common/buffer/Constants'; -import { CellData } from 'common/buffer/CellData'; -import { IBufferService } from 'common/services/Services'; - -export class JoinedCellData extends AttributeData implements ICellData { - private _width: number; - // .content carries no meaning for joined CellData, simply nullify it - // thus we have to overload all other .content accessors - public content: number = 0; - public fg: number; - public bg: number; - public combinedData: string = ''; - - constructor(firstCell: ICellData, chars: string, width: number) { - super(); - this.fg = firstCell.fg; - this.bg = firstCell.bg; - this.combinedData = chars; - this._width = width; - } - - public isCombined(): number { - // always mark joined cell data as combined - return Content.IS_COMBINED_MASK; - } - - public getWidth(): number { - return this._width; - } - - public getChars(): string { - return this.combinedData; - } - - public getCode(): number { - // code always gets the highest possible fake codepoint (read as -1) - // this is needed as code is used by caches as identifier - return 0x1FFFFF; - } - - public setFromCharData(value: CharData): void { - throw new Error('not implemented'); - } - - public getAsCharData(): CharData { - return [this.fg, this.getChars(), this.getWidth(), this.getCode()]; - } -} - -export class CharacterJoinerRegistry implements ICharacterJoinerRegistry { - - private _characterJoiners: ICharacterJoiner[] = []; - private _nextCharacterJoinerId: number = 0; - private _workCell: CellData = new CellData(); - - constructor(private _bufferService: IBufferService) { } - - public registerCharacterJoiner(handler: (text: string) => [number, number][]): number { - const joiner: ICharacterJoiner = { - id: this._nextCharacterJoinerId++, - handler - }; - - this._characterJoiners.push(joiner); - return joiner.id; - } - - public deregisterCharacterJoiner(joinerId: number): boolean { - for (let i = 0; i < this._characterJoiners.length; i++) { - if (this._characterJoiners[i].id === joinerId) { - this._characterJoiners.splice(i, 1); - return true; - } - } - - return false; - } - - public getJoinedCharacters(row: number): [number, number][] { - if (this._characterJoiners.length === 0) { - return []; - } - - const line = this._bufferService.buffer.lines.get(row); - if (!line || line.length === 0) { - return []; - } - - const ranges: [number, number][] = []; - const lineStr = line.translateToString(true); - - // Because some cells can be represented by multiple javascript characters, - // we track the cell and the string indexes separately. This allows us to - // translate the string ranges we get from the joiners back into cell ranges - // for use when rendering - let rangeStartColumn = 0; - let currentStringIndex = 0; - let rangeStartStringIndex = 0; - let rangeAttrFG = line.getFg(0); - let rangeAttrBG = line.getBg(0); - - for (let x = 0; x < line.getTrimmedLength(); x++) { - line.loadCell(x, this._workCell); - - if (this._workCell.getWidth() === 0) { - // If this character is of width 0, skip it. - continue; - } - - // End of range - if (this._workCell.fg !== rangeAttrFG || this._workCell.bg !== rangeAttrBG) { - // If we ended up with a sequence of more than one character, - // look for ranges to join. - if (x - rangeStartColumn > 1) { - const joinedRanges = this._getJoinedRanges( - lineStr, - rangeStartStringIndex, - currentStringIndex, - line, - rangeStartColumn - ); - for (let i = 0; i < joinedRanges.length; i++) { - ranges.push(joinedRanges[i]); - } - } - - // Reset our markers for a new range. - rangeStartColumn = x; - rangeStartStringIndex = currentStringIndex; - rangeAttrFG = this._workCell.fg; - rangeAttrBG = this._workCell.bg; - } - - currentStringIndex += this._workCell.getChars().length || WHITESPACE_CELL_CHAR.length; - } - - // Process any trailing ranges. - if (this._bufferService.cols - rangeStartColumn > 1) { - const joinedRanges = this._getJoinedRanges( - lineStr, - rangeStartStringIndex, - currentStringIndex, - line, - rangeStartColumn - ); - for (let i = 0; i < joinedRanges.length; i++) { - ranges.push(joinedRanges[i]); - } - } - - return ranges; - } - - /** - * Given a segment of a line of text, find all ranges of text that should be - * joined in a single rendering unit. Ranges are internally converted to - * column ranges, rather than string ranges. - * @param line String representation of the full line of text - * @param startIndex Start position of the range to search in the string (inclusive) - * @param endIndex End position of the range to search in the string (exclusive) - */ - private _getJoinedRanges(line: string, startIndex: number, endIndex: number, lineData: IBufferLine, startCol: number): [number, number][] { - const text = line.substring(startIndex, endIndex); - // At this point we already know that there is at least one joiner so - // we can just pull its value and assign it directly rather than - // merging it into an empty array, which incurs unnecessary writes. - const joinedRanges: [number, number][] = this._characterJoiners[0].handler(text); - for (let i = 1; i < this._characterJoiners.length; i++) { - // We merge any overlapping ranges across the different joiners - const joinerRanges = this._characterJoiners[i].handler(text); - for (let j = 0; j < joinerRanges.length; j++) { - CharacterJoinerRegistry._mergeRanges(joinedRanges, joinerRanges[j]); - } - } - this._stringRangesToCellRanges(joinedRanges, lineData, startCol); - return joinedRanges; - } - - /** - * Modifies the provided ranges in-place to adjust for variations between - * string length and cell width so that the range represents a cell range, - * rather than the string range the joiner provides. - * @param ranges String ranges containing start (inclusive) and end (exclusive) index - * @param line Cell data for the relevant line in the terminal - * @param startCol Offset within the line to start from - */ - private _stringRangesToCellRanges(ranges: [number, number][], line: IBufferLine, startCol: number): void { - let currentRangeIndex = 0; - let currentRangeStarted = false; - let currentStringIndex = 0; - let currentRange = ranges[currentRangeIndex]; - - // If we got through all of the ranges, stop searching - if (!currentRange) { - return; - } - - for (let x = startCol; x < this._bufferService.cols; x++) { - const width = line.getWidth(x); - const length = line.getString(x).length || WHITESPACE_CELL_CHAR.length; - - // We skip zero-width characters when creating the string to join the text - // so we do the same here - if (width === 0) { - continue; - } - - // Adjust the start of the range - if (!currentRangeStarted && currentRange[0] <= currentStringIndex) { - currentRange[0] = x; - currentRangeStarted = true; - } - - // Adjust the end of the range - if (currentRange[1] <= currentStringIndex) { - currentRange[1] = x; - - // We're finished with this range, so we move to the next one - currentRange = ranges[++currentRangeIndex]; - - // If there are no more ranges left, stop searching - if (!currentRange) { - break; - } - - // Ranges can be on adjacent characters. Because the end index of the - // ranges are exclusive, this means that the index for the start of a - // range can be the same as the end index of the previous range. To - // account for the start of the next range, we check here just in case. - if (currentRange[0] <= currentStringIndex) { - currentRange[0] = x; - currentRangeStarted = true; - } else { - currentRangeStarted = false; - } - } - - // Adjust the string index based on the character length to line up with - // the column adjustment - currentStringIndex += length; - } - - // If there is still a range left at the end, it must extend all the way to - // the end of the line. - if (currentRange) { - currentRange[1] = this._bufferService.cols; - } - } - - /** - * Merges the range defined by the provided start and end into the list of - * existing ranges. The merge is done in place on the existing range for - * performance and is also returned. - * @param ranges Existing range list - * @param newRange Tuple of two numbers representing the new range to merge in. - * @returns The ranges input with the new range merged in place - */ - private static _mergeRanges(ranges: [number, number][], newRange: [number, number]): [number, number][] { - let inRange = false; - for (let i = 0; i < ranges.length; i++) { - const range = ranges[i]; - if (!inRange) { - if (newRange[1] <= range[0]) { - // Case 1: New range is before the search range - ranges.splice(i, 0, newRange); - return ranges; - } - - if (newRange[1] <= range[1]) { - // Case 2: New range is either wholly contained within the - // search range or overlaps with the front of it - range[0] = Math.min(newRange[0], range[0]); - return ranges; - } - - if (newRange[0] < range[1]) { - // Case 3: New range either wholly contains the search range - // or overlaps with the end of it - range[0] = Math.min(newRange[0], range[0]); - inRange = true; - } - - // Case 4: New range starts after the search range - continue; - } else { - if (newRange[1] <= range[0]) { - // Case 5: New range extends from previous range but doesn't - // reach the current one - ranges[i - 1][1] = newRange[1]; - return ranges; - } - - if (newRange[1] <= range[1]) { - // Case 6: New range extends from prvious range into the - // current range - ranges[i - 1][1] = Math.max(newRange[1], range[1]); - ranges.splice(i, 1); - return ranges; - } - - // Case 7: New range extends from previous range past the - // end of the current range - ranges.splice(i, 1); - i--; - } - } - - if (inRange) { - // Case 8: New range extends past the last existing range - ranges[ranges.length - 1][1] = newRange[1]; - } else { - // Case 9: New range starts after the last existing range - ranges.push(newRange); - } - - return ranges; - } -}