From f2e9c73b3123765615d7f15fd1961b2c6c9a50c2 Mon Sep 17 00:00:00 2001 From: Abdo Date: Thu, 21 Dec 2023 06:59:52 +0300 Subject: [PATCH] Do not close web pages when Esc is pressed and a modal is open (#2894) * Prefer key over keyCode * Do not close TS pages on Esc when floating elements are open * Close pop-up when Escape is pressed regardless of keepOnKeyup * Close help modals when Escape is pressed * Avoid duplicate handling of Esc in WithFloating * Formatting * Handle closing of preset management modals * Reset text input modal to initial value --- qt/aqt/webview.py | 2 +- ts/components/HelpModal.svelte | 24 +++++++++++++++++-- ts/components/WithFloating.svelte | 12 ++++++++-- ts/deck-options/ConfigSelector.svelte | 2 +- ts/deck-options/TextInputModal.svelte | 30 +++++++++++++++++++---- ts/sveltelib/modal-closing.ts | 34 +++++++++++++++++++++++++++ 6 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 ts/sveltelib/modal-closing.ts diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 250c4d68c..a977d83df 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -295,7 +295,7 @@ class AnkiWebView(QWebEngineView): self.eval( """ document.addEventListener("keydown", function(evt) { - if (evt.keyCode === 27) { + if (evt.key === "Escape") { pycmd("close"); } }); diff --git a/ts/components/HelpModal.svelte b/ts/components/HelpModal.svelte index 27d0dac65..8f529271a 100644 --- a/ts/components/HelpModal.svelte +++ b/ts/components/HelpModal.svelte @@ -7,8 +7,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import { renderMarkdown } from "@tslib/helpers"; import Carousel from "bootstrap/js/dist/carousel"; import Modal from "bootstrap/js/dist/modal"; - import { createEventDispatcher, getContext, onMount } from "svelte"; + import { createEventDispatcher, getContext, onDestroy, onMount } from "svelte"; + import { registerModalClosingHandler } from "../sveltelib/modal-closing"; import { pageTheme } from "../sveltelib/theme"; import Badge from "./Badge.svelte"; import Col from "./Col.svelte"; @@ -40,8 +41,21 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html const dispatch = createEventDispatcher(); + const { set: setModalOpen, remove: removeModalClosingHandler } = + registerModalClosingHandler(onOkClicked); + + function onShown() { + setModalOpen(true); + } + + function onHidden() { + setModalOpen(false); + } + onMount(() => { - modal = new Modal(modalRef); + modalRef.addEventListener("shown.bs.modal", onShown); + modalRef.addEventListener("hidden.bs.modal", onHidden); + modal = new Modal(modalRef, { keyboard: false }); carousel = new Carousel(carouselRef, { interval: false, ride: false }); /* Bootstrap's Carousel.Event interface doesn't seem to work as a type here */ carouselRef.addEventListener("slide.bs.carousel", (e: any) => { @@ -51,6 +65,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html modals.set(modalKey, modal); }); + onDestroy(() => { + removeModalClosingHandler(); + modalRef.removeEventListener("shown.bs.modal", onShown); + modalRef.removeEventListener("hidden.bs.modal", onHidden); + }); + let activeIndex = startIndex; diff --git a/ts/components/WithFloating.svelte b/ts/components/WithFloating.svelte index a26cdb038..3171ce601 100644 --- a/ts/components/WithFloating.svelte +++ b/ts/components/WithFloating.svelte @@ -18,6 +18,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import isClosingKeyup from "../sveltelib/closing-keyup"; import type { EventPredicateResult } from "../sveltelib/event-predicate"; import { documentClick, documentKeyup } from "../sveltelib/event-store"; + import { registerModalClosingHandler } from "../sveltelib/modal-closing"; import portal from "../sveltelib/portal"; import type { PositioningCallback } from "../sveltelib/position/auto-update"; import autoUpdate from "../sveltelib/position/auto-update"; @@ -54,6 +55,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html let arrow: HTMLElement; + const { set: setModalOpen, remove: removeModalClosingHandler } = + registerModalClosingHandler(() => dispatch("close", { reason: "esc" })); + $: positionCurried = positionFloating({ placement, offset, @@ -124,7 +128,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html ) { cleanup?.(); cleanup = null; - + setModalOpen(isShowing); if (!reference || !floating || !isShowing) { return; } @@ -164,7 +168,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html ); } - cleanup = singleCallback(...subscribers, autoAction.destroy!); + cleanup = singleCallback( + ...subscribers, + autoAction.destroy!, + removeModalClosingHandler, + ); } $: updateFloating(reference, floating, show); diff --git a/ts/deck-options/ConfigSelector.svelte b/ts/deck-options/ConfigSelector.svelte index 1d4dfb9b7..1dbf18f9a 100644 --- a/ts/deck-options/ConfigSelector.svelte +++ b/ts/deck-options/ConfigSelector.svelte @@ -86,7 +86,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html diff --git a/ts/deck-options/TextInputModal.svelte b/ts/deck-options/TextInputModal.svelte index f4718cb70..08be7e295 100644 --- a/ts/deck-options/TextInputModal.svelte +++ b/ts/deck-options/TextInputModal.svelte @@ -5,14 +5,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html @@ -81,7 +99,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html