🏠 Home 

YouTube link on Piped websites

Shows a YouTube link on Piped websites like https://piped.kavin.rocks.


Install this script?
// ==UserScript==
// @name         YouTube link on Piped websites
// @namespace    https://devture.com
// @license      AGPL-3.0-or-later
// @version      1.2
// @description  Shows a YouTube link on Piped websites like https://piped.kavin.rocks.
// @copyright 2022, Slavi Pantaleev (https://devture.com)
// @author       s.pantaleev
// @grant        none
// @match        https://piped.kavin.rocks/*
// @match        https://piped.video/*
// ==/UserScript==
(function() {
'use strict';
let injectButtonNextToOther = function (otherButton) {
let queryString = window.location.href.split('?')[1];
let queryParamsMap = {};
let keyValPairs = queryString.split('&');
keyValPairs.forEach(function (keyValPairString) {
let keyValPair = keyValPairString.split('=');
queryParamsMap[keyValPair[0]] = keyValPair[1];
});
if (typeof(queryParamsMap.v) === 'undefined') {
console.log('Could not find "v" query-string parameter. Likely not on a /watch page.');
return;
}
let youtubeUrl = 'https://www.youtube.com/watch?v=' + queryParamsMap.v;
let containerElement = otherButton.closest('div');
let newButton = document.createElement('a');
newButton.href = youtubeUrl;
newButton.target = '_blank';
newButton.classList = ['btn', 'flex-col'];
newButton.textContent = '📺 YouTube';
containerElement.appendChild(newButton);
};
// Piped is a SPA application. We can't inject a new button into it until it has loaded.
// With the mutation observer below, we're waiting for some known button element to appear
// (signifying that the page has loaded), before running our logic above.
//
// The observer below may run more than just once.
// Piped intercepts link clicks and loads new pages into the same DOM, without a full page reload (PJAX-style).
let rssButtonSelector = 'a[title="RSS feed"]';
let observer = new MutationObserver(mutations => {
for (let mutation of mutations) {
for (let node of mutation.addedNodes) {
// Skip text nodes, etc.
if (!(node instanceof HTMLElement)) {
continue;
}
let rssButton = null;
// Check if the added node is the button itself,
// or fall back to looking for the button within the added node's children.
if (node.matches(rssButtonSelector)) {
rssButton = node;
} else {
rssButton = node.querySelector(rssButtonSelector);
}
if (rssButton !== null) {
injectButtonNextToOther(rssButton);
}
}
}
});
observer.observe(window.document, {childList: true, subtree: true});
})();