FA Download Button

Adds a hovering download button in gallery pages on FurAffinity

  1. // ==UserScript==
  2. // @name FA Download Button
  3. // @namespace https://gist.github.com/dragantic
  4. // @version 0.2
  5. // @description Adds a hovering download button in gallery pages on FurAffinity
  6. // @author Dragantic
  7. // @match *://*.furaffinity.net/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=furaffinity.net
  9. // @grant GM_addStyle
  10. // @grant GM_download
  11. // ==/UserScript==
  12.  
  13. (() => {
  14. 'use strict';
  15.  
  16. GM_addStyle(
  17. `@keyframes fadein {
  18. 0% {opacity: 0;}
  19. 100% {opacity: 0.5;}
  20. }
  21.  
  22. #fatabs {
  23. width: 60px !important;
  24. height: 60px !important;
  25. left: calc(50% - 30px);
  26. z-index: 2147483647;
  27. position: absolute;
  28. cursor: pointer;
  29.  
  30. animation: fadein 0.1s;
  31. transition: 0.1s;
  32.  
  33. filter: hue-rotate(240deg);
  34. background-color: black;
  35. opacity: 0.5;
  36. }
  37.  
  38. #fatabs.hide {
  39. opacity: 0;
  40. }
  41.  
  42. #fatabs:hover {
  43. opacity: 1;
  44. }
  45.  
  46. *[data-fav] #fatabs {
  47. filter: hue-rotate(120deg);
  48. }
  49.  
  50. *[data-fav='1'] #fatabs {
  51. filter: hue-rotate(0deg);
  52. }`);
  53.  
  54. let img;
  55. let a;
  56. let fav;
  57. const btn = document.createElement('img');
  58. btn.id = 'fatabs';
  59. btn.src = 'data:image/svg+xml;base64,' + btoa( // From KDE's Breeze Dark theme
  60. `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
  61. <defs id="defs3051">
  62. <style type="text/css" id="current-color-scheme">
  63. .ColorScheme-Text { color:#ffff00; }
  64. </style>
  65. </defs>
  66. <g transform="translate(1,1)">
  67. <path style="fill:currentColor;fill-opacity:1;stroke:none" d="M 8 3 L 8 9 L 9 9 L 9 4 L 13 4 L 13 9 L 14 9 L 14 3 L 13 3 L 9 3 L 8 3 z M 5.7929688 10 L 5 10.816406 L 11 17 L 17 10.816406 L 16.207031 10 L 11 15.367188 L 5.7929688 10 z M 4 17 L 4 19 L 5 19 L 17 19 L 18 19 L 18 17 L 17 17 L 17 18 L 5 18 L 5 17 L 4 17 z " class="ColorScheme-Text"/>
  68. </g>
  69. </svg>`);
  70. btn.addEventListener('click', (e) => {
  71. const prev = fav;
  72. fav = +!fav;
  73. btn.title = (fav ? 'UnFav' : 'Fav') + ' Image';
  74. a.dataset.fav = fav.toString();
  75. fetch(a.href)
  76. .then((response) => response.text())
  77. .then((text) => {
  78. if (prev < 0) { // download
  79. const m = text.match(/(d\.furaffinity\.net\/.*?)"/);
  80. if (m) {
  81. const name = m[1].substring(m[1].lastIndexOf('/') + 1);
  82. GM_download({
  83. url: `https://${m[1]}`,
  84. name: name,
  85. onerror: (result) => { console.log(result); }
  86. });
  87. }
  88. }
  89. else { // (un)fav
  90. const m = text.match(new RegExp(`(/${prev ? 'un' : ''}fav/.*?)"`));
  91. m && fetch(`https://www.furaffinity.net${m[1]}`);
  92. }
  93. });
  94. e.preventDefault();
  95. });
  96. document.addEventListener('mouseover', (e) => {
  97. const t = e.target;
  98. if (t === btn) {
  99. return;
  100. }
  101. if (t instanceof HTMLImageElement
  102. && (t.offsetWidth >= 180 || t.offsetHeight >= 180)) {
  103. btn.className = '';
  104. if (img !== t) {
  105. const anc = t.closest('a');
  106. if (anc) {
  107. (a = anc).prepend(btn);
  108. img = t;
  109. fav = parseInt(a.dataset.fav || '-1');
  110. btn.title = (fav == -1 ? 'Download' :
  111. (fav == 0 ? 'Fav' : 'UnFav')) + ' Image';
  112. }
  113. }
  114. }
  115. else {
  116. btn.className = 'hide';
  117. }
  118. });
  119. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址