戴森球蓝图 增强

Extend the website Dyson Sphere Blueprints

  1. // ==UserScript==
  2. // @name 戴森球蓝图 增强
  3. // @namespace https://blog.rhilip.info/
  4. // @version 0.0.3
  5. // @description Extend the website Dyson Sphere Blueprints
  6. // @author Rhilip
  7. // @match https://www.dysonsphereblueprints.com/*
  8. // @require https://unpkg.com/jquery@3.3.1/dist/jquery.min.js
  9. // @require https://unpkg.com/jszip@3.7.0/dist/jszip.min.js
  10. // @require https://unpkg.com/file-saver@2.0.5/dist/FileSaver.min.js
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (async function () {
  15. 'use strict';
  16.  
  17. // 清理文件名中的特殊字符
  18. function sanitizeFileName(input) {
  19. if (typeof input !== 'string') {
  20. throw new Error('Input must be string');
  21. }
  22. return input
  23. .replace(/[\/\?<>\\:\*\|":]/g, '_')
  24. .replace(/[\x00-\x1f\x80-\x9f]/g, '_')
  25. .replace(/^\.+$/, '_')
  26. .replace(/^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i, '_')
  27. .replace(/[\. ]+$/, '_');;
  28. }
  29.  
  30. function getBlueprintNameFromAnother(another) {
  31. return another.find('div.o-blueprint-card__content h2 a').text().trim();
  32. }
  33.  
  34. function getBlueprintTextFromAnother(another) {
  35. return another.find('button[data-clipboard-text]').data('clipboard-text');
  36. }
  37.  
  38. function getBlueprintDataFromAnother(another) {
  39. return [getBlueprintNameFromAnother(another), getBlueprintTextFromAnother(another)]
  40. }
  41.  
  42. // 给列表的单个蓝图加上下载按钮
  43. function addBlueprintDownloadBtn() {
  44. $('.o-blueprint-card__copy').each(function () {
  45. const that = $(this);
  46. const blueprintString = that.data('clipboard-text');
  47. const blueprintAnother = that.parents('li.o-blueprint-card');
  48. const blueprintName = getBlueprintNameFromAnother(blueprintAnother);
  49.  
  50. const downloadBtn = $('<button class="o-blueprint-card__copy uj_added uj_download_this" style="left:80px">Download</button>');
  51. downloadBtn.click(function () {
  52. saveAs(new Blob([blueprintString]), `${sanitizeFileName(blueprintName)}.txt`);
  53. })
  54.  
  55. if (blueprintAnother.find('button.uj_download_this').length === 0) {
  56. that.after(downloadBtn);
  57. }
  58. })
  59. }
  60.  
  61. function addDownloadThisPageBtn() {
  62. const downloadThisPageBtn = $('<button class="o-blueprint-card__copy uj_added uj_download_page" style="position: static;">Download This Page</button>');
  63. downloadThisPageBtn.click(function () {
  64. const allBlueprintInThisPage = $('li.o-blueprint-card').map(function () {
  65. return [getBlueprintDataFromAnother($(this))];
  66. }).get();
  67.  
  68. if (allBlueprintInThisPage.length > 1) {
  69. const jszip = new JSZip();
  70. for (const getBlueprintDataFromAnother of allBlueprintInThisPage) {
  71. const [blueprintName, blueprintString] = getBlueprintDataFromAnother
  72. jszip.file(`${sanitizeFileName(blueprintName)}.txt`, blueprintString)
  73. }
  74.  
  75. jszip.generateAsync({ type: "blob" })
  76. .then(function (content) {
  77. saveAs(content, "blueprint.zip");
  78. });
  79. } else {
  80. const [blueprintName, blueprintString] = allBlueprintInThisPage[0];
  81. saveAs(new Blob([blueprintString]), `${sanitizeFileName(blueprintName)}.txt`);
  82. }
  83. })
  84.  
  85. if ($('button.uj_download_page').length === 0) {
  86. $('div.t-blueprint-list').prepend(downloadThisPageBtn);
  87. }
  88. }
  89.  
  90. function main() {
  91. $('.uj_added').remove(); // 清空所有我们添加的DOM,防止 turbolinks 切换时出现重复按钮
  92.  
  93. if (
  94. location.pathname === '/' // 首页
  95. || (location.pathname === '/blueprints' && location.search.includes('search=')) // 搜索页
  96. ) {
  97. console.log('首页以及蓝图搜索页');
  98. addBlueprintDownloadBtn();
  99. addDownloadThisPageBtn();
  100. } else if (
  101. location.pathname === '/collections'
  102. ) {
  103. console.log('合集搜索页面');
  104.  
  105. // TODO 直接在合集搜索页面搜索下载整个合集
  106.  
  107. } else if (
  108. location.pathname.startsWith('/blueprints/')
  109. ) {
  110. console.log('蓝图详细页面');
  111. const downloadBtn = $('<button class="t-blueprint__copy uj_added" style="margin-right: 10px;"><i class="fas fa-download"></i>Download</button>');
  112. downloadBtn.click(function () {
  113. const bpText = $('div.t-blueprint__blueprint > textarea').text();
  114. const bpName = $('div.t-blueprint__title h2').text().trim();
  115. saveAs(new Blob([bpText]), `${sanitizeFileName(bpName)}.txt`);
  116. });
  117.  
  118. $('.t-blueprint__blueprint button.t-blueprint__copy').after(downloadBtn);
  119. } else if (
  120. location.pathname.startsWith('/collections/')
  121. || /^\/users(\/\d+)?\/blueprints/.test(location.pathname) // 用户列表页(包括自己和他人)
  122. ) {
  123. console.log('合集详细页面');
  124. addBlueprintDownloadBtn();
  125. addDownloadThisPageBtn();
  126. }
  127. }
  128.  
  129. // 运行主方法,并在页面切换时同样运行
  130. main();
  131. document.addEventListener("turbolinks:load", function () {
  132. main();
  133. })
  134. })();

QingJ © 2025

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