tianteng

各种开车网站的优化

2024/07/23のページです。最新版はこちら。

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
  1. // ==UserScript==
  2. // @name tianteng
  3. // @namespace https://greasyfork.org/xmlspy
  4. // @version 1.7.5
  5. // @description 各种开车网站的优化
  6.  
  7. // @author xmlspy
  8. // @license MIT
  9.  
  10. // @require https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
  11. // @require https://cdn.jsdelivr.net/npm/@adguard/extended-css@2.0.56/dist/extended-css.umd.min.js
  12. // @require https://cdn.jsdelivr.net/npm/jquery-simulate@1.0.2/jquery.simulate.min.js
  13.  
  14.  
  15. // @resource ldbutton https://cdn.jsdelivr.net/gh/loadingio/ldbutton@latest/dist/index.min.css
  16. // @resource ldloader https://cdn.jsdelivr.net/gh/loadingio/ldloader@v1.0.0/dist/ldld.min.css
  17.  
  18. // @include *
  19. // @connect *
  20.  
  21. // @run-at document-start
  22.  
  23. // @grant GM_xmlhttpRequest
  24. // @grant GM.setClipboard
  25. // @grant GM_setClipboard
  26. // @grant GM.xmlhttpRequest
  27. // @grant GM_openInTab
  28. // @grant GM_addStyle
  29. // @grant GM_getResourceText
  30. // @grant GM.getResourceText
  31. // @grant unsafeWindow
  32. // @grant GM_log
  33. // @grant GM_info
  34. // @grant GM_getValue
  35. // @grant GM_setValue
  36. // @grant GM_deleteValue
  37.  
  38.  
  39. // ==/UserScript==
  40.  
  41. /*
  42. 1. 以下开车的网站经常换域名,本程序使用特征识别,不使用网址进行判断,
  43. 即使域名换了也能识别并进入本程序
  44. * skrbt,
  45. * javbus,
  46. * 紳士漫畫,
  47. * JAVLibrary,
  48. * BTSOW,
  49. * 松鼠症倉庫
  50. * 禁漫天堂
  51. 2. javbus,
  52. * 所有页面,搜索按钮后面都添加"粘贴&搜索"按钮,点击后复制剪贴板的内容到搜索框并自动点击搜索按钮
  53. * 所有页面,添加"打开skrbt"的链接
  54. * 所有页面,添加"打开今日新帖"按钮,一键打开老司机福利讨论区的今日新帖,最多30个
  55. * 影片明细页面,添加复制车牌号按钮,删除磁链的onclick事件(否则会执行两次打开磁链事件),添加 在javlibrary中打开
  56. * 论坛明细页面,为每个磁力链后面添加"复制磁链"和"打开磁链"按钮,为每个回复添加"复制所有磁链","打开所有磁链","复制所有磁链(不含点评)"和"打开所有磁链(不含点评) 4个按钮(气死各种课代表)
  57. * 论坛明细页面,调整样式,更紧凑
  58. 3. 松鼠症倉庫,
  59. * 去除点击广告
  60. 4. 紳士漫畫,
  61. * 明细页面,添加搜索框
  62. * 下拉阅读页面,图片由一列改为两列
  63. * 所有页面, 为搜索框后面添加 粘贴&搜索 按钮
  64. 5. JAVLibrary,
  65. * 所有页面,添加 打开skrbt 链接
  66. * 所有页面,添加 粘贴&搜索 按钮
  67. * 所有页面,删除 url重定向
  68. * 详情页面,添加 复制车牌 按钮
  69. * 详情页面,添加 javbus中查询 链接
  70. * 详情页面,删除 名称中的链接,否则很容易误点,又不容易复制文字
  71. 6. BTSOW,
  72. * 所有页面,添加 粘贴&搜索 按钮
  73. * 搜索结果列表页面,每条结果后面添加"复制磁链"和"打开磁链"按钮,不用进入明细页面
  74. 7. skrbt,
  75. * 所有页面,添加 粘贴&搜索 按钮
  76. * 首页,通过别的网站直接访问,比如(https://skrbtqx.top/search?keyword=abp133),会直接跳转到首页.
  77. 解决办法,在别的地方进来之前,先把要查询的关键字保存起来,然后进入到skrbt后获取,赋值到输入框,然后查询.
  78. 如果,在skrbt首页中没有找到保存的关键字,就从剪贴板获取.
  79. 如果,剪贴板没有任何内容,则啥也不做.
  80. * 搜索结果列表页面,每条结果后面添加"复制磁链"和"点击磁链"按钮,不用进入明细页面
  81. 8. 知乎,
  82. * 添加 粘贴&搜索 按钮
  83. 9. 百度,
  84. * 添加 粘贴&搜索 按钮
  85. 10. 禁漫天堂
  86. * 删除广告
  87.  
  88. ====================更新记录
  89. * 2024-7-24 1.7.5
  90. * javbus
  91. * 所有页面,"打开今日新帖"按钮, 增加点击后提示
  92. * 2024-7-22 1.7.4
  93. * javbus
  94. * 更新url
  95. * btsow
  96. * 搜索结果列表页面,每条结果后面添加"复制磁链"和"打开磁链"按钮,不用进入明细页面
  97. * skrbt
  98. * 首页,通过别的网站直接访问,比如(https://skrbtqx.top/search?keyword=abp133),会直接跳转到首页.
  99. 解决办法,在别的地方进来之前,先把要查询的关键字保存起来,然后进入到skrbt后获取,赋值到输入框,然后查询.
  100. 如果,在skrbt首页中没有找到保存的关键字,就从剪贴板获取.
  101. 如果,剪贴板没有任何内容,则啥也不做.
  102. * 2024-7-20 1.6.4
  103. * javbus
  104. * 论坛明细页面,调整样式,更紧凑
  105. * 2024-7-19
  106. * 禁漫天堂
  107. * 删除广告
  108. * 2024-7-18
  109. * javbus
  110. * 所有页面,添加"打开今日新帖"按钮,一键打开老司机福利讨论区的今日新帖,最多30个
  111. * 2024-7-16
  112. * javbus
  113. * 影片明细页面添加 在javlibrary中打开;
  114. * 论坛明细页面,为每个回复添加"复制所有磁链","打开所有磁链","复制所有磁链(不含点评)"和"打开所有磁链(不含点评) 4个按钮
  115. */
  116.  
  117. // https://cdn.jsdelivr.net/gh/loadingio/ldloader@v1.0.0/dist/ldld.min.js
  118. // prettier-ignore
  119. (function(){var ldLoader;ldLoader=function(opt){var this$=this;opt==null&&(opt={});this.opt=import$({activeClass:"running",baseZ:4e3,autoZ:false,className:"",atomic:true},opt);["root","container"].map(function(n){if(opt[n]){return this$[n]=(Array.isArray(opt[n])?opt[n]:[opt[n]]).map(function(it){var ret;ret=typeof it==="string"?document.querySelector(it):it;if(!ret){console.warn("[ldLoader] warning: no node found for "+it)}return ret})}});if(!this.container){this.container=this.root?this.root.map(function(it){return it.parentNode}):[document.body]}if(!this.root){this.root=this.container.map(function(it){var node;node=document.createElement("div");it.appendChild(node);return node})}this.root.map(function(it){it.classList.add.apply(it.classList,(this$.opt.className||"").split(" ").filter(function(it){return it}));it.classList.remove(opt.activeClass);if(opt.inactiveClass){return it.classList.add(opt.inactiveClass)}});this.running=false;this.count=0;return this};ldLoader.prototype=import$(Object.create(Object.prototype),{isOn:function(){return this.running},on:function(delay){delay==null&&(delay=0);return this.toggle(true,delay)},off:function(delay,force){delay==null&&(delay=0);force==null&&(force=false);return this.toggle(false,delay,force)},flash:function(dur,delay){var this$=this;dur==null&&(dur=1e3);delay==null&&(delay=0);return this.toggle(true,delay).then(function(){return this$.toggle(false,dur+delay)})},render:function(){var runid,_,ret,this$=this;if(!(this.running&&this.opt.ctrl&&this.opt.ctrl.step)){return this.render.runid=-1}this.render.runid=runid=Math.random();this.render.start=0;if(this.opt.ctrl.init){this.root.map(function(it){return this$.opt.ctrl.init.call(it)})}_=function(t){if(!this$.render.start){this$.render.start=t}this$.root.map(function(it){return this$.opt.ctrl.step.call(it,t-this$.render.start)});if(this$.render.runid===runid){return requestAnimationFrame(function(it){return _(it)})}else if(this$.opt.ctrl.done){return this$.root.map(function(it){return this$.opt.ctrl.done.call(it,t-this$.render.start)})}};return ret=requestAnimationFrame(function(it){return _(it)})},toggle:function(v,delay,force){var d,this$=this;delay==null&&(delay=0);force==null&&(force=false);d=!(v!=null)?this.root[0].classList.contains(this.opt.activeClass)?-1:1:v?1:-1;if(delay){return new Promise(function(res,rej){if(d>0){return this$.toggle(v).then(function(){return setTimeout(function(){return res()},delay)})}else{return setTimeout(function(){return this$.toggle(v).then(function(){return res()})},delay)}})}return new Promise(function(res,rej){var running,z,ref$,idx;this$.count+=d;if(!force&&!this$.opt.atomic&&(this$.count>=2||this$.count===1&&d<0)){return res()}this$.root.map(function(it){it.classList.toggle(this$.opt.activeClass,d>0);if(this$.opt.inactiveClass){return it.classList.toggle(this$.opt.inactiveClass,d<0)}});this$.running=running=this$.root[0].classList.contains(this$.opt.activeClass);if(this$.opt.ctrl){this$.render()}if(!this$.opt.autoZ){return res()}if(running){this$.z=z=((ref$=ldLoader.zstack)[ref$.length-1]||0)+this$.opt.baseZ;this$.root.map(function(it){return it.style.zIndex=z});ldLoader.zstack.push(z)}else{if((idx=ldLoader.zstack.indexOf(this$.z))<0){return res()}this$.root.map(function(it){return it.style.zIndex=""});ldLoader.zstack.splice(idx,1)}return res()})}});import$(ldLoader,{zstack:[]});return window.ldLoader=ldLoader})();function import$(obj,src){var own={}.hasOwnProperty;for(var key in src)if(own.call(src,key))obj[key]=src[key];return obj}
  120.  
  121. (function () {
  122. "use strict";
  123. // #region 开头
  124.  
  125. /**
  126. * skrbt
  127. */
  128. const skrbtDomain = "skrbtqx";
  129. const skrbtHost = skrbtDomain + ".top";
  130. const skrbtUrl = "https://" + skrbtHost;
  131.  
  132. /**
  133. * javbus
  134. */
  135. const javbusDomain = "fanbus";
  136. const javabusUrl = `https://www.${javbusDomain}.help`;
  137.  
  138. /**
  139. * javLibrary
  140. */
  141. var javLibDomain = "y78k";
  142. var javLibUrl = "https://www." + javLibDomain + ".com";
  143. let javLibRegx = "(" + javLibDomain + "|javlib|javlibrary)";
  144.  
  145. const enableDebug = true;
  146. let seq = 0;
  147. // function (){}
  148.  
  149. // // 获取 HTMLElement 构造函数
  150. // const HTMLElementConstructor = HTMLElement;
  151.  
  152. // // 创建一个代理对象来拦截 HTMLElement 的构造函数
  153. // const HTMLElementProxy = new Proxy(HTMLElementConstructor, {
  154. // construct(target, args, newTarget) {
  155. // console.log("Creating a new HTMLElement instance");
  156. // // 创建一个新的 HTMLElement 实例
  157. // const instance = new target(...args);
  158. // // 返回一个新的代理对象来拦截实例的属性和方法
  159. // return new Proxy(instance, {
  160. // get(target, prop, receiver) {
  161. // console.log(`Accessing property: ${prop}`);
  162. // return Reflect.get(target, prop, receiver);
  163. // },
  164. // set(target, prop, value, receiver) {
  165. // console.log(`Setting property: ${prop} to ${value}`);
  166. // return Reflect.set(target, prop, value, receiver);
  167. // },
  168. // has(target, prop) {
  169. // console.log(`Checking if property exists: ${prop}`);
  170. // return Reflect.has(target, prop);
  171. // },
  172. // deleteProperty(target, prop) {
  173. // console.log(`Deleting property: ${prop}`);
  174. // return Reflect.deleteProperty(target, prop);
  175. // },
  176. // ownKeys(target) {
  177. // console.log(`Enumerating properties`);
  178. // return Reflect.ownKeys(target);
  179. // },
  180. // getOwnPropertyDescriptor(target, prop) {
  181. // console.log(`Getting property descriptor for: ${prop}`);
  182. // return Reflect.getOwnPropertyDescriptor(target, prop);
  183. // },
  184. // defineProperty(target, prop, descriptor) {
  185. // console.log(`Defining property: ${prop}`);
  186. // return Reflect.defineProperty(target, prop, descriptor);
  187. // },
  188. // });
  189. // },
  190. // });
  191.  
  192. // // 替换全局的 HTMLElement 构造函数
  193. // Object.defineProperty(window, "HTMLElement", {
  194. // value: HTMLElementProxy,
  195. // writable: false,
  196. // configurable: false,
  197. // });
  198.  
  199. // // 测试
  200. // const div = document.createElement("div");
  201. // div.innerHTML = "Hello, World!";
  202. // console.log(div.innerHTML);
  203. // div.innerHTML = "Hello, Proxy!";
  204. // console.log(div.innerHTML);
  205. /////////////////////////////////////////////////////////////////////////////
  206. // 事件拦截
  207. /////////////////////////////////////////////////////////////////////////////
  208. debug(document.querySelector("title"));
  209.  
  210. //松鼠症倉庫 地址发布页 https://ahrilist.top/
  211.  
  212. const ep = EventTarget.prototype;
  213.  
  214. if (!ep.addEventListenerOriginal) {
  215. ep.addEventListenerOriginal = ep.addEventListener;
  216. ep.addEventListener = function (type, callback, options) {
  217. // if (/ahri8\.top/.test(window.location.href)) {
  218. // debug(`添加事件监听器:target: ${this} type: ${type} callback: ${callback} options: ${options}`);
  219. if (this) {
  220. /////////////////////////////////////////////////////////////////////////////
  221. // 松鼠症倉庫
  222. /////////////////////////////////////////////////////////////////////////////
  223. if (
  224. this.className &&
  225. this.className.includes &&
  226. this.className.includes("apo")
  227. ) {
  228. debug("禁止点击广告", "松鼠症倉庫");
  229. return;
  230. }
  231. // }
  232. this.allListeners = this.allListeners || [];
  233. this.allListeners.push({ type, callback, options });
  234. // this.addEventListenerOriginal(type, callback, options);
  235. this.addEventListenerOriginal.apply(this, arguments);
  236. } else {
  237. debug(
  238. `[this] is bad. type: ${type} callback: ${callback} options: ${options}`,
  239. "addEventListenerHook"
  240. );
  241. }
  242. };
  243. }
  244. if (!ep.removeEventListenerOriginal) {
  245. ep.removeEventListenerOriginal = ep.removeEventListener;
  246. ep.removeEventListener = function (type, callback, options) {
  247. if (this) {
  248. this.removeEventListenerOriginal.apply(this, arguments);
  249. this.allListeners = this.allListeners || [];
  250. const index = this.allListeners.indexOf({ type, callback, options });
  251. if (index != -1) {
  252. this.allListeners.splice(index, 1);
  253. }
  254. } else {
  255. debug(
  256. `[this] is bad. type: ${type} callback: ${callback} options: ${options}`,
  257. "removeEventListenerHook"
  258. );
  259. }
  260. };
  261. }
  262.  
  263. /////////////////////////////////////////////////////////////////////////////
  264. // 节点变化监控
  265. /////////////////////////////////////////////////////////////////////////////
  266. new MutationObserver(function (mutationsList, observer) {
  267. 禁漫天堂();
  268. }).observe(document, {
  269. childList: true,
  270. subtree: true,
  271. // attributes: true,
  272. //attributeFilter: [],
  273. // attributeOldValue: true,
  274. // characterData: false,
  275. // characterDataOldValue: false,
  276. });
  277.  
  278. ///////////////////////////////////////////////////////////////////////////
  279. // 禁漫天堂 发布页: https://jmcomicltd.xyz/
  280. //
  281. // 國際通用網域 不支援日本/韓國路線
  282. // 18comic.vip
  283. // 18comic.org
  284. // 東南亞路線建議使用
  285. // jmcomic.me
  286. // jmcomic1.me
  287. //
  288. // =內地網域= 請使用Chrome瀏覽器開啟
  289. // 18-comicblade.vip
  290. //
  291. // 分流1
  292. // 18-comic-minions.club
  293. //
  294. // 分流2
  295. // https://18comic-erdtree.org
  296. //
  297. // APP軟件下載
  298. // jm365.work/ZNPJam
  299. //
  300. // 如果地址無法打開,歡迎發送郵件告知
  301. // re18comic@gmail.com
  302. //
  303. // 或是直接到DC群找管理員處理問題
  304. // discord.gg/V74p7HM
  305. ///////////////////////////////////////////////////////////////////////////
  306. function 禁漫天堂() {
  307. execute("禁漫天堂", $(`head>title`)[0].text.endsWith("禁漫天堂"), () => {
  308. // 删除广告
  309. $(".top-nav, .div-bf-pv").remove();
  310. $("#Comic_Top_Nav").css("top", "-1px");
  311. $("div.e8c78e-4_b").remove();
  312.  
  313. if (location.pathname === "/albums") {
  314. const childNodes = document.querySelector(
  315. "#wrapper > div.container"
  316. ).childNodes;
  317. var forEach = Array.prototype.forEach;
  318.  
  319. forEach.call(childNodes, function (node) {
  320. if (
  321. node.nodeName === "#text" &&
  322. node.nodeValue.includes("中間廣告")
  323. ) {
  324. node.nodeValue = "";
  325. }
  326. });
  327. }
  328. });
  329. }
  330. // #endregion
  331. // execute(()=>{},()=>{});
  332.  
  333. // #region jquery.ready
  334. ///////////////////////////////////////////////////////////////////////////
  335. // jquery.ready
  336. ///////////////////////////////////////////////////////////////////////////
  337. $(function () {
  338. ///////////////////////////////////////////////////////////////////////////
  339. // oschina
  340. ///////////////////////////////////////////////////////////////////////////
  341. execute("开源中国", /oschina\.net/, () => {
  342. debug("修改首页某些链接无法中键点击问题.", "开源中国");
  343. $(`[data-href]`).each(function () {
  344. const $this = $(this);
  345. const href = $this.attr("data-href");
  346. const classCss = $this.attr("class");
  347. const title = $this.attr("title");
  348. const innerHtml = this.innerHTML;
  349.  
  350. const html = `<a target="_blank" title="${title}" href="${href}" class="${classCss}">${innerHtml}</a>`;
  351. $this.replaceWith(html);
  352. });
  353.  
  354. debug("删除url中的重定向.", "开源中国");
  355. $('a[href*="/action/GoToLink?url"]').each(function (index) {
  356. // https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fcode.visualstudio.com%2Fupdates%2Fv1_91
  357. var url = getQueryVariable(this, "url");
  358. this.href = decodeURIComponent(url);
  359. });
  360. });
  361. ///////////////////////////////////////////////////////////////////////////
  362. // gitee.com
  363. ///////////////////////////////////////////////////////////////////////////
  364. execute("gitee", /gitee\.com/, () => {
  365. debug("删除url中的重定向.", "gitee");
  366. $('a[href*="/link?target"]').each(function (index) {
  367. var url = getQueryVariable(this, "target");
  368. this.href = decodeURIComponent(url);
  369. });
  370. });
  371.  
  372. ///////////////////////////////////////////////////////////////////////////
  373. // 紳士漫畫 永久域名: wnacg.com 紳士漫畫永久地址發佈頁: wnacg.date
  374. ///////////////////////////////////////////////////////////////////////////
  375. execute("紳士漫畫", $('head>title:contains("紳士漫畫")'), () => {
  376. if (location.href.includes("photos-index-aid")) {
  377. debug("明细页面添加搜索框", "紳士漫畫");
  378. const searchInput = `
  379. <div class="search" style="float:right;">
  380. <form id="album_search q-form" action="/search/" method="get" _lpchecked="1">
  381. <div class="input-append" id="q-input">
  382. <input type="text" class="search-query ui-autocomplete-input tips"
  383. name="q" value="" title="搜索漫畫" autocomplete="off"
  384. role="textbox" aria-autocomplete="list" aria-haspopup="true">
  385. <input style="display:none" type="radio" name="f" value="_all" checked="">
  386. <input style="display:none" name="s" value="create_time_DESC">
  387. <input style="display:none" name="syn" value="yes">
  388. <button type="" name=""></button>
  389. </div>
  390. </form>
  391. </div>
  392. `;
  393. $("#bodywrap").prepend(searchInput);
  394. }
  395.  
  396. if (location.href.includes("photos-slide-aid")) {
  397. debug("下拉阅读页面,图片由一列改为两列", "紳士漫畫");
  398. const nodeToObserve = document.querySelector("#img_list");
  399. $(nodeToObserve).css({
  400. width: "100%",
  401. display: "flex",
  402. "flex-wrap": "wrap",
  403. "justify-content": "flex-start",
  404. "overflow-x": "hidden",
  405. });
  406. const imgWidth = document.documentElement.clientWidth / 2 - 10;
  407. const imgHeight = document.documentElement.clientHeight - 50;
  408. new MutationObserver((mutations, observer) => {
  409. $("#img_list>div").css({
  410. flex: "1",
  411. "background-color": "#cacaca",
  412. margin: "0 5px 5px 0",
  413. width: "calc((100% - 10px) / 2)",
  414. "min-width": "calc((100% - 10px) / 2)",
  415. "max-width": "calc((100% - 10px) / 2)",
  416. });
  417. $("#img_list>div>img").on("load", (e) => {
  418. drawImage(e.target, imgWidth, imgHeight);
  419. });
  420. }).observe(nodeToObserve, { childList: true });
  421. }
  422.  
  423. if ($("input.search-query").length > 0) {
  424. debug("为搜索框后面添加 粘贴&搜索 按钮", "紳士漫畫");
  425. const $pasteAndSearchButton = $(
  426. `<button style="float:right;height:30px;">粘贴&amp;搜索</button>`
  427. );
  428. $("#bodywrap").prepend($pasteAndSearchButton);
  429. $pasteAndSearchButton.on("click", () => {
  430. navigator.clipboard.readText().then((clipText) => {
  431. if (clipText != null && $.trim(clipText) != "") {
  432. $("[name=q]").val($.trim(clipText));
  433. $("#q-input > button").click();
  434. }
  435. });
  436. });
  437. }
  438. });
  439.  
  440. ///////////////////////////////////////////////////////////////////////////
  441. // JAVLibrary github.com/javlibcom 会有最新的网址
  442. // 我们的入口 javlib.com zlibz.com link@zlibz.com
  443. ///////////////////////////////////////////////////////////////////////////
  444. execute("JAVLibrary", $('head>title:contains("JAVLibrary")'), () => {
  445. // ---- 所有页面
  446.  
  447. // 删除广告
  448. $(".socialmedia,#bottombanner13,#topbanner11,#sidebanner11").remove();
  449. $("#leftmenu>div>ul:nth-child(2)>li:nth-child(2)").remove();
  450.  
  451. // 调节UI
  452. $("#content").css("padding-top", "10px");
  453. $("#toplogo").css("height", "50px");
  454. $("#toplogo").find('img[src*="logo-top"]').attr("height", "40");
  455.  
  456. // 添加 粘贴&搜索 按钮
  457. const styleMap = {};
  458. $("#idsearchbutton")[0] &&
  459. $("#idsearchbutton")[0]
  460. .computedStyleMap()
  461. .forEach((value, key) => {
  462. styleMap[key] = value;
  463. });
  464. const $pasteAndSearchButton = $(
  465. `<input type="button" value="粘贴&搜索" id="pasteAndSearch"></input>`
  466. );
  467. $pasteAndSearchButton.css(styleMap);
  468. $pasteAndSearchButton.click(() => {
  469. navigator.clipboard.readText().then((clipText) => {
  470. if (clipText != null && $.trim(clipText) != "") {
  471. $("#idsearchbox").val(clipText);
  472. $("#idsearchbutton").click();
  473. }
  474. });
  475. });
  476. $("#idsearchbutton").parent().append($pasteAndSearchButton);
  477.  
  478. // 添加 打开skrbt 连接
  479. $(".advsearch").append(
  480. `&nbsp;&nbsp;
  481. <a href="${skrbtUrl}"
  482. target="_blank"
  483. class="tianteng-search-anchor"
  484. title="打开后自动搜索剪贴板中的内容">打开skrbt</a>`
  485. );
  486.  
  487. // 恢复原始url,删除重定向
  488. $.each($("a[href^='redirect.php?url']"), function (index, a) {
  489. var url = getQueryVariable(a, "url");
  490. a.href = decodeURIComponent(url);
  491. if (!a.href.startsWith("https")) {
  492. a.href = a.href.replace("http", "https");
  493. }
  494. a.text = a.text + " " + a.href + " ";
  495. if (a.href.includes("yimuhe")) {
  496. $(a)
  497. .parentsUntil("tr")
  498. .closest(".t")
  499. .css("background-color", "#6B6C83");
  500. a.style = "font-size:20px;";
  501. } else {
  502. a.style = "font-size:20px;";
  503. }
  504. });
  505.  
  506. // ---- 详情页面
  507.  
  508. if (/.*\?v=.*/.test(location.href)) {
  509. // 添加 复制车牌 按钮
  510. let chePai = document.querySelector(
  511. "#video_id > table > tbody > tr > td.text"
  512. ).innerText;
  513. let toAppendElement = document.querySelector(
  514. "#video_id > table > tbody > tr > td.text"
  515. );
  516. appendCopyButton(chePai, toAppendElement);
  517.  
  518. // 添加 javbus中查询 链接
  519. let trTag = document.querySelector("#video_id > table > tbody > tr");
  520. let javdbQueryId = "javdbQueryId";
  521. trTag.innerHTML = [
  522. trTag.innerHTML,
  523. '<td><a id="',
  524. javdbQueryId,
  525. '"href="',
  526. javabusUrl,
  527. "/",
  528. chePai,
  529. '">javbus中查询</a></td>',
  530. ].join("");
  531.  
  532. // 添加 用SkrBt搜索 链接
  533. $(trTag).append(`
  534. <td>
  535. <a
  536. class="tianteng-search-anchor"
  537. href="${skrbtUrl}/search?keyword=${chePai}"
  538. data-tianteng-keyword="${chePai}">
  539. SkrBt搜索
  540. </a>
  541. </td>
  542. `);
  543.  
  544. // 删除名称中的链接,否则很容易误点,又不容易复制文字
  545. const videoTitleNode = document.querySelector("#video_title > h3 > a");
  546. if (videoTitleNode) {
  547. const videoTitle = videoTitleNode.getInnerHTML();
  548. videoTitleNode.parentNode.innerText = videoTitle;
  549. }
  550. }
  551.  
  552. //
  553. $(".tianteng-search-anchor").on("click mouseup", function () {
  554. const keyword = $(this).data("tiantengKeyword");
  555. if (keyword) {
  556. GM_setValue("tiantengKeyword", keyword);
  557. }
  558. });
  559. });
  560.  
  561. ///////////////////////////////////////////////////////////////////////////
  562. // javbus 永久域名:https://www.javbus.com 防屏蔽地址:https://www.fanbus.help
  563. // 防屏蔽地址:https://www.javsee.help 防屏蔽地址:https://www.buscdn.help
  564. ///////////////////////////////////////////////////////////////////////////
  565. execute(
  566. "javbus",
  567. [
  568. $('head>title:contains("JavBus")'),
  569. // /genre/hd , /genre/sub
  570. $("body > nav > div > div.navbar-header.mh50 > a > img[alt='JavBus']"),
  571. // 论坛
  572. "#toptb.jav-nav",
  573. ],
  574. () => {
  575. // #region 所有页面
  576. debug("添加 粘贴&搜索 按钮", "javbus");
  577. const searchButton = $(
  578. "button[onclick=\"searchs('search-input')\"]:first"
  579. );
  580. const searchInput = $("#search-input:first");
  581. addPasteAndSearchButton(searchButton, searchInput);
  582.  
  583. // 调整样式
  584. $(".nav>li>a").attr("style", "padding-left:8px;padding-right:8px;");
  585.  
  586. debug("添加 打开skrbt 链接", "javbus");
  587. //添加skrbt链接
  588. $(".nav-title.nav-inactive:last,ul.nav.navbar-nav:first").append(`
  589. <li class="hidden-md hidden-sm">
  590. <a href="${skrbtUrl}" target="_blank">打开skrbt</a>
  591. </li>
  592. `);
  593.  
  594. debug("添加 打开今日新帖 按钮", "javbus");
  595.  
  596. // function showTip(message) {
  597. // let tipBox = $("#tiantengTipBox");
  598. // if (tipBox.length === 0) {
  599. // const html = `
  600. // <div class="alert alert-info alert-dismissable alert-common text-center"
  601. // style="position:relative;">
  602. // <button type="button"
  603. // class="close"
  604. // style="position:absolute; right:8px; top:3px;"
  605. // data-dismiss="alert">×</button>
  606. // <strong id="tiantengTipBox"></strong>
  607. // </div>`;
  608. // // $("div.container-fluid>div.row").prepend(html);
  609. // $('nav').append(html);
  610. // $('#toptb').after(html);
  611. // }
  612. // tipBox = $("#tiantengTipBox");
  613. // tipBox.text(message);
  614. // }
  615.  
  616. // showTip("xxxxxxxxxxxxxxxxxx");
  617. let todayNewButton = $(
  618. `<button id="tiantengNewButton"
  619. class="jav-button btn btn-default ld-ext-right"
  620. title="打开老司机福利讨论区的今日新帖,最多30个"
  621. style="margin-top:7px;">
  622.  
  623. <span>打开今日新帖</span>
  624. <div class="ld ldld bare"
  625. style="width:1em;height:1em">
  626. </div>
  627. </button>`
  628. );
  629. const ldbuttonCss = GM_getResourceText("ldbutton");
  630. GM_addStyle(ldbuttonCss);
  631. const ldloaderCss = GM_getResourceText("ldloader");
  632. GM_addStyle(ldloaderCss);
  633.  
  634. // prettier-ignore
  635. $(".nav-title.nav-inactive:last,ul.nav.navbar-nav:first")
  636. .append(todayNewButton);
  637.  
  638. let ldloader = new ldLoader({ root: "#tiantengNewButton" });
  639. todayNewButton.click(function () {
  640. if (ldloader.running) {
  641. debug("正在加载数据,忽略点击...", "javbus");
  642. return;
  643. }
  644. ldloader.toggle();
  645. todayNewButton.attr("disabled", "true");
  646.  
  647. const origin = location.origin;
  648. // 老司机福利讨论区
  649. const talkUrl = `${origin}/forum/forum.php?mod=forumdisplay&fid=2&filter=author&orderby=dateline&dateline=86400`;
  650. // 求福利带带我
  651. const askUrl = `${origin}/forum/forum.php?mod=forumdisplay&fid=36&filter=author&orderby=dateline&dateline=86400`;
  652. const now = new Date();
  653. // prettier-ignore
  654. const today = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
  655.  
  656. async function getPostData(url, date, pageNum) {
  657. // pageNum= pageNum ?? 1;
  658. // url = url+'&page='+'pageNum'
  659. const r = await GM.xmlHttpRequest({
  660. url: url,
  661. headers: {
  662. Accept: `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7`,
  663. "Accept-Encoding": "gzip, deflate, br",
  664. "Accept-Language": "zh-CN,zh;q=0.9",
  665. "Cache-Control": "max-age=0",
  666. },
  667. }).catch((e) => {
  668. ldloader.off();
  669. todayNewButton.attr("disabled", false);
  670. console.error(e);
  671. debug(e,'javbus');
  672. alert('获取数据出现错误!!');
  673. });
  674. const data = $(r.responseXML);
  675. const result = [];
  676. $(".post_inforight", data).each(function (index) {
  677. const date = $("span.dateline>span", $(this)).attr("title");
  678. if (date === today) {
  679. let postUrl = $("a.s", $(this)).attr("href");
  680. result.push(`${origin}/forum/${postUrl}`);
  681. }
  682. });
  683. return result;
  684. }
  685. getPostData(talkUrl).then(function (urlArray) {
  686. if (urlArray.length === 0) {
  687. debug("没有新的帖子", "javbus");
  688. alert('没有新的帖子.');
  689. }
  690. $(urlArray).each(function () {
  691. GM_openInTab(this, true);
  692. });
  693. ldloader.off();
  694. todayNewButton.attr("disabled", false);
  695. });
  696. });
  697. // #endregion
  698. // #region 明细页面
  699. let chePaiNode = document.querySelector(
  700. "body > div.container > div.row.movie > div.col-md-3.info > p:nth-child(1) > span:nth-child(2)"
  701. );
  702.  
  703. if (chePaiNode) {
  704. debug("添加复制车牌号按钮", "javbus");
  705. const chePai = chePaiNode.innerText.trim();
  706. const toAppendElement = document.querySelector(
  707. "body > div.container > div.row.movie > div.col-md-3.info > p:nth-child(1)"
  708. );
  709. appendCopyButton(
  710. chePai,
  711. toAppendElement,
  712. (copyButton) =>
  713. (copyButton.className = "jav-button btn btn-default")
  714. );
  715.  
  716. debug("删除磁力链接中的onclick事件", "javbus");
  717. setInterval(() => $("#magnet-table td").removeAttr("onclick"), 1000);
  718.  
  719. debug("添加 在javlibrary中打开", "javabus");
  720. //https://www.y78k.com/cn/vl_searchbyid.php?keyword=SUJI-241
  721. const javLibLink = `<a href="${javLibUrl}/cn/vl_searchbyid.php?keyword=${chePai}">在javlib中打开</a>`;
  722. $(toAppendElement).append(javLibLink);
  723. }
  724. // #endregion
  725.  
  726. // #region 论坛明细页面
  727. if (location.href.includes("mod=viewthread")) {
  728. // #region 调整样式
  729. debug("调整样式", "论坛明细页面");
  730. GM_addStyle(`
  731. #p_btn {
  732. padding:0;
  733. }
  734. .mtw {
  735. margin-top: 0px !important;
  736. }
  737. .mbm {
  738. margin-bottom: 10px !important;
  739. }
  740. .pi {
  741. overflow: hidden;
  742. margin-bottom: 0;
  743. padding: 0;
  744. height: 16px;
  745. border-bottom: 1px dashed #CDCDCD;
  746. }
  747. .pct {
  748. padding-bottom: 0;
  749. }
  750. .t_fsz {
  751. min-height: auto;
  752. }
  753. .nthread_postinfo {
  754. margin: 0 -16px;
  755. border-top: 10px solid #f5f5f5;
  756. padding: 10px 40px;
  757. }
  758. .pcb .cm .psth {
  759. margin-bottom: 0px;
  760. }
  761. .pcb .psth {
  762. width: 100%;
  763. font-size: 17px !important;
  764. line-height: 28px;
  765. font-weight: normal;
  766. color: #454545;
  767. background: none;
  768. border-bottom: 1px solid #CECECE;
  769. padding: 0;
  770. margin: 10px 0 0;
  771. }
  772. .pstl {
  773. clear: left;
  774. padding: 0em 0;
  775. }
  776. hin .pob {
  777. padding-bottom: 0px !important;
  778. }
  779. .plc{padding-top:14px}
  780. `);
  781. // #endregion
  782.  
  783. // #region 为磁链添加按钮
  784. debug("为磁链添加按钮", "论坛明细页面");
  785. function toAlienMagnet(magnet, alien) {
  786. alien = alien ? alien : "-";
  787. let part1 = magnet.slice(0, 21);
  788. let part2 = magnet.slice(21);
  789. return `${part1}${alien}${part2}`;
  790. }
  791. function toNormalMagnet(magnet, alien) {
  792. alien = alien ? alien : "-";
  793. return magnet.replace(alien, "");
  794. }
  795. function getMagnetRegExp(alien) {
  796. if (alien) {
  797. return new RegExp(
  798. `(?:magnet:\\?xt=urn:btih:)?(?:(?:[0-9a-f]{1}${alien}[0-9a-f]{39})|(?:[2-7a-zA-Z]${alien}[2-7a-zA-Z]{31}))`,
  799. "gim"
  800. );
  801. } else {
  802. return /(?:magnet:\?xt=urn:btih:)?(?:[0-9a-fA-F]{40}|[2-7a-zA-Z]{32})/gim;
  803. }
  804. }
  805. function completeMagnet(magnet) {
  806. if (!magnet) {
  807. return magnet;
  808. }
  809. if (magnet.length === 32 || magnet.length === 40) {
  810. return `magnet:?xt=urn:btih:${magnet}`;
  811. }
  812. return magnet;
  813. }
  814.  
  815. // 所有按钮的点击事件处理
  816. $(document).on(
  817. "click",
  818. 'button[class*="tianteng-button"]',
  819. function (e) {
  820. let button = $(e.target);
  821. let buttonType = button.data("tiantengButton");
  822. // 复制磁链
  823. if (buttonType === "copy") {
  824. let magnet = button.data("tiantengMagnet");
  825. GM.setClipboard(toNormalMagnet(magnet), "text");
  826. return;
  827. }
  828. // 打开磁链
  829. if (buttonType === "click") {
  830. let magnet = button.data("tiantengMagnet");
  831. setTimeout(() => window.open(toNormalMagnet(magnet)), 500);
  832. return;
  833. }
  834. // 复制所有磁链
  835. if (buttonType === "copyAll") {
  836. let postId = button.data("tiantengPostId");
  837. let magnets = "";
  838. $(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(
  839. function () {
  840. let magnet = $(this).data("tiantengMagnet");
  841. magnets = magnets + toNormalMagnet(magnet) + "\n";
  842. }
  843. );
  844. GM.setClipboard(magnets, "text");
  845. return;
  846. }
  847. // 打开所有磁链
  848. if (buttonType === "clickAll") {
  849. let postId = button.data("tiantengPostId");
  850. $(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(
  851. function () {
  852. let magnet = $(this).data("tiantengMagnet");
  853. magnet = toNormalMagnet(magnet);
  854. setTimeout(() => window.open(toNormalMagnet(magnet)), 500);
  855. }
  856. );
  857. return;
  858. }
  859. // 复制所有磁链(不含点评)
  860. if (buttonType === "copyAllNot") {
  861. let postId = button.data("tiantengPostMessageId");
  862. let magnets = "";
  863. $(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(
  864. function () {
  865. let magnet = $(this).data("tiantengMagnet");
  866. magnets = magnets + toNormalMagnet(magnet) + "\n";
  867. }
  868. );
  869. GM.setClipboard(magnets, "text");
  870. return;
  871. }
  872. // 打开所有磁链(不含点评)
  873. if (buttonType === "clickAllNot") {
  874. let postId = button.data("tiantengPostMessageId");
  875. $(`[data-tianteng-button="copy"]`, $(`#${postId}`)).each(
  876. function () {
  877. let magnet = $(this).data("tiantengMagnet");
  878. magnet = toNormalMagnet(magnet);
  879. setTimeout(() => window.open(toNormalMagnet(magnet)), 500);
  880. }
  881. );
  882. return;
  883. }
  884. }
  885. ); // end 所有按钮事件
  886.  
  887. let magnetRegExp = getMagnetRegExp();
  888.  
  889. // 先处理a标签元素中的磁链,加上标记
  890. $(`div[id^="post_"] a[href^="magnet:?xt=urn:btih:"]`).each(
  891. function () {
  892. let magnetAlien = completeMagnet($(this).attr("href"));
  893. magnetAlien = toAlienMagnet(magnetAlien);
  894. // $(this).data('tiantengStatus','@');
  895. let html = this.outerHTML.replace(
  896. magnetRegExp,
  897. (match, offset, str) =>
  898. toAlienMagnet(completeMagnet(match), "@")
  899. );
  900.  
  901. html = html.replace("href", `data-tianteng-status="ok" href`);
  902.  
  903. html = `${html}
  904. <button style="margin:0;padding:3px;"
  905. class="jav-button tianteng-button"
  906. data-tianteng-button="copy"
  907. data-tianteng-magnet="${magnetAlien}"
  908. type="button">复制磁链
  909. </button>
  910. <button style="margin:0;padding:3px;"
  911. class="jav-button tianteng-button"
  912. data-tianteng-button="click"
  913. data-tianteng-magnet="${magnetAlien}"
  914. type="button">打开磁链
  915. </button>`;
  916. this.outerHTML = html;
  917. }
  918. );
  919. // 再处理所有文本节点,加上标记
  920. $('div[id^="post_"]').each(function () {
  921. const treeWalker = document.createTreeWalker(
  922. this,
  923. NodeFilter.SHOW_TEXT
  924. );
  925.  
  926. while (treeWalker.nextNode()) {
  927. const node = treeWalker.currentNode;
  928. if (node.nodeValue && magnetRegExp.test(node.nodeValue)) {
  929. node.nodeValue = node.nodeValue.replace(
  930. magnetRegExp,
  931. (match, offset, str) =>
  932. toAlienMagnet(completeMagnet(match), "tianteng")
  933. );
  934. }
  935. }
  936. });
  937.  
  938. // 去除标记
  939. $('div[id^="post_"]').each(function () {
  940. // 去除文本节点中磁链的标记
  941. let magnetAlienRegExp = getMagnetRegExp("tianteng");
  942. let html = this.innerHTML;
  943. html = html.replace(magnetAlienRegExp, function (match) {
  944. match = toNormalMagnet(match, "tianteng");
  945. let magnetAlien = toAlienMagnet(match);
  946. return `
  947. <a href="${match}" data-tianteng-status="ok">${match}</a>
  948. <button style="margin:0;padding:3px;"
  949. class="jav-button tianteng-button"
  950. data-tianteng-button="copy"
  951. data-tianteng-magnet="${magnetAlien}"
  952. type="button">复制磁链
  953. </button>
  954. <button style="margin:0;padding:3px;"
  955. class="jav-button tianteng-button"
  956. data-tianteng-button="click"
  957. data-tianteng-magnet="${magnetAlien}"
  958. type="button">打开磁链
  959. </button>`;
  960. });
  961. // 去除A标签中磁链的标记
  962. magnetAlienRegExp = getMagnetRegExp("@");
  963. html = html.replace(magnetAlienRegExp, function (match) {
  964. return toNormalMagnet(match, "@");
  965. });
  966.  
  967. this.innerHTML = html;
  968.  
  969. const postId = $(this).attr("id");
  970. const id = postId.replace("post_", "");
  971. const postMessageId = `postmessage_${id}`;
  972.  
  973. // 添加 4个 "所有" 按钮,在每个回复的开头和结尾,共8个
  974. if (
  975. $(`[data-tianteng-button="copy"]`, $(`#${postId}`)).length > 0
  976. ) {
  977. let allButtonHtml = `
  978. <button style="margin:0;padding:5px;"
  979. class="jav-button tianteng-button"
  980. data-tianteng-button="copyAll"
  981. data-tianteng-post-id="${postId}"
  982. data-tianteng-post-message-id="${postMessageId}"
  983. type="button">复制所有磁链
  984. </button>
  985. <button style="margin:0;padding:5px;"
  986. class="jav-button tianteng-button"
  987. data-tianteng-button="clickAll"
  988. data-tianteng-post-id="${postId}"
  989. data-tianteng-post-message-id="${postMessageId}"
  990. type="button">打开所有磁链
  991. </button>
  992. <button style="margin:0;padding:5px;margin-left:10px;"
  993. class="jav-button tianteng-button"
  994. data-tianteng-button="copyAllNot"
  995. data-tianteng-post-id="${postId}"
  996. data-tianteng-post-message-id="${postMessageId}"
  997. type="button">复制所有磁链(不含点评)
  998. </button>
  999. <button style="margin:0;padding:5px;"
  1000. class="jav-button tianteng-button"
  1001. data-tianteng-button="clickAllNot"
  1002. data-tianteng-post-id="${postId}"
  1003. data-tianteng-post-message-id="${postMessageId}"
  1004. type="button">打开所有磁链(不含点评)
  1005. </button>`;
  1006. $(`#${postMessageId}`).prepend(allButtonHtml + "<br><br>");
  1007. $(`#${postMessageId}`).append("<br><br>" + allButtonHtml);
  1008. }
  1009. });
  1010. // 自动分页插件兼容
  1011. const nodeToObserve =
  1012. document.querySelectorAll(".nthread_postbox")[14];
  1013. new MutationObserver((mutationRecords, observer) => {
  1014. // $('div[id^="post_"]').each(function () {
  1015. // if ($(this).data("tiantengStatus") !== "ok") {
  1016. // handleMagnet();
  1017. // }
  1018. // });
  1019. }).observe(nodeToObserve, { childList: true });
  1020. // #endregion
  1021. } // end if 论坛明细页面
  1022. // # endregion
  1023. } // end callback
  1024. );
  1025. // #region BT搜索网站
  1026. ///////////////////////////////////////////////////////////////////////////
  1027. // BTSOW https://btsow.motorcycles https://btsow.com
  1028. ///////////////////////////////////////////////////////////////////////////
  1029. execute("btsow", $('head>title:contains("BTSOW")'), () => {
  1030. function allPages() {
  1031. const form = $("form.fullsearch-form");
  1032. form.each(function () {
  1033. const me = $(this);
  1034. if ($(".tianteng-paste-search", me).length === 0) {
  1035. const searchButton = $(`:submit`, me);
  1036. const pasteAndSearchButton = $(`
  1037. <button type="button" class="btn btn-default tianteng-paste-search">
  1038. 粘贴&搜索
  1039. </button>`);
  1040.  
  1041. searchButton.after(pasteAndSearchButton);
  1042. }
  1043. });
  1044. }
  1045. function searchPage() {
  1046. if (location.pathname.startsWith("/search")) {
  1047. debug("添加 复制磁链,打开磁链 按钮", "btsow-搜索结果列表");
  1048. let buttonsHtml = `
  1049. <button class="btn btn-danger copy" type="button">复制磁链</button>
  1050. <button class="btn btn-danger click" type="button">打开磁链</button>`;
  1051. $("div.data-list>div.row>a>div.file").each((index, el) => {
  1052. if ($(el).find("button.copy").length === 0) {
  1053. $(el).append(buttonsHtml);
  1054. }
  1055. });
  1056. }
  1057. }
  1058.  
  1059. debug("添加 粘贴&搜索 按钮", "btsow-所有页面");
  1060. allPages();
  1061. $(document).on("click", "button.tianteng-paste-search", function (e) {
  1062. const me = $(this);
  1063. navigator.clipboard.readText().then((text) => {
  1064. if (text != null && $.trim(text) != "") {
  1065. me.parent().prev().val($.trim(text));
  1066. me.parentsUntil(".container")[2].submit();
  1067. }
  1068. });
  1069. });
  1070.  
  1071. searchPage();
  1072. if (location.pathname.startsWith("/search")) {
  1073. debug("添加 复制磁链,打开磁链 按钮", "btsow-搜索结果列表");
  1074. $(document).on("click", "button.copy, button.click", function (e) {
  1075. let magnet = $(this).parent().parent().attr("href").split("/")[6];
  1076. magnet = `magnet:?xt=urn:btih:${magnet}`;
  1077.  
  1078. if ($(this).attr("class").includes("copy")) {
  1079. GM_setClipboard(magnet, "text", () => debug("ok"));
  1080. } else if ($(this).attr("class").includes("click")) {
  1081. GM_openInTab(magnet);
  1082. }
  1083.  
  1084. e.preventDefault();
  1085. e.stopImmediatePropagation();
  1086. e.stopPropagation();
  1087. });
  1088. }
  1089.  
  1090. // 自动分页插件兼容
  1091. const nodeToObserve = document.querySelector("body");
  1092. new MutationObserver((mutationRecords, observer) => {
  1093. allPages();
  1094. searchPage();
  1095. }).observe(nodeToObserve, { childList: true });
  1096. });
  1097.  
  1098. ///////////////////////////////////////////////////////////////////////////
  1099. // skrbt https://skrbtqx.top 永久地址: skrfabu.top skrso.link
  1100. ///////////////////////////////////////////////////////////////////////////
  1101. execute("skrbt", $(`head>link[rel='shortcut icon'][href*='skrbt']`), () => {
  1102. debug("添加 粘贴&搜索 按钮", "skrbt");
  1103. const $searchButton = $("button.search-btn");
  1104. const $searchInput = $(`input.search-input[name='keyword']`);
  1105. const $pasteAndSearchButton = addPasteAndSearchButton(
  1106. $searchButton,
  1107. $searchInput
  1108. );
  1109. // 调整'粘贴&搜索'按钮样式
  1110. $pasteAndSearchButton.removeAttr("style");
  1111. $pasteAndSearchButton.css("margin-left", "3px");
  1112. $pasteAndSearchButton.attr("class", $searchButton.attr("class"));
  1113.  
  1114. // 通过别的网站直接访问,比如(https://skrbtqx.top/search?keyword=abp133),会直接跳转到首页
  1115. // 解决办法,在别的地方进来之前,先把要查询的关键字保存起来,然后进入到skrbt后获取,赋值到输入框,然后查询.
  1116. // 如果,在skrbt首页中没有找到保存的关键字,就从剪贴板获取.
  1117. // 如果,剪贴板没有任何内容,则啥也不做.
  1118. if (location.pathname === "/") {
  1119. const keyword = GM_getValue("tiantengKeyword", null);
  1120. if (keyword) {
  1121. debug("搜索存储的内容", "skrbt-首页");
  1122. GM_deleteValue("tiantengKeyword");
  1123. $searchInput.val(keyword);
  1124. $searchButton.click();
  1125. } else {
  1126. debug("搜索剪贴板中的内容", "skrbt-首页");
  1127. $pasteAndSearchButton.click();
  1128. }
  1129. }
  1130.  
  1131. debug("删除广告", "skrbt");
  1132. // 删除广告
  1133. function removeAd() {
  1134. const $container = $(".col-md-6:eq(2)");
  1135. $container.remove(".label.label-primary");
  1136. $container
  1137. .find('a.rrt.common-link[href^="http"]')
  1138. .parent()
  1139. .parent()
  1140. .remove();
  1141. }
  1142. removeAd();
  1143.  
  1144. // 搜索结果列表页面
  1145. if (location.href.includes("search")) {
  1146. debug("添加 复制磁链和打开磁链 按钮", "skrbt-搜索结果列表页面");
  1147. let buttonsHtml = `
  1148. <span class="rrmiv"><button class="btn btn-danger copy" type="button">复制磁链</button></span>
  1149. <span class="rrmiv"><button class="btn btn-danger click" type="button">打开磁链</button></span>`;
  1150. addButtonsForSkrbt(buttonsHtml, $(".col-md-6:eq(2)"), (el) => {
  1151. const classValue = $(el).attr("class");
  1152. if (classValue && classValue.includes("copy")) {
  1153. return "copy";
  1154. }
  1155. if (classValue && classValue.includes("click")) {
  1156. return "click";
  1157. }
  1158. return "other";
  1159. });
  1160.  
  1161. // 自动分页插件兼容,删除广告
  1162. const nodeToObserve = document.querySelectorAll(".col-md-6")[2];
  1163. new MutationObserver((mutationRecords, observer) => {
  1164. $("a.rrt.common-link").each((index, el) => {
  1165. if ($(el).parent().find(".btn.btn-danger.copy").length === 0) {
  1166. $(el).after(buttonsHtml);
  1167. }
  1168. });
  1169.  
  1170. removeAd();
  1171. }).observe(nodeToObserve, { childList: true });
  1172. } // end if
  1173. });
  1174. // #endregion
  1175.  
  1176. ///////////////////////////////////////////////////////////////////////////
  1177. // 知乎
  1178. ///////////////////////////////////////////////////////////////////////////
  1179. execute("知乎", /zhihu\.com/, () => {
  1180. const searchButton = $(`button[class*="SearchBar-searchButton"]`);
  1181. const searchInput = $(`#Popover1-toggle`);
  1182. addPasteAndSearchButton(searchButton, searchInput);
  1183. });
  1184. ///////////////////////////////////////////////////////////////////////////
  1185. // 百度
  1186. ///////////////////////////////////////////////////////////////////////////
  1187. execute("百度", /baidu\.com/, () => {
  1188. const searchButton = $(`#su`);
  1189. const searchInput = $(`#kw`);
  1190. addPasteAndSearchButton(searchButton, searchInput);
  1191. });
  1192. });
  1193. // #endregion
  1194.  
  1195. // #region 公共方法
  1196. /////////////////////////////////////////////////////////////////////////////
  1197. // 公共方法
  1198. /////////////////////////////////////////////////////////////////////////////
  1199.  
  1200. function execute(title, condition, callback) {
  1201. if (checkCondition(condition) === true) {
  1202. if (callback) {
  1203. debug(condition.toString(), title);
  1204. callback(title, condition);
  1205. }
  1206. }
  1207. }
  1208.  
  1209. /**
  1210. *
  1211. * @param {RegExp|Function|Boolean|String|jQuery} condition
  1212. * @returns {Boolean}
  1213. */
  1214. function checkCondition(condition) {
  1215. if ($.type(condition) === "regexp") {
  1216. return condition.test(window.location.href);
  1217. }
  1218. if ($.isFunction(condition)) {
  1219. return condition() === true;
  1220. }
  1221. if ($.type(condition) === "boolean") {
  1222. return condition === true;
  1223. }
  1224. if ($.type(condition) === "string") {
  1225. return document.querySelector(condition) != null;
  1226. }
  1227. if (condition instanceof jQuery) {
  1228. return condition.length > 0;
  1229. }
  1230.  
  1231. if ($.isArray(condition)) {
  1232. for (let c of condition) {
  1233. if (checkCondition(c)) {
  1234. return true;
  1235. }
  1236. }
  1237. }
  1238. return false;
  1239. }
  1240.  
  1241. function addPasteAndSearchButton($searchButton, $searchInput, callback) {
  1242. const styleMap = { "margin-left": "5px" };
  1243. $searchButton[0] &&
  1244. $searchButton[0].computedStyleMap().forEach((value, key) => {
  1245. styleMap[key] = value;
  1246. });
  1247. let $pasteAndSearchButton = $(
  1248. `<input type="button" value="粘贴&搜索" id="pasteAndSearch"></input>`
  1249. );
  1250.  
  1251. $pasteAndSearchButton.css(styleMap);
  1252. $searchButton.after($pasteAndSearchButton);
  1253. $pasteAndSearchButton.click(() => {
  1254. navigator.clipboard.readText().then((clipText) => {
  1255. if (clipText != null && $.trim(clipText) != "") {
  1256. $searchInput.val($.trim(clipText));
  1257. $searchButton.click();
  1258. }
  1259. });
  1260. });
  1261. callback && callback($searchButton, $searchInput, $pasteAndSearchButton);
  1262. return $pasteAndSearchButton;
  1263. }
  1264. function addPasteAndSearchButton1(
  1265. searchButton,
  1266. searchInput,
  1267. pasteSearchButton
  1268. ) {
  1269. const styleMap = { "margin-left": "5px" };
  1270. $searchButton[0] &&
  1271. $searchButton[0].computedStyleMap().forEach((value, key) => {
  1272. styleMap[key] = value;
  1273. });
  1274. let $pasteAndSearchButton = $(
  1275. `<input type="button" value="粘贴&搜索" id="pasteAndSearch"></input>`
  1276. );
  1277.  
  1278. $pasteAndSearchButton.css(styleMap);
  1279. $searchButton.after($pasteAndSearchButton);
  1280. $pasteAndSearchButton.click(() => {
  1281. navigator.clipboard.readText().then((clipText) => {
  1282. if (clipText != null && $.trim(clipText) != "") {
  1283. $searchInput.val($.trim(clipText));
  1284. $searchButton.click();
  1285. }
  1286. });
  1287. });
  1288. callback && callback($searchButton, $searchInput, $pasteAndSearchButton);
  1289. return $pasteAndSearchButton;
  1290. }
  1291.  
  1292. function appendCopyButton(chePai, toAppendElement, callback) {
  1293. var copyButton = document.createElement("button");
  1294. copyButton.innerHTML = "复 制";
  1295. copyButton.setAttribute("id", "copyButton");
  1296. toAppendElement.appendChild(copyButton);
  1297. document.addEventListener("click", (e) => {
  1298. if (e.target.getAttribute("id") === "copyButton") {
  1299. GM.setClipboard(chePai, "text");
  1300. }
  1301. });
  1302. callback && callback(copyButton, chePai, toAppendElement);
  1303. }
  1304.  
  1305. function debug(str, title) {
  1306. if (enableDebug) {
  1307. if (!str) {
  1308. str = "";
  1309. }
  1310. if (!Array.isArray(str)) {
  1311. str = [str];
  1312. }
  1313. seq++;
  1314. console.log(
  1315. `%ctianteng ${GM_info.script.version}】 ${title ? title : "debug"}:`,
  1316. "color: yellow;font-size: large;font-weight: bold;background-color: darkblue;",
  1317. seq,
  1318. ...str
  1319. );
  1320. }
  1321. }
  1322.  
  1323. function isNativeCode(obj) {
  1324. const nativeCodeTag = "[native code]";
  1325. return obj && obj.toString && obj.toString().includes(nativeCodeTag);
  1326. }
  1327.  
  1328. function getQueryVariable(anchor, variable) {
  1329. var query = anchor.search.substring(1);
  1330. var vars = query.split("&");
  1331. for (var i = 0; i < vars.length; i++) {
  1332. var pair = vars[i].split("=");
  1333. if (pair[0] == variable) {
  1334. return pair[1];
  1335. }
  1336. }
  1337. return false;
  1338. }
  1339.  
  1340. /**
  1341. * 图片按宽高比例进行自动缩放
  1342. * @param ImgObj
  1343. * 缩放图片源对象
  1344. * @param maxWidth
  1345. * 允许缩放的最大宽度
  1346. * @param maxHeight
  1347. * 允许缩放的最大高度
  1348. * @usage
  1349. * 调用:<img src="图片" onload="javascript:drawImage(this,300,200)">
  1350. */
  1351. function drawImage(ImgObj, maxWidth, maxHeight) {
  1352. var image = new Image();
  1353. //原图片原始地址(用于获取原图片的真实宽高,当<img>标签指定了宽、高时不受影响)
  1354. image.src = ImgObj.src;
  1355. // 用于设定图片的宽度和高度
  1356. var tempWidth;
  1357. var tempHeight;
  1358.  
  1359. if (image.width > 0 && image.height > 0) {
  1360. //原图片宽高比例 大于 指定的宽高比例,这就说明了原图片的宽度必然 > 高度
  1361. if (image.width / image.height >= maxWidth / maxHeight) {
  1362. if (image.width > maxWidth) {
  1363. tempWidth = maxWidth;
  1364. // 按原图片的比例进行缩放
  1365. tempHeight = (image.height * maxWidth) / image.width;
  1366. } else {
  1367. // 按原图片的大小进行缩放
  1368. tempWidth = image.width;
  1369. tempHeight = image.height;
  1370. }
  1371. } else {
  1372. // 原图片的高度必然 > 宽度
  1373. if (image.height > maxHeight) {
  1374. tempHeight = maxHeight;
  1375. // 按原图片的比例进行缩放
  1376. tempWidth = (image.width * maxHeight) / image.height;
  1377. } else {
  1378. // 按原图片的大小进行缩放
  1379. tempWidth = image.width;
  1380. tempHeight = image.height;
  1381. }
  1382. }
  1383. // 设置页面图片的宽和高
  1384. ImgObj.height = tempHeight;
  1385. ImgObj.width = tempWidth;
  1386. // 提示图片的原来大小
  1387. ImgObj.alt = image.width + "×" + image.height;
  1388. }
  1389. }
  1390.  
  1391. /**
  1392. *
  1393. * @param {EventTarget|NodeList|Array|jQuery} elements
  1394. * @param {undefined|null|String|Array} events
  1395. */
  1396. function removeEvents(elements, events) {
  1397. if (!elements) return;
  1398. if (elements instanceof EventTarget) {
  1399. elements = [elements];
  1400. }
  1401. if (elements instanceof jQuery) {
  1402. elements = elements.toArray();
  1403. }
  1404.  
  1405. if (!events) {
  1406. elements.forEach((element) => {
  1407. for (let t in element) {
  1408. if (t.startsWith("on") && element[t] != null) {
  1409. element[t] = null;
  1410. console.log("cleanup removed listener from " + element.nodeName, t);
  1411. }
  1412. }
  1413. for (let t of element.allListeners || []) {
  1414. element.removeEventListener(t.type, t.callback, t.options);
  1415. console.log(
  1416. "cleanup removed listener from " + element.nodeName,
  1417. t.type
  1418. );
  1419. }
  1420. element.allListeners = [];
  1421. });
  1422. } else {
  1423. if (typeof events === "string") {
  1424. events = [events];
  1425. }
  1426. if (!Array.isArray(events)) {
  1427. return;
  1428. }
  1429. events.forEach((event) => {
  1430. const onEvent = "on" + event;
  1431. elements.forEach((element) => {
  1432. for (let t in element) {
  1433. if (t.startsWith(onEvent) && element[t] != null) {
  1434. element[t] = null;
  1435. console.log(
  1436. "cleanup removed listener from " + element.nodeName,
  1437. t
  1438. );
  1439. }
  1440. }
  1441. // const toRemoved = [];
  1442. element.allListeners = element.allListeners || [];
  1443. let allListenersNew;
  1444. element.allListeners.forEach((t, i) => {
  1445. if (t.type === event) {
  1446. element.removeEventListener(t.type, t.callback, t.options);
  1447. allListenersNew = element.allListeners.slice(i, 1);
  1448. // toRemoved.push(i);
  1449. console.log(
  1450. "cleanup removed listener from " + element.nodeName,
  1451. t.type
  1452. );
  1453. }
  1454. });
  1455. // toRemoved.forEach((item, index) => {
  1456. // element.allListeners = element.allListeners.slice(item, 1);
  1457. // });
  1458. if (allListenersNew) {
  1459. element.allListeners = allListenersNew;
  1460. }
  1461. });
  1462. });
  1463. }
  1464. }
  1465.  
  1466. function addButtonsForSkrbt(
  1467. buttonsHtml,
  1468. delegateElement,
  1469. buttonTypeCallback
  1470. ) {
  1471. delegateElement.find("a.rrt.common-link").after(buttonsHtml);
  1472.  
  1473. delegateElement.click((event) => {
  1474. const buttonType = buttonTypeCallback(event.target);
  1475. if ("copy" !== buttonType && "click" !== buttonType) {
  1476. return;
  1477. }
  1478. let liNode = $(event.target).parent().parent();
  1479.  
  1480. const exeButtonClick = () => {
  1481. if ("copy" === buttonType) {
  1482. navigator.clipboard.writeText(liNode.find(".magnet").attr("href"));
  1483. } else {
  1484. // liNode.find('.magnet').trigger('click'); //不好使
  1485. liNode.find(".magnet")[0].click();
  1486. }
  1487. };
  1488.  
  1489. if (liNode.find(".magnet").length != 0) {
  1490. // 磁链已经添加过
  1491. exeButtonClick();
  1492. return;
  1493. }
  1494. let detailUrl = liNode.find("a.rrt.common-link").attr("href");
  1495. detailUrl = `${skrbtUrl}${detailUrl}`;
  1496. $.get(detailUrl, function (data, textStatus, jqXHR) {
  1497. liNode.find("#errorTip").remove();
  1498. //成功后在页面添加磁链
  1499. const magnet = $(data).find("#magnet").attr("href");
  1500. if (magnet) {
  1501. const aHtml =
  1502. '<a class="magnet" href="' + magnet + '">' + magnet + "</a>";
  1503. liNode.append(aHtml);
  1504. exeButtonClick();
  1505. } else {
  1506. liNode.append(
  1507. '<span id="errorTip">1.获取磁链失败,等会儿再试一试! 若仍然有问题请刷新网页.</span>'
  1508. );
  1509. }
  1510. }).fail(function (e) {
  1511. //失败后在页面提示
  1512. liNode.append(
  1513. '<span id="errorTip">2.获取磁链失败,等会儿再试一试! 若仍然有问题请刷新网页.</span>'
  1514. );
  1515. console.log(e);
  1516. });
  1517. });
  1518. }
  1519. // #endregion
  1520. })();