aboutsummaryrefslogtreecommitdiff
path: root/static/popup.ts
blob: 3fb4ae543bc8d995d7a40a685d06ee2eaa94d3f8 (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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { find_block, find_popup, PopupElement } from './globals'
export { event_from_popup, popup_from_event, close_popup, close_all_popups, VIEW, open_popup, toggle_popup, activePopup }


/* event component => coresponding popup component */
function event_from_popup(popup: Element): HTMLElement | null {
    // return document.getElementById(popup.id.substr(5))
    let el = popup.closest('[data-uid]')
    if (!el) return null;
    let uid = (el as HTMLElement).dataset.uid
    if (!uid) return null;
    return find_block(uid)
}

/* popup component => coresponding event component */
function popup_from_event(event: Element): HTMLElement | null {
    // return document.getElementById("popup" + event.id);
    // return find_popup(event.closest('[data-uid]').dataset.uid)
    let el = event.closest('[data-uid]')
    if (!el) return null;
    let uid = (el as HTMLElement).dataset.uid
    if (!uid) return null;
    return find_popup(uid)
}

/* hides given popup */
function close_popup(popup: Element): void {
    popup.classList.remove("visible");
}

/* hides all popups */
function close_all_popups() {
    for (let popup of document.querySelectorAll("popup-element.visible")) {
        close_popup(popup);
    }
}

declare let VIEW: 'month' | 'week'

/* open given popup */
function open_popup(popup: HTMLElement) {
    popup.classList.add("visible");
    let element = event_from_popup(popup);
    // let root = document.body;
    let root;
    switch (VIEW) {
        case 'week':
            root = document.getElementsByClassName("days")[0];
            break;
        case 'month':
        default:
            root = document.body;
            break;
    }
    /* start <X, Y> sets offset between top left corner
       of event in calendar and popup. 10, 10 soo old
       event is still visible */
    let offsetX = 10, offsetY = 10;
    while (element !== root && element !== null) {
        offsetX += element.offsetLeft;
        offsetY += element.offsetTop;
        element = element.offsetParent as HTMLElement;
    }
    popup.style.left = offsetX + "px";
    popup.style.top = offsetY + "px";
}

/* toggles open/closed status of popup given by id */
function toggle_popup(popup: HTMLElement) {
    // let popup = document.getElementById(popup_id);
    if (popup.classList.contains("visible")) {
        close_popup(popup);
    } else {
        open_popup(popup);
    }
}

/* Code for managing "selected" popup */
/* Makes the popup last hovered over the selected popup, moving it to
 * the top, and allowing global keyboard bindings to affect it. */

let activePopup: PopupElement | undefined;

for (let popup of document.querySelectorAll('popup-element')) {
    /* TODO possibly only change "active" element after a fraction of
     * a second, for example when moving between tabs */
    popup.addEventListener('mouseover', function() {
        /* This is ever so slightly inefficient,
           but it really dosen't mammet */
        for (let other of
            document.querySelectorAll('popup-element')) {
            /* TODO get this from somewhere */
            /* Currently it's manually copied from the stylesheet */
            ((other as PopupElement).style as any)['z-index'] = 1000;
        }
        ((popup as PopupElement).style as any)['z-index'] += 1;
        activePopup = popup as PopupElement
    });
}

document.addEventListener('keydown', function(event) {
    /* Physical key position, names are what that key would
       be in QWERTY */
    let i = ({
        'KeyQ': 0,
        'KeyW': 1,
        'KeyE': 2,
        'KeyR': 3,
    })[event.code];
    if (i === undefined) return
    if (!activePopup) return;
    let element: HTMLLabelElement | undefined = activePopup.querySelectorAll(".tab > label")[i] as HTMLLabelElement;
    if (!element) return;
    element.click();
});

/* END Code for managing "selected" popup */