USOa - Show source code

Display the source code of the userstyle's on its "UserStyles.org Archive" page

  1. // ==UserScript==
  2. // @name USOa - Show source code
  3. // @namespace https://github.com/Procyon-b
  4. // @version 0.3.1
  5. // @description Display the source code of the userstyle's on its "UserStyles.org Archive" page
  6. // @author Achernar
  7. // @match https://uso.kkx.one/*
  8. // @run-at document-start
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. "use strict";
  14.  
  15. var RJ=Response.prototype.json;
  16. Response.prototype.json=function(){
  17. var e=this;
  18. var r=RJ.apply(e, ...arguments)
  19. return r.then(function (o) {
  20. uCSS='';
  21. if (o && o.style) {
  22. if (o.style.settings) uCSS=toUsercss(o);
  23. else uCSS=o.style.css;
  24. setTimeout(init, 0);
  25. }
  26. return o;
  27. });
  28. }
  29.  
  30. var uCSS='';
  31.  
  32. function init() {
  33. var r=document.querySelectorAll('.col-12'), R;
  34. if (R=r[1]) {
  35. R=R.parentNode.appendChild(document.createElement('div'));
  36. R.className='source';
  37. R.appendChild(document.createElement('h2')).textContent='Source code';
  38. R.appendChild(document.createElement('style')).textContent=`
  39. html {
  40. --bdcol: #6c757d;
  41. }
  42. html.dark {
  43. --bdcol: #626262;
  44. }
  45. .source {
  46. order: 9;
  47. }
  48. .source pre {
  49. padding: 0.5rem;
  50. overflow: auto;
  51. resize: vertical;
  52. border: 1px solid var(--bdcol);
  53. border-radius: .25rem;
  54. min-height: 20rem;
  55. height: 20rem;
  56. font-size: 13px;
  57. }
  58. `;
  59. let S=document.createElement('div');
  60. S.className='Style-source';
  61. R.appendChild(S);
  62. S.appendChild(document.createElement('pre')).appendChild(document.createElement('code')).textContent=uCSS;
  63. }
  64. }
  65.  
  66.  
  67. /* source code imported from https://github.com/uso-archive/data/blob/flomaster/lib/converters.js */
  68. /* 2023-02-19 */
  69. function toUsercss(style) {
  70. let replaces = [];
  71. const settings = toUsercssSettings(style.style.settings);
  72.  
  73. function processKey(key) {
  74. if (/^[\w-_]+$/.test(key)) {
  75. return key;
  76. }
  77. else {
  78. const result = key.replace(/[^\w-_]/g, "-");
  79. const c = replaces.filter(v => v.r === result).length || null;
  80. replaces.push({ from: new RegExp(utils.escapeRegExp(`/*[[${key}]]*/`), "gi"), to: `/*[[${result}${c ? "-" + c : ""}]]*/`, r: result });
  81. return result;
  82. }
  83. }
  84.  
  85. function toUsercssDropdownOptions(options) {
  86. let result = "";
  87. for (const option of options) {
  88. if (option.default) result = `${processKey(option.key)} "${option.label.replace(/"/g, "\\\"")}${option.default ? "*" : ""}" <<<EOT ${option.value} EOT;\r\n` + result;
  89. else result += `${processKey(option.key)} "${option.label.replace(/"/g, "\\\"")}${option.default ? "*" : ""}" <<<EOT ${option.value} EOT;\r\n`;
  90. }
  91. return result;
  92. }
  93.  
  94. function toUsercssSetting(setting) {
  95. switch (setting.type) {
  96. case "dropdown":
  97. return `@advanced dropdown ${processKey(setting.key)} "${setting.label.replace(/"/g, "\\\"")}" {
  98. ${toUsercssDropdownOptions(setting.options)}
  99. }`;
  100. case "color":
  101. return `@advanced color ${processKey(setting.key)} "${setting.label.replace(/"/g, "\\\"")}" ${setting.options[0].value}`;
  102. case "image":
  103. const key = processKey(setting.key);
  104. return `@advanced dropdown ${key} "${setting.label.replace(/"/g, "\\\"")}" {
  105. ${toUsercssDropdownOptions(setting.options)}
  106. ${processKey(key)}-custom-dropdown "Custom" <<<EOT /*[[${processKey(key)}-custom]]*/ EOT;
  107. }
  108. @advanced text ${processKey(key)}-custom "${setting.label.replace(/"/g, "\\\"")} (Custom)" "https://example.com/image.png"`;
  109. case "text":
  110. return `@advanced text ${processKey(setting.key)} "${setting.label.replace(/"/g, "\\\"")}" "${setting.options[0].value}"`;
  111. }
  112. }
  113.  
  114. function toUsercssSettings(settings) {
  115. if (!settings) return "";
  116. let result = "";
  117. for (const setting of settings) {
  118. result += `${toUsercssSetting(setting).replace(/\*\//g, "*\\/")}\r\n`;
  119. }
  120. return result;
  121. }
  122.  
  123. let result = `/* ==UserStyle==
  124. @name ${style.info.name}
  125. @namespace USO Archive
  126. @author ${style.info.author ? style.info.author.name || "unknown" : "unknown"}
  127. @description \`${style.info.description ? style.info.description.replace(/[\r\n]/gm, "") : "none"}\`
  128. @version ${versionFromTimestamp(style.info.updatedAt)}
  129. @license ${style.info.license}
  130. @preprocessor uso${settings ? "\n" + settings : ""}
  131. ==/UserStyle== */
  132. ${style.style.css}`;
  133.  
  134. for (const replace of replaces) {
  135. result = result.replace(replace.from, replace.to);
  136. }
  137.  
  138. return result;
  139. }
  140.  
  141. function versionFromTimestamp(timestamp) {
  142. const date = new Date(timestamp);
  143. return `${date.getFullYear()}${(date.getMonth() + 1).toString().padStart(2, 0)}${date.getDate().toString().padStart(2, 0)}.${date.getHours()}.${date.getMinutes()}`;
  144. }
  145.  
  146. // source code from https://github.com/uso-archive/data/blob/flomaster/lib/utils.js
  147. /* 2023-02-19 */
  148. function escapeRegExp(string) {
  149. return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  150. }
  151. var utils={escapeRegExp};
  152.  
  153. })();

QingJ © 2025

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