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

1551
node_modules/jodit/esm/config.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

903
node_modules/jodit/esm/config.js generated vendored Normal file
View File

@@ -0,0 +1,903 @@
/*!
* 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
*/
/**
* Editor options. These can be configured upon the creation of the editor.
* ```javascript
* const editor = Jodit.make('#editor', {
* toolbar: true,
* buttons: ['bold', 'italic', 'underline']
* // other options
* // ...
* });
* ```
* @packageDocumentation
* @module config
*/
import * as consts from "./core/constants.js";
import { globalDocument, globalWindow, INSERT_AS_HTML } from "./core/constants.js";
let ConfigPrototype = {};
/**
* Default Editor's Configuration
*/
class Config {
constructor() {
/**
* Use cache for heavy methods
*/
this.cache = true;
/**
* Timeout of all asynchronous methods
*/
this.defaultTimeout = 100;
this.namespace = '';
/**
* Editor loads completely without plugins. Useful when debugging your own plugin.
*/
this.safeMode = false;
/**
* Editor's width
*
* @example
* ```javascript
* Jodit.make('.editor', {
* width: '100%',
* })
* ```
* @example
* ```javascript
* Jodit.make('.editor', {
* width: 600, // equivalent for '600px'
* })
* ```
* @example
* ```javascript
* Jodit.make('.editor', {
* width: 'auto', // autosize
* })
* ```
*/
this.width = 'auto';
/**
* Editor's height
*
* @example
* ```javascript
* Jodit.make('.editor', {
* height: '100%',
* })
* ```
* @example
* ```javascript
* Jodit.make('.editor', {
* height: 600, // equivalent for '600px'
* })
* ```
* @example
* ```javascript
* Jodit.make('.editor', {
* height: 'auto', // default - autosize
* })
* ```
*/
this.height = 'auto';
/**
* List of plugins that will be initialized in safe mode.
*
* ```js
* Jodit.make('#editor', {
* safeMode: true,
* safePluginsList: ['about'],
* extraPlugins: ['yourPluginDev']
* });
* ```
*/
this.safePluginsList = [
'about',
'enter',
'backspace',
'size',
'bold',
'hotkeys'
];
/**
* Reserved for the paid version of the editor
*/
this.license = '';
/**
* The name of the preset that will be used to initialize the editor.
* The list of available presets can be found here Jodit.defaultOptions.presets
* ```javascript
* Jodit.make('.editor', {
* preset: 'inline'
* });
* ```
*/
this.preset = 'custom';
this.presets = {
inline: {
inline: true,
toolbar: false,
toolbarInline: true,
toolbarInlineForSelection: true,
showXPathInStatusbar: false,
showCharsCounter: false,
showWordsCounter: false,
showPlaceholder: false
}
};
this.ownerDocument = globalDocument;
/**
* Allows you to specify the window in which the editor will be created. Default - window
* This is necessary if you are creating the editor inside an iframe but the code is running in the parent window
*/
this.ownerWindow = globalWindow;
/**
* Shadow root if Jodit was created in it
*
* ```html
* <div id="editor"></div>
* ```
*
* ```js
* const app = document.getElementById('editor');
* app.attachShadow({ mode: 'open' });
* const root = app.shadowRoot;
*
* root.innerHTML = `
* <link rel="stylesheet" href="./build/jodit.css"/>
* <h1>Jodit example in Shadow DOM</h1>
* <div id="edit"></div>
* `;
*
* const editor = Jodit.make(root.getElementById('edit'), {
* globalFullSize: false,
* shadowRoot: root
* });
* editor.value = '<p>start</p>';
* ```
*/
this.shadowRoot = null;
/**
* z-index For editor
*/
this.zIndex = 0;
/**
* Change the read-only state of the editor
*/
this.readonly = false;
/**
* Change the disabled state of the editor
*/
this.disabled = false;
/**
* In readOnly mode, some buttons can still be useful, for example, the button to view source code or print
*/
this.activeButtonsInReadOnly = [
'source',
'fullsize',
'print',
'about',
'dots',
'selectall'
];
/**
* When the editor is in read-only mode, some commands can still be executed:
* ```javascript
* const editor = Jodit.make('.editor', {
* allowCommandsInReadOnly: ['selectall', 'preview', 'print']
* readonly: true
* });
* editor.execCommand('selectall');// will be selected all content
* editor.execCommand('delete');// but content will not be deleted
* ```
*/
this.allowCommandsInReadOnly = ['selectall', 'preview', 'print'];
/**
* Size of icons in the toolbar (can be "small", "middle", "large")
*
* @example
* ```javascript
* const editor = Jodit.make(".dark_editor", {
* toolbarButtonSize: "small"
* });
* ```
*/
this.toolbarButtonSize = 'middle';
/**
* Allow navigation in the toolbar of the editor by Tab key
*/
this.allowTabNavigation = false;
/**
* Inline editing mode
*/
this.inline = false;
/**
* Theme (can be "dark")
* @example
* ```javascript
* const editor = Jodit.make(".dark_editor", {
* theme: "dark"
* });
* ```
*/
this.theme = 'default';
/**
* if set true, then the current mode is saved in a cookie, and is restored after a reload of the page
*/
this.saveModeInStorage = false;
/**
* Class name that can be appended to the editable area
*
* @see [[Config.iframeCSSLinks]]
* @see [[Config.iframeStyle]]
*
* @example
* ```javascript
* Jodit.make('#editor', {
* editorClassName: 'some_my_class'
* });
* ```
* ```html
* <style>
* .some_my_class p{
* line-height: 16px;
* }
* </style>
* ```
*/
this.editorClassName = false;
/**
* Class name that can be appended to the main editor container
* @example
* ```javascript
* const jodit = Jodit.make('#editor', {
* className: 'some_my_class'
* });
*
* console.log(jodit.container.classList.contains('some_my_class')); // true
* ```
* ```html
* <style>
* .some_my_class {
* max-width: 600px;
* margin: 0 auto;
* }
* </style>
* ```
*/
this.className = false;
/**
* The internal styles of the editable area. They are intended to change
* not the appearance of the editor, but to change the appearance of the content.
* @example
* ```javascript
* Jodit.make('#editor', {
* style: {
* font: '12px Arial',
* color: '#0c0c0c'
* }
* });
* ```
*/
this.style = false;
/**
*
* @example
* ```javascript
* Jodit.make('#editor', {
* editorStyle: {
* font: '12px Arial',
* color: '#0c0c0c'
* }
* });
* ```
*/
this.containerStyle = false;
/**
* Dictionary of variable values in css, a complete list can be found here
* https://github.com/xdan/jodit/blob/main/src/styles/variables.less#L25
*
* @example
* ```js
* const editor = Jodit.make('#editor', {
* styleValues: {
* 'color-text': 'red',
* colorBorder: 'black',
* 'color-panel': 'blue'
* }
* });
* ```
*/
this.styleValues = {};
/**
* After all, changes in editors for textarea will call change trigger
*
* @example
* ```javascript
* const editor = Jodit.make('#editor');
* document.getElementById('editor').addEventListener('change', function () {
* console.log(this.value);
* })
* ```
*/
this.triggerChangeEvent = true;
/**
* The writing direction of the language which is used to create editor content. Allowed values are: ''
* (an empty string) Indicates that content direction will be the same as either the editor UI direction or
* the page element direction. 'ltr' Indicates a Left-To-Right text direction (like in English).
* 'rtl' Indicates a Right-To-Left text direction (like in Arabic).
*
* @example
* ```javascript
* Jodit.make('.editor', {
* direction: 'rtl'
* })
* ```
*/
this.direction = '';
/**
* Language by default. if `auto` language set by document.documentElement.lang ||
* (navigator.language && navigator.language.substr(0, 2)) ||
* (navigator.browserLanguage && navigator.browserLanguage.substr(0, 2)) || 'en'
*
* @example
* ```html
* <!-- include in you page lang file -->
* <script src="jodit/lang/de.js"></script>
* <script>
* var editor = Jodit.make('.editor', {
* language: 'de'
* });
* </script>
* ```
*/
this.language = 'auto';
/**
* if true all Lang.i18n(key) return `{key}`
*
* @example
* ```html
* <script>
* var editor = Jodit.make('.editor', {
* debugLanguage: true
* });
*
* console.log(editor.i18n("Test")); // {Test}
* </script>
* ```
*/
this.debugLanguage = false;
/**
* Collection of language pack data `{en: {'Type something': 'Type something', ...}}`
*
* @example
* ```javascript
* const editor = Jodit.make('#editor', {
* language: 'ru',
* i18n: {
* ru: {
* 'Type something': 'Начните что-либо вводить'
* }
* }
* });
* console.log(editor.i18n('Type something')) //Начните что-либо вводить
* ```
*/
this.i18n = false;
/**
* The tabindex global attribute is an integer indicating if the element can take
* input focus (is focusable), if it should participate to sequential keyboard navigation,
* and if so, at what position. It can take several values
*/
this.tabIndex = -1;
/**
* Boolean, whether the toolbar should be shown.
* Alternatively, a valid css-selector-string to use an element as toolbar container.
*/
this.toolbar = true;
/**
* Boolean, whether the statusbar should be shown.
*/
this.statusbar = true;
/**
* Show tooltip after mouse enter on the button
*/
this.showTooltip = true;
/**
* Delay before show tooltip
*/
this.showTooltipDelay = 200;
/**
* Instead of create custop tooltip - use native title tooltips
*/
this.useNativeTooltip = false;
/**
* Default insert method
* @default insert_as_html
*/
this.defaultActionOnPaste = INSERT_AS_HTML;
// TODO
// autosave: false, // false or url
// autosaveCallback: false, // function
// interval: 60, // seconds
// TODO
/**
* Element that will be created when you press Enter
*/
this.enter = consts.PARAGRAPH;
/**
* When this option is enabled, the editor's content will be placed in an iframe and isolated from the rest of the page.
*
* @example
* ```javascript
* Jodit.make('#editor', {
* iframe: true,
* iframeStyle: 'html{margin: 0px;}body{padding:10px;background:transparent;color:#000;position:relative;z-index:2;\
* user-select:auto;margin:0px;overflow:hidden;}body:after{content:"";clear:both;display:block}';
* });
* ```
*/
this.iframe = false;
/**
* Allow editing the entire HTML document(html, head)
* \> Works together with the iframe option.
* @example
* ```js
* const editor = Jodit.make('#editor', {
* iframe: true,
* editHTMLDocumentMode: true
* });
* editor.value = '<!DOCTYPE html><html lang="en" style="overflow-y:hidden">' +
* '<head><title>Jodit Editor</title></head>' +
* '<body spellcheck="false"><p>Some text</p><p> a </p></body>' +
* '</html>';
* ```
*/
this.editHTMLDocumentMode = false;
/**
* Use when you need to insert new block element
* use enter option if not set
*/
this.enterBlock = this.enter !== 'br' ? this.enter : consts.PARAGRAPH;
/**
* Jodit.MODE_WYSIWYG The HTML editor allows you to write like MSWord,
* Jodit.MODE_SOURCE syntax highlighting source editor
* @example
* ```javascript
* var editor = Jodit.make('#editor', {
* defaultMode: Jodit.MODE_SPLIT
* });
* console.log(editor.getRealMode())
* ```
*/
this.defaultMode = consts.MODE_WYSIWYG;
/**
* Use split mode
*/
this.useSplitMode = false;
/**
* The colors in HEX representation to select a color for the background and for the text in colorpicker
* @example
* ```javascript
* Jodit.make('#editor', {
* colors: ['#ff0000', '#00ff00', '#0000ff']
* })
* ```
*/
this.colors = {
greyscale: [
'#000000',
'#434343',
'#666666',
'#999999',
'#B7B7B7',
'#CCCCCC',
'#D9D9D9',
'#EFEFEF',
'#F3F3F3',
'#FFFFFF'
],
palette: [
'#980000',
'#FF0000',
'#FF9900',
'#FFFF00',
'#00F0F0',
'#00FFFF',
'#4A86E8',
'#0000FF',
'#9900FF',
'#FF00FF'
],
full: [
'#E6B8AF',
'#F4CCCC',
'#FCE5CD',
'#FFF2CC',
'#D9EAD3',
'#D0E0E3',
'#C9DAF8',
'#CFE2F3',
'#D9D2E9',
'#EAD1DC',
'#DD7E6B',
'#EA9999',
'#F9CB9C',
'#FFE599',
'#B6D7A8',
'#A2C4C9',
'#A4C2F4',
'#9FC5E8',
'#B4A7D6',
'#D5A6BD',
'#CC4125',
'#E06666',
'#F6B26B',
'#FFD966',
'#93C47D',
'#76A5AF',
'#6D9EEB',
'#6FA8DC',
'#8E7CC3',
'#C27BA0',
'#A61C00',
'#CC0000',
'#E69138',
'#F1C232',
'#6AA84F',
'#45818E',
'#3C78D8',
'#3D85C6',
'#674EA7',
'#A64D79',
'#85200C',
'#990000',
'#B45F06',
'#BF9000',
'#38761D',
'#134F5C',
'#1155CC',
'#0B5394',
'#351C75',
'#733554',
'#5B0F00',
'#660000',
'#783F04',
'#7F6000',
'#274E13',
'#0C343D',
'#1C4587',
'#073763',
'#20124D',
'#4C1130'
]
};
/**
* The default tab color picker
* @example
* ```javascript
* Jodit.make('#editor2', {
* colorPickerDefaultTab: 'color'
* })
* ```
*/
this.colorPickerDefaultTab = 'background';
/**
* Image size defaults to a larger image
*/
this.imageDefaultWidth = 300;
/**
* Do not display these buttons that are on the list
* @example
* ```javascript
* Jodit.make('#editor2', {
* removeButtons: ['hr', 'source']
* });
* ```
*/
this.removeButtons = [];
/**
* Do not init these plugins
* @example
* ```typescript
* var editor = Jodit.make('.editor', {
* disablePlugins: 'table,iframe'
* });
* //or
* var editor = Jodit.make('.editor', {
* disablePlugins: ['table', 'iframe']
* });
* ```
*/
this.disablePlugins = [];
/**
* Init and download extra plugins
* @example
* ```typescript
* var editor = Jodit.make('.editor', {
* extraPlugins: ['emoji']
* });
* ```
* It will try load %SCRIPT_PATH%/plugins/emoji/emoji.js and after load will try init it
*/
this.extraPlugins = [];
/**
* These buttons list will be added to the option. Buttons
*/
this.extraButtons = [];
/**
* By default, you can only install an icon from the Jodit suite.
* You can add your icon to the set using the `Jodit.modules.Icon.set (name, svg Code)` method.
* But for a declarative declaration, you can use this option.
*
* @example
* ```js
* Jodit.modules.Icon.set('someIcon', '<svg><path.../></svg>');
* const editor = Jodit.make({
* extraButtons: [{
* name: 'someButton',
* icon: 'someIcon'
* }]
* });
*
* @example
* const editor = Jodit.make({
* extraIcons: {
* someIcon: '<svg><path.../></svg>'
* },
* extraButtons: [{
* name: 'someButton',
* icon: 'someIcon'
* }]
* });
* ```
* @example
* ```js
* const editor = Jodit.make({
* extraButtons: [{
* name: 'someButton',
* icon: '<svg><path.../></svg>'
* }]
* });
* ```
*/
this.extraIcons = {};
/**
* Default attributes for created inside editor elements
* @example
* ```js
* const editor2 = Jodit.make('#editor', {
* createAttributes: {
* div: {
* class: 'test'
* },
* ul: function (ul) {
* ul.classList.add('ui-test');
* }
* }
* });
*
* const div2 = editor2.createInside.div();
* expect(div2.className).equals('test');
*
* const ul = editor2.createInside.element('ul');
* expect(ul.className).equals('ui-test');
* ```
* Or JSX in React
* @example
* ```jsx
* import React, {useState, useRef} from 'react';
* import JoditEditor from "jodit-react";
*
* const config = {
* createAttributes: {
* div: {
* class: 'align-center'
* }
* }
* };
*
* <JoditEditor config={config}/>
* ```
*/
this.createAttributes = {
table: {
style: 'border-collapse:collapse;width: 100%;'
}
};
/**
* The width of the editor, accepted as the biggest. Used to the responsive version of the editor
*/
this.sizeLG = 900;
/**
* The width of the editor, accepted as the medium. Used to the responsive version of the editor
*/
this.sizeMD = 700;
/**
* The width of the editor, accepted as the small. Used to the responsive version of the editor
*/
this.sizeSM = 400;
/**
* The list of buttons that appear in the editor's toolbar on large places (≥ options.sizeLG).
* Note - this is not the width of the device, the width of the editor
* @example
* ```javascript
* Jodit.make('#editor', {
* buttons: ['bold', 'italic', 'source'],
* buttonsMD: ['bold', 'italic'],
* buttonsXS: ['bold', 'fullsize'],
* });
* ```
* @example
* ```javascript
* Jodit.make('#editor2', {
* buttons: [{
* name: 'empty',
* icon: 'source',
* exec: function (editor) {
* const dialog = new Jodit.modules.Dialog({}),
* text = editor.c.element('textarea');
*
* dialog.setHeader('Source code');
* dialog.setContent(text);
* dialog.setSize(400, 300);
*
* Jodit.modules.Helpers.css(elm, {
* width: '100%',
* height: '100%'
* })
* dialog.open();
* }
* }]
* });
* ```
* @example
* ```javascript
* Jodit.make('#editor2', {
* buttons: Jodit.defaultOptions.buttons.concat([{
* name: 'listsss',
* iconURL: 'stuf/dummy.png',
* list: {
* h1: 'insert Header 1',
* h2: 'insert Header 2',
* clear: 'Empty editor',
* },
* exec: ({originalEvent, control, btn}) => {
* var key = control.args[0],
* value = control.args[1];
* if (key === 'clear') {
* this.val('');
* return;
* }
* this.s.insertNode(this.c.element(key, ''));
* this.message.info('Was inserted ' + value);
* },
* template: function (key, value) {
* return '<div>' + value + '</div>';
* }
* });
* ```
*/
this.buttons = [
{
group: 'font-style',
buttons: []
},
{
group: 'list',
buttons: []
},
{
group: 'font',
buttons: []
},
'---',
{
group: 'script',
buttons: []
},
{
group: 'media',
buttons: []
},
'\n',
{
group: 'state',
buttons: []
},
{
group: 'clipboard',
buttons: []
},
{
group: 'insert',
buttons: []
},
{
group: 'indent',
buttons: []
},
{
group: 'color',
buttons: []
},
{
group: 'form',
buttons: []
},
'---',
{
group: 'history',
buttons: []
},
{
group: 'search',
buttons: []
},
{
group: 'source',
buttons: []
},
{
group: 'other',
buttons: []
},
{
group: 'info',
buttons: []
}
];
/**
* Some events are called when the editor is initialized, for example, the `afterInit` event.
* So this code won't work:
* ```javascript
* const editor = Jodit.make('#editor');
* editor.events.on('afterInit', () => console.log('afterInit'));
* ```
* You need to do this:
* ```javascript
* Jodit.make('#editor', {
* events: {
* afterInit: () => console.log('afterInit')
* }
* });
* ```
* The option can use any Jodit events, for example:
* ```javascript
* const editor = Jodit.make('#editor', {
* events: {
* hello: (name) => console.log('Hello', name)
* }
* });
* editor.e.fire('hello', 'Mike');
* ```
*/
this.events = {};
/**
* Buttons in toolbat without SVG - only texts
*/
this.textIcons = false;
/**
* Element for dialog container
*/
this.popupRoot = null;
/**
* shows a INPUT[type=color] to open the browser color picker, on the right bottom of widget color picker
*/
this.showBrowserColorPicker = true;
Object.assign(this, ConfigPrototype);
}
static get defaultOptions() {
if (!Config.__defaultOptions) {
Config.__defaultOptions = new Config();
}
return Config.__defaultOptions;
}
}
ConfigPrototype = Config.prototype;
Config.prototype.controls = {};
export { Config };

