Wanta

移除跳转外链提示

目前为 2023-05-19 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Wanta
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.4.0
  5. // @description 移除跳转外链提示
  6. // @author PRO
  7. // @match *://www.jianshu.com/p/*
  8. // @match *://juejin.cn/post/*
  9. // @match *://gitee.com/*
  10. // @match *://zhuanlan.zhihu.com/*
  11. // @match *://*.feishu.cn/*
  12. // @match *://leetcode.cn/problems/*
  13. // @match *://www.mcmod.cn/*
  14. // @match *://play.mcmod.cn/*
  15. // @match *://www.mcbbs.net/*
  16. // @match *://www.minecraftforum.net/*
  17. // @match *://www.curseforge.com/minecraft/mc-mods/*
  18. // @icon https://greasyfork.org/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBMWhLQVE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--2831c7f8ea43fc8b8e3eed3818b98e88bb689285/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202022-07-16%20105357.png?locale=zh-CN
  19. // @grant none
  20. // @license gpl-3.0
  21. // ==/UserScript==
  22.  
  23. (function() {
  24. 'use strict';
  25. let debug = false;
  26. // domain: [link_prefix query_parameter main_article_path dynamic_query decode_func always_listen]
  27. // query_parameter = '': Get the last part of url
  28. function same(orig) {
  29. return orig;
  30. }
  31. function b64Decode(orig) {
  32. return decodeURIComponent(atob(orig));
  33. }
  34. function mcmod(orig) {
  35. let parts = orig.split("@");
  36. return parts.map(b64Decode).join("?");
  37. }
  38.  
  39. let fuck = {
  40. 'www.jianshu.com': ['https://links.jianshu.com/go', 'to', 'article', '', decodeURIComponent, false],
  41. 'juejin.cn': ['https://link.juejin.cn', 'target', '#juejin > div.view-container > main > div > div.main-area.article-area > article', ' > .article-content', decodeURIComponent, false],
  42. 'gitee.com': ['https://gitee.com/link', 'target', '.markdown-body', '', decodeURIComponent, false],
  43. 'zhuanlan.zhihu.com': ['https://link.zhihu.com/', 'target', 'div.Post-RichTextContainer', '', decodeURIComponent, false],
  44. '.*\.feishu\.cn': ['https://security.feishu.cn/link/safety', 'target', 'div#mainBox', ' div.mindnote-paper', decodeURIComponent, false],
  45. 'leetcode.cn': ['https://leetcode.cn/link/', 'target', '#app', ' div#question-detail-main-tabs', same, true],
  46. 'www.mcmod.cn': ['https://link.mcmod.cn/target/', '', 'body > div.col-lg-12.common-frame > div > div.col-lg-12.center > div.col-lg-12.right', '', mcmod, false],
  47. 'play.mcmod.cn': ['https://link.mcmod.cn/target/', '', 'body > div.col-lg-12.common-frame > div > div.col-lg-12.center', '', mcmod, false],
  48. 'www.mcbbs.net': ['https://www.mcbbs.net/plugin.php', 'target', 'div#ct', '', decodeURIComponent, false],
  49. 'www.minecraftforum.net': ['https://www.minecraftforum.net/linkout', 'remoteUrl', '.listing-container', '', decodeURIComponent, false],
  50. 'www.curseforge.com': ['https://www.curseforge.com/linkout', 'remoteUrl', '.project-page', ' > .tab-content', decodeURIComponent, true]
  51. };
  52. let domain = window.location.hostname;
  53. if (!(domain in fuck)) {
  54. for (let d in fuck) {
  55. if (domain.match(d)) {
  56. domain = d;
  57. break;
  58. }
  59. }
  60. }
  61. let suffix = fuck[domain][0];
  62. let query_name = fuck[domain][1];
  63. let main_path = fuck[domain][2];
  64. let dynamic = fuck[domain][3];
  65. let decode_func = fuck[domain][4];
  66. let always_listen = fuck[domain][5];
  67. let name = 'Wanta';
  68. let toast = (s, error=false) => {
  69. if (error) {
  70. console.error(`[${name}] ${s}`);
  71. } else {
  72. console.log(`[${name}] ${s}`);
  73. }
  74. };
  75. if (window.invoke_toastify) {
  76. window.invoke_toastify();
  77. toast = (s, error = false) => {
  78. window.toast(`[${name}] ${s}`, error);
  79. };
  80. }
  81. function purify(link) {
  82. let new_href;
  83. if (query_name.length == 0) {
  84. let l = link.href.split('/');
  85. new_href = l[l.length - 1];
  86. } else {
  87. let params = new URL(link.href).searchParams;
  88. new_href = params.get(query_name);
  89. }
  90. new_href = decode_func(new_href);
  91. if (new_href) {
  92. if (debug) console.log(`[${name} DEBUG] ${link.href} -> ${new_href}`);
  93. link.href = new_href;
  94. return true;
  95. }
  96. else {
  97. toast("Failed to purify below link element:", true);
  98. toast(link, true);
  99. return false;
  100. }
  101. }
  102. function main() {
  103. let target_node = document.querySelector(main_path + dynamic);
  104. let links;
  105. if (target_node) {
  106. links = target_node.getElementsByTagName('a');
  107. } else {
  108. return;
  109. }
  110. if (debug) console.log(links);
  111. let purified = 0;
  112. for (let i = 0;i < links.length; i++) {
  113. if (links[i].href.startsWith(suffix)) {
  114. if (purify(links[i])) purified++;
  115. } else if (debug) console.log(`[${name} DEBUG] Skipped "${links[i].href}".`);
  116. }
  117. if (purified > 0) {
  118. toast(`Purified ${purified} links out of ${links.length} links.`);
  119. } else {
  120. console.log(`[${name}] Purified ${purified} links out of ${links.length} links.`);
  121. }
  122. }
  123. if (dynamic) {
  124. const node = document.querySelector(main_path);
  125. const config = { attributes: false, childList: true, subtree: true };
  126. const callback = function(mutations, observer) {
  127. let article = node.querySelector(dynamic.slice(3));
  128. if (article) {
  129. main();
  130. if (!always_listen)
  131. observer.disconnect();
  132. }
  133. }
  134. const observer = new MutationObserver(callback);
  135. observer.observe(node, config);
  136. }
  137. else main();
  138. })();