]> git.proxmox.com Git - mirror_xterm.js.git/blame - src/utils/Mouse.ts
Make SelectionManager more resilient
[mirror_xterm.js.git] / src / utils / Mouse.ts
CommitLineData
4d328268
DI
1/**
2 * @license MIT
3 */
4
5import { CharMeasure } from './CharMeasure';
6
0dc3dd03 7export function getCoordsRelativeToElement(event: MouseEvent, element: HTMLElement): [number, number] {
70e35de5 8 // Ignore browsers that don't support MouseEvent.pageX
4d328268
DI
9 if (event.pageX == null) {
10 return null;
11 }
12
13 let x = event.pageX;
14 let y = event.pageY;
4d328268 15
70e35de5
DI
16 // Converts the coordinates from being relative to the document to being
17 // relative to the terminal.
0dc3dd03
DI
18 while (element && element !== self.document.documentElement) {
19 x -= element.offsetLeft;
20 y -= element.offsetTop;
21 element = 'offsetParent' in element ? <HTMLElement>element.offsetParent : <HTMLElement>element.parentElement;
4d328268 22 }
0dc3dd03
DI
23 return [x, y];
24}
25
26/**
27 * Gets coordinates within the terminal for a particular mouse event. The result
28 * is returned as an array in the form [x, y] instead of an object as it's a
29 * little faster and this function is used in some low level code.
30 * @param event The mouse event.
31 * @param rowContainer The terminal's row container.
32 * @param charMeasure The char measure object used to determine character sizes.
b05814e6
DI
33 * @param colCount The number of columns in the terminal.
34 * @param rowCount The number of rows n the terminal.
35 * @param isSelection Whether the request is for the selection or not. This will
36 * apply an offset to the x value such that the left half of the cell will
37 * select that cell and the right half will select the next cell.
0dc3dd03 38 */
b05814e6 39export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure, colCount: number, rowCount: number, isSelection?: boolean): [number, number] {
e56f710c
DI
40 // Coordinates cannot be measured if charMeasure has not been initialized
41 if (!charMeasure.width || !charMeasure.height) {
42 return null;
43 }
44
0dc3dd03 45 const coords = getCoordsRelativeToElement(event, rowContainer);
e56f710c
DI
46 if (!coords) {
47 return null;
48 }
4d328268 49
b05814e6
DI
50 // Convert to cols/rows.
51 coords[0] = Math.ceil((coords[0] + (isSelection ? charMeasure.width / 2 : 0)) / charMeasure.width);
0dc3dd03 52 coords[1] = Math.ceil(coords[1] / charMeasure.height);
4d328268 53
0dc3dd03
DI
54 // Ensure coordinates are within the terminal viewport.
55 coords[0] = Math.min(Math.max(coords[0], 1), colCount + 1);
56 coords[1] = Math.min(Math.max(coords[1], 1), rowCount + 1);
57
58 return coords;
4d328268
DI
59}
60
c323e0ad
DI
61/**
62 * Gets coordinates within the terminal for a particular mouse event, wrapping
63 * them to the bounds of the terminal and adding 32 to both the x and y values
64 * as expected by xterm.
65 * @param event The mouse event.
66 * @param rowContainer The terminal's row container.
67 * @param charMeasure The char measure object used to determine character sizes.
68 * @param colCount The number of columns in the terminal.
69 * @param rowCount The number of rows in the terminal.
70 */
4d328268 71export function getRawByteCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure, colCount: number, rowCount: number): { x: number, y: number } {
0dc3dd03 72 const coords = getCoords(event, rowContainer, charMeasure, colCount, rowCount);
4d328268
DI
73 let x = coords[0];
74 let y = coords[1];
75
70e35de5 76 // xterm sends raw bytes and starts at 32 (SP) for each.
4d328268
DI
77 x += 32;
78 y += 32;
79
80 return { x, y };
81}