Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/js/ui/text-editor/src/ |
Upload File : |
/* eslint-disable @bitrix24/bitrix24-rules/no-native-dom-methods */ import { Type } from 'main.core'; import { $createParagraphNode, $isElementNode, $isRootNode, $isTextNode } from 'ui.lexical.core'; import { type ElementNode, type LexicalNode } from 'ui.lexical.core'; import { type TextEditor } from './text-editor'; import { type SchemeNodeValidation, type SchemeValidationOptions } from './types/scheme-validation-options'; export default class SchemeValidation { #editor: TextEditor = null; #nodeTypeToBBCodeType: Map<string, string> = new Map(); #nodeValidation: Map<string, Object> = new Map(); constructor(editor: TextEditor) { this.#editor = editor; this.#initNodeValidation(); } isNodeAllowed(parent: LexicalNode | string, child: LexicalNode | string): boolean { const parentCode = Type.isString(parent) ? parent : this.#nodeTypeToBBCodeType.get(parent.getType()); const childCode = Type.isString(child) ? child : this.#nodeTypeToBBCodeType.get(child.getType()); if (!parentCode) { // eslint-disable-next-line no-console console.warn(`TextEditor: parent node (${parent.getType()}) doesn't have a bbcode tag.`); } if (!childCode) { // eslint-disable-next-line no-console console.warn(`TextEditor: child node (${child.getType()}) doesn't have a bbcode tag.`); } return this.#editor.getBBCodeScheme().isChildAllowed(parentCode, childCode); } findAllowedParent(node: LexicalNode): ElementNode | null { let parent: ElementNode = node.getParent(); while (parent !== null) { if (this.isNodeAllowed(parent, node)) { return parent; } parent = parent.getParent(); } return null; } #initNodeValidation(): void { const handleNodeTransform = this.#handleNodeTransform.bind(this); for (const [, plugin] of this.#editor.getPlugins()) { const validation: SchemeValidationOptions | null = plugin.validateScheme(); if (!Type.isPlainObject(validation)) { continue; } if (Type.isArrayFilled(validation.nodes)) { validation.nodes.forEach((nodeValidation: SchemeNodeValidation) => { this.#editor.registerNodeTransform(nodeValidation.nodeClass, handleNodeTransform); if (Type.isFunction(nodeValidation.validate)) { this.#nodeValidation.set(nodeValidation.nodeClass.getType(), { validate: nodeValidation.validate }); } }); } if (Type.isPlainObject(validation.bbcodeMap)) { for (const [nodeType, bbcodeTag] of Object.entries(validation.bbcodeMap)) { this.#nodeTypeToBBCodeType.set(nodeType, bbcodeTag); } } } } #handleNodeTransform(node: LexicalNode | ElementNode): void { const { validate = null } = this.#nodeValidation.get(node.getType()) || {}; if (validate !== null && validate(node, this) === true) { return; } const parent: ElementNode = node.getParent(); if (this.isNodeAllowed(parent, node)) { return; } // eslint-disable-next-line no-console console.warn(`TextEditor: ${node.getType()} is not allowed in ${parent.getType()}`); this.moveToNextParent(node); } moveToNextParent(node: LexicalNode | ElementNode, removeOnFail: boolean = true): boolean { let parent: ElementNode = node.getParent(); let targetNode: ElementNode = null; while (parent.getParent() !== null) { if (this.isNodeAllowed(parent.getParent(), node)) { targetNode = parent; break; } parent = parent.getParent(); } if (targetNode === null) { if (removeOnFail) { node.remove(); } return false; } if ($isRootNode(targetNode.getParent()) && ($isTextNode(node) || ($isElementNode(node) && node.isInline()))) { targetNode.insertBefore($createParagraphNode().append(node)); return true; } targetNode.insertBefore(node); return true; } }