Furaffinity-Custom-Pages

Library to create Custom pages on Furaffinitiy

当前为 2025-02-02 提交的版本,查看 最新版本

此脚本不应直接安装,它是供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/476762/1530874/Furaffinity-Custom-Pages.js

  1. // ==UserScript==
  2. // @name Furaffinity-Custom-Pages
  3. // @namespace Violentmonkey Scripts
  4. // @grant none
  5. // @version 1.2.0
  6. // @author Midori Dragon
  7. // @description Library to create Custom pages on Furaffinitiy
  8. // @icon https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png
  9. // @license MIT
  10. // ==/UserScript==
  11. // jshint esversion: 8
  12. (() => {
  13. "use strict";
  14. var LogLevel;
  15. !function(LogLevel) {
  16. LogLevel[LogLevel.Error = 1] = "Error";
  17. LogLevel[LogLevel.Warning = 2] = "Warning";
  18. LogLevel[LogLevel.Info = 3] = "Info";
  19. }(LogLevel || (LogLevel = {}));
  20. class Logger {
  21. static log(logLevel = LogLevel.Warning, ...args) {
  22. if (null == window.__FF_GLOBAL_LOG_LEVEL__) window.__FF_GLOBAL_LOG_LEVEL__ = LogLevel.Error;
  23. if (!(logLevel > window.__FF_GLOBAL_LOG_LEVEL__)) switch (logLevel) {
  24. case LogLevel.Error:
  25. console.error(...args);
  26. break;
  27.  
  28. case LogLevel.Warning:
  29. console.warn(...args);
  30. break;
  31.  
  32. case LogLevel.Info:
  33. console.log(...args);
  34. }
  35. }
  36. static setLogLevel(logLevel) {
  37. window.__FF_GLOBAL_LOG_LEVEL__ = logLevel;
  38. }
  39. static logError(...args) {
  40. Logger.log(LogLevel.Error, ...args);
  41. }
  42. static logWarning(...args) {
  43. Logger.log(LogLevel.Warning, ...args);
  44. }
  45. static logInfo(...args) {
  46. Logger.log(LogLevel.Info, ...args);
  47. }
  48. }
  49. function extractParameter(url, parameterName) {
  50. const parts = url.split("?");
  51. if (parts.length > 1) {
  52. const params = parts[parts.length - 1].split("&");
  53. for (const param of params) {
  54. const [key, value] = param.split("=");
  55. if (key === parameterName) return {
  56. key,
  57. value: decodeURIComponent(value)
  58. };
  59. }
  60. }
  61. }
  62. class CustomData {
  63. constructor(document) {
  64. this.document = document;
  65. }
  66. removeDocumentSiteContent() {
  67. const siteContent = this.document.getElementById("site-content");
  68. if (null != siteContent) siteContent.remove();
  69. return siteContent;
  70. }
  71. }
  72. class CustomPage extends EventTarget {
  73. constructor(pageUrl, parameterName) {
  74. super();
  75. Object.setPrototypeOf(this, CustomPage.prototype);
  76. this.pageUrl = pageUrl;
  77. this.parameterName = parameterName;
  78. CustomPage.customPages.push(this);
  79. Logger.logInfo(`New CustomPage at '${pageUrl}'='${parameterName}'`);
  80. }
  81. get isOpen() {
  82. const url = window.location.toString();
  83. if (!url.includes(this.pageUrl)) return false;
  84. const parameter = extractParameter(url, this.parameterName), isOpen = (null == parameter ? void 0 : parameter.key) === this.parameterName;
  85. if (isOpen) Logger.logInfo(`CustomPage '${this.pageUrl}'='${this.parameterName}' is open`);
  86. return isOpen;
  87. }
  88. get parameterValue() {
  89. const parameter = extractParameter(window.location.toString(), this.parameterName);
  90. return null == parameter ? void 0 : parameter.value;
  91. }
  92. get onOpen() {
  93. return this._onOpen;
  94. }
  95. set onOpen(handler) {
  96. this._onOpen = handler;
  97. }
  98. static checkAllPages() {
  99. CustomPage.customPages.forEach((page => page.checkPageOpened()));
  100. }
  101. checkPageOpened() {
  102. if (this.isOpen) this.pageOpened(this.parameterValue, document);
  103. }
  104. pageOpened(parameterValue, openedPage) {
  105. const customData = new CustomData(openedPage);
  106. customData.parameterValue = parameterValue;
  107. const event = new CustomEvent("onOpen", {
  108. detail: customData
  109. });
  110. this.dispatchEvent(event);
  111. }
  112. invokeOpen(doc, parameterValue) {
  113. var _a;
  114. const customData = new CustomData(doc);
  115. customData.parameterValue = parameterValue;
  116. null === (_a = this._onOpen) || void 0 === _a || _a.call(this, customData);
  117. this.dispatchEvent(new CustomEvent("open", {
  118. detail: customData
  119. }));
  120. }
  121. }
  122. CustomPage.customPages = [];
  123. Object.defineProperties(window, {
  124. FACustomPage: {
  125. get: () => CustomPage
  126. }
  127. });
  128. })();