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 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Drag-Drop Image Uploader
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.1
  5. // @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.
  6. // @match https://*/*
  7. // @grant none
  8. // @license MIT License
  9. // @author CY Fung
  10. // @run-at document-start
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. if (location.hostname === 'lihkg.com') {
  17.  
  18. if(location.pathname!=='/robots.txt')return;
  19.  
  20. function T(e) {
  21. return new Promise(function (resolve, reject) {
  22. window.history.replaceState(null, '', 'https://lihkg.com');
  23. var xhr = new XMLHttpRequest();
  24. var formData = new FormData();
  25. formData.append('image', e);
  26. xhr.open('POST', 'https://api.na.cx/upload');
  27.  
  28. // Set the Referer header to an empty string
  29. xhr.onreadystatechange = function () {
  30. if (xhr.readyState === 4) {
  31. if (xhr.status === 200) {
  32. var response = JSON.parse(xhr.responseText);
  33. var status = response.status;
  34. var url = response.url;
  35. var error = response.error;
  36.  
  37. if (status === 200) {
  38. resolve(url);
  39. } else {
  40. reject(new Error(error));
  41. }
  42. } else {
  43. reject(new Error('Status is not 200'));
  44. }
  45. }
  46. };
  47.  
  48. xhr.send(formData);
  49. });
  50. }
  51.  
  52.  
  53. let iframe = document;
  54.  
  55. // Function to handle the dragenter event
  56. function handleDragEnter(e) {
  57. top.postMessage('top-dragenter', '*');
  58. // Add a class to visually indicate the drag over the iframe
  59. //iframe.classList.add("drag-over");
  60. }
  61.  
  62. // Function to handle the dragover event
  63. function handleDragOver(e) {
  64. // top.postMessage('top-dragover','*');
  65. e.preventDefault();
  66. e.dataTransfer.dropEffect = 'copy';
  67. }
  68.  
  69. // Function to handle the dragleave event
  70. function handleDragLeave(e) {
  71. top.postMessage('top-dragleave', '*');
  72. // Remove the class when the drag leaves the iframe
  73. //iframe.classList.remove("drag-over");
  74. }
  75.  
  76. async function goUpload(e) {
  77.  
  78. var files = e.dataTransfer.files;
  79. let images = [...files].filter(file => file.type == "image/png" || file.type == "image/jpg" || file.type == "image/jpeg" || file.type == "image/gif")
  80. console.log(images);
  81.  
  82. for (const image of images) {
  83. await T(image)
  84. .then(function (url) {
  85. // focusElement.focus();
  86. // document.execCommand("insertText", false, url)
  87. top.postMessage({ p: 'finish-upload', url: url }, '*')
  88. console.log('Uploaded image URL:', url);
  89. })
  90. .catch(function (error) {
  91. console.error('Upload failed:', error);
  92. });
  93. }
  94.  
  95. }
  96.  
  97. // Function to handle the drop event
  98. function handleDrop(e) {
  99. e.preventDefault();
  100. top.postMessage('top-drop', '*');
  101.  
  102. // Remove the class when the drop occurs
  103. //iframe.classList.remove("drag-over");
  104.  
  105. // Access the dropped files or data
  106.  
  107. goUpload(e);
  108.  
  109. // Process the dropped files or data as needed
  110. // ...
  111. }
  112. // Add event listeners for drag and drop events
  113. iframe.addEventListener("dragenter", handleDragEnter, false);
  114. iframe.addEventListener("dragover", handleDragOver, false);
  115. iframe.addEventListener("dragleave", handleDragLeave, false);
  116. iframe.addEventListener("drop", handleDrop, false);
  117.  
  118.  
  119. top.postMessage('top-uploader-ready', '*');
  120.  
  121.  
  122. } else {
  123.  
  124. function onReady() {
  125.  
  126. // Create the fixed div element
  127. var fixedDiv = document.createElement('div');
  128. fixedDiv.style.position = 'fixed';
  129. fixedDiv.style.zIndex = '8888';
  130. fixedDiv.style.bottom = '10px';
  131. fixedDiv.style.right = '10px';
  132. fixedDiv.style.width = '200px';
  133. fixedDiv.style.height = '200px';
  134. fixedDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
  135. fixedDiv.style.border = '2px solid white';
  136. fixedDiv.style.borderRadius = '5px';
  137. fixedDiv.style.padding = '0px';
  138. fixedDiv.style.color = 'white';
  139. fixedDiv.style.fontSize = '14px';
  140. fixedDiv.style.textAlign = 'center';
  141. // fixedDiv.style.cursor = 'move';
  142. // fixedDiv.draggable = true;
  143. fixedDiv.style.opacity = '0'; // Set initial opacity to 0 (hidden)
  144. fixedDiv.style.display = 'none';
  145. fixedDiv.id = 'maksdmksrnvj';
  146. fixedDiv.style.background = 'url(https://static.thenounproject.com/png/3905046-200.png)';
  147. fixedDiv.style.backgroundPosition = 'center';
  148. fixedDiv.style.backgroundSize = 'cover';
  149. fixedDiv.style.backgroundRepeat = 'no-repeat';
  150.  
  151. fixedDiv.style.pointerEvents = 'none';
  152.  
  153. let focusElement = null;
  154.  
  155. let moused = false;
  156.  
  157. let lastDragIn = 0;
  158. let cid = 0;
  159. function setupIframe(iframe) {
  160.  
  161. iframe.style.position = 'relative';
  162. iframe.style.width = '100%';
  163. iframe.style.height = '100%';
  164. iframe.style.opacity = '0';
  165. iframe.style.pointerEvents = 'all';
  166. iframe.style.transform = 'translateY(-300vh)';
  167. fixedDiv.style.transform = 'translateY(-300vh)';
  168.  
  169. }
  170.  
  171. // Create the Intersection Observer
  172. var observer = new IntersectionObserver(function (entries) {
  173. entries.forEach(function (entry) {
  174. if (entry.isIntersecting) {
  175. // When fixedDiv appears, check if it has an iframe inside
  176. var iframe = fixedDiv.querySelector('iframe');
  177. if (!iframe) {
  178. // If no iframe inside, create and append one
  179. iframe = document.createElement('iframe');
  180. setupIframe(iframe);
  181. iframe.src = 'https://lihkg.com/robots.txt';
  182. fixedDiv.appendChild(iframe);
  183. }
  184. }
  185. });
  186. });
  187.  
  188. // Observe the fixedDiv element
  189. observer.observe(fixedDiv);
  190.  
  191.  
  192.  
  193. document.addEventListener('dragleave', function (event) {
  194. if (moused) return;
  195.  
  196. if (cid > 0) cid = clearTimeout(cid);
  197. if (event.relatedTarget) return;
  198. console.log(221);
  199.  
  200. let endTime = Date.now();
  201. cid = setTimeout(() => {
  202. cid = 0;
  203. requestAnimationFrame(() => {
  204. if (lastDragIn > endTime) return;
  205.  
  206. if (fixedDiv.style.display !== 'none' && !moused) {
  207.  
  208. // focusElement = null;
  209. fixedDiv.style.display = 'none';
  210. fixedDiv.style.opacity = '0';
  211. }
  212. });
  213. }, 80)
  214.  
  215. event.preventDefault();
  216.  
  217. });
  218.  
  219. document.addEventListener('dragenter', function (event) {
  220. if (moused) return;
  221. if (cid > 0) cid = clearTimeout(cid);
  222. if (event.relatedTarget) return;
  223. console.log(222);
  224.  
  225.  
  226. lastDragIn = Date.now();
  227.  
  228. let activeNode = document.activeElement || 0;
  229. let activeNodeName = activeNode.nodeName;
  230. if (activeNodeName === 'TEXTAREA' || (activeNodeName === 'INPUT' && (!activeNode.type || activeNode.type == 'text'))) {
  231. if (fixedDiv.style.display === 'none') {
  232. fixedDiv.style.display = 'block';
  233. fixedDiv.style.opacity = '0.4';
  234. focusElement = activeNode;
  235. console.log(focusElement)
  236. }
  237. }
  238.  
  239. requestAnimationFrame(() => {
  240.  
  241. lastDragIn = Date.now();
  242. });
  243. }, true);
  244.  
  245. document.addEventListener('drop', function (event) {
  246. moused = false;
  247. if (moused) return;
  248. if (cid > 0) cid = clearTimeout(cid);
  249. console.log(223);
  250.  
  251. let endTime = Date.now();
  252. cid = setTimeout(() => {
  253. cid = 0;
  254. if (lastDragIn > endTime) return;
  255. if (fixedDiv.style.display !== 'none' && !moused) {
  256. // focusElement = null;
  257.  
  258. fixedDiv.style.display = 'none';
  259. fixedDiv.style.opacity = '0';
  260. }
  261. }, 80)
  262.  
  263.  
  264. }, true);
  265.  
  266. // Append the div to the document body
  267. document.body.appendChild(fixedDiv);
  268.  
  269.  
  270. window.addEventListener('message', event => {
  271.  
  272. let data = (((event || 0).data || 0));
  273.  
  274.  
  275. if (data === 'top-uploader-ready') {
  276.  
  277. let fixedDiv = document.querySelector('#maksdmksrnvj');
  278. let iframe = fixedDiv.querySelector('iframe');
  279.  
  280. iframe.style.transform = '';
  281. fixedDiv.style.transform = '';
  282.  
  283. }
  284.  
  285. if (data === 'top-dragenter') {
  286. moused = true;
  287. fixedDiv.style.opacity = '1';
  288. }
  289. if (data === 'top-dragleave') {
  290. moused = false;
  291. fixedDiv.style.opacity = '0.4';
  292. }
  293.  
  294. if (data === 'top-dragenter') {
  295.  
  296. if (cid > 0) cid = clearTimeout(cid);
  297. }
  298.  
  299. if (data === 'top-dragleave') {
  300.  
  301. let endTime = Date.now();
  302. if (cid > 0) cid = clearTimeout(cid);
  303. cid = setTimeout(() => {
  304. cid = 0;
  305. requestAnimationFrame(() => {
  306. if (lastDragIn > endTime) return;
  307.  
  308. if (fixedDiv.style.display !== 'none' && !moused) {
  309.  
  310. // focusElement = null;
  311. fixedDiv.style.display = 'none';
  312. fixedDiv.style.opacity = '0';
  313. }
  314. });
  315. }, 80)
  316.  
  317. }
  318.  
  319. if (data.p === 'finish-upload') {
  320. let url = event.data.url;
  321. focusElement.focus();
  322. document.execCommand("insertText", false, url)
  323. }
  324.  
  325. if (data === 'top-drop') {
  326. moused = false;
  327.  
  328. let endTime = Date.now();
  329. cid = setTimeout(() => {
  330. cid = 0;
  331. if (lastDragIn > endTime) return;
  332. if (fixedDiv.style.display !== 'none' && !moused) {
  333. // focusElement = null;
  334.  
  335. fixedDiv.style.display = 'none';
  336. fixedDiv.style.opacity = '0';
  337. }
  338. }, 80)
  339. }
  340.  
  341. })
  342.  
  343. }
  344. if (document.readyState !== 'loading') {
  345. onReady();
  346. } else {
  347. document.addEventListener('DOMContentLoaded', onReady, false);
  348. }
  349.  
  350.  
  351.  
  352. }
  353. })();