diff options
Diffstat (limited to 'static')
-rw-r--r-- | static/components/popup-element.ts | 21 | ||||
-rw-r--r-- | static/components/vevent-block.ts | 7 | ||||
-rw-r--r-- | static/popup.ts | 107 | ||||
-rw-r--r-- | static/script.ts | 31 | ||||
-rw-r--r-- | static/style.scss | 4 |
5 files changed, 51 insertions, 119 deletions
diff --git a/static/components/popup-element.ts b/static/components/popup-element.ts index 42e8ee7f..a9ada71c 100644 --- a/static/components/popup-element.ts +++ b/static/components/popup-element.ts @@ -2,8 +2,7 @@ export { PopupElement } import { VEvent } from '../vevent' import { bind_popup_control } from '../dragable' -import { close_popup, event_from_popup } from '../popup' -import { vcal_objects } from '../globals' +import { find_block, vcal_objects } from '../globals' import { ComponentVEvent } from './vevent' @@ -12,6 +11,11 @@ import { remove_event } from '../server_connect' /* <popup-element /> */ class PopupElement extends ComponentVEvent { + /* The popup which is the "selected" popup. + /* Makes the popup last hovered over the selected popup, moving it to + * the top, and allowing global keyboard bindings to affect it. */ + static activePopup: PopupElement | null = null; + constructor(uid?: string) { super(uid); @@ -21,6 +25,15 @@ class PopupElement extends ComponentVEvent { if (obj && obj.calendar) { this.dataset.calendar = obj.calendar; } + + /* Makes us the active popup */ + this.addEventListener('mouseover', () => { + if (PopupElement.activePopup) { + PopupElement.activePopup.removeAttribute('active'); + } + PopupElement.activePopup = this; + this.setAttribute('active', 'active'); + }) } redraw(data: VEvent) { @@ -43,7 +56,7 @@ class PopupElement extends ComponentVEvent { bind_popup_control(nav); let close_btn = body.querySelector('.popup-control .close-button') as HTMLButtonElement - close_btn.addEventListener('click', () => close_popup(this)); + close_btn.addEventListener('click', () => this.visible = false); let maximize_btn = body.querySelector('.popup-control .maximize-button') as HTMLButtonElement maximize_btn.addEventListener('click', () => { @@ -106,7 +119,7 @@ class PopupElement extends ComponentVEvent { break; } - let element = event_from_popup(this) as HTMLElement; + let element = find_block(this.uid) as HTMLElement | null /* start <X, Y> sets offset between top left corner of event in calendar and popup. 10, 10 soo old event is still visible */ diff --git a/static/components/vevent-block.ts b/static/components/vevent-block.ts index 0aad19b2..6b3e7dec 100644 --- a/static/components/vevent-block.ts +++ b/static/components/vevent-block.ts @@ -2,7 +2,6 @@ export { ComponentBlock } import { ComponentVEvent } from './vevent' import { VEvent } from '../vevent' -import { toggle_popup, find_popup } from '../popup' import { parseDate, to_local } from '../lib' @@ -16,9 +15,11 @@ class ComponentBlock extends ComponentVEvent { this.addEventListener('click', () => { let uid = this.uid - let popup = find_popup(uid); + /* TODO is it better to find the popup through a query selector, or + by looking through all registered components of a VEvent? */ + let popup = document.querySelector(`popup-element[data-uid="${uid}"]`) if (popup === null) throw new Error('no popup for uid ' + uid); - toggle_popup(popup); + popup.toggleAttribute('visible'); }); } diff --git a/static/popup.ts b/static/popup.ts deleted file mode 100644 index 69edbb6e..00000000 --- a/static/popup.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { find_block } from './globals' -import { PopupElement } from './components/popup-element' -import { ComponentBlock } from './components/vevent-block' -import { uid } from './types' - -export { - event_from_popup, popup_from_event, close_popup, - close_all_popups, open_popup, toggle_popup, activePopup, - find_popup -} - -/* TODO rewrite most of this */ - -/* event component => coresponding popup component */ -function event_from_popup(popup: PopupElement): ComponentBlock | 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: ComponentBlock): PopupElement | 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: PopupElement): void { - popup.visible = false; -} - -/* hides all popups */ -function close_all_popups() { - for (let popup of document.querySelectorAll("popup-element[visible]")) { - close_popup(popup as PopupElement) - } -} - - -function find_popup(uid: uid): PopupElement | null { - // for (let el of vcal_objects[uid].registered) { - // if (el.tagName === 'popup-element') { - // return el; - // } - // } - // throw 'Popup not fonud'; - return document.querySelector(`popup-element[data-uid="${uid}"]`) -} - -/* open given popup */ -function open_popup(popup: PopupElement) { - popup.visible = true; -} - -/* toggles open/closed status of popup given by id */ -function toggle_popup(popup: PopupElement) { - popup.visible = !popup.visible; -} - -/* 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 */ diff --git a/static/script.ts b/static/script.ts index f378ced1..34443b16 100644 --- a/static/script.ts +++ b/static/script.ts @@ -1,9 +1,7 @@ -import { close_all_popups } from './popup' import { VEvent, xml_to_vcal } from './vevent' import { SmallcalCellHighlight, Timebar } from './clock' import { makeElement } from './lib' import { vcal_objects, event_calendar_mapping } from './globals' -import { open_popup } from './popup' import { EventCreator } from './event-creator' import { PopupElement } from './components/popup-element' import { initialize_components } from './elements' @@ -97,7 +95,7 @@ window.addEventListener('load', function() { tabBtn.click() let tab = document.getElementById(tabBtn.getAttribute('aria-controls')!)! let input = tab.querySelector('input[name="summary"]') as HTMLInputElement - open_popup(popup); + popup.visible = true; input.select(); })); @@ -125,7 +123,7 @@ window.addEventListener('load', function() { present in the global_events map */ (document.querySelector('.days') as Element).appendChild(popup); ev.register(popup); - open_popup(popup); + popup.visible = true; console.log(popup); // (popup.querySelector("input[name='summary']") as HTMLInputElement).focus(); // let popupElement = document.getElementById("popup" + event.id); @@ -181,7 +179,9 @@ window.addEventListener('load', function() { evt = evt || window.event; if (!evt.key) return; if (evt.key.startsWith("Esc")) { - close_all_popups(); + for (let popup of document.querySelectorAll("popup-element[visible]")) { + popup.removeAttribute('visible') + } } } @@ -232,6 +232,27 @@ window.addEventListener('load', function() { // init_input_list(); + 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, + 'KeyT': 4, + 'KeyY': 5, + })[event.code]; + if (i === undefined) return + if (!PopupElement.activePopup) return; + let element = PopupElement + .activePopup + .querySelectorAll("[role=tab]")[i] as HTMLInputElement | undefined + if (!element) return; + /* don't switch tab if event was fired while writing */ + if ('value' in (event.target as any)) return; + element.click(); + }); document.addEventListener('keydown', function(event) { if (event.key == '/') { diff --git a/static/style.scss b/static/style.scss index 847ffb16..92ab9441 100644 --- a/static/style.scss +++ b/static/style.scss @@ -772,6 +772,10 @@ popup-element { position: absolute; z-index: 1000; + &[active] { + z-index: 1001; + } + /* ??? */ left: 10px; top: -50px; |