1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
import axios from '~/lib/utils/axios_utils';
/**
* A set of functions to decouple the content_editor component from
* the draw.io editor.
* It allows the draw.io editor to obtain a selected drawio_diagram
* and replace it or insert a new drawio_diagram node without coupling
* the drawio_editor to the Content Editor implementation details
* *
* @param {Object} params Factory function parameters
* @param {Object} params.tiptapEditor See https://tiptap.dev/api/editor
* @param {String} params.drawioNodeName Name of the drawio_diagram node in
* the ProseMirror document
* @param {String} params.uploadsPath API endpoint to upload files
* @param {Object} params.assetResolver See
* app/assets/javascripts/content_editor/services/asset_resolver.js
*
* @returns A content_editor_facade object with operations
* to get a selected diagram, upload a diagram, insert a new one in the
* Content Editor, and update an existing’s diagram URL.
*/
export const create = ({ tiptapEditor, drawioNodeName, uploadsPath, assetResolver }) => ({
getDiagram: async () => {
const { node } = tiptapEditor.state.selection;
if (!node || node.type.name !== drawioNodeName) {
return null;
}
const { src } = node.attrs;
const response = await axios.get(src, { responseType: 'text' });
const diagramSvg = response.data;
const contentType = response.headers['content-type'];
const filename = src.split('/').pop();
return {
diagramURL: src,
filename,
diagramSvg,
contentType,
};
},
updateDiagram: async ({ uploadResults: { file_path: canonicalSrc } }) => {
const src = await assetResolver.resolveUrl(canonicalSrc);
tiptapEditor
.chain()
.focus()
.updateAttributes(drawioNodeName, {
src,
canonicalSrc,
})
.run();
},
insertDiagram: async ({ uploadResults: { file_path: canonicalSrc } }) => {
const src = await assetResolver.resolveUrl(canonicalSrc);
tiptapEditor
.chain()
.focus()
.insertContent({
type: drawioNodeName,
attrs: {
src,
canonicalSrc,
},
})
.run();
},
uploadDiagram: async ({ filename, diagramSvg }) => {
const blob = new Blob([diagramSvg], { type: 'image/svg+xml' });
const formData = new FormData();
formData.append('file', blob, filename);
const response = await axios.post(uploadsPath, formData);
return response.data;
},
});
|