jodit
Version:
Jodit is an awesome and useful wysiwyg editor with filebrowser
168 lines (167 loc) • 6.2 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 { Dom } from "../../dom/dom.js";
import { isString } from "../checker/is-string.js";
import { attr } from "./attr.js";
import { css } from "./css.js";
import { $$ } from "./selector.js";
/**
* Fixes image sizes and sets absolute paths to images
*/
function fixedAssetsSizeAndAbsoluteLinks(editor, points) {
const restoreAttributes = [];
try {
$$('img', editor.editor).forEach(item => {
const previousAttrs = [
attr(item, 'width'),
attr(item, 'height'),
item.src
];
attr(item, {
width: item.offsetWidth + points,
height: item.offsetHeight + points
});
const a = editor.createInside.a();
editor.ed.body.appendChild(a);
a.href = item.src;
item.src = a.href;
Dom.safeRemove(a);
restoreAttributes.push(() => {
var _a;
item.src = (_a = previousAttrs[2]) !== null && _a !== void 0 ? _a : '';
attr(item, {
width: previousAttrs[0] || null,
height: previousAttrs[1] || null
});
});
});
}
catch (e) {
restoreAttributes.forEach(c => c());
restoreAttributes.length = 0;
throw e;
}
return restoreAttributes;
}
/**
* Generates a copy of an HTML document, resizes images, executes JS
*
* @event beforePreviewBox(string | undefined, 'pt' | 'px' | '')
* @event afterPreviewBox(HTMLElement)
*/
export function previewBox(editor, defaultValue, points = 'px', container = null) {
const onDestruct = [];
const restoreAttributes = fixedAssetsSizeAndAbsoluteLinks(editor, points);
try {
const res = editor.e.fire('beforePreviewBox', defaultValue, points);
if (res != null) {
return res;
}
let div = editor.c.div('jodit__preview-box jodit-context');
if (container) {
container.appendChild(div);
}
css(div, {
position: 'relative',
padding: 16
});
const value = editor.value ||
`<div style='position: absolute;left:50%;top:50%;transform: translateX(-50%) translateY(-50%);color:#ccc;'>${editor.i18n('Empty')}</div>`;
if (editor.iframe) {
const iframe = editor.create.element('iframe');
css(iframe, {
minWidth: 800,
minHeight: 600,
border: 0
});
div.appendChild(iframe);
const myWindow = iframe.contentWindow;
if (myWindow) {
editor.e.fire('generateDocumentStructure.iframe', myWindow.document, editor);
div = myWindow.document.body;
if (typeof ResizeObserver === 'function') {
let destructed = false;
const elm = myWindow.document.body;
const resizeObserver = new ResizeObserver(editor.async.debounce(() => {
resizeObserver.unobserve(elm);
iframe.style.height = `${elm.offsetHeight + 20}px`;
editor.async.requestAnimationFrame(() => {
!destructed && resizeObserver.observe(elm);
});
}, 100));
const beforeDestruct = () => {
destructed = true;
resizeObserver.unobserve(elm);
resizeObserver.disconnect();
editor.e.off('beforeDestruct', beforeDestruct);
};
onDestruct.push(beforeDestruct);
editor.e.on('beforeDestruct', beforeDestruct);
}
}
}
else {
css(div, {
minWidth: 1024,
minHeight: 600,
border: 0
});
}
const setHTML = (box, value) => {
const dv = isString(value) ? editor.c.div() : value;
if (isString(value)) {
dv.innerHTML = value;
}
for (let i = 0; i < dv.childNodes.length; i += 1) {
const c = dv.childNodes[i];
if (Dom.isElement(c)) {
const newNode = box.ownerDocument.createElement(c.nodeName);
for (let j = 0; j < c.attributes.length; j += 1) {
attr(newNode, c.attributes[j].nodeName, c.attributes[j].nodeValue);
}
if (c.childNodes.length === 0 || Dom.isTag(c, 'table')) {
switch (c.nodeName) {
case 'SCRIPT':
if (c.textContent) {
newNode.textContent = c.textContent;
}
break;
default:
if (c.innerHTML) {
newNode.innerHTML = c.innerHTML;
}
break;
}
}
else {
setHTML(newNode, c);
}
try {
box.appendChild(newNode);
}
catch (_a) { }
}
else {
try {
box.appendChild(c.cloneNode(true));
}
catch (_b) { }
}
}
};
setHTML(div, value);
editor.e.fire('afterPreviewBox', div);
return [
div,
() => {
onDestruct.forEach(cb => cb());
}
];
}
finally {
restoreAttributes.forEach(clb => clb());
}
}