Drag-Drop Image Uploader

Enables image uploading by simply dragging and dropping images onto a fixed div in the bottom right corner of the page. Easily upload and use images on any website with this convenient script.

Pada tanggal 21 Mei 2023. Lihat %(latest_version_link).

// ==UserScript==
// @name         Drag-Drop Image Uploader
// @namespace           http://tampermonkey.net/
// @version      0.1.1
// @description  Enables image uploading by simply dragging and dropping images onto a fixed div in the bottom right corner of the page. Easily upload and use images on any website with this convenient script.
// @match        https://*/*
// @grant        none
// @license             MIT License
// @author              CY Fung
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    if (location.hostname === 'lihkg.com') {

        if(location.pathname!=='/robots.txt')return;

        function T(e) {
            return new Promise(function (resolve, reject) {
                window.history.replaceState(null, '', 'https://lihkg.com');
                var xhr = new XMLHttpRequest();
                var formData = new FormData();
                formData.append('image', e);
                xhr.open('POST', 'https://api.na.cx/upload');

                // Set the Referer header to an empty string
                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4) {
                        if (xhr.status === 200) {
                            var response = JSON.parse(xhr.responseText);
                            var status = response.status;
                            var url = response.url;
                            var error = response.error;

                            if (status === 200) {
                                resolve(url);
                            } else {
                                reject(new Error(error));
                            }
                        } else {
                            reject(new Error('Status is not 200'));
                        }
                    }
                };

                xhr.send(formData);
            });
        }


        let iframe = document;

        // Function to handle the dragenter event
        function handleDragEnter(e) {
            top.postMessage('top-dragenter', '*');
            // Add a class to visually indicate the drag over the iframe
            //iframe.classList.add("drag-over");
        }

        // Function to handle the dragover event
        function handleDragOver(e) {
            // top.postMessage('top-dragover','*');
            e.preventDefault();
            e.dataTransfer.dropEffect = 'copy';
        }

        // Function to handle the dragleave event
        function handleDragLeave(e) {
            top.postMessage('top-dragleave', '*');
            // Remove the class when the drag leaves the iframe
            //iframe.classList.remove("drag-over");
        }

        async function goUpload(e) {

            var files = e.dataTransfer.files;
            let images = [...files].filter(file => file.type == "image/png" || file.type == "image/jpg" || file.type == "image/jpeg" || file.type == "image/gif")
            console.log(images);

            for (const image of images) {
                await T(image)
                    .then(function (url) {
                        // focusElement.focus();
                        // document.execCommand("insertText", false, url)
                        top.postMessage({ p: 'finish-upload', url: url }, '*')
                        console.log('Uploaded image URL:', url);
                    })
                    .catch(function (error) {
                        console.error('Upload failed:', error);
                    });
            }

        }

        // Function to handle the drop event
        function handleDrop(e) {
            e.preventDefault();
            top.postMessage('top-drop', '*');

            // Remove the class when the drop occurs
            //iframe.classList.remove("drag-over");

            // Access the dropped files or data

            goUpload(e);

            // Process the dropped files or data as needed
            // ...
        }
        // Add event listeners for drag and drop events
        iframe.addEventListener("dragenter", handleDragEnter, false);
        iframe.addEventListener("dragover", handleDragOver, false);
        iframe.addEventListener("dragleave", handleDragLeave, false);
        iframe.addEventListener("drop", handleDrop, false);


        top.postMessage('top-uploader-ready', '*');


    } else {

        function onReady() {

            // Create the fixed div element
            var fixedDiv = document.createElement('div');
            fixedDiv.style.position = 'fixed';
            fixedDiv.style.zIndex = '8888';
            fixedDiv.style.bottom = '10px';
            fixedDiv.style.right = '10px';
            fixedDiv.style.width = '200px';
            fixedDiv.style.height = '200px';
            fixedDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
            fixedDiv.style.border = '2px solid white';
            fixedDiv.style.borderRadius = '5px';
            fixedDiv.style.padding = '0px';
            fixedDiv.style.color = 'white';
            fixedDiv.style.fontSize = '14px';
            fixedDiv.style.textAlign = 'center';
            //    fixedDiv.style.cursor = 'move';
            // fixedDiv.draggable = true;
            fixedDiv.style.opacity = '0'; // Set initial opacity to 0 (hidden)
            fixedDiv.style.display = 'none';
            fixedDiv.id = 'maksdmksrnvj';
            fixedDiv.style.background = 'url(https://static.thenounproject.com/png/3905046-200.png)';
            fixedDiv.style.backgroundPosition = 'center';
            fixedDiv.style.backgroundSize = 'cover';
            fixedDiv.style.backgroundRepeat = 'no-repeat';

            fixedDiv.style.pointerEvents = 'none';

            let focusElement = null;

            let moused = false;

            let lastDragIn = 0;
            let cid = 0;
            function setupIframe(iframe) {

                iframe.style.position = 'relative';
                iframe.style.width = '100%';
                iframe.style.height = '100%';
                iframe.style.opacity = '0';
                iframe.style.pointerEvents = 'all';
                iframe.style.transform = 'translateY(-300vh)';
                fixedDiv.style.transform = 'translateY(-300vh)';

            }

            // Create the Intersection Observer
            var observer = new IntersectionObserver(function (entries) {
                entries.forEach(function (entry) {
                    if (entry.isIntersecting) {
                        // When fixedDiv appears, check if it has an iframe inside
                        var iframe = fixedDiv.querySelector('iframe');
                        if (!iframe) {
                            // If no iframe inside, create and append one
                            iframe = document.createElement('iframe');
                            setupIframe(iframe);
                            iframe.src = 'https://lihkg.com/robots.txt';
                            fixedDiv.appendChild(iframe);
                        }
                    }
                });
            });

            // Observe the fixedDiv element
            observer.observe(fixedDiv);



            document.addEventListener('dragleave', function (event) {
                if (moused) return;

                if (cid > 0) cid = clearTimeout(cid);
                if (event.relatedTarget) return;
                console.log(221);

                let endTime = Date.now();
                cid = setTimeout(() => {
                    cid = 0;
                    requestAnimationFrame(() => {
                        if (lastDragIn > endTime) return;

                        if (fixedDiv.style.display !== 'none' && !moused) {

                            // focusElement = null;
                            fixedDiv.style.display = 'none';
                            fixedDiv.style.opacity = '0';
                        }
                    });
                }, 80)

                event.preventDefault();

            });

            document.addEventListener('dragenter', function (event) {
                if (moused) return;
                if (cid > 0) cid = clearTimeout(cid);
                if (event.relatedTarget) return;
                console.log(222);


                lastDragIn = Date.now();

                let activeNode = document.activeElement || 0;
                let activeNodeName = activeNode.nodeName;
                if (activeNodeName === 'TEXTAREA' || (activeNodeName === 'INPUT' && (!activeNode.type || activeNode.type == 'text'))) {
                    if (fixedDiv.style.display === 'none') {
                        fixedDiv.style.display = 'block';
                        fixedDiv.style.opacity = '0.4';
                        focusElement = activeNode;
                        console.log(focusElement)
                    }
                }

                requestAnimationFrame(() => {

                    lastDragIn = Date.now();
                });
            }, true);

            document.addEventListener('drop', function (event) {
                moused = false;
                if (moused) return;
                if (cid > 0) cid = clearTimeout(cid);
                console.log(223);

                let endTime = Date.now();
                cid = setTimeout(() => {
                    cid = 0;
                    if (lastDragIn > endTime) return;
                    if (fixedDiv.style.display !== 'none' && !moused) {
                        // focusElement = null;

                        fixedDiv.style.display = 'none';
                        fixedDiv.style.opacity = '0';
                    }
                }, 80)


            }, true);

            // Append the div to the document body
            document.body.appendChild(fixedDiv);


            window.addEventListener('message', event => {

                let data = (((event || 0).data || 0));


                if (data === 'top-uploader-ready') {

                    let fixedDiv = document.querySelector('#maksdmksrnvj');
                    let iframe = fixedDiv.querySelector('iframe');

                    iframe.style.transform = '';
                    fixedDiv.style.transform = '';

                }

                if (data === 'top-dragenter') {
                    moused = true;
                    fixedDiv.style.opacity = '1';
                }
                if (data === 'top-dragleave') {
                    moused = false;
                    fixedDiv.style.opacity = '0.4';
                }

                if (data === 'top-dragenter') {

                    if (cid > 0) cid = clearTimeout(cid);
                }

                if (data === 'top-dragleave') {

                    let endTime = Date.now();
                    if (cid > 0) cid = clearTimeout(cid);
                    cid = setTimeout(() => {
                        cid = 0;
                        requestAnimationFrame(() => {
                            if (lastDragIn > endTime) return;

                            if (fixedDiv.style.display !== 'none' && !moused) {

                                // focusElement = null;
                                fixedDiv.style.display = 'none';
                                fixedDiv.style.opacity = '0';
                            }
                        });
                    }, 80)

                }

                if (data.p === 'finish-upload') {
                    let url = event.data.url;
                    focusElement.focus();
                    document.execCommand("insertText", false, url)
                }

                if (data === 'top-drop') {
                    moused = false;

                    let endTime = Date.now();
                    cid = setTimeout(() => {
                        cid = 0;
                        if (lastDragIn > endTime) return;
                        if (fixedDiv.style.display !== 'none' && !moused) {
                            // focusElement = null;

                            fixedDiv.style.display = 'none';
                            fixedDiv.style.opacity = '0';
                        }
                    }, 80)
                }

            })

        }
        if (document.readyState !== 'loading') {
            onReady();
        } else {
            document.addEventListener('DOMContentLoaded', onReady, false);
        }



    }
})();