Files
xterm.js/src/browser/renderer/shared/TextBlinkStateManager.ts
T
Daniel ImmsandCursor 17ad33dc3d Remove TypeScript path mappings in favor of relative imports
Fixes https://github.com/xtermjs/xterm.js/issues/5896

TypeScript path mappings for common/*, browser/*, and headless/*
were not rewritten in emitted JavaScript, which forced webpack resolve
aliases and NODE_PATH workarounds so runtime could resolve modules.
That added build complexity and broke tooling such as ESLint import/no-cycle.

Changes:
- Convert ~750 imports across src/, addons/, and test/ to relative paths
- Remove common/browser/headless paths and src catch-all mappings from tsconfigs
  (keep @xterm/addon-* demo and addon typings paths)
- Remove webpack resolve.alias for common, browser, headless, and vs
- Drop NODE_PATH from unit tests, benchmarks, and VS Code launch config
- Fix addon-image IIPImageStorage to import ./Types after removing catch-all *

Verified: npm run build, esbuild, package, package-headless
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 09:16:10 -07:00

98 lines
2.7 KiB
TypeScript

/**
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { ICoreBrowserService } from '../../services/Services';
import { Disposable, toDisposable } from '../../../common/Lifecycle';
import { IOptionsService } from '../../../common/services/Services';
export class TextBlinkStateManager extends Disposable {
private _intervalDuration: number = 0;
private _interval: number | undefined;
private _blinkOn: boolean = true;
private _needsBlinkInViewport: boolean = false;
private _isViewportVisible: boolean = true;
constructor(
private readonly _renderCallback: () => void,
private readonly _coreBrowserService: ICoreBrowserService,
private readonly _optionsService: IOptionsService
) {
super();
this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {
this.setIntervalDuration(duration);
}));
this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
this._register(toDisposable(() => this._clearInterval()));
}
public get isBlinkOn(): boolean {
return this._blinkOn;
}
public get isEnabled(): boolean {
return this._intervalDuration > 0;
}
public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {
if (this._needsBlinkInViewport === needsBlinkInViewport) {
return;
}
this._needsBlinkInViewport = needsBlinkInViewport;
this._updateIntervalState();
}
public setViewportVisible(isVisible: boolean): void {
if (this._isViewportVisible === isVisible) {
return;
}
this._isViewportVisible = isVisible;
this._updateIntervalState();
}
public setIntervalDuration(duration: number): void {
if (duration === this._intervalDuration) {
return;
}
this._intervalDuration = duration;
this._clearInterval();
this._updateIntervalState();
}
private _updateIntervalState(): void {
const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;
if (shouldBlink) {
if (this._interval !== undefined) {
return;
}
const wasBlinkOn = this._blinkOn;
this._blinkOn = true;
this._interval = this._coreBrowserService.window.setInterval(() => {
this._blinkOn = !this._blinkOn;
this._renderCallback();
}, this._intervalDuration);
if (!wasBlinkOn) {
this._renderCallback();
}
return;
}
this._clearInterval();
if (!this._blinkOn) {
this._blinkOn = true;
this._renderCallback();
}
}
private _clearInterval(): void {
if (this._interval !== undefined) {
this._coreBrowserService.window.clearInterval(this._interval);
this._interval = undefined;
}
}
}