83
node_modules/jodit/esm/core/async/async.d.ts generated vendored Normal file
View File

@@ -0,0 +1,83 @@
/*!
* 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:core/async/README.md]]
* @packageDocumentation
* @module async
*/
import type { CallbackFunction, IAsync, IAsyncParams, ITimeout, Nullable, RejectablePromise } from "../../types/index";
type Callback = (...args: any[]) => void;
export declare class Async implements IAsync {
private timers;
private __callbacks;
delay(timeout: number | IAsyncParams): RejectablePromise<void>;
setTimeout(callback: Callback, timeout: number | IAsyncParams | undefined, ...args: any[]): number;
updateTimeout(label: string, timeout: number): Nullable<number>;
private clearLabel;
clearTimeout(timer: number): void;
clearTimeout(label: string): void;
/**
* Debouncing enforces that a function not be called again until a certain amount of time has passed without
* it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
*
* @example
* ```javascript
* var jodit = Jodit.make('.editor');
* jodit.e.on('mousemove', jodit.async.debounce(() => {
* // Do expensive things
* }, 100));
* ```
*/
debounce(fn: CallbackFunction, timeout: ITimeout | IAsyncParams, firstCallImmediately?: boolean): CallbackFunction;
private __queueMicrotaskNative;
microDebounce<T extends CallbackFunction>(fn: T, firstCallImmediately?: boolean): T;
/**
* Throttling enforces a maximum number of times a function can be called over time.
* As in "execute this function at most once every 100 milliseconds."
*
* @example
* ```javascript
* var jodit = Jodit.make('.editor');
* jodit.e.on(document.body, 'scroll', jodit.async.throttle(function() {
* // Do expensive things
* }, 100));
* ```
*/
throttle(fn: CallbackFunction, timeout: ITimeout | IAsyncParams, ignore?: boolean): CallbackFunction;
private promisesRejections;
promise<T>(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): RejectablePromise<T>;
/**
* Get Promise status
*/
promiseState(p: Promise<any>): Promise<'pending' | 'fulfilled' | 'rejected'>;
private __requestsIdle;
private __controllers;
private __requestsRaf;
private __requestIdleCallbackNative;
private __cancelIdleCallbackNative;
requestIdleCallback(callback: IdleRequestCallback, options?: {
timeout: number;
}): number;
requestIdlePromise(options?: {
timeout: number;
}): RejectablePromise<number>;
/**
* Try to use scheduler.postTask if it is available https://wicg.github.io/scheduling-apis/
*/
schedulerPostTask<T = void>(task: () => T, options?: {
signal?: AbortSignal;
delay?: number;
priority?: 'background' | 'user-blocking' | 'user-visible';
}): Promise<T>;
schedulerYield(): Promise<void>;
cancelIdleCallback(request: number): void;
requestAnimationFrame(callback: FrameRequestCallback): number;
cancelAnimationFrame(request: number): void;
clear(): void;
isDestructed: boolean;
destruct(): any;
}
export {};

338
node_modules/jodit/esm/core/async/async.js generated vendored Normal file
View File

@@ -0,0 +1,338 @@
/*!
* 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 { IS_ES_NEXT } from "../constants.js";
import { clearTimeout, setTimeout } from "../helpers/async/index.js";
import { isAbortError } from "../helpers/checker/is-abort-error.js";
import { isFunction } from "../helpers/checker/is-function.js";
import { isNumber } from "../helpers/checker/is-number.js";
import { isPlainObject } from "../helpers/checker/is-plain-object.js";
import { isPromise } from "../helpers/checker/is-promise.js";
import { isString } from "../helpers/checker/is-string.js";
import { isVoid } from "../helpers/checker/is-void.js";
import { assert } from "../helpers/utils/assert.js";
import { abort } from "../helpers/utils/error/errors/abort-error.js";
export class Async {
constructor() {
var _a, _b, _c, _d, _e;
this.timers = new Map();
this.__callbacks = new Map();
this.__queueMicrotaskNative = (_a = queueMicrotask === null || queueMicrotask === void 0 ? void 0 : queueMicrotask.bind(window)) !== null && _a !== void 0 ? _a : Promise.resolve().then.bind(Promise.resolve());
this.promisesRejections = new Set();
this.__requestsIdle = new Set();
this.__controllers = new Set();
this.__requestsRaf = new Set();
this.__requestIdleCallbackNative = (_c = (_b = window['requestIdleCallback']) === null || _b === void 0 ? void 0 : _b.bind(window)) !== null && _c !== void 0 ? _c : ((callback, options) => {
var _a;
const start = Date.now();
return this.setTimeout(() => {
callback({
didTimeout: false,
timeRemaining: () => Math.max(0, 50 - (Date.now() - start))
});
}, (_a = options === null || options === void 0 ? void 0 : options.timeout) !== null && _a !== void 0 ? _a : 1);
});
this.__cancelIdleCallbackNative = (_e = (_d = window['cancelIdleCallback']) === null || _d === void 0 ? void 0 : _d.bind(window)) !== null && _e !== void 0 ? _e : ((request) => {
this.clearTimeout(request);
});
this.isDestructed = false;
}
delay(timeout) {
return this.promise(resolve => this.setTimeout(resolve, timeout));
}
setTimeout(callback, timeout, ...args) {
if (this.isDestructed) {
return 0;
}
let options = {};
if (isVoid(timeout)) {
timeout = 0;
}
if (!isNumber(timeout)) {
options = timeout;
timeout = options.timeout || 0;
}
if (options.label) {
this.clearLabel(options.label);
}
const timer = setTimeout(callback, timeout, ...args);
const key = options.label || timer;
this.timers.set(key, timer);
this.__callbacks.set(key, callback);
return timer;
}
updateTimeout(label, timeout) {
assert(label && this.timers.has(label), 'Label does not exist');
if (!label || !this.timers.has(label)) {
return null;
}
const callback = this.__callbacks.get(label);
assert(isFunction(callback), 'Callback is not a function');
return this.setTimeout(callback, { label, timeout });
}
clearLabel(label) {
if (label && this.timers.has(label)) {
clearTimeout(this.timers.get(label));
this.timers.delete(label);
this.__callbacks.delete(label);
}
}
clearTimeout(timerOrLabel) {
if (isString(timerOrLabel)) {
return this.clearLabel(timerOrLabel);
}
clearTimeout(timerOrLabel);
this.timers.delete(timerOrLabel);
this.__callbacks.delete(timerOrLabel);
}
/**
* Debouncing enforces that a function not be called again until a certain amount of time has passed without
* it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
*
* @example
* ```javascript
* var jodit = Jodit.make('.editor');
* jodit.e.on('mousemove', jodit.async.debounce(() => {
* // Do expensive things
* }, 100));
* ```
*/
debounce(fn, timeout, firstCallImmediately = false) {
let timer = 0, fired = false;
const promises = [];
const callFn = (...args) => {
if (!fired) {
timer = 0;
const res = fn(...args);
fired = true;
if (promises.length) {
const runPromises = () => {
promises.forEach(res => res());
promises.length = 0;
};
isPromise(res) ? res.finally(runPromises) : runPromises();
}
}
};
const onFire = (...args) => {
fired = false;
if (!timeout) {
callFn(...args);
}
else {
if (!timer && firstCallImmediately) {
callFn(...args);
}
clearTimeout(timer);
timer = this.setTimeout(() => callFn(...args), isFunction(timeout) ? timeout() : timeout);
this.timers.set(fn, timer);
}
};
return isPlainObject(timeout) && timeout.promisify
? (...args) => {
const promise = this.promise(res => {
promises.push(res);
}).catch((e) => {
if (isAbortError(e)) {
return null;
}
throw e;
});
onFire(...args);
return promise;
}
: onFire;
}
microDebounce(fn, firstCallImmediately = false) {
let scheduled = false;
let needCall = true;
let savedArgs;
return ((...args) => {
savedArgs = args;
if (scheduled) {
needCall = true;
return;
}
needCall = true;
if (firstCallImmediately) {
needCall = false;
fn(...savedArgs);
}
scheduled = true;
this.__queueMicrotaskNative(() => {
scheduled = false;
if (this.isDestructed) {
return;
}
needCall && fn(...savedArgs);
});
});
}
/**
* Throttling enforces a maximum number of times a function can be called over time.
* As in "execute this function at most once every 100 milliseconds."
*
* @example
* ```javascript
* var jodit = Jodit.make('.editor');
* jodit.e.on(document.body, 'scroll', jodit.async.throttle(function() {
* // Do expensive things
* }, 100));
* ```
*/
throttle(fn, timeout, ignore = false) {
let timer = null, needInvoke, callee, lastArgs;
return (...args) => {
needInvoke = true;
lastArgs = args;
if (!timeout) {
fn(...lastArgs);
return;
}
if (!timer) {
callee = () => {
if (needInvoke) {
fn(...lastArgs);
needInvoke = false;
timer = this.setTimeout(callee, isFunction(timeout) ? timeout() : timeout);
this.timers.set(callee, timer);
}
else {
timer = null;
}
};
callee();
}
};
}
promise(executor) {
let rejectCallback = () => { };
const promise = new Promise((resolve, reject) => {
rejectCallback = () => reject(abort('Abort async'));
this.promisesRejections.add(rejectCallback);
executor(resolve, reject);
});
if (!promise.finally && typeof process !== 'undefined' && !IS_ES_NEXT) {
promise.finally = (onfinally) => {
promise.then(onfinally).catch(onfinally);
return promise;
};
}
promise
.finally(() => {
this.promisesRejections.delete(rejectCallback);
})
.catch(() => null);
promise.rejectCallback = rejectCallback;
return promise;
}
/**
* Get Promise status
*/
promiseState(p) {
if (p.status) {
return p.status;
}
// Hi IE11
if (!Promise.race) {
return new Promise(resolve => {
p.then(v => {
resolve('fulfilled');
return v;
}, e => {
resolve('rejected');
throw e;
});
this.setTimeout(() => {
resolve('pending');
}, 100);
});
}
const t = {};
return Promise.race([p, t]).then(v => (v === t ? 'pending' : 'fulfilled'), () => 'rejected');
}
requestIdleCallback(callback, options = { timeout: 100 }) {
const request = this.__requestIdleCallbackNative(callback, options);
this.__requestsIdle.add(request);
return request;
}
requestIdlePromise(options) {
return this.promise(res => {
const request = this.requestIdleCallback(() => res(request), options);
});
}
/**
* Try to use scheduler.postTask if it is available https://wicg.github.io/scheduling-apis/
*/
schedulerPostTask(task, options = {
delay: 0,
priority: 'user-visible'
}) {
const controller = new AbortController();
if (options.signal) {
options.signal.addEventListener('abort', () => controller.abort());
}
this.__controllers.add(controller);
// @ts-ignore
if (typeof globalThis.scheduler !== 'undefined') {
const scheduler = globalThis.scheduler;
const promise = scheduler.postTask(task, {
...options,
signal: controller.signal
});
promise
.finally(() => {
this.__controllers.delete(controller);
})
.catch(() => null);
return promise;
}
return this.promise((resolve, reject) => {
const timeout = this.setTimeout(() => {
try {
resolve(task());
}
catch (e) {
reject(e);
}
this.__controllers.delete(controller);
}, options.delay || 1);
controller.signal.addEventListener('abort', () => {
this.clearTimeout(timeout);
this.__controllers.delete(controller);
reject(abort());
});
});
}
schedulerYield() {
return this.schedulerPostTask(() => { }, { priority: 'user-visible' });
}
cancelIdleCallback(request) {
this.__requestsIdle.delete(request);
return this.__cancelIdleCallbackNative(request);
}
requestAnimationFrame(callback) {
const request = requestAnimationFrame(callback);
this.__requestsRaf.add(request);
return request;
}
cancelAnimationFrame(request) {
this.__requestsRaf.delete(request);
cancelAnimationFrame(request);
}
clear() {
this.__requestsIdle.forEach(key => this.cancelIdleCallback(key));
this.__requestsRaf.forEach(key => this.cancelAnimationFrame(key));
this.__controllers.forEach(controller => controller.abort());
this.timers.forEach(key => clearTimeout(this.timers.get(key)));
this.timers.clear();
this.promisesRejections.forEach(reject => reject());
this.promisesRejections.clear();
}
destruct() {
this.clear();
this.isDestructed = true;
}
}

9
node_modules/jodit/esm/core/async/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* 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 async
*/
export * from "./async";

9
node_modules/jodit/esm/core/async/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* 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 async
*/
export * from "./async.js";

121
node_modules/jodit/esm/core/component/component.d.ts generated vendored Normal file
View File

@@ -0,0 +1,121 @@
/*!
* 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:core/component/README.md]]
* @packageDocumentation
* @module component
*/
import type { ComponentStatus, IAsync, IComponent, IDictionary, Nullable } from "../../types/index";
/**
* The base class of all Jodit UI components. Provides work with a life cycle.
*/
export declare abstract class Component implements IComponent {
static STATUSES: {
readonly beforeInit: "beforeInit";
readonly ready: "ready";
readonly beforeDestruct: "beforeDestruct";
readonly destructed: "destructed";
};
private __componentName;
async: IAsync;
get componentName(): string;
readonly uid: string;
/**
* Calc BEM element class name
* @param elementName - element name in the bem classification
*/
getFullElName(elementName: string): string;
getFullElName(elementName: string, mod: string): string;
getFullElName(elementName: string, mod: string, modValue: boolean | string): string;
/**
* The document in which jodit was created
*/
get ownerDocument(): Document;
/**
* Shortcut for `this.ownerDocument`
*/
get od(): Document;
/**
* The window in which jodit was created
*/
ownerWindow: Window;
get ow(): Window;
/**
* Safe get any field
* @example
* ```js
* private a = {
* b: {
* c: {
* e: {
* g: {
* color: 'red'
* }
* }
* }
* }
* }
*
* this.get('a.b.c.e.g.color'); // Safe access to color
* // instead using optionsl chaining
* this?.a?.b?.c?.e?.g?.color
* ```
*
* @param chain - the path to be traversed in the obj object
* @param obj - the object in which the value is searched
*/
get<T>(chain: string, obj?: IDictionary): Nullable<T>;
/**
* Component is ready for work
*/
get isReady(): boolean;
/**
* Component was destructed
*/
get isDestructed(): boolean;
/**
* The component is currently undergoing destructuring or has already been destroyed.
* Those. you should not the app froze new events on him now or do anything else with him.
*/
get isInDestruct(): boolean;
/**
* Bind destructor to some View
*/
bindDestruct(component: IComponent): this;
abstract className(): string;
protected constructor();
/**
* Destruct component method
*/
destruct(): void;
private __componentStatus;
/**
* Current component status
*/
get componentStatus(): ComponentStatus;
/**
* Setter for current component status
*/
set componentStatus(componentStatus: ComponentStatus);
/**
* Set component status
* @param componentStatus - component status
* @see ComponentStatus
*/
setStatus(componentStatus: ComponentStatus): void;
/**
* Set status recursively on all parents
*/
private setStatusComponent;
/**
* Adds a handler for changing the component's status
*
* @param status - the status at which the callback is triggered
* @param callback - a function that will be called when the status is `status`
*/
hookStatus(status: ComponentStatus, callback: (component: this) => void): void;
static isInstanceOf<T extends Component>(c: unknown | Component, constructorFunc: Function): c is T;
}

190
node_modules/jodit/esm/core/component/component.js generated vendored Normal file
View File

@@ -0,0 +1,190 @@
/*!
* 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 { Async } from "../async/index.js";
import { STATUSES } from "./statuses.js";
import { uniqueUid } from "../global.js";
import { get, getClassName, isFunction, isVoid, kebabCase } from "../helpers/index.js";
const StatusListHandlers = new Map();
/**
* The base class of all Jodit UI components. Provides work with a life cycle.
*/
export class Component {
get componentName() {
if (!this.__componentName) {
this.__componentName =
'jodit-' +
kebabCase((isFunction(this.className) ? this.className() : '') ||
getClassName(this));
}
return this.__componentName;
}
getFullElName(elementName, mod, modValue) {
const result = [this.componentName];
if (elementName) {
elementName = elementName.replace(/[^a-z0-9-]/gi, '-');
result.push(`__${elementName}`);
}
if (mod) {
result.push('_', mod);
result.push('_', isVoid(modValue) ? 'true' : modValue.toString());
}
return result.join('');
}
/**
* The document in which jodit was created
*/
get ownerDocument() {
return this.ow.document;
}
/**
* Shortcut for `this.ownerDocument`
*/
get od() {
return this.ownerDocument;
}
get ow() {
return this.ownerWindow;
}
/**
* Safe get any field
* @example
* ```js
* private a = {
* b: {
* c: {
* e: {
* g: {
* color: 'red'
* }
* }
* }
* }
* }
*
* this.get('a.b.c.e.g.color'); // Safe access to color
* // instead using optionsl chaining
* this?.a?.b?.c?.e?.g?.color
* ```
*
* @param chain - the path to be traversed in the obj object
* @param obj - the object in which the value is searched
*/
get(chain, obj) {
return get(chain, obj || this);
}
/**
* Component is ready for work
*/
get isReady() {
return this.componentStatus === STATUSES.ready;
}
/**
* Component was destructed
*/
get isDestructed() {
return this.componentStatus === STATUSES.destructed;
}
/**
* The component is currently undergoing destructuring or has already been destroyed.
* Those. you should not the app froze new events on him now or do anything else with him.
*/
get isInDestruct() {
return (STATUSES.beforeDestruct === this.componentStatus ||
STATUSES.destructed === this.componentStatus);
}
/**
* Bind destructor to some View
*/
bindDestruct(component) {
component.hookStatus(STATUSES.beforeDestruct, () => !this.isInDestruct && this.destruct());
return this;
}
constructor() {
this.async = new Async();
/**
* The window in which jodit was created
*/
this.ownerWindow = window;
this.__componentStatus = STATUSES.beforeInit;
this.uid = 'jodit-uid-' + uniqueUid();
}
/**
* Destruct component method
*/
destruct() {
this.setStatus(STATUSES.destructed);
if (this.async) {
this.async.destruct();
// @ts-ignore
this.async = undefined;
}
if (StatusListHandlers.get(this)) {
StatusListHandlers.delete(this);
}
// @ts-ignore
this.ownerWindow = undefined;
}
/**
* Current component status
*/
get componentStatus() {
return this.__componentStatus;
}
/**
* Setter for current component status
*/
set componentStatus(componentStatus) {
this.setStatus(componentStatus);
}
/**
* Set component status
* @param componentStatus - component status
* @see ComponentStatus
*/
setStatus(componentStatus) {
return this.setStatusComponent(componentStatus, this);
}
/**
* Set status recursively on all parents
*/
setStatusComponent(componentStatus, component) {
if (componentStatus === this.__componentStatus) {
return;
}
if (component === this) {
this.__componentStatus = componentStatus;
}
const proto = Object.getPrototypeOf(this);
if (proto && isFunction(proto.setStatusComponent)) {
proto.setStatusComponent(componentStatus, component);
}
const statuses = StatusListHandlers.get(this), list = statuses === null || statuses === void 0 ? void 0 : statuses[componentStatus];
if (list && list.length) {
list.forEach(cb => cb(component));
}
}
/**
* Adds a handler for changing the component's status
*
* @param status - the status at which the callback is triggered
* @param callback - a function that will be called when the status is `status`
*/
hookStatus(status, callback) {
let list = StatusListHandlers.get(this);
if (!list) {
list = {};
StatusListHandlers.set(this, list);
}
if (!list[status]) {
list[status] = [];
}
list[status].push(callback);
}
static isInstanceOf(c, constructorFunc) {
return c instanceof constructorFunc;
}
}
Component.STATUSES = STATUSES;

