1/**
2 * Prosemirror view for the diagrams node
3 */
4class DiagramsView extends AbstractNodeView {
5    /** {DiagramsForm} The form to edit the node attributes */
6    #dForm = null;
7
8
9    /**
10     * Render the node into this.dom
11     *
12     * We use the schema's spec.toDOM() method instead of directly using the passed attributes
13     * to render the node to avoid code duplication and to have a central way to map node
14     * attributes to dom attributes.
15     *
16     * @param {object} attrs
17     */
18    renderNode(attrs) {
19        const schemaSpec = this.node.type.spec.toDOM(this.node);
20        const elem = document.createElement(schemaSpec[0]);
21
22        // copy attributes to dom element
23        Object.entries(schemaSpec[1]).forEach(([key, value]) => {
24            if (value) {
25                elem.setAttribute(key, value);
26            }
27        });
28
29        this.dom = elem;
30    }
31
32    /**
33     * Handle node selection
34     *
35     * Update and show the form
36     */
37    selectNode() {
38        this.dom.classList.add('ProseMirror-selectednode');
39
40        this.#dForm = new DiagramsForm(
41            this.node.attrs,
42            this.dispatchNodeUpdate.bind(this),
43            this.deselectNode.bind(this)
44        );
45        this.#dForm.show();
46    }
47
48    /**
49     * Handle node deselection
50     *
51     * Closes the form
52     */
53    deselectNode() {
54        this.dom.classList.remove('ProseMirror-selectednode');
55    }
56
57    /**
58     * Dispatches a node update to the editor
59     *
60     * @param {object} newAttrs
61     */
62    dispatchNodeUpdate(newAttrs) {
63        const nodeStartPos = this.getPos();
64        this.outerView.dispatch(this.outerView.state.tr.setNodeMarkup(
65            nodeStartPos,
66            null,
67            newAttrs,
68            this.node.marks,
69        ));
70    }
71}
72