jodit
Version:
Jodit is awesome and usefully wysiwyg editor with filebrowser
299 lines (268 loc) • 7.21 kB
text/typescript
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Licensed under GNU General Public License version 2 or later or a commercial license or MIT;
* For GPL see LICENSE-GPL.txt in the project root for license information.
* For MIT see LICENSE-MIT.txt in the project root for license information.
* For commercial licenses see https://xdsoft.net/jodit/commercial/
* Copyright (c) 2013-2019 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import { Config } from '../Config';
import { defaultLanguage } from '../modules/helpers/defaultLanguage';
import { throttle } from '../modules/helpers/async';
import { css } from '../modules/helpers/css';
import { IJodit } from '../types';
declare module '../Config' {
interface Config {
iframeDefaultSrc: string;
iframeBaseUrl: string;
iframeStyle: string;
iframeCSSLinks: string[];
}
}
/**
* Base URL where the root directory for {@link Jodit.defaultOptions.iframe|iframe} mode
*
* @example
* ```javascript
* new Jodit('#editor', {
* iframe: true,
* iframeBaseUrl: 'http://xdsoft.net/jodit/docs/',
* });
* ```
*/
Config.prototype.iframeBaseUrl = '';
/**
* You can redefine default page
*
* @example
* ```javascript
* new Jodit('#editor', {
* iframe: true,
* iframeDefaultSrc: 'http://xdsoft.net/jodit/docs/',
* });
* ```
*/
Config.prototype.iframeDefaultSrc = 'about:blank';
/**
* Custom style toWYSIWYG be used inside the iframe toWYSIWYG display content.
* @example
* ```javascript
* new Jodit('#editor', {
* iframe: true,
* iframeStyle: 'html{margin: 0px;}',
* })
* ```
*/
Config.prototype.iframeStyle =
'html{' +
'margin: 0px;' +
'min-height: 100%;' +
'}' +
'body{' +
'box-sizing: border-box;' +
'font-size: 13px;' +
' line-height: 1.6;' +
'padding:10px;' +
'background:transparent;' +
'color:#000;' +
'position:' +
'relative;' +
'z-index: 2;' +
'user-select:auto;' +
'margin:0px;' +
'overflow:auto;' +
'}' +
'table{' +
'width:100%;' +
'border: none;' +
'border-collapse:collapse;' +
'empty-cells: show;' +
'max-width: 100%;' +
'}' +
'th,td{' +
'padding: 2px 5px;' +
'border:1px solid #ccc;' +
'-webkit-user-select:text;' +
'-moz-user-select:text;' +
'-ms-user-select:text;' +
'user-select:text' +
'}' +
'td[data-jodit-selected-cell],' +
'th[data-jodit-selected-cell]{' +
'border: 1px double #1e88e5' +
'}' +
'p{' +
'margin-top:0;' +
'}' +
'.jodit_editor .jodit_iframe_wrapper{' +
'display: block;' +
'clear: both;' +
'user-select: none;' +
'position: relative;' +
'}' +
'.jodit_editor .jodit_iframe_wrapper:after {' +
'position:absolute;' +
'content:"";' +
'z-index:1;' +
'top:0;' +
'left:0;' +
'right: 0;' +
'bottom: 0;' +
'cursor: pointer;' +
'display: block;' +
'background: rgba(0, 0, 0, 0);' +
'} ' +
'.jodit_disabled{' +
'user-select: none;' +
'-o-user-select: none;' +
'-moz-user-select: none;' +
'-khtml-user-select: none;' +
'-webkit-user-select: none;' +
'-ms-user-select: none' +
'}';
/**
* Custom stylesheet files toWYSIWYG be used inside the iframe toWYSIWYG display content.
*
* @example
* ```javascript
* new Jodit('#editor', {
* iframe: true,
* iframeCSSLinks: ['styles/default.css'],
* })
* ```
*/
Config.prototype.iframeCSSLinks = [];
/**
* Iframe plugin - use `iframe` instead of DIV in editor. It can be need when you want attach custom styles in editor
* in backend of you system
*/
export function iframe(editor: IJodit) {
editor.events
.on('afterSetMode', () => {
if (editor.isEditorMode()) {
editor.selection.focus();
}
})
.on(
'generateDocumentStructure.iframe',
(__doc: Document | undefined, jodit: IJodit) => {
const
doc = __doc || ((jodit.iframe as HTMLIFrameElement).contentWindow as Window).document;
doc.open();
doc.write(
'<!DOCTYPE html>' +
'<html dir="' +
jodit.options.direction +
'" class="jodit" ' +
'lang="' +
defaultLanguage(jodit.options.language) +
'">' +
'<head>' +
'<title>Jodit Editor</title>' +
(jodit.options.iframeBaseUrl
? '<base href="' +
jodit.options.iframeBaseUrl +
'"/>'
: '') +
'</head>' +
'<body class="jodit_wysiwyg" style="outline:none" contenteditable="true"></body>' +
'</html>'
);
doc.close();
if (jodit.options.iframeCSSLinks) {
jodit.options.iframeCSSLinks.forEach(href => {
const link = doc.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', href);
doc.head && doc.head.appendChild(link);
});
}
if (jodit.options.iframeStyle) {
const style = doc.createElement('style');
style.innerHTML = jodit.options.iframeStyle;
doc.head && doc.head.appendChild(style);
}
}
)
.on('createEditor', async (): Promise<void | false> => {
if (!editor.options.iframe) {
return;
}
delete editor.editor;
const iframe = editor.create.element('iframe');
iframe.style.display = 'block';
iframe.src = 'about:blank';
iframe.className = 'jodit_wysiwyg_iframe';
iframe.setAttribute('allowtransparency', 'true');
iframe.setAttribute('tabindex', editor.options.tabIndex.toString());
iframe.setAttribute('frameborder', '0');
editor.workplace.appendChild(iframe);
editor.iframe = iframe;
await editor.events.fire(
'generateDocumentStructure.iframe',
null,
editor
);
const doc = (editor.iframe.contentWindow as Window).document;
editor.editorDocument = doc;
editor.editorWindow = editor.iframe.contentWindow as Window;
editor.create.inside.setDocument(doc);
editor.editor = doc.body as HTMLBodyElement;
if (editor.options.height === 'auto') {
doc.documentElement &&
(doc.documentElement.style.overflowY = 'hidden');
const resizeIframe = throttle(() => {
if (
editor.editor &&
editor.iframe &&
editor.options.height === 'auto'
) {
css(
editor.iframe,
'height',
editor.editor.offsetHeight
);
}
}, editor.defaultTimeout / 2);
editor.events
.on('change afterInit afterSetMode resize', resizeIframe)
.on(
[
editor.iframe,
editor.editorWindow,
doc.documentElement
],
'load',
resizeIframe
)
.on(doc, 'readystatechange DOMContentLoaded', resizeIframe);
}
(e => {
e.matches || (e.matches = Element.prototype.matches); // fix inside iframe polifill
})((editor.editorWindow as any).Element.prototype);
// throw events in our world
if (editor.editorDocument.documentElement) {
editor.events
.on(
editor.editorDocument.documentElement,
'mousedown touchend',
() => {
if (!editor.selection.isFocused()) {
editor.selection.focus();
editor.selection.setCursorIn(editor.editor);
}
}
)
.on(
editor.editorWindow,
'mousedown touchstart keydown keyup touchend click mouseup mousemove scroll',
(e: Event) => {
editor.events &&
editor.events.fire &&
editor.events.fire(editor.ownerWindow, e);
}
);
}
return false;
});
}