tinymce-5tinymce-plugins

Can TinyMCE convert image pasted as data to an upload?


I am using TinyMCE 5.7 and it handles uploading images well. However when an image is pasted from the clipboard (ex: Snipping Tool) it gets pasted as data which is not desired. I can use the setting paste_data_images to block pasting data images but I would prefer that it convert the data into an upload request like normal image upload process. Is there a way to intercept the paste and do the upload? I am using both the image and paste plugins. Thanks


Solution

  • Eventually I figured out how to write my own paste function. First, in the TinyMCE config:

            setup: function (editor) {
            editor.on('paste', function (e) {
                var imageBlob = retrieveImageFromClipboardAsBlob(e);
                if (!imageBlob) {
                    return;
                }
                e.preventDefault();
                uploadFile(imageBlob, function (response) {
                    if ('location' in response) {
                        if (editor) {
                            // console.log('upload completed', response);
                            editor.insertContent('<img src="' + response.location + '" />');
                        } else {
                            console.log('Tinymce editor not found!');
                        }
                    }
                });
            });
        }
    

    Then the routine to decode the pasted info:

    function retrieveImageFromClipboardAsBlob(pasteEvent) {
        if (pasteEvent.clipboardData === false) {
            return false;
        }
    
        var items = pasteEvent.clipboardData.items;
    
        if (items === undefined) {
            return false;
        }
    
        for (var i = 0; i < items.length; i++) {
            // Only paste if image is only choice
            if (items[i].type.indexOf("image") === -1) {
                return false;
            }
            // Retrieve image on clipboard as blob
            var blob = items[i].getAsFile();
    
            // load image if there is a pasted image
            if (blob !== null) {
                const reader = new FileReader();
                reader.onload = function(e) {
                    // console.log('result', e.target.result);
                };
                reader.readAsDataURL(blob);
                return blob;
            }
        }
        return false;
    }
    

    and a routine to upload the file

    function uploadFile(file, callback) {
        var xhr = new XMLHttpRequest();
    
        xhr.upload.onprogress = function (e) {
            var percentComplete = (e.loaded / e.total) * 100;
            console.log("Uploaded: " + percentComplete + "%");
        };
    
        xhr.onload = function () {
            if (xhr.status !== 200) {
                alert("Error! Upload failed " + xhr.response);
            }
            if (callback) {
                callback(JSON.parse(xhr.response));
            }
        };
    
        xhr.onerror = function () {
            alert("Error! Upload failed. Can not connect to server.");
        };
    
        xhr.open("POST", "/upload/tinymce", true);
        var data = new FormData();
        data.append('file', file);
        xhr.send(data);
    }