Skip to content

Commit

Permalink
Move the CKEditor overlays into the page overlay container
Browse files Browse the repository at this point in the history
  • Loading branch information
dtdesign committed Aug 8, 2023
1 parent e6640c0 commit 696e7e4
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 2 deletions.
3 changes: 3 additions & 0 deletions ts/WoltLabSuite/Core/Component/Ckeditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { element as scrollToElement } from "../Ui/Scroll";
import Devtools from "../Devtools";
import { ClassicEditor, CodeBlockConfig, EditorConfig, Element as CkeElement } from "./Ckeditor/Types";
import { setupSubmitShortcut } from "./Ckeditor/Keyboard";
import { setup as setupLayer } from "./Ckeditor/Layer";

const instances = new WeakMap<HTMLElement, CKEditor>();

Expand Down Expand Up @@ -238,6 +239,8 @@ export async function setupCkeditor(
throw new TypeError(`Cannot initialize the editor for '${element.id}' twice.`);
}

setupLayer();

const injectedStylesheet = injectCss();

await Promise.all([
Expand Down
50 changes: 50 additions & 0 deletions ts/WoltLabSuite/Core/Component/Ckeditor/Layer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Moves CKEditor’s overlay elements into the page overlay container. This
* preserves their functionality when the editor appears within a native
* `<dialog>` element.
*
* See https://github.com/ckeditor/ckeditor5/issues/14747
*
* @author Alexander Ebert
* @copyright 2001-2023 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @since 6.0
* @woltlabExcludeBundle tiny
*/

import { getPageOverlayContainer } from "../../Helper/PageOverlay";

const targetClassNames = ["ck-body-wrapper", "ck-inspector-wrapper", "ck-inspector-portal"];

function setupWatcher(): void {
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (!(node instanceof HTMLElement)) {
continue;
}

for (const className of targetClassNames) {
if (node.classList.contains(className)) {
getPageOverlayContainer().append(node);

continue;
}
}
}
}
});
observer.observe(document.body, {
childList: true,
});
}

let hasWatcher = false;
export function setup(): void {
if (hasWatcher) {
return;
}

hasWatcher = true;
setupWatcher();
}
4 changes: 4 additions & 0 deletions ts/WoltLabSuite/Core/Ui/Dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import * as EventHandler from "../Event/Handler";
import { AjaxCallbackSetup } from "../Ajax/Data";
import CloseOverlay from "./CloseOverlay";
import { createFocusTrap } from "focus-trap";
import { adoptPageOverlayContainer, releasePageOverlayContainer } from "../Helper/PageOverlay";

let _activeDialog: string | null = null;
let _container: HTMLElement;
Expand Down Expand Up @@ -285,6 +286,8 @@ const UiDialog = {
}, 200);
}

adoptPageOverlayContainer(data.dialog);

return data;
},

Expand Down Expand Up @@ -811,6 +814,7 @@ const UiDialog = {
}
}

releasePageOverlayContainer(data.dialog);
UiScreen.pageOverlayClose();

if (_activeDialog === null) {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dialog.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 696e7e4

Please sign in to comment.