See https://www.woltlab.com/community/thread/300815-ckeditor-link-menu-non-functional-in-ckeditor-instances-in-a-dialog/
See ckeditor/ckeditor#14747
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>();
throw new TypeError(`Cannot initialize the editor for '${element.id}' twice.`);
}
+ setupLayer();
+
const injectedStylesheet = injectCss();
await Promise.all([
--- /dev/null
+/**
+ * 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();
+}
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;
}, 200);
}
+ adoptPageOverlayContainer(data.dialog);
+
return data;
},
}
}
+ releasePageOverlayContainer(data.dialog);
UiScreen.pageOverlayClose();
if (_activeDialog === null) {
* @since 6.0
* @woltlabExcludeBundle tiny
*/
-define(["require", "exports", "tslib", "./Ckeditor/Attachment", "./Ckeditor/Media", "./Ckeditor/Mention", "./Ckeditor/Quote", "./Ckeditor/Autosave", "./Ckeditor/Configuration", "./Ckeditor/Event", "./Ckeditor/SubmitOnEnter", "./Ckeditor/Normalizer", "../Ui/Scroll", "../Devtools", "./Ckeditor/Keyboard"], function (require, exports, tslib_1, Attachment_1, Media_1, Mention_1, Quote_1, Autosave_1, Configuration_1, Event_1, SubmitOnEnter_1, Normalizer_1, Scroll_1, Devtools_1, Keyboard_1) {
+define(["require", "exports", "tslib", "./Ckeditor/Attachment", "./Ckeditor/Media", "./Ckeditor/Mention", "./Ckeditor/Quote", "./Ckeditor/Autosave", "./Ckeditor/Configuration", "./Ckeditor/Event", "./Ckeditor/SubmitOnEnter", "./Ckeditor/Normalizer", "../Ui/Scroll", "../Devtools", "./Ckeditor/Keyboard", "./Ckeditor/Layer"], function (require, exports, tslib_1, Attachment_1, Media_1, Mention_1, Quote_1, Autosave_1, Configuration_1, Event_1, SubmitOnEnter_1, Normalizer_1, Scroll_1, Devtools_1, Keyboard_1, Layer_1) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCkeditorById = exports.getCkeditor = exports.setupCkeditor = void 0;
if (instances.has(element)) {
throw new TypeError(`Cannot initialize the editor for '${element.id}' twice.`);
}
+ (0, Layer_1.setup)();
const injectedStylesheet = injectCss();
await Promise.all([
new Promise((resolve) => {
--- /dev/null
+/**
+ * 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
+ */
+define(["require", "exports", "../../Helper/PageOverlay"], function (require, exports, PageOverlay_1) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.setup = void 0;
+ const targetClassNames = ["ck-body-wrapper", "ck-inspector-wrapper", "ck-inspector-portal"];
+ function setupWatcher() {
+ 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)) {
+ (0, PageOverlay_1.getPageOverlayContainer)().append(node);
+ continue;
+ }
+ }
+ }
+ }
+ });
+ observer.observe(document.body, {
+ childList: true,
+ });
+ }
+ let hasWatcher = false;
+ function setup() {
+ if (hasWatcher) {
+ return;
+ }
+ hasWatcher = true;
+ setupWatcher();
+ }
+ exports.setup = setup;
+});
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @deprecated 6.0 Use `dialogFactory()` instead.
*/
-define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./Screen", "../Dom/Util", "../Language", "../Environment", "../Event/Handler", "./CloseOverlay", "focus-trap"], function (require, exports, tslib_1, Core, Listener_1, UiScreen, Util_1, Language, Environment, EventHandler, CloseOverlay_1, focus_trap_1) {
+define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "./Screen", "../Dom/Util", "../Language", "../Environment", "../Event/Handler", "./CloseOverlay", "focus-trap", "../Helper/PageOverlay"], function (require, exports, tslib_1, Core, Listener_1, UiScreen, Util_1, Language, Environment, EventHandler, CloseOverlay_1, focus_trap_1, PageOverlay_1) {
"use strict";
Core = tslib_1.__importStar(Core);
Listener_1 = tslib_1.__importDefault(Listener_1);
data.content.querySelector("input, textarea")?.focus();
}, 200);
}
+ (0, PageOverlay_1.adoptPageOverlayContainer)(data.dialog);
return data;
},
/**
break;
}
}
+ (0, PageOverlay_1.releasePageOverlayContainer)(data.dialog);
UiScreen.pageOverlayClose();
if (_activeDialog === null) {
_container.setAttribute("aria-hidden", "true");