inital commit

This commit is contained in:
2026-01-01 15:25:19 +05:30
commit f0ae49465a
36361 changed files with 4894111 additions and 0 deletions

26
node_modules/jodit/esm/plugins/enter/enter.d.ts generated vendored Normal file
View File

@@ -0,0 +1,26 @@
/*!
* 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
*/
/**
* [[include:plugins/enter/README.md]]
* @packageDocumentation
* @module plugins/enter
*/
import type { IJodit } from "../../types/index";
import { Plugin } from "../../core/plugin/plugin";
import "./interface";
/**
* One of most important core plugins. It is responsible for all the browsers to have the same effect when the Enter
* button is pressed. By default, it should insert the <p>
*/
export declare class enter extends Plugin {
/** @override */
protected afterInit(editor: IJodit): void;
protected onEnterKeyDown(event: KeyboardEvent): false | void;
private onEnter;
private __isEmptyListLeaf;
/** @override */
beforeDestruct(editor: IJodit): void;
}

105
node_modules/jodit/esm/plugins/enter/enter.js generated vendored Normal file
View File

@@ -0,0 +1,105 @@
/*!
* 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 { BR, KEY_ENTER, PARAGRAPH } from "../../core/constants.js";
import { watch } from "../../core/decorators/index.js";
import { Dom } from "../../core/dom/dom.js";
import { pluginSystem } from "../../core/global.js";
import { isBoolean } from "../../core/helpers/checker/is-boolean.js";
import { Plugin } from "../../core/plugin/plugin.js";
import "./interface.js";
import { checkBR, checkUnsplittableBox, getBlockWrapper, hasPreviousBlock, insertParagraph, moveCursorOutFromSpecialTags, processEmptyLILeaf, splitFragment, wrapText } from "./helpers/index.js";
/**
* One of most important core plugins. It is responsible for all the browsers to have the same effect when the Enter
* button is pressed. By default, it should insert the <p>
*/
export class enter extends Plugin {
/** @override */
afterInit(editor) {
// use 'enter' option if no set
const defaultTag = editor.o.enter.toLowerCase();
const brMode = defaultTag === BR.toLowerCase();
if (!editor.o.enterBlock) {
editor.o.enterBlock = brMode
? PARAGRAPH
: defaultTag;
}
editor.registerCommand('enter', (command, value, event = {}) => this.onEnter(event));
}
onEnterKeyDown(event) {
if (event.key === KEY_ENTER) {
const editor = this.j;
const beforeEnter = editor.e.fire('beforeEnter', event);
if (beforeEnter !== undefined) {
return beforeEnter;
}
if (!editor.s.isCollapsed()) {
editor.execCommand('Delete');
}
editor.s.focus();
this.onEnter(event);
editor.e.fire('afterEnter', event);
editor.synchronizeValues(); // fire change
return false;
}
}
onEnter(event) {
const { jodit } = this;
const fake = jodit.createInside.fake();
try {
Dom.safeInsertNode(jodit.s.range, fake);
moveCursorOutFromSpecialTags(jodit, fake, ['a']);
let block = getBlockWrapper(fake, jodit);
const isLi = Dom.isLeaf(block);
// if use <br> defaultTag for break line or when was entered SHIFt key or in <td> or <th> or <blockquote>
if ((!isLi || (event === null || event === void 0 ? void 0 : event.shiftKey)) &&
checkBR(fake, jodit, event === null || event === void 0 ? void 0 : event.shiftKey)) {
return false;
}
// wrap no wrapped element
if (!block && !hasPreviousBlock(fake, jodit)) {
block = wrapText(fake, jodit);
}
if (!block) {
insertParagraph(fake, jodit, isLi ? 'li' : jodit.o.enter);
return false;
}
if (!checkUnsplittableBox(fake, jodit, block)) {
return false;
}
if (isLi && this.__isEmptyListLeaf(block)) {
processEmptyLILeaf(fake, jodit, block);
return false;
}
splitFragment(fake, jodit, block);
}
finally {
fake.isConnected && jodit.s.setCursorBefore(fake);
Dom.safeRemove(fake);
}
}
__isEmptyListLeaf(li) {
const result = this.j.e.fire('enterIsEmptyListLeaf', li);
return isBoolean(result) ? result : Dom.isEmpty(li);
}
/** @override */
beforeDestruct(editor) {
editor.e.off('keydown.enter');
}
}
__decorate([
watch(':keydown.enter')
], enter.prototype, "onEnterKeyDown", null);
pluginSystem.add('enter', enter);

