diff options
Added invidious link replacer script
1 files changed, 80 insertions, 0 deletions
| -rw-r--r-- | youtube-invidious-link-replacer.js | 80 |
diff --git a/youtube-invidious-link-replacer.js b/youtube-invidious-link-replacer.js new file mode 100644 index 0000000..c1fbea5 --- /dev/null +++ b/youtube-invidious-link-replacer.js @@ -0,0 +1,80 @@ +// ==UserScript== +// @name YouTube to Invidious video link replacer +// @description Replace video links in the youtube site to their Invidious equivalents +// +// @version 1.0 +// @license MIT +// @author Syndamia +// +// @source https://gitlab.com/Syndamia/userscripts/-/blob/main/youtube-invidious-link-replacer.js +// @supportURL https://gitlab.com/Syndamia/userscripts/-/issues +// @homepage https://gitlab.com/Syndamia/userscripts/ +// @icon https://upload.wikimedia.org/wikipedia/commons/a/a0/Invidious-logo.svg +// +// @namespace Syndamia +// @match *://www.youtube.com/* +// @run-at document-start +// ==/UserScript== + +const invidiousInstance = 'yewtu.be'; + + + +// Wait for ytd-app element to appear +const ytdObserver = new MutationObserver(function(mutations) { + /* Detect when ytd-app element is present */ + + // Thanks https://stackoverflow.com/a/45267350/12036073 + if (document.getElementsByTagName('ytd-app').length > 0) { + disableCertainClickEventListeners(); // Refer to function for information + + /* When you open a link in YouTube, the site doesn't fully reload, but the ytd-app element + * (which contains the whole UI) is updated (and the website URL also updates). + * Also, YouTube's infinite scroll updates the ytd-app element, so the best way to detect + * when we need to fix links is when ytd-app changes. + */ + const observer = new MutationObserver(replaceAnchors); + observer.observe(document.getElementsByTagName('ytd-app')[0], { childList: true, attributes: true, subtree: true, }); + + ytdObserver.disconnect(); + } +}); + +ytdObserver.observe(document, {attributes: false, childList: true, characterData: false, subtree:true}); + +function replaceAnchors() { + for (var anchor of document.getElementsByTagName('ytd-app')[0].getElementsByTagName('a')) { + if (anchor.href.indexOf('www.youtube.com/watch') > 0) { + anchor.href = anchor.href.replace('www.youtube.com/watch', invidiousInstance + '/watch'); + } + } +} + +/* As already meantioned, opening a link in YouTube doesn't work like clicking on a normal anchor, + * it updates the ytd-app element and website URL. When clicking on a video, a special eventListener(s) + * handles loading the YouTube video page and if we don't disable it(them), even with anchors that href to + * a page outside YouTube, we'll still load the YouTube video as normal. + */ +function disableCertainClickEventListeners() { + /* It's not enough to only override the HTMLAnchorElement addEventListener function, + * from testing it seems that there are other elements that also have the appropriate event listeners + * which trigger opening of the YouTube player + */ + + // Thanks https://stackoverflow.com/a/57437878/12036073 + HTMLElement.prototype.oldaddEventListener = HTMLElement.prototype.addEventListener; + HTMLElement.prototype.addEventListener = function(event, handler, placeholder) { + if (event === 'click') { + /* The functions that actually handles clicking on videos to open player is this: + * (c){if(a[b])a[b](c,c.detail);else console.warn("listener method `"+b+"` not defined")} + * As far as I have tested, '_handleNative$$module$third_party$javascript$polymer$v2$polymer$lib$utils$gestures' and functions like: + * (a){a.target===this.liveBadge.element&&(this.api.seekTo(Infinity),this.api.playVideo())} + * don't play a direct role in the click video -> open player process. + */ + if (handler.toString().indexOf('c', 7) === 9) { + return; + } + } + this.oldaddEventListener(event, handler, placeholder); + } +} |
