Skip to main content
added 204 characters in body
Source Link

I've gone ahead and implemented paste functionality, allowing you to simply press paste while having an image copied to your clipboard. Note that it does not open any sort of UI or show any indicator that it is uploading, but when itthe cursor will show a waiting spinner while the image is being uploaded. When the upload finishes, the URL is automatically inserted into the text box.

// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                  responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}body.waiting *{cursor:progress;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        if (!imageType) {
                            return;
                        }
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        document.body.classList.add("waiting");
                        const response = await uploadFile(fkey, blob);
                        document.body.classList.remove("waiting");
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});

I've gone ahead and implemented paste functionality, allowing you to simply press paste while having an image copied to your clipboard. Note that it does not open any sort of UI or show any indicator that it is uploading, but when it finishes, the URL is automatically inserted into the text box.

// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                  responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        if (!imageType) {
                            return;
                        }
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        const response = await uploadFile(fkey, blob);
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});

I've gone ahead and implemented paste functionality, allowing you to simply press paste while having an image copied to your clipboard. Note that it does not open any sort of UI, but the cursor will show a waiting spinner while the image is being uploaded. When the upload finishes, the URL is automatically inserted into the text box.

// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                  responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}body.waiting *{cursor:progress;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        if (!imageType) {
                            return;
                        }
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        document.body.classList.add("waiting");
                        const response = await uploadFile(fkey, blob);
                        document.body.classList.remove("waiting");
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});
Updated the userscript
Source Link
// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                  responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    console.log(clipboardItems);
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        console.logif (!imageType); {
                            return;
                        }
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        const response = await uploadFile(fkey, blob);
                        console.log(response);
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});
// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    console.log(clipboardItems);
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        console.log(imageType);
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        const response = await uploadFile(fkey, blob);
                        console.log(response);
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});
// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                  responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        if (!imageType) {
                            return;
                        }
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        const response = await uploadFile(fkey, blob);
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});
Source Link

I've gone ahead and implemented paste functionality, allowing you to simply press paste while having an image copied to your clipboard. Note that it does not open any sort of UI or show any indicator that it is uploading, but when it finishes, the URL is automatically inserted into the text box.

Here's the new userscript:

// ==UserScript==
// @name Chat Image Upload
// @description Drag and Drop upload images
// @author fredley
// @version 1.0.0
// @match *://chat.meta.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.askubuntu.com/rooms/*
// @match *://chat.serverfault.com/rooms/*
// @run-at document-end
// ==/UserScript==

function inject() {
    for (var i = 0; i < arguments.length; ++i) {
        if (typeof arguments[i] == "function") {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.textContent = "(" + arguments[i].toString() + ")(jQuery)";
            document.body.appendChild(script);
        }
    }
}

inject(function ($) {
    async function uploadFile(fkey, image) {
        const formdata = new FormData();
        formdata.append("filename", image), formdata.append("fkey", fkey);
        try {
            const response = await fetch("https://chat.stackexchange.com/upload/image", { method: "post", body: formdata }),
                responseText = await response.text();

            const responseParsed = responseText.match(/var result = '(.+)'/);
            if (!responseParsed) {
                console.error("Failed to upload image", responseText);
                return "ERROR";
            } else return responseParsed[1];
        } catch (e) {
            console.error(e);
        }
    }

    $(document).ready(function () {
        $("body").append('<div id="dropper"><h1>Upload image!</h1></div>');
        $("body").append(
            "<style>#dropper{display:none;position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.7);z-index:9999;}#dropper h1{text-align:center;padding-top:200px;position:absolute;width:100%;color:#FFF;font-size:450%;font-weight:bold;font-family:Helvetica;}</style>"
        );
        $("body").on({
            dragenter: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragover: function (e) {
                $("#dropper").show();
                e.preventDefault();
                e.stopPropagation();
            },
            dragend: function (e) {
                $("#dropper").hide();
                e.preventDefault();
                e.stopPropagation();
            },
            drop: function (e) {
                $("#dropper").hide();
                if (e.originalEvent.dataTransfer && e.originalEvent.dataTransfer.files.length) {
                    console.log("upload!");
                    e.preventDefault();
                    e.stopPropagation();
                    var files = e.originalEvent.dataTransfer.files;
                    initFileUpload().showDialog(function (a) {
                        $("#input").val($("#input").val() + a);
                        $("#input").focus();
                    });
                    setTimeout(function () {
                        $("#filename-input").prop("files", files);
                        setTimeout(function () {
                            $('input[value="upload"]').click();
                        }, 20);
                    }, 20);
                }
            },
            paste: async function (e) {
                // upload the image from clipboard
                try {
                    const clipboardItems = await navigator.clipboard.read();
                    console.log(clipboardItems);
                    for (const clipboardItem of clipboardItems) {
                        const imageType = clipboardItem.types.find((type) => type.startsWith("image/"));
                        console.log(imageType);
                        const blob = await clipboardItem.getType(imageType);
                        const fkey = $("#fkey").val();
                        const response = await uploadFile(fkey, blob);
                        console.log(response);
                        if (response !== "ERROR") {
                            $("#input").val($("#input").val() + response);
                            $("#input").focus();
                        }
                    }
                } catch (err) {
                    console.error(err.name, err.message);
                }
            },
        });
        $("#dropper").on("click", function (e) {
            $(this).hide();
        });
    });
});

And the download link:

Click to download