View File

@@ -0,0 +1,14 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit } from "../../../types/index";
/**
* Checks the possibility and necessity of inserting a BR instead of a block
* @private
*/
export declare function checkBR(fake: Text, jodit: IJodit, shiftKeyPressed?: boolean): boolean;

View File

@@ -0,0 +1,57 @@
/*!
* 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 { BR } from "../../../core/constants.js";
import { Dom } from "../../../core/dom/dom.js";
import { scrollIntoViewIfNeeded } from "../../../core/helpers/utils/scroll-into-view.js";
/**
* Checks the possibility and necessity of inserting a BR instead of a block
* @private
*/
export function checkBR(fake, jodit, shiftKeyPressed) {
const isMultiLineBlock = Boolean(Dom.closest(fake, ['pre', 'blockquote'], jodit.editor));
const isCell = !isMultiLineBlock && Dom.closest(fake, ['td', 'th'], jodit.editor);
const isBRMode = jodit.o.enter.toLowerCase() === BR.toLowerCase();
// if you use <br> defaultTag for break line or when was entered SHIFt key or in <td> or <th> or <blockquote>
if (isBRMode ||
isCell ||
(shiftKeyPressed && !isMultiLineBlock) ||
(!shiftKeyPressed && isMultiLineBlock)) {
// 2 BR before
if (isMultiLineBlock && checkSeveralBR(fake)) {
return false;
}
const br = jodit.createInside.element('br');
Dom.before(fake, br);
if (!Dom.findNotEmptySibling(br, false)) {
const clone = br.cloneNode();
Dom.after(br, clone);
Dom.before(clone, fake);
}
scrollIntoViewIfNeeded(br, jodit.editor, jodit.ed);
return true;
}
return false;
}
function checkSeveralBR(fake) {
// 2 BR before
const preBr = brBefore(brBefore(fake));
if (preBr) {
Dom.safeRemove(brBefore(fake));
Dom.safeRemove(preBr);
return true;
}
return false;
}
function brBefore(start) {
if (!start) {
return false;
}
const prev = Dom.findSibling(start, true);
if (!prev || !Dom.isTag(prev, 'br')) {
return false;
}
return prev;
}

View File

@@ -0,0 +1,14 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit } from "../../../types/index";
/**
* Inside quote/tables cell, etc. you can't split so just add br
* @private
*/
export declare function checkUnsplittableBox(fake: Text, jodit: IJodit, currentBox: HTMLElement): boolean;

View File

@@ -0,0 +1,17 @@
/*!
* 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 "../../../core/dom/dom.js";
/**
* Inside quote/tables cell, etc. you can't split so just add br
* @private
*/
export function checkUnsplittableBox(fake, jodit, currentBox) {
if (!Dom.canSplitBlock(currentBox)) {
Dom.before(fake, jodit.createInside.element('br'));
return false;
}
return true;
}

View File

@@ -0,0 +1,14 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit, Nullable } from "../../../types/index";
/**
* Finds a suitable parent block container
* @private
*/
export declare function getBlockWrapper(fake: Node | null, jodit: IJodit, tagReg?: RegExp): Nullable<HTMLElement>;

View File

@@ -0,0 +1,29 @@
/*!
* 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 * as consts from "../../../core/constants.js";
import { Dom } from "../../../core/dom/dom.js";
/**
* Finds a suitable parent block container
* @private
*/
export function getBlockWrapper(fake, jodit, tagReg = consts.IS_BLOCK) {
let node = fake;
const root = jodit.editor;
do {
if (!node || node === root) {
break;
}
if (tagReg.test(node.nodeName)) {
if (Dom.isLeaf(node)) {
return node;
}
return (getBlockWrapper(node.parentNode, jodit, /^li$/i) ||
node);
}
node = node.parentNode;
} while (node && node !== root);
return null;
}

View File

@@ -0,0 +1,13 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit } from "../../../types/index";
/**
* @private
*/
export declare function hasPreviousBlock(fake: Text, jodit: IJodit): boolean;

