]> git.proxmox.com Git - mirror_xterm.js.git/blob - src/utils/CharMeasure.ts
Merge pull request #723 from Tyriar/699_linux_middle_click
[mirror_xterm.js.git] / src / utils / CharMeasure.ts
1 /**
2 * @module xterm/utils/CharMeasure
3 * @license MIT
4 */
5
6 import { EventEmitter } from '../EventEmitter.js';
7
8 /**
9 * Utility class that measures the size of a character.
10 */
11 export class CharMeasure extends EventEmitter {
12 private _document: Document;
13 private _parentElement: HTMLElement;
14 private _measureElement: HTMLElement;
15 private _width: number;
16 private _height: number;
17
18 constructor(document: Document, parentElement: HTMLElement) {
19 super();
20 this._document = document;
21 this._parentElement = parentElement;
22 }
23
24 public get width(): number {
25 return this._width;
26 }
27
28 public get height(): number {
29 return this._height;
30 }
31
32 public measure(): void {
33 if (!this._measureElement) {
34 this._measureElement = this._document.createElement('span');
35 this._measureElement.style.position = 'absolute';
36 this._measureElement.style.top = '0';
37 this._measureElement.style.left = '-9999em';
38 this._measureElement.textContent = 'W';
39 this._measureElement.setAttribute('aria-hidden', 'true');
40 this._parentElement.appendChild(this._measureElement);
41 // Perform _doMeasure async if the element was just attached as sometimes
42 // getBoundingClientRect does not return accurate values without this.
43 setTimeout(() => this._doMeasure(), 0);
44 } else {
45 this._doMeasure();
46 }
47 }
48
49 private _doMeasure(): void {
50 const geometry = this._measureElement.getBoundingClientRect();
51 // The element is likely currently display:none, we should retain the
52 // previous value.
53 if (geometry.width === 0 || geometry.height === 0) {
54 return;
55 }
56 if (this._width !== geometry.width || this._height !== geometry.height) {
57 this._width = geometry.width;
58 this._height = geometry.height;
59 this.emit('charsizechanged');
60 }
61 }
62 }