YTShareAntiTrack

Remove any tracking parameters from the YouTube share feature

  1. // ==UserScript==
  2. // @name YTShareAntiTrack
  3. // @namespace https://github.com/Xenorio/YTShareAntiTrack
  4. // @version 1.2.1
  5. // @license AGPL-3.0-or-later
  6. // @description Remove any tracking parameters from the YouTube share feature
  7. // @author xenorio
  8. // @match https://www.youtube.com/*
  9. // @match https://m.youtube.com/*
  10. // @match https://music.youtube.com/*
  11. // @grant GM.getValue
  12. // @grant GM.setValue
  13. // @grant GM.openInTab
  14. // ==/UserScript==
  15.  
  16. // Copyright (C) 2023 Marcus Huber (xenorio) <dev@xenorio.xyz>
  17. //
  18. // This program is free software: you can redistribute it and/or modify
  19. // it under the terms of the GNU Affero General Public License as
  20. // published by the Free Software Foundation, either version 3 of the
  21. // License, or (at your option) any later version.
  22. //
  23. // This program is distributed in the hope that it will be useful,
  24. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. // GNU Affero General Public License for more details.
  27. //
  28. // You should have received a copy of the GNU Affero General Public License
  29. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  30.  
  31. (function () {
  32.  
  33. // How fast we should check for element changes (ms)
  34. const updateInterval = 50
  35.  
  36. // Parameters which are allowed to stay in the URL
  37. const allowedParams = [
  38. "t", // start time
  39. "list", // playlist ID
  40. "v" // video ID
  41. ]
  42.  
  43. // Identifiers for all elements to target
  44. const elementIdentifiers = {
  45. id: [
  46. 'share-url' // Input field on desktop
  47. ],
  48. class: [
  49. 'unified-share-url-input' // Input field on mobile
  50. ]
  51. }
  52.  
  53. // Element has been found, update URL
  54. function handleTargetElement(targetElement) {
  55.  
  56. // Set up a copy of the current URL to work on
  57. let url = new URL(targetElement.value)
  58. let params = url.searchParams
  59.  
  60. // Remove all parameters that are not allowed
  61. for (let param of params.keys()) {
  62. if (!allowedParams.includes(param)) {
  63. params.delete(param)
  64. }
  65. }
  66.  
  67. url.search = params
  68.  
  69. let newValue = url.toString()
  70.  
  71. // Abort if everything is already correct
  72. if (targetElement.value == newValue) return;
  73.  
  74. console.log('[YTShareAntiTrack] Changing share url from ' + targetElement.value + ' to ' + newValue)
  75.  
  76. // Update element
  77. targetElement.value = newValue
  78. }
  79.  
  80. // Repeatedly look for the element, and if it's there, change it
  81. setInterval(() => {
  82.  
  83. // Gather all elements which should be modified based on their ID
  84. for (let identifier of elementIdentifiers.id) {
  85. const element = document.getElementById(identifier)
  86. if (element) {
  87. handleTargetElement(element)
  88. }
  89. }
  90.  
  91. // Gather all elements which should be modified based on their class
  92. for (let identifier of elementIdentifiers.class) {
  93. const elements = document.getElementsByClassName(identifier)
  94. if (elements) {
  95. for (let element of elements) {
  96. handleTargetElement(element)
  97. }
  98. }
  99. }
  100.  
  101. }, updateInterval)
  102.  
  103. // Handle opening the notice page for transitioning to the TubeTweaks extension
  104. try {
  105.  
  106. // Check if the notice has been opened already
  107. GM.getValue("transitionPageVisited")
  108. .then(hasVisited => {
  109. if (hasVisited) return;
  110.  
  111. // Remember that the notice has already been opened
  112. // We do this first to prevent race conditions which would open tons of tabs
  113. GM.setValue("transitionPageVisited", true)
  114. .then(() => {
  115.  
  116. // Open the notice page, and focus it
  117. GM.openInTab("https://extensions.xenorio.xyz/tubetweaks-migration", {
  118. active: true
  119. })
  120. })
  121.  
  122. })
  123.  
  124. } catch (error) {
  125. // GreaseMonkey API not supported
  126. console.log('Goshdarn get a better userscript manager')
  127. }
  128.  
  129. })();