import { EditorState } from 'prosemirror-state';
import { EditorView } from 'prosemirror-view';
import { Logger2 } from "../logger.js";
import { WysiwygContentHandler } from "./ContentHandler.js";
import { ExtensionsManager } from "./ExtensionsManager.js";
import { SchemaDynamicModifier } from "./SchemaDynamicModifier.js";
import { MarkdownParserDynamicModifier } from "./markdown/MarkdownParser.js";
import { MarkdownSerializerDynamicModifier } from "./markdown/MarkdownSerializerDynamicModifier.js";
import { bindActions } from "./utils/actions.js";
import { convertDynamicModifiersConfigs } from "./utils/dynamicModifiers.js";
import { LoggerFacet } from "./utils/logger.js";
import { logTransactionMetrics } from "./utils/metrics.js";
export class WysiwygEditor {
    #view;
    #serializer;
    #parser;
    #actions;
    #contentHandler;
    #escapeConfig;
    get dom() {
        return this.#view.dom;
    }
    get serializer() {
        return this.#serializer;
    }
    get parser() {
        return this.#parser;
    }
    get actions() {
        return this.#actions.actions;
    }
    /** @internal used for prosemirror-dev-tools in demo */
    get view() {
        return this.#view;
    }
    constructor({ domElem, initialContent = '', extensions = () => { }, allowHTML, mdPreset, linkify, pmTransformers, linkifyTlds, escapeConfig, onChange, onDocChange, modifiers, logger = new Logger2(), }) {
        const dynamicModifiersConfig = modifiers
            ? convertDynamicModifiersConfigs(modifiers)
            : undefined;
        const dynamicModifiers = dynamicModifiersConfig
            ? {
                schema: new SchemaDynamicModifier(dynamicModifiersConfig.schema),
                parser: new MarkdownParserDynamicModifier(dynamicModifiersConfig.parser),
                serializer: new MarkdownSerializerDynamicModifier(dynamicModifiersConfig.serializer),
            }
            : undefined;
        const { schema, markupParser: parser, serializer, nodeViews, markViews, plugins, rawActions, actions, } = ExtensionsManager.process(extensions, {
            // "breaks" option only affects the renderer, but not the parser
            mdOpts: { html: allowHTML, linkify, breaks: true, preset: mdPreset },
            linkifyTlds,
            pmTransformers,
            dynamicModifiers,
        }, logger);
        plugins.unshift(LoggerFacet.of(logger));
        const state = EditorState.create({
            schema,
            doc: parser.parse(initialContent),
            plugins,
        });
        const thisOnChange = () => this.tryOnChange(onChange);
        const thisOnDocChange = () => this.tryOnChange(onDocChange);
        this.#view = new EditorView(domElem ?? null, {
            state,
            nodeViews,
            markViews,
            dispatchTransaction(tr) {
                const newState = this.state.apply(tr);
                // @ts-expect-error
                this.updateState(newState);
                thisOnChange();
                if (tr.docChanged) {
                    thisOnDocChange();
                }
                logTransactionMetrics(tr, logger);
            },
        });
        this.#actions = actions.setActions(bindActions(rawActions)(this.#view));
        this.#serializer = serializer;
        this.#parser = parser;
        this.#contentHandler = new WysiwygContentHandler(this.#view, parser);
        this.#escapeConfig = escapeConfig;
    }
    action(actionName) {
        return this.#actions.action(actionName);
    }
    focus() {
        return this.#view.focus();
    }
    hasFocus() {
        return this.#view.hasFocus();
    }
    getValue() {
        return this.#serializer.serialize(this.#view.state.doc, this.#escapeConfig);
    }
    isEmpty() {
        const { doc } = this.#view.state;
        return (doc.childCount === 1 &&
            doc.firstChild?.type.name === 'paragraph' &&
            doc.firstChild.childCount === 0);
    }
    clear() {
        return this.#contentHandler.clear();
    }
    replace(newMarkup) {
        return this.#contentHandler.replace(newMarkup);
    }
    prepend(markup) {
        return this.#contentHandler.prepend(markup);
    }
    append(markup) {
        return this.#contentHandler.append(markup);
    }
    moveCursor(position) {
        return this.#contentHandler.moveCursor(position);
    }
    destroy() {
        this.#view.destroy();
    }
    tryOnChange(cb) {
        if (cb) {
            try {
                cb(this);
            }
            catch (err) {
                console.error(err);
            }
        }
    }
}
//# sourceMappingURL=Editor.js.map
