"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = SanitizePastePlugin;
const clipboard_1 = require("@lexical/clipboard");
const html_1 = require("@lexical/html");
const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext");
const lexical_1 = require("lexical");
const react_1 = require("react");
const LEXICAL_MIME_TYPE = 'application/x-lexical-editor';
const PRESENTATIONAL_ATTRIBUTES = ['class', 'id', 'style'];
const LEGACY_PRESENTATIONAL_ATTRIBUTES = ['align', 'bgcolor', 'color', 'face', 'size'];
const REMOVED_TAGS = ['link', 'meta', 'script', 'style'];
/**
 * Removes unsafe and presentational markup from pasted HTML.
 * @param doc Parsed clipboard HTML document.
 */
function sanitizePastedHTMLDocument(doc) {
    REMOVED_TAGS.forEach((tagName) => {
        doc.querySelectorAll(tagName).forEach((node) => node.remove());
    });
    doc.body.querySelectorAll('*').forEach((element) => {
        PRESENTATIONAL_ATTRIBUTES.forEach((attribute) => {
            element.removeAttribute(attribute);
        });
        if (element.tagName === 'FONT') {
            LEGACY_PRESENTATIONAL_ATTRIBUTES.forEach((attribute) => {
                element.removeAttribute(attribute);
            });
        }
    });
}
/**
 * Inserts pasted plain text as separate paragraphs when it contains line breaks.
 * @param text Plain text clipboard content.
 * @returns True when text was handled as multiple paragraphs.
 */
function insertMultilinePlainText(text) {
    if (!/\r|\n/.test(text)) {
        return false;
    }
    const selection = (0, lexical_1.$getSelection)();
    if (!(0, lexical_1.$isRangeSelection)(selection)) {
        return false;
    }
    const paragraphs = text
        .replace(/\r\n?/g, '\n')
        .split('\n')
        .map((line) => {
        const paragraph = (0, lexical_1.$createParagraphNode)();
        if (line.length > 0) {
            paragraph.append((0, lexical_1.$createTextNode)(line));
        }
        return paragraph;
    });
    selection.insertNodes(paragraphs);
    return true;
}
/**
 * Registers paste sanitization for the rich text editor.
 * @returns Null because the plugin only registers editor commands.
 */
function SanitizePastePlugin() {
    const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
    (0, react_1.useEffect)(() => editor.registerCommand(lexical_1.PASTE_COMMAND, (event) => {
        if (!('clipboardData' in event) || event.clipboardData == null) {
            return false;
        }
        const { clipboardData } = event;
        if (clipboardData.types.includes(LEXICAL_MIME_TYPE)) {
            return false;
        }
        const text = clipboardData.getData('text/plain');
        if (/\r|\n/.test(text)) {
            event.preventDefault();
            return insertMultilinePlainText(text);
        }
        const html = clipboardData.getData('text/html');
        if (!html) {
            return false;
        }
        event.preventDefault();
        editor.update(() => {
            const selection = (0, lexical_1.$getSelection)();
            if (selection == null) {
                return;
            }
            const parser = new DOMParser();
            const doc = parser.parseFromString(html, 'text/html');
            sanitizePastedHTMLDocument(doc);
            const nodes = (0, html_1.$generateNodesFromDOM)(editor, doc);
            (0, clipboard_1.$insertGeneratedNodes)(editor, nodes, selection);
        });
        return true;
    }, lexical_1.COMMAND_PRIORITY_HIGH), [editor]);
    return null;
}
//# sourceMappingURL=index.js.map