summaryrefslogtreecommitdiffstats
path: root/html/src/components/terminal/xterm/addons/overlay.ts
blob: 74da07990eca26a689d2af66d5c55218b5ee6b0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// ported from hterm.Terminal.prototype.showOverlay
// https://chromium.googlesource.com/apps/libapps/+/master/hterm/js/hterm_terminal.js
import { bind } from 'decko';
import { ITerminalAddon, Terminal } from '@xterm/xterm';

export class OverlayAddon implements ITerminalAddon {
    private terminal: Terminal;
    private overlayNode: HTMLElement;
    private overlayTimeout?: number;

    constructor() {
        this.overlayNode = document.createElement('div');
        this.overlayNode.style.cssText = `border-radius: 15px;
font-size: xx-large;
opacity: 0.75;
padding: 0.2em 0.5em 0.2em 0.5em;
position: absolute;
-webkit-user-select: none;
-webkit-transition: opacity 180ms ease-in;
-moz-user-select: none;
-moz-transition: opacity 180ms ease-in;`;

        this.overlayNode.addEventListener(
            'mousedown',
            e => {
                e.preventDefault();
                e.stopPropagation();
            },
            true
        );
    }

    activate(terminal: Terminal): void {
        this.terminal = terminal;
    }

    dispose(): void {}

    @bind
    showOverlay(msg: string, timeout?: number): void {
        const { terminal, overlayNode } = this;
        if (!terminal.element) return;

        overlayNode.style.color = '#101010';
        overlayNode.style.backgroundColor = '#f0f0f0';
        overlayNode.textContent = msg;
        overlayNode.style.opacity = '0.75';

        if (!overlayNode.parentNode) {
            terminal.element.appendChild(overlayNode);
        }

        const divSize = terminal.element.getBoundingClientRect();
        const overlaySize = overlayNode.getBoundingClientRect();

        overlayNode.style.top = (divSize.height - overlaySize.height) / 2 + 'px';
        overlayNode.style.left = (divSize.width - overlaySize.width) / 2 + 'px';

        if (this.overlayTimeout) clearTimeout(this.overlayTimeout);
        if (!timeout) return;

        this.overlayTimeout = window.setTimeout(() => {
            overlayNode.style.opacity = '0';
            this.overlayTimeout = window.setTimeout(() => {
                if (overlayNode.parentNode) {
                    overlayNode.parentNode.removeChild(overlayNode);
                }
                this.overlayTimeout = undefined;
                overlayNode.style.opacity = '0.75';
            }, 200);
        }, timeout || 1500);
    }
}