]> BookStack Code Mirror - hacks/commitdiff
Merge branch 'main' of github.com:BookStackApp/hacks
authorDan Brown <redacted>
Wed, 7 Jun 2023 09:58:33 +0000 (10:58 +0100)
committerDan Brown <redacted>
Wed, 7 Jun 2023 09:58:33 +0000 (10:58 +0100)
content/wysiwyg-docx-import/head.html [new file with mode: 0644]
content/wysiwyg-docx-import/index.md [new file with mode: 0644]

diff --git a/content/wysiwyg-docx-import/head.html b/content/wysiwyg-docx-import/head.html
new file mode 100644 (file)
index 0000000..7612b5d
--- /dev/null
@@ -0,0 +1,40 @@
+<script src="https://cdn.jsdelivr.net/npm/[email protected]/mammoth.browser.min.js" defer></script>
+
+<script type="module">
+    // Convert the given "file" instance to HTML and insert the results
+    // into the given TinyMCE "editor" instance.
+    function convertAndInsertDocx(editor, file) {
+        // Use a FileReader to handle conversion via an ArrayBuffer
+        const reader = new FileReader();
+        reader.onload = async function(loadEvent) {
+            // Get and convert the ArrayBuffer version of the file
+            const arrayBuffer = loadEvent.target.result;
+            const {value: html, messages} = await window.mammoth.convertToHtml({arrayBuffer});
+            // If warnings exists from conversion, log them to the browser console then
+            // show a warning alert via BookStack's event system.
+            if (messages.length > 0) {
+                console.error(messages);
+                window.$events.emit('warning', `${messages.length} warnings logged to browser console during conversion`);
+            }
+            // Insert the resulting HTML content insert the editor
+            editor.insertContent(html);
+        }
+        reader.readAsArrayBuffer(file);
+    }
+
+    // Listen to BookStack emmitted WYSWIYG editor setup event
+    window.addEventListener('editor-tinymce::setup', event => {
+        // Get a reference to the editor and listen to file "drop" events
+        const editor = event.detail.editor;
+        editor.on('drop', event => {
+            // For each of the files in the drop event, pass them, alonside the editor instance
+            // to our "convertAndInsertDocx" function above if they're docx files.
+            const files = event?.dataTransfer?.files || [];
+            for (const file of files) {
+                if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' && window.mammoth) {
+                    convertAndInsertDocx(editor, file);
+                }
+            }
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/content/wysiwyg-docx-import/index.md b/content/wysiwyg-docx-import/index.md
new file mode 100644 (file)
index 0000000..7c67b8c
--- /dev/null
@@ -0,0 +1,25 @@
++++
+title = "WYSIWYG Docx Import"
+author = "@ssddanbrown"
+date = 2023-06-07T09:00:00Z
+updated = 2023-06-07T09:00:00Z
+tested = "v23.05"
++++
+
+This hack adds the ability to import ".docx" files into the WYSIWYG editor,
+by dragging and dropping a "docx" file into the editor area. 
+The file contents are converted to HTML then inserted into the editor at the current cursor position.
+
+Conversion is performed browser-side using the [mammoth.js](https://github.com/mwilliamson/mammoth.js) library.
+Warning messages from the conversion will be logged to the browser console, and a popup warning notification will advise of this.
+
+#### Considerations
+
+- This hack uses an externally hosted library, hosted on `jsdelivr.net`. You could host this locally instead if desired.
+- The conversion is relatively simplistic, to result in clean HTML for use in BookStack. Not all formatting is supported by the conversion and you'll likely loose layout or formatting. Don't expect a replica result in BookStack, this is more for easy importing of existing content.
+- Images will be within content, base64 included, until save when BookStack will attempt to extract them out. This may cause editor performance to be particular slow until first save after import.
+- You will likely see a "Dropped file type is not supported" warning message pop-up in the editor.
+
+#### Code
+
+{{<hack file="head.html" type="head">}}