Reddit Link Hijack Remover

Remove link-click tracking from reddit

  1. // ==UserScript==
  2. // @name Reddit Link Hijack Remover
  3. // @author jmesmon
  4. // @description Remove link-click tracking from reddit
  5. // @include *://reddit.com/*
  6. // @include *://*.reddit.com/*
  7. // @grant none
  8. // @namespace https://github.com/jmesmon
  9. // @license AGPL3
  10. // @supportURL https://github.com/jmesmon/greasy/issues
  11. // @run-at document-end
  12. // @version 0.0.1.20210226040629
  13. // ==/UserScript==
  14.  
  15. // TODO: consider if run-at document-start is useful, and how we can
  16. // effectively hook urls as they show up in that case (right now it doesn't
  17. // work).
  18.  
  19. (function () {
  20. 'use strict';
  21. function cl(ac) {
  22. var a = ac.querySelectorAll('a.outbound');
  23. var ct_out = 0, ct_aff = 0, ct = 0, ct_in = 0;
  24. for (var i = 0; i < a.length; i++) {
  25. /*
  26. // This is reddit's function to determine the url, which is stored in `o`.
  27. // It then hooks window unload to call sendBeacon with the url in `o` or
  28. // modifies the href attribute (if sendBeacon is disabled in config or unsupported by the browser).
  29. function o(e) {
  30. var t = $(e),
  31. r = Date.now(),
  32. o;
  33. return t.attr('data-inbound-url')
  34. ? o = t.attr('data-inbound-url')
  35. : !n && t.attr('data-outbound-expiration') > r && (o = t.attr('data-outbound-url')),
  36. o && (i ? s = o : e.href = o),
  37. !0
  38. }
  39. */
  40.  
  41. // Some minimal counting so we can tell things are working
  42. if (a[i].getAttribute('data-inbound-url')) {
  43. ct_in++;
  44. }
  45. if (a[i].getAttribute('data-affiliate-url')) {
  46. ct_aff++;
  47. }
  48. if (a[i].getAttribute('data-outbound-url') || a[i].getAttribute('data-outbound-expiration')) {
  49. ct_out++;
  50. }
  51.  
  52. // Goals:
  53. // - make sure `o` stays undefined.
  54. // - avoid ever getting this function called
  55. // Removing all the relevent attributes gets us both of those
  56.  
  57. // Unclear what the purpose of these is, but they are being used to
  58. // re-write urls (and trigger entry to the fn above), so remove.
  59. a[i].removeAttribute('data-inbound-url');
  60.  
  61. // Doesn't appear that reddit is injecting these affiliate links
  62. // anymore, but no reason to remove this
  63. a[i].removeAttribute('data-affiliate-url');
  64.  
  65. // We don't actually need to remove this, but it does short circuit
  66. // the condition quicker & cleans up the html, so do it.
  67. a[i].removeAttribute('data-outbound-expiration');
  68. a[i].removeAttribute('data-outbound-url');
  69. a[i].classList.remove('outbound');
  70. ct++;
  71. }
  72.  
  73. console.log('hijacks removed: outbound ' + ct_out + ', inbound ' + ct_in + ', affiliate ' + ct_aff + ', examined ' + ct);
  74. }
  75.  
  76. var obs = new MutationObserver(function (r, self) {
  77. for (var i = 0; i < r.length; i++) {
  78. var ad = r[i].addedNodes;
  79. for (var j = 0; j < ad.length; j++) {
  80. var n = ad[j];
  81. cl(n);
  82. }
  83. }
  84. });
  85. obs.observe(document, {
  86. childList: true,
  87. subtree: true
  88. });
  89.  
  90. // TODO: consider patching out window.navigator.sendBeacon (which reddit only uses for this link tracking)
  91. // TODO: consider blocking the recent_srs cookie used for tracking
  92. cl(document);
  93. }) ();
  94.