jodit
Version:
Jodit is an awesome and useful wysiwyg editor with filebrowser
107 lines (106 loc) • 3.8 kB
JavaScript
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import { css } from "./helpers/index.js";
import { isJoditObject } from "./helpers/checker/is-jodit-object.js";
import { isString } from "./helpers/checker/is-string.js";
import { isViewObject } from "./helpers/checker/is-view-object.js";
import { kebabCase } from "./helpers/string/kebab-case.js";
import { getClassName } from "./helpers/utils/get-class-name.js";
import { PluginSystem } from "./plugin/plugin-system.js";
import { lang } from "./constants.js";
import { Dom } from "./dom/index.js";
import { EventEmitter } from "./event-emitter/index.js";
export const instances = {};
let counter = 1;
const uuids = new Set();
/**
* Generate global unique uid
*/
export function uniqueUid() {
function gen() {
counter += 10 * (Math.random() + 1);
return Math.round(counter).toString(16);
}
let uid = gen();
while (uuids.has(uid)) {
uid = gen();
}
uuids.add(uid);
return uid;
}
export const pluginSystem = new PluginSystem();
export const modules = {};
export const extendLang = (langs) => {
Object.keys(langs).forEach(key => {
if (lang[key]) {
Object.assign(lang[key], langs[key]);
}
else {
lang[key] = langs[key];
}
});
};
const boxes = new WeakMap();
/**
* Create unique box(HTMLCotainer) and remove it after destroy
*/
export function getContainer(jodit, classFunc, tag = 'div', createInsideEditor = false) {
const name = isString(classFunc)
? classFunc
: classFunc
? getClassName(classFunc.prototype)
: 'jodit-utils';
const data = boxes.get(jodit) || {}, key = name + tag;
const view = isViewObject(jodit) ? jodit : jodit.j;
let body = null;
if (!data[key]) {
let c = view.c;
body = getPopupViewRoot(view.o, view.container, jodit.od.body);
if (createInsideEditor &&
isJoditObject(jodit) &&
jodit.od !== jodit.ed) {
c = jodit.createInside;
const place = tag === 'style' ? jodit.ed.head : jodit.ed.body;
body =
isJoditObject(jodit) && jodit.o.shadowRoot
? jodit.o.shadowRoot
: place;
}
const box = c.element(tag, {
className: `jodit jodit-${kebabCase(name)}-container jodit-box`
});
box.classList.add(`jodit_theme_${view.o.theme || 'default'}`);
body.appendChild(box);
data[key] = box;
jodit.hookStatus('beforeDestruct', () => {
view.events.off(box);
Dom.safeRemove(box);
delete data[key];
if (Object.keys(data).length) {
boxes.delete(jodit);
}
});
boxes.set(jodit, data);
view.events.fire('getContainer', box);
}
data[key].classList.remove('jodit_theme_default', 'jodit_theme_dark');
data[key].classList.add(`jodit_theme_${view.o.theme || 'default'}`);
return data[key];
}
/**
* Get root element for view
* @internal
*/
export function getPopupViewRoot(o, container, defaultRoot) {
var _a, _b, _c;
return ((_c = (_b = (_a = o.popupRoot) !== null && _a !== void 0 ? _a : o.shadowRoot) !== null && _b !== void 0 ? _b : Dom.closest(container, parentElement => Dom.isHTMLElement(parentElement) &&
(Dom.isTag(parentElement, 'dialog') ||
['fixed', 'absolute'].includes(css(parentElement, 'position'))), defaultRoot)) !== null && _c !== void 0 ? _c : defaultRoot);
}
/**
* Global event emitter
*/
export const eventEmitter = new EventEmitter();