]> BookStack Code Mirror - bookstack/blob - resources/js/services/drawio.js
Ran eslint fix on existing codebase
[bookstack] / resources / js / services / drawio.js
1 let iFrame = null;
2 let lastApprovedOrigin;
3 let onInit; let
4     onSave;
5
6 /**
7  * Show the draw.io editor.
8  * @param {String} drawioUrl
9  * @param {Function} onInitCallback - Must return a promise with the xml to load for the editor.
10  * @param {Function} onSaveCallback - Is called with the drawing data on save.
11  */
12 function show(drawioUrl, onInitCallback, onSaveCallback) {
13     onInit = onInitCallback;
14     onSave = onSaveCallback;
15
16     iFrame = document.createElement('iframe');
17     iFrame.setAttribute('frameborder', '0');
18     window.addEventListener('message', drawReceive);
19     iFrame.setAttribute('src', drawioUrl);
20     iFrame.setAttribute('class', 'fullscreen');
21     iFrame.style.backgroundColor = '#FFFFFF';
22     document.body.appendChild(iFrame);
23     lastApprovedOrigin = (new URL(drawioUrl)).origin;
24 }
25
26 function close() {
27     drawEventClose();
28 }
29
30 /**
31  * Receive and handle a message event from the draw.io window.
32  * @param {MessageEvent} event
33  */
34 function drawReceive(event) {
35     if (!event.data || event.data.length < 1) return;
36     if (event.origin !== lastApprovedOrigin) return;
37
38     const message = JSON.parse(event.data);
39     if (message.event === 'init') {
40         drawEventInit();
41     } else if (message.event === 'exit') {
42         drawEventClose();
43     } else if (message.event === 'save') {
44         drawEventSave(message);
45     } else if (message.event === 'export') {
46         drawEventExport(message);
47     } else if (message.event === 'configure') {
48         drawEventConfigure();
49     }
50 }
51
52 function drawEventExport(message) {
53     if (onSave) {
54         onSave(message.data);
55     }
56 }
57
58 function drawEventSave(message) {
59     drawPostMessage({
60         action: 'export', format: 'xmlpng', xml: message.xml, spin: 'Updating drawing',
61     });
62 }
63
64 function drawEventInit() {
65     if (!onInit) return;
66     onInit().then(xml => {
67         drawPostMessage({action: 'load', autosave: 1, xml});
68     });
69 }
70
71 function drawEventConfigure() {
72     const config = {};
73     window.$events.emitPublic(iFrame, 'editor-drawio::configure', {config});
74     drawPostMessage({action: 'configure', config});
75 }
76
77 function drawEventClose() {
78     window.removeEventListener('message', drawReceive);
79     if (iFrame) document.body.removeChild(iFrame);
80 }
81
82 function drawPostMessage(data) {
83     iFrame.contentWindow.postMessage(JSON.stringify(data), lastApprovedOrigin);
84 }
85
86 async function upload(imageData, pageUploadedToId) {
87     const data = {
88         image: imageData,
89         uploaded_to: pageUploadedToId,
90     };
91     const resp = await window.$http.post(window.baseUrl('/images/drawio'), data);
92     return resp.data;
93 }
94
95 /**
96  * Load an existing image, by fetching it as Base64 from the system.
97  * @param drawingId
98  * @returns {Promise<string>}
99  */
100 async function load(drawingId) {
101     try {
102         const resp = await window.$http.get(window.baseUrl(`/images/drawio/base64/${drawingId}`));
103         return `data:image/png;base64,${resp.data.content}`;
104     } catch (error) {
105         if (error instanceof window.$http.HttpError) {
106             window.$events.showResponseError(error);
107         }
108         close();
109         throw error;
110     }
111 }
112
113 export default {
114     show, close, upload, load,
115 };