Greasy Fork is available in English.

GreasyFork: download script button

If you have a script manager and you want to download some script without installing it, this script will help

Verze ze dne 30. 01. 2021. Zobrazit nejnovější verzi.

  1. // ==UserScript==
  2. // @name GreasyFork: download script button
  3. // @description If you have a script manager and you want to download some script without installing it, this script will help
  4. // @namespace https://greatest.deepsurf.us/users/424058
  5. // @version 1.1.0
  6. // @author Konf
  7. // @match https://greatest.deepsurf.us
  8. // @include /^http(s|):\/\/greatest.deepsurf.us\/[a-zA-Z_-]*\/scripts\/\d.*$/
  9. // @run-at document-end
  10. // @resource iconDownload https://img.icons8.com/pastel-glyph/64/ffffff/download.png
  11. // @compatible Chrome
  12. // @compatible Opera
  13. // @compatible Firefox
  14. // @grant GM_getResourceUrl
  15. // @grant GM.getResourceUrl
  16. // @noframes
  17. // ==/UserScript==
  18.  
  19. /* jshint esversion: 6 */
  20. /* eslint-disable no-multi-spaces */
  21.  
  22. (function() {
  23. 'use strict';
  24.  
  25. const userLang = location.pathname.split('/')[1];
  26. const langStringsList = {
  27. 'en': {
  28. Dl: 'Download without installing',
  29. unableDl: 'Unable to download the script'
  30. },
  31. 'zh-CN': {
  32. Dl: '下载此脚本',
  33. unableDl: '无法下载此脚本'
  34. },
  35. 'ru': {
  36. Dl: 'Скачать не устанавливая',
  37. unableDl: 'Не удалось скачать скрипт'
  38. }
  39. };
  40. const langStrings = langStringsList[userLang] || langStringsList.en;
  41.  
  42. (GM.getResourceUrl || GM_getResourceUrl)('iconDownload')
  43. .then(downloadIconUrl => {
  44. addCSS(`
  45. .tm-dsb-downloadBtn {
  46. width: 43px;
  47. height: 38px;
  48. position: relative;
  49. padding: 0;
  50. vertical-align: bottom;
  51. cursor: pointer;
  52. border: none;
  53. outline: none;
  54. background: #0F750F;
  55. transition: box-shadow 0.2s;
  56. }
  57.  
  58. .tm-dsb-downloadBtn:hover,
  59. .tm-dsb-downloadBtn:focus {
  60. box-shadow: 0 8px 16px 0 rgb(0 0 0 / 20%), 0 6px 20px 0 rgb(0 0 0 / 19%);
  61. }
  62.  
  63.  
  64. .tm-dsb-downloadBtn__icon {
  65. position: absolute;
  66. }
  67.  
  68. .tm-dsb-downloadBtn__icon--download {
  69. width: 35px;
  70. height: 35px;
  71. top: 1px;
  72. left: 4px;
  73. background: url(${downloadIconUrl});
  74. background-size: contain;
  75. }
  76.  
  77. .tm-dsb-downloadBtn__icon--loading,
  78. .tm-dsb-downloadBtn__icon--loading:after {
  79. border-radius: 50%;
  80. width: 16px;
  81. height: 16px;
  82. }
  83.  
  84. .tm-dsb-downloadBtn__icon--loading {
  85. top: 6px;
  86. left: 8px;
  87. text-indent: -9999em;
  88. border-top: 5px solid rgba(255, 255, 255, 0.2);
  89. border-right: 5px solid rgba(255, 255, 255, 0.2);
  90. border-bottom: 5px solid rgba(255, 255, 255, 0.2);
  91. border-left: 5px solid #ffffff;
  92. -webkit-transform: translateZ(0);
  93. -ms-transform: translateZ(0);
  94. transform: translateZ(0);
  95. -webkit-animation: loading 1.1s infinite linear;
  96. animation: loading 1.1s infinite linear;
  97. }
  98.  
  99. @-webkit-keyframes loading {
  100. 0% {
  101. -webkit-transform: rotate(0deg);
  102. transform: rotate(0deg);
  103. }
  104. 100% {
  105. -webkit-transform: rotate(360deg);
  106. transform: rotate(360deg);
  107. }
  108. }
  109.  
  110. @keyframes loading {
  111. 0% {
  112. -webkit-transform: rotate(0deg);
  113. transform: rotate(0deg);
  114. }
  115. 100% {
  116. -webkit-transform: rotate(360deg);
  117. transform: rotate(360deg);
  118. }
  119. }
  120. `);
  121. });
  122.  
  123. const b = document.createElement('button'); // downloadBtn
  124. const bIcon = document.createElement('div');
  125. const bParent = document.body.querySelector('div#install-area');
  126. const bNeighbour = document.body.querySelector('a.install-help-link');
  127. const installBtn = document.body.querySelector('a.install-link');
  128.  
  129. b.title = langStrings.Dl;
  130. b.className = 'tm-dsb-downloadBtn';
  131. bIcon.className = 'tm-dsb-downloadBtn__icon tm-dsb-downloadBtn__icon--download';
  132. bNeighbour.style.position = 'relative'; // shadow bugfix
  133. bParent.insertBefore(b, bNeighbour);
  134. b.appendChild(bIcon);
  135.  
  136. let fetchingDelay = false;
  137.  
  138. b.addEventListener('click', () => {
  139. setTimeout(() => {
  140. if (b === document.activeElement) document.activeElement.blur();
  141. }, 750);
  142.  
  143. if (fetchingDelay) return;
  144. fetchingDelay = true;
  145. bIcon.className = 'tm-dsb-downloadBtn__icon tm-dsb-downloadBtn__icon--loading';
  146.  
  147. fetch(installBtn.href)
  148. .then(res => res.blob())
  149. .then(blob => {
  150. const url = window.URL.createObjectURL(blob);
  151. const a = document.createElement('a');
  152.  
  153. a.href = url;
  154. a.download = `${installBtn.dataset.scriptName}.user.js`;
  155. document.body.appendChild(a); // needed due to firefox bug
  156. a.click();
  157. a.remove();
  158.  
  159. setTimeout(closeFetchUX, 300);
  160. window.URL.revokeObjectURL(url);
  161. })
  162. .catch(e => {
  163. setTimeout(closeFetchUX, 300);
  164. alert(`${langStrings.unableDl}: \n${e}`);
  165. });
  166. });
  167.  
  168.  
  169. // utils -------------------------------------------------------------
  170.  
  171. function closeFetchUX() {
  172. fetchingDelay = false;
  173. bIcon.className = 'tm-dsb-downloadBtn__icon tm-dsb-downloadBtn__icon--download';
  174. }
  175.  
  176. function addCSS(cssCode) {
  177. const styleEl = document.createElement("style");
  178. styleEl.type = "text/css";
  179.  
  180. if (styleEl.styleSheet) {
  181. styleEl.styleSheet.cssText = cssCode;
  182. } else {
  183. styleEl.appendChild(document.createTextNode(cssCode));
  184. }
  185.  
  186. document.getElementsByTagName("head")[0].appendChild(styleEl);
  187.  
  188. return styleEl;
  189. }
  190.  
  191. // --------------------------------------------------------------------
  192.  
  193. })();