GreaysFork 增强WebHook同步设置

GreaysFork 快速输入脚本同步信息,并批量增加多个国家的语言代码,而不用一个个地点击选择框再去对应的网址。

当前为 2024-09-04 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name GreaysFork Enhanced WebHook Sync Settings
  3. // @description Quickly input script sync information and batch add language codes for multiple countries without the need to click
  4. // @name:zh-CN GreaysFork 增强WebHook同步设置
  5. // @description:zh-CN GreaysFork 快速输入脚本同步信息,并批量增加多个国家的语言代码,而不用一个个地点击选择框再去对应的网址。
  6. // @name:zh-TW GreaysFork 增強WebHook同步設定
  7. // @description:zh-TW GreaysFork 快速輸入腳本同步資訊,並批量增加多個國家的語言代碼,而不用逐個點擊選擇框再去對應的網址。
  8. // @name:zh-HK GreaysFork 增強WebHook同步設置
  9. // @description:zh-HK GreaysFork 快速輸入腳本同步信息,並批量增加多個國家語言代碼,而不用逐個點擊選擇框再去對應的網址。
  10. // @name:ja GreaysFork WebHook同期設定の強化
  11. // @description:ja GreaysFork スクリプト同期情報を素早く入力し、複数の国の言語コードを一括で追加します。選択ボックスを一つ一つクリックする必要はありません。
  12. // @name:ko GreaysFork WebHook 동기화 설정 강화
  13. // @description:ko GreaysFork 스크립트 동기화 정보를 빠르게 입력하고, 여러 국가의 언어 코드를 한 번에 추가합니다. 선택 상자를 하나하나 클릭할 필요가 없습니다.
  14. // @name:ru Улучшенные настройки синхронизации WebHook для GreaysFork
  15. // @description:ru Быстрое ввод данных синхронизации скриптов GreaysFork и массовое добавление языковых кодов нескольких стран без необходимости поочередного выбора из выпадающего списка и перехода по соответствующим ссылкам.
  16. // @name:en GreaysFork Enhanced WebHook Sync Settings
  17. // @description:en Quickly input script sync information and batch add language codes for multiple countries without the need to click through each selection box and visit corresponding URLs.
  18. // @name:fr GreaysFork Amélioration des paramètres de synchronisation WebHook
  19. // @description:fr Saisie rapide des informations de synchronisation des scripts GreaysFork et ajout en masse des codes de langue pour plusieurs pays sans avoir à sélectionner chaque option individuellement et visiter les URL correspondantes.
  20. // @name:de GreaysFork Verbesserte WebHook-Synchronisierungseinstellungen
  21. // @description:de Schnelles Eingeben von Skriptsynchronisierungsinformationen und gleichzeitiges Hinzufügen von Sprachcodes für mehrere Länder, ohne jedes Auswahlfeld einzeln anzuklicken und die entsprechenden URLs zu besuchen.
  22. // @name:vi Cài đặt đồng bộ WebHook GreaysFork được nâng cao
  23. // @description:vi Nhập nhanh thông tin đồng bộ hóa kịch bản GreaysFork và thêm hàng loạt mã ngôn ngữ cho nhiều quốc gia mà không cần phải nhấp từng ô chọn và truy cập các URL tương ứng.
  24. // @version 1.1
  25. // @compatible chrome
  26. // @compatible firefox
  27. // @compatible edge
  28. // @compatible opera
  29. // @compatible safari
  30. // @icon https://github.com/ChinaGodMan/UserScripts/raw/main/docs/icon/Scripts%20Icons/RedFork.svg
  31. // @author 人民的勤务员 <toniaiwanowskiskr47@gmail.com>
  32. // @match *://gf.qytechs.cn/*
  33. // @license MIT
  34. // @supportURL https://github.com/ChinaGodMan/UserScripts/issues
  35. // @homepageURL https://github.com/ChinaGodMan/UserScripts
  36. // @namespace https://github.com/ChinaGodMan/UserScripts
  37. // @modified 2024-9-05 04:29
  38. // ==/UserScript==
  39. (function () {
  40. 'use strict'
  41. let isCreated1 = null
  42. let isCreated = null
  43. const global = {
  44. syncingfrom: null,//脚本同步地址
  45. adminUrl: null,//同步地址
  46. defaultAttribute: null,//默认匹配@name //用于设置时显示用
  47. inputModal: null,//设置床窗口
  48. inputModalTextArea: null,//链接
  49. inputModalScript: null,//输入同步脚本地址框
  50. inputModalDefault: null, //默认匹配@name的输入框
  51. attribute_other: null,///本地化附加信息,用于设置时显示.
  52. scriptname: null
  53. }
  54. document.head.appendChild(document.createElement('style')).textContent = `
  55. #main-header ~ .width-constraint > .text-content:only-child > ul li {
  56. font-size: 0.88rem;
  57. }
  58. /* Basic Styling for Submit Inputs and Buttons */
  59. .Sync-Modal button {
  60. font-family: 'Arial', sans-serif;
  61. font-size: 10pt;
  62. color: #FFFFFF;
  63. background-color: #007BFF;
  64. border: none;
  65. border-radius: 5px;
  66. padding: 8px 16px;
  67. cursor: pointer;
  68. transition: background-color 0.3s ease;
  69. text-align: center;
  70. outline: none;
  71. box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  72. }
  73. /* Hover effect */
  74. input[type="submit"]:hover, button:hover {
  75. background-color: #0056b3;
  76. }
  77. /* Active (pressed) effect */
  78. input[type="submit"]:active, button:active {
  79. background-color: #004494;
  80. }
  81. /* Focus effect for accessibility */
  82. input[type="submit"]:focus, button:focus {
  83. box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.5);
  84. }
  85. .Sync-Modal textarea {
  86. border: 0;
  87. padding: 0;
  88. font-family: inherit;
  89. font-weight: 900;
  90. color: #a83710;
  91. font-size: inherit;
  92. appearance: none;
  93. border: none;
  94. outline: none;
  95. resize: none;
  96. }
  97. .Sync-Modal input {
  98. border: 0;
  99. padding: 0;
  100. font-family: inherit;
  101. font-weight: 900;
  102. color: #80ecd3;
  103. font-size: inherit;
  104. appearance: none;
  105. border: none;
  106. outline: none;
  107. resize: none;
  108. }
  109. .custom-label {
  110. font-weight: bold;
  111. color: #bfe6a0;
  112. }
  113. `
  114. function creatSetModal() {
  115. if (isCreated) return
  116. }
  117. document.body.insertAdjacentHTML('beforeend', `
  118. <div class="Sync-Modal">
  119. <button id="openSyncButton" style="position:fixed;top:10px;right:10px;z-index:1000;display:none;">Open Modal</button>
  120. <button id="openSyncOnadminPage" style="position:fixed;top:300px;right:200px;z-index:1000;display:none;">Set sync</button>
  121. <div id="inputWindow" style="display:none;position:fixed;left:0;top:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5);justify-content:center;align-items:center;z-index:1001;">
  122. <div style="background-color:white;padding:20px;border-radius:5px;width:90%;max-width:1000px;height:90%;max-height:95%;display:flex;flex-direction:column;">
  123. <center><label id="ScriptName">Source Syncing</label></center>
  124. <h2 style="color: blue;flex-shrink:0;"><label id="SyncLabel" label for="SyncScript">Source Syncing</label></h2>
  125. <input type="text" id="SyncScriptForm" style="width:100%;margin-bottom:10px;flex-shrink:0;">
  126. <h3 style="flex-shrink:0;">
  127. <label for="default" class="custom-label">Default additional info (language matches @name)</label>
  128. </h3>
  129. <input type="text" id="inputdefaultAttribute" style="width:100%;margin-bottom:10px;flex-shrink:0;">
  130. <h3 style="flex-shrink:0;">For locale (matches @name:XX):</h3>
  131. <textarea id="urlTextArea" rows="6" style="flex-grow:1;width:100%;resize:none;"></textarea>
  132. <div style="display:flex;justify-content:flex-end;margin-top:10px;flex-shrink:0;">
  133. <button id="submitModalButton" style="margin-left:10px;">Update and sync now</button>
  134. <button id="closeSyncButton" style="margin-left:10px;background-color:red;">Close</button>
  135. </div>
  136. </div>
  137. </div>
  138. </div>
  139. `)
  140. global.inputModal = document.getElementById('inputWindow')
  141. global.inputModalScript = document.getElementById('SyncScriptForm')
  142. global.inputModalDefault = document.getElementById('inputdefaultAttribute')
  143. global.inputModalTextArea = document.getElementById('urlTextArea')
  144. const openModalButton = document.getElementById('openSyncButton')
  145. const closeModalButton = document.getElementById('closeSyncButton')
  146. const submitModalButton = document.getElementById('submitModalButton')
  147. const openSyncOnadminPage = document.getElementById('openSyncOnadminPage')
  148. openModalButton.addEventListener('click', addAdminButtons)
  149. closeModalButton.addEventListener('click', () => global.inputModal.style.display = 'none')
  150. submitModalButton.addEventListener('click', handleSubmit)
  151. function handleSubmit() {
  152. syncUpdate(SyncScriptForm.value, global.inputModalDefault.value, global.adminUrl)
  153. }
  154. openSyncOnadminPage.addEventListener('click', () => {
  155. openSuperAdmin(window.location.href.replace(/\/[^\/]*$/, ''), "", false)
  156. })
  157. //取消鲨臂按钮
  158. addNavLink("Set sync", '#', false, false, "ScriptSyncLink")
  159. var customClassName = 'ScriptSyncLink'
  160. var link = document.querySelector(`.${customClassName} > a`)
  161. if (link) {
  162. link.addEventListener('click', function (event) {
  163. event.preventDefault()
  164. addAdminButtons()
  165. })
  166. }
  167. if (window.location.pathname.includes("/admin")) {
  168. // openSyncOnadminPage.style.display = "block"
  169. const targetElement = document.querySelector("#script-content > section:nth-child(2) > h3")
  170. const newLink = document.createElement('a')
  171. newLink.href = '#'
  172. newLink.textContent = 'Set sync'
  173. newLink.addEventListener('click', function (event) {
  174. event.preventDefault()
  175. openSuperAdmin(window.location.href.replace(/\/[^\/]*$/, ''), "", false)
  176. })
  177. targetElement.insertAdjacentElement('afterend', newLink)
  178. }
  179. async function syncUpdate(scriptSyncIdentifier, additionalInfoSyncIdentifier, postUrl) {
  180. const urls = global.inputModalTextArea.value.trim().split('\n')
  181. const translateTable = [
  182. { "code": "aa", "value": "1" },
  183. { "code": "ab", "value": "2" },
  184. { "code": "ae", "value": "3" },
  185. { "code": "af", "value": "4" },
  186. { "code": "ak", "value": "5" },
  187. { "code": "am", "value": "6" },
  188. { "code": "as", "value": "8" },
  189. { "code": "ast", "value": "9" },
  190. { "code": "av", "value": "10" },
  191. { "code": "ay", "value": "11" },
  192. { "code": "az", "value": "12" },
  193. { "code": "ba", "value": "13" },
  194. { "code": "be", "value": "14" },
  195. { "code": "bh", "value": "16" },
  196. { "code": "bi", "value": "17" },
  197. { "code": "bm", "value": "18" },
  198. { "code": "bn", "value": "19" },
  199. { "code": "bo", "value": "20" },
  200. { "code": "br", "value": "21" },
  201. { "code": "bs", "value": "22" },
  202. { "code": "ca", "value": "23" },
  203. { "code": "ce", "value": "24" },
  204. { "code": "ceb", "value": "25" },
  205. { "code": "ch", "value": "26" },
  206. { "code": "chr", "value": "27" },
  207. { "code": "co", "value": "28" },
  208. { "code": "cr", "value": "29" },
  209. { "code": "cs", "value": "30" },
  210. { "code": "cu", "value": "31" },
  211. { "code": "cv", "value": "32" },
  212. { "code": "cy", "value": "33" },
  213. { "code": "da", "value": "34" },
  214. { "code": "de", "value": "35" },
  215. { "code": "dv", "value": "36" },
  216. { "code": "dz", "value": "37" },
  217. { "code": "ee", "value": "38" },
  218. { "code": "el", "value": "39" },
  219. { "code": "en", "value": "40" },
  220. { "code": "eo", "value": "41" },
  221. { "code": "es", "value": "42" },
  222. { "code": "et", "value": "43" },
  223. { "code": "eu", "value": "44" },
  224. { "code": "fa", "value": "45" },
  225. { "code": "ff", "value": "46" },
  226. { "code": "fi", "value": "47" },
  227. { "code": "fil", "value": "48" },
  228. { "code": "fj", "value": "49" },
  229. { "code": "fo", "value": "50" },
  230. { "code": "fr", "value": "51" },
  231. { "code": "fy", "value": "52" },
  232. { "code": "ga", "value": "53" },
  233. { "code": "gd", "value": "54" },
  234. { "code": "gl", "value": "55" },
  235. { "code": "gn", "value": "56" },
  236. { "code": "gsw-berne", "value": "57" },
  237. { "code": "gu", "value": "58" },
  238. { "code": "gv", "value": "59" },
  239. { "code": "ha", "value": "60" },
  240. { "code": "he", "value": "61" },
  241. { "code": "hi", "value": "62" },
  242. { "code": "hmn", "value": "63" },
  243. { "code": "ho", "value": "64" },
  244. { "code": "hr", "value": "65" },
  245. { "code": "ht", "value": "66" },
  246. { "code": "hu", "value": "67" },
  247. { "code": "hy", "value": "68" },
  248. { "code": "hz", "value": "69" },
  249. { "code": "ia", "value": "70" },
  250. { "code": "id", "value": "71" },
  251. { "code": "ie", "value": "72" },
  252. { "code": "ig", "value": "73" },
  253. { "code": "ik", "value": "74" },
  254. { "code": "is", "value": "75" },
  255. { "code": "it", "value": "76" },
  256. { "code": "iu", "value": "77" },
  257. { "code": "ja", "value": "78" },
  258. { "code": "jv", "value": "79" },
  259. { "code": "ka", "value": "80" },
  260. { "code": "kg", "value": "81" },
  261. { "code": "ki", "value": "82" },
  262. { "code": "kj", "value": "83" },
  263. { "code": "kk", "value": "84" },
  264. { "code": "kl", "value": "85" },
  265. { "code": "km", "value": "86" },
  266. { "code": "kn", "value": "87" },
  267. { "code": "ko", "value": "88" },
  268. { "code": "kr", "value": "89" },
  269. { "code": "ks", "value": "90" },
  270. { "code": "ku", "value": "91" },
  271. { "code": "kv", "value": "92" },
  272. { "code": "kw", "value": "93" },
  273. { "code": "ky", "value": "94" },
  274. { "code": "la", "value": "95" },
  275. { "code": "lb", "value": "96" },
  276. { "code": "lg", "value": "97" },
  277. { "code": "lif", "value": "98" },
  278. { "code": "ln", "value": "99" },
  279. { "code": "lo", "value": "100" },
  280. { "code": "lt", "value": "101" },
  281. { "code": "lu", "value": "102" },
  282. { "code": "lv", "value": "103" },
  283. { "code": "mg", "value": "104" },
  284. { "code": "mh", "value": "105" },
  285. { "code": "mi", "value": "106" },
  286. { "code": "mk", "value": "107" },
  287. { "code": "ml", "value": "108" },
  288. { "code": "mn", "value": "109" },
  289. { "code": "mo", "value": "110" },
  290. { "code": "mr", "value": "111" },
  291. { "code": "ms", "value": "112" },
  292. { "code": "mt", "value": "113" },
  293. { "code": "my", "value": "114" },
  294. { "code": "na", "value": "115" },
  295. { "code": "nb", "value": "119" },
  296. { "code": "nd", "value": "120" },
  297. { "code": "ne", "value": "121" },
  298. { "code": "ng", "value": "122" },
  299. { "code": "nl", "value": "118" },
  300. { "code": "nn", "value": "124" },
  301. { "code": "no", "value": "125" },
  302. { "code": "nr", "value": "126" },
  303. { "code": "nv", "value": "127" },
  304. { "code": "ny", "value": "128" },
  305. { "code": "oc", "value": "129" },
  306. { "code": "pa", "value": "131" },
  307. { "code": "pi", "value": "132" },
  308. { "code": "ps", "value": "133" },
  309. { "code": "pt", "value": "134" },
  310. { "code": "qu", "value": "135" },
  311. { "code": "rm", "value": "136" },
  312. { "code": "rn", "value": "137" },
  313. { "code": "ro", "value": "138" },
  314. { "code": "ru", "value": "139" },
  315. { "code": "rw", "value": "140" },
  316. { "code": "sa", "value": "141" },
  317. { "code": "sc", "value": "142" },
  318. { "code": "sd", "value": "143" },
  319. { "code": "sg", "value": "144" },
  320. { "code": "sh", "value": "145" },
  321. { "code": "si", "value": "146" },
  322. { "code": "sk", "value": "149" },
  323. { "code": "sl", "value": "150" },
  324. { "code": "sm", "value": "151" },
  325. { "code": "sn", "value": "152" },
  326. { "code": "so", "value": "153" },
  327. { "code": "sq", "value": "154" },
  328. { "code": "sr", "value": "155" },
  329. { "code": "ss", "value": "156" },
  330. { "code": "st", "value": "157" },
  331. { "code": "su", "value": "158" },
  332. { "code": "sv", "value": "159" },
  333. { "code": "sw", "value": "160" },
  334. { "code": "ta", "value": "161" },
  335. { "code": "te", "value": "162" },
  336. { "code": "tg", "value": "163" },
  337. { "code": "th", "value": "165" },
  338. { "code": "ti", "value": "166" },
  339. { "code": "tk", "value": "167" },
  340. { "code": "tl", "value": "168" },
  341. { "code": "tn", "value": "169" },
  342. { "code": "to", "value": "170" },
  343. { "code": "tr", "value": "171" },
  344. { "code": "ts", "value": "172" },
  345. { "code": "tt", "value": "173" },
  346. { "code": "tw", "value": "174" },
  347. { "code": "ty", "value": "175" },
  348. { "code": "ug", "value": "176" },
  349. { "code": "uk", "value": "177" },
  350. { "code": "ur", "value": "178" },
  351. { "code": "uz", "value": "179" },
  352. { "code": "ve", "value": "180" },
  353. { "code": "vi", "value": "181" },
  354. { "code": "vo", "value": "182" },
  355. { "code": "wa", "value": "183" },
  356. { "code": "wo", "value": "184" },
  357. { "code": "xh", "value": "185" },
  358. { "code": "yi", "value": "186" },
  359. { "code": "zh-CN", "value": "187" },
  360. { "code": "zh-TW", "value": "188" },
  361. { "code": "zu", "value": "189" }
  362. ]
  363. const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
  364. const formDataObj = {
  365. _method: 'patch',
  366. authenticity_token: csrfToken,
  367. 'script[sync_identifier]': scriptSyncIdentifier,
  368. 'script[sync_type]': 'webhook',
  369. }
  370. if (additionalInfoSyncIdentifier) {
  371. formDataObj['additional_info_sync[0][attribute_default]'] = 'true'
  372. formDataObj['additional_info_sync[0][sync_identifier]'] = additionalInfoSyncIdentifier
  373. formDataObj['additional_info_sync[0][value_markup]'] = 'markdown'
  374. }
  375. urls.forEach((url, index) => {
  376. const localeKey = extractLocaleKey(url)
  377. const locale = translateTable.find(entry => entry.code === localeKey)
  378. const cleanUrl = url.replace(/##.*/, '')
  379. formDataObj[`additional_info_sync[${index + 1}][attribute_default]`] = 'false'
  380. formDataObj[`additional_info_sync[${index + 1}][locale]`] = locale ? locale.value : ''
  381. formDataObj[`additional_info_sync[${index + 1}][sync_identifier]`] = cleanUrl
  382. formDataObj[`additional_info_sync[${index + 1}][value_markup]`] = 'markdown'
  383. })
  384. formDataObj['update-and-sync'] = '更新设置并立即同步'
  385. const formData = new URLSearchParams(formDataObj)
  386. console.log(formData.toString())
  387. const postResp = await fetch(postUrl + '/sync_update', {
  388. method: 'POST',
  389. headers: { "Content-Type": "application/x-www-form-urlencoded" },
  390. body: formData
  391. })
  392. const responseText = await postResp.text()
  393. const parser = new DOMParser()
  394. const doc = parser.parseFromString(responseText, 'text/html')
  395. const specificElement = doc.querySelector("body > div.width-constraint > p")
  396. // 创建并插入弹出框的 HTML
  397. document.body.insertAdjacentHTML('beforeend', `
  398. <div id="custom-popup" style="position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);padding:20px;background-color:#fff;border:1px solid #ccc;box-shadow:0 0 10px rgba(0,0,0,0.1);z-index:9999;">
  399. ${specificElement ? specificElement.innerHTML : 'Element not found'}
  400. <button id="close-popup" style="top: 10px; right: 10px; color: red;">&times;</button>
  401. </div>
  402. `)
  403. document.getElementById('close-popup').onclick = function () {
  404. document.getElementById('custom-popup').remove()
  405. }
  406. setTimeout(function () {
  407. const popup = document.getElementById('custom-popup')
  408. if (popup) {
  409. popup.remove()
  410. }
  411. }, 5000)
  412. // global.inputModal.style.display = 'none'
  413. //alert((postResp.ok || postResp.status === 302) ? global.scriptname + ' Sync Successful!' : 'Synchronization failed, please check the input.')
  414. }
  415. function extractLocaleKey(url) {
  416. let localeKey = url.includes('##') ? url.match(/##.*\((.*?)\)$/) || url.match(/##(.*?)$/) : url.match(/README_(.*?)\.md/)
  417. return localeKey ? localeKey[1] : null
  418. }
  419. //----设置主窗口
  420. function addAdminButtons() {
  421. fetch('https://gf.qytechs.cn/zh-CN/users/webhook-info')
  422. .then(response => response.ok ? response.text() : Promise.reject('Network response was not ok'))
  423. .then(data => createModalWindow(parseLinks(data)))
  424. .catch(error => console.error('Fetch operation failed:', error))
  425. }
  426. function parseLinks(data) {
  427. const parser = new DOMParser()
  428. const doc = parser.parseFromString(data, 'text/html')
  429. const firstUl = doc.querySelector('ul')
  430. if (!firstUl) return []
  431. return Array.from(firstUl.querySelectorAll('li')).map(li => {
  432. const links = li.querySelectorAll('a')
  433. return {
  434. firstHref: links[0]?.href || '',
  435. firstTitle: links[0]?.textContent || '',
  436. secondHref: links[1]?.href || '',
  437. secondTitle: links[1]?.textContent || ''
  438. }
  439. })
  440. }
  441. function openSuperAdmin(url, syncjs, isFetch = false) {
  442. global.adminUrl = url
  443. if (isFetch) {
  444. updateWebHookInfo(url + "/admin")
  445. } else {
  446. updateWebHookInfo()
  447. }
  448. global.inputModalScript.value = global.syncingfrom
  449. global.inputModalDefault.value = global.defaultAttribute
  450. global.inputModalTextArea.value = global.attribute_other
  451. global.inputModal.style.display = 'flex'
  452. document.querySelector("h2 label[for='SyncScript']").textContent = global.scriptname + "←Source Syncing"
  453. document.getElementById("ScriptName").textContent = global.scriptname
  454. }
  455. function createModalWindow(linksData) {
  456. const modalHtml = `
  457. <center>
  458. <div class="Sync-Modal">
  459. <div id="adminModal" style="display: none; position: fixed; z-index: 1000; left: 0; top: 50px; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background-color: transparent;">
  460. <div style="background-color: #fefefe; padding: 20px; border: 1px solid #888; width: 40%; max-width: 100%;">
  461. <span id="closeLinkModal" style="color: red; float: right; font-size: 28px; font-weight: bold; cursor: pointer;">&times;</span>
  462. <h2>Here are the scripts you have already set up to sync</h2>
  463. <ul id="linksList" style="list-style-type: none; padding: 0; max-height: 60vh; overflow-y: auto;">
  464. </ul>
  465. </div>
  466. </div>
  467. </div>
  468. </center>
  469. `
  470. document.body.insertAdjacentHTML('beforeend', modalHtml)
  471. const modal = document.getElementById('adminModal')
  472. const closeModal = document.getElementById('closeLinkModal')
  473. const linksList = document.getElementById('linksList')
  474. //
  475. linksData.forEach(link => {
  476. const listItem = document.createElement('li')
  477. listItem.style.marginBottom = '10px'
  478. listItem.innerHTML = `
  479. <div style="display: flex; justify-content: space-between; align-items: center;">
  480. <a href="${link.firstHref}" target="_blank" style="text-decoration: none; color: blue;">${link.firstTitle}</a>
  481. <div>
  482. <a href="${link.secondHref}" target="_blank" style="text-decoration: none; color: blue;">Source Syncing</a>
  483. <!--<button style="margin-left: 10px;" onclick="window.open('${link.firstHref}')">View</button>
  484. -->
  485. <button class="super-admin-btn" style="margin-left: 10px;" onclick="openSuperAdmin('${link.firstHref}/admin')">Set Sync</button>
  486. </div>
  487. </div>
  488. `
  489. linksList.appendChild(listItem)
  490. listItem.querySelector('.super-admin-btn').addEventListener('click', () => {
  491. openSuperAdmin(link.firstHref, link.secondHref, true)
  492. })
  493. })
  494. modal.style.display = 'block'
  495. closeModal.addEventListener('click', () => {
  496. modal.style.display = 'none'
  497. modal.remove()
  498. })
  499. window.addEventListener('click', (event) => {
  500. return//不关闭
  501. if (event.target === modal) {
  502. modal.style.display = 'none'
  503. modal.remove()
  504. }
  505. })
  506. }
  507. function updateStateFromDOM(dom) {
  508. const syncInputElement = dom.getElementById('script_sync_identifier')
  509. if (syncInputElement) {
  510. global.syncingfrom = syncInputElement.value
  511. } else {
  512. console.warn("Input element with id 'script_sync_identifier' not found")
  513. }
  514. const defaultInputElement = dom.querySelector('input#script-version-additional-info-0.previewable')
  515. if (defaultInputElement) {
  516. global.defaultAttribute = defaultInputElement.value
  517. } else {
  518. console.warn("Default input element not found")
  519. }
  520. const inputElements = dom.querySelectorAll('input[id^="script-version-additional-info-"].previewable')
  521. global.scriptname = dom.querySelector("#script-info > header > h2").textContent
  522. global.attribute_other = ''
  523. inputElements.forEach((inputElement, index) => {
  524. if (inputElement.id !== "script-version-additional-info-0") {
  525. if (global.attribute_other) {
  526. global.attribute_other += '\n'
  527. }
  528. const previousSibling = inputElement.previousElementSibling
  529. const selectElement = previousSibling?.previousElementSibling
  530. const selectedText = selectElement?.options[selectElement.selectedIndex]?.text
  531. global.attribute_other += `${inputElement.value}##${selectedText}`
  532. }
  533. })
  534. }
  535. function updateWebHookInfo(url = null) {
  536. if (url) {
  537. try {
  538. const xhr = new XMLHttpRequest()
  539. xhr.open("GET", url, false) // `false` 使请求同步
  540. xhr.send(null)
  541. if (xhr.status >= 200 && xhr.status < 300) {
  542. const htmlText = xhr.responseText
  543. const parser = new DOMParser()
  544. const doc = parser.parseFromString(htmlText, 'text/html')
  545. updateStateFromDOM(doc)
  546. console.log("Data fetched from URL and parsed:", global)
  547. } else {
  548. throw new Error(`Network response was not ok: ${xhr.statusText}`)
  549. }
  550. } catch (error) {
  551. console.error("Error fetching data from URL:", error)
  552. }
  553. } else {
  554. updateStateFromDOM(document)
  555. console.log("Data fetched from current page:", global)
  556. }
  557. }
  558. function addNavLink(link_text, linkurl, newtab, lastone, lclassname) {
  559. var li = document.createElement('li')
  560. if (lclassname) {
  561. li.className = lclassname
  562. } else {
  563. li.className = 'scripts-index-link'
  564. }
  565. var a = document.createElement('a')
  566. a.href = linkurl
  567. a.innerText = link_text
  568. li.appendChild(a)
  569. var nav = document.querySelector('div#site-nav > nav')
  570. if (nav) {
  571. if (lastone) {
  572. nav.append(li)
  573. } else {
  574. nav.prepend(li)
  575. }
  576. }
  577. }
  578. })()

QingJ © 2025

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