mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Further merge and reduce
- Remove unused keyboardEvent module - Trim unused browserEvent in OnStopCallback - Inline single-use helpers to reduce module surface - Remove createFastDomNode wrapper
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from '../Dom';
|
||||
import { createFastDomNode, FastDomNode } from './fastDomNode';
|
||||
import { FastDomNode } from './fastDomNode';
|
||||
import { GlobalPointerMoveMonitor } from './globalPointerMoveMonitor';
|
||||
import { StandardWheelEvent } from './mouseEvent';
|
||||
import { ScrollbarArrow, IScrollbarArrowOptions } from './scrollbarArrow';
|
||||
@@ -67,7 +67,7 @@ export abstract class AbstractScrollbar extends Widget {
|
||||
this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());
|
||||
this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());
|
||||
this._shouldRender = true;
|
||||
this.domNode = createFastDomNode(document.createElement('div'));
|
||||
this.domNode = new FastDomNode(document.createElement('div'));
|
||||
this.domNode.setAttribute('role', 'presentation');
|
||||
this.domNode.setAttribute('aria-hidden', 'true');
|
||||
|
||||
@@ -92,7 +92,7 @@ export abstract class AbstractScrollbar extends Widget {
|
||||
* Creates the slider dom node, adds it to the container & hooks up the events
|
||||
*/
|
||||
protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {
|
||||
this.slider = createFastDomNode(document.createElement('div'));
|
||||
this.slider = new FastDomNode(document.createElement('div'));
|
||||
this.slider.setClassName('slider');
|
||||
this.slider.setPosition('absolute');
|
||||
this.slider.setTop(top);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
export function tail<T>(array: ArrayLike<T>, n: number = 0): T | undefined {
|
||||
return array[array.length - (1 + n)];
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export function memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {
|
||||
let fnKey: string | null = null;
|
||||
let fn: Function | null = null;
|
||||
|
||||
if (typeof descriptor.value === 'function') {
|
||||
fnKey = 'value';
|
||||
fn = descriptor.value;
|
||||
|
||||
if (fn!.length !== 0) {
|
||||
console.warn('Memoize should only be used in functions with zero parameters');
|
||||
}
|
||||
} else if (typeof descriptor.get === 'function') {
|
||||
fnKey = 'get';
|
||||
fn = descriptor.get;
|
||||
}
|
||||
|
||||
if (!fn) {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
const memoizeKey = `$memoize$${key}`;
|
||||
const descriptorAny = descriptor as { [key: string]: any };
|
||||
descriptorAny[fnKey!] = function (...args: any[]) {
|
||||
if (!this.hasOwnProperty(memoizeKey)) {
|
||||
Object.defineProperty(this, memoizeKey, {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: fn.apply(this, args)
|
||||
});
|
||||
}
|
||||
|
||||
return (this as { [key: string]: any })[memoizeKey];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -121,10 +121,6 @@ export class FastDomNode<T extends HTMLElement> {
|
||||
|
||||
}
|
||||
|
||||
export function createFastDomNode<T extends HTMLElement>(domNode: T): FastDomNode<T> {
|
||||
return new FastDomNode(domNode);
|
||||
}
|
||||
|
||||
function numberAsPixels(value: number | string): string {
|
||||
return (typeof value === 'number' ? `${value}px` : value);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as dom from '../Dom';
|
||||
import { DisposableStore, IDisposable, toDisposable } from 'common/Lifecycle';
|
||||
|
||||
type PointerMoveCallback = (event: PointerEvent) => void;
|
||||
type OnStopCallback = (browserEvent?: PointerEvent | KeyboardEvent) => void;
|
||||
type OnStopCallback = () => void;
|
||||
|
||||
export class GlobalPointerMoveMonitor implements IDisposable {
|
||||
|
||||
@@ -20,7 +20,7 @@ export class GlobalPointerMoveMonitor implements IDisposable {
|
||||
this._hooks.dispose();
|
||||
}
|
||||
|
||||
public stopMonitoring(invokeStopCallback: boolean, browserEvent?: PointerEvent | KeyboardEvent): void {
|
||||
public stopMonitoring(invokeStopCallback: boolean): void {
|
||||
if (!this.isMonitoring()) {
|
||||
return;
|
||||
}
|
||||
@@ -31,7 +31,7 @@ export class GlobalPointerMoveMonitor implements IDisposable {
|
||||
this._onStopCallback = null;
|
||||
|
||||
if (invokeStopCallback && onStopCallback) {
|
||||
onStopCallback(browserEvent);
|
||||
onStopCallback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Represents a window in a possible chain of iframes
|
||||
*/
|
||||
interface IWindowChainElement {
|
||||
/**
|
||||
* The window object for it
|
||||
*/
|
||||
readonly window: WeakRef<Window>;
|
||||
/**
|
||||
* The iframe element inside the window.parent corresponding to window
|
||||
*/
|
||||
readonly iframeElement: Element | null;
|
||||
}
|
||||
|
||||
const sameOriginWindowChainCache = new WeakMap<Window, IWindowChainElement[] | null>();
|
||||
|
||||
function getParentWindowIfSameOrigin(w: Window): Window | null {
|
||||
if (!w.parent || w.parent === w) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Cannot really tell if we have access to the parent window unless we try
|
||||
// to access something in it.
|
||||
try {
|
||||
const location = w.location;
|
||||
const parentLocation = w.parent.location;
|
||||
if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {
|
||||
return null;
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
return w.parent;
|
||||
}
|
||||
|
||||
export class IframeUtils {
|
||||
|
||||
/**
|
||||
* Returns a chain of embedded windows with the same origin.
|
||||
* The chain can be accessed programmatically.
|
||||
* Having a chain of length 1 might mean that the current execution environment is
|
||||
* running outside of an iframe or inside an iframe embedded in a window with a different origin.
|
||||
*/
|
||||
private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {
|
||||
let windowChainCache = sameOriginWindowChainCache.get(targetWindow);
|
||||
if (!windowChainCache) {
|
||||
windowChainCache = [];
|
||||
sameOriginWindowChainCache.set(targetWindow, windowChainCache);
|
||||
let w: Window | null = targetWindow;
|
||||
let parent: Window | null;
|
||||
do {
|
||||
parent = getParentWindowIfSameOrigin(w);
|
||||
if (parent) {
|
||||
windowChainCache.push({
|
||||
window: new WeakRef(w),
|
||||
iframeElement: w.frameElement ?? null
|
||||
});
|
||||
} else {
|
||||
windowChainCache.push({
|
||||
window: new WeakRef(w),
|
||||
iframeElement: null
|
||||
});
|
||||
}
|
||||
w = parent;
|
||||
} while (w);
|
||||
}
|
||||
return windowChainCache.slice(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position of `childWindow` relative to `ancestorWindow`
|
||||
*/
|
||||
public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {
|
||||
|
||||
if (!ancestorWindow || childWindow === ancestorWindow) {
|
||||
return {
|
||||
top: 0,
|
||||
left: 0
|
||||
};
|
||||
}
|
||||
|
||||
let top = 0; let left = 0;
|
||||
|
||||
const windowChain = this._getSameOriginWindowChain(childWindow);
|
||||
|
||||
for (const windowChainEl of windowChain) {
|
||||
const windowInChain = windowChainEl.window.deref();
|
||||
top += windowInChain?.scrollY ?? 0;
|
||||
left += windowInChain?.scrollX ?? 0;
|
||||
|
||||
if (windowInChain === ancestorWindow) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!windowChainEl.iframeElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();
|
||||
top += boundingRect.top;
|
||||
left += boundingRect.left;
|
||||
}
|
||||
|
||||
return {
|
||||
top: top,
|
||||
left: left
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a sha-256 composed of `parentOrigin` and `salt` converted to base 32
|
||||
*/
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
export interface IKeyboardEvent {
|
||||
readonly browserEvent: KeyboardEvent;
|
||||
readonly keyCode: number;
|
||||
readonly ctrlKey: boolean;
|
||||
readonly shiftKey: boolean;
|
||||
readonly altKey: boolean;
|
||||
readonly metaKey: boolean;
|
||||
readonly key: string;
|
||||
|
||||
preventDefault(): void;
|
||||
stopPropagation(): void;
|
||||
}
|
||||
|
||||
export class StandardKeyboardEvent implements IKeyboardEvent {
|
||||
public readonly browserEvent: KeyboardEvent;
|
||||
public readonly keyCode: number;
|
||||
public readonly ctrlKey: boolean;
|
||||
public readonly shiftKey: boolean;
|
||||
public readonly altKey: boolean;
|
||||
public readonly metaKey: boolean;
|
||||
public readonly key: string;
|
||||
|
||||
constructor(e: KeyboardEvent) {
|
||||
this.browserEvent = e;
|
||||
this.keyCode = (e.keyCode || (e as any).which || 0) as number;
|
||||
this.ctrlKey = e.ctrlKey;
|
||||
this.shiftKey = e.shiftKey;
|
||||
this.altKey = e.altKey;
|
||||
this.metaKey = e.metaKey;
|
||||
this.key = e.key || '';
|
||||
}
|
||||
|
||||
public preventDefault(): void {
|
||||
this.browserEvent.preventDefault();
|
||||
}
|
||||
|
||||
public stopPropagation(): void {
|
||||
this.browserEvent.stopPropagation();
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
class Node<E> {
|
||||
|
||||
public static readonly Undefined = new Node<any>(undefined);
|
||||
|
||||
public element: E;
|
||||
public next: Node<E>;
|
||||
public prev: Node<E>;
|
||||
|
||||
public constructor(element: E) {
|
||||
this.element = element;
|
||||
this.next = Node.Undefined;
|
||||
this.prev = Node.Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export class LinkedList<E> {
|
||||
|
||||
private _first: Node<E> = Node.Undefined;
|
||||
private _last: Node<E> = Node.Undefined;
|
||||
|
||||
public push(element: E): () => void {
|
||||
return this._insert(element, true);
|
||||
}
|
||||
|
||||
private _insert(element: E, atTheEnd: boolean): () => void {
|
||||
const newNode = new Node(element);
|
||||
if (this._first === Node.Undefined) {
|
||||
this._first = newNode;
|
||||
this._last = newNode;
|
||||
|
||||
} else if (atTheEnd) {
|
||||
// push
|
||||
const oldLast = this._last;
|
||||
this._last = newNode;
|
||||
newNode.prev = oldLast;
|
||||
oldLast.next = newNode;
|
||||
|
||||
} else {
|
||||
// unshift
|
||||
const oldFirst = this._first;
|
||||
this._first = newNode;
|
||||
newNode.next = oldFirst;
|
||||
oldFirst.prev = newNode;
|
||||
}
|
||||
let didRemove = false;
|
||||
return () => {
|
||||
if (!didRemove) {
|
||||
didRemove = true;
|
||||
this._remove(newNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _remove(node: Node<E>): void {
|
||||
if (node.prev !== Node.Undefined && node.next !== Node.Undefined) {
|
||||
// middle
|
||||
const anchor = node.prev;
|
||||
anchor.next = node.next;
|
||||
node.next.prev = anchor;
|
||||
|
||||
} else if (node.prev === Node.Undefined && node.next === Node.Undefined) {
|
||||
// only node
|
||||
this._first = Node.Undefined;
|
||||
this._last = Node.Undefined;
|
||||
|
||||
} else if (node.next === Node.Undefined) {
|
||||
// last
|
||||
this._last = this._last.prev!;
|
||||
this._last.next = Node.Undefined;
|
||||
|
||||
} else if (node.prev === Node.Undefined) {
|
||||
// first
|
||||
this._first = this._first.next!;
|
||||
this._first.prev = Node.Undefined;
|
||||
}
|
||||
|
||||
// done
|
||||
}
|
||||
|
||||
public *[Symbol.iterator](): Iterator<E> {
|
||||
let node = this._first;
|
||||
while (node !== Node.Undefined) {
|
||||
yield node.element;
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,100 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IframeUtils } from './iframe';
|
||||
import * as platform from 'common/Platform';
|
||||
|
||||
interface IWindowChainElement {
|
||||
readonly window: WeakRef<Window>;
|
||||
readonly iframeElement: Element | null;
|
||||
}
|
||||
|
||||
const sameOriginWindowChainCache = new WeakMap<Window, IWindowChainElement[] | null>();
|
||||
|
||||
function getParentWindowIfSameOrigin(w: Window): Window | null {
|
||||
if (!w.parent || w.parent === w) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const location = w.location;
|
||||
const parentLocation = w.parent.location;
|
||||
if (location.origin !== 'null' && parentLocation.origin !== 'null' && location.origin !== parentLocation.origin) {
|
||||
return null;
|
||||
}
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
||||
return w.parent;
|
||||
}
|
||||
|
||||
class IframeUtils {
|
||||
|
||||
private static _getSameOriginWindowChain(targetWindow: Window): IWindowChainElement[] {
|
||||
let windowChainCache = sameOriginWindowChainCache.get(targetWindow);
|
||||
if (!windowChainCache) {
|
||||
windowChainCache = [];
|
||||
sameOriginWindowChainCache.set(targetWindow, windowChainCache);
|
||||
let w: Window | null = targetWindow;
|
||||
let parent: Window | null;
|
||||
do {
|
||||
parent = getParentWindowIfSameOrigin(w);
|
||||
if (parent) {
|
||||
windowChainCache.push({
|
||||
window: new WeakRef(w),
|
||||
iframeElement: w.frameElement ?? null
|
||||
});
|
||||
} else {
|
||||
windowChainCache.push({
|
||||
window: new WeakRef(w),
|
||||
iframeElement: null
|
||||
});
|
||||
}
|
||||
w = parent;
|
||||
} while (w);
|
||||
}
|
||||
return windowChainCache.slice(0);
|
||||
}
|
||||
|
||||
public static getPositionOfChildWindowRelativeToAncestorWindow(childWindow: Window, ancestorWindow: Window | null): { top: number, left: number } {
|
||||
|
||||
if (!ancestorWindow || childWindow === ancestorWindow) {
|
||||
return {
|
||||
top: 0,
|
||||
left: 0
|
||||
};
|
||||
}
|
||||
|
||||
let top = 0;
|
||||
let left = 0;
|
||||
|
||||
const windowChain = this._getSameOriginWindowChain(childWindow);
|
||||
|
||||
for (const windowChainEl of windowChain) {
|
||||
const windowInChain = windowChainEl.window.deref();
|
||||
top += windowInChain?.scrollY ?? 0;
|
||||
left += windowInChain?.scrollX ?? 0;
|
||||
|
||||
if (windowInChain === ancestorWindow) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!windowChainEl.iframeElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
const boundingRect = windowChainEl.iframeElement.getBoundingClientRect();
|
||||
top += boundingRect.top;
|
||||
left += boundingRect.left;
|
||||
}
|
||||
|
||||
return {
|
||||
top: top,
|
||||
left: left
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface IMouseEvent {
|
||||
readonly browserEvent: MouseEvent;
|
||||
readonly leftButton: boolean;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from '../Dom';
|
||||
import { FastDomNode, createFastDomNode } from './fastDomNode';
|
||||
import { FastDomNode } from './fastDomNode';
|
||||
import { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from './mouseEvent';
|
||||
import { IScrollbarHost } from './abstractScrollbar';
|
||||
import { HorizontalScrollbar } from './horizontalScrollbar';
|
||||
@@ -227,15 +227,15 @@ export class SmoothScrollableElement extends Widget {
|
||||
this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);
|
||||
|
||||
if (this._options.useShadows) {
|
||||
this._leftShadowDomNode = createFastDomNode(document.createElement('div'));
|
||||
this._leftShadowDomNode = new FastDomNode(document.createElement('div'));
|
||||
this._leftShadowDomNode.setClassName('shadow');
|
||||
this._domNode.appendChild(this._leftShadowDomNode.domNode);
|
||||
|
||||
this._topShadowDomNode = createFastDomNode(document.createElement('div'));
|
||||
this._topShadowDomNode = new FastDomNode(document.createElement('div'));
|
||||
this._topShadowDomNode.setClassName('shadow');
|
||||
this._domNode.appendChild(this._topShadowDomNode.domNode);
|
||||
|
||||
this._topLeftShadowDomNode = createFastDomNode(document.createElement('div'));
|
||||
this._topLeftShadowDomNode = new FastDomNode(document.createElement('div'));
|
||||
this._topLeftShadowDomNode.setClassName('shadow');
|
||||
this._domNode.appendChild(this._topLeftShadowDomNode.domNode);
|
||||
} else {
|
||||
|
||||
+135
-17
@@ -4,11 +4,129 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as DomUtils from '../Dom';
|
||||
import { mainWindow } from './window';
|
||||
import * as arrays from './arrays';
|
||||
import { memoize } from './decorators';
|
||||
import { Disposable, IDisposable, toDisposable } from 'common/Lifecycle';
|
||||
import { LinkedList } from './linkedList';
|
||||
|
||||
const mainWindow = (typeof window === 'object' ? window : globalThis) as Window & typeof globalThis;
|
||||
|
||||
function tail<T>(array: ArrayLike<T>, n: number = 0): T | undefined {
|
||||
return array[array.length - (1 + n)];
|
||||
}
|
||||
|
||||
function memoize(_target: any, key: string, descriptor: PropertyDescriptor): void {
|
||||
let fnKey: string | null = null;
|
||||
let fn: Function | null = null;
|
||||
|
||||
if (typeof descriptor.value === 'function') {
|
||||
fnKey = 'value';
|
||||
fn = descriptor.value;
|
||||
|
||||
if (fn!.length !== 0) {
|
||||
console.warn('Memoize should only be used in functions with zero parameters');
|
||||
}
|
||||
} else if (typeof descriptor.get === 'function') {
|
||||
fnKey = 'get';
|
||||
fn = descriptor.get;
|
||||
}
|
||||
|
||||
if (!fn || !fnKey) {
|
||||
throw new Error('not supported');
|
||||
}
|
||||
|
||||
const memoizeKey = `$memoize$${key}`;
|
||||
const descriptorAny = descriptor as { [key: string]: any };
|
||||
descriptorAny[fnKey] = function (...args: any[]) {
|
||||
if (!this.hasOwnProperty(memoizeKey)) {
|
||||
Object.defineProperty(this, memoizeKey, {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: fn.apply(this, args)
|
||||
});
|
||||
}
|
||||
|
||||
return (this as { [key: string]: any })[memoizeKey];
|
||||
};
|
||||
}
|
||||
|
||||
class LinkedListNode<E> {
|
||||
|
||||
public static readonly Undefined = new LinkedListNode<any>(undefined);
|
||||
|
||||
public element: E;
|
||||
public next: LinkedListNode<E>;
|
||||
public prev: LinkedListNode<E>;
|
||||
|
||||
public constructor(element: E) {
|
||||
this.element = element;
|
||||
this.next = LinkedListNode.Undefined;
|
||||
this.prev = LinkedListNode.Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
class LinkedList<E> {
|
||||
|
||||
private _first: LinkedListNode<E> = LinkedListNode.Undefined;
|
||||
private _last: LinkedListNode<E> = LinkedListNode.Undefined;
|
||||
|
||||
public push(element: E): () => void {
|
||||
return this._insert(element, true);
|
||||
}
|
||||
|
||||
private _insert(element: E, atTheEnd: boolean): () => void {
|
||||
const newNode = new LinkedListNode(element);
|
||||
if (this._first === LinkedListNode.Undefined) {
|
||||
this._first = newNode;
|
||||
this._last = newNode;
|
||||
|
||||
} else if (atTheEnd) {
|
||||
const oldLast = this._last;
|
||||
this._last = newNode;
|
||||
newNode.prev = oldLast;
|
||||
oldLast.next = newNode;
|
||||
|
||||
} else {
|
||||
const oldFirst = this._first;
|
||||
this._first = newNode;
|
||||
newNode.next = oldFirst;
|
||||
oldFirst.prev = newNode;
|
||||
}
|
||||
let didRemove = false;
|
||||
return () => {
|
||||
if (!didRemove) {
|
||||
didRemove = true;
|
||||
this._remove(newNode);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _remove(node: LinkedListNode<E>): void {
|
||||
if (node.prev !== LinkedListNode.Undefined && node.next !== LinkedListNode.Undefined) {
|
||||
const anchor = node.prev;
|
||||
anchor.next = node.next;
|
||||
node.next.prev = anchor;
|
||||
|
||||
} else if (node.prev === LinkedListNode.Undefined && node.next === LinkedListNode.Undefined) {
|
||||
this._first = LinkedListNode.Undefined;
|
||||
this._last = LinkedListNode.Undefined;
|
||||
|
||||
} else if (node.next === LinkedListNode.Undefined) {
|
||||
this._last = this._last.prev!;
|
||||
this._last.next = LinkedListNode.Undefined;
|
||||
|
||||
} else if (node.prev === LinkedListNode.Undefined) {
|
||||
this._first = this._first.next!;
|
||||
this._first.prev = LinkedListNode.Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public *[Symbol.iterator](): Iterator<E> {
|
||||
let node = this._first;
|
||||
while (node !== LinkedListNode.Undefined) {
|
||||
yield node.element;
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace EventType {
|
||||
export const TAP = '-xterm-gesturetap';
|
||||
@@ -188,28 +306,28 @@ export class Gesture extends Disposable {
|
||||
const holdTime = Date.now() - data.initialTimeStamp;
|
||||
|
||||
if (holdTime < Gesture._holdDelay
|
||||
&& Math.abs(data.initialPageX - arrays.tail(data.rollingPageX)!) < 30
|
||||
&& Math.abs(data.initialPageY - arrays.tail(data.rollingPageY)!) < 30) {
|
||||
&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30
|
||||
&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {
|
||||
|
||||
const evt = this._newGestureEvent(EventType.TAP, data.initialTarget);
|
||||
evt.pageX = arrays.tail(data.rollingPageX)!;
|
||||
evt.pageY = arrays.tail(data.rollingPageY)!;
|
||||
evt.pageX = tail(data.rollingPageX)!;
|
||||
evt.pageY = tail(data.rollingPageY)!;
|
||||
this._dispatchEvent(evt);
|
||||
|
||||
} else if (holdTime >= Gesture._holdDelay
|
||||
&& Math.abs(data.initialPageX - arrays.tail(data.rollingPageX)!) < 30
|
||||
&& Math.abs(data.initialPageY - arrays.tail(data.rollingPageY)!) < 30) {
|
||||
&& Math.abs(data.initialPageX - tail(data.rollingPageX)!) < 30
|
||||
&& Math.abs(data.initialPageY - tail(data.rollingPageY)!) < 30) {
|
||||
|
||||
const evt = this._newGestureEvent(EventType.CONTEXT_MENU, data.initialTarget);
|
||||
evt.pageX = arrays.tail(data.rollingPageX)!;
|
||||
evt.pageY = arrays.tail(data.rollingPageY)!;
|
||||
evt.pageX = tail(data.rollingPageX)!;
|
||||
evt.pageY = tail(data.rollingPageY)!;
|
||||
this._dispatchEvent(evt);
|
||||
|
||||
} else if (activeTouchCount === 1) {
|
||||
const finalX = arrays.tail(data.rollingPageX)!;
|
||||
const finalY = arrays.tail(data.rollingPageY)!;
|
||||
const finalX = tail(data.rollingPageX)!;
|
||||
const finalY = tail(data.rollingPageY)!;
|
||||
|
||||
const deltaT = arrays.tail(data.rollingTimestamps)! - data.rollingTimestamps[0];
|
||||
const deltaT = tail(data.rollingTimestamps)! - data.rollingTimestamps[0];
|
||||
const deltaX = finalX - data.rollingPageX[0];
|
||||
const deltaY = finalY - data.rollingPageY[0];
|
||||
|
||||
@@ -337,8 +455,8 @@ export class Gesture extends Disposable {
|
||||
const data = this._activeTouches[touch.identifier];
|
||||
|
||||
const evt = this._newGestureEvent(EventType.CHANGE, data.initialTarget);
|
||||
evt.translationX = touch.pageX - arrays.tail(data.rollingPageX)!;
|
||||
evt.translationY = touch.pageY - arrays.tail(data.rollingPageY)!;
|
||||
evt.translationX = touch.pageX - tail(data.rollingPageX)!;
|
||||
evt.translationY = touch.pageY - tail(data.rollingPageY)!;
|
||||
evt.pageX = touch.pageX;
|
||||
evt.pageY = touch.pageY;
|
||||
this._dispatchEvent(evt);
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export type CodeWindow = Window & typeof globalThis & {
|
||||
readonly vscodeWindowId: number;
|
||||
};
|
||||
|
||||
export const mainWindow = (typeof window === 'object' ? window : globalThis) as CodeWindow;
|
||||
Reference in New Issue
Block a user