View File

@@ -0,0 +1,12 @@
/*!
* 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 "../../../core/dom/dom.js";
/**
* @private
*/
export function hasPreviousBlock(fake, jodit) {
return Boolean(Dom.prev(fake, elm => Dom.isBlock(elm) || Dom.isImage(elm), jodit.editor));
}

View File

@@ -0,0 +1,17 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
export * from "./check-br";
export * from "./check-unsplittable-box";
export * from "./get-block-wrapper";
export * from "./has-previous-block";
export * from "./insert-paragraph";
export * from "./move-cursor-out-from-specal-tags";
export * from "./process-empty-li-leaf";
export * from "./split-fragment";
export * from "./wrap-text";

17
node_modules/jodit/esm/plugins/enter/helpers/index.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
export * from "./check-br.js";
export * from "./check-unsplittable-box.js";
export * from "./get-block-wrapper.js";
export * from "./has-previous-block.js";
export * from "./insert-paragraph.js";
export * from "./move-cursor-out-from-specal-tags.js";
export * from "./process-empty-li-leaf.js";
export * from "./split-fragment.js";
export * from "./wrap-text.js";

View File

@@ -0,0 +1,14 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { HTMLTagNames, IJodit } from "../../../types/index";
/**
* Insert default paragraph
* @private
*/
export declare function insertParagraph(fake: Text, editor: IJodit, wrapperTag: HTMLTagNames, style?: CSSStyleDeclaration): HTMLElement;

View File

@@ -0,0 +1,24 @@
/*!
* 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 "../../../core/dom/dom.js";
import { scrollIntoViewIfNeeded } from "../../../core/helpers/utils/scroll-into-view.js";
/**
* Insert default paragraph
* @private
*/
export function insertParagraph(fake, editor, wrapperTag, style) {
const isBR = wrapperTag.toLowerCase() === 'br', { createInside } = editor, p = createInside.element(wrapperTag), br = createInside.element('br');
if (!isBR) {
p.appendChild(br);
}
if (style && style.cssText) {
p.setAttribute('style', style.cssText);
}
Dom.after(fake, p);
Dom.before(isBR ? p : br, fake);
scrollIntoViewIfNeeded(p, editor.editor, editor.ed);
return p;
}

View File

@@ -0,0 +1,14 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { HTMLTagNames, IJodit } from "../../../types/index";
/**
* Checks if the cursor is on the edge of a special tag and exits if so
* @private
*/
export declare function moveCursorOutFromSpecialTags(jodit: IJodit, fake: Text, tags: HTMLTagNames[]): void;

View File

@@ -0,0 +1,22 @@
/*!
* 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 "../../../core/dom/dom.js";
/**
* Checks if the cursor is on the edge of a special tag and exits if so
* @private
*/
export function moveCursorOutFromSpecialTags(jodit, fake, tags) {
const { s } = jodit;
const link = Dom.closest(fake, tags, jodit.editor);
if (link) {
if (s.cursorOnTheRight(link, fake)) {
Dom.after(link, fake);
}
else if (s.cursorOnTheLeft(link, fake)) {
Dom.before(link, fake);
}
}
}

View File

@@ -0,0 +1,14 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit } from "../../../types/index";
/**
* Handles pressing the Enter key inside an empty LI inside a list
* @private
*/
export declare function processEmptyLILeaf(fake: Text, jodit: IJodit, li: HTMLElement): void;

View File

@@ -0,0 +1,40 @@
/*!
* 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 "../../../core/dom/dom.js";
import { $$ } from "../../../core/helpers/utils/selector.js";
import { insertParagraph } from "./insert-paragraph.js";
/**
* Handles pressing the Enter key inside an empty LI inside a list
* @private
*/
export function processEmptyLILeaf(fake, jodit, li) {
const list = Dom.closest(li, ['ol', 'ul'], jodit.editor);
if (!list) {
return;
}
const parentLi = list.parentElement, listInsideLeaf = Dom.isLeaf(parentLi);
const container = listInsideLeaf ? parentLi : list;
// Empty element in the middle of the list
const leftRange = jodit.s.createRange();
leftRange.setStartAfter(li);
leftRange.setEndAfter(list);
const rightPart = leftRange.extractContents();
Dom.after(container, fake);
Dom.safeRemove(li);
if (!$$('li', list).length) {
Dom.safeRemove(list);
}
const newLi = insertParagraph(fake, jodit, listInsideLeaf ? 'li' : jodit.o.enter);
if (!rightPart.querySelector('li')) {
return;
}
if (listInsideLeaf) {
newLi.appendChild(rightPart);
}
else {
Dom.after(newLi, rightPart);
}
}

