userscripts-core-library

Core library to handle webpages dom with userscripts from document-start

目前为 2023-09-24 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/476017/1255617/userscripts-core-library.js

  1. // ==UserScript==
  2. // @name userscripts-core-library
  3. // @version 0.1.0
  4. // @author lucianjp
  5. // @description Core library to handle webpages dom with userscripts from document-start
  6. // ==/UserScript==
  7.  
  8. const core = {
  9. ready: (callback) =>
  10. document.readyState !== "loading"
  11. ? callback()
  12. : document.addEventListener("DOMContentLoaded", callback),
  13. addStyle: (aCss) => {
  14. let head = document.getElementsByTagName("head")[0];
  15. if (!head) {
  16. console.error("Head element not found. Cannot add style.");
  17. return null;
  18. }
  19.  
  20. let style = document.createElement("style");
  21. style.setAttribute("type", "text/css");
  22. style.textContent = aCss;
  23. head.appendChild(style);
  24. return style;
  25. },
  26. observe: (observableCollection, continuous = false) => {
  27. const observables = Array.from(observableCollection.entries()).filter(
  28. ([_, observable]) => !observable.currentValue
  29. );
  30.  
  31. const observer = new MutationObserver(function (mutations) {
  32. for (var i = mutations.length - 1; i >= 0; i--) {
  33. const mutation = mutations[i];
  34. const addedNodesLength = mutation.addedNodes.length;
  35. if (addedNodesLength > 0) {
  36. for (var j = addedNodesLength - 1; j >= 0; j--) {
  37. const $node = mutation.addedNodes[j];
  38. if ($node && $node.nodeType === 1) {
  39. let observablesLength = observables.length;
  40. for (let k = observablesLength - 1; k >= 0; k--) {
  41. const [_, observable] = observables[k];
  42.  
  43. if (observable.test($node)) {
  44. observable.set($node);
  45. const last = observables.pop();
  46. if (k < observablesLength - 1) observables[k] = last;
  47. observablesLength = observablesLength - 1;
  48. break;
  49. }
  50. }
  51. }
  52. }
  53.  
  54. if (observables.length === 0 && !continuous) {
  55. observer.disconnect();
  56. return;
  57. }
  58. }
  59. }
  60. });
  61.  
  62. observer.observe(document, { childList: true, subtree: true });
  63.  
  64. if (!continuous) core.ready(() => observer.disconnect());
  65.  
  66. return observer;
  67. },
  68. };
  69.  
  70. class Observable {
  71. constructor(lookup, test) {
  72. this.value = undefined;
  73. this.callbacks = [];
  74. this.lookup = lookup;
  75. this.test = test;
  76.  
  77. if (typeof lookup === "function") {
  78. this.value = lookup();
  79. }
  80. }
  81.  
  82. set(newValue) {
  83. this.value = newValue;
  84. this.executeCallbacks(this.value);
  85. }
  86.  
  87. then(callback) {
  88. if (typeof callback === "function") {
  89. this.callbacks.push(callback);
  90. if (this.value) callback(this.value);
  91. }
  92. return this;
  93. }
  94.  
  95. executeCallbacks(value) {
  96. this.callbacks.forEach((callback) => callback(value));
  97. }
  98.  
  99. get currentValue() {
  100. return this.value;
  101. }
  102. }
  103.  
  104. class ObservableCollection extends Map {
  105. constructor() {
  106. super();
  107. }
  108.  
  109. add(name, observable) {
  110. this.set(name, observable);
  111. return observable;
  112. }
  113. }

QingJ © 2025

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