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.

目前為 2023-05-21 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Drag-Drop Image Uploader
// @namespace           http://tampermonkey.net/
// @version      0.1.0
// @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') {

        window.addEventListener('message', (e) => {

            if ((((e || 0).data || 0).p || 0) === 'semmr') {
                // console.log(e)

                // uploadImage(e.data.detail);
            }


        });




        function uploadImage(file) {
            // Upload the file using the provided function
            T(file)
                .then(function (url) {
                    // focusElement.focus();
                    // document.execCommand("insertText", false, url)
                    console.log('Uploaded image URL:', url);
                })
                .catch(function (error) {
                    console.error('Upload failed:', error);
                });
        }

        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);

        /*
        // Prevent the default behavior for dragover and drop events
        iframe.addEventListener("dragover", function (e) {
          e.preventDefault();
        });
        iframe.addEventListener("drop", function (e) {
          e.preventDefault();
        });*/


        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)';

                window.addEventListener('message',e=>{
                if(e.data==='top-uploader-ready'){

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

                }
                })


                // iframe.id='maksdmksrnvj';

                /*
                // Function to handle the dragenter event
                function handleDragEnter(e) {
                  // 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) {
                  e.preventDefault();
                }

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

                // Function to handle the drop event
                function handleDrop(e) {
                  e.preventDefault();

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

                  // Access the dropped files or data
                  var files = e.dataTransfer.files;
                  var data = e.dataTransfer.getData("text/plain");

                  // 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);

                // Prevent the default behavior for dragover and drop events
                iframe.addEventListener("dragover", function (e) {
                  e.preventDefault();
                });
                iframe.addEventListener("drop", function (e) {
                  e.preventDefault();
                });
                */


            }

            // 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.style.position = 'fixed';

                            iframe.style.zIndex = '8888';
                            iframe.style.left = '-1000px';
                            iframe.style.top = '-1000px';
                            iframe.style.width = '200px';
                            iframe.style.height = '200px';
        */
                            iframe.src = 'https://lihkg.com/robots.txt';
                            fixedDiv.appendChild(iframe);
                        }
                    }
                });
            });

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

            /*




            fixedDiv.addEventListener('dragenter', function () {
                if (event.relatedTarget && event.relatedTarget.closest('#maksdmksrnvj')) return;
                if (event.target && event.target.closest('iframe')) return;
                moused = true;
            })*/

            window.addEventListener('message', e => {
                if (e.data === 'top-dragenter') {
                    moused = true;
                    fixedDiv.style.opacity = '1';
                }
                if (e.data === 'top-dragleave') {
                    moused = false;
                    fixedDiv.style.opacity = '0.4';
                }

            })
            /*

            fixedDiv.addEventListener('dragleave', function () {
                if (event.relatedTarget && event.relatedTarget.closest('#maksdmksrnvj')) return;
                if (event.target && event.target.closest('iframe')) return;
                moused = false;
            })

            fixedDiv.addEventListener('dragenter', function (event) {
                if (event.target && event.target.closest('iframe')) return;
                if (cid > 0) cid = clearTimeout(cid);
                if (+fixedDiv.style.opacity > 0.9) return;
                event.preventDefault();
                fixedDiv.style.opacity = '1'; // Show the div when cursor enters by setting opacity to 1
            });

            */

            window.addEventListener('message', event => {
                if (event.data === 'top-dragenter') {

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

            })
            /*

            fixedDiv.addEventListener('dragleave', function (event) {
                if (event.target && event.target.closest('iframe')) return;
                if (+fixedDiv.style.opacity < 0.9) return;
                if (event.target.closest('#maksdmksrnvj')) return;
                console.log(124);
                event.preventDefault();
                fixedDiv.style.opacity = '0.4'; // Hide the div when cursor leaves by setting opacity to 0
            });

            fixedDiv.addEventListener('drop', function (event) {
                moused = false;
                if (event.target && event.target.closest('iframe')) return;
                console.log(126);
                event.preventDefault();
                fixedDiv.style.opacity = '0.4'; // Hide the div after the drop by setting opacity to 0

                var files = event.dataTransfer.files;
                if (files.length > 0) {
                    var file = files[0];
                    uploadImage(file);
                }
            });

            fixedDiv.addEventListener('dragover', function (event) {
                if (event.target && event.target.closest('iframe')) return;
                if (cid > 0) cid = clearTimeout(cid);
                event.preventDefault();
                event.dataTransfer.dropEffect = 'copy';
            });
            */



            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();

            });

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

                if (e.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)

                }
            })

            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);

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

                if (event.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)
                }

            })


            // fixedDiv.innerText = 'Drag and drop images here';

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


            /*

            // Create the fixed div element
            var fixedDiv = document.createElement('div');
            fixedDiv.style.position = 'fixed';
            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 = '10px';
            fixedDiv.style.color = 'white';
            fixedDiv.style.fontSize = '14px';
            fixedDiv.style.textAlign = 'center';
            fixedDiv.style.cursor = 'move';
            fixedDiv.draggable = true;
            fixedDiv.setAttribute('ondragstart', 'event.dataTransfer.setData("text/plain",null)');

            fixedDiv.innerText = 'Drag and drop images here';

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

            // Implement drag and drop event handlers
            fixedDiv.addEventListener('dragover', function(e) {
                e.preventDefault();
                e.dataTransfer.dropEffect = 'copy';
                fixedDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
            });

            fixedDiv.addEventListener('dragleave', function(e) {
                e.preventDefault();
                fixedDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
            });

            fixedDiv.addEventListener('drop', function(e) {
                e.preventDefault();
                fixedDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';

                var files = e.dataTransfer.files;
                if (files.length > 0) {
                    var file = files[0];
                    uploadImage(file);
                }
            });
            */

            window.addEventListener('message', (event) => {
                if ((((event || 0).data || 0).p) === 'finish-upload') {
                    let url = event.data.url;
                    focusElement.focus();
                    document.execCommand("insertText", false, url)

                }
            })

            function uploadImage(file) {
                // Upload the file using the provided function
                T(file)
                    .then(function (url) {
                        focusElement.focus();
                        document.execCommand("insertText", false, url)
                        console.log('Uploaded image URL:', url);
                    })
                    .catch(function (error) {
                        console.error('Upload failed:', error);
                    });
            }

            function T(e) {
                return new Promise(function (resolve, reject) {
                    var xhr = new XMLHttpRequest();
                    var formData = new FormData();
                    formData.append('image', e);

                    /*
                    xhr.open('POST', 'https://api.na.cx/upload');
                    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);
                    */

                    fixedDiv.querySelector('iframe').contentWindow.postMessage({ p: 'semmr', detail: e }, '*')
                });
            }
        }
        if (document.readyState !== 'loading') {
            onReady();
        } else {
            document.addEventListener('DOMContentLoaded', onReady, false);
        }



    }
})();