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

42
node_modules/jodit/esm/plugins/paste/config.d.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
/**
* @module plugins/paste
*/
import type { HTMLTagNames, IUIOption } from "../../types/index";
declare module 'jodit/config' {
interface Config {
/**
* Ask before paste HTML in WYSIWYG mode
*/
askBeforePasteHTML: boolean;
/**
* When the user inserts a snippet of HTML, the plugin will prompt for the insertion method.
* If the user inserts the same fragment again, the previously selected option will be used without prompting for confirmation.
*/
memorizeChoiceWhenPasteFragment: boolean;
/**
* Handle pasted text - similar to HTML
*/
processPasteHTML: boolean;
/**
* Inserts HTML line breaks before all newlines in a string
*/
nl2brInPlainText: boolean;
/**
* List of tags that will not be removed from the pasted HTML with INSERT_AS_TEXT mode
*/
pasteExcludeStripTags: HTMLTagNames[];
/**
* Options when inserting HTML string
*/
pasteHTMLActionList: IUIOption[];
/**
* Scroll the editor to the pasted fragment
*/
scrollToPastedContent: boolean;
}
}

84
node_modules/jodit/esm/plugins/paste/config.js generated vendored Normal file
View File

@@ -0,0 +1,84 @@
/*!
* 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 { CLIPBOARD_ID, INSERT_AS_HTML, INSERT_AS_TEXT, INSERT_ONLY_TEXT, IS_PROD, TEXT_PLAIN } from "../../core/constants.js";
import { Config } from "../../config.js";
import { pasteInsertHtml } from "./helpers.js";
Config.prototype.askBeforePasteHTML = true;
Config.prototype.processPasteHTML = true;
Config.prototype.scrollToPastedContent = true;
Config.prototype.pasteExcludeStripTags = ['br', 'hr'];
Config.prototype.pasteHTMLActionList = [
{ value: INSERT_AS_HTML, text: 'Keep' },
{ value: INSERT_AS_TEXT, text: 'Insert as Text' },
{ value: INSERT_ONLY_TEXT, text: 'Insert only Text' }
];
Config.prototype.memorizeChoiceWhenPasteFragment = false;
Config.prototype.nl2brInPlainText = true;
const psKey = 'pasteStorage';
Config.prototype.controls.paste = {
tooltip: 'Paste from clipboard',
async exec(editor, _, { control }) {
if (control.name === psKey) {
editor.execCommand('showPasteStorage');
return;
}
editor.s.focus();
let text = '', error = true;
if (navigator.clipboard) {
try {
const items = await navigator.clipboard.read();
if (items && items.length) {
const textBlob = await items[0].getType(TEXT_PLAIN);
text = await new Response(textBlob).text();
}
error = false;
}
catch (e) {
if (!IS_PROD) {
// eslint-disable-next-line no-console
console.log(e);
}
}
if (error) {
try {
text = await navigator.clipboard.readText();
error = false;
}
catch (e) {
if (!IS_PROD) {
// eslint-disable-next-line no-console
console.log(e);
}
}
}
}
if (error) {
text = editor.buffer.get(CLIPBOARD_ID) || '';
error = text.length === 0;
}
const value = editor.value;
if (error) {
editor.ed.execCommand('paste');
error = value === editor.value;
!error && editor.e.fire('afterPaste');
}
else if (text.length) {
pasteInsertHtml(null, editor, text);
editor.e.fire('afterPaste');
}
else {
if (error) {
editor.alert("Your browser doesn't support direct access to the clipboard.", () => void editor.s.focus());
}
}
},
list: {
[psKey]: 'Paste Storage'
},
isChildDisabled(j) {
return j.e.fire('pasteStorageList') < 2;
}
};

25
node_modules/jodit/esm/plugins/paste/helpers.d.ts generated vendored Normal file
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 plugins/paste
*/
import type { IDialog, IJodit, InsertMode, IUIOption, Nullable } from "../../types/index";
import type { PasteEvent } from "./interface";
/**
* One insert point for clipboard plugins
* @private
*/
export declare function pasteInsertHtml(e: Nullable<PasteEvent>, editor: IJodit, html: number | string | Node): void;
/**
* Return all available data types in event
* @private
*/
export declare function getAllTypes(dt: DataTransfer): string;
/**
* Make command dialog
* @private
*/
export declare function askInsertTypeDialog(jodit: IJodit, msg: string, title: string, callback: (yes: InsertMode) => void, buttonList: IUIOption[]): IDialog | void;

