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