11
node_modules/jodit/esm/core/component/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/*!
* 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 component
*/
export * from "./component";
export * from "./statuses";
export * from "./view-component";

11
node_modules/jodit/esm/core/component/index.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/*!
* 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 component
*/
export * from "./component.js";
export * from "./statuses.js";
export * from "./view-component.js";

14
node_modules/jodit/esm/core/component/statuses.d.ts generated vendored Normal file
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 component
*/
export declare const STATUSES: {
readonly beforeInit: "beforeInit";
readonly ready: "ready";
readonly beforeDestruct: "beforeDestruct";
readonly destructed: "destructed";
};

14
node_modules/jodit/esm/core/component/statuses.js generated vendored Normal file
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 component
*/
export const STATUSES = {
beforeInit: 'beforeInit',
ready: 'ready',
beforeDestruct: 'beforeDestruct',
destructed: 'destructed'
};

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
*/
/**
* @module component
*/
import type { IViewBased, IViewComponent } from "../../types/index";
import { Component } from "./component";
export declare abstract class ViewComponent<T extends IViewBased = IViewBased> extends Component implements IViewComponent<T> {
/**
* Parent View element
*/
jodit: T;
/**
* Shortcut for `this.jodit`
*/
get j(): T;
get defaultTimeout(): number;
i18n(text: string, ...params: Array<string | number>): string;
/**
* Attach component to View
*/
setParentView(jodit: T): this;
constructor(jodit: T);
/** @override */
destruct(): any;
}

View File

@@ -0,0 +1,37 @@
/*!
* 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 { Component } from "./component.js";
export class ViewComponent extends Component {
/**
* Shortcut for `this.jodit`
*/
get j() {
return this.jodit;
}
get defaultTimeout() {
return this.j.defaultTimeout;
}
i18n(text, ...params) {
return this.j.i18n(text, ...params);
}
/**
* Attach component to View
*/
setParentView(jodit) {
this.jodit = jodit;
jodit.components.add(this);
return this;
}
constructor(jodit) {
super();
this.setParentView(jodit);
}
/** @override */
destruct() {
this.j.components.delete(this);
return super.destruct();
}
}

145
node_modules/jodit/esm/core/constants.d.ts generated vendored Normal file
View File

@@ -0,0 +1,145 @@
/*!
* 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
*/
/**
* You can use Jodit constants in your code
* ```javascript
* import { Jodit } from 'jodit';
* console.log(Jodit.constants.IS_IE);
* console.log(Jodit.constants.APP_VERSION);
* ```
* @packageDocumentation
* @module constants
*/
import type { HTMLTagNames, IDictionary } from "../types/index";
export declare const APP_VERSION: string;
export declare const ES: 'es5' | 'es2015' | 'es2018' | 'es2021';
export declare const IS_ES_MODERN: boolean;
export declare const IS_ES_NEXT: boolean;
export declare const IS_PROD: boolean;
export declare let IS_TEST: boolean;
export declare const FAT_MODE: boolean;
export declare const HOMEPAGE: string;
export declare const SET_TEST: () => boolean;
export declare const TOKENS: Record<string, string>;
export declare const INVISIBLE_SPACE = "\uFEFF";
export declare const NBSP_SPACE = "\u00A0";
export declare const INVISIBLE_SPACE_REG_EXP: () => RegExp;
export declare const INVISIBLE_SPACE_REG_EXP_END: () => RegExp;
export declare const INVISIBLE_SPACE_REG_EXP_START: () => RegExp;
export declare const SPACE_REG_EXP: () => RegExp;
export declare const SPACE_REG_EXP_START: () => RegExp;
export declare const SPACE_REG_EXP_END: () => RegExp;
export declare const globalWindow: typeof window;
export declare const globalDocument: Document;
export declare const IS_BLOCK: RegExp;
export declare const IS_INLINE: RegExp;
export declare const LIST_TAGS: Set<"ol" | "ul">;
export declare const INSEPARABLE_TAGS: Set<HTMLTagNames>;
export declare const NO_EMPTY_TAGS: Set<HTMLTagNames>;
export declare const KEY_META = "Meta";
export declare const KEY_BACKSPACE = "Backspace";
export declare const KEY_TAB = "Tab";
export declare const KEY_ENTER = "Enter";
export declare const KEY_ESC = "Escape";
export declare const KEY_ALT = "Alt";
export declare const KEY_LEFT = "ArrowLeft";
export declare const KEY_UP = "ArrowUp";
export declare const KEY_RIGHT = "ArrowRight";
export declare const KEY_DOWN = "ArrowDown";
export declare const KEY_SPACE = "Space";
export declare const KEY_DELETE = "Delete";
export declare const KEY_F3 = "F3";
export declare const NEARBY = 5;
export declare const ACCURACY = 10;
export declare const COMMAND_KEYS: string[];
export declare const BR = "br";
export declare const PARAGRAPH = "p";
/**
* WYSIWYG editor mode
*/
export declare const MODE_WYSIWYG = 1;
/**
* html editor mode
*/
export declare const MODE_SOURCE = 2;
/**
* Source code editor and HTML editor both like
* @see http://getuikit.com/docs/htmleditor.html|this
*/
export declare const MODE_SPLIT = 3;
/**
* Is Internet Explorer
*/
export declare const IS_IE: boolean;
/**
* For IE11 it will be 'text'. Need for dataTransfer.setData
*/
export declare const TEXT_PLAIN: string;
export declare const TEXT_HTML: string;
export declare const TEXT_RTF: string;
export declare const MARKER_CLASS = "jodit-selection_marker";
export declare const EMULATE_DBLCLICK_TIMEOUT = 300;
/**
* Paste the copied text as HTML, all content will be pasted exactly as it was on the clipboard.
* So how would you copy its code directly into the source document.
* ```
* <h1 style="color:red">test</h1>
* ```
* Will be inserted into the document as
* ```
* <h1 style="color:red">test</h1>
* ```
*/
export declare const INSERT_AS_HTML = "insert_as_html";
/**
* Same as [[INSERT_AS_HTML]], but content will be stripped of extra styles and empty tags
* ```html
* <h1 style="color:red">test</h1>
* ```
* Will be inserted into the document as
* ```html
* <h1>test</h1>
* ```
*/
export declare const INSERT_CLEAR_HTML = "insert_clear_html";
/**
* The contents of the clipboard will be pasted into the document as plain text, i.e. all tags will be displayed as text.
* ```html
* <h1>test</h1>
* ```
* Will be inserted into the document as
* ```html
* &gt;&lt;h1&gt;test&lt;/h1&gt;
* ```
*/
export declare const INSERT_AS_TEXT = "insert_as_text";
/**
* All tags will be stripped:
* ```html
* <h1>test</h1>
* ```
* Will be inserted into the document as
* ```html
* test
* ```
*/
export declare const INSERT_ONLY_TEXT = "insert_only_text";
export declare const SAFE_COUNT_CHANGE_CALL = 10;
export declare const IS_MAC: boolean;
export declare const KEY_ALIASES: IDictionary<string>;
/**
* Path to the current script
*/
export declare const BASE_PATH: string;
/**
* Current script is minified
*/
export declare const BASE_PATH_IS_MIN: boolean;
export declare const TEMP_ATTR = "data-jodit-temp";
export declare const lang: IDictionary<IDictionary<string>>;
export declare const CLIPBOARD_ID = "clipboard";
export declare const SOURCE_CONSUMER = "source-consumer";
export declare const PASSIVE_EVENTS: Set<string>;

229
node_modules/jodit/esm/core/constants.js generated vendored Normal file
View File

@@ -0,0 +1,229 @@
/*!
* 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
*/
export const APP_VERSION = "4.7.9";
// prettier-ignore
export const ES = "es2020";
export const IS_ES_MODERN = true;
export const IS_ES_NEXT = true;
export const IS_PROD = true;
export let IS_TEST = false;
export const FAT_MODE = true;
export const HOMEPAGE = "https://xdsoft.net/jodit/";
export const SET_TEST = () => (IS_TEST = true);
export const TOKENS = {};
export const INVISIBLE_SPACE = '\uFEFF';
export const NBSP_SPACE = '\u00A0';
export const INVISIBLE_SPACE_REG_EXP = () => /[\uFEFF]/g;
export const INVISIBLE_SPACE_REG_EXP_END = () => /[\uFEFF]+$/g;
export const INVISIBLE_SPACE_REG_EXP_START = () => /^[\uFEFF]+/g;
export const SPACE_REG_EXP = () => /[\s\n\t\r\uFEFF\u200b]+/g;
export const SPACE_REG_EXP_START = () => /^[\s\n\t\r\uFEFF\u200b]+/g;
export const SPACE_REG_EXP_END = () => /[\s\n\t\r\uFEFF\u200b]+$/g;
export const globalWindow = typeof window !== 'undefined' ? window : undefined;
export const globalDocument = typeof document !== 'undefined'
? document
: undefined;
export const IS_BLOCK = /^(ADDRESS|ARTICLE|ASIDE|BLOCKQUOTE|CANVAS|DD|DFN|DIV|DL|DT|FIELDSET|FIGCAPTION|FIGURE|FOOTER|FORM|H[1-6]|HEADER|HGROUP|HR|LI|MAIN|NAV|NOSCRIPT|OUTPUT|P|PRE|RUBY|SCRIPT|STYLE|OBJECT|OL|SECTION|IFRAME|JODIT|JODIT-MEDIA|UL|TR|TD|TH|TBODY|THEAD|TFOOT|TABLE|BODY|HTML|VIDEO)$/i;
export const IS_INLINE = /^(STRONG|SPAN|I|EM|B|SUP|SUB|A|U)$/i;
export const LIST_TAGS = new Set(['ul', 'ol']);
const __UNSEPARABLE_TAGS = [
'img',
'video',
'svg',
'iframe',
'script',
'input',
'textarea',
'link',
'jodit',
'jodit-media'
];
export const INSEPARABLE_TAGS = new Set([
...__UNSEPARABLE_TAGS,
'br',
'hr'
]);
export const NO_EMPTY_TAGS = new Set(__UNSEPARABLE_TAGS);
export const KEY_META = 'Meta';
export const KEY_BACKSPACE = 'Backspace';
export const KEY_TAB = 'Tab';
export const KEY_ENTER = 'Enter';
export const KEY_ESC = 'Escape';
export const KEY_ALT = 'Alt';
export const KEY_LEFT = 'ArrowLeft';
export const KEY_UP = 'ArrowUp';
export const KEY_RIGHT = 'ArrowRight';
export const KEY_DOWN = 'ArrowDown';
export const KEY_SPACE = 'Space';
export const KEY_DELETE = 'Delete';
export const KEY_F3 = 'F3';
export const NEARBY = 5;
export const ACCURACY = 10;
export const COMMAND_KEYS = [
KEY_META,
KEY_BACKSPACE,
KEY_DELETE,
KEY_UP,
KEY_DOWN,
KEY_RIGHT,
KEY_LEFT,
KEY_ENTER,
KEY_ESC,
KEY_F3,
KEY_TAB
];
export const BR = 'br';
export const PARAGRAPH = 'p';
/**
* WYSIWYG editor mode
*/
export const MODE_WYSIWYG = 1;
/**
* html editor mode
*/
export const MODE_SOURCE = 2;
/**
* Source code editor and HTML editor both like
* @see http://getuikit.com/docs/htmleditor.html|this
*/
export const MODE_SPLIT = 3;
/**
* Is Internet Explorer
*/
export const IS_IE = typeof navigator !== 'undefined' &&
(navigator.userAgent.indexOf('MSIE') !== -1 ||
/rv:11.0/i.test(navigator.userAgent));
/**
* For IE11 it will be 'text'. Need for dataTransfer.setData
*/
export const TEXT_PLAIN = IS_IE ? 'text' : 'text/plain';
export const TEXT_HTML = IS_IE ? 'html' : 'text/html';
export const TEXT_RTF = IS_IE ? 'rtf' : 'text/rtf';
export const MARKER_CLASS = 'jodit-selection_marker';
export const EMULATE_DBLCLICK_TIMEOUT = 300;
/**
* Paste the copied text as HTML, all content will be pasted exactly as it was on the clipboard.
* So how would you copy its code directly into the source document.
* ```
* <h1 style="color:red">test</h1>
* ```
* Will be inserted into the document as
* ```
* <h1 style="color:red">test</h1>
* ```
*/
export const INSERT_AS_HTML = 'insert_as_html';
/**
* Same as [[INSERT_AS_HTML]], but content will be stripped of extra styles and empty tags
* ```html
* <h1 style="color:red">test</h1>
* ```
* Will be inserted into the document as
* ```html
* <h1>test</h1>
* ```
*/
export const INSERT_CLEAR_HTML = 'insert_clear_html';
/**
* The contents of the clipboard will be pasted into the document as plain text, i.e. all tags will be displayed as text.
* ```html
* <h1>test</h1>
* ```
* Will be inserted into the document as
* ```html
* &gt;&lt;h1&gt;test&lt;/h1&gt;
* ```
*/
export const INSERT_AS_TEXT = 'insert_as_text';
/**
* All tags will be stripped:
* ```html
* <h1>test</h1>
* ```
* Will be inserted into the document as
* ```html
* test
* ```
*/
export const INSERT_ONLY_TEXT = 'insert_only_text';
export const SAFE_COUNT_CHANGE_CALL = 10;
export const IS_MAC = typeof globalWindow !== 'undefined' &&
/Mac|iPod|iPhone|iPad/.test(globalWindow.navigator.platform);
export const KEY_ALIASES = {
add: '+',
break: 'pause',
cmd: 'meta',
command: 'meta',
ctl: 'control',
ctrl: 'control',
del: 'delete',
down: 'arrowdown',
esc: 'escape',
ins: 'insert',
left: 'arrowleft',
mod: IS_MAC ? 'meta' : 'control',
opt: 'alt',
option: 'alt',
return: 'enter',
right: 'arrowright',
space: 'space',
spacebar: 'space',
up: 'arrowup',
win: 'meta',
windows: 'meta'
};
const removeScriptName = (src) => {
const parts = src.split('/');
const isMin = typeof false === 'boolean'
? false : /\.min\.js/.test(src);
if (/\.js/.test(parts[parts.length - 1])) {
return {
basePath: parts.slice(0, parts.length - 1).join('/') + '/',
isMin
};
}
return {
basePath: src,
isMin
};
};
const { basePath, isMin } = (() => {
if (typeof document === 'undefined') {
return {
basePath: '',
isMin: Boolean(false)
};
}
const script = globalDocument.currentScript;
if (script) {
return removeScriptName(script.src);
}
const scripts = globalDocument.querySelectorAll('script[src]');
if (scripts && scripts.length) {
return removeScriptName(scripts[scripts.length - 1].src);
}
return removeScriptName(globalWindow.location.href);
})();
/**
* Path to the current script
*/
export const BASE_PATH = basePath;
/**
* Current script is minified
*/
export const BASE_PATH_IS_MIN = isMin;
export const TEMP_ATTR = 'data-jodit-temp';
export const lang = {};
export const CLIPBOARD_ID = 'clipboard';
export const SOURCE_CONSUMER = 'source-consumer';
export const PASSIVE_EVENTS = new Set([
'touchstart',
'touchend',
'scroll',
'mousewheel',
'mousemove',
'touchmove'
]);

62
node_modules/jodit/esm/core/create/create.d.ts generated vendored Normal file
View File

@@ -0,0 +1,62 @@
/*!
* 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:core/create/README.md]]
* @packageDocumentation
* @module create
*/
import type { Attributes, CanUndef, Children, ICreate, IDictionary, NodeFunction } from "../../types/index";
export declare class Create implements ICreate {
readonly document: Document | (() => Document);
readonly createAttributes?: CanUndef<IDictionary<Attributes | NodeFunction>>;
private get doc();
constructor(document: Document | (() => Document), createAttributes?: CanUndef<IDictionary<Attributes | NodeFunction>>);
element<K extends keyof HTMLElementTagNameMap>(tagName: K, children?: Children): HTMLElementTagNameMap[K];
element<K extends keyof HTMLElementTagNameMap>(tagName: K, attributes?: Attributes, children?: Children): HTMLElementTagNameMap[K];
div(className?: string, childrenOrAttributes?: Children): HTMLDivElement;
div(className?: string, childrenOrAttributes?: Attributes, children?: Children): HTMLDivElement;
sandbox(): [
HTMLElement,
HTMLIFrameElement
];
span(className?: string, childrenOrAttributes?: Children): HTMLSpanElement;
span(className?: string, childrenOrAttributes?: Attributes, children?: Children): HTMLSpanElement;
a(className?: string, children?: Children): HTMLAnchorElement;
a(className?: string, childrenOrAttributes?: Attributes, children?: Children): HTMLAnchorElement;
/**
* Create text node
*/
text(value: string): Text;
/**
* Create invisible text node
*/
fake(): Text;
/**
* Create HTML Document fragment element
*/
fragment(): DocumentFragment;
/**
* Create a DOM element from HTML text
*
// eslint-disable-next-line tsdoc/syntax
* @param refsToggleElement - State dictionary in which you can set the visibility of some of the elements
* ```js
* const editor = Jodit.make('#editor');
* editor.createInside.fromHTML(`<div>
* <input name="name" ref="name"/>
* <input name="email" ref="email"/>
* </div>`, {
* name: true,
* email: false
* });
* ```
*/
fromHTML<T extends HTMLElement>(html: string | number, refsToggleElement?: IDictionary<boolean | void>): T;
/**
* Apply to element `createAttributes` options
*/
applyCreateAttributes(elm: HTMLElement): void;
}

139
node_modules/jodit/esm/core/create/create.js generated vendored Normal file
View File

