"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.selection = void 0;
const prosemirror_commands_1 = require("prosemirror-commands");
const prosemirror_keymap_1 = require("prosemirror-keymap");
const prosemirror_state_1 = require("prosemirror-state");
const prosemirror_view_1 = require("prosemirror-view");
const nodes_1 = require("../../../utils/nodes.js");
const selection_1 = require("../../../utils/selection.js");
const commands_1 = require("./commands.js");
require("./selection.css");
const selection = () => new prosemirror_state_1.Plugin({
    props: {
        handleKeyDown: (0, prosemirror_keymap_1.keydownHandler)({
            ArrowLeft: commands_1.arrowLeft,
            ArrowRight: commands_1.arrowRight,
            ArrowUp: commands_1.arrowUp,
            ArrowDown: commands_1.arrowDown,
            Backspace: commands_1.backspace,
        }),
        decorations(state) {
            return getDecorations(state.tr);
        },
        handleClickOn(view, _pos, node, nodePos, _event, direct) {
            if (direct && node.type.spec.allowSelection) {
                return selectNode(nodePos)(view.state, view.dispatch);
            }
            return false;
        },
    },
    view(view) {
        reselect(view);
        return {
            update(view) {
                reselect(view);
            },
        };
    },
});
exports.selection = selection;
const reselect = (view) => {
    const { selection: sel } = view.state;
    if (!sel.empty && (0, selection_1.isNodeSelection)(sel) && !(0, nodes_1.isSelectableNode)(sel.node)) {
        return (0, prosemirror_commands_1.selectParentNode)(view.state, view.dispatch);
    }
    return false;
};
const selectNode = (pos) => (state, dispatch) => {
    if (dispatch) {
        dispatch(state.tr.setSelection(new prosemirror_state_1.NodeSelection(state.doc.resolve(pos))));
    }
    return true;
};
const getDecorations = (tr) => {
    if (tr.selection instanceof prosemirror_state_1.NodeSelection) {
        return prosemirror_view_1.DecorationSet.create(tr.doc, [
            prosemirror_view_1.Decoration.node(tr.selection.from, tr.selection.to, {
                class: 'pm-node-selected',
            }),
        ]);
    }
    if (tr.selection instanceof prosemirror_state_1.TextSelection || tr.selection instanceof prosemirror_state_1.AllSelection) {
        const decorations = getTopLevelNodesFromSelection(tr.selection, tr.doc).map(({ node, pos }) => {
            return prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
                class: 'pm-node-selected',
            });
        });
        return prosemirror_view_1.DecorationSet.create(tr.doc, decorations);
    }
    return prosemirror_view_1.DecorationSet.empty;
};
const getTopLevelNodesFromSelection = (selection, doc) => {
    const nodes = [];
    if (selection.from !== selection.to) {
        const { from, to } = selection;
        doc.nodesBetween(from, to, (node, pos) => {
            const withinSelection = from <= pos && pos + node.nodeSize <= to;
            if (node && !node.isText && node.type.spec.selectable !== false && withinSelection) {
                nodes.push({ node, pos });
                return false;
            }
            return true;
        });
    }
    return nodes;
};
//# sourceMappingURL=selection.js.map