104
node_modules/jodit/esm/plugins/paste/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,104 @@
/*!
* 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 { TEXT_PLAIN } from "../../core/constants.js";
import { Dom } from "../../core/dom/dom.js";
import { isArray, isNumber, isString, isVoid } from "../../core/helpers/checker/index.js";
import { Button } from "../../core/ui/button/button/button.js";
/**
* Remove special HTML comments
* @private
*/
function removeExtraFragments(html) {
html = html.replace(/<meta[^>]+?>/g, '');
const start = html.search(/<!--StartFragment-->/i);
if (start !== -1) {
html = html.substring(start + 20);
}
const end = html.search(/<!--EndFragment-->/i);
if (end !== -1) {
html = html.substring(0, end);
}
return html;
}
/**
* @private
*/
function isDragEvent(e) {
return Boolean(e && e.type === 'drop');
}
/**
* One insert point for clipboard plugins
* @private
*/
export function pasteInsertHtml(e, editor, html) {
if (editor.isInDestruct) {
return;
}
if (isDragEvent(e)) {
editor.s.insertCursorAtPoint(e.clientX, e.clientY);
}
const result = editor.e.fire('beforePasteInsert', html);
if (!isVoid(result) &&
(isString(result) || isNumber(result) || Dom.isNode(result))) {
html = result;
}
if (isString(html)) {
html = removeExtraFragments(html);
}
editor.s.insertHTML(html);
}
/**
* Return all available data types in event
* @private
*/
export function getAllTypes(dt) {
const types = dt.types;
let types_str = '';
if (isArray(types) ||
{}.toString.call(types) === '[object DOMStringList]') {
for (let i = 0; i < types.length; i += 1) {
types_str += types[i] + ';';
}
}
else {
types_str = (types || TEXT_PLAIN).toString() + ';';
}
return types_str;
}
/**
* Make command dialog
* @private
*/
export function askInsertTypeDialog(jodit, msg, title, callback, buttonList) {
if (jodit.e.fire('beforeOpenPasteDialog', msg, title, callback, buttonList) === false) {
return;
}
const dialog = jodit.confirm(`<div style="word-break: normal; white-space: normal">${jodit.i18n(msg)}</div>`, jodit.i18n(title));
const buttons = buttonList.map(({ text, value }) => Button(jodit, {
text,
name: text.toLowerCase(),
tabIndex: 0
}).onAction(() => {
dialog.close();
callback(value);
}));
dialog.e.one(dialog, 'afterClose', () => {
if (!jodit.s.isFocused()) {
jodit.s.focus();
}
});
const cancel = Button(jodit, {
text: 'Cancel',
tabIndex: 0
}).onAction(() => {
dialog.close();
});
dialog.setFooter([...buttons, cancel]);
buttons[0].focus();
buttons[0].state.variant = 'primary';
jodit.e.fire('afterOpenPasteDialog', dialog, msg, title, callback, buttonList);
return dialog;
}

38
node_modules/jodit/esm/plugins/paste/interface.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 plugins/paste
*/
import type { InsertMode } from "../../types/index";
export type PasteEvent = ClipboardEvent | DragEvent;
export type PastedValue = {
html: string | Node;
action?: InsertMode;
};
export interface PastedData {
html?: string;
plain?: string;
rtf?: string;
}
declare module 'jodit/types/events' {
interface IEventEmitter {
/**
* Emitted before a clipboard paste is processed
* @event
*/
on(event: 'beforePaste', callback: (e: PasteEvent) => void | false): this;
/**
* Emitted after a clipboard paste is processed
* @event
*/
on(event: 'afterPaste', callback: (e: PasteEvent) => false): this;
/**
* Emitted before a clipboard paste if buffer content is like HTML
* @event
*/
on(event: 'processHTML', callback: (e: PasteEvent, value: string, texts: PastedData) => void | true): this;
}
}

6
node_modules/jodit/esm/plugins/paste/interface.js generated vendored Normal file
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 {};

51
node_modules/jodit/esm/plugins/paste/paste.d.ts generated vendored Normal file
View File

@@ -0,0 +1,51 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
/**
* [[include:plugins/paste/README.md]]
* @packageDocumentation
* @module plugins/paste
*/
import type { IJodit } from "../../types/index";
import { Plugin } from "../../core/plugin/plugin";
import "./config";
/**
* Ask before paste HTML source
*/
export declare class paste extends Plugin {
private pasteStack;
/** @override **/
protected afterInit(jodit: IJodit): void;
/** @override **/
protected beforeDestruct(jodit: IJodit): void;
/**
* Paste event handler
*/
private onPaste;
/**
* Process before paste
*/
private customPasteProcess;
/**
* Default paster process
*/
private defaultPasteProcess;
/**
* The dialog box was already open
*/
private _isDialogOpened;
/**
* Process usual HTML text fragment
*/
private processHTML;
/**
* Insert HTML by option type
*/
private __insertByType;
/**
* Replace all \\n chars in plain text to br
*/
private onProcessPasteReplaceNl2Br;
}

181
node_modules/jodit/esm/plugins/paste/paste.js generated vendored Normal file
View File

