From 5a31bc5f2bc64e4765b16210a63d2fb9438db223 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 30 Oct 2020 22:52:32 +0100 Subject: [PATCH] basic focus trapping of lightbox --- .../web/ui/session/room/LightboxView.js | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/platform/web/ui/session/room/LightboxView.js b/src/platform/web/ui/session/room/LightboxView.js index e6d613eb..27151617 100644 --- a/src/platform/web/ui/session/room/LightboxView.js +++ b/src/platform/web/ui/session/room/LightboxView.js @@ -42,11 +42,14 @@ export class LightboxView extends TemplateView { const details = t.div({ className: "details" }, [t.strong(vm => vm.name), t.br(), "uploaded by ", t.strong(vm => vm.sender), vm => ` at ${vm.time} on ${vm.date}.`]); - return t.div({ + const dialog = t.div({ + role: "dialog", className: "lightbox", onClick: evt => this.clickToClose(evt), onKeydown: evt => this.closeOnEscKey(evt) }, [image, loading, details, close]); + trapFocus(t, dialog); + return dialog; } clickToClose(evt) { @@ -61,3 +64,33 @@ export class LightboxView extends TemplateView { } } } + +function trapFocus(t, element) { + const elements = focusables(element); + const first = elements[0]; + const last = elements[elements.length - 1]; + + t.addEventListener(element, "keydown", evt => { + if (evt.key === "Tab") { + if (evt.shiftKey) { + if (document.activeElement === first) { + last.focus(); + evt.preventDefault(); + } + } else { + if (document.activeElement === last) { + first.focus(); + evt.preventDefault(); + } + } + } + }, true); + Promise.resolve().then(() => { + first.focus(); + }); +} + +function focusables(element) { + return element.querySelectorAll('a[href], button, textarea, input, select'); +} +