Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit368b55361b5c90a381a942e5486a841ab4fd572e (patch)
Author
 Kamen Mladenov <kamen.d.mladenov@protonmail.com>
2022-04-17 06:45:12 +0000
Committer
 Kamen Mladenov <kamen.d.mladenov@protonmail.com>
2022-04-17 06:45:12 +0000
Filesb0d0edc8e0e64fc437e3009e3c95fb0f60f6883b
userscripts-368b55361b5c90a381a942e5486a841ab4fd572e.tar
userscripts-368b55361b5c90a381a942e5486a841ab4fd572e.tar.gz
userscripts-368b55361b5c90a381a942e5486a841ab4fd572e.zip
Parent326ee2a5dc669d6953ce55da873ed7bfdf2a1f4a (diff)
Added invidious link replacer script
1 files changed, 80 insertions, 0 deletions
-rw-r--r--youtube-invidious-link-replacer.js80
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);
+ }
+}