@@ -0,0 +1,181 @@
/*!
* 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 { CLIPBOARD_ID, INSERT_AS_TEXT, INSERT_CLEAR_HTML, INSERT_ONLY_TEXT, TEXT_HTML, TEXT_PLAIN, TEXT_RTF } from "../../core/constants.js";
import { autobind } from "../../core/decorators/index.js";
import { Dom } from "../../core/dom/dom.js";
import { pluginSystem } from "../../core/global.js";
import { cleanFromWord, getDataTransfer, htmlspecialchars, isHTML, isString, LimitedStack, nl2br, stripTags, trim } from "../../core/helpers/index.js";
import { Plugin } from "../../core/plugin/plugin.js";
import "./config.js";
import { askInsertTypeDialog, getAllTypes, pasteInsertHtml } from "./helpers.js";
/**
* Ask before paste HTML source
*/
export class paste extends Plugin {
constructor() {
super(...arguments);
this.pasteStack = new LimitedStack(20);
/**
* The dialog box was already open
*/
this._isDialogOpened = false;
}
/** @override **/
afterInit(jodit) {
jodit.e
.on('paste.paste', this.onPaste)
.on('pasteStack.paste', (item) => this.pasteStack.push(item));
if (jodit.o.nl2brInPlainText) {
this.j.e.on('processPaste.paste', this.onProcessPasteReplaceNl2Br);
}
}
/** @override **/
beforeDestruct(jodit) {
jodit.e
.off('paste.paste', this.onPaste)
.off('processPaste.paste', this.onProcessPasteReplaceNl2Br)
.off('.paste');
}
/**
* Paste event handler
*/
onPaste(e) {
try {
if (this.customPasteProcess(e) === false ||
this.j.e.fire('beforePaste', e) === false) {
e.preventDefault();
return false;
}
this.defaultPasteProcess(e);
}
finally {
this.j.e.fire('afterPaste', e);
}
}
/**
* Process before paste
*/
customPasteProcess(e) {
if (!this.j.o.processPasteHTML) {
return;
}
const dt = getDataTransfer(e), texts = [
dt === null || dt === void 0 ? void 0 : dt.getData(TEXT_PLAIN),
dt === null || dt === void 0 ? void 0 : dt.getData(TEXT_HTML),
dt === null || dt === void 0 ? void 0 : dt.getData(TEXT_RTF)
];
for (const value of texts) {
if (isHTML(value) &&
(this.j.e.fire('processHTML', e, value, {
plain: texts[0],
html: texts[1],
rtf: texts[2]
}) ||
this.processHTML(e, value))) {
return false;
}
}
}
/**
* Default paster process
*/
defaultPasteProcess(e) {
const dt = getDataTransfer(e);
let text = (dt === null || dt === void 0 ? void 0 : dt.getData(TEXT_HTML)) || (dt === null || dt === void 0 ? void 0 : dt.getData(TEXT_PLAIN));
if (dt && text && trim(text) !== '') {
const result = this.j.e.fire('processPaste', e, text, getAllTypes(dt));
if (result !== undefined) {
text = result;
}
if (isString(text) || Dom.isNode(text)) {
this.__insertByType(e, text, this.j.o.defaultActionOnPaste);
}
e.preventDefault();
e.stopPropagation();
}
}
/**
* Process usual HTML text fragment
*/
processHTML(e, html) {
if (!this.j.o.askBeforePasteHTML) {
return false;
}
if (this.j.o.memorizeChoiceWhenPasteFragment) {
const cached = this.pasteStack.find(cachedItem => cachedItem.html === html);
if (cached) {
this.__insertByType(e, html, cached.action || this.j.o.defaultActionOnPaste);
return true;
}
}
if (this._isDialogOpened) {
return true;
}
const dialog = askInsertTypeDialog(this.j, 'Your code is similar to HTML. Keep as HTML?', 'Paste as HTML', insertType => {
this._isDialogOpened = false;
this.__insertByType(e, html, insertType);
}, this.j.o.pasteHTMLActionList);
if (dialog) {
this._isDialogOpened = true;
dialog.e.on('beforeClose', () => {
this._isDialogOpened = false;
});
}
return true;
}
/**
* Insert HTML by option type
*/
__insertByType(e, html, action) {
this.pasteStack.push({ html, action });
if (isString(html)) {
this.j.buffer.set(CLIPBOARD_ID, html);
switch (action) {
case INSERT_CLEAR_HTML:
html = cleanFromWord(html);
break;
case INSERT_ONLY_TEXT:
html = stripTags(html, this.j.ed, new Set(this.j.o.pasteExcludeStripTags));
break;
case INSERT_AS_TEXT:
html = htmlspecialchars(html);
break;
default: {
const newHTML = this.j.e.fire('onCustomPasteHTMLOption', action, html, e);
if (typeof newHTML === 'string') {
html = newHTML;
}
}
}
}
pasteInsertHtml(e, this.j, html);
}
/**
* Replace all \\n chars in plain text to br
*/
onProcessPasteReplaceNl2Br(ignore, text, type) {
if (type === TEXT_PLAIN + ';' && !isHTML(text)) {
return nl2br(text);
}
}
}
__decorate([
autobind
], paste.prototype, "onPaste", null);
__decorate([
autobind
], paste.prototype, "onProcessPasteReplaceNl2Br", null);
pluginSystem.add('paste', paste);