oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1/* A modal dialog owns the keyboard.
2 *
3 * A native modal <dialog> makes the page behind it inert to the pointer
4 * and to focus, but not to key events: a keydown on the dialog's own
5 * button still travels to document and window, where commands.js,
6 * clipboard.js and the vendored grid all listen. So with the Keyboard
7 * shortcuts dialog open, Ctrl+D filled the selection down behind it and
8 * a letter key started an edit in a cell nobody could see — persisted
9 * writes made from a dialog (Astra, #39 finding 1).
10 *
11 * So while any modal dialog is open, key and clipboard events stop here,
12 * at the window in the capture phase, before any page listener hears
13 * them. Stopping propagation is not preventing the default: Tab still
14 * moves inside the dialog, Enter and Space still press its buttons,
15 * typing still reaches its fields and Escape still closes it. A dialog
16 * that needs key handling of its own adds it on the dialog element in
17 * the capture phase.
18 *
19 * Loaded first of the page's scripts, so its listener is registered
20 * before any other window listener. General on purpose: it is about
21 * every modal on every page, not about one dialog. */
22(function () {
23 'use strict';
24
25 function modalOpen() {
26 try {
27 return !!document.querySelector('dialog:modal');
28 } catch (e) {
29 return !!document.querySelector('dialog[open]');
30 }
31 }
32
33 ['keydown', 'keypress', 'keyup', 'beforeinput', 'paste', 'cut', 'copy'].forEach(function (type) {
34 window.addEventListener(type, function (e) {
35 if (modalOpen()) e.stopImmediatePropagation();
36 }, true);
37 });
38}());
39