From a1822e2091b900bfcf5cf2ef62191255d8da1b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Mon, 15 Apr 2024 19:41:18 +0200 Subject: [PATCH] Close bookmark details with escape (#702) --- .../e2e/e2e_test_bookmark_details_modal.py | 5 +++ bookmarks/frontend/behaviors/modal.js | 32 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/bookmarks/e2e/e2e_test_bookmark_details_modal.py b/bookmarks/e2e/e2e_test_bookmark_details_modal.py index beef9bdf..73872e5e 100644 --- a/bookmarks/e2e/e2e_test_bookmark_details_modal.py +++ b/bookmarks/e2e/e2e_test_bookmark_details_modal.py @@ -34,6 +34,11 @@ def test_close_details(self): overlay.click(position={"x": 0, "y": 0}) expect(details_modal).to_be_hidden() + # close with escape + details_modal = self.open_details_modal(bookmark) + self.page.keyboard.press("Escape") + expect(details_modal).to_be_hidden() + def test_toggle_archived(self): bookmark = self.setup_bookmark() diff --git a/bookmarks/frontend/behaviors/modal.js b/bookmarks/frontend/behaviors/modal.js index 37b6da6d..f22ed247 100644 --- a/bookmarks/frontend/behaviors/modal.js +++ b/bookmarks/frontend/behaviors/modal.js @@ -4,13 +4,41 @@ class ModalBehavior extends Behavior { constructor(element) { super(element); + this.onClose = this.onClose.bind(this); + this.onKeyDown = this.onKeyDown.bind(this); + const modalOverlay = element.querySelector(".modal-overlay"); const closeButton = element.querySelector("button.close"); - modalOverlay.addEventListener("click", this.onClose.bind(this)); - closeButton.addEventListener("click", this.onClose.bind(this)); + modalOverlay.addEventListener("click", this.onClose); + closeButton.addEventListener("click", this.onClose); + + document.addEventListener("keydown", this.onKeyDown); + } + + destroy() { + document.removeEventListener("keydown", this.onKeyDown); + } + + onKeyDown(event) { + // Skip if event occurred within an input element + const targetNodeName = event.target.nodeName; + const isInputTarget = + targetNodeName === "INPUT" || + targetNodeName === "SELECT" || + targetNodeName === "TEXTAREA"; + + if (isInputTarget) { + return; + } + + if (event.key === "Escape") { + event.preventDefault(); + this.onClose(); + } } onClose() { + document.removeEventListener("keydown", this.onKeyDown); this.element.classList.add("closing"); this.element.addEventListener("animationend", (event) => { if (event.animationName === "fade-out") {