xref: /plugin/diagrams/script/DiagramsForm.js (revision 0ec94f66261066d45d3a211f0fade04069b99b28)
1class DiagramsForm extends KeyValueForm {
2    constructor(name = 'diagrams-form', fields = []) {
3        if (fields.length === 0) {
4            fields = [
5                {
6                    label: LANG.plugins.diagrams.mediaSource, name: 'src'
7                },
8                {
9                    type: 'select', 'label': LANG.plugins.diagrams.alignment, 'options':
10                        [
11                            {name: 'alignment', value: 'left', label: LANG.plugins.diagrams.left},
12                            {name: 'alignment', value: 'right', label: LANG.plugins.diagrams.right},
13                            {name: 'alignment', value: 'center', label: LANG.plugins.diagrams.center}
14                        ]
15                }
16            ];
17        }
18
19        super(name, fields);
20
21        if (!this.instance) {
22            // media manager button
23            const selectButton = document.createElement('button');
24            selectButton.innerText = LANG.plugins.diagrams.selectSource;
25            selectButton.className = 'diagrams-btn-select';
26            selectButton.addEventListener('click', DiagramsForm.openMediaManager);
27            this.$form.find('fieldset').prepend(selectButton);
28            window.dMediaSelect = this.mediaSelect.bind(this);
29
30            // editor button
31            const editButton = document.createElement('button');
32            editButton.className = 'diagrams-btn-edit';
33            editButton.id = 'diagrams__btn-edit';
34            editButton.innerText = LANG.plugins.diagrams.editButton;
35            this.$form.find('fieldset').prepend(editButton);
36
37            editButton.addEventListener('click', event => {
38                event.preventDefault(); // prevent form submission
39
40                const url = editButton.getAttribute('data-url');
41                const mediaid = editButton.getAttribute('data-id');
42
43                if(mediaid) {
44                    console.log('edit media');
45                    const diagramsEditor = new DiagramsEditor(this.onSavedMediaFile.bind(this, url));
46                    diagramsEditor.editMediaFile();
47                } else {
48                    console.log('edit embed');
49                    const diagramsEditor = new DiagramsEditor();
50                    diagramsEditor.editMemory(url, this.onSaveEmbed);
51                }
52
53            });
54        }
55
56        return this.instance;
57    }
58
59    /**
60     * After svaing a media file reload the src for all images using it
61     *
62     * @see https://stackoverflow.com/a/66312176
63     * @param {string} url
64     * @returns {Promise<void>}
65     */
66    async onSavedMediaFile(url) {
67        await fetch(url, {cache: 'reload', mode: 'no-cors'});
68        document.body.querySelectorAll(`img[src='${url}']`)
69            .forEach(img => img.src = url)
70    }
71
72    /**
73     * Save an embedded diagram back to the editor
74     */
75    onSaveEmbed(svg) {
76        // FIXME how do we update the diagram?
77        const url = 'data:image/svg+xml;base64,' + btoa(svg);
78
79        return true;
80    }
81
82    setEditButtonUrl(id, url) {
83        const $editButton = jQuery(this.$form.find('#diagrams__btn-edit'));
84        // FIXME show/hide button depending on set url
85        $editButton.attr('data-id', id);
86        $editButton.attr('data-url', url);
87    }
88
89    setSource(id = '') {
90        this.$form.find('[name="src"]').val(id);
91    }
92
93    getSource() {
94        return this.$form.find('[name="src"]').val();
95    }
96
97    setAlignment(align = '') {
98        this.$form.find('[name="alignment"]').prop('selected', '');
99        this.$form.find(`[name="alignment"][value="${align}"]`).prop('selected', 'selected');
100    }
101
102    getAlignment() {
103        return this.$form.find('[name="alignment"]:checked').val();
104    }
105
106    resetForm() {
107        this.setSource();
108        this.setAlignment();
109    }
110
111    static resolveSubmittedLinkData(initialAttrs, $diagramsForm, callback) {
112        return (event) => {
113            event.preventDefault();
114            const newAttrs = { ...initialAttrs };
115            newAttrs.id = $diagramsForm.getSource();
116            // FIXME is this conditional?
117            newAttrs.data = `${DOKU_BASE}lib/exe/fetch.php?cache=nocache&media=` + $diagramsForm.getSource();
118            newAttrs.align = $diagramsForm.getAlignment();
119
120            callback(newAttrs);
121        };
122    }
123
124    static openMediaManager() {
125        window.open(
126            `${DOKU_BASE}lib/exe/mediamanager.php?ns=${encodeURIComponent(JSINFO.namespace)}&onselect=dMediaSelect`,
127            'mediaselect',
128            'width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes',
129        );
130    }
131
132    mediaSelect(edid, mediaid, opts, align) {
133        this.setSource(mediaid);
134    }
135}
136