Actually working youtube downloader

Actually working youtube downloader!

// ==UserScript==
// @name Actually working youtube downloader
// @description Actually working youtube downloader!
// @namespace https://greasyfork.org/users/152924
// @homepageURL https://greasyfork.org/scripts/34613
// @supportURL https://greasyfork.org/scripts/34613/feedback
// @author Punisher
// @version 9.1
// @date 2024-09-04
// @icon https://i.imgur.com/InuDDVK.png
// @compatible chrome
// @compatible firefox
// @compatible opera
// @compatible safari
// @compatible edge
// @license CC-BY-NC-ND-4.0
// @match https://*.youtube.com/*
// @grant GM_addStyle
// @run-at document-idle
// ==/UserScript==

(function() {
    var punisherYT = "https://youtubepp.com/";
    var tubeID = "dwnldBtn";
    var currentButton = "#owner";
    var addClick = `
        #${tubeID} {
            background-color: #272727;
            color: #f1f1f1;
            border: 0px solid;
            border-color: rgba(255,255,255,0.2);
            margin-left: 8px;
            padding: 0 16px;
            border-radius: 18px;
            font-size: 14px;
            font-family: Roboto, Noto, sans-serif;
            font-weight: 500;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            height: 36px;
            line-height: normal;
        }
        #${tubeID}:hover {
            background-color: #3f3f3f;
            color: #f1f1f1;
            border-color: #F1F1F1;
        }
    `;
    GM_addStyle(addClick);

    function inspectPg(selector) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) {
                return resolve(document.querySelector(selector));
            }
            var observer = new MutationObserver(mutations => {
                if (document.querySelector(selector)) {
                    resolve(document.querySelector(selector));
                    observer.disconnect();
                }
            });
            observer.observe(document.body,{childList: true, subtree: true});
        });
    }

    function addBtn() {
        inspectPg(currentButton).then((btnContainer) => {
            if (!btnContainer) {
                return;
            }
            if (document.querySelector(`#${tubeID}`)) {
            } else {
                var downloadBtn = document.createElement('a');
              
                downloadBtn.href = `${"https://youtubepp.com/" + window.location.href}`;
              
                downloadBtn.target = '_blank';
                downloadBtn.id = tubeID;
                downloadBtn.innerText = 'Download';
                btnContainer.appendChild(downloadBtn);
            }
        });
    }

    function pageLoad() {
        inspectPg(`#${tubeID}`).then((btn) => {
            if (!btn) {
                return;
            }
            btn.href = punisherYT + decodeURIComponent(extractYT(window.location));
        });
    }

    extractYT = function(url) {
        var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
        var match = String(url).match(regExp);
        return (match&&match[7].length==11)? match[7]: false;
    }

    let buttonSet = false;
    function checkButton() {
        if (window.location.pathname === '/watch' && !buttonSet) {
            addBtn();
            buttonSet = true;
            setTimeout(pageLoad, 2000);
        }
    }
    window.addEventListener("yt-navigate-finish", () => {
        buttonSet = false;
        checkButton();
    });
    checkButton();
})();