import MarkdownIt from "markdown-it";
import mdTasksLists from 'markdown-it-task-lists';
import code from '../services/code';
+import Clipboard from "../services/clipboard";
import {debounce} from "../services/util";
import DrawIO from "../services/drawio";
// Handle image paste
cm.on('paste', (cm, event) => {
- const clipboardItems = event.clipboardData.items;
- if (!event.clipboardData || !clipboardItems) return;
+ const clipboard = new Clipboard(event.clipboardData || event.dataTransfer);
- // Don't handle if clipboard includes text content
- for (let clipboardItem of clipboardItems) {
- if (clipboardItem.type.includes('text/')) {
- return;
- }
+ // Don't handle the event ourselves if no items exist of contains table-looking data
+ if (!clipboard.hasItems() || clipboard.containsTabularData()) {
+ return;
}
- for (let clipboardItem of clipboardItems) {
- if (clipboardItem.type.includes("image")) {
- uploadImage(clipboardItem.getAsFile());
- }
+ const images = clipboard.getImages();
+ for (const image of images) {
+ uploadImage(image);
}
});
});
}
- if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) {
+ const clipboard = new Clipboard(event.dataTransfer);
+ if (clipboard.hasItems()) {
const cursorPos = cm.coordsChar({left: event.pageX, top: event.pageY});
cm.setCursor(cursorPos);
event.stopPropagation();
event.preventDefault();
- for (let i = 0; i < event.dataTransfer.files.length; i++) {
- uploadImage(event.dataTransfer.files[i]);
+ const images = clipboard.getImages();
+ for (const image of images) {
+ uploadImage(image);
}
}
import Code from "../services/code";
import DrawIO from "../services/drawio";
+import Clipboard from "../services/clipboard";
/**
* Handle pasting images from clipboard.
* @param editor
*/
function editorPaste(event, editor, wysiwygComponent) {
- const clipboardItems = event.clipboardData.items;
- if (!event.clipboardData || !clipboardItems) return;
+ const clipboard = new Clipboard(event.clipboardData || event.dataTransfer);
- // Don't handle if clipboard includes text content
- for (let clipboardItem of clipboardItems) {
- if (clipboardItem.type.includes('text/')) {
- return;
- }
+ // Don't handle the event ourselves if no items exist of contains table-looking data
+ if (!clipboard.hasItems() || clipboard.containsTabularData()) {
+ return;
}
- for (let clipboardItem of clipboardItems) {
- if (!clipboardItem.type.includes("image")) {
- continue;
- }
+ const images = clipboard.getImages();
+ for (const imageFile of images) {
const id = "image-" + Math.random().toString(16).slice(2);
const loadingImage = window.baseUrl('/loading.gif');
- const file = clipboardItem.getAsFile();
+ event.preventDefault();
setTimeout(() => {
editor.insertContent(`<p><img src="${loadingImage}" id="${id}"></p>`);
- uploadImageFile(file, wysiwygComponent).then(resp => {
- editor.dom.setAttrib(id, 'src', resp.thumbs.display);
+ uploadImageFile(imageFile, wysiwygComponent).then(resp => {
+ const safeName = resp.name.replace(/"/g, '');
+ const newImageHtml = `<img src="${resp.thumbs.display}" alt="${safeName}" />`;
+
+ const newEl = editor.dom.create('a', {
+ target: '_blank',
+ href: resp.url,
+ }, newImageHtml);
+
+ editor.dom.replace(newEl, id);
}).catch(err => {
editor.dom.remove(id);
window.$events.emit('error', trans('errors.image_upload_error'));
});
}
+ if (!event.isDefaultPrevented()) {
+ editorPaste(event, editor, context);
+ }
+
wrap = null;
});
--- /dev/null
+
+class Clipboard {
+
+ /**
+ * Constructor
+ * @param {DataTransfer} clipboardData
+ */
+ constructor(clipboardData) {
+ this.data = clipboardData;
+ }
+
+ /**
+ * Check if the clipboard has any items.
+ */
+ hasItems() {
+ return Boolean(this.data) && Boolean(this.data.types) && this.data.types.length > 0;
+ }
+
+ /**
+ * Check if the given event has tabular-looking data in the clipboard.
+ * @return {boolean}
+ */
+ containsTabularData() {
+ const rtfData = this.data.getData( 'text/rtf');
+ return rtfData && rtfData.includes('\\trowd');
+ }
+
+ /**
+ * Get the images that are in the clipboard data.
+ * @return {Array<File>}
+ */
+ getImages() {
+ const types = this.data.types;
+ const files = this.data.files;
+ const images = [];
+
+ for (const type of types) {
+ if (type.includes('image')) {
+ const item = this.data.getData(type);
+ images.push(item.getAsFile());
+ }
+ }
+
+ for (const file of files) {
+ if (file.type.includes('image')) {
+ images.push(file);
+ }
+ }
+
+ return images;
+ }
+}
+
+export default Clipboard;
\ No newline at end of file