aboutsummaryrefslogtreecommitdiffstats
path: root/node_modules/xterm/src/browser/input
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2022-03-23 14:04:55 -0500
committerToby Vincent <tobyv13@gmail.com>2022-03-23 14:15:18 -0500
commit8e36499326e969c7c34ecc537e589bd5ef5598a0 (patch)
tree7943cda837324847875d472d2ad68922c5019a50 /node_modules/xterm/src/browser/input
parent337fa04fe3686e0f0d236eef5df89179ee68f673 (diff)
chore: removed node_modules from git
Diffstat (limited to 'node_modules/xterm/src/browser/input')
-rw-r--r--node_modules/xterm/src/browser/input/CompositionHelper.ts237
-rw-r--r--node_modules/xterm/src/browser/input/Mouse.ts58
-rw-r--r--node_modules/xterm/src/browser/input/MoveToCell.ts249
3 files changed, 0 insertions, 544 deletions
diff --git a/node_modules/xterm/src/browser/input/CompositionHelper.ts b/node_modules/xterm/src/browser/input/CompositionHelper.ts
deleted file mode 100644
index 61051b5..0000000
--- a/node_modules/xterm/src/browser/input/CompositionHelper.ts
+++ /dev/null
@@ -1,237 +0,0 @@
-/**
- * Copyright (c) 2016 The xterm.js authors. All rights reserved.
- * @license MIT
- */
-
-import { IRenderService } from 'browser/services/Services';
-import { IBufferService, ICoreService, IOptionsService } from 'common/services/Services';
-
-interface IPosition {
- start: number;
- end: number;
-}
-
-/**
- * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend
- * events, displaying the in-progress composition to the UI and forwarding the final composition
- * to the handler.
- */
-export class CompositionHelper {
- /**
- * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or
- * IME. This variable determines whether the compositionText should be displayed on the UI.
- */
- private _isComposing: boolean;
- public get isComposing(): boolean { return this._isComposing; }
-
- /**
- * The position within the input textarea's value of the current composition.
- */
- private _compositionPosition: IPosition;
-
- /**
- * Whether a composition is in the process of being sent, setting this to false will cancel any
- * in-progress composition.
- */
- private _isSendingComposition: boolean;
-
- /**
- * Data already sent due to keydown event.
- */
- private _dataAlreadySent: string;
-
- constructor(
- private readonly _textarea: HTMLTextAreaElement,
- private readonly _compositionView: HTMLElement,
- @IBufferService private readonly _bufferService: IBufferService,
- @IOptionsService private readonly _optionsService: IOptionsService,
- @ICoreService private readonly _coreService: ICoreService,
- @IRenderService private readonly _renderService: IRenderService
- ) {
- this._isComposing = false;
- this._isSendingComposition = false;
- this._compositionPosition = { start: 0, end: 0 };
- this._dataAlreadySent = '';
- }
-
- /**
- * Handles the compositionstart event, activating the composition view.
- */
- public compositionstart(): void {
- this._isComposing = true;
- this._compositionPosition.start = this._textarea.value.length;
- this._compositionView.textContent = '';
- this._dataAlreadySent = '';
- this._compositionView.classList.add('active');
- }
-
- /**
- * Handles the compositionupdate event, updating the composition view.
- * @param ev The event.
- */
- public compositionupdate(ev: Pick<CompositionEvent, 'data'>): void {
- this._compositionView.textContent = ev.data;
- this.updateCompositionElements();
- setTimeout(() => {
- this._compositionPosition.end = this._textarea.value.length;
- }, 0);
- }
-
- /**
- * Handles the compositionend event, hiding the composition view and sending the composition to
- * the handler.
- */
- public compositionend(): void {
- this._finalizeComposition(true);
- }
-
- /**
- * Handles the keydown event, routing any necessary events to the CompositionHelper functions.
- * @param ev The keydown event.
- * @return Whether the Terminal should continue processing the keydown event.
- */
- public keydown(ev: KeyboardEvent): boolean {
- if (this._isComposing || this._isSendingComposition) {
- if (ev.keyCode === 229) {
- // Continue composing if the keyCode is the "composition character"
- return false;
- }
- if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {
- // Continue composing if the keyCode is a modifier key
- return false;
- }
- // Finish composition immediately. This is mainly here for the case where enter is
- // pressed and the handler needs to be triggered before the command is executed.
- this._finalizeComposition(false);
- }
-
- if (ev.keyCode === 229) {
- // If the "composition character" is used but gets to this point it means a non-composition
- // character (eg. numbers and punctuation) was pressed when the IME was active.
- this._handleAnyTextareaChanges();
- return false;
- }
-
- return true;
- }
-
- /**
- * Finalizes the composition, resuming regular input actions. This is called when a composition
- * is ending.
- * @param waitForPropagation Whether to wait for events to propagate before sending
- * the input. This should be false if a non-composition keystroke is entered before the
- * compositionend event is triggered, such as enter, so that the composition is sent before
- * the command is executed.
- */
- private _finalizeComposition(waitForPropagation: boolean): void {
- this._compositionView.classList.remove('active');
- this._isComposing = false;
-
- if (!waitForPropagation) {
- // Cancel any delayed composition send requests and send the input immediately.
- this._isSendingComposition = false;
- const input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);
- this._coreService.triggerDataEvent(input, true);
- } else {
- // Make a deep copy of the composition position here as a new compositionstart event may
- // fire before the setTimeout executes.
- const currentCompositionPosition = {
- start: this._compositionPosition.start,
- end: this._compositionPosition.end
- };
-
- // Since composition* events happen before the changes take place in the textarea on most
- // browsers, use a setTimeout with 0ms time to allow the native compositionend event to
- // complete. This ensures the correct character is retrieved.
- // This solution was used because:
- // - The compositionend event's data property is unreliable, at least on Chromium
- // - The last compositionupdate event's data property does not always accurately describe
- // the character, a counter example being Korean where an ending consonsant can move to
- // the following character if the following input is a vowel.
- this._isSendingComposition = true;
- setTimeout(() => {
- // Ensure that the input has not already been sent
- if (this._isSendingComposition) {
- this._isSendingComposition = false;
- let input;
- // Add length of data already sent due to keydown event,
- // otherwise input characters can be duplicated. (Issue #3191)
- currentCompositionPosition.start += this._dataAlreadySent.length;
- if (this._isComposing) {
- // Use the end position to get the string if a new composition has started.
- input = this._textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);
- } else {
- // Don't use the end position here in order to pick up any characters after the
- // composition has finished, for example when typing a non-composition character
- // (eg. 2) after a composition character.
- input = this._textarea.value.substring(currentCompositionPosition.start);
- }
- if (input.length > 0) {
- this._coreService.triggerDataEvent(input, true);
- }
- }
- }, 0);
- }
- }
-
- /**
- * Apply any changes made to the textarea after the current event chain is allowed to complete.
- * This should be called when not currently composing but a keydown event with the "composition
- * character" (229) is triggered, in order to allow non-composition text to be entered when an
- * IME is active.
- */
- private _handleAnyTextareaChanges(): void {
- const oldValue = this._textarea.value;
- setTimeout(() => {
- // Ignore if a composition has started since the timeout
- if (!this._isComposing) {
- const newValue = this._textarea.value;
- const diff = newValue.replace(oldValue, '');
- if (diff.length > 0) {
- this._dataAlreadySent = diff;
- this._coreService.triggerDataEvent(diff, true);
- }
- }
- }, 0);
- }
-
- /**
- * Positions the composition view on top of the cursor and the textarea just below it (so the
- * IME helper dialog is positioned correctly).
- * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is
- * necessary as the IME events across browsers are not consistently triggered.
- */
- public updateCompositionElements(dontRecurse?: boolean): void {
- if (!this._isComposing) {
- return;
- }
-
- if (this._bufferService.buffer.isCursorInViewport) {
- const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);
-
- const cellHeight = this._renderService.dimensions.actualCellHeight;
- const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.actualCellHeight;
- const cursorLeft = cursorX * this._renderService.dimensions.actualCellWidth;
-
- this._compositionView.style.left = cursorLeft + 'px';
- this._compositionView.style.top = cursorTop + 'px';
- this._compositionView.style.height = cellHeight + 'px';
- this._compositionView.style.lineHeight = cellHeight + 'px';
- this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;
- this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';
- // Sync the textarea to the exact position of the composition view so the IME knows where the
- // text is.
- const compositionViewBounds = this._compositionView.getBoundingClientRect();
- this._textarea.style.left = cursorLeft + 'px';
- this._textarea.style.top = cursorTop + 'px';
- // Ensure the text area is at least 1x1, otherwise certain IMEs may break
- this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';
- this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';
- this._textarea.style.lineHeight = compositionViewBounds.height + 'px';
- }
-
- if (!dontRecurse) {
- setTimeout(() => this.updateCompositionElements(true), 0);
- }
- }
-}
diff --git a/node_modules/xterm/src/browser/input/Mouse.ts b/node_modules/xterm/src/browser/input/Mouse.ts
deleted file mode 100644
index 2986fb3..0000000
--- a/node_modules/xterm/src/browser/input/Mouse.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Copyright (c) 2017 The xterm.js authors. All rights reserved.
- * @license MIT
- */
-
-export function getCoordsRelativeToElement(event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {
- const rect = element.getBoundingClientRect();
- return [event.clientX - rect.left, event.clientY - rect.top];
-}
-
-/**
- * Gets coordinates within the terminal for a particular mouse event. The result
- * is returned as an array in the form [x, y] instead of an object as it's a
- * little faster and this function is used in some low level code.
- * @param event The mouse event.
- * @param element The terminal's container element.
- * @param colCount The number of columns in the terminal.
- * @param rowCount The number of rows n the terminal.
- * @param isSelection Whether the request is for the selection or not. This will
- * apply an offset to the x value such that the left half of the cell will
- * select that cell and the right half will select the next cell.
- */
-export function getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, actualCellWidth: number, actualCellHeight: number, isSelection?: boolean): [number, number] | undefined {
- // Coordinates cannot be measured if there are no valid
- if (!hasValidCharSize) {
- return undefined;
- }
-
- const coords = getCoordsRelativeToElement(event, element);
- if (!coords) {
- return undefined;
- }
-
- coords[0] = Math.ceil((coords[0] + (isSelection ? actualCellWidth / 2 : 0)) / actualCellWidth);
- coords[1] = Math.ceil(coords[1] / actualCellHeight);
-
- // Ensure coordinates are within the terminal viewport. Note that selections
- // need an addition point of precision to cover the end point (as characters
- // cover half of one char and half of the next).
- coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));
- coords[1] = Math.min(Math.max(coords[1], 1), rowCount);
-
- return coords;
-}
-
-/**
- * Gets coordinates within the terminal for a particular mouse event, wrapping
- * them to the bounds of the terminal and adding 32 to both the x and y values
- * as expected by xterm.
- */
-export function getRawByteCoords(coords: [number, number] | undefined): { x: number, y: number } | undefined {
- if (!coords) {
- return undefined;
- }
-
- // xterm sends raw bytes and starts at 32 (SP) for each.
- return { x: coords[0] + 32, y: coords[1] + 32 };
-}
diff --git a/node_modules/xterm/src/browser/input/MoveToCell.ts b/node_modules/xterm/src/browser/input/MoveToCell.ts
deleted file mode 100644
index 82e767c..0000000
--- a/node_modules/xterm/src/browser/input/MoveToCell.ts
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * Copyright (c) 2018 The xterm.js authors. All rights reserved.
- * @license MIT
- */
-
-import { C0 } from 'common/data/EscapeSequences';
-import { IBufferService } from 'common/services/Services';
-
-const enum Direction {
- UP = 'A',
- DOWN = 'B',
- RIGHT = 'C',
- LEFT = 'D'
-}
-
-/**
- * Concatenates all the arrow sequences together.
- * Resets the starting row to an unwrapped row, moves to the requested row,
- * then moves to requested col.
- */
-export function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
- const startX = bufferService.buffer.x;
- const startY = bufferService.buffer.y;
-
- // The alt buffer should try to navigate between rows
- if (!bufferService.buffer.hasScrollback) {
- return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +
- moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +
- moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);
- }
-
- // Only move horizontally for the normal buffer
- let direction;
- if (startY === targetY) {
- direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;
- return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));
- }
- direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;
- const rowDifference = Math.abs(startY - targetY);
- const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +
- (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +
- colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);
- return repeat(cellsToMove, sequence(direction, applicationCursor));
-}
-
-/**
- * Find the number of cols from a row beginning to a col.
- */
-function colsFromRowBeginning(currX: number, bufferService: IBufferService): number {
- return currX - 1;
-}
-
-/**
- * Find the number of cols from a col to row end.
- */
-function colsFromRowEnd(currX: number, bufferService: IBufferService): number {
- return bufferService.cols - currX;
-}
-
-/**
- * If the initial position of the cursor is on a row that is wrapped, move the
- * cursor up to the first row that is not wrapped to have accurate vertical
- * positioning.
- */
-function resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
- if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {
- return '';
- }
- return repeat(bufferLine(
- startX, startY, startX,
- startY - wrappedRowsForRow(bufferService, startY), false, bufferService
- ).length, sequence(Direction.LEFT, applicationCursor));
-}
-
-/**
- * Using the reset starting and ending row, move to the requested row,
- * ignoring wrapped rows
- */
-function moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
- const startRow = startY - wrappedRowsForRow(bufferService, startY);
- const endRow = targetY - wrappedRowsForRow(bufferService, targetY);
-
- const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);
-
- return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));
-}
-
-/**
- * Move to the requested col on the ending row
- */
-function moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
- let startRow;
- if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {
- startRow = targetY - wrappedRowsForRow(bufferService, targetY);
- } else {
- startRow = startY;
- }
-
- const endRow = targetY;
- const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);
-
- return repeat(bufferLine(
- startX, startRow, targetX, endRow,
- direction === Direction.RIGHT, bufferService
- ).length, sequence(direction, applicationCursor));
-}
-
-/**
- * Utility functions
- */
-
-/**
- * Calculates the number of wrapped rows between the unwrapped starting and
- * ending rows. These rows need to ignored since the cursor skips over them.
- */
-function wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {
- let wrappedRows = 0;
- const startRow = startY - wrappedRowsForRow(bufferService, startY);
- const endRow = targetY - wrappedRowsForRow(bufferService, targetY);
-
- for (let i = 0; i < Math.abs(startRow - endRow); i++) {
- const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;
- const line = bufferService.buffer.lines.get(startRow + (direction * i));
- if (line?.isWrapped) {
- wrappedRows++;
- }
- }
-
- return wrappedRows;
-}
-
-/**
- * Calculates the number of wrapped rows that make up a given row.
- * @param currentRow The row to determine how many wrapped rows make it up
- */
-function wrappedRowsForRow(bufferService: IBufferService, currentRow: number): number {
- let rowCount = 0;
- let line = bufferService.buffer.lines.get(currentRow);
- let lineWraps = line?.isWrapped;
-
- while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {
- rowCount++;
- line = bufferService.buffer.lines.get(--currentRow);
- lineWraps = line?.isWrapped;
- }
-
- return rowCount;
-}
-
-/**
- * Direction determiners
- */
-
-/**
- * Determines if the right or left arrow is needed
- */
-function horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {
- let startRow;
- if (moveToRequestedRow(targetX, targetY, bufferService, applicationCursor).length > 0) {
- startRow = targetY - wrappedRowsForRow(bufferService, targetY);
- } else {
- startRow = startY;
- }
-
- if ((startX < targetX &&
- startRow <= targetY) || // down/right or same y/right
- (startX >= targetX &&
- startRow < targetY)) { // down/left or same y/left
- return Direction.RIGHT;
- }
- return Direction.LEFT;
-}
-
-/**
- * Determines if the up or down arrow is needed
- */
-function verticalDirection(startY: number, targetY: number): Direction {
- return startY > targetY ? Direction.UP : Direction.DOWN;
-}
-
-/**
- * Constructs the string of chars in the buffer from a starting row and col
- * to an ending row and col
- * @param startCol The starting column position
- * @param startRow The starting row position
- * @param endCol The ending column position
- * @param endRow The ending row position
- * @param forward Direction to move
- */
-function bufferLine(
- startCol: number,
- startRow: number,
- endCol: number,
- endRow: number,
- forward: boolean,
- bufferService: IBufferService
-): string {
- let currentCol = startCol;
- let currentRow = startRow;
- let bufferStr = '';
-
- while (currentCol !== endCol || currentRow !== endRow) {
- currentCol += forward ? 1 : -1;
-
- if (forward && currentCol > bufferService.cols - 1) {
- bufferStr += bufferService.buffer.translateBufferLineToString(
- currentRow, false, startCol, currentCol
- );
- currentCol = 0;
- startCol = 0;
- currentRow++;
- } else if (!forward && currentCol < 0) {
- bufferStr += bufferService.buffer.translateBufferLineToString(
- currentRow, false, 0, startCol + 1
- );
- currentCol = bufferService.cols - 1;
- startCol = currentCol;
- currentRow--;
- }
- }
-
- return bufferStr + bufferService.buffer.translateBufferLineToString(
- currentRow, false, startCol, currentCol
- );
-}
-
-/**
- * Constructs the escape sequence for clicking an arrow
- * @param direction The direction to move
- */
-function sequence(direction: Direction, applicationCursor: boolean): string {
- const mod = applicationCursor ? 'O' : '[';
- return C0.ESC + mod + direction;
-}
-
-/**
- * Returns a string repeated a given number of times
- * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
- * @param count The number of times to repeat the string
- * @param string The string that is to be repeated
- */
-function repeat(count: number, str: string): string {
- count = Math.floor(count);
- let rpt = '';
- for (let i = 0; i < count; i++) {
- rpt += str;
- }
- return rpt;
-}