import { chainCommands, exitCode } from 'prosemirror-commands';
import { TextSelection } from 'prosemirror-state';
import { logger } from "../../../logger.js";
import { isMac } from "../../../utils/platform.js";
import { isTextSelection } from "../../../utils/selection.js";
import { pType } from "../../base/BaseSchema/BaseSchemaSpecs/index.js";
import { BreaksSpecs, hbType, sbType } from "./BreaksSpecs/index.js";
export { BreaksSpecs, BreakNodeName, hbType, sbType } from "./BreaksSpecs/index.js";
export const Breaks = (builder, opts) => {
    let preferredBreak;
    if (builder.context.has('breaks')) {
        preferredBreak = builder.context.get('breaks') ? 'soft' : 'hard';
    }
    else {
        preferredBreak = opts.preferredBreak ?? 'hard';
        logger.info("[Breaks extension]: Parameter 'breaks' is not defined in context; value from options is used");
    }
    builder.use(BreaksSpecs, { preferredBreak });
    builder.addKeymap(({ schema }) => {
        const cmd = addBr((preferredBreak === 'soft' ? sbType : hbType)(schema));
        const keys = {
            'Shift-Enter': cmd,
        };
        if (isMac()) {
            keys['Ctrl-Enter'] = cmd;
        }
        return keys;
    });
};
const addBr = (br) => chainCommands(exitCode, (state, dispatch) => {
    const { selection: sel, schema } = state;
    if (!isTextSelection(sel) ||
        !sel.empty ||
        // breaks can only be in the paragraph
        sel.$cursor?.parent.type !== pType(schema))
        return false;
    if (isBreakNode(sel.$cursor.nodeBefore)) {
        if (dispatch) {
            const { $cursor, $cursor: { pos }, } = sel;
            const from = isBreakNode($cursor.nodeAfter) ? pos + 1 : pos;
            const posEnd = $cursor.end();
            const posAfter = $cursor.after();
            const contentAfter = state.doc.slice(from, posEnd, false).content;
            let tr = state.tr.insert(posAfter, pType(schema).create(null, contentAfter));
            tr = tr
                .setSelection(TextSelection.create(tr.doc, posAfter + 1))
                .scrollIntoView()
                .delete(pos, posEnd) // remove content after current pos (it's moved to next para)
                .delete(pos - 1, pos); // remove break before current pos ($cursor.nodeBefore)
            dispatch(tr);
        }
        return true;
    }
    dispatch?.(state.tr.replaceSelectionWith(br.create()).scrollIntoView());
    return true;
});
function isBreakNode(node) {
    return Boolean(node?.type.spec.isBreak);
}
//# sourceMappingURL=index.js.map
