UNPKG

jodit

Version:

Jodit is an awesome and useful wysiwyg editor with filebrowser

147 lines (146 loc) 5.23 kB
/*! * 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 */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { autobind } from "../../core/decorators/index.js"; import { Dom } from "../../core/dom/index.js"; import { pluginSystem } from "../../core/global.js"; import { isString } from "../../core/helpers/checker/is-string.js"; import { Plugin } from "../../core/plugin/index.js"; import "./config.js"; /** * Wrap single text nodes in block wrapper */ class wrapNodes extends Plugin { constructor() { super(...arguments); /** * Found Node which should be wrapped */ this.isSuitableStart = (n) => { var _a; return (Dom.isText(n) && isString(n.nodeValue) && (/[^\s]/.test(n.nodeValue) || (((_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === n && this.isSuitable(n.nextSibling)))) || (this.isNotWrapped(n) && !Dom.isTemporary(n)); }; /** * Node should add in a block element */ this.isSuitable = (n) => Dom.isText(n) || this.isNotWrapped(n); /** * Some element which needs to append in block */ this.isNotWrapped = (n) => Dom.isElement(n) && !(Dom.isBlock(n) || Dom.isTag(n, this.j.o.wrapNodes.exclude)); } /** @override **/ afterInit(jodit) { if (jodit.o.enter.toLowerCase() === 'br') { return; } jodit.e .on('drop.wtn focus.wtn keydown.wtn mousedown.wtn afterInit.wtn backSpaceAfterDelete.wtn', this.preprocessInput, { top: true }) .on('afterInit.wtn postProcessSetEditorValue.wtn afterCommitStyle.wtn backSpaceAfterDelete.wtn', this.postProcessSetEditorValue); } /** @override **/ beforeDestruct(jodit) { jodit.e.off('.wtn'); } /** * Process changed value */ postProcessSetEditorValue() { const { jodit } = this; if (!jodit.isEditorMode()) { return; } let child = jodit.editor.firstChild, isChanged = false; while (child) { child = checkAloneListLeaf(child, jodit); if (this.isSuitableStart(child)) { if (!isChanged) { jodit.s.save(); } isChanged = true; const box = jodit.createInside.element(jodit.o.enter); Dom.before(child, box); while (child && this.isSuitable(child)) { const next = child.nextSibling; box.appendChild(child); child = next; } box.normalize(); child = box; } child = child && child.nextSibling; } if (isChanged) { jodit.s.restore(); if (jodit.e.current === 'afterInit') { jodit.e.fire('internalChange'); } } } /** * Process input without parent box */ preprocessInput() { const { jodit } = this, isAfterInitEvent = jodit.e.current === 'afterInit'; if (!jodit.isEditorMode() || jodit.editor.firstChild || (!jodit.o.wrapNodes.emptyBlockAfterInit && isAfterInitEvent)) { return; } const box = jodit.createInside.element(jodit.o.enter); const br = jodit.createInside.element('br'); Dom.append(box, br); Dom.append(jodit.editor, box); jodit.s.isFocused() && jodit.s.setCursorBefore(br); jodit.e.fire('internalChange'); } } __decorate([ autobind ], wrapNodes.prototype, "postProcessSetEditorValue", null); __decorate([ autobind ], wrapNodes.prototype, "preprocessInput", null); function checkAloneListLeaf(child, jodit) { let result = child; let next = child; do { if (Dom.isElement(next) && Dom.isLeaf(next) && !Dom.isList(next.parentElement)) { const nextChild = Dom.findNotEmptySibling(next, false); if (Dom.isTag(result, 'ul')) { result.appendChild(next); } else { result = Dom.wrap(next, 'ul', jodit.createInside); } next = nextChild; } else { break; } } while (next); return result; } pluginSystem.add('wrapNodes', wrapNodes);