"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = PreserveFontSizeOnEnterPlugin;
const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext");
const lexical_1 = require("lexical");
const list_1 = require("@lexical/list");
const selection_1 = require("@lexical/selection");
const react_1 = require("react");
/**
 * Extracts font size from a CSS style string.
 * @param style CSS style text to parse.
 * @returns Font size value, or an empty string when absent.
 */
function getFontSizeFromStyle(style) {
    var _a;
    return ((_a = (0, selection_1.getStyleObjectFromCSS)(style)) === null || _a === void 0 ? void 0 : _a['font-size']) || '';
}
/**
 * Gets the font size that should be preserved for a collapsed selection.
 * @returns Font size value, or an empty string when no font size is available.
 */
function getCollapsedSelectionFontSize() {
    const selection = (0, lexical_1.$getSelection)();
    if (!(0, lexical_1.$isRangeSelection)(selection) || !selection.isCollapsed()) {
        return '';
    }
    const selectionFontSize = (0, selection_1.$getSelectionStyleValueForProperty)(selection, 'font-size', '');
    if (selectionFontSize) {
        return selectionFontSize;
    }
    const anchor = selection.anchor;
    const anchorNode = anchor.getNode();
    if ((0, lexical_1.$isTextNode)(anchorNode)) {
        return getFontSizeFromStyle(anchorNode.getStyle());
    }
    if ((0, lexical_1.$isElementNode)(anchorNode)) {
        const previousNode = anchor.offset > 0 ? anchorNode.getChildAtIndex(anchor.offset - 1) : null;
        const nextNode = anchorNode.getChildAtIndex(anchor.offset);
        if ((0, lexical_1.$isTextNode)(previousNode)) {
            return getFontSizeFromStyle(previousNode.getStyle());
        }
        if ((0, lexical_1.$isTextNode)(nextNode)) {
            return getFontSizeFromStyle(nextNode.getStyle());
        }
    }
    return '';
}
/**
 * Checks whether the current selection is inside an empty list item.
 * @returns True when the collapsed selection is in an empty list item.
 */
function isSelectionInEmptyListItem() {
    const selection = (0, lexical_1.$getSelection)();
    if (!(0, lexical_1.$isRangeSelection)(selection) || !selection.isCollapsed()) {
        return false;
    }
    const anchorNode = selection.anchor.getNode();
    if ((0, list_1.$isListItemNode)(anchorNode) && anchorNode.getChildrenSize() === 0) {
        return true;
    }
    if (!(0, lexical_1.$isTextNode)(anchorNode)) {
        return false;
    }
    const parent = anchorNode.getParent();
    return ((0, list_1.$isListItemNode)(parent) &&
        parent.getChildren().every((node) => (0, lexical_1.$isTextNode)(node) && node.getTextContent().trim() === ''));
}
/**
 * Syncs the inserted block and collapsed selection to a font size after Lexical handles list exit.
 * @param editor Active Lexical editor.
 * @param fontSize Font size that should drive the next caret height.
 */
function syncListExitFontSize(editor, fontSize) {
    const applyFontSize = () => {
        editor.update(() => {
            const selection = (0, lexical_1.$getSelection)();
            if (!(0, lexical_1.$isRangeSelection)(selection) || !selection.isCollapsed()) {
                return;
            }
            const anchorNode = selection.anchor.getNode();
            const targetNode = (0, lexical_1.$isElementNode)(anchorNode)
                ? anchorNode
                : (0, lexical_1.$isTextNode)(anchorNode)
                    ? anchorNode.getTopLevelElement()
                    : null;
            if (!(0, lexical_1.$isElementNode)(targetNode)) {
                return;
            }
            const targetNodeKey = targetNode.getKey();
            const blockStyles = (0, selection_1.getStyleObjectFromCSS)(targetNode.getStyle());
            const fontSizeStyle = (0, selection_1.getCSSFromStyleObject)({ 'font-size': fontSize });
            targetNode.setStyle((0, selection_1.getCSSFromStyleObject)({
                ...blockStyles,
                'font-size': fontSize,
            }));
            targetNode.setTextStyle(fontSizeStyle);
            (0, selection_1.$patchStyleText)(selection, {
                'font-size': fontSize,
            });
            const applyFontSizeToElement = () => {
                const targetElement = editor.getElementByKey(targetNodeKey);
                targetElement === null || targetElement === void 0 ? void 0 : targetElement.style.setProperty('font-size', fontSize);
            };
            if (typeof queueMicrotask === 'function') {
                queueMicrotask(applyFontSizeToElement);
            }
            requestAnimationFrame(applyFontSizeToElement);
        });
    };
    if (typeof queueMicrotask === 'function') {
        queueMicrotask(applyFontSize);
    }
    else {
        setTimeout(applyFontSize);
    }
}
/**
 * Preserves font size when inserting a paragraph with Enter.
 * @returns Null because the plugin renders no UI.
 */
function PreserveFontSizeOnEnterPlugin() {
    const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
    (0, react_1.useEffect)(() => {
        return editor.registerCommand(lexical_1.INSERT_PARAGRAPH_COMMAND, () => {
            const selection = (0, lexical_1.$getSelection)();
            const fontSize = getCollapsedSelectionFontSize();
            if (!(0, lexical_1.$isRangeSelection)(selection) || !selection.isCollapsed() || !fontSize) {
                return false;
            }
            if (isSelectionInEmptyListItem()) {
                syncListExitFontSize(editor, fontSize);
                return false;
            }
            const insertedBlock = selection.insertParagraph();
            if ((0, lexical_1.$isElementNode)(insertedBlock)) {
                const insertedBlockKey = insertedBlock.getKey();
                const blockStyles = (0, selection_1.getStyleObjectFromCSS)(insertedBlock.getStyle());
                const fontSizeStyle = (0, selection_1.getCSSFromStyleObject)({ 'font-size': fontSize });
                insertedBlock.setStyle((0, selection_1.getCSSFromStyleObject)({
                    ...blockStyles,
                    'font-size': fontSize,
                }));
                insertedBlock.setTextStyle(fontSizeStyle);
                insertedBlock.selectStart();
                const applyFontSizeToInsertedElement = () => {
                    const insertedElement = editor.getElementByKey(insertedBlockKey);
                    insertedElement === null || insertedElement === void 0 ? void 0 : insertedElement.style.setProperty('font-size', fontSize);
                };
                if (typeof queueMicrotask === 'function') {
                    queueMicrotask(applyFontSizeToInsertedElement);
                }
                requestAnimationFrame(applyFontSizeToInsertedElement);
            }
            const nextSelection = (0, lexical_1.$getSelection)();
            if ((0, lexical_1.$isRangeSelection)(nextSelection) && nextSelection.isCollapsed()) {
                (0, selection_1.$patchStyleText)(nextSelection, {
                    'font-size': fontSize,
                });
            }
            return true;
        }, lexical_1.COMMAND_PRIORITY_CRITICAL);
    }, [editor]);
    return null;
}
//# sourceMappingURL=index.js.map