Beibei.js

IMPORTANT: This function requires your script to have loaded jQuery.

Este script não deve ser instalado diretamente. Este script é uma biblioteca de outros scripts para incluir com o diretório meta // @require https://update.greasyfork.org/scripts/448161/1362731/Beibeijs.js

  1. // ==UserScript==
  2. // @name beibei.js
  3. // @namespace https://github.com/iibeibei
  4. // @version 0.0.7
  5. // @description IMPORTANT: This function requires your script to have loaded jQuery.
  6. // @author Beibei
  7. // @license GPLv3
  8. // @match *://*/*
  9. // ==/UserScript==
  10.  
  11. /**
  12. * @description: 一个实用程序函数,用于 Greasemonkey 脚本, 检测和处理 AJAXed 内容
  13. * @param {*} selector_txt 元素选择器
  14. * @param {*} active_host 激活的域名
  15. * @param {*} active_url 激活的页面URL
  16. * @param {*} b_wait_once 是否只扫描一次
  17. * @param {*} iframe_selector 是否扫描Frame框架
  18. * @param {*} action_function 找到元素时运行的方法,传送 node, selector_txt, active_host, active_url 四个变量
  19. */
  20. function waitForKeyElements(selector_txt, active_host, active_url, b_wait_once, iframe_selector, js_code, action_function) {
  21. if (active_host != '*' && document.domain.split('.').slice(-2).join('.') != active_host) return;
  22.  
  23. var active_url_type = false;
  24. if (typeof active_url == 'object') {
  25. for (let index = 0; index < active_url.length; index++) {
  26. if (window.location.href.indexOf(active_url[index]) > -1) {
  27. active_url_type = true;
  28. break;
  29. }
  30. }
  31. } else if (typeof active_url == 'string') {
  32. if (window.location.href.indexOf(active_url) > -1) active_url_type = true;
  33. }
  34.  
  35. if (active_url_type) {
  36. var target_nodes, b_targets_found;
  37. if (iframe_selector) {
  38. target_nodes = $(iframe_selector).contents().find(selector_txt);
  39. } else {
  40. target_nodes = $(selector_txt);
  41. }
  42.  
  43. if (target_nodes && target_nodes.length > 0) {
  44. b_targets_found = true;
  45. target_nodes.each(function () {
  46. var j_this = $(this);
  47. var already_found = j_this.data('alreadyFound') || false;
  48.  
  49. if (!already_found) {
  50. logPrint(`selector_txt > ${selector_txt} active_host > ${active_host} active_url > ${active_url} b_wait_once > ${b_wait_once} iframe_selector > ${iframe_selector}`);
  51. console.log(j_this);
  52.  
  53. var cancel_found = false;
  54. if (typeof action_function == 'object') {
  55. action_function.forEach((element) => {
  56. cancel_found = element(j_this, selector_txt, active_host, active_url, js_code);
  57. });
  58. } else if (typeof action_function == 'function') {
  59. cancel_found = action_function(j_this, selector_txt, active_host, active_url, js_code);
  60. }
  61.  
  62. if (cancel_found) {
  63. b_targets_found = false;
  64. } else {
  65. j_this.data('alreadyFound', true);
  66. }
  67. }
  68. });
  69. } else {
  70. b_targets_found = false;
  71. }
  72.  
  73. var control_obj = waitForKeyElements.control_obj || {};
  74. var control_key = selector_txt.replace(/[^\w]/g, '_');
  75. var time_control = control_obj[control_key];
  76.  
  77. if (b_targets_found && b_wait_once && time_control) {
  78. clearInterval(time_control);
  79. delete control_obj[control_key];
  80. } else {
  81. if (!time_control) {
  82. time_control = setInterval(function () {
  83. waitForKeyElements(selector_txt, active_host, active_url, b_wait_once, iframe_selector, js_code, action_function);
  84. }, 300);
  85. control_obj[control_key] = time_control;
  86. }
  87. }
  88. waitForKeyElements.control_obj = control_obj;
  89. }
  90. }
  91. function makeGetRequest(url, method = 'GET', data = null) {
  92. logPrint(`${method} -> ${url}`);
  93. return new Promise((resolve, reject) => {
  94. GM_xmlhttpRequest({
  95. url: url,
  96. method: method,
  97. data: data,
  98. onload: function (response) {
  99. resolve(response);
  100. },
  101. onerror: function (error) {
  102. reject(error);
  103. },
  104. });
  105. });
  106. }
  107. function logPrint(params) {
  108. var date_time = $.trim(new Date(new Date().setHours(new Date().getHours() + 8)).toISOString().replace('Z', ' ').replace('T', ' '));
  109. var function_name = new Error().stack.split('\n')[2].trim().split(' ')[1];
  110. console.log(`[${date_time}][DEBUG] ${function_name} - ${params}`);
  111. }
  112. function sleep(interval) {
  113. return new Promise((resolve) => {
  114. setTimeout(resolve, interval);
  115. });
  116. }
  117. function loadMenu(menu_ALL, version_url) {
  118. var menu_ID = [];
  119.  
  120. // 如果读取到的值为 null 就写入默认值
  121. for (let i = 0; i < menu_ALL.length; i++) {
  122. if (GM_getValue(menu_ALL[i][0]) == null) {
  123. GM_setValue(menu_ALL[i][0], menu_ALL[i][3]);
  124. }
  125. }
  126.  
  127. registerMenuCommand();
  128.  
  129. // 注册脚本菜单
  130. function registerMenuCommand() {
  131. // 如果菜单ID数组多于菜单数组,说明不是首次添加菜单,需要卸载所有脚本菜单
  132. if (menu_ID.length > menu_ALL.length) {
  133. for (let i = 0; i < menu_ID.length; i++) {
  134. GM_unregisterMenuCommand(menu_ID[i]);
  135. }
  136. }
  137.  
  138. // 循环注册脚本菜单
  139. for (let i = 0; i < menu_ALL.length; i++) {
  140. menu_ALL[i][3] = GM_getValue(menu_ALL[i][0]);
  141. menu_ID[i] = GM_registerMenuCommand(`${menu_ALL[i][3] ? '✅' : '❌'} ${menu_ALL[i][2]}`, function () {
  142. menu_switch(`${menu_ALL[i][0]}`, `${menu_ALL[i][1]}`, `${menu_ALL[i][2]}`, `${menu_ALL[i][3]}`);
  143. });
  144. }
  145.  
  146. // 加入版本信息
  147. menu_ID[menu_ID.length] = GM_registerMenuCommand(`🏁 当前版本 ${GM_info['script']['version']}`, function () {
  148. window.GM_openInTab(version_url, { active: true, insert: true, setParent: true });
  149. });
  150. }
  151.  
  152. //切换选项
  153. function menu_switch(name, ename, cname, value) {
  154. if (value == 'false') {
  155. // 重新注册脚本菜单,刷新网页
  156. GM_setValue(`${name}`, true);
  157. registerMenuCommand();
  158. location.reload();
  159. GM_notification({ text: `「${cname}」已开启\n`, timeout: 3500 });
  160. } else {
  161. // 重新注册脚本菜单,刷新网页
  162. GM_setValue(`${name}`, false);
  163. registerMenuCommand();
  164. location.reload();
  165. GM_notification({ text: `「${cname}」已关闭\n`, timeout: 3500 });
  166. }
  167. // 重新注册脚本菜单
  168. registerMenuCommand();
  169. }
  170. }
  171. /**
  172. * 获取指定的cookie
  173. * @param {String} key cookie的key
  174. * @returns {String}
  175. */
  176. function get_cookie(key) {
  177. const cookie = document.cookie.split(';');
  178. for (let i = 0, len = cookie.length; i < len; i++) {
  179. const cur = cookie[i].split('=');
  180. if (key === cur[0]) {
  181. return cur[1];
  182. }
  183. }
  184.  
  185. return '';
  186. }
  187. function initializationScript() {
  188. var $ = window.$;
  189. var VueCDN = 'https://lib.baomitu.com/vue/3.2.36/vue.global.prod.min.js';
  190. var ElementPlusCDN = 'https://lib.baomitu.com/element-plus/2.2.2/index.full.min.js';
  191. GM_addStyle(GM_getResourceText('element-plus'));
  192. $.getScript(VueCDN, function () {
  193. console.log('[' + VueCDN + '] Vue 加载成功');
  194. $.getScript(ElementPlusCDN, function () {
  195. console.log('[' + ElementPlusCDN + '] ElementPlus 加载成功');
  196. var ElementPlus = unsafeWindow.ElementPlus;
  197. var Vue = unsafeWindow.Vue;
  198. });
  199. });
  200. }