View File

@@ -0,0 +1,15 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit } from "../../../types/index";
/**
* Splits a block element into two parts
* and adds a new default block in the middle/start/end
* @private
*/
export declare function splitFragment(fake: Text, jodit: IJodit, block: HTMLElement): void;

View File

@@ -0,0 +1,36 @@
/*!
* 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 "../../../core/dom/dom.js";
import { scrollIntoViewIfNeeded } from "../../../core/helpers/utils/scroll-into-view.js";
import { insertParagraph } from "./insert-paragraph.js";
/**
* Splits a block element into two parts
* and adds a new default block in the middle/start/end
* @private
*/
export function splitFragment(fake, jodit, block) {
const sel = jodit.s, { enter } = jodit.o;
const defaultTag = enter.toLowerCase();
const isLi = Dom.isLeaf(block);
const canSplit = block.tagName.toLowerCase() === defaultTag || isLi;
const cursorOnTheRight = sel.cursorOnTheRight(block, fake);
const cursorOnTheLeft = sel.cursorOnTheLeft(block, fake);
if (!canSplit && (cursorOnTheRight || cursorOnTheLeft)) {
if (cursorOnTheRight) {
Dom.after(block, fake);
}
else {
Dom.before(block, fake);
}
insertParagraph(fake, jodit, defaultTag);
if (cursorOnTheLeft && !cursorOnTheRight) {
Dom.prepend(block, fake);
}
return;
}
const newP = sel.splitSelection(block, fake);
scrollIntoViewIfNeeded(newP, jodit.editor, jodit.ed);
}

View File

@@ -0,0 +1,15 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
import type { IJodit } from "../../../types/index";
/**
* If there is no container outside,
* then we wrap all the nearest inline nodes in a container
* @private
*/
export declare function wrapText(fake: Text, jodit: IJodit): HTMLElement;

View File

@@ -0,0 +1,26 @@
/*!
* 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 "../../../core/dom/dom.js";
/**
* If there is no container outside,
* then we wrap all the nearest inline nodes in a container
* @private
*/
export function wrapText(fake, jodit) {
let needWrap = fake;
Dom.up(needWrap, node => {
if (node && node.hasChildNodes() && node !== jodit.editor) {
needWrap = node;
}
}, jodit.editor);
const currentBox = Dom.wrapInline(needWrap, jodit.o.enter, jodit);
if (Dom.isEmpty(currentBox)) {
const br = jodit.createInside.element('br');
currentBox.appendChild(br);
Dom.before(br, fake);
}
return currentBox;
}

36
node_modules/jodit/esm/plugins/enter/interface.d.ts generated vendored Normal file
View File

@@ -0,0 +1,36 @@
/*!
* 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
*/
/**
* @module plugins/enter
*/
declare module 'jodit/types/events' {
interface IEventEmitter {
/**
* Fired on processing `Enter` key. If return some value, plugin `enter` will do nothing.
* if return false - prevent default Enter behavior
*/
on(event: 'beforeEnter', callback: (e: KeyboardEvent) => void | false): this;
/**
* Fired after processing `Enter` key.
*/
on(event: 'afterEnter', callback: (e: KeyboardEvent) => void): this;
/**
* When inside the list there is a click on an empty element of the list, then it is deleted if empty.
* This event can handle this situation.
* @example
* ```javascript
* Jodit.make('#editor', {
* events: {
* enterIsEmptyListLeaf(li){
* return Jodit.ns.Dom.isEmpty(li);
* }
* }
* });
* ```
*/
on(event: 'enterIsEmptyListLeaf', callback: (li: HTMLElement) => void): this;
}
}

1
node_modules/jodit/esm/plugins/enter/interface.js generated vendored Normal file
View File

@@ -0,0 +1 @@
"use strict";