From dc43359fc35fedef3faf3bfbc93e020b4b37e1e7 Mon Sep 17 00:00:00 2001 From: Tomas Roun Date: Wed, 28 Sep 2022 15:26:26 +0200 Subject: [PATCH] Stop propagation of keydown events when full screen is active --- src/fullscreen.js | 70 +++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/src/fullscreen.js b/src/fullscreen.js index d69a748..f90b82b 100644 --- a/src/fullscreen.js +++ b/src/fullscreen.js @@ -6,6 +6,24 @@ import {CLOSE_ON_ESCAPE, CLOSE_ON_CLICK} from './config'; import '../theme/fullscreen.css'; +let closeOnEscape, closeOnClick, button; +let isFullScreen = false; + +// Close on escape +const onKeyDown = e => { + if (closeOnEscape && e.key === 'Escape' && button && isFullScreen) { + // If the full screen mode is active, prevent triggering any other event handler. + e.stopPropagation(); + e.stopImmediatePropagation(); + button.fire('execute'); + } +}; +// Attach the event handler as soon as possible in case the editor +// is rendered in a modal which can be closed with an escape +// (or anything else listening for keydown events that we don't want to accidentally trigger). +// This makes it possible to stop event propagation, which keeps the modal open. +document.addEventListener('keydown', onKeyDown, {capture: true}); + export default class FullScreen extends Plugin { static get pluginName() { return 'FullScreen'; @@ -25,11 +43,11 @@ export default class FullScreen extends Plugin { // Set the default configuration editor.config.define(CLOSE_ON_ESCAPE, true); editor.config.define(CLOSE_ON_CLICK, true); + closeOnEscape = editor.config.get(CLOSE_ON_ESCAPE); + closeOnClick = editor.config.get(CLOSE_ON_CLICK); const maximize = () => { const wrapperElement = editor.ui.view.element; - // Make the wrapping div focusable so it can capture key presses - wrapperElement.setAttribute('tabindex', '0'); // Apply styles wrapperElement.classList.add('ck-plugin-full-screen'); this.styles = { @@ -44,55 +62,43 @@ export default class FullScreen extends Plugin { const minimize = () => { const wrapperElement = editor.ui.view.element; - wrapperElement.removeAttribute('tabindex'); wrapperElement.classList.remove('ck-plugin-full-screen'); editor.editing.view.change(writer => { this._restoreStyles(writer, rootElement); }); }; - editor.ui.componentFactory.add('fullscreen', () => { - const wrapperElement = editor.ui.view.element; - const button = new ButtonView(); - button.set({ - label: t('Full screen'), - icon: Maximize, - tooltip: true, - }); - - // Make the toolbar button appear clicked when full screen is active - button.bind('isOn').to(this, 'isFullScreen'); + button = new ButtonView(); + button.set({ + label: t('Full screen'), + icon: Maximize, + tooltip: true, + }); - const closeOnEscape = editor.config.get(CLOSE_ON_ESCAPE); - const closeOnClick = editor.config.get(CLOSE_ON_CLICK); + // Make the toolbar button appear clicked when full screen is active + button.bind('isOn').to(this, 'isFullScreen'); - // Close on escape - const onKeyDown = e => { - if (e.key === 'Escape' && this.isFullScreen) { - button.fire('execute'); - e.stopPropagation(); - } - }; + // Close on background click + const onClick = e => { + if (e.target === e.currentTarget && this.isFullScreen) { + e.stopPropagation(); + button.fire('execute'); + } + }; - // Close on background click - const onClick = e => { - if (e.target === e.currentTarget && this.isFullScreen) { - button.fire('execute'); - e.stopPropagation(); - } - }; + editor.ui.componentFactory.add('fullscreen', () => { + const wrapperElement = editor.ui.view.element; button.on('execute', () => { if (!this.isFullScreen) { - closeOnEscape && wrapperElement.addEventListener('keydown', onKeyDown); closeOnClick && wrapperElement.addEventListener('click', onClick); maximize(); } else { - closeOnEscape && wrapperElement.removeEventListener('keydown', onKeyDown); closeOnClick && wrapperElement.removeEventListener('click', onClick); minimize(); } this.isFullScreen = !this.isFullScreen; + isFullScreen = this.isFullScreen; editor.editing.view.focus(); });