TetteLib

A library containing several functions I use often in my other scripts

当前为 2023-10-27 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/478390/1271151/TetteLib.js

  1. // ==UserScript==
  2. // @name TetteLib
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description A library containing several functions I use often in my other scripts
  6. // @author TetteDev
  7. // @match *://*/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. function simulateNotification(title, message, type = "info", timeout = 2500) {
  12. const toastId = "simpleToast";
  13. var notificationContainer = document.createElement("div");
  14. notificationContainer.id = toastId;
  15.  
  16. let existingNotification = document.getElementById(toastId);
  17. if (existingNotification) existingNotification.remove();
  18.  
  19. notificationContainer.title = "Click to dismiss this message";
  20.  
  21. var innerContainer = document.createElement("div");
  22. const imgSize = 54;
  23. let imgSrc = "";
  24. let backgroundColor = "";
  25. let fontColor = "";
  26.  
  27. if (type.toLowerCase() === "debug") {
  28. imgSrc = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678124-wrench-screwdriver-64.png";
  29. backgroundColor = "#eac100";
  30. fontColor = "#323232";
  31. }
  32. else if (type.toLowerCase() === "error") {
  33. imgSrc = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678069-sign-error-64.png";
  34. backgroundColor = "#ff0000";
  35. fontColor = "#ffffff";
  36. }
  37. else {
  38. imgSrc = "https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678110-sign-info-64.png";
  39. backgroundColor = "#0f0f0f";
  40. fontColor = "#ffffff";
  41. }
  42.  
  43. notificationContainer.style.cssText
  44. = `position: fixed;
  45. bottom: 15px;
  46. right: 15px;
  47. background-color: ${backgroundColor};
  48. color: ${fontColor};
  49. border: 1px solid #ffffff;
  50. max-width: 20%;
  51. padding-left: 50px;
  52. padding-right: 50px;
  53. padding-top:10px;
  54. box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  55. z-index: 9999;
  56. opacity: 1;
  57. transition: opacity 1s, border-radius 0.5s;
  58. border-radius: 5px;
  59. cursor: pointer;
  60. `
  61.  
  62. innerContainer.innerHTML =
  63. `<img src='${imgSrc}' style='width:${imgSize}px;height:${imgSize}px;padding-bottom:10px;display:block;margin:auto;'></img>
  64. <p id='title' style='text-align:center;font-weight:bold;font-size:20px;'>${title}</p>
  65. <p id='message' style='text-align:center;padding-bottom:15px;font-size:15px;'>${message}</p>`;
  66.  
  67. notificationContainer.appendChild(innerContainer);
  68.  
  69. notificationContainer.onclick = function() { document.body.removeChild(notificationContainer); notificationContainer = null; }
  70. document.body.appendChild(notificationContainer);
  71.  
  72. if (type.toLowerCase() === "debug") {
  73. console.warn(`[Youtube AdSkipper][DEBUG] ${title}: ${message}`);
  74. }
  75. else if (type.toLowerCase() === "error") {
  76. console.error(`[Youtube AdSkipper][ERROR] ${title}: ${message}`);
  77. }
  78.  
  79. // Set a timer to fade out the notification after 'timeout' milliseconds if (if 'timeout' is not -1 or less)
  80. if (timeout > -1) {
  81. setTimeout(function() {
  82. if (notificationContainer == null) return;
  83. notificationContainer.style.opacity = 0;
  84. setTimeout(function() {
  85. if (notificationContainer == null) return;
  86. document.body.removeChild(notificationContainer);
  87. }, 500); // Remove the notification after the fade-out animation (adjust as needed)
  88. }, (timeout < 1 ? 2500 : timeout)); // Start the fade-out animation after 5 seconds (adjust as needed)
  89. }
  90. }
  91. function waitForElement(selector) {
  92. return new Promise((resolve, reject) => {
  93. const el = document.querySelector(selector);
  94. if (el) {resolve(el);}
  95. new MutationObserver((mutationRecords, observer) => {
  96. // Query for elements matching the specified selector
  97. Array.from(document.querySelectorAll(selector)).forEach((element) => {
  98. resolve(element);
  99. //Once we have resolved we don't need the observer anymore.
  100. observer.disconnect();
  101. });
  102. })
  103. .observe(document.documentElement, {
  104. childList: true,
  105. subtree: true
  106. });
  107. });
  108. }
  109. function traverseParentsUntil(startElement, predicateUntil) {
  110. if (!startElement) return null;
  111. if (!predicateUntil || typeof predicateUntil !== "function") return null;
  112. if (!startElement.parentElement) return predicateUntil(startElement) ? startElement : null;
  113.  
  114. while (startElement.parentElement) {
  115. if (predicateUntil(startElement.parentElement)) return startElement.parentElement;
  116. else startElement = startElement.parentElement;
  117. }
  118. return null;
  119. }
  120. function traverseChildrenUntil(startElement, predicateUntil) {
  121. if (!startElement) return null;
  122. if (!predicateUntil || typeof predicateUntil !== "function") return null;
  123. if (!startElement.firstChild) return predicateUntil(startElement) ? startElement : null;
  124.  
  125. while (startElement.firstChild) {
  126. if (predicateUntil(startElement.firstChild)) return startElement.firstChild;
  127. else startElement = startElement.firstChild;
  128. }
  129. return null;
  130. }

QingJ © 2025

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