Greasy Fork镜像脚本页面适用于网址增强

脚本详情页适用于网址不默认跳转搜索 转为可点击的文本链接并弹出提示

目前为 2024-08-30 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Greasy Fork镜像脚本页面适用于网址增强
  3. // @namespace https://github.com/qinwuyuan-cn/UserScripts
  4. // @version 0.9.3.48
  5. // @description 脚本详情页适用于网址不默认跳转搜索 转为可点击的文本链接并弹出提示
  6. // @author 人民的勤务员 <toniaiwanowskiskr47@gmail.com>
  7. // @match https://*.gf.qytechs.cn/zh-CN/scripts/*
  8. // @match https://*.sleazyfork.org/zh-CN/scripts/*
  9. // @icon https://gf.qytechs.cn/vite/assets/blacklogo96-CxYTSM_T.png
  10. // @license MIT
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @supportURL https://github.com/ChinaGodMan/UserScripts/issues
  14. // @homepageURL https://github.com/ChinaGodMan/UserScripts
  15. // ==/UserScript==
  16.  
  17. (function () {
  18. 'use strict'
  19. let useWindowOpen = GM_getValue('useWindowOpen', false) // 默认在当前页面跳转
  20. let linkBehavior = GM_getValue('linkBehavior', 0)
  21. let shouldMatchLink = false // 添加一个全局变量,默认为假 不显示适用于脚本的数量
  22.  
  23. function Toast(msg, duration) {
  24. duration = isNaN(duration) ? 3000 : duration
  25. var m = document.createElement('div')
  26. m.innerHTML = msg
  27. m.style.cssText = "max-width:60%;min-width: 150px;padding:0 14px;height: 40px;color: black;line-height: 40px;text-align: center;border-radius: 12px;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 2147483647;background: white;font-size: 16px;"
  28. document.body.appendChild(m)
  29. setTimeout(function () {
  30. var d = 0.5
  31. m.style.transition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in'
  32. m.style.opacity = '0'; setTimeout(function () { document.body.removeChild(m) }, d * 1000)
  33. }, duration)
  34. }
  35.  
  36.  
  37. function navigateTo(url, useWindowOpen) {
  38. if (useWindowOpen) {
  39. window.open(url, '_blank')
  40. } else {
  41. window.location.href = url
  42. }
  43. }
  44.  
  45. const ddElements = document.querySelectorAll('dd.script-show-applies-to ul.block-list.expandable > li')
  46.  
  47. ddElements.forEach(dd => {
  48. const link = dd.querySelector('a[title^="查看其他"]')
  49. const text = dd.textContent.trim()
  50. if (shouldMatchLink && link) { // 检查 shouldMatchLink 变量的值
  51. const match = link.title.match(/查看其他 (\d+) 个适用/)
  52. if (match) {
  53. const count = match[1]
  54. const note = document.createElement('sup')
  55. note.textContent = count
  56. link.appendChild(note)
  57. link.title = link.title.replace(/ \d+ /, ' ')
  58. link.addEventListener('click', function (event) {
  59. event.preventDefault()
  60. handleLinkClick(text)
  61. })
  62. }
  63. } else {
  64. const newLink = document.createElement('a')
  65. newLink.textContent = text
  66. newLink.href = '#'
  67. newLink.addEventListener('click', function (event) {
  68. event.preventDefault()
  69. handleLinkClick(text)
  70. })
  71. dd.textContent = ''
  72. dd.appendChild(newLink)
  73. }
  74. })
  75.  
  76. function handleLinkClick(linkText) {
  77. if (linkBehavior === 0) {
  78. const bodyBackgroundColor = window.getComputedStyle(document.body).backgroundColor
  79. const dialogBox = document.createElement('div')
  80. dialogBox.style.position = 'fixed'
  81. dialogBox.style.top = '50%'
  82. dialogBox.style.left = '50%'
  83. dialogBox.style.transform = 'translate(-50%, -50%)'
  84. dialogBox.style.background = bodyBackgroundColor
  85. dialogBox.style.padding = '20px'
  86. dialogBox.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'
  87. dialogBox.style.borderRadius = '8px'
  88. dialogBox.style.zIndex = '9999'
  89. dialogBox.innerHTML = `
  90. <span id="closeBtn" style="position: absolute; top: 10px; right: 10px; color: red; cursor: pointer; font-size: 30px;">&times;</span>
  91. <p style="font-weight: bold; font-size: 20px;"> <span id="linkTextSpan" style="color: red;">${linkText}</span> 操作</p>
  92. <button id="forumSearchBtn">论坛搜索</button>
  93. <button id="openUrlBtn">打开网址</button>
  94. <button id="copyLinkBtn">复制链接</button>
  95. `
  96. document.body.appendChild(dialogBox)
  97.  
  98. let dialogInitialX, dialogInitialY, initialX, initialY
  99. dialogBox.addEventListener('mousedown', onMouseDown)
  100. dialogBox.addEventListener('touchstart', onTouchStart)
  101.  
  102. function onMouseDown(event) {
  103. dialogInitialX = dialogBox.offsetLeft
  104. dialogInitialY = dialogBox.offsetTop
  105. initialX = event.clientX
  106. initialY = event.clientY
  107. document.addEventListener('mousemove', onMouseMove)
  108. document.addEventListener('mouseup', onMouseUp)
  109. }
  110.  
  111. function onTouchStart(event) {
  112. dialogInitialX = dialogBox.offsetLeft
  113. dialogInitialY = dialogBox.offsetTop
  114. initialX = event.touches[0].clientX
  115. initialY = event.touches[0].clientY
  116. document.addEventListener('touchmove', onTouchMove)
  117. document.addEventListener('touchend', onTouchEnd)
  118. }
  119.  
  120. function onMouseMove(event) {
  121. const deltaX = event.clientX - initialX
  122. const deltaY = event.clientY - initialY
  123. dialogBox.style.left = dialogInitialX + deltaX + 'px'
  124. dialogBox.style.top = dialogInitialY + deltaY + 'px'
  125. }
  126.  
  127. function onTouchMove(event) {
  128. const deltaX = event.touches[0].clientX - initialX
  129. const deltaY = event.touches[0].clientY - initialY
  130. dialogBox.style.left = dialogInitialX + deltaX + 'px'
  131. dialogBox.style.top = dialogInitialY + deltaY + 'px'
  132. }
  133.  
  134. function onMouseUp() {
  135. document.removeEventListener('mousemove', onMouseMove)
  136. document.removeEventListener('mouseup', onMouseUp)
  137. }
  138.  
  139. function onTouchEnd() {
  140. document.removeEventListener('touchmove', onTouchMove)
  141. document.removeEventListener('touchend', onTouchEnd)
  142. }
  143.  
  144. document.getElementById('linkTextSpan').style.pointerEvents = 'none'
  145. document.getElementById('closeBtn').addEventListener('click', function () {
  146. document.body.removeChild(dialogBox)
  147. })
  148.  
  149. document.getElementById('copyLinkBtn').addEventListener('click', function () {
  150. const linkText = document.getElementById('linkTextSpan').innerText
  151. const tempTextarea = document.createElement('textarea')
  152. tempTextarea.value = linkText
  153. document.body.appendChild(tempTextarea)
  154. tempTextarea.select()
  155. document.execCommand('copy')
  156. document.body.removeChild(tempTextarea)
  157. document.body.removeChild(dialogBox)
  158. Toast('文本已复制到剪贴板!', 1000)
  159. })
  160.  
  161. document.getElementById('forumSearchBtn').addEventListener('click', function () {
  162. const newUrl = `https://${location.host}/zh-CN/scripts/by-site/${linkText}`
  163. navigateTo(newUrl, useWindowOpen)
  164. document.body.removeChild(dialogBox)
  165. })
  166.  
  167. document.getElementById('openUrlBtn').addEventListener('click', function () {
  168. const originalUrl = `https://${linkText.replace(/\d+/g, '')}`
  169. navigateTo(originalUrl, useWindowOpen)
  170. document.body.removeChild(dialogBox)
  171. })
  172. } else if (linkBehavior === 1) {
  173. const originalUrl = `https://${linkText.replace(/\d+/g, '')}`
  174. navigateTo(originalUrl, useWindowOpen)
  175. } else if (linkBehavior === 2) {
  176. const newUrl = `https://${location.host}/zh-CN/scripts/by-site/${linkText}`
  177. navigateTo(newUrl, useWindowOpen)
  178. }
  179. }
  180.  
  181. const appliesToSection = document.querySelector('dt.script-show-applies-to')
  182. if (appliesToSection) {
  183. const changeConfigText = document.createElement('span')
  184. changeConfigText.textContent = '[适用于] '
  185. changeConfigText.style.fontWeight = 'bold'
  186.  
  187. const checkboxLabel = document.createElement('label')
  188. checkboxLabel.textContent = '新窗口打开'
  189. checkboxLabel.style.marginLeft = '10px'
  190.  
  191. const checkboxInput = document.createElement('input')
  192. checkboxInput.type = 'checkbox'
  193. checkboxInput.checked = useWindowOpen
  194. checkboxInput.style.marginRight = '5px'
  195.  
  196. checkboxInput.addEventListener('change', function () {
  197. useWindowOpen = checkboxInput.checked
  198. GM_setValue('useWindowOpen', useWindowOpen)
  199. })
  200.  
  201. checkboxLabel.appendChild(checkboxInput)
  202.  
  203. const selectList = document.createElement('select')
  204. selectList.style.width = '7em'
  205. const options = [
  206. { value: 0, text: '弹出提示' },
  207. { value: 1, text: '打开网址' },
  208. { value: 2, text: '论坛搜索' }
  209. ]
  210. options.forEach(option => {
  211. const optionElement = document.createElement('option')
  212. optionElement.textContent = option.text
  213. optionElement.value = option.value
  214. if (linkBehavior === option.value) {
  215. optionElement.selected = true
  216. }
  217. selectList.appendChild(optionElement)
  218. })
  219. selectList.addEventListener('change', function () {
  220. linkBehavior = parseInt(selectList.value)
  221. GM_setValue('linkBehavior', linkBehavior)
  222. Toast(`点击"适用于"网址已设置为: ${options.find(option => option.value === linkBehavior).text}`, 1000)
  223. })
  224.  
  225. appliesToSection.parentElement.appendChild(changeConfigText)
  226. appliesToSection.parentElement.appendChild(selectList)
  227. appliesToSection.parentElement.appendChild(checkboxLabel)
  228. }
  229. })();
  230.  

QingJ © 2025

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