Block reddit click tracking

Stops reddit from tracking your inbound and outbound clicks

当前为 2018-04-29 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Block reddit click tracking
  3. // @namespace mjhcfwlmjfzg778evppa995xavvt2nmb
  4. // @description Stops reddit from tracking your inbound and outbound clicks
  5. // @match *://*.reddit.com/*
  6. // @version 1.2
  7. // @grant unsafeWindow
  8. // @run-at document-start
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. "use strict";
  13.  
  14. const expiredDate = Date.now().toString();
  15. const targetLink = Symbol();
  16.  
  17.  
  18. // Capturing event listener on the outermost element.
  19. // Runs FIRST, before any others.
  20. const beforeClick = function (event) {
  21. let target = event.target;
  22.  
  23. // Did we click on an element?
  24. if (target.nodeType === 1) {
  25. // Is that element inside a link?
  26. target = target.closest("a");
  27.  
  28. if (target) {
  29. // Stash link in the event object so that
  30. // the second handler doesn't have to dig
  31. // through the DOM with .closest() again
  32. event[targetLink] = target;
  33.  
  34. if (target.dataset.hrefUrl) {
  35. // Remove link tracking attributes
  36. delete target.dataset.inboundUrl;
  37. delete target.dataset.outboundUrl;
  38.  
  39. // Mark outbound link as expired so reddit code
  40. // does not try to use it
  41. if (target.dataset.outboundExpiration) {
  42. target.dataset.outboundExpiration = expiredDate;
  43. }
  44. }
  45. }
  46. }
  47. };
  48.  
  49.  
  50. // Bubbling event listener on the outermost element.
  51. // Runs LAST, just before the click goes through
  52. // (unless reddit code adds any others afterwards)
  53. const justBeforeClick = function (event) {
  54. const target = event[targetLink];
  55.  
  56. // If reddit event handlers modified the link, change it back
  57. if (target && target.dataset.hrefUrl) {
  58. target.href = target.dataset.hrefUrl;
  59. }
  60. };
  61.  
  62.  
  63. // Mark both event listeners as passive so they
  64. // won't impact scroll performance
  65. const doCapture = { capture: true, passive: true };
  66. const doBubble = { capture: false, passive: true };
  67.  
  68. window.addEventListener("mousedown", beforeClick, doCapture);
  69. window.addEventListener("keydown", beforeClick, doCapture);
  70. window.addEventListener("touchstart", beforeClick, doCapture);
  71.  
  72. window.addEventListener("mousedown", justBeforeClick, doBubble);
  73. window.addEventListener("keydown", justBeforeClick, doBubble);
  74. window.addEventListener("touchstart", justBeforeClick, doBubble);
  75.  
  76.  
  77. // Patch navigator.sendBeacon() if it is available
  78. if (typeof unsafeWindow.Navigator.prototype.sendBeacon === "function") {
  79. // Firefox/Greasemonkey defines exportFunction to make
  80. // sandboxed functions callable by the page script.
  81. const exportFunction = (window.exportFunction) ? window.exportFunction : (f) => f;
  82.  
  83. // Fake sendBeacon() function that does nothing
  84. Reflect.defineProperty(unsafeWindow.Navigator.prototype, "sendBeacon", {
  85. value: exportFunction(function sendBeacon(url) { return true; }, unsafeWindow)
  86. });
  87. }
  88. })();