链接助手

大部分主流网盘和小众网盘自动填写密码; 跳转页面自动跳转; 文本转链接; 净化跳转链接; 维基百科及镜像、开发者文档、谷歌商店自动切换中文, 维基百科、谷歌开发者、谷歌商店链接转为镜像链接; 新标签打开链接; (外部)链接净化直达

25.05.2021 itibariyledir. En son verisyonu görün.

  1. // ==UserScript==
  2. // @name 链接助手
  3. // @namespace https://github.com/oneNorth7
  4. // @include *
  5. // @version 1.7.8
  6. // @author 一个北七
  7. // @run-at document-body
  8. // @description 大部分主流网盘和小众网盘自动填写密码; 跳转页面自动跳转; 文本转链接; 净化跳转链接; 维基百科及镜像、开发者文档、谷歌商店自动切换中文, 维基百科、谷歌开发者、谷歌商店链接转为镜像链接; 新标签打开链接; (外部)链接净化直达
  9. // @icon https://gitee.com/oneNorth7/pics/raw/master/picgo/link-helper.png
  10. // @compatible chrome 69+
  11. // @compatible firefox 78+
  12. // @compatible edge Latest
  13. // @noframes
  14. // @license GPL-3.0 License
  15. // @grant GM_registerMenuCommand
  16. // @grant GM_unregisterMenuCommand
  17. // @grant GM_notification
  18. // @grant GM_info
  19. // @grant GM_setValue
  20. // @grant GM_getValue
  21. // @grant GM_deleteValue
  22. // @grant GM_openInTab
  23. // @grant GM_xmlhttpRequest
  24. // @grant GM_addStyle
  25. // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js
  26. // @require https://cdn.jsdelivr.net/npm/sweetalert2@10.15.5/dist/sweetalert2.all.min.js
  27. // @created 2021年3月19日 09:48:14
  28. // ==/UserScript==
  29.  
  30. $(function () {
  31. "use strict";
  32.  
  33. const scriptInfo = GM_info.script,
  34. locHost = location.host,
  35. locHref = location.href,
  36. locHash = location.hash,
  37. locPath = location.pathname;
  38.  
  39. let t = {
  40. showNotice(msg) {
  41. GM_notification({
  42. text: msg,
  43. title: scriptInfo.name,
  44. image: scriptInfo.icon,
  45. highlight: false,
  46. silent: false,
  47. timeout: 1500,
  48. });
  49. },
  50.  
  51. clog() {
  52. console.group('[链接助手]');
  53. for (let m of arguments) {
  54. if (void 0 !== m) console.log(m);
  55. }
  56. console.groupEnd();
  57. },
  58.  
  59. get(name, def) {
  60. return GM_getValue(name, def);
  61. },
  62.  
  63. set(name, value) {
  64. GM_setValue(name, value);
  65. },
  66.  
  67. delete(name) {
  68. GM_deleteValue(name);
  69. },
  70.  
  71. registerMenu(title, func) {
  72. return GM_registerMenuCommand(title, func);
  73. },
  74.  
  75. unregisterMenu(menuID) {
  76. GM_unregisterMenuCommand(menuID);
  77. },
  78.  
  79. open(url, options = { active: true, insert: true, setParent :true }) {
  80. GM_openInTab(url, options);
  81. },
  82.  
  83. http(link, s = false) {
  84. return link.startsWith("http")
  85. ? link
  86. : (s ? "https://" : "http://") + link;
  87. },
  88.  
  89. title(a, mark='') {
  90. if (a.title)
  91. a.title += "\n" + mark + decodeURIComponent(a.href);
  92. else a.title = mark + decodeURIComponent(a.href);
  93. },
  94.  
  95. hashcode(l=location) {
  96. return l.hash.slice(1);
  97. },
  98.  
  99. search(l=location, p = 'password') {
  100. let args = l.search.slice(1).split('&');
  101. for (let a of args) {
  102. if (a.includes(p + '='))
  103. return a.replace(p + '=', '');
  104. }
  105. return '';
  106. },
  107.  
  108. clean(src, str) {
  109. for (let s of str) {
  110. src = src.replace(s, "");
  111. }
  112. return src;
  113. },
  114.  
  115. loop(func, times) {
  116. let tid = setInterval(() => {
  117. if (times <= 0) clearInterval(tid);
  118. func();
  119. this.clog(times);
  120. times--;
  121. }, 100);
  122. },
  123.  
  124. confirm(title, yes, no, deny) {
  125. let option = {
  126. toast: true,
  127. showCancelButton: true,
  128. position: 'center',
  129. title,
  130. confirmButtonText: '是',
  131. cancelButtonText: '否',
  132. showDenyButton: deny,
  133. denyButtonText: '取消',
  134. // customClass
  135. };
  136. return Swal.fire(option).then((res) => {
  137. if (res.isConfirmed) yes();
  138. else if (res.isDismissed) no();
  139. else if (res.isDenied) deny();
  140. });
  141. },
  142.  
  143. increase() {
  144. success_times = +this.get("success_times") + 1;
  145. this.set("success_times", success_times);
  146. },
  147.  
  148. subscribe() {
  149. let isFollowed = t.get('isFollowed', false), least_times = t.get('least_times', 50);
  150. success_times = +this.get("success_times");
  151. if (success_times > least_times && !isFollowed) {
  152. Swal.fire({
  153. title: '\u5173\u6ce8\u516c\u4f17\u53f7\uff0c\u4e0d\u8ff7\u8def\uff01',
  154. html: $(
  155. `<div><img style="width: 300px;margin: 5px auto;" src="https://gitee.com/oneNorth7/pics/raw/master/picgo/oneNorth7.png"><p style="font-size: 16px;color: red;">\u7b2c\u4e00\u65f6\u95f4\u83b7\u53d6<span style="color: gray;font-weight: 800;">\u3010\u94fe\u63a5\u52a9\u624b\u3011</span>\u66f4\u65b0\u63a8\u9001\uff01</p></div>`
  156. )[0],
  157. showCancelButton: true,
  158. allowOutsideClick: false,
  159. confirmButtonColor: '#d33',
  160. confirmButtonText: '\u5df2\u5173\u6ce8\uff0c\u4e0d\u518d\u63d0\u9192\uff01',
  161. cancelButtonColor: '#3085d6',
  162. cancelButtonText: '\u7a0d\u540e\u5173\u6ce8',
  163. }).then((result) => {
  164. if (result.isConfirmed) {
  165. Swal.fire({
  166. position: 'center',
  167. icon: 'success',
  168. title: '\u611f\u8c22\u5173\u6ce8\uff01\uff01\uff01',
  169. text: '\u4e00\u4e2a\u5317\u4e03\u4f1a\u7ee7\u7eed\u4e0d\u9057\u4f59\u529b\u5730\u521b\u4f5c\u66f4\u591a\u5b9e\u7528\u5de5\u5177',
  170. showConfirmButton: false,
  171. timer: 2000
  172. });
  173. t.set('isFollowed', true);
  174. } else t.set('least_times', least_times + 50);
  175. });
  176. }
  177. },
  178.  
  179. update(name, value) {
  180. if (this.get('updated_version', '') != scriptInfo.version) {
  181. let data = this.get(name, false);
  182. if (data) {
  183. for (let v of value) {
  184. if (!data.some(d => d == v)) {
  185. data.push(v);
  186. }
  187. }
  188. this.set('updated_version', scriptInfo.version);
  189. this.set(name, data);
  190. }
  191. }
  192. },
  193. };
  194.  
  195. let url_re_str = "((?<![.@])\\w(?:[\\w._-])+@\\w[\\w\\._-]+\\.(?:com|cn|org|net|info|tv|cc|gov|edu|nz|me)|(?:https?:\\/\\/|www\\.)[\\w_\\-\\.~\\/\\=\\?&#%\\+:!*\\u4e00-\\u9fa5]+|(?<!@)(?:\\w[\\w._-]+\\.(?:com|cn|org|net|info|tv|cc|gov|edu|nz|me))(?:\\/[\\w_\\-\\.~\\/\\=\\?&#%\\+:!*\\u4e00-\\u9fa5]*)?)",
  196. url_regexp = new RegExp(url_re_str, "i");
  197.  
  198. let Preprocess = {
  199. "www.38hack.com": function () {
  200. if (/http:\/\/www\.38hack\.com\/\d+\.html/.test(locHref)) {
  201. let lines = $("div.down-line");
  202.  
  203. if (lines.length)
  204. lines.last().append(lines.first().prev().prev());
  205. }
  206. },
  207.  
  208. "www.mikuclub.xyz": function () {
  209. if (/https:\/\/www\.mikuclub\.xyz\/\d+/.test(locHref)) {
  210. let password = $(".password1"),
  211. link = $("a.download");
  212. if (password.length && link.length)
  213. link[0].hash = password[0].value;
  214. }
  215. },
  216.  
  217. "www.acggw.com": function () {
  218. if (/https:\/\/www\.acggw\.com\/\d+\.html/.test(locHref)) {
  219. let paragraphs = $(".single-content>p"),
  220. weiyun = null,
  221. mega = null;
  222. for (let p of paragraphs) {
  223. let text = $(p).text();
  224. if (text.startsWith("链接:")) weiyun = $(p);
  225. if (weiyun && text.startsWith("密码:"))
  226. weiyun.text(
  227. weiyun.text() + "#" + text.replace("密码:", "")
  228. );
  229. if (mega && text.startsWith("国外M盘:"))
  230. mega.text(
  231. mega.text() + "#" + text.replace("国外M盘:", "")
  232. );
  233. if (text.startsWith("国外M盘:http")) mega = $(p);
  234. }
  235. }
  236. },
  237.  
  238. "www.olecn.com": function () {
  239. if (
  240. /http:\/\/www\.olecn\.com\/download\.php\?id=\d+/.test(locHref)
  241. ) {
  242. let link = $("div.panel-body a"),
  243. pass = $("div.plus_l li:eq(3)");
  244. if (link.length && pass.length)
  245. link[0].hash = pass
  246. .text()
  247. .trim()
  248. .replace("网盘提取码 :", "");
  249. }
  250. },
  251.  
  252. "www.qiuziyuan.net": function () {
  253. if (
  254. /https:\/\/www\.qiuziyuan\.net\/(?:pcrj\/|Android\/\d+\.html)/.test(
  255. locHref
  256. )
  257. ) {
  258. let filetit = $("div.filetit:first");
  259. for (let child of filetit.children()) {
  260. if (child.href) {
  261. let result = url_regexp.exec(child.innerHTML);
  262. if (result) child.href = t.http(result[1]);
  263. }
  264.  
  265. if (
  266. child.innerHTML.startsWith("90网盘:") ||
  267. child.innerHTML.includes("90pan")
  268. ) {
  269. let dom = filetit.next().next(),
  270. result = /(?:90网盘:|\/\s*)(\d+)/.exec(dom.html());
  271. if (result) child.href += "#" + result[1];
  272. }
  273. }
  274. }
  275. },
  276.  
  277. "www.gopojie.net": function () {
  278. if (/https:\/\/www\.gopojie\.net\/download\?post_id=/.test(locHref)) {
  279. setTimeout(() => {
  280. let a = $('a.empty.button'), url = a.prop('href'), code = $('#tq').attr('data-clipboard-text');
  281. if (url) a.prop('href', url + '#' + code);
  282. }, 1000);
  283. }
  284. },
  285.  
  286. };
  287.  
  288. if (Preprocess[locHost]) Preprocess[locHost]();
  289.  
  290. let YunDisk = {
  291. sites: {
  292. "pan.baidu.com": {
  293. // 百度云
  294. inputSelector: "#accessCode",
  295. buttonSelector: "#submitBtn",
  296. regStr: "[a-z\\d]{4}",
  297. },
  298.  
  299. "eyun.baidu.com": {
  300. // 百度企业网盘
  301. inputSelector: "input.share-access-code",
  302. buttonSelector: "a.g-button",
  303. regStr: "[a-z\\d]{4}",
  304. },
  305.  
  306. "cloud.189.cn": {
  307. // 天翼云
  308. inputSelector: "#code_txt",
  309. buttonSelector: "a.btn-primary",
  310. regStr: "[a-z\\d]{4}",
  311. clickTimeout: 500,
  312. },
  313.  
  314. "lanzou.com": {
  315. // 蓝奏云
  316. inputSelector: "#pwd",
  317. buttonSelector: "#sub, .passwddiv-btn",
  318. regStr: "[a-z\\d]{2,10}",
  319. redirect: true,
  320. },
  321.  
  322. "ct.ghpym.com": {
  323. // 果核城通网盘
  324. inputSelector: "#passcode",
  325. buttonSelector: "button.btn-primary",
  326. regStr: "[a-z\\d]{4,6}",
  327. timeout: 200, // >=125
  328. },
  329.  
  330. "www.90pan.com": {
  331. // 90网盘
  332. inputSelector: "#code",
  333. buttonSelector: "button.btn-info",
  334. regStr: "[a-z\\d]{4,6}",
  335. },
  336.  
  337. "vdisk.weibo.com": {
  338. // 微盘
  339. inputSelector: "#keypass",
  340. buttonSelector: "div.search_btn_wrap>a",
  341. regStr: "[a-z\\d]{4}",
  342. },
  343.  
  344. "pan.xunlei.com": {
  345. // 迅雷云盘
  346. inputSelector: "#__nuxt input.td-input__inner",
  347. buttonSelector: "#__nuxt button.td-button",
  348. regStr: "[a-z\\d]{4}",
  349. timeout: 1200,
  350. store: true,
  351. inputEvent: true,
  352. },
  353.  
  354. "share.weiyun.com": {
  355. // 微云
  356. inputSelector: "input.input-txt",
  357. buttonSelector: "button.btn-main",
  358. regStr: "[a-z\\d]{4,6}",
  359. timeout: 500,
  360. inputEvent: true,
  361. },
  362.  
  363. "115.com": {
  364. // 115网盘
  365. inputSelector: "input.text",
  366. buttonSelector: "a.btn-large",
  367. regStr: "[a-z\\d]{4}",
  368. timeout: 500,
  369. password: true,
  370. },
  371.  
  372. "quqi.com": {
  373. // 曲奇云
  374. inputSelector: "div.webix_el_box>input",
  375. buttonSelector: "button.webixtype_base",
  376. regStr: "[a-z\\d]{6}",
  377. timeout: 800,
  378. },
  379.  
  380. "caiyun.139.com": {
  381. // 和彩云
  382. inputSelector: "input",
  383. buttonSelector: "a.btn-token",
  384. regStr: "[a-z\\d]{4}",
  385. timeout: 100,
  386. clickTimeout: 10,
  387. inputEvent: true,
  388. store: true,
  389. },
  390.  
  391. "mo.own-cloud.cn": {
  392. // 小麦魔方
  393. inputSelector: "#pwd",
  394. buttonSelector: "button.MuiButton-root",
  395. regStr: "[a-z\\d\\u4e00-\\u9fa5]{2,8}",
  396. timeout: 500,
  397. password: true,
  398. },
  399.  
  400. "moecloud.cn": {
  401. // 萌云
  402. inputSelector: "#pwd",
  403. buttonSelector: "button.MuiButton-root",
  404. regStr: "[a-z\\d]{4,8}",
  405. timeout: 500,
  406. password: true,
  407. },
  408.  
  409. "www.wenshushu.cn": {
  410. // 文叔叔
  411. inputSelector: "input.ivu-input",
  412. buttonSelector: "button.m-mg_t40",
  413. regStr: "[a-z\\d]{4}",
  414. timeout: 1000,
  415. inputEvent: true,
  416. },
  417.  
  418. "mega.nz": {
  419. regStr: "[a-z\\d\\-_]{22}",
  420. },
  421.  
  422. "gofile.me": {
  423. inputSelector: "#login_passwd",
  424. buttonSelector: 'button[aria-label="进入"]',
  425. regStr: "[a-z\\d]{4}",
  426. clickTimeout: 1000,
  427. store: true,
  428. },
  429.  
  430. "www.jianguoyun.com": {
  431. // 坚果云
  432. inputSelector: "#access-pwd",
  433. buttonSelector: "button.action-button",
  434. regStr: "[a-z\\d]{6}",
  435. },
  436.  
  437. "yunpan.360.cn": {
  438. // 360安全云盘
  439. inputSelector: "input.pwd-input",
  440. buttonSelector: "input.submit-btn",
  441. regStr: "[a-z\\d]{4}",
  442. },
  443.  
  444. "pan-yz.chaoxing.com": {
  445. // 超星云盘
  446. inputSelector: "input.tqInp",
  447. buttonSelector: "a.blueBgBtn",
  448. regStr: "[a-z\\d]{6}",
  449. },
  450.  
  451. "shandianpan.com": {
  452. // 闪电盘
  453. inputSelector: 'input[placeholder="请输入文件密码"]',
  454. buttonSelector: "div.btn",
  455. regStr: "[a-z\\d]{4}",
  456. timeout: 200,
  457. inputEvent: true,
  458. store: true,
  459. },
  460.  
  461. "drive.dnxshare.cn": {}, // 电脑小分享
  462.  
  463. "my.sharepoint.com": {
  464. // OneDrive
  465. inputSelector: '#txtPassword',
  466. buttonSelector: "#btnSubmitPassword",
  467. regStr: "[a-z\\d]{4}",
  468. },
  469.  
  470. "disk.yandex.com": {}, // YandexDisk
  471.  
  472. },
  473.  
  474. pans: [
  475. "cowtransfer.com", // 奶牛快传
  476. "www.mediafire.com", // MediaFire
  477. "drive.google.com", // GoogleDrive
  478. "down.52pojie.cn", // 爱盘
  479. "www.yunzhongzhuan.com", // 云中转
  480. "yiqixie.qingque.cn", // 一起写
  481. "www.androiddownload.net",
  482. "www.dropbox.com", // Dropbox
  483. "www.kufile.net", // 库云
  484. "www.kdocs.cn", // 金山文档
  485. ],
  486.  
  487. mapHost(host) {
  488. return host
  489. .replace('yun.baidu.com', 'pan.baidu.com')
  490. .replace(/.*lanzou[isx]?.com/, 'lanzou.com')
  491. .replace(/^(?:[a-z]\d{3}|\d{3}[a-z])\.com$/, 'ct.ghpym.com')
  492. .replace(/quqi\.\w+\.com/, 'quqi.com')
  493. .replace('feixin.10086.cn', '139.com')
  494. .replace('ws28.cn', 'www.wenshushu.cn')
  495. .replace('zb.my.to:5000', 'gofile.me')
  496. .replace('cloud.dnxshare.cn', 'drive.dnxshare.cn')
  497. .replace(/\w+\-my\.sharepoint\.(?:com|cn)/, 'my.sharepoint.com')
  498. .replace(/\w{6}.link.yunpan.360.cn|yunpan.cn/, 'yunpan.360.cn')
  499. .replace('mofile.own-cloud.cn', 'mo.own-cloud.cn')
  500. .replace('cloud.qingstore.cn', 'moecloud.cn')
  501. .replace('pan.mebk.org', 'moecloud.cn')
  502. .replace('cncncloud.com', 'moecloud.cn')
  503. .replace('ilolita945.softether.net:5212', 'moecloud.cn')
  504. .replace('my-file.cn', 'moecloud.cn')
  505. .replace('pan.bilnn.com', 'moecloud.cn')
  506. .replace('yadi.sk', 'disk.yandex.com');
  507. },
  508.  
  509. autoFill(host) {
  510. let site = this.sites[host];
  511. if (site.timeout) setTimeout(fillOnce, site.timeout);
  512. else fillOnce();
  513. function fillOnce() {
  514. if (site.inputSelector) {
  515. let input = $(site.inputSelector),
  516. button = $(site.buttonSelector),
  517. code = null;
  518. function click() {
  519. if (site.clickTimeout)
  520. setTimeout(() => {
  521. button = $(site.buttonSelector);
  522. button[0].click();
  523. }, site.clickTimeout);
  524. else button[0].click();
  525. }
  526.  
  527. if (input.length) {
  528. if (site.store) code = t.get(host);
  529. else if (site.password) code = decodeURIComponent(t.search());
  530. else code = t.hashcode();
  531. if (code) {
  532. let codeRe = RegExp("^" + site.regStr + "$", "i");
  533. if (codeRe.test(code)) {
  534. if (site.inputEvent) {
  535. let tid = setInterval(() => {
  536. input.val(code);
  537. if (input.val() !== "") {
  538. if (InputEvent) {
  539. input[0].dispatchEvent(
  540. new InputEvent("input")
  541. );
  542. } else if (KeyboardEvent) {
  543. input[0].dispatchEvent(
  544. new KeyboardEvent("input")
  545. );
  546. }
  547.  
  548. clearInterval(tid);
  549. click();
  550. }
  551. }, 1000);
  552. } else if (site.password) {
  553. click();
  554. } else {
  555. input.val(code);
  556. click();
  557. }
  558. t.increase();
  559. t.subscribe();
  560. } else {
  561. t.clog("未找到合适的提取码!");
  562. }
  563. } else {
  564. t.clog("未找到提取码!");
  565. }
  566. } else {
  567. t.clog("无需填写密码!");
  568. }
  569. }
  570. }
  571. },
  572.  
  573. addCode(a) {
  574. let mapped = this.mapHost(a.host),
  575. site = this.sites[mapped],
  576. codeRe = new RegExp("^" + site.regStr + "$", "i");
  577. if (site.password) {
  578. let result = a.hash && /#(\/s\/\w{6})/.exec(a.hash);
  579. if (result)
  580. if (a.pathname == '/') {
  581. a.pathname = result[1];
  582. a.hash = '';
  583. }
  584. } else if (site.redirect) {
  585. a.host = a.host.replace('lanzous', 'lanzoux');
  586. }
  587.  
  588. if (!codeRe.test(t.hashcode(a)) && !codeRe.test(t.search(a))) {
  589. let reg = new RegExp(
  590. "\\s*(?:提[取示]|访问|查阅|密\\s*|艾|Extracted-code|key|password|pwd)[码碼]?\\s*[:: ((]?\\s*(" +
  591. site.regStr +
  592. ")|^[码碼]?\\s*[::【\\[ ((]?\\s*(" +
  593. site.regStr +
  594. ")[】\\]]?$",
  595. "i"
  596. ),
  597. code = reg.exec($(a).text().trim());
  598. outloop: for (
  599. let i = 10, current = a;
  600. current && !code && i > 0;
  601. i--, current = current.parentElement
  602. ) {
  603. let next = current;
  604. while (!code) {
  605. next = next.nextSibling;
  606. if (!next) break;
  607. else if ((node => {
  608. if (node.href) return true;
  609. else if (node.innerHTML)
  610. if (/<a.*href=.*/i.test(node.innerHTML))
  611. return true;
  612. })(next)) break outloop;
  613. else code = reg.exec($(next).text().trim());
  614. }
  615. }
  616.  
  617. if (code) {
  618. let c = code[1] || code[2];
  619. if (site.store) t.set(mapped, c);
  620. else if (site.password) {
  621. if (!t.search(a))
  622. a.search = a.search ? a.search + '&' + 'password=' + encodeURIComponent(c) : 'password=' + encodeURIComponent(c);
  623. } else a.hash = c;
  624. } else {
  625. if (site.store) t.delete(mapped);
  626. t.clog("找不到code!");
  627. }
  628. }
  629. },
  630. };
  631. let success_times = t.get("success_times");
  632. if (!success_times) t.set("success_times", 0);
  633.  
  634. let dealedHost = YunDisk.mapHost(locHost);
  635. if (YunDisk.sites[dealedHost]) YunDisk.autoFill(dealedHost);
  636. else {
  637. let RedirectPage = {
  638. sites: {
  639. "show.bookmarkearth.com": {
  640. // 书签地球
  641. include: "http://show.bookmarkearth.com/view/",
  642. selector: "a.open-in-new-window",
  643. },
  644.  
  645. "t.cn": {
  646. // 微博
  647. include: "http://t.cn/",
  648. selector: "a.m-btn-orange",
  649. },
  650.  
  651. "sunbox.cc": {
  652. // 阳光盒子
  653. include:
  654. "https://sunbox.cc/wp-content/themes/begin/go.php?url=",
  655. selector: "a.alert-btn",
  656. },
  657.  
  658. "www.itdaan.com": {
  659. // 开发者知识库
  660. include: "https://www.itdaan.com/link/",
  661. selector: "a.c-footer-a1",
  662. },
  663.  
  664. "to.redircdn.com": {
  665. include:
  666. "https://to.redircdn.com/?action=image&url=",
  667. selector: "a.bglink",
  668. },
  669.  
  670. "link.csdn.net": {
  671. // CSDN
  672. include: "https://link.csdn.net/?target=",
  673. selector: "a.loading-btn",
  674. timeout: 100,
  675. },
  676.  
  677. "niao.su": {
  678. // 不死鸟
  679. include: "https://niao.su/go/",
  680. selector: "a.c-footer-a1",
  681. },
  682.  
  683. "support.qq.com": {
  684. include: "support.qq.com/products/",
  685. selector: "span.link_url",
  686. },
  687.  
  688. "www.imaybes.cc": {
  689. // 也许吧
  690. include: "www.imaybes.cc/wl?url=",
  691. selector: "a.button"
  692. },
  693. },
  694.  
  695. redirect(host) {
  696. let site = this.sites[host];
  697. if (locHref.includes(site.include)) {
  698. if (site.timeout) setTimeout(redirect, site.timeout);
  699. else redirect();
  700.  
  701. function redirect() {
  702. let target = $(site.selector);
  703. if (target.length) location.replace(target[0].href || target[0].innerText);
  704. else t.clog('找不到跳转目标!');
  705. t.increase();
  706. }
  707. }
  708. },
  709.  
  710. wiki() {
  711. let isZh = locHost.includes("zh"),
  712. jumpToZh = t.get("jumpToZh", true),
  713. a = $("a.interlanguage-link-target[lang='zh']");
  714.  
  715. if (!isZh && jumpToZh) {
  716. history.pushState(null, null, locHref);
  717. if (a.length) location.replace(a[0].href);
  718. else t.showNotice("没有找到中文页面!");
  719. }
  720.  
  721. let menuID = t.registerMenu(
  722. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  723. autoJump
  724. );
  725.  
  726. function autoJump() {
  727. jumpToZh = !jumpToZh;
  728. t.set("jumpToZh", jumpToZh);
  729. t.unregisterMenu(menuID);
  730. menuID = t.registerMenu(
  731. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  732. autoJump
  733. );
  734. if (!isZh && jumpToZh) {
  735. history.pushState(null, null, locHref);
  736. if (a.length) location.replace(a[0].href);
  737. else t.showNotice("没有找到中文页面!");
  738. }// else history.back();
  739. }
  740. },
  741.  
  742. mozilla() {
  743. let isZh = locPath.includes("zh-CN"),
  744. jumpToZh = t.get("jumpToZh", true);
  745. jump();
  746. function jump() {
  747. if (!isZh && jumpToZh) {
  748. let result = /developer\.mozilla\.org\/(.+?)\//.exec(
  749. locHref
  750. ), options = $("#language-selector").children(), flag = false;
  751.  
  752. if (result) {
  753. for (let i = options.length; i > 0; i--) {
  754. if (options[i - 1].value === "zh-CN") {
  755. flag = true;
  756. break;
  757. }
  758. }
  759. if (flag) {
  760. let zh_url = locHref.replace(result[1], "zh-CN");
  761. history.pushState(null, null, locHref);
  762. location.replace(zh_url);
  763. }
  764. else t.showNotice("没有找到中文页面!");
  765. }
  766. }
  767. }
  768. let menuID = t.registerMenu(
  769. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  770. autoJump
  771. );
  772.  
  773. function autoJump() {
  774. jumpToZh = !jumpToZh;
  775. t.set("jumpToZh", jumpToZh);
  776. t.unregisterMenu(menuID);
  777. menuID = t.registerMenu(
  778. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  779. autoJump
  780. );
  781. jump();
  782. }
  783. },
  784.  
  785. MSDocs() {
  786. let isZh = locPath.includes("zh-cn"),
  787. jumpToZh = t.get("jumpToZh", true);
  788. if (!isZh && jumpToZh) {
  789. history.pushState(null, null, locHref);
  790. location.replace(locHref.replace(/docs.microsoft.com\/[a-z\-]{5}\//i, 'docs.microsoft.com/zh-cn/'));
  791. }
  792.  
  793. let menuID = t.registerMenu(
  794. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  795. autoJump
  796. );
  797.  
  798. function autoJump() {
  799. jumpToZh = !jumpToZh;
  800. t.set("jumpToZh", jumpToZh);
  801. t.unregisterMenu(menuID);
  802. menuID = t.registerMenu(
  803. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  804. autoJump
  805. );
  806. if (!isZh && jumpToZh) {
  807. history.pushState(null, null, locHref);
  808. location.replace(locHref.replace(/docs.microsoft.com\/[a-z\-]{5}\//i, 'docs.microsoft.com/zh-cn/'));
  809. }
  810. }
  811. },
  812.  
  813. chrome() {
  814. let isZh = location.search.includes('hl=zh-CN'),
  815. jumpToZh = t.get("jumpToZh", true);
  816. if (!isZh && jumpToZh) {
  817. history.pushState(null, null, locHref);
  818. location.search = location.search.replace(/hl=[a-zA-Z]{2}-[a-zA-Z]{2}/, 'hl=zh-CN');
  819. }
  820.  
  821. let menuID = t.registerMenu(
  822. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  823. autoJump
  824. );
  825.  
  826. function autoJump() {
  827. jumpToZh = !jumpToZh;
  828. t.set("jumpToZh", jumpToZh);
  829. t.unregisterMenu(menuID);
  830. menuID = t.registerMenu(
  831. `${jumpToZh ? "[✔]" : "[✖]"}自动切换中文`,
  832. autoJump
  833. );
  834. if (!isZh && jumpToZh) {
  835. history.pushState(null, null, locHref);
  836. location.search = location.search.replace(/hl=[a-zA-Z]{2}-[a-zA-Z]{2}/, 'hl=zh-CN');
  837. }
  838. }
  839. },
  840. };
  841.  
  842. if (locHost.match(/.+wiki(?:\.sxisa|pedia)\.org/))
  843. RedirectPage.wiki();
  844. else if (locHost == 'chrome.google.com')
  845. RedirectPage.chrome();
  846. else {
  847. if (locHost === "developer.mozilla.org") RedirectPage.mozilla();
  848. else if (locHost === "docs.microsoft.com") RedirectPage.MSDocs();
  849.  
  850. let isChromium = navigator.appVersion.includes('Chrome');
  851.  
  852. $(document).on("mouseup", (obj) => listener(obj));
  853.  
  854. if (isChromium && locHost == 'www.52pojie.cn')
  855. $(document).on("selectstart", (obj) => listener(obj));
  856.  
  857. if (locHost.includes('blog.csdn.net'))
  858. document.body.addEventListener('click', function (obj) {
  859. let e = obj.target;
  860. if (e.nodeName.toLocaleLowerCase() === 'a') {
  861. obj.stopImmediatePropagation();
  862. window.open(e.href);
  863. obj.preventDefault();
  864. }
  865. }, true);
  866.  
  867. async function listener(obj) {
  868. let e = obj.originalEvent.explicitOriginalTarget || obj.originalEvent.target,
  869. isTextToLink = false, isInput = false;
  870. if (e && !e.href) {
  871. let flag = true,
  872. selectNode = null;
  873. for (
  874. let current = e, limit = 5;
  875. current.localName !== "html" && current.localName !== "body" && limit > 0;
  876. current = current.parentElement, limit--
  877. ) {
  878. if (current.localName === "a") {
  879. e = current;
  880. break;
  881. } else if (
  882. ["code", "pre"].some(
  883. (tag) => tag === current.localName
  884. )
  885. ) {
  886. let selection = getSelection(),
  887. text = selection.toString();
  888. if (url_regexp.test(text))
  889. selectNode =
  890. selection.anchorNode || selection.focusNode;
  891. else flag = false;
  892. break;
  893. } else if (['input', 'textarea'].some((tag) => tag === current.localName) && current.className == 'direct-input') {
  894. let text = t.clean(current.value, [/[\u4e00-\u9fa5\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]+/g, /^[::]/, /App.*$/]),
  895. result = url_regexp.exec(text);
  896. if (result) {
  897. selectNode = document.createTextNode(text);
  898. isInput = true;
  899. }
  900. else flag = false;
  901. break;
  902. }
  903. }
  904.  
  905. if (e.localName !== "a" && flag) {
  906. let node = selectNode || e;
  907. if (node && node.nodeValue) e = text2Link(node);
  908. else e = textToLink(e);
  909. if (e)
  910. isTextToLink = true;
  911. }
  912. }
  913.  
  914. if (e && e.localName === "a" && e.href) {
  915. let a = e, isPrevent = false;
  916. if (locHref.includes("mod.3dmgame.com/mod/"))
  917. a.search = "3dmgame.com";
  918.  
  919. if (locHost == "bbs.nga.cn" || locHost == "nga.178.com" || locHost == "ngabbs.com") {
  920. if (!(a.host == "bbs.nga.cn" || a.host == "nga.178.com" || a.host == "ngabbs.com"))
  921. if (a.attributes.onclick && a.attributes.onclick.nodeValue.startsWith("ubbcode.showUrlAlert(event,this)"))
  922. a.onclick = null;
  923. }
  924.  
  925. if (locHost == "twitter.com" && a.host == "t.co") a.href = t.http(a.innerText, true);
  926.  
  927. if (locHost == "www.youtube.com" && a.href.includes("www.youtube.com/redirect?")) {
  928. if (!a.style.padding) {
  929. $("#secondary-links.ytd-c4-tabbed-header-renderer a.ytd-c4-tabbed-header-renderer").css({padding: "10px 10px 10px 2px", lineHeight: 0, display: "inline-block"});
  930. $("#secondary-links.ytd-c4-tabbed-header-renderer a.ytd-c4-tabbed-header-renderer:first-child").css("padding-left", "10px");
  931. }
  932. a.classList.remove("yt-simple-endpoint");
  933. }
  934.  
  935. if (locHost == "www.facebook.com") {
  936. a.onclick = function() { return false; };
  937. t.open(a.href);
  938. }
  939.  
  940. if (!cleanRedirectLink(a) && RegExp("^" + url_re_str + "$", "i").test(a.innerText)) {
  941. if (isLinkText(a)) {
  942. t.title(a, '【替换】');
  943. a.href = t.http(a.innerText, true);
  944. t.increase();
  945. }
  946. else if (!isTextToLink && !a.parentElement.className.includes('text2Link') && !a.parentElement.className.includes('textToLink') && locHost != 'blog.csdn.net' && isDifferent(a)) {
  947. a.onclick = function() { return false; };
  948. isPrevent = true;
  949. await t.confirm("是否使用链接文本替换目标链接后打开?",
  950. () => {
  951. // 是
  952. let linkTextPrefixes = t.get("linkTextPrefixes", []),
  953. reg = /(?:http|https|\/|\%2F).*?\?.+?=|.*?\?/,
  954. result = reg.exec(a.href);
  955. if (result) {
  956. linkTextPrefixes.push(result[0]);
  957. t.set("linkTextPrefixes", linkTextPrefixes);
  958. }
  959. t.title(a, '【替换】');
  960. a.href = t.http(a.innerText, true);
  961. t.increase();
  962. },
  963. () => {
  964. // 否
  965. },
  966. () => {
  967. // 取消
  968. isPrevent = false;
  969. a.onclick = null;
  970. });
  971. }
  972. }
  973.  
  974. if (jumpToMirror) {
  975. if (a.host.includes("wikipedia.org")) {
  976. // 维基百科
  977. if (!locHost == "www.bing.com" || !locHost.includes("www.google."))
  978. a.href = a.href.replace(
  979. "wikipedia.org",
  980. "wiki.sxisa.org"
  981. );
  982. } else if (a.host.includes("developers.google.com")) {
  983. // 谷歌开发者
  984. if (!locHost == "developers.google.com")
  985. a.href = a.href.replace(
  986. "developers.google.com",
  987. "developers.google.cn"
  988. );
  989. } else if (a.host.includes("chrome.google.com")) {
  990. // 谷歌应用商店
  991. if (isChromium) {
  992. a.onclick = function() { return false; };
  993. isPrevent = true;
  994. await t.confirm('是否跳转到【crx4chrome】镜像站?',
  995. () => {
  996. // 是
  997. t.title(a);
  998. a.href = a.href.replace(/chrome\.google\.com\/webstore\/detail[\/\w\-%]*(?=\w{32})/i, 'www.crx4chrome.com/extensions/');
  999. },
  1000. () => {
  1001. // 否
  1002. },
  1003. () => {
  1004. // 取消
  1005. isPrevent = false;
  1006. a.onclick = null;
  1007.  
  1008. });
  1009. }
  1010. }
  1011. }
  1012.  
  1013. let pan = YunDisk.sites[YunDisk.mapHost(a.host)];
  1014. if (pan) YunDisk.addCode(a);
  1015.  
  1016. if (isTextToLink) {
  1017. let isClicked = false;
  1018. if (pan || t.get("autoClickSites", []).concat(YunDisk.pans).some(h => h == a.host)) {
  1019. a.click();
  1020. isClicked = true;
  1021. }
  1022.  
  1023. if (isInput) {
  1024. if (!isClicked) a.click();
  1025. $('#L_DirectInput').val('');
  1026. }
  1027. }
  1028.  
  1029. add_blank(a);
  1030.  
  1031. if (isPrevent) {
  1032. a.onclick = null;
  1033. t.open(a.href);
  1034. }
  1035. }
  1036. }
  1037.  
  1038. // 注册菜单项添加文本转链接后自动跳转域名
  1039. t.registerMenu('添加自动跳转域名', addAutoClick);
  1040.  
  1041. function addAutoClick() {
  1042. let autoClickSites = t.get("autoClickSites", []), input = prompt("输入的域名的链接文本转链接后会自动跳转", locHost);
  1043. if (input) {
  1044. if (/[\w]+(\.[\w]+)+/.test(input)) {
  1045. if (!autoClickSites.some((s) => s.includes(input))) {
  1046. autoClickSites.push(input);
  1047. t.set("autoClickSites", autoClickSites);
  1048. } else t.showNotice(`域名 <${input}> 已存在!!!`);
  1049. } else t.showNotice(`<${input}> 不是有效域名!!!`);
  1050. }
  1051. }
  1052.  
  1053. // 注册菜单项自动切换镜像
  1054. let jumpToMirror = t.get("jumpToMirror", true);
  1055.  
  1056. let menuID = t.registerMenu(
  1057. `${jumpToMirror ? "[✔]" : "[✖]"}自动切换镜像`,
  1058. autoJump
  1059. );
  1060.  
  1061. function autoJump() {
  1062. jumpToMirror = !jumpToMirror;
  1063. t.set("jumpToMirror", jumpToMirror);
  1064. t.unregisterMenu(menuID);
  1065. menuID = t.registerMenu(
  1066. `${jumpToMirror ? "[✔]" : "[✖]"}自动切换镜像`,
  1067. autoJump
  1068. );
  1069. }
  1070.  
  1071. if (RedirectPage.sites[locHost]) RedirectPage.redirect(locHost);
  1072.  
  1073. let textLength = t.get("textLength", 200);
  1074.  
  1075. // t.registerMenu(
  1076. // `设置文本字数限制(${textLength})`,
  1077. // limitText
  1078. // );
  1079.  
  1080. // function limitText() {
  1081. // let input = prompt(
  1082. // "请输入文本字数限制: ",
  1083. // t.get("textLength", 200)
  1084. // );
  1085. // }
  1086.  
  1087. let url_regexp_g = new RegExp(
  1088. "\\b(" + url_re_str +
  1089. "|" +
  1090. "ed2k:\\/\\/\\|file\\|[^\\|]+\\|\\d+\\|\\w{32}\\|(?:h=\\w{32}\\|)?\\/" +
  1091. "|" +
  1092. "magnet:\\?xt=urn:btih:\\w{40}(&[\\w\\s]+)?" +
  1093. ")",
  1094. "ig"
  1095. );
  1096.  
  1097. function textToLink(e) {
  1098. if (
  1099. !["body", "code", "pre", "select", "main", "input", "textarea"].some(
  1100. (tag) => tag === e.localName
  1101. ) &&
  1102. !["www.google."].some((h) => locHost.includes(h))
  1103. ) {
  1104. let span = null,
  1105. count = 0;
  1106. if (e.childNodes.length < 10)
  1107. for (
  1108. let i = e.childNodes.length - 1;
  1109. i >= 0;
  1110. i--
  1111. ) {
  1112. let child = e.childNodes[i];
  1113. if (
  1114. !["a", "br", "code", "pre", "img", "script", "option", "input", "textarea"].some(
  1115. (tag) => tag === child.localName
  1116. ) &&
  1117. child.className !== "textToLink" &&
  1118. child.textContent.length < textLength
  1119. ) {
  1120. let text = child.textContent,
  1121. result = url_regexp_g.test(text);
  1122. if (result) {
  1123. span = $("<span class='textToLink'></span>");
  1124. span.html(
  1125. text.replace(url_regexp_g, function ($1) {
  1126. count++;
  1127. if ($1.includes("@")) return `<a href="mailto:${$1}">${$1}</a>`;
  1128. return $1.startsWith("http") ||
  1129. $1.includes("magnet") ||
  1130. $1.includes("ed2k")
  1131. ? `<a href="${$1}" target="_blank">${$1}</a>`
  1132. : `<a href="https://${$1}" target="_blank">${$1}</a>`;
  1133. })
  1134. );
  1135. $(child).replaceWith(span);
  1136. }
  1137. }
  1138. }
  1139. if (count) t.increase();
  1140. return count == 1 && span && span.children()[0];
  1141. }
  1142. }
  1143.  
  1144. function text2Link(node) {
  1145. if (node.nodeValue.length < textLength) {
  1146. let text = node.nodeValue,
  1147. result = url_regexp_g.test(text),
  1148. span = null,
  1149. count = 0;
  1150. if (result) {
  1151. span = $("<span class='text2Link'></span>");
  1152. span.html(
  1153. text.replace(url_regexp_g, function ($1) {
  1154. count++;
  1155. if ($1.includes("@")) return `<a href="mailto:${$1}">${$1}</a>`;
  1156. return $1.startsWith("http") ||
  1157. $1.includes("magnet") ||
  1158. $1.includes("ed2k")
  1159. ? `<a href="${$1}" target="_blank">${$1}</a>`
  1160. : `<a href="https://${$1}" target="_blank">${$1}</a>`;
  1161. }).replace(/点/g, '.')
  1162. );
  1163. $(node).replaceWith(span);
  1164. }
  1165. if (count) t.increase();
  1166. return count == 1 && span && span.children()[0];
  1167. }
  1168. }
  1169.  
  1170. function isLinkText(a) {
  1171. let keywords = [
  1172. "niao.su/go",
  1173. "www.sunweihu.com/go/?url=",
  1174. "jump.bdimg.com/safecheck/index?url=",
  1175. "jump2.bdimg.com/safecheck/index?url=",
  1176. "zhouxiaoben.info/wp-content/themes/begin/go.php?url=",
  1177. "www.423down.com/wp-content/plugins/momgo/go.php?url=",
  1178. "www.423down.com/go.php?url=",
  1179. "www.ccava.net/xc_url/?url=",
  1180. "www.imaybes.cc/wl?url=",
  1181. ],
  1182. linkTextPrefixes = t.get("linkTextPrefixes", []);
  1183. return keywords.some((k) => a.href.includes(k)) || linkTextPrefixes.some((k) => a.href.includes(k));
  1184. }
  1185.  
  1186. function isDifferent(a) {
  1187. if (/(?:http|https|\/|\%2F).*?\?.+?=|.*?\?/.test(a.href)) {
  1188. let hash = a.hash, search = a.search, password = t.search(a);
  1189. a.hash = "";
  1190. if (password) a.search = "";
  1191. let text = decodeURIComponent(a.innerText).toLowerCase().replace(/^https?:\/\/|\/$/, ''), href = decodeURIComponent(a.href).toLowerCase().replace(/^https?:\/\/|\/$/, '');
  1192. a.hash = hash;
  1193. if (password) a.search = search;
  1194. return !(text.includes('...') || !text.includes('/') || text == href);
  1195. }
  1196. return false;
  1197. }
  1198.  
  1199. let excludeSites = [
  1200. "v.qq.com",
  1201. "v.youku.com",
  1202. "blog.csdn.net",
  1203. "cloud.tencent.com",
  1204. "translate.google.com",
  1205. "domains.live.com",
  1206. "passport.yandex.ru",
  1207. "www.iconfont.cn",
  1208. "www.kdocs.cn",
  1209. "help.aliyun.com",
  1210. "cn.bing.com",
  1211. "service.weibo.com",
  1212. "zhannei.baidu.com",
  1213. "pc.woozooo.com",
  1214. "play.google.com",
  1215. ];
  1216.  
  1217. t.update('excludeSites', excludeSites);
  1218.  
  1219. excludeSites = t.get("excludeSites", excludeSites);
  1220.  
  1221. t.registerMenu("添加例外域名", addExcludeSite);
  1222.  
  1223. // 添加例外域名
  1224. function addExcludeSite() {
  1225. let input = prompt("输入的域名下的链接不会被净化: ", locHost);
  1226. if (input) {
  1227. if (/[\w]+(\.[\w]+)+/.test(input)) {
  1228. if (!excludeSites.some((s) => s.includes(input))) {
  1229. excludeSites.push(input);
  1230. t.set("excludeSites", excludeSites);
  1231. } else t.showNotice(`例外域名 <${input}> 已存在!!!`);
  1232. } else t.showNotice(`<${input}> 不是有效域名!!!`);
  1233. }
  1234. }
  1235.  
  1236. function cleanRedirectLink(a) {
  1237. // 小众软件
  1238. if (locHost == 'www.appinn.com' && (a.search.includes('ref=appinn') || a.hash.includes('ref=appinn'))) {
  1239. t.title(a, '【净化】');
  1240. a.search = a.search.replace(/[?&]ref=appinn$/, '');
  1241. a.hash = a.hash.replace(/[#&]ref=appinn$/, '');
  1242. t.increase();
  1243. return true;
  1244. }
  1245.  
  1246. // 净化跳转链接
  1247. let hosts = ['dalao.ru', 'niao.su', 'iao.su', 'nicelinks.site', 'www.appinn.com', 'support.qq.com', locHost];
  1248. for (let h of hosts) {
  1249. let reg = RegExp(`\\?(?:utm_source=)?${h}$`), result = reg.exec(a.href);
  1250. if (result) {
  1251. t.title(a, '【净化】');
  1252. a.href = a.href.replace(result[0], '');
  1253. t.increase();
  1254. }
  1255. }
  1256.  
  1257. let reg = new RegExp('((?:http|https|\\/|\\%2F)(?:.*?[?&].+?=|.*?[?&]))' + url_re_str, "i"),
  1258. result = reg.exec(decodeURIComponent(a.href));
  1259. if (result) {
  1260. let temp = decodeURIComponent(
  1261. decodeURIComponent(result[2])
  1262. ).replace(/https?:\/\//, '');
  1263. if (
  1264. !(
  1265. decodeURIComponent(locHref).replace(/https?:\/\//, '').includes(
  1266. temp.split("&")[0]
  1267. ) || ['login', 'oauth'].some(k => locHref.includes(k)) || a.innerText.includes('登录') ||
  1268. excludeSites.some((s) => result[1].includes(s)) ||
  1269. YunDisk.sites[YunDisk.mapHost(a.host)]
  1270. )
  1271. ) {
  1272. if (!/t\d+\.html/i.test(temp)) {
  1273. let href = decodeURIComponent(
  1274. decodeURIComponent(
  1275. result[3]
  1276. ? "http://" + result[3]
  1277. : result[2].startsWith("http")
  1278. ? result[2]
  1279. : location.origin + result[2]
  1280. )
  1281. );
  1282.  
  1283. t.title(a, '【净化】');
  1284. if (["c.pc.qq.com","mail.qq.com", "m.sogou.com", "www.douban.com", "www.google.com", "txt.guoqiangti.ga", "g.luciaz.me"].some((h) => a.host == h))
  1285. a.href = href.split("&")[0];
  1286. else a.href = href.replace(/______/g, '.');
  1287. }
  1288. t.increase();
  1289. return true;
  1290. }
  1291. }
  1292.  
  1293. }
  1294.  
  1295. let defaultTargetSites = t.get("defaultTargetSites", ['shuax.com', 'app.infinityfree.net']);
  1296. let isAddBlank = t.get("isAddBlank", false);
  1297. let isDefault = defaultTargetSites.some((s) => s == location.host);
  1298. // 注册菜单项该站链接保持默认打开方式
  1299. if (!isDefault) {
  1300. let menuID2 = t.registerMenu(
  1301. "该站链接保持默认打开方式",
  1302. function () {
  1303. defaultTargetSites.push(location.host);
  1304. t.set("defaultTargetSites", defaultTargetSites);
  1305. isDefault = defaultTargetSites.some(
  1306. (s) => s == location.host
  1307. );
  1308. t.unregisterMenu(menuID2);
  1309. t.unregisterMenu(menuID);
  1310. }
  1311. );
  1312.  
  1313. // 注册菜单项启停在新标签打开链接
  1314. let menuID = t.registerMenu(
  1315. `${isAddBlank ? "[✔]" : "[✖]"}在新标签打开链接`,
  1316. addBlank
  1317. );
  1318.  
  1319. // 启停在新标签打开链接
  1320. function addBlank() {
  1321. isAddBlank = !isAddBlank;
  1322. t.set("isAddBlank", isAddBlank);
  1323. t.unregisterMenu(menuID);
  1324. menuID = t.registerMenu(
  1325. `${isAddBlank ? "[✔]" : "[✖]"}在新标签打开链接`,
  1326. addBlank
  1327. );
  1328. }
  1329. }
  1330.  
  1331. // 给链接添加[target="_blank"]属性
  1332. function add_blank(a) {
  1333. if (isAddBlank && !isDefault) {
  1334. let result =
  1335. a.href == "" || a.target == "_blank" ||
  1336. /javascript[\w:;()]+/.test(a.href) ||
  1337. /\/\w+-\d+-\d+\.html|.+page\/\d+|category-\d+_?\d*/.test(
  1338. a.href
  1339. ) ||
  1340. /[前后上下首末].+[页篇张]|^\.*\s*\d+\s*\.*$|^next$|^previous$/i.test(
  1341. a.innerText
  1342. ) ||
  1343. ["prev", "next"].some(
  1344. (r) =>
  1345. r == a.attributes.rel &&
  1346. a.attributes.rel.nodeValue
  1347. ) ||
  1348. ["prev", "next", "nxt"].some((r) =>
  1349. a.className.includes(r)
  1350. ) ||
  1351. a.href == location.origin + "/" ||
  1352. a.href.endsWith(".user.js"),
  1353. relative = t.get("relative", false);
  1354. if (!relative)
  1355. result =
  1356. result ||
  1357. !/^(?:https?|\/\/).+/.test(
  1358. a.attributes.href && a.attributes.href.nodeValue
  1359. );
  1360. if (!result) a.target = "_blank";
  1361. }
  1362. }
  1363.  
  1364. // 添加链接直达输入框
  1365. let addDirectTo = t.get('addDirectTo', true);
  1366. if (addDirectTo) add_direct();
  1367. let menuID2 = t.registerMenu(`${addDirectTo ? "[✔]" : "[✖]"}显示链接直达输入框`, directToMenu);
  1368.  
  1369. function directToMenu() {
  1370. addDirectTo = !addDirectTo;
  1371. t.set('addDirectTo', addDirectTo);
  1372. t.unregisterMenu(menuID2);
  1373. menuID2 = t.registerMenu(`${addDirectTo ? "[✔]" : "[✖]"}显示链接直达输入框`, directToMenu);
  1374. if (addDirectTo) add_direct();
  1375. else if ($('#L_DirectTo').length) $('#L_DirectTo').remove();
  1376. }
  1377.  
  1378. function add_direct() {
  1379. $('body').append(`<div id="L_DirectTo" class="l-direct-to">
  1380. <input type="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAaU0lEQVR4nO2deVgUZ57Hm8S4k50cc2SSzGR2J5ccAg1yI0c30A10QzcgllxyNw0iRAkao0bTKGhUPDIJGpMYjZoLowZEvEVlc+xONjOTmXWfOEncuJNhMpmNkozRiPrZP0j7VFVXI5AmIPbneb5/hPq+7/t969exq6veqlKp3Lhx48aNGzdu3Lhx48aNGzdu3Lhx48aNGzdu3PRJ4Ezu9SmnwLuCVZ7ltHlO47jXNLrGVXDGs4JvvKbxhWcFJ8dN422vaWz2ns487yq0v6zh5uHO7maQ+FgJ8qyk0auCk54VMChN47x3OfvGVVJ0v5Xbh3tObq6CrYMx3uXk+FTwnnc5uFQVfO07jbUPWnlguOfpRgEfK+njrXzoY4Uh1sXxVjb4zeCu4Z6zG1Xv97uflX2+VnAmPytnfcs5ON7K4+pyJvuWE6Cu4E5tJbcIAjf6T+PHPtP5la+VOP9pWP3KeN63nBNX6fOMfwVVKhUew70PrlvUFib7l3Harwzk8i/jor+VnWoLk4VBHsyFTcfTz8Lj/mV8rDSGXxn4W2mLKeZnrp6bmz7BI8BCo9oCcgWUcUFdSpP/NO531Wi2Dsaoy8hWl/G+kzH/7DcNtavGc9MHwVZuCrSwJcACcgVa2B9sxXuoxrZ1MCaglKqAMr5QGPt0aBmaoRrbjUqlEgTGBllonVAKYgWVci7IwvT+9KGt5JZgK0FBZWSEllMcZMEaYiEnsBy92sJ9/flOj63kXwJL6VTKEVrs/hAMCYLA2KBiWoNKQKJSPg2pYEJfbQOm4xtioSGolHeDS7jo0IdIwaV8HlTM9qAS8tSz+KGzPm0djAkpYbVCH6fD3V8HrkUQGBtaTGtICYgVWsoH2gruddYu2EpKmIVj8nb9VWgJ3WEWlof38ZMvvIxZISVcluX632ArdwzJzrjesBc/tBjECinhuLPChBcxLrSY/fI2g1VYMd1hxdQIAjcqjlfKLId8RbS5fyJ+RwSBsREltIQXg1gRfRQ/zEJBRAlfydtI2hdzIryIoxGlvBJezIbIEnaFl/Cb8GK6+2oXXsLhYCs/Vxo3spRVcn9kP49L3CggCIyNKqElsggkclp8PKJLqXfw9+pyZCEHIkqoiK3kX5yNGWzlplgL8dElrIwq5HOlvqKKORVTzHh5W1sHYyYWc0ziL+ZMYgV3unbPXA/ADRML2TaxEGRyWvyJJTQp+IkqYn94wcAPyswl3Bpdgi2qiC8V+v17gsKHQJvHL6OKOC3xFrBhcDvhOiamhJXRhSBWTB/Fjy2hScH/j+hiir9rFmMld0cXcsCh/yJOxSh8HUQVUCXLcXGi+wJS/4kpoCqmAMSKLeC42aJcfE0BTXJ/TAGfRRcS7KpMgsCNSuNEF3JYfmAoCNwYW8j7Em8ha12VZVSTWEy4Np+Lmny4ogI+0WfzC0c3HpqpNEm8+aAtoCtxiM4GKo2nKaRG7tMWkyXzfa0T3OsJ+kQQGBtXwB+1+XBFBZyOK8PX0d1bfIl3iIv/bcYbtQUcEI8ZV8gZ+b9OgsCNcQV8KPbFF1E0VLlGBXGF1MVPBZEu6/JJcnTioZtKk8xLfD5dunx8hjpnjJWfx+dzWjx2XB7LHOZTwAJZxn1Dne2axWThPl0e3yTkgV36PNYpeRPzWS32JeRBwtTvp/h29AXMEI+vm0q3IHCL2GPI4gGJJ5/zRTZ+8H1lvKbQTaVJ31t09HmQmMdJcwm3OvhymSX26fMg6XsuvkqlUhXZ+IE+j7+Kc+gKyJX79Ll8IPYYctwXihwwW7grMZevE3PBLsNUCuQ+Qw6apDwuiX1JU+nSZX2/xbeTlMNqSZZcXpd7EnNZL/Yk5zN3OLKOaFKyaUjOAbsMOXwg/2llLuHW5BxOin1JuZxOycdvuHIn5aKT5f6b/Nx/Ug4WmWfTMMUduaRk87Ghd+dgyIHUHMeTNynZLBJ7jLlcMuQTPxx57QgCY425fCnOlV4kvTJpzCVWvD05hzeHKe7IJGMqASnZYFdqNmfNZul3f0YFd6Zm85XYZ85j+XBlFmPK4T1xrpQp6MTbBYF/lWzP5uRwZR2RmHOxpWaBSK84eKYwV+bpyu9jocb3SWoWu8XZ0vKkB4JFRfxIvN2UzefDlXVEkpbNm+YsuKJcshU8H4g9phxmDkdWJUxZvCDOlp6LVbzdZmOMZH7ZnBuurCMQPNKy6E6bAldULL1UKwiMl2zP4lxKLj8ersRyMrJoFuebJEjP9lmt/LMsf/cwRR15TJrErzIEuKIpfCr3pAtUiT2ZU2gdjqzOyBA4Js4nCGRItmdw59XmeN0iCKRMEsCuzCnslXsyJrNJ7MnIdrzwMpxkCnwsmUOmdHFqZiZqyXaBPw5X1hHH5MlYJk8Gu6ZM4UW5RxDoFHsEYXh/+okRBO4TZ5s8mZ5ZsoPTKVPIlOVvGa68I46cyVRPyQS7cjIdf9pNmczHYk9u7sDv9snKIjUnx/UrdAWBKnG2rEz+Q+7JnsICiWcKja7Occ0yZRKPZPXuOLIyYcokHpd7sgU+FXsEgbsHMkbuZLKzMunJyuR3rv4Q5EziiCz/IrknK5MDYk/uZPJcmeGaZupkFuRMArvyMlgq9+Rk0iX2DOQDkJ9Bds4kekTtXfYhyM8gXpwrZxLkCdI1gjYbP8ibxFmxpzjN+YLU6468yVTnZoBdOemsdvBk8L7YkysQ2J++8zPIzs2gR9I2g55sgRRXZJ+ayTuyvo84ZBeYLPN86IqxRw1TM8mcmgF2FaTzktSBR34GnWLP1Em8PTWDTXmZzC+cRJTNxhh5v0UZZE/NoEfSLoOegklkuSJ3YTpWWd/kT3FcuJKfyU6xJ2+y46KR65oSgcj8dLCrIJ33VCqVShC4OX8StYUZnBBvV1JBOqcK0pg3K7/36Ls4jaz8dHpkvp7iNNcUvyCdsPwMvhb3PzWDdrkvN5f75TlKzX3fv3jdUSBwT2Ea2FWUxtl8AU1RBifEf++nPinJoKEwjR7Z311W/PwsfIrM/E2W+cupAg/KvcUZPCPxZfCfrsgw6ihO53+KenekXZdl/z1oFabRY3Fl8dPochjD7HhUXywwvjidC2Kfq3KMOkrT2VxiBmcqTeNLi4lXS9MoLzaRajWTUpqGxZLG1lIzXzhtZ3Zd8Suz8Ckx0yUfozidxY5uPErMHJJl+ZOzm0qve0rTsJSawEFmLpaaWFEq8BNnbfPyuK3MRJ3FzAV5e2saDa7IV5mBT6mJLnn/FjNrle78tabxkNxbYsbsiiwjmpnZ3Gs1k2JJx1qRTlW5iTkWE/PKTVSXZzCpLI2JJWbHmzssJurLTCCW1UR3WTqG/o493UysxczfZX18Yj8wHCyVGfhYTHTJ8zkrfpWZEKuJ87IcDgeIo4LyDAKsqTxuTeXN8lS6ranQL5n4xGpiszUNS0UaDfLt5al0W0xEDDTPdCOxVjMXxH2VmQe/ALMyA5/yVLoc8jspvsXEfVYzf5HN5YvpRn412Awjjhk53DXNRENlKh9XpICrNS2F7monxZ9zgNvr3kFf9xZJq95S/looN7NY0mcqnwzmu9eahv+0FLoc8pmUi19p5O6KVE7I/ZVmJg107BFJlYn7KlJompbCuWm9hXK5Kp0UH/BY2smc+k7O1h+D+mPQcIzzi4+xCLhB7LXquL0yldPifqenEjmQuZab0U9L4YxDxj6KX5nCcQe/eWSsWfxONAuMrTZQV5XCN9ON0Jeqjfyl2si+aiMvVhpYMd3EwmoDT1QbWVll5KUqA/85PYWzSm2rjM6Lv7yDNcuPgKKOUSdvU2XkJXHflUYe7c9cKwVueSiFVVUpXHLI2Efxp6dwXO6vTGHLNf9omBlGwqsM/LHKAEqqNvL1Q8m8NsNEbm0/v+eqTWiqDFyW9GNwXvzVHaxZ0wHO9OQRzq3tlC4Pm2GkXJLVyAt9ZZqewE9nGKitMvCZ4lyNrHFW/CojxxX8u6zB3NSf/TFiqTFQ9ZCRiw8ZwEFGPqhOoWSZ2fG2rT77FLh5hpETsv6cFn/dIdY0HYar6ZmD6MVtZyaRIhvj7YdTCag0cvcjZn4xw4xXrRl9jYHamSm0PWTgvJN5XpxhZLbSXCqN3D3DyHF5mxlGdlVX808D29sjCOCGh5JZOSMZ5JqZzMkZBgoGe0LjYSMPS/o0cLHW4PhTD/B44RBrnjsI/dHz+0kQt5+Vikkp/4Bk5JNqk/I9fPPM3DUzieMKba7t4jcLjK0xsK0mGWS6XGNk3UD/j5eCR42RE+J+ZxlY4eACjxcPsebFA9AfbT7IVy3/Js1Vk0ylwhz6pYeT+cfMJOpXODl/UCNwT00Sxx3ajYbi1ybT8nASyHR6TorS/flSatMYX2OgapaBTbXJdD5s4KPaJE7VJvFZbRJ/qE2mU9xvbTJf1sjO8AEeLx9kzSv7od86xCx5lhoD2xTm0adqkjhRY+Sx6Qn81Nkca9Lwr03ilLxtbdIoKP4jybTMSgSJkji1IEnpyRy9zBX42SMG5sxK5gOHtldRbRKvyvvbtpc5r++F/mrHXtaA9ODMZuKOWYl8JR5rdhLHZiXxu9mJfDo7iS9mJXFqdiK/mZ3ES7OTmDEr+epPD5uTRMrsRM44zEVP2zVf/NmJtD6SCGLNSeR4TTz3KLVZZubWuXrq5iTylbxdfzVXT7kkxwFu37WHs617oD/a3e5YfJVKpXo0kVWysU58l59j1Xnc9kgyzz2SyGWHeSSx85ov/qOJtM7Rg0zHbUbldXdzjMQ+mshJhTYD0uxEUsX9HtyNfm879FOKxZ+jI+XRRC6Jx5mr5+HB7BtrMDfNS6TkkUROKc4hkWeu6at7zQJjH02gda4OxJrfR/EfS6J2np5L8jZzdTBXz/m5OnY9lkjNwmQSbAl42jK4s8HMXfP0BM7V847Y/1gyRnHfh/eQdLgNrqZDTopv0xExT0+3eIxH9ZyoEQb2lpDV6fxorp7yuTo+UpynjguPJVE7sL09wrAGc9P8BFrn6UAs58XHY24iq+X+eTp4TEfXAh0zV/VxyValUqnmJ7BR0jYJi3j7W3v5SWcb5zt3gTO9udt58efr6ZZnm2vo36NYHk3h/vkJ5M3X8fp8HeeU5vmtPlpgJLw/fY5g8FiQwJbHEkCsBTqOL3dS/Pk6mhT8lxbqWO7s55Kc+XrmSfrQsVXueaeNRf/eCkp6t4/iL9DRLc/3bcazC3S895ielx/X8+RCPU8s1LPocT0rv90Hhxbo+EypraSfBM4tTKR+vZV/HsweH1HYEmhcEA8SJTgv/uM6muT+hfGctiUO7PasBXqi5H38Oo/bJKPBDe+3Uvf7Fs799g347Rvwuzf46vetzHJW/IUJdDvMx0VamMA3C3RsWJriuvcODSsL4xEejwexbAl84Kz4Nh1NDv54uhoSB/5Mng4bY+riOCXuq07veBeNSqVSvd/Gj/+wi8T/2knC5/+mfPKpXkeELYFueT5XyBbPSVscDcsM/HKg8xyxLE3mXlscp21xcEXxfLo02fFNG6jwsMXRJPH2qmtZ7OCfxrUogXni/uriuLBEP/BHptXriLDF0y3PV5fAksVaym3xbLfF0aWQX1nxfGOLo7MugUX1iUzkWr+Kp8RiDfsWaUGkc4tiHdeoo8JjkYYmmZdF2u9WfJVKpWoSuGWRhk8k/Wr4v8U6tP3to05HyiIN3fJ8dQkskXvr47lncSLx9VoKG7TMWaShri6e+gYtc+rjqaiLx7QsDq/11/qVu6uxJIH0xVoQqz6eKrkPFR4NGprk3sUuKL6dRRoaHLJoubA4nvondM4fpNxo4o7F8axarOGSQj4WxUt/Vbj5lg4bYxq0fNigAbuWajmg9M9cvYYGsa9BA/UuLP5SLVkNWnrkY1yRltNL43h5aRzWJQmk1sdjqo+jcomWbQ1avnLaTgP1cWx2RcZRx3INOUtiwa6lsVxYrVDQJVoKxb4lsbBUQ5eSd1A5tGQt0dAjH2OwWhrLZcnfYvgfV+QcdTyh4b0nYuGKYhxfWrAsDq9lGv4h8Wn4uyuL/4SGHnH/yzRcXBrHkuWxnJKM2z990BhP7BOxnBX/vd7JtYvrltUxBC2LAbuWx3Jx+UTH15Ysj+GgxBfDhaXa/h+Y9cVKLVnLYukR978slp4ntL2PgmsSuKVRw7zlsZySeBS0PJYTjRpqmr89vbtcw2/F21cnDGzx56hnRSwrVkTDFUXxhoNHg0niiYZVMVS4YvyVsWStiKFH0n8MPSu0js8B7LAxZnkcUSuimNsYy6bl0bwty3VMftzSGMMrYs/yGDJdkXvUsDKKk43RYNfKaAS5pzGWt2SeTleMvSaa1MYYesR9NzopvhLLJxIoy/U7uWdVLE9K+tdQ7Yrso4LVWu5dFQV2rY7ibLPsytjKOALEnlVR8FQcUa4Yv9HEHauj+f2VvqPpeTKmf8VXqVSqZXp+Icv2Z7lnZQzLxJ4no1jgiuyjgl9HU7B6Ioh0SO5ZHc0ysWdNFPtdmaHRxB1rovn96ih6nood2F26T+n5hSR/FKfknlWR1Ik9v45RXsF7XbImhtVPToQrisYm9zwZxW/Fnl9HSVfpuIJGE3esiZQu/ugPTVoelGVzeLbO0xNpFHvWRDme3LpueWoibU9FgkiS7/+tBm57KpJL9u1PR3J53Qj6GfVMOHpZ/iNyT1MUW8WepyMpGYaoI5OnI/nvpyPArmcnSp+s1aQhVLx9bQQnhiurEuvCqRXnawp3fPXq0xM5JJlDVP9vJx/1rI2ga21vYVkbARtDpZd810UwRbx9XQQdw5VVibUTaRPneybC8afpukg+E3vW6/jX4cg6IlkXwVfrwsGuzWrpyp3nwigVb18XKX882/DxYgI/XRfGeXG+Z6PxFHvWT+QBSf5wukflZdzB8mw459aHgV3tD0qXLz8TQYV4+/ownhuurHLWh1IryRbOf8k9z4aSJ/Y8G+Z+D4+E58L5v2d7dwzPhsHaaOkdtBvCKBBvXx82Mp7B3yxwy3Ph/FWc7dkIx6Xd6yPYLvY8H8nC4cg7Ynk+lE+eDwW7NmqlK382hpIs3r4hjN8MU1QJz0ewSpzr+VDONCdJVxxv1PKjDWGcE/ueC7/63T3XFRvDeHtDCNj1QpB0EeemYB6QbA/hdIfCI1e/T54LR78hhEviXBuCHc/uvRBGuSR7KB8NR94RzYthbN4YAna9ECY9yYOKGzaF8YXYszly+F5pujUY/40hnBHn2RTCh/KD1/XB3LQxlI8kucOVntV3nbMliHmbgsGuzUGOv6M3hvCG2LMpeHheZPBqBD6bQugSZ3kxhItbIxyvS2wOo1Tm+3qzmjuHI/eIZksE2s1BYNeWIP4k97wUQoHEM4G/Nmulb78eal6NwGdzMF3iHJuDYHOI43uB2g3ctjmYU2Lf1hCe/j7zXjM0C9y8JYjzW3qL36sQvMSeFjO3bgnmS4lH4Tt3qHg1Ap8twXRJxu/VKiX/lhCeF/u2BvHNZjX3fV95rzleCmbfSxPgikIcLwi9OoFGiSeI7ubQgb2SZTDsiMBnaxBdkrEnwNZgmpRO6GwNIvXlCVy+2nzciHg1gOKXA8GuVwI5KT/Sbw7l7pcn0C3xTeBN+YkjV7IjAp9XAugSj/lyILwc5KT4/vi/MoEzsrn8oVlg7FBlHBU0B3P7axP4+tVAsOu1EHIcfBN4WOz5VhuHItOOCHxeC6BLPt5rTorfHMA9zYH8r8Q7gYvNAYQNRb5Rx6sTWPtaAIj0B4d/BQRu3BZIh8zHa2qaml34EITmAMKaA/mb0jiKxQ/l7tfUHHfwBzHdVZlGPTuDeWBbIBe3BYBd2yc4rp3bHszPtwdwSuzbFgDNag5sD+bn3yUDKjy2B1C+LZCv5f1v66P429Ucl/t3BLDyu2S5LtkRyAuvq8Gu7QGc3hfq+OqyHUH47Ajgc7H3dTVsV/PltkBs7Qbp7dz9oVVN/OsBvCPv83U17LxK8R3aBLAdlfTZwG76QYsfd+1Qc2aHP9i1049OpVO/O4LwecOfT8ReUZvPdwSwaucEEvo6ANun5r6WAKp2qDmq1M8Of2jxZ5Gz4u/057hCm7ahPDAd9bQEUPWGP4jVqnZ8R59K1ft1sFPNIblfrBZ/vmxR816LP22t/rzQ6s9rrX50vqHm5NXa7QpUfnNmRyh3v+HPcYU27uJ/V1Dh0eJPW4sfiLVLrbySFhU3tPkys8WfM/I2g1WrL+3twY53JqlUvcXf5cdxh3bu4ruO9hh+1ubHn3f5gl1tvlze7eRDoFKpVPvU3NnqyxNtfpwRtxuI2vzoaPGTPtBZTJs/97f5ckKhnbv4rqbFD/VuP8609Rb/itr9WNPX5eB9an64R01Omy/bdvnxmby9WLv96NntyzvtvtS1BfV9g2mrL6G7felS6MNd/KGi3RvNnvGcax8PYu3xpfOowq8DOajwOOTDr/arSdjnS/Y+f6x7/Cna50P6/kAC3w2++tO0UOHR7svMdl++kedo92GXu/hDTLs3mr0+nNnjA2LtG8/p9vFUD+XikH1q/Pb6clg+9h4f2OPN1ndH+yNbRgp7fQnY78Of9/mAg8bzx72+5Lryg7Dfh3F7fXhu/3h6FMf0ZoV7Ze/3TPuD/OyAF7v3e4MTnTw4nrqj4wb3sIh9an64z5fs/d607vfmkuIYPnxxwNd9a/ewgQqPDm+qDnpx5qAX9KGPDnmy8eB4yvd7krDfh3F7I/lJs8DYA/dz+1sB3HPYm+AOT7IOerHosDdHDnlx7ip97jnkM4req3ctc9CPuw5788IhLy4e8oKh1GFP/nTU6zp4neq1yKEHeeCoD+uOeHKuwxNcqSOevNfhQ3az6hp+1Pr1QkcgP+r0ovjoOPYfGcf5I+NgMDrqycfHvFjxtg9Bwz0nN4PkrV9y87EH0RzzZt7RB3nx2DjeOubJyU4vvuj05ELnOLqPefKXY54cPzqO1s4HWfmmJ/nv3u++YdONGzdu3Lhx48aNGzdu3Lhx48aNGzdu3Lhx4+Zq/D+9fBbn0eLVnwAAAABJRU5ErkJggg==" alt="直达" id="L_DirectButton" class="direct-button" />
  1381. <span title="粘贴或输入包含单链接的文本后点击输入框直达链接">
  1382. <input type="text" id="L_DirectInput" class="direct-input" placeholder="粘贴或输入链接" />
  1383. </span>
  1384. </div>`);
  1385. GM_addStyle(`#L_DirectTo input {
  1386. outline: none;
  1387. }
  1388. #L_DirectTo {
  1389. position: fixed;
  1390. left: 0;
  1391. top: 25%;
  1392. }
  1393. #L_DirectButton {
  1394. width: 30px;
  1395. height: 30px;
  1396. position: absolute;
  1397. z-index: 1;
  1398. left: -16px;
  1399. }
  1400. #L_DirectInput {
  1401. width: 300px;
  1402. height: 22px;
  1403. position: absolute;
  1404. left: -350px;
  1405. border: 3px solid #b52bff;
  1406. border-radius: 20px;
  1407. background-color: #99adf7;
  1408. padding-left: 10px;
  1409. box-sizing: content-box;
  1410. }
  1411. `);
  1412.  
  1413.  
  1414.  
  1415. let direct = $('#L_DirectTo'),
  1416. input = $('#L_DirectInput'),
  1417. button = $('#L_DirectButton');
  1418.  
  1419. input.on('click', obj => listener(obj));
  1420. input.on('paste', () => {
  1421. setTimeout(() => input[0].click(), 500);
  1422. });
  1423. // 清空输入框文本内容
  1424. input.val('');
  1425.  
  1426. button.on('click', () => {
  1427. if (button.hasClass('open')) {
  1428. input.animate({ left: '-350px' }).val('').blur();
  1429. button.removeClass('open');
  1430. button.prop('title', '点击展开输入框');
  1431. } else {
  1432. button.addClass('open');
  1433. input.focus().animate({ left: '28px' });
  1434. button.prop('title', '点击收起输入框');
  1435. }
  1436. })
  1437. .on('mouseover', () => {
  1438. button.animate({ left: 0 });
  1439. if (!button.hasClass('open')) button.click();
  1440. })
  1441. .on('mouseout', () => {
  1442. if (!button.hasClass('open'))
  1443. button.animate({ left: '-16px' });
  1444. });
  1445.  
  1446. let timeId = null;
  1447. direct.on('mouseout', () => {
  1448. timeId = setTimeout(() => {
  1449. if (button.hasClass('open')) {
  1450. button.click();
  1451. button.animate({ left: '-16px' });
  1452. }
  1453. }, 5000);
  1454. })
  1455. .on('mouseover', () => {
  1456. if (timeId) clearTimeout(timeId);
  1457. });
  1458. }
  1459. }
  1460. }
  1461. });