@@ -0,0 +1,139 @@
/*!
* 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 { INVISIBLE_SPACE } from "../constants.js";
import { Dom } from "../dom/dom.js";
import { asArray, attr, isFunction, isPlainObject, isString, refs } from "../helpers/index.js";
import { assert } from "../helpers/utils/assert.js";
export class Create {
get doc() {
// @ts-ignore - TODO it's a function
return isFunction(this.document) ? this.document() : this.document;
}
constructor(document, createAttributes) {
this.document = document;
this.createAttributes = createAttributes;
}
element(tagName, childrenOrAttributes, children) {
const elm = this.doc.createElement(tagName.toLowerCase());
this.applyCreateAttributes(elm);
if (childrenOrAttributes) {
if (isPlainObject(childrenOrAttributes)) {
attr(elm, childrenOrAttributes);
}
else {
children = childrenOrAttributes;
}
}
if (children) {
asArray(children).forEach((child) => elm.appendChild(isString(child) ? this.fromHTML(child) : child));
}
return elm;
}
div(className, childrenOrAttributes, children) {
const div = this.element('div', childrenOrAttributes, children);
if (className) {
div.className = className;
}
return div;
}
sandbox() {
var _a;
const iframe = this.element('iframe', { sandbox: 'allow-same-origin' });
this.doc.body.appendChild(iframe);
const doc = (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document;
assert(doc, 'iframe.contentWindow.document');
if (!doc) {
throw Error('Iframe error');
}
doc.open();
doc.write('<!DOCTYPE html><html><head></head><body></body></html>');
doc.close();
return [doc.body, iframe];
}
span(className, childrenOrAttributes, children) {
const span = this.element('span', childrenOrAttributes, children);
if (className) {
span.className = className;
}
return span;
}
a(className, childrenOrAttributes, children) {
const a = this.element('a', childrenOrAttributes, children);
if (className) {
a.className = className;
}
return a;
}
/**
* Create text node
*/
text(value) {
return this.doc.createTextNode(value);
}
/**
* Create invisible text node
*/
fake() {
return this.text(INVISIBLE_SPACE);
}
/**
* Create HTML Document fragment element
*/
fragment() {
return this.doc.createDocumentFragment();
}
/**
* Create a DOM element from HTML text
*
// eslint-disable-next-line tsdoc/syntax
* @param refsToggleElement - State dictionary in which you can set the visibility of some of the elements
* ```js
* const editor = Jodit.make('#editor');
* editor.createInside.fromHTML(`<div>
* <input name="name" ref="name"/>
* <input name="email" ref="email"/>
* </div>`, {
* name: true,
* email: false
* });
* ```
*/
fromHTML(html, refsToggleElement) {
const div = this.div();
div.innerHTML = html.toString();
const child = div.firstChild !== div.lastChild || !div.firstChild
? div
: div.firstChild;
Dom.safeRemove(child);
if (refsToggleElement) {
const refElements = refs(child);
Object.keys(refsToggleElement).forEach(key => {
const elm = refElements[key];
if (elm && refsToggleElement[key] === false) {
Dom.hide(elm);
}
});
}
return child;
}
/**
* Apply to element `createAttributes` options
*/
applyCreateAttributes(elm) {
if (this.createAttributes) {
const ca = this.createAttributes;
if (ca && ca[elm.tagName.toLowerCase()]) {
const attrsOpt = ca[elm.tagName.toLowerCase()];
if (isFunction(attrsOpt)) {
attrsOpt(elm);
}
else if (isPlainObject(attrsOpt)) {
attr(elm, attrsOpt);
}
}
}
}
}

9
node_modules/jodit/esm/core/create/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* 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 create
*/
export * from "./create";

