remove_redirect

remove redirects in zhihu.com

  1. // ==UserScript==
  2. // @name remove_redirect
  3. // @namespace https://github.com/mikelxk/remove_redirect
  4. // @version 0.1.0
  5. // @author mikelxk
  6. // @description remove redirects in zhihu.com
  7. // @license MIT
  8. // @icon https://vitejs.dev/logo.svg
  9. // @match *://*.zhihu.com/*
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. const updatedLinks = /* @__PURE__ */ new WeakSet();
  17. const ZHIHU_PATTERNS = [
  18. "https://link.zhihu.com/?target=",
  19. "http://link.zhihu.com/?target="
  20. ];
  21. function debounce(fn, delay) {
  22. let timeoutId;
  23. return (...args) => {
  24. clearTimeout(timeoutId);
  25. timeoutId = setTimeout(() => fn(...args), delay);
  26. };
  27. }
  28. function updateLinkHref(link) {
  29. try {
  30. const href = link.href;
  31. if (!ZHIHU_PATTERNS.some((pattern) => href.includes(pattern))) {
  32. return null;
  33. }
  34. const urlParams = new URLSearchParams(href.split("?")[1]);
  35. const newLink = urlParams.get("target");
  36. if (!newLink) return null;
  37. const decodedLink = decodeURIComponent(newLink);
  38. link.href = decodedLink;
  39. return decodedLink;
  40. } catch (error) {
  41. console.error("Error updating link:", error);
  42. return null;
  43. }
  44. }
  45. function updateAllLinks() {
  46. const links = document.getElementsByTagName("a");
  47. Array.from(links).forEach((link) => updateLinkHref(link));
  48. }
  49. const debouncedObserverCallback = debounce((mutations) => {
  50. mutations.forEach((mutation) => {
  51. if (mutation.type === "childList") {
  52. mutation.addedNodes.forEach((node) => {
  53. if (node instanceof HTMLElement) {
  54. if (node instanceof HTMLAnchorElement) {
  55. updateLinkHref(node);
  56. } else {
  57. const links = node.getElementsByTagName("a");
  58. Array.from(links).forEach((link) => updateLinkHref(link));
  59. }
  60. }
  61. });
  62. }
  63. });
  64. }, 100);
  65. document.addEventListener("DOMContentLoaded", updateAllLinks);
  66. const observer = new MutationObserver(debouncedObserverCallback);
  67. observer.observe(document.body, {
  68. childList: true,
  69. subtree: true
  70. });
  71. window.addEventListener("unload", () => {
  72. observer.disconnect();
  73. });
  74. const listenedEvents = ["click", "mouseover"];
  75. listenedEvents.forEach((eventName) => {
  76. document.addEventListener(eventName, (event) => {
  77. const target = event.target;
  78. if (target.tagName === "A") {
  79. const link = target;
  80. if (!updatedLinks.has(link)) {
  81. const newHref = updateLinkHref(link);
  82. if (newHref) {
  83. updatedLinks.add(link);
  84. if (eventName === "click") {
  85. event.preventDefault();
  86. window.location.href = newHref;
  87. }
  88. }
  89. }
  90. }
  91. });
  92. });
  93.  
  94. })();