9
node_modules/jodit/esm/core/create/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* 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 create
*/
export * from "./create.js";

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
*/
/**
* [[include:core/decorators/autobind/README.md]]
* @packageDocumentation
* @module decorators/autobind
*/
/**
* Decorator that automatically binds a method to its class instance.
* This is useful when passing methods as callbacks to preserve the correct `this` context.
*
* @example
* ```typescript
* class MyComponent {
* @autobind
* handleClick() {
* console.log(this); // Always refers to MyComponent instance
* }
* }
*
* const component = new MyComponent();
* const button = document.createElement('button');
* button.addEventListener('click', component.handleClick); // `this` is correctly bound
* ```
*/
export declare function autobind(_target: object, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;

View File

@@ -0,0 +1,50 @@
/*!
* 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 { isFunction } from "../../helpers/checker/is-function.js";
/**
* [[include:core/decorators/autobind/README.md]]
* @packageDocumentation
* @module decorators/autobind
*/
/**
* Decorator that automatically binds a method to its class instance.
* This is useful when passing methods as callbacks to preserve the correct `this` context.
*
* @example
* ```typescript
* class MyComponent {
* @autobind
* handleClick() {
* console.log(this); // Always refers to MyComponent instance
* }
* }
*
* const component = new MyComponent();
* const button = document.createElement('button');
* button.addEventListener('click', component.handleClick); // `this` is correctly bound
* ```
*/
export function autobind(_target, propertyKey, descriptor) {
if (!isFunction(descriptor.value)) {
throw new TypeError(`@autobind can only be applied to methods, but "${propertyKey}" is not a function`);
}
const originalMethod = descriptor.value;
return {
configurable: true,
get() {
// Create a bound version of the method and cache it on the instance
const boundMethod = originalMethod.bind(this);
// Define the bound method as a property on the instance
// This ensures the same bound function is returned on subsequent accesses
Object.defineProperty(this, propertyKey, {
value: boundMethod,
configurable: true,
writable: true
});
return boundMethod;
}
};
}

117
node_modules/jodit/esm/core/decorators/cache/cache.d.ts generated vendored Normal file
View File

@@ -0,0 +1,117 @@
/*!
* 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:core/decorators/cache/README.md]]
* @packageDocumentation
* @module decorators/cache
*/
import type { IDictionary, Nullable } from "../../../types/index";
export interface CachePropertyDescriptor<T, R> extends PropertyDescriptor {
get?: (this: T) => R;
}
/**
* Retrieves a cached property value from an object if it exists; otherwise, returns `null`.
*
* This utility is particularly useful when working with properties that are lazily initialized
* or dynamically created, such as getters or cached computations. It ensures you can safely
* access the value without triggering initialization or creating a new instance.
*
* ### Usage Example:
* ```typescript
* import type { IUIElement } from "jodit";
*
* const { component, cache, cached } = Jodit.decorators;
* const { UIElement } = Jodit.modules;
*
* @component
* class SomeComponent extends UIElement {
* @cache
* get someElement(): IUIElement {
* return new UIElement(this.jodit);
* }
*
* destruct() {
* // Use the cached utility to clean up only if the property is initialized
* cached(this, 'someElement')?.destruct();
* super.destruct();
* }
* }
* ```
*
* @param object - The object containing the property to check.
* @param property - The name of the property to retrieve from the cache.
* @returns The cached value of the property if it exists; otherwise, `null`.
*
* ### Notes:
* - If the property is defined as a getter, the function will return `null`
* instead of invoking the getter.
* - This function is non-destructive and does not alter the object's state.
*/
export declare function cached<T>(object: object, property: string): Nullable<T>;
/**
* A decorator that caches the result of a getter method. Once the getter is accessed for the first time,
* its computed value is stored as a property of the object. Subsequent accesses return the cached value
* without recalculating it, improving performance and avoiding redundant computations.
*
* ### Key Features:
* - **Lazy Initialization**: The original getter is invoked only once, the first time the property is accessed.
* - **Immutability**: After caching, the value is stored as a non-writable, non-configurable property, preventing accidental modifications.
* - **Conditional Caching**: If the returned value has a property `noCache` set to `true`, the caching mechanism is bypassed, and the getter is invoked each time.
*
* ### Usage Example 1: Basic Caching
* ```typescript
* import { cache } from './decorators';
*
* class Example {
* private counter = 0;
*
* @cache
* get expensiveComputation(): number {
* console.log('Calculating...');
* return ++this.counter;
* }
* }
*
* const instance = new Example();
* console.log(instance.expensiveComputation); // Logs "Calculating..." and returns 1
* console.log(instance.expensiveComputation); // Returns 1 (cached value, no calculation)
* ```
*
* ### Usage Example 2: Integration with Cached Utilities
* ```typescript
* import { cache, cached } from './decorators';
* import type { IUIElement } from "jodit";
*
* const { component } = Jodit.decorators;
* const { UIElement } = Jodit.modules;
*
* @component
* class SomeComponent extends UIElement {
* @cache
* get someElement(): IUIElement {
* return new UIElement(this.jodit);
* }
*
* destruct() {
* // Use the cached utility to clean up only if the property is initialized
* cached(this, 'someElement')?.destruct();
* super.destruct();
* }
* }
* ```
*
* @param _ - The target object (not used directly).
* @param name - The name of the property to decorate.
* @param descriptor - The property descriptor, which must include a getter method.
* @throws Will throw an error if the descriptor does not include a getter.
*
* ### Notes:
* - **Performance**: Ideal for properties that are computationally expensive and do not change after the initial computation.
* - **Flexibility**: Supports conditional caching via the `noCache` property in the returned value.
* - **Compatibility**: Designed to work seamlessly with objects and classes in TypeScript or JavaScript.
*/
export declare function cache<T, R>(_: object, name: PropertyKey, descriptor: CachePropertyDescriptor<T, R>): void;
export declare function cacheHTML<T extends Function, R>(target: IDictionary, _: string, descriptor: CachePropertyDescriptor<T, R>): void;

166
node_modules/jodit/esm/core/decorators/cache/cache.js generated vendored Normal file
View File

@@ -0,0 +1,166 @@
/*!
* 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 { STATUSES } from "../../component/statuses.js";
import { IS_PROD } from "../../constants.js";
import { Dom } from "../../dom/dom.js";
import { isFunction, isViewObject } from "../../helpers/checker/index.js";
import { error } from "../../helpers/utils/error/error.js";
/**
* Retrieves a cached property value from an object if it exists; otherwise, returns `null`.
*
* This utility is particularly useful when working with properties that are lazily initialized
* or dynamically created, such as getters or cached computations. It ensures you can safely
* access the value without triggering initialization or creating a new instance.
*
* ### Usage Example:
* ```typescript
* import type { IUIElement } from "jodit";
*
* const { component, cache, cached } = Jodit.decorators;
* const { UIElement } = Jodit.modules;
*
* @component
* class SomeComponent extends UIElement {
* @cache
* get someElement(): IUIElement {
* return new UIElement(this.jodit);
* }
*
* destruct() {
* // Use the cached utility to clean up only if the property is initialized
* cached(this, 'someElement')?.destruct();
* super.destruct();
* }
* }
* ```
*
* @param object - The object containing the property to check.
* @param property - The name of the property to retrieve from the cache.
* @returns The cached value of the property if it exists; otherwise, `null`.
*
* ### Notes:
* - If the property is defined as a getter, the function will return `null`
* instead of invoking the getter.
* - This function is non-destructive and does not alter the object's state.
*/
export function cached(object, property) {
const descriptor = Object.getOwnPropertyDescriptor(object, property);
if (!descriptor || isFunction(descriptor.get)) {
return null;
}
return descriptor.value;
}
/**
* A decorator that caches the result of a getter method. Once the getter is accessed for the first time,
* its computed value is stored as a property of the object. Subsequent accesses return the cached value
* without recalculating it, improving performance and avoiding redundant computations.
*
* ### Key Features:
* - **Lazy Initialization**: The original getter is invoked only once, the first time the property is accessed.
* - **Immutability**: After caching, the value is stored as a non-writable, non-configurable property, preventing accidental modifications.
* - **Conditional Caching**: If the returned value has a property `noCache` set to `true`, the caching mechanism is bypassed, and the getter is invoked each time.
*
* ### Usage Example 1: Basic Caching
* ```typescript
* import { cache } from './decorators';
*
* class Example {
* private counter = 0;
*
* @cache
* get expensiveComputation(): number {
* console.log('Calculating...');
* return ++this.counter;
* }
* }
*
* const instance = new Example();
* console.log(instance.expensiveComputation); // Logs "Calculating..." and returns 1
* console.log(instance.expensiveComputation); // Returns 1 (cached value, no calculation)
* ```
*
* ### Usage Example 2: Integration with Cached Utilities
* ```typescript
* import { cache, cached } from './decorators';
* import type { IUIElement } from "jodit";
*
* const { component } = Jodit.decorators;
* const { UIElement } = Jodit.modules;
*
* @component
* class SomeComponent extends UIElement {
* @cache
* get someElement(): IUIElement {
* return new UIElement(this.jodit);
* }
*
* destruct() {
* // Use the cached utility to clean up only if the property is initialized
* cached(this, 'someElement')?.destruct();
* super.destruct();
* }
* }
* ```
*
* @param _ - The target object (not used directly).
* @param name - The name of the property to decorate.
* @param descriptor - The property descriptor, which must include a getter method.
* @throws Will throw an error if the descriptor does not include a getter.
*
* ### Notes:
* - **Performance**: Ideal for properties that are computationally expensive and do not change after the initial computation.
* - **Flexibility**: Supports conditional caching via the `noCache` property in the returned value.
* - **Compatibility**: Designed to work seamlessly with objects and classes in TypeScript or JavaScript.
*/
export function cache(_, name, descriptor) {
const getter = descriptor.get;
if (!getter) {
throw error('Getter property descriptor expected');
}
descriptor.get = function () {
if (!IS_PROD) {
if (this.isInDestruct) {
console.error('Trying to access property in destructed component');
}
}
const value = getter.call(this);
if (value && value.noCache === true) {
return value;
}
Object.defineProperty(this, name, {
configurable: descriptor.configurable,
enumerable: descriptor.enumerable,
writable: false,
value
});
return value;
};
}
export function cacheHTML(target, _, descriptor) {
const fn = descriptor.value;
if (!isFunction(fn)) {
throw error('Handler must be a Function');
}
let useCache = true;
const cached = new WeakMap();
descriptor.value = function (...attrs) {
var _a;
if (useCache && cached.has(this.constructor)) {
return (_a = cached.get(this.constructor)) === null || _a === void 0 ? void 0 : _a.cloneNode(true);
}
const value = fn.apply(this, attrs);
if (useCache && Dom.isElement(value)) {
cached.set(this.constructor, value);
}
return useCache ? value.cloneNode(true) : value;
};
target.hookStatus(STATUSES.ready, (component) => {
const view = isViewObject(component)
? component
: component.jodit;
useCache = Boolean(view.options.cache);
});
}

View File

@@ -0,0 +1,19 @@
/*!
* 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:core/decorators/component/README.md]]
* @packageDocumentation
* @module decorators/component
*/
interface ComponentCompatible {
new (...constructorArgs: any[]): any;
}
/**
* Decorate components and set status isReady after constructor
* @param constructorFunction - Component constructor class
*/
export declare function component<T extends ComponentCompatible>(constructorFunction: T): T;
export {};

View File

@@ -0,0 +1,27 @@
/*!
* 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
*/
/**
* Decorate components and set status isReady after constructor
* @param constructorFunction - Component constructor class
*/
export function component(constructorFunction) {
class newConstructorFunction extends constructorFunction {
constructor(...args) {
super(...args);
const isRootConstructor = this.constructor === newConstructorFunction;
// We can add a decorator to multiple classes in a chain.
// Status should be set only as root
if (isRootConstructor) {
// In some es/minimizer builds, JS instantiates the original class rather than the new constructor
if (!(this instanceof newConstructorFunction)) {
Object.setPrototypeOf(this, newConstructorFunction.prototype);
}
this.setStatus('ready');
}
}
}
return newConstructorFunction;
}

View File

@@ -0,0 +1,16 @@
/*!
* 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:core/decorators/debounce/README.md]]
* @packageDocumentation
* @module decorators/debounce
*/
import type { DecoratorHandler, IAsyncParams, IViewComponent } from "../../../types/index";
export declare function debounce<V extends IViewComponent = IViewComponent>(timeout?: number | ((ctx: V) => number | IAsyncParams) | IAsyncParams, firstCallImmediately?: boolean, method?: 'debounce' | 'throttle'): DecoratorHandler;
/**
* Wrap function in throttle wrapper
*/
export declare function throttle<V extends IViewComponent = IViewComponent>(timeout?: number | ((ctx: V) => number | IAsyncParams) | IAsyncParams, firstCallImmediately?: boolean): DecoratorHandler;

View File

@@ -0,0 +1,43 @@
/*!
* 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 { Component, STATUSES } from "../../component/index.js";
import { isFunction, isNumber, isPlainObject } from "../../helpers/checker/index.js";
import { assert } from "../../helpers/utils/assert.js";
import { error } from "../../helpers/utils/error/index.js";
export function debounce(timeout, firstCallImmediately = false, method = 'debounce') {
return (target, propertyKey) => {
const fn = target[propertyKey];
if (!isFunction(fn)) {
throw error('Handler must be a Function');
}
target.hookStatus(STATUSES.ready, (component) => {
const { async } = component;
assert(async != null, `Component ${component.componentName || component.constructor.name} should have "async:IAsync" field`);
const propTimeout = isFunction(timeout)
? timeout(component)
: timeout;
const realTimout = isNumber(propTimeout) || isPlainObject(propTimeout)
? propTimeout
: component.defaultTimeout;
Object.defineProperty(component, propertyKey, {
configurable: true,
value: async[method](component[propertyKey].bind(component), realTimout, firstCallImmediately)
});
});
return {
configurable: true,
get() {
return fn.bind(this);
}
};
};
}
/**
* Wrap function in throttle wrapper
*/
export function throttle(timeout, firstCallImmediately = false) {
return debounce(timeout, firstCallImmediately, 'throttle');
}

View File

@@ -0,0 +1,6 @@
/*!
* 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
*/
export declare function derive(...traits: Function[]): (target: Function) => 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
*/
/**
* [[include:core/decorators/derive/README.md]]
* @packageDocumentation
* @module decorators/derive
*/
import { isFunction } from "../../helpers/checker/is-function.js";
export function derive(...traits) {
return (target) => {
const origin = target.prototype;
for (let i = 0; i < traits.length; i++) {
const trait = traits[i];
const keys = Object.getOwnPropertyNames(trait.prototype);
for (let j = 0; j < keys.length; j++) {
const key = keys[j], method = Object.getOwnPropertyDescriptor(trait.prototype, key);
const canDerive = method != null &&
isFunction(method.value) &&
!isFunction(origin[key]);
if (canDerive) {
Object.defineProperty(origin, key, {
enumerable: true,
configurable: true,
writable: true,
value: function (...args) {
return method.value.call(this, ...args);
}
});
}
}
}
};
}

16
node_modules/jodit/esm/core/decorators/hook/hook.d.ts generated vendored Normal file
View File

@@ -0,0 +1,16 @@
/*!
* 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:core/decorators/hook/README.md]]
* @packageDocumentation
* @module decorators/hook
*/
import type { ComponentStatus, IDictionary } from "../../../types/index";
import type { Component } from "../../component/index";
/**
* Call on some component status
*/
export declare function hook(status: ComponentStatus): <T extends Component & IDictionary>(target: IDictionary, propertyKey: string) => void;

20
node_modules/jodit/esm/core/decorators/hook/hook.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
/*!
* 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 { isFunction } from "../../helpers/checker/is-function.js";
import { error } from "../../helpers/utils/error/index.js";
/**
* Call on some component status
*/
export function hook(status) {
return (target, propertyKey) => {
if (!isFunction(target[propertyKey])) {
throw error('Handler must be a Function');
}
target.hookStatus(status, (component) => {
component[propertyKey].call(component);
});
};
}

12
node_modules/jodit/esm/core/decorators/idle/idle.d.ts generated vendored Normal file
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
*/
/**
* [[include:core/decorators/idle/README.md]]
* @packageDocumentation
* @module decorators/idle
*/
import type { DecoratorHandler, IComponent } from "../../../types/index";
export declare function idle<V extends IComponent = IComponent>(): DecoratorHandler;

20
node_modules/jodit/esm/core/decorators/idle/idle.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
/*!
* 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 { Component, STATUSES } from "../../component/index.js";
import { isFunction } from "../../helpers/checker/is-function.js";
import { error } from "../../helpers/utils/error/index.js";
export function idle() {
return (target, propertyKey) => {
if (!isFunction(target[propertyKey])) {
throw error('Handler must be a Function');
}
target.hookStatus(STATUSES.ready, (component) => {
const { async } = component;
const originalMethod = component[propertyKey];
component[propertyKey] = (...args) => async.requestIdleCallback(originalMethod.bind(component, ...args));
});
};
}

21
node_modules/jodit/esm/core/decorators/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,21 @@
/*!
* 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:core/decorators/README.md]]
* @packageDocumentation
* @module decorators
*/
export * from "./autobind/autobind";
export * from "./cache/cache";
export * from "./component/component";
export * from "./debounce/debounce";
export * from "./derive/derive";
export * from "./hook/hook";
export * from "./idle/idle";
export * from "./nonenumerable/nonenumerable";
export * from "./persistent/persistent";
export * from "./wait/wait";
export * from "./watch/watch";

21
node_modules/jodit/esm/core/decorators/index.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
/*!
* 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:core/decorators/README.md]]
* @packageDocumentation
* @module decorators
*/
export * from "./autobind/autobind.js";
export * from "./cache/cache.js";
export * from "./component/component.js";
export * from "./debounce/debounce.js";
export * from "./derive/derive.js";
export * from "./hook/hook.js";
export * from "./idle/idle.js";
export * from "./nonenumerable/nonenumerable.js";
export * from "./persistent/persistent.js";
export * from "./wait/wait.js";
export * from "./watch/watch.js";

View File

@@ -0,0 +1,11 @@
/*!
* 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:core/decorators/nonenumerable/README.md]]
* @packageDocumentation
* @module decorators/nonenumerable
*/
export declare const nonenumerable: (target: object, propertyKey: string) => void;

View File

@@ -0,0 +1,25 @@
/*!
* 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:core/decorators/nonenumerable/README.md]]
* @packageDocumentation
* @module decorators/nonenumerable
*/
export const nonenumerable = (target, propertyKey) => {
const descriptor = Object.getOwnPropertyDescriptor(target, propertyKey) || {};
if (descriptor.enumerable !== false) {
Object.defineProperty(target, propertyKey, {
enumerable: false,
set(value) {
Object.defineProperty(this, propertyKey, {
enumerable: false,
writable: true,
value
});
}
});
}
};

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
*/
/**
* [[include:core/decorators/persistent/README.md]]
* @packageDocumentation
* @module decorators/persistent
*/
import type { IComponent } from "../../../types/index";
export declare function persistent<T extends IComponent>(target: T, propertyKey: string): void;

View File

@@ -0,0 +1,23 @@
/*!
* 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 { STATUSES } from "../../component/statuses.js";
import { isViewObject } from "../../helpers/checker/is-view-object.js";
export function persistent(target, propertyKey) {
target.hookStatus(STATUSES.ready, (component) => {
const jodit = isViewObject(component)
? component
: component.jodit, storageKey = `${jodit.options.namespace}${component.componentName}_prop_${propertyKey}`, initialValue = component[propertyKey];
Object.defineProperty(component, propertyKey, {
get() {
var _a;
return (_a = jodit.storage.get(storageKey)) !== null && _a !== void 0 ? _a : initialValue;
},
set(value) {
jodit.storage.set(storageKey, value);
}
});
});
}

13
node_modules/jodit/esm/core/decorators/wait/wait.d.ts generated vendored Normal file
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
*/
/**
* [[include:core/decorators/wait/README.md]]
* @packageDocumentation
* @module decorators/wait
*/
import type { IViewBased, IViewComponent } from "../../../types/index";
export declare function wait<T extends IViewBased>(condition: (ctx: T) => boolean): Function;
export declare function wait<T extends IViewComponent>(condition: (ctx: T) => boolean): Function;

33
node_modules/jodit/esm/core/decorators/wait/wait.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/*!
* 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 { STATUSES } from "../../component/statuses.js";
import { isFunction } from "../../helpers/checker/is-function.js";
import { error } from "../../helpers/utils/error/index.js";
export function wait(condition) {
return (target, propertyKey) => {
const fn = target[propertyKey];
if (!isFunction(fn)) {
throw error('Handler must be a Function');
}
target.hookStatus(STATUSES.ready, (component) => {
const { async } = component;
const realMethod = component[propertyKey];
let timeout = 0;
Object.defineProperty(component, propertyKey, {
configurable: true,
value: function callProxy(...args) {
async.clearTimeout(timeout);
if (condition(component)) {
realMethod.apply(component, args);
}
else {
timeout = async.setTimeout(() => callProxy(...args), 10);
}
}
});
});
};
}

View File

@@ -0,0 +1,19 @@
/*!
* 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:core/decorators/watch/README.md]]
* @packageDocumentation
* @module decorators/watch
*/
import type { CanUndef, DecoratorHandler, IDictionary } from "../../../types/index";
export declare function getPropertyDescriptor(obj: unknown, prop: string): CanUndef<PropertyDescriptor>;
/**
* Watch decorator. Added observer for some change in field value
*/
export declare function watch(observeFields: string[] | string, opts?: {
context?: object | ((c: IDictionary) => object);
immediately?: boolean;
}): DecoratorHandler;

106
node_modules/jodit/esm/core/decorators/watch/watch.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
/*!
* 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 { STATUSES } from "../../component/statuses.js";
import { observable } from "../../event-emitter/observable.js";
import { splitArray } from "../../helpers/array/split-array.js";
import { isFunction } from "../../helpers/checker/is-function.js";
import { isPlainObject } from "../../helpers/checker/is-plain-object.js";
import { isViewObject } from "../../helpers/checker/is-view-object.js";
import { error } from "../../helpers/utils/error/index.js";
export function getPropertyDescriptor(obj, prop) {
let desc;
do {
desc = Object.getOwnPropertyDescriptor(obj, prop);
obj = Object.getPrototypeOf(obj);
} while (!desc && obj);
return desc;
}
/**
* Watch decorator. Added observer for some change in field value
*/
export function watch(observeFields, opts) {
return (target, propertyKey) => {
var _a;
if (!isFunction(target[propertyKey])) {
throw error('Handler must be a Function');
}
const immediately = (_a = opts === null || opts === void 0 ? void 0 : opts.immediately) !== null && _a !== void 0 ? _a : true;
const context = opts === null || opts === void 0 ? void 0 : opts.context;
const process = (component) => {
const view = isViewObject(component)
? component
: component.jodit;
let callback = (key, ...args) => {
if (component.isInDestruct) {
return;
}
return component[propertyKey](key, ...args);
};
if (!immediately) {
callback = component.async.microDebounce(callback, true);
}
splitArray(observeFields).forEach(field => {
if (/:/.test(field)) {
const [objectPath, eventName] = field.split(':');
let ctx = context;
if (objectPath.length) {
ctx = component.get(objectPath);
}
if (isFunction(ctx)) {
ctx = ctx(component);
}
view.events.on(ctx || component, eventName, callback);
if (!ctx) {
view.events.on(eventName, callback);
}
component.hookStatus('beforeDestruct', () => {
view.events
.off(ctx || component, eventName, callback)
.off(eventName, callback);
});
return;
}
const parts = field.split('.'), [key] = parts, teil = parts.slice(1);
let value = component[key];
if (isPlainObject(value)) {
const observableValue = observable(value);
observableValue.on(`change.${teil.join('.')}`, callback);
}
const descriptor = getPropertyDescriptor(target, key);
Object.defineProperty(component, key, {
configurable: true,
set(v) {
const oldValue = value;
if (oldValue === v) {
return;
}
value = v;
if (descriptor && descriptor.set) {
descriptor.set.call(component, v);
}
if (isPlainObject(value)) {
value = observable(value);
value.on(`change.${teil.join('.')}`, callback);
}
callback(key, oldValue, value);
},
get() {
if (descriptor && descriptor.get) {
return descriptor.get.call(component);
}
return value;
}
});
});
};
if (isFunction(target.hookStatus)) {
target.hookStatus(STATUSES.ready, process);
}
else {
process(target);
}
};
}

260
node_modules/jodit/esm/core/dom/dom.d.ts generated vendored Normal file
View File

@@ -0,0 +1,260 @@
/*!
* 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:core/dom/README.md]]
* @packageDocumentation
* @module dom
*/
import type { HTMLTagNames, ICreate, IDictionary, IJodit, NodeCondition, Nullable } from "../../types/index";
/**
* Module for working with DOM
*/
export declare class Dom {
private constructor();
/**
* Remove all content from element
*/
static detach(node: Nullable<Node>): void;
/**
* Wrap all inline next siblings
*/
static wrapNextInline(current: Node, tag: Node | HTMLTagNames, editor: IJodit): HTMLElement;
private static __wrapElements;
/**
* Wrap all inline siblings
*/
static wrapInline(current: Node, tag: Node | HTMLTagNames, editor: IJodit): HTMLElement;
static wrap<K extends HTMLTagNames>(current: Node | Range, tag: HTMLElement, create: ICreate): HTMLElementTagNameMap[K];
static wrap<K extends HTMLTagNames>(current: Node | Range, tag: K, create: ICreate): HTMLElementTagNameMap[K];
/**
* Remove parent of node and insert this node instead that parent
*/
static unwrap(node: Node): void;
/**
* Call functions for all nodes between `start` and `end`
*/
static between(start: Node, end: Node, callback: (node: Node) => void | boolean): void;
/**
* Replace one tag to another transfer content
*
* @param elm - The element that needs to be replaced by new
* @param newTagName - tag name for which will change `elm`
* @param withAttributes - If true move tag's attributes
* @param notMoveContent - false - Move content from elm to newTagName
* @example
* ```javascript
* Jodit.modules.Dom.replace(parent.editor.getElementsByTagName('span')[0], 'p');
* // Replace the first <span> element to the < p >
* ```
*/
static replace<T extends HTMLElement>(elm: Node, newTagName: HTMLTagNames): T;
static replace<T extends HTMLElement>(elm: Node, newTagName: HTMLTagNames, create: ICreate, withAttributes?: boolean, notMoveContent?: boolean): T;
static replace<T extends Node>(elm: Node, newTagName: T | string, create?: ICreate, withAttributes?: boolean, notMoveContent?: boolean): T;
/**
* Checks whether the Node text and blank (in this case it may contain invisible auxiliary characters ,
* it is also empty )
*
* @param node - The element of wood to be checked
*/
static isEmptyTextNode(node: Nullable<Node>): boolean;
static isEmptyContent(node: Node): boolean;
/**
* The node is editable
*/
static isContentEditable(node: Nullable<Node>, root: HTMLElement): boolean;
/**
* Check if element is empty
*/
static isEmpty(node: Node, condNoEmptyElement: (node: Element) => boolean): boolean;
static isEmpty(node: Node, noEmptyTags?: Set<string>): boolean;
/**
* Returns true if it is a DOM node
*/
static isNode(object: unknown): object is Node;
/**
* Check if element is table cell
*/
static isCell(elm: unknown): elm is HTMLTableCellElement;
/**
* Check if element is a list element UL or OL
*/
static isList(elm: Nullable<Node>): elm is HTMLOListElement;
/**
* Check if element is a part of list element LI
*/
static isLeaf(elm: Nullable<Node>): elm is HTMLLIElement;
/**
* Check is element is Image element
*/
static isImage(elm: unknown): elm is HTMLImageElement;
/**
* Check the `node` is a block element
* @param node - Object to check
*/
static isBlock(node: unknown): node is HTMLDivElement;
/**
* Check if element is text node
*/
static isText(node: Node | null | false): node is Text;
/**
* Check if element is comment node
*/
static isComment(node: Node): node is Comment;
/**
* Check if element is element node
*/
static isElement(node: unknown): node is Element;
/**
* Check if element is document fragment
*/
static isFragment(node: unknown): node is DocumentFragment;
/**
* Check if element is HTMLElement node
*/
static isHTMLElement(node: unknown): node is HTMLElement;
/**
* Check element is inline block
*/
static isInlineBlock(node: Node | null | false): node is HTMLElement;
/**
* It's block and it can be split
*/
static canSplitBlock(node: unknown): boolean;
/**
* Get last matched node inside root
*/
static last(root: Nullable<Node>, condition: NodeCondition): Nullable<Node>;
/**
* Find previous node
*/
static prev<T extends Node = Node>(node: Node, condition: NodeCondition, root: HTMLElement, withChild?: boolean): Nullable<T>;
/**
* Find next node what `condition(next) === true`
*/
static next<T extends Node = Node>(node: Node, condition: NodeCondition, root: HTMLElement, withChild?: boolean): Nullable<T>;
static prevWithClass(node: HTMLElement, className: string): Nullable<HTMLElement>;
static nextWithClass(node: HTMLElement, className: string): Nullable<HTMLElement>;
/**
* Find next/prev node what `condition(next) === true`
*/
static find<T extends Node = Node>(node: Node, condition: NodeCondition, root: HTMLElement, leftToRight?: boolean, withChild?: boolean): Nullable<T>;
/**
* Find next/prev node what `condition(next) === true`
*/
static nextGen(start: Node, root: HTMLElement, leftToRight?: boolean, withChild?: boolean): Generator<Node>;
/**
* It goes through all the internal elements of the node, causing a callback function
*
* @param elm - the element whose children and descendants you want to iterate over
* @param callback - It called for each item found
* @example
* ```javascript
* Jodit.modules.Dom.each(editor.s.current(), function (node) {
* if (node.nodeType === Node.TEXT_NODE) {
* node.nodeValue = node.nodeValue.replace(Jodit.INVISIBLE_SPACE_REG_EX, '') // remove all of the text element codes invisible character
* }
* });
* ```
*/
static each(elm: Node, callback: (node: Node) => void | boolean, leftToRight?: boolean): boolean;
static eachGen(root: Node, leftToRight?: boolean): Generator<Node>;
private static runInStack;
/**
* Find next/prev node what `condition(next) === true`
*/
static findWithCurrent(node: Node, condition: NodeCondition, root: HTMLElement | Node, sibling?: 'nextSibling' | 'previousSibling', child?: 'firstChild' | 'lastChild'): Nullable<Node>;
/**
* Get not empty sibling
*/
static findSibling(node: Node, left?: boolean, cond?: (n: Node) => boolean): Nullable<Node>;
/**
* Returns the nearest non-empty sibling
*/
static findNotEmptySibling(node: Node, left: boolean): Nullable<Node>;
/**
* Returns the nearest non-empty neighbor
*/
static findNotEmptyNeighbor(node: Node, left: boolean, root: HTMLElement): Nullable<Node>;
static sibling(node: Node, left?: boolean): Nullable<Node>;
/**
* It goes through all the elements in ascending order, and checks to see if they meet the predetermined condition
*/
static up<T extends HTMLElement>(node: Nullable<Node>, condition: NodeCondition, root?: Node, checkRoot?: boolean): Nullable<T>;
/**
* Find parent by tag name
*/
static closest<T extends HTMLElement, K extends HTMLTagNames>(node: Nullable<Node>, tags: K, root: HTMLElement): Nullable<HTMLElementTagNameMap[K]>;
static closest<T extends HTMLElement, K extends keyof HTMLElementTagNameMap>(node: Nullable<Node>, tags: Set<K>, root: HTMLElement): Nullable<HTMLElementTagNameMap[K]>;
static closest<T extends HTMLElement, K extends keyof HTMLElementTagNameMap>(node: Nullable<Node>, tags: K[], root: HTMLElement): Nullable<HTMLElementTagNameMap[K]>;
static closest<T extends HTMLElement>(node: Nullable<Node>, condition: NodeCondition, root: HTMLElement): Nullable<T>;
/**
* Furthest parent node matching condition
*/
static furthest<T extends HTMLElement>(node: Nullable<Node>, condition: NodeCondition, root: HTMLElement): Nullable<T>;
/**
* Append new element in the start of root
*/
static appendChildFirst(root: HTMLElement, newElement: HTMLElement | DocumentFragment): void;
/**
* Insert newElement after element
*/
static after(elm: Node, newElement: Node | DocumentFragment): void;
/**
* Insert newElement before element
*/
static before(elm: Node, newElement: Node | DocumentFragment): void;
/**
* Insert newElement as first child inside element
*/
static prepend(root: Node, newElement: Node | DocumentFragment): void;
/**
* Insert newElement as last child inside element
*/
static append(root: Node, newElements: Array<Node | DocumentFragment>): void;
static append(root: Node, newElement: Node | DocumentFragment): void;
/**
* Move all content to another element
*/
static moveContent(from: Node, to: Node, inStart?: boolean, filter?: (node: Node) => boolean): void;
/**
* Check root contains child or equal child
*/
static isOrContains(root: Node, child: Node, onlyContains?: boolean): boolean;
/**
* Safe remove element from DOM
*/
static safeRemove(...nodes: unknown[]): void;
static safeInsertNode(range: Range, node: Node): void;
/**
* Hide element
*/
static hide(node: Nullable<HTMLElement>): void;
/**
* Show element
*/
static show(node: Nullable<HTMLElement>): void;
/**
* Check if element is some tag
*/
static isTag<K extends HTMLTagNames>(node: Node | null | undefined | false | EventTarget, tagName: K): node is HTMLElementTagNameMap[K];
static isTag<K extends HTMLTagNames>(node: Node | null | undefined | false | EventTarget, tagNames: Set<K>): node is HTMLElementTagNameMap[K];
/**
* Marks an item as temporary
*/
static markTemporary<K extends HTMLElement>(element: K, attributes?: IDictionary): K;
/**
* Check if element is temporary
*/
static isTemporary(element: unknown): boolean;
/**
* Replace temporary elements from string
*/
static replaceTemporaryFromString(value: string): string;
/**
* Get temporary list
*/
static temporaryList(root: HTMLElement): HTMLElement[];
}

739
node_modules/jodit/esm/core/dom/dom.js generated vendored Normal file
View File

@@ -0,0 +1,739 @@
/*!
* 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 "../constants.js";
import { globalDocument, INSEPARABLE_TAGS, LIST_TAGS, NO_EMPTY_TAGS, TEMP_ATTR } from "../constants.js";
import { toArray } from "../helpers/array/to-array.js";
import { isArray, isFunction, isHTML, isMarker, isSet, isString, isVoid } from "../helpers/checker/index.js";
import { trim } from "../helpers/string/trim.js";
import { $$, assert, attr, call, css, dataBind, error } from "../helpers/utils/index.js";
/**
* Module for working with DOM
*/
export class Dom {
constructor() {
throw new Error('Dom is static module');
}
/**
* Remove all content from element
*/
static detach(node) {
while (node && node.firstChild) {
node.removeChild(node.firstChild);
}
}
/**
* Wrap all inline next siblings
*/
static wrapNextInline(current, tag, editor) {
let tmp;
const first = current;
let last = current;
editor.s.save();
let needFindNext = false;
do {
needFindNext = false;
tmp = last.nextSibling;
if (tmp && !Dom.isBlock(tmp) && !Dom.isTag(tmp, 'br')) {
needFindNext = true;
last = tmp;
}
} while (needFindNext);
return Dom.__wrapElements(tag, editor, first, last);
}
static __wrapElements(tag, editor, first, last) {
const wrapper = isString(tag) ? editor.createInside.element(tag) : tag;
if (first.parentNode) {
first.parentNode.insertBefore(wrapper, first);
}
let next = first;
while (next) {
next = first.nextSibling;
wrapper.appendChild(first);
if (first === last || !next) {
break;
}
first = next;
}
editor.s.restore();
return wrapper;
}
/**
* Wrap all inline siblings
*/
static wrapInline(current, tag, editor) {
let tmp;
let first = current;
let last = current;
editor.s.save();
let needFindNext = false;
do {
needFindNext = false;
tmp = first.previousSibling;
if (tmp && !Dom.isBlock(tmp)) {
needFindNext = true;
first = tmp;
}
} while (needFindNext);
do {
needFindNext = false;
tmp = last.nextSibling;
if (tmp && !Dom.isBlock(tmp)) {
needFindNext = true;
last = tmp;
}
} while (needFindNext);
return Dom.__wrapElements(tag, editor, first, last);
}
/**
* Wrap node inside another node
*/
static wrap(current, tag, create) {
const wrapper = isString(tag) ? create.element(tag) : tag;
if (Dom.isNode(current)) {
if (!current.parentNode) {
throw error('Element should be in DOM');
}
current.parentNode.insertBefore(wrapper, current);
wrapper.appendChild(current);
}
else {
const fragment = current.extractContents();
current.insertNode(wrapper);
wrapper.appendChild(fragment);
}
return wrapper;
}
/**
* Remove parent of node and insert this node instead that parent
*/
static unwrap(node) {
const parent = node.parentNode;
if (parent) {
while (node.firstChild) {
parent.insertBefore(node.firstChild, node);
}
Dom.safeRemove(node);
}
}
/**
* Call functions for all nodes between `start` and `end`
*/
static between(start, end, callback) {
let next = start;
while (next && next !== end) {
if (start !== next && callback(next)) {
break;
}
let step = next.firstChild || next.nextSibling;
if (!step) {
while (next && !next.nextSibling) {
next = next.parentNode;
}
step = next === null || next === void 0 ? void 0 : next.nextSibling;
}
next = step;
}
}
static replace(elm, newTagName, create, withAttributes = false, notMoveContent = false) {
if (isHTML(newTagName)) {
assert(create, 'Need create instance for new tag');
newTagName = create.fromHTML(newTagName);
}
let tag;
if (isString(newTagName)) {
assert(create, 'Need create instance for new tag');
tag = create.element(newTagName);
}
else {
tag = newTagName;
}
if (!notMoveContent) {
while (elm.firstChild) {
tag.appendChild(elm.firstChild);
}
}
if (withAttributes && Dom.isElement(elm) && Dom.isElement(tag)) {
toArray(elm.attributes).forEach(attr => {
tag.setAttribute(attr.name, attr.value);
});
}
if (elm.parentNode) {
elm.parentNode.replaceChild(tag, elm);
}
return tag;
}
/**
* Checks whether the Node text and blank (in this case it may contain invisible auxiliary characters ,
* it is also empty )
*
* @param node - The element of wood to be checked
*/
static isEmptyTextNode(node) {
return (Dom.isText(node) &&
(!node.nodeValue ||
node.nodeValue
.replace(consts.INVISIBLE_SPACE_REG_EXP(), '')
.trim().length === 0));
}
static isEmptyContent(node) {
return Dom.each(node, (elm) => Dom.isEmptyTextNode(elm));
}
/**
* The node is editable
*/
static isContentEditable(node, root) {
return (Dom.isNode(node) &&
!Dom.closest(node, elm => Dom.isElement(elm) &&
elm.getAttribute('contenteditable') === 'false', root));
}
static isEmpty(node, condNoEmptyElement = NO_EMPTY_TAGS) {
if (!node) {
return true;
}
let cond;
if (!isFunction(condNoEmptyElement)) {
cond = (elm) => condNoEmptyElement.has(elm.nodeName.toLowerCase());
}
else {
cond = condNoEmptyElement;
}
const emptyText = (node) => node.nodeValue == null || trim(node.nodeValue).length === 0;
if (Dom.isText(node)) {
return emptyText(node);
}
return (!(Dom.isElement(node) && cond(node)) &&
Dom.each(node, (elm) => {
if ((Dom.isText(elm) && !emptyText(elm)) ||
(Dom.isElement(elm) && cond(elm))) {
return false;
}
}));
}
/**
* Returns true if it is a DOM node
*/
static isNode(object) {
// Duck-typing
return Boolean(object &&
isString(object.nodeName) &&
typeof object.nodeType === 'number' &&
object.childNodes &&
isFunction(object.appendChild));
}
/**
* Check if element is table cell
*/
static isCell(elm) {
return (Dom.isNode(elm) && (elm.nodeName === 'TD' || elm.nodeName === 'TH'));
}
/**
* Check if element is a list element UL or OL
*/
static isList(elm) {
return Dom.isTag(elm, LIST_TAGS);
}
/**
* Check if element is a part of list element LI
*/
static isLeaf(elm) {
return Dom.isTag(elm, 'li');
}
/**
* Check is element is Image element
*/
static isImage(elm) {
return (Dom.isNode(elm) && /^(img|svg|picture|canvas)$/i.test(elm.nodeName));
}
/**
* Check the `node` is a block element
* @param node - Object to check
*/
static isBlock(node) {
return (!isVoid(node) &&
typeof node === 'object' &&
Dom.isNode(node) &&
consts.IS_BLOCK.test(node.nodeName));
}
/**
* Check if element is text node
*/
static isText(node) {
return Boolean(node && node.nodeType === Node.TEXT_NODE);
}
/**
* Check if element is comment node
*/
static isComment(node) {
return Boolean(node && node.nodeType === Node.COMMENT_NODE);
}
/**
* Check if element is element node
*/
static isElement(node) {
var _a;
if (!Dom.isNode(node)) {
return false;
}
const win = (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView;
return Boolean(win && node.nodeType === Node.ELEMENT_NODE);
}
/**
* Check if element is document fragment
*/
static isFragment(node) {
var _a;
if (!Dom.isNode(node)) {
return false;
}
const win = (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView;
return Boolean(win && node.nodeType === Node.DOCUMENT_FRAGMENT_NODE);
}
/**
* Check if element is HTMLElement node
*/
static isHTMLElement(node) {
var _a;
if (!Dom.isNode(node)) {
return false;
}
const win = (_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView;
return Boolean(win && node instanceof win.HTMLElement);
}
/**
* Check element is inline block
*/
static isInlineBlock(node) {
return (Dom.isElement(node) &&
!/^(BR|HR)$/i.test(node.tagName) &&
['inline', 'inline-block'].indexOf(css(node, 'display').toString()) !== -1);
}
/**
* It's block and it can be split
*/
static canSplitBlock(node) {
return (!isVoid(node) &&
Dom.isHTMLElement(node) &&
Dom.isBlock(node) &&
!/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) &&
node.style !== undefined &&
!/^(fixed|absolute)/i.test(node.style.position));
}
/**
* Get last matched node inside root
*/
static last(root, condition) {
let last = root === null || root === void 0 ? void 0 : root.lastChild;
if (!last) {
return null;
}
do {
if (condition(last)) {
return last;
}
let next = last.lastChild;
if (!next) {
next = last.previousSibling;
}
if (!next && last.parentNode !== root) {
do {
last = last.parentNode;
} while (last &&
!(last === null || last === void 0 ? void 0 : last.previousSibling) &&
last.parentNode !== root);
next = last === null || last === void 0 ? void 0 : last.previousSibling;
}
last = next;
} while (last);
return null;
}
/**
* Find previous node
*/
static prev(node, condition, root, withChild = true) {
return Dom.find(node, condition, root, false, withChild);
}
/**
* Find next node what `condition(next) === true`
*/
static next(node, condition, root, withChild = true) {
return Dom.find(node, condition, root, true, withChild);
}
static prevWithClass(node, className) {
return Dom.prev(node, node => {
return (Dom.isElement(node) && node.classList.contains(className));
}, node.parentNode);
}
static nextWithClass(node, className) {
return Dom.next(node, elm => Dom.isElement(elm) && elm.classList.contains(className), node.parentNode);
}
/**
* Find next/prev node what `condition(next) === true`
*/
static find(node, condition, root, leftToRight = true, withChild = true) {
const gen = this.nextGen(node, root, leftToRight, withChild);
let item = gen.next();
while (!item.done) {
if (condition(item.value)) {
return item.value;
}
item = gen.next();
}
return null;
}
/**
* Find next/prev node what `condition(next) === true`
*/
static *nextGen(start, root, leftToRight = true, withChild = true) {
const stack = [];
let currentNode = start;
do {
let next = leftToRight
? currentNode.nextSibling
: currentNode.previousSibling;
while (next) {
stack.unshift(next);
next = leftToRight ? next.nextSibling : next.previousSibling;
}
yield* this.runInStack(start, stack, leftToRight, withChild);
currentNode = currentNode.parentNode;
} while (currentNode && currentNode !== root);
return null;
}
/**
* It goes through all the internal elements of the node, causing a callback function
*
* @param elm - the element whose children and descendants you want to iterate over
* @param callback - It called for each item found
* @example
* ```javascript
* Jodit.modules.Dom.each(editor.s.current(), function (node) {
* if (node.nodeType === Node.TEXT_NODE) {
* node.nodeValue = node.nodeValue.replace(Jodit.INVISIBLE_SPACE_REG_EX, '') // remove all of the text element codes invisible character
* }
* });
* ```
*/
static each(elm, callback, leftToRight = true) {
const gen = this.eachGen(elm, leftToRight);
let item = gen.next();
while (!item.done) {
if (callback(item.value) === false) {
return false;
}
item = gen.next();
}
return true;
}
static eachGen(root, leftToRight = true) {
return this.runInStack(root, [root], leftToRight);
}
static *runInStack(start, stack, leftToRight, withChild = true) {
while (stack.length) {
const item = stack.pop();
if (withChild) {
let child = leftToRight ? item.lastChild : item.firstChild;
while (child) {
stack.push(child);
child = leftToRight
? child.previousSibling
: child.nextSibling;
}
}
if (start !== item) {
yield item;
}
}
}
/**
* Find next/prev node what `condition(next) === true`
*/
static findWithCurrent(node, condition, root, sibling = 'nextSibling', child = 'firstChild') {
let next = node;
do {
if (condition(next)) {
return next || null;
}
if (child && next && next[child]) {
const nextOne = Dom.findWithCurrent(next[child], condition, next, sibling, child);
if (nextOne) {
return nextOne;
}
}
while (next && !next[sibling] && next !== root) {
next = next.parentNode;
}
if (next && next[sibling] && next !== root) {
next = next[sibling];
}
} while (next && next !== root);
return null;
}
/**
* Get not empty sibling
*/
static findSibling(node, left = true, cond = (n) => !Dom.isEmptyTextNode(n)) {
let sibling = Dom.sibling(node, left);
while (sibling && !cond(sibling)) {
sibling = Dom.sibling(sibling, left);
}
return sibling && cond(sibling) ? sibling : null;
}
/**
* Returns the nearest non-empty sibling
*/
static findNotEmptySibling(node, left) {
return Dom.findSibling(node, left, n => {
var _a;
return (!Dom.isEmptyTextNode(n) &&
Boolean(!Dom.isText(n) || (((_a = n.nodeValue) === null || _a === void 0 ? void 0 : _a.length) && trim(n.nodeValue))));
});
}
/**
* Returns the nearest non-empty neighbor
*/
static findNotEmptyNeighbor(node, left, root) {
return call(left ? Dom.prev : Dom.next, node, n => Boolean(n &&
(!(Dom.isText(n) || Dom.isComment(n)) ||
trim((n === null || n === void 0 ? void 0 : n.nodeValue) || '').length)), root);
}
static sibling(node, left) {
return left ? node.previousSibling : node.nextSibling;
}
/**
* It goes through all the elements in ascending order, and checks to see if they meet the predetermined condition
*/
static up(node, condition, root, checkRoot = false) {
let start = node;
if (!start) {
return null;
}
do {
if (condition(start)) {
return start;
}
if (start === root || !start.parentNode) {
break;
}
start = start.parentNode;
} while (start && start !== root);
if (start === root && checkRoot && condition(start)) {
return start;
}
return null;
}
static closest(node, tagsOrCondition, root) {
let condition;
const lc = (s) => s.toLowerCase();
if (isFunction(tagsOrCondition)) {
condition = tagsOrCondition;
}
else if (isArray(tagsOrCondition) || isSet(tagsOrCondition)) {
const set = isSet(tagsOrCondition)
? tagsOrCondition
: new Set(tagsOrCondition.map(lc));
condition = (tag) => Boolean(tag && set.has(lc(tag.nodeName)));
}
else {
condition = (tag) => Boolean(tag && lc(tagsOrCondition) === lc(tag.nodeName));
}
return Dom.up(node, condition, root);
}
/**
* Furthest parent node matching condition
*/
static furthest(node, condition, root) {
let matchedParent = null, current = node === null || node === void 0 ? void 0 : node.parentElement;
while (current && current !== root) {
if (condition(current)) {
matchedParent = current;
}
current = current === null || current === void 0 ? void 0 : current.parentElement;
}
return matchedParent;
}
/**
* Append new element in the start of root
*/
static appendChildFirst(root, newElement) {
const child = root.firstChild;
if (child) {
if (child !== newElement) {
root.insertBefore(newElement, child);
}
}
else {
root.appendChild(newElement);
}
}
/**
* Insert newElement after element
*/
static after(elm, newElement) {
const { parentNode } = elm;
if (!parentNode) {
return;
}
if (parentNode.lastChild === elm) {
parentNode.appendChild(newElement);
}
else {
parentNode.insertBefore(newElement, elm.nextSibling);
}
}
/**
* Insert newElement before element
*/
static before(elm, newElement) {
const { parentNode } = elm;
if (!parentNode) {
return;
}
parentNode.insertBefore(newElement, elm);
}
/**
* Insert newElement as first child inside element
*/
static prepend(root, newElement) {
root.insertBefore(newElement, root.firstChild);
}
static append(root, newElement) {
if (isArray(newElement)) {
newElement.forEach(node => {
this.append(root, node);
});
}
else {
root.appendChild(newElement);
}
}
/**
* Move all content to another element
*/
static moveContent(from, to, inStart = false, filter = () => true) {
const fragment = (from.ownerDocument || globalDocument).createDocumentFragment();
toArray(from.childNodes)
.filter(elm => {
if (filter(elm)) {
return true;
}
Dom.safeRemove(elm);
return false;
})
.forEach((node) => {
fragment.appendChild(node);
});
if (!inStart || !to.firstChild) {
to.appendChild(fragment);
}
else {
to.insertBefore(fragment, to.firstChild);
}
}
/**
* Check root contains child or equal child
*/
static isOrContains(root, child, onlyContains = false) {
if (root === child) {
return !onlyContains;
}
return Boolean(child && root && this.up(child, nd => nd === root, root, true));
}
/**
* Safe remove element from DOM
*/
static safeRemove(...nodes) {
nodes.forEach(node => Dom.isNode(node) &&
node.parentNode &&
node.parentNode.removeChild(node));
}
static safeInsertNode(range, node) {
range.collapsed || range.deleteContents();
const child = Dom.isFragment(node) ? node.lastChild : node;
if (range.startContainer === range.endContainer &&
range.collapsed &&
Dom.isTag(range.startContainer, INSEPARABLE_TAGS)) {
Dom.after(range.startContainer, node);
}
else {
range.insertNode(node);
child && range.setStartBefore(child);
}
range.collapse(true);
// https://developer.mozilla.org/en-US/docs/Web/API/Range/insertNode
// if the new node is to be added to a text Node, that Node is split at the
// insertion point, and the insertion occurs between the two text nodes.
[node.nextSibling, node.previousSibling].forEach(n => Dom.isText(n) && !n.nodeValue && Dom.safeRemove(n));
}
/**
* Hide element
*/
static hide(node) {
if (!node) {
return;
}
dataBind(node, '__old_display', node.style.display);
node.style.display = 'none';
}
/**
* Show element
*/
static show(node) {
if (!node) {
return;
}
const display = dataBind(node, '__old_display');
if (node.style.display === 'none') {
node.style.display = display || '';
}
}
static isTag(node, tagNames) {
if (!this.isElement(node)) {
return false;
}
const nameL = node.tagName.toLowerCase();
const nameU = node.tagName.toUpperCase();
if (tagNames instanceof Set) {
return tagNames.has(nameL) || tagNames.has(nameU);
}
if (Array.isArray(tagNames)) {
throw new TypeError('Dom.isTag does not support array');
}
const tags = tagNames;
if (nameL === tags || nameU === tags) {
return true;
}
return false;
}
/**
* Marks an item as temporary
*/
static markTemporary(element, attributes) {
attributes && attr(element, attributes);
attr(element, TEMP_ATTR, true);
return element;
}
/**
* Check if element is temporary
*/
static isTemporary(element) {
if (!Dom.isElement(element)) {
return false;
}
return isMarker(element) || attr(element, TEMP_ATTR) === 'true';
}
/**
* Replace temporary elements from string
*/
static replaceTemporaryFromString(value) {
return value.replace(/<([a-z]+)[^>]+data-jodit-temp[^>]+>(.+?)<\/\1>/gi, '$2');
}
/**
* Get temporary list
*/
static temporaryList(root) {
return $$(`[${TEMP_ATTR}]`, root);
}
}

10
node_modules/jodit/esm/core/dom/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,10 @@
/*!
* 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 dom
*/
export * from "./dom";
export * from "./lazy-walker";

10
node_modules/jodit/esm/core/dom/index.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
/*!
* 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 dom
*/
export * from "./dom.js";
export * from "./lazy-walker.js";

38
node_modules/jodit/esm/core/dom/lazy-walker.d.ts generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/*!
* 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 dom
*/
import type { IAsync, IDestructible } from "../../types/index";
import { Eventify } from "../event-emitter/eventify";
export declare class LazyWalker extends Eventify<{
visit: (node: Node) => boolean;
break: (reason?: string) => void;
end: (affect: boolean) => void;
}> implements IDestructible {
private readonly async;
private readonly options;
private workNodes;
setWork(root: Node): this;
private hadAffect;
private isWorked;
private isFinished;
constructor(async: IAsync, options?: {
readonly whatToShow?: number;
readonly reverse?: boolean;
readonly timeoutChunkSize?: number;
readonly timeout?: number;
});
private idleId;
private __schedulerController;
private _requestStarting;
break(reason?: string): void;
end(): void;
private stop;
destruct(): void;
private __workPerform;
private visitNode;
}

109
node_modules/jodit/esm/core/dom/lazy-walker.js generated vendored Normal file
View File

@@ -0,0 +1,109 @@
/*!
* 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 "../decorators/index.js";
import { Dom } from "./dom.js";
import { Eventify } from "../event-emitter/eventify.js";
export class LazyWalker extends Eventify {
setWork(root) {
if (this.isWorked) {
this.break();
}
this.workNodes = Dom.eachGen(root, !this.options.reverse);
this.isFinished = false;
this._requestStarting();
return this;
}
constructor(async, options = {}) {
super();
this.async = async;
this.options = options;
this.workNodes = null;
this.hadAffect = false;
this.isWorked = false;
this.isFinished = false;
this.idleId = 0;
this.__schedulerController = null;
}
_requestStarting() {
this.__schedulerController = new AbortController();
this.async
.schedulerPostTask(this.__workPerform, {
delay: this.options.timeout,
signal: this.__schedulerController.signal
})
.catch(() => null);
}
break(reason) {
if (this.isWorked) {
this.stop();
this.emit('break', reason);
}
}
end() {
if (this.isWorked) {
this.stop();
this.emit('end', this.hadAffect);
this.hadAffect = false;
}
}
stop() {
this.isWorked = false;
this.isFinished = true;
this.workNodes = null;
this.async.cancelIdleCallback(this.idleId);
}
destruct() {
super.destruct();
this.stop();
}
__workPerform() {
var _a;
if (this.workNodes) {
this.isWorked = true;
let count = 0;
const chunkSize = (_a = this.options.timeoutChunkSize) !== null && _a !== void 0 ? _a : 50;
while (!this.isFinished && count <= chunkSize) {
const item = this.workNodes.next();
count += 1;
if (this.visitNode(item.value)) {
this.hadAffect = true;
}
if (item.done) {
this.end();
return;
}
}
}
else {
this.end();
}
if (!this.isFinished) {
this._requestStarting();
}
}
visitNode(nodeElm) {
var _a;
if (!nodeElm ||
(this.options.whatToShow !== undefined &&
nodeElm.nodeType !== this.options.whatToShow)) {
return false;
}
return (_a = this.emit('visit', nodeElm)) !== null && _a !== void 0 ? _a : false;
}
}
__decorate([
autobind
], LazyWalker.prototype, "__workPerform", null);

View File

@@ -0,0 +1,138 @@
/*!
* 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:core/event-emitter/README.md]]
* @packageDocumentation
* @module event-emitter
*/
import type { CallbackFunction, CanArray, IEventEmitter, IEventEmitterOnOptions } from "../../types/index";
/**
* The module editor's event manager
*/
export declare class EventEmitter implements IEventEmitter {
private __domEventsMap;
private __mutedEvents;
mute(event?: string): this;
isMuted(event?: string): boolean;
unmute(event?: string): this;
readonly __key: string;
private __doc;
private __eachEvent;
private __getStore;
private __removeStoreFromSubject;
private __prepareEvent;
private __triggerNativeEvent;
/**
* Get current event name
*
* @example
* ```javascript
* parent.e.on('openDialog closeDialog', function () {
* if (parent.e.current === 'closeDialog') {
* alert('Dialog was closed');
* } else {
* alert('Dialog was opened');
* }
* });
* ```
*/
get current(): string;
currents: string[];
/**
* Sets the handler for the specified event ( Event List ) for a given element
*
* @example
* ```javascript
* // set global handler
* editor.events.on('beforeCommand', function (command) {
* alert('command');
* });
* ```
* * @example
* ```javascript
* // set global handler
* editor.events.on(document.body, 'click', function (e) {
* alert(this.href);
* });
* ```
*/
on(events: CanArray<string>, callback: CallbackFunction, options?: IEventEmitterOnOptions): this;
on(subjects: CanArray<HTMLElement | Window | object>, events: CanArray<string>, callback: CallbackFunction, options?: IEventEmitterOnOptions): this;
private __memoryDOMSubjectToHandler;
private __unmemoryDOMSubjectToHandler;
one(eventsOrSubjects: CanArray<string> | CanArray<HTMLElement | Window | object>, callbackOrEvents: CallbackFunction | CanArray<string>, optionsOrCallback: IEventEmitterOnOptions | CallbackFunction | void, opts?: IEventEmitterOnOptions): this;
/**
* Disable all handlers specified event ( Event List ) for a given element. Either a specific event handler.
*
* @param subjectOrEvents - The object which is disabled handlers
* @param eventsOrCallback - List of events, separated by a space or comma , which is necessary
* to disable the handlers for a given object
* @param handler - Specific event handler to be removed
*
* @example
* ```javascript
* var a = {name: "Anton"};
* parent.e.on(a, 'open', function () {
* alert(this.name);
* });
*
* parent.e.fire(a, 'open');
* parent.e.off(a, 'open');
* var b = {name: "Ivan"}, hndlr = function () {
* alert(this.name);
* };
* parent.e.on(b, 'open close', hndlr);
* parent.e.fire(a, 'open');
* parent.e.off(a, 'open', hndlr);
* parent.e.fire(a, 'close');
* parent.e.on('someGlobalEvents', function () {
* console.log(this); // parent
* });
* parent.e.fire('someGlobalEvents');
* parent.e.off('someGlobalEvents');
* ```
*/
off(events: CanArray<string>, callback?: CallbackFunction): this;
off(subjects: CanArray<Window | HTMLElement | object>, events?: CanArray<string>, callback?: CallbackFunction): this;
/**
* Stop execute all another listeners for this event
*/
stopPropagation(events: string): void;
stopPropagation(subject: object, eventsList: string): void;
private __stopped;
private __removeStop;
private __isStopped;
/**
* Emits an event to all handlers and calls them
*
* @param subjectOrEvents - The object which is caused by certain events
* @param eventsList - List of events , separated by a space or comma
* @param args - Options for the event handler
* @returns `false` if one of the handlers return `false`
* @example
* ```javascript
* var dialog = new Jodit.modules.Dialog();
* parent.e.on('afterClose', function () {
* dialog.destruct(); // will be removed from DOM
* });
* dialog.open('Hello world!!!');
* ```
* or you can trigger native browser listener
* ```javascript
* var events = new Jodit.modules.EventEmitter();
* events.on(document.body, 'click',function (event) {
* alert('click on ' + event.target.id );
* });
* events.fire(document.body.querySelector('div'), 'click');
* ```
*
*/
fire(subjectOrEvents: string, ...args: any[]): any;
fire(subjectOrEvents: object, eventsList: string | Event, ...args: any[]): any;
private __isDestructed;
constructor(doc?: Document);
destruct(): void;
}

View File

@@ -0,0 +1,481 @@
/*!
* 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 { globalDocument, PASSIVE_EVENTS } from "../constants.js";
import { splitArray } from "../helpers/array/split-array.js";
import { isArray } from "../helpers/checker/is-array.js";
import { isFunction } from "../helpers/checker/is-function.js";
import { isString, isStringArray } from "../helpers/checker/is-string.js";
import { error } from "../helpers/utils/error/index.js";
import { defaultNameSpace, EventHandlersStore } from "./store.js";
/**
* The module editor's event manager
*/
export class EventEmitter {
mute(event) {
this.__mutedEvents.add(event !== null && event !== void 0 ? event : '*');
return this;
}
isMuted(event) {
if (event && this.__mutedEvents.has(event)) {
return true;
}
return this.__mutedEvents.has('*');
}
unmute(event) {
this.__mutedEvents.delete(event !== null && event !== void 0 ? event : '*');
return this;
}
__eachEvent(events, callback) {
const eventParts = splitArray(events).map(e => e.trim());
eventParts.forEach(eventNameSpace => {
const eventAndNameSpace = eventNameSpace.split('.');
const namespace = eventAndNameSpace[1] || defaultNameSpace;
callback.call(this, eventAndNameSpace[0], namespace);
});
}
__getStore(subject) {
if (!subject) {
throw error('Need subject');
}
if (subject[this.__key] === undefined) {
const store = new EventHandlersStore();
Object.defineProperty(subject, this.__key, {
enumerable: false,
configurable: true,
writable: true,
value: store
});
}
return subject[this.__key];
}
__removeStoreFromSubject(subject) {
if (subject[this.__key] !== undefined) {
Object.defineProperty(subject, this.__key, {
enumerable: false,
configurable: true,
writable: true,
value: undefined
});
}
}
__triggerNativeEvent(element, event) {
const evt = this.__doc.createEvent('HTMLEvents');
if (isString(event)) {
evt.initEvent(event, true, true);
}
else {
evt.initEvent(event.type, event.bubbles, event.cancelable);
[
'screenX',
'screenY',
'clientX',
'clientY',
'target',
'srcElement',
'currentTarget',
'timeStamp',
'which',
'keyCode'
].forEach(property => {
Object.defineProperty(evt, property, {
value: event[property],
enumerable: true
});
});
Object.defineProperty(evt, 'originalEvent', {
value: event,
enumerable: true
});
}
element.dispatchEvent(evt);
}
/**
* Get current event name
*
* @example
* ```javascript
* parent.e.on('openDialog closeDialog', function () {
* if (parent.e.current === 'closeDialog') {
* alert('Dialog was closed');
* } else {
* alert('Dialog was opened');
* }
* });
* ```
*/
get current() {
return this.currents[this.currents.length - 1];
}
on(eventsOrSubjects, callbackOrEvents, optionsOrCallback, opts) {
let subjects;
let events;
let callback;
let options;
if (isString(eventsOrSubjects) || isStringArray(eventsOrSubjects)) {
subjects = this;
events = eventsOrSubjects;
callback = callbackOrEvents;
options = optionsOrCallback;
}
else {
subjects = eventsOrSubjects;
events = callbackOrEvents;
callback = optionsOrCallback;
options = opts;
}
if (!(isString(events) || isStringArray(events)) ||
events.length === 0) {
throw error('Need events names');
}
if (!isFunction(callback)) {
throw error('Need event handler');
}
if (isArray(subjects)) {
subjects.forEach(subj => {
this.on(subj, events, callback, options);
});
return this;
}
const subject = subjects;
const store = this.__getStore(subject);
const self = this;
let syntheticCallback = function (event, ...args) {
if (self.isMuted(event)) {
return;
}
return callback && callback.call(this, ...args);
};
if (isDOMElement(subject)) {
syntheticCallback = function (event) {
if (self.isMuted(event.type)) {
return;
}
self.__prepareEvent(event);
if (callback && callback.call(this, event) === false) {
event.preventDefault();
event.stopImmediatePropagation();
return false;
}
return;
};
}
this.__eachEvent(events, (event, namespace) => {
var _a, _b;
if (event.length === 0) {
throw error('Need event name');
}
if (store.indexOf(event, namespace, callback) === false) {
const block = {
event,
originalCallback: callback,
syntheticCallback
};
store.set(event, namespace, block, options === null || options === void 0 ? void 0 : options.top);
if (isDOMElement(subject)) {
const eOpts = PASSIVE_EVENTS.has(event)
? {
passive: true,
capture: (_a = options === null || options === void 0 ? void 0 : options.capture) !== null && _a !== void 0 ? _a : false
}
: ((_b = options === null || options === void 0 ? void 0 : options.capture) !== null && _b !== void 0 ? _b : false);
syntheticCallback.options = eOpts;
subject.addEventListener(event, syntheticCallback, eOpts);
this.__memoryDOMSubjectToHandler(subject, syntheticCallback);
}
}
});
return this;
}
__memoryDOMSubjectToHandler(subject, syntheticCallback) {
const callbackStore = this.__domEventsMap.get(subject) || new Set();
callbackStore.add(syntheticCallback);
this.__domEventsMap.set(subject, callbackStore);
}
__unmemoryDOMSubjectToHandler(subject, syntheticCallback) {
const m = this.__domEventsMap;
const callbackStore = m.get(subject) || new Set();
callbackStore.delete(syntheticCallback);
if (callbackStore.size) {
m.set(subject, callbackStore);
}
else {
m.delete(subject);
}
}
one(eventsOrSubjects, callbackOrEvents, optionsOrCallback, opts) {
let subjects;
let events;
let callback;
let options;
if (isString(eventsOrSubjects) || isStringArray(eventsOrSubjects)) {
subjects = this;
events = eventsOrSubjects;
callback = callbackOrEvents;
options = optionsOrCallback;
}
else {
subjects = eventsOrSubjects;
events = callbackOrEvents;
callback = optionsOrCallback;
options = opts;
}
const newCallback = (...args) => {
this.off(subjects, events, newCallback);
return callback(...args);
};
this.on(subjects, events, newCallback, options);
return this;
}
off(eventsOrSubjects, callbackOrEvents, handler) {
let subjects;
let events;
let callback;
if (isString(eventsOrSubjects) || isStringArray(eventsOrSubjects)) {
subjects = this;
events = eventsOrSubjects;
callback = callbackOrEvents;
}
else {
subjects = eventsOrSubjects;
events = callbackOrEvents;
callback = handler;
}
if (isArray(subjects)) {
subjects.forEach(subj => {
this.off(subj, events, callback);
});
return this;
}
const subject = subjects;
const store = this.__getStore(subject);
if (!(isString(events) || isStringArray(events)) ||
events.length === 0) {
store.namespaces().forEach((namespace) => {
this.off(subject, '.' + namespace);
});
this.__removeStoreFromSubject(subject);
return this;
}
const removeEventListener = (block) => {
var _a;
if (isDOMElement(subject)) {
subject.removeEventListener(block.event, block.syntheticCallback, (_a = block.syntheticCallback.options) !== null && _a !== void 0 ? _a : false);
this.__unmemoryDOMSubjectToHandler(subject, block.syntheticCallback);
}
}, removeCallbackFromNameSpace = (event, namespace) => {
if (event === '') {
store.events(namespace).forEach((eventName) => {
if (eventName !== '') {
removeCallbackFromNameSpace(eventName, namespace);
}
});
return;
}
const blocks = store.get(event, namespace);
if (!blocks || !blocks.length) {
return;
}
if (!isFunction(callback)) {
blocks.forEach(removeEventListener);
blocks.length = 0;
store.clearEvents(namespace, event);
}
else {
const index = store.indexOf(event, namespace, callback);
if (index !== false) {
removeEventListener(blocks[index]);
blocks.splice(index, 1);
if (!blocks.length) {
store.clearEvents(namespace, event);
}
}
}
};
this.__eachEvent(events, (event, namespace) => {
if (namespace === defaultNameSpace) {
store.namespaces().forEach(namespace => {
removeCallbackFromNameSpace(event, namespace);
});
}
else {
removeCallbackFromNameSpace(event, namespace);
}
});
if (store.isEmpty()) {
this.__removeStoreFromSubject(subject);
}
return this;
}
stopPropagation(subjectOrEvents, eventsList) {
const subject = isString(subjectOrEvents)
? this
: subjectOrEvents;
const events = isString(subjectOrEvents)
? subjectOrEvents
: eventsList;
if (typeof events !== 'string') {
throw error('Need event names');
}
const store = this.__getStore(subject);
this.__eachEvent(events, (event, namespace) => {
const blocks = store.get(event, namespace);
if (blocks) {
this.__stopped.push(blocks);
}
if (namespace === defaultNameSpace) {
store
.namespaces(true)
.forEach(ns => this.stopPropagation(subject, event + '.' + ns));
}
});
}
__removeStop(currentBlocks) {
if (currentBlocks) {
const index = this.__stopped.indexOf(currentBlocks);
index !== -1 && this.__stopped.splice(0, index + 1);
}
}
__isStopped(currentBlocks) {
return (currentBlocks !== undefined &&
this.__stopped.indexOf(currentBlocks) !== -1);
}
fire(subjectOrEvents, eventsList, ...args) {
let result, result_value;
const subject = isString(subjectOrEvents)
? this
: subjectOrEvents;
const events = isString(subjectOrEvents)
? subjectOrEvents
: eventsList;
const argumentsList = isString(subjectOrEvents)
? [eventsList, ...args]
: args;
if (!isDOMElement(subject) && !isString(events)) {
throw error('Need events names');
}
const store = this.__getStore(subject);
if (!isString(events) && isDOMElement(subject)) {
this.__triggerNativeEvent(subject, eventsList);
}
else {
this.__eachEvent(events, (event, namespace) => {
if (isDOMElement(subject)) {
this.__triggerNativeEvent(subject, event);
}
else {
const blocks = store.get(event, namespace);
if (blocks) {
try {
[...blocks].every((block) => {
if (this.__isStopped(blocks)) {
return false;
}
this.currents.push(event);
result_value =
block.syntheticCallback.call(subject, event, ...argumentsList);
this.currents.pop();
if (result_value !== undefined) {
result = result_value;
}
return true;
});
}
finally {
this.__removeStop(blocks);
}
}
if (namespace === defaultNameSpace &&
!isDOMElement(subject)) {
store
.namespaces()
.filter(ns => ns !== namespace)
.forEach((ns) => {
const result_second = this.fire.apply(this, [
subject,
event + '.' + ns,
...argumentsList
]);
if (result_second !== undefined) {
result = result_second;
}
});
}
}
});
}
return result;
}
constructor(doc) {
this.__domEventsMap = new Map();
this.__mutedEvents = new Set();
this.__key = '__JoditEventEmitterNamespaces';
this.__doc = globalDocument;
this.__prepareEvent = (e) => {
if (e.cancelBubble) {
return;
}
// for Shadow Dom
if (e.composed && isFunction(e.composedPath) && e.composedPath()[0]) {
Object.defineProperty(e, 'target', {
value: e.composedPath()[0],
configurable: true,
enumerable: true
});
}
if (e.type.match(/^touch/) &&
e.changedTouches &&
e.changedTouches.length) {
['clientX', 'clientY', 'pageX', 'pageY'].forEach((key) => {
Object.defineProperty(e, key, {
value: e.changedTouches[0][key],
configurable: true,
enumerable: true
});
});
}
if (!e.originalEvent) {
e.originalEvent = e;
}
if (e.type === 'paste' &&
e.clipboardData === undefined &&
this.__doc.defaultView.clipboardData) {
Object.defineProperty(e, 'clipboardData', {
get: () => {
return this.__doc.defaultView.clipboardData;
},
configurable: true,
enumerable: true
});
}
};
this.currents = [];
this.__stopped = [];
this.__isDestructed = false;
if (doc) {
this.__doc = doc;
}
this.__key += new Date().getTime();
}
destruct() {
if (this.__isDestructed) {
return;
}
this.__isDestructed = true;
this.__domEventsMap.forEach((set, elm) => {
this.off(elm);
});
this.__domEventsMap.clear();
this.__mutedEvents.clear();
this.currents.length = 0;
this.__stopped.length = 0;
this.off(this);
this.__getStore(this).clear();
this.__removeStoreFromSubject(this);
}
}
function isDOMElement(subject) {
return isFunction(subject.addEventListener);
}

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
*/
/**
* @module event-emitter
*/
import type { CanUndef, IDestructible } from "../../types/index";
/**
* Class for adding event handling capability
*
* ```ts
* class SomeClass extends Eventify<{ start: (node: Node) => boolean; }> {
* constructor() {
* super();
* setTimeout(() => {
* if (this.emit('start', document.body)) {
* console.log('yes');
* };
* }, 100);
* }
* }
*
* const sm = new SomeClass();
* sm.on('start', (node) => {
* console.log(node);
* return true;
* })
* ```
*/
export declare abstract class Eventify<MAP extends {
[key: string]: (...args: any[]) => any;
}, EVENT extends keyof MAP = keyof MAP> implements IDestructible {
private __map;
on(name: EVENT, func: MAP[EVENT]): this;
off(name: keyof MAP, func: MAP[EVENT]): this;
destruct(): void;
protected emit(name: EVENT, ...args: Parameters<MAP[EVENT]>): CanUndef<ReturnType<MAP[EVENT]>>;
}

60
node_modules/jodit/esm/core/event-emitter/eventify.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
/*!
* 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
*/
/**
* Class for adding event handling capability
*
* ```ts
* class SomeClass extends Eventify<{ start: (node: Node) => boolean; }> {
* constructor() {
* super();
* setTimeout(() => {
* if (this.emit('start', document.body)) {
* console.log('yes');
* };
* }, 100);
* }
* }
*
* const sm = new SomeClass();
* sm.on('start', (node) => {
* console.log(node);
* return true;
* })
* ```
*/
export class Eventify {
constructor() {
this.__map = new Map();
}
on(name, func) {
var _a;
if (!this.__map.has(name)) {
this.__map.set(name, new Set());
}
(_a = this.__map.get(name)) === null || _a === void 0 ? void 0 : _a.add(func);
return this;
}
off(name, func) {
var _a;
if (this.__map.has(name)) {
(_a = this.__map.get(name)) === null || _a === void 0 ? void 0 : _a.delete(func);
}
return this;
}
destruct() {
this.__map.clear();
}
emit(name, ...args) {
var _a;
let result;
if (this.__map.has(name)) {
(_a = this.__map.get(name)) === null || _a === void 0 ? void 0 : _a.forEach(cb => {
result = cb(...args);
});
}
return result;
}
}

12
node_modules/jodit/esm/core/event-emitter/index.d.ts generated vendored Normal file
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
*/
/**
* @module event-emitter
*/
export * from "./event-emitter";
export * from "./eventify";
export * from "./observable";
export * from "./store";

12
node_modules/jodit/esm/core/event-emitter/index.js generated vendored Normal file
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
*/
/**
* @module event-emitter
*/
export * from "./event-emitter.js";
export * from "./eventify.js";
export * from "./observable.js";
export * from "./store.js";

View File

@@ -0,0 +1,45 @@
/*!
* 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 event-emitter
*/
import type { IDictionary, IObservable } from "../../types/index";
/**
* Makes any object an observable object
* @example
* ```js
* const obj = {
* a: 1,
* b: {
* c: 5
* }
* }
*
* const obsObj = Jodit.modules.observable(obj);
* console.log(obj === obsObj); // true
* obsObj.on('change', () => {
* console.log('Object changed');
* });
* obsObj.on('change.a', () => {
* console.log('Key a changed');
* });
* obsObj.on('change.b.c', () => {
* console.log('Key b.c changed');
* });
*
* obj.a = 6;
* // Object changed
* // Key a changed
*
* obj.b = {c: 6}
* // Object changed
*
* obj.b.c = 8
* // Object changed
* // Key b.c changed
* ```
*/
export declare function observable<T extends IDictionary, O extends T & IObservable>(obj: T): O;

144
node_modules/jodit/esm/core/event-emitter/observable.js generated vendored Normal file
View File

@@ -0,0 +1,144 @@
/*!
* 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 { getPropertyDescriptor } from "../decorators/watch/watch.js";
import { isArray } from "../helpers/checker/is-array.js";
import { isFastEqual } from "../helpers/checker/is-equal.js";
import { isPlainObject } from "../helpers/checker/is-plain-object.js";
const OBSERVABLE_OBJECT = Symbol('observable-object');
function isObservableObject(obj) {
return obj[OBSERVABLE_OBJECT] !== undefined;
}
/**
* Makes any object an observable object
* @example
* ```js
* const obj = {
* a: 1,
* b: {
* c: 5
* }
* }
*
* const obsObj = Jodit.modules.observable(obj);
* console.log(obj === obsObj); // true
* obsObj.on('change', () => {
* console.log('Object changed');
* });
* obsObj.on('change.a', () => {
* console.log('Key a changed');
* });
* obsObj.on('change.b.c', () => {
* console.log('Key b.c changed');
* });
*
* obj.a = 6;
* // Object changed
* // Key a changed
*
* obj.b = {c: 6}
* // Object changed
*
* obj.b.c = 8
* // Object changed
* // Key b.c changed
* ```
*/
export function observable(obj) {
if (isObservableObject(obj)) {
return obj;
}
const __lockEvent = {};
const __onEvents = {};
const on = (event, callback) => {
if (isArray(event)) {
event.map(e => on(e, callback));
return obj;
}
if (!__onEvents[event]) {
__onEvents[event] = [];
}
__onEvents[event].push(callback);
return obj;
};
const fire = (event, ...attr) => {
if (isArray(event)) {
event.map(e => fire(e, ...attr));
return;
}
try {
if (!__lockEvent[event] && __onEvents[event]) {
__lockEvent[event] = true;
__onEvents[event].forEach(clb => clb.call(obj, ...attr));
}
}
finally {
__lockEvent[event] = false;
}
};
const initAccessors = (dict, prefixes = []) => {
const store = {};
if (isObservableObject(dict)) {
return;
}
Object.defineProperty(dict, OBSERVABLE_OBJECT, {
enumerable: false,
value: true
});
Object.keys(dict).forEach(_key => {
const key = _key;
const prefix = prefixes.concat(key).filter(a => a.length);
store[key] = dict[key];
const descriptor = getPropertyDescriptor(dict, key);
Object.defineProperty(dict, key, {
set: (value) => {
const oldValue = store[key];
if (!isFastEqual(store[key], value)) {
fire([
'beforeChange',
`beforeChange.${prefix.join('.')}`
], key, value);
if (isPlainObject(value)) {
initAccessors(value, prefix);
}
if (descriptor && descriptor.set) {
descriptor.set.call(obj, value);
}
else {
store[key] = value;
}
const sum = [];
fire([
'change',
...prefix.reduce((rs, p) => {
sum.push(p);
rs.push(`change.${sum.join('.')}`);
return rs;
}, [])
], prefix.join('.'), oldValue, (value === null || value === void 0 ? void 0 : value.valueOf)
? value.valueOf()
: value);
}
},
get: () => {
if (descriptor && descriptor.get) {
return descriptor.get.call(obj);
}
return store[key];
},
enumerable: true,
configurable: true
});
if (isPlainObject(store[key])) {
initAccessors(store[key], prefix);
}
});
Object.defineProperty(obj, 'on', {
value: on
});
};
initAccessors(obj);
return obj;
}

21
node_modules/jodit/esm/core/event-emitter/store.d.ts generated vendored Normal file
View File

@@ -0,0 +1,21 @@
/*!
* 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 event-emitter
*/
import type { CallbackFunction, EventHandlerBlock } from "../../types/index";
export declare const defaultNameSpace = "JoditEventDefaultNamespace";
export declare class EventHandlersStore {
private __store;
get(event: string, namespace: string): EventHandlerBlock[] | void;
indexOf(event: string, namespace: string, originalCallback: CallbackFunction): false | number;
namespaces(withoutDefault?: boolean): string[];
events(namespace: string): string[];
set(event: string, namespace: string, data: EventHandlerBlock, onTop?: boolean): void;
clear(): void;
clearEvents(namespace: string, event: string): void;
isEmpty(): boolean;
}

70
node_modules/jodit/esm/core/event-emitter/store.js generated vendored Normal file
View File

@@ -0,0 +1,70 @@
/*!
* 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 { toArray } from "../helpers/array/to-array.js";
import { assert } from "../helpers/utils/assert.js";
export const defaultNameSpace = 'JoditEventDefaultNamespace';
export class EventHandlersStore {
constructor() {
this.__store = new Map();
}
get(event, namespace) {
if (this.__store.has(namespace)) {
const ns = this.__store.get(namespace);
assert(ns, '-');
return ns[event];
}
}
indexOf(event, namespace, originalCallback) {
const blocks = this.get(event, namespace);
if (blocks) {
for (let i = 0; i < blocks.length; i += 1) {
if (blocks[i].originalCallback === originalCallback) {
return i;
}
}
}
return false;
}
namespaces(withoutDefault = false) {
const nss = toArray(this.__store.keys());
return withoutDefault ? nss.filter(ns => ns !== defaultNameSpace) : nss;
}
events(namespace) {
const ns = this.__store.get(namespace);
return ns ? Object.keys(ns) : [];
}
set(event, namespace, data, onTop = false) {
let ns = this.__store.get(namespace);
if (!ns) {
ns = {};
this.__store.set(namespace, ns);
}
if (ns[event] === undefined) {
ns[event] = [];
}
if (!onTop) {
ns[event].push(data);
}
else {
ns[event].unshift(data);
}
}
clear() {
this.__store.clear();
}
clearEvents(namespace, event) {
const ns = this.__store.get(namespace);
if (ns && ns[event]) {
delete ns[event];
if (!Object.keys(ns).length) {
this.__store.delete(namespace);
}
}
}
isEmpty() {
return this.__store.size === 0;
}
}

32
node_modules/jodit/esm/core/global.d.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
/*!
* 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 global
*/
import type { HTMLTagNames, IDictionary, IJodit, IViewBased, IViewComponent, IViewOptions } from "../types/index";
import { PluginSystem } from "./plugin/plugin-system";
import { EventEmitter } from "./event-emitter/index";
export declare const instances: IDictionary<IJodit>;
/**
* Generate global unique uid
*/
export declare function uniqueUid(): string;
export declare const pluginSystem: PluginSystem;
export declare const modules: IDictionary<Function>;
export declare const extendLang: (langs: IDictionary) => void;
/**
* Create unique box(HTMLCotainer) and remove it after destroy
*/
export declare function getContainer<T extends HTMLTagNames = HTMLTagNames>(jodit: IViewBased | IViewComponent, classFunc?: Function | string, tag?: T, createInsideEditor?: boolean): HTMLElementTagNameMap[T];
/**
* Get root element for view
* @internal
*/
export declare function getPopupViewRoot(o: IViewOptions, container: HTMLElement, defaultRoot: HTMLElement): HTMLElement;
/**
* Global event emitter
*/
export declare const eventEmitter: EventEmitter;

106
node_modules/jodit/esm/core/global.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
/*!
* 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();

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
*/
/**
* Always return Array
* ```javascript
* Jodit.modules.Helpers.asArray('test') // ['test']
* Jodit.modules.Helpers.asArray(['test']) // ['test']
* Jodit.modules.Helpers.asArray(1) // [1]
* ```
*/
export declare const asArray: <T>(a: T[] | T) => T[];

18
node_modules/jodit/esm/core/helpers/array/as-array.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/*!
* 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 helpers/array
*/
import { isArray } from "../checker/is-array.js";
/**
* Always return Array
* ```javascript
* Jodit.modules.Helpers.asArray('test') // ['test']
* Jodit.modules.Helpers.asArray(['test']) // ['test']
* Jodit.modules.Helpers.asArray(1) // [1]
* ```
*/
export const asArray = (a) => (isArray(a) ? a : [a]);

11
node_modules/jodit/esm/core/helpers/array/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/*!
* 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 helpers/array
*/
export { asArray } from "./as-array";
export { splitArray } from "./split-array";
export { toArray } from "./to-array";

11
node_modules/jodit/esm/core/helpers/array/index.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/*!
* 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 helpers/array
*/
export { asArray } from "./as-array.js";
export { splitArray } from "./split-array.js";
export { toArray } from "./to-array.js";

View File

@@ -0,0 +1,11 @@
/*!
* 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 helpers/array
*/
export declare function splitArray(a: string): string[];
export declare function splitArray<T extends any[]>(a: T): T;
export declare function splitArray<T extends any[]>(a: T | string): T | string[];

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
*/
/**
* Return an array from string or array
* ```javascript
* Jodit.modules.Helpers.splitArray('1,2,3') // ['1', '2', '3']
* Jodit.modules.Helpers.splitArray(['1', '2', '3']) // ['1', '2', '3']
* ```
*/
export function splitArray(a) {
return Array.isArray(a) ? a : a.split(/[,\s]+/);
}

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
*/
/**
* Always return Array. It's a safe polyfill for [Array.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) method
* In certain scenarios (such as with Joomla Mootools), Array.from may be substituted with a less optimal implementation
* ```javascript
* Jodit.modules.Helpers.toArray('123') // ['1', '2', '3']
* Jodit.modules.Helpers.toArray(['test']) // ['test']
* Jodit.modules.Helpers.toArray(1) // []
* ```
*/
export declare const toArray: typeof Array.from;

26
node_modules/jodit/esm/core/helpers/array/to-array.js 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
*/
/**
* @module helpers/array
*/
import { isNativeFunction } from "../checker/is-native-function.js";
import { reset } from "../utils/reset.js";
/**
* Always return Array. It's a safe polyfill for [Array.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from) method
* In certain scenarios (such as with Joomla Mootools), Array.from may be substituted with a less optimal implementation
* ```javascript
* Jodit.modules.Helpers.toArray('123') // ['1', '2', '3']
* Jodit.modules.Helpers.toArray(['test']) // ['test']
* Jodit.modules.Helpers.toArray(1) // []
* ```
*/
export const toArray = function toArray(...args) {
var _a;
const func = isNativeFunction(Array.from)
? Array.from
: ((_a = reset('Array.from')) !== null && _a !== void 0 ? _a : Array.from);
return func.apply(Array, args);
};

9
node_modules/jodit/esm/core/helpers/async/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* 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 helpers/async
*/
export * from "./set-timeout";

9
node_modules/jodit/esm/core/helpers/async/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/*!
* 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 helpers/async
*/
export * from "./set-timeout.js";

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
*/
/**
* Create async callback if set timeout value - else call function immediately
*/
export declare function setTimeout<T = any>(callback: (...args: T[]) => void, timeout: number, ...args: T[]): number;
/**
* Clear timeout
*/
export declare function clearTimeout(timer: number): void;

View File

@@ -0,0 +1,27 @@
/*!
* 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 helpers/async
*/
import { globalWindow } from "../../constants.js";
/**
* Create async callback if set timeout value - else call function immediately
*/
export function setTimeout(callback, timeout, ...args) {
if (!timeout) {
callback.call(null, ...args);
}
else {
return globalWindow.setTimeout(callback, timeout, ...args);
}
return 0;
}
/**
* Clear timeout
*/
export function clearTimeout(timer) {
globalWindow.clearTimeout(timer);
}

View File

@@ -0,0 +1,9 @@
/*!
* 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
*/
/**
* Check if browser has a color picker (a new HTML5 attribute for input tag)
*/
export declare function hasBrowserColorPicker(): boolean;

View File

@@ -0,0 +1,25 @@
/*!
* 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 helpers/checker
*/
import { globalDocument } from "../../constants.js";
/**
* Check if browser has a color picker (a new HTML5 attribute for input tag)
*/
export function hasBrowserColorPicker() {
let supportsColor = true;
try {
const a = globalDocument.createElement('input');
a.type = 'color';
a.value = '!';
supportsColor = a.type === 'color' && a.value !== '!';
}
catch (e) {
supportsColor = false;
}
return supportsColor;
}

33
node_modules/jodit/esm/core/helpers/checker/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/*!
* 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 helpers/checker
*/
export * from "./has-browser-color-picker";
export * from "./is-abort-error";
export * from "./is-array";
export * from "./is-boolean";
export * from "./is-equal";
export * from "./is-function";
export * from "./is-html";
export * from "./is-html-from-word";
export * from "./is-imp-interface";
export * from "./is-int";
export * from "./is-jodit-object";
export * from "./is-license";
export * from "./is-marker";
export * from "./is-native-function";
export * from "./is-number";
export * from "./is-numeric";
export * from "./is-plain-object";
export * from "./is-promise";
export * from "./is-set";
export * from "./is-string";
export * from "./is-url";
export * from "./is-valid-name";
export * from "./is-view-object";
export * from "./is-void";
export * from "./is-window";

33
node_modules/jodit/esm/core/helpers/checker/index.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
/*!
* 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 helpers/checker
*/
export * from "./has-browser-color-picker.js";
export * from "./is-abort-error.js";
export * from "./is-array.js";
export * from "./is-boolean.js";
export * from "./is-equal.js";
export * from "./is-function.js";
export * from "./is-html.js";
export * from "./is-html-from-word.js";
export * from "./is-imp-interface.js";
export * from "./is-int.js";
export * from "./is-jodit-object.js";
export * from "./is-license.js";
export * from "./is-marker.js";
export * from "./is-native-function.js";
export * from "./is-number.js";
export * from "./is-numeric.js";
export * from "./is-plain-object.js";
export * from "./is-promise.js";
export * from "./is-set.js";
export * from "./is-string.js";
export * from "./is-url.js";
export * from "./is-valid-name.js";
export * from "./is-view-object.js";
export * from "./is-void.js";
export * from "./is-window.js";

View File

@@ -0,0 +1,10 @@
/*!
* 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 helpers/checker
*/
import type { AbortError } from "../utils/error/errors/abort-error";
export declare function isAbortError(error: unknown): error is AbortError;

View File

@@ -0,0 +1,10 @@
/*!
* 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
*/
export function isAbortError(error) {
return (Boolean(error) &&
error instanceof DOMException &&
error.name === 'AbortError');
}

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
*/
/**
* @module helpers/checker
*/
/**
* Check if element is array
*/
export declare function isArray<T = any>(elm: unknown): elm is T[];

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 helpers/checker
*/
/**
* Check if element is array
*/
export function isArray(elm) {
return Array.isArray(elm);
}

View File

@@ -0,0 +1,9 @@
/*!
* 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 helpers/checker
*/
export declare function isBoolean(elm: unknown): elm is boolean;

View File

@@ -0,0 +1,11 @@
/*!
* 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 helpers/checker
*/
export function isBoolean(elm) {
return typeof elm === 'boolean';
}

View File

@@ -0,0 +1,10 @@
/*!
* 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
*/
/**
* Check two element are equal
*/
export declare function isEqual(a: unknown, b: unknown): boolean;
export declare function isFastEqual(a: unknown, b: unknown): boolean;

View File

@@ -0,0 +1,18 @@
/*!
* 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 helpers/checker
*/
import { stringify } from "../string/stringify.js";
/**
* Check two element are equal
*/
export function isEqual(a, b) {
return a === b || stringify(a) === stringify(b);
}
export function isFastEqual(a, b) {
return a === b;
}

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
*/
/**
* @module helpers/checker
*/
/**
* Check value is Function
*/
export declare function isFunction(value: unknown): value is Function;

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 helpers/checker
*/
/**
* Check value is Function
*/
export function isFunction(value) {
return typeof value === 'function';
}

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
*/
/**
* @module helpers/checker
*/
/**
* Detect if string is HTML from MS Word or Excel
*/
export declare function isHtmlFromWord(data: string): boolean;

View File

@@ -0,0 +1,16 @@
/*!
* 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 helpers/checker
*/
/**
* Detect if string is HTML from MS Word or Excel
*/
export function isHtmlFromWord(data) {
return (data.search(/<meta.*?Microsoft Excel\s[\d].*?>/) !== -1 ||
data.search(/<meta.*?Microsoft Word\s[\d].*?>/) !== -1 ||
(data.search(/style="[^"]*mso-/) !== -1 && data.search(/<font/) !== -1));
}

View File

@@ -0,0 +1,9 @@
/*!
* 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
*/
/**
* Check if a string is html or not
*/
export declare const isHTML: (str: unknown) => str is string;

14
node_modules/jodit/esm/core/helpers/checker/is-html.js generated vendored Normal file
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 helpers/checker
*/
import { isString } from "./is-string.js";
/**
* Check if a string is html or not
*/
export const isHTML = (str) => isString(str) &&
/<([A-Za-z][A-Za-z0-9]*)\b[^>]*>(.*?)<\/\1>/m.test(str.replace(/[\r\n]/g, ''));

View File

@@ -0,0 +1,21 @@
/*!
* 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 helpers/checker
*/
import type { IContainer, IDestructible, IInitable } from "../../../types/index";
/**
* Check value has method init
*/
export declare function isInitable(value: unknown): value is IInitable;
/**
* Check value has method destruct
*/
export declare function isDestructable(value: unknown): value is IDestructible;
/**
* Check value is instant that implements IContainer
*/
export declare function hasContainer(value: unknown): value is IContainer;

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 "../../dom/dom.js";
import { isFunction } from "./is-function.js";
import { isVoid } from "./is-void.js";
/**
* Check value has method init
*/
export function isInitable(value) {
return !isVoid(value) && isFunction(value.init);
}
/**
* Check value has method destruct
*/
export function isDestructable(value) {
return !isVoid(value) && isFunction(value.destruct);
}
/**
* Check value is instant that implements IContainer
*/
export function hasContainer(value) {
return !isVoid(value) && Dom.isElement(value.container);
}

View File

@@ -0,0 +1,9 @@
/*!
* 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
*/
/**
* Check value is Int
*/
export declare function isInt(value: number | string): boolean;

19
node_modules/jodit/esm/core/helpers/checker/is-int.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/*!
* 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 helpers/checker
*/
import { isNumeric } from "./is-numeric.js";
import { isString } from "./is-string.js";
/**
* Check value is Int
*/
export function isInt(value) {
if (isString(value) && isNumeric(value)) {
value = parseFloat(value);
}
return typeof value === 'number' && Number.isFinite(value) && !(value % 1);
}

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 helpers/checker
*/
import type { IJodit } from "../../../types/index";
/**
* Check if element is instance of Jodit
*/
export declare function isJoditObject(jodit: unknown): jodit is IJodit;

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 { isFunction } from "./is-function.js";
/**
* Check if element is instance of Jodit
*/
export function isJoditObject(jodit) {
return Boolean(jodit &&
jodit instanceof Object &&
isFunction(jodit.constructor) &&
// @ts-ignore
((typeof Jodit !== 'undefined' && jodit instanceof Jodit) ||
jodit.isJodit));
}

View File

@@ -0,0 +1,6 @@
/*!
* 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
*/
export declare const isLicense: (license: string) => 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
*/
/**
* @module helpers/checker
*/
import { isString } from "./is-string.js";
export const isLicense = (license) => isString(license) &&
license.length === 23 &&
/^[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{5}$/i.test(license);

Some files were not shown because too many files have changed in this diff Show More