Open As User Script

Opens gitlab or github files as a userscript on Violentmonkey

As of 2024-08-28. See the latest version.

// ==UserScript==
// @name         Open As User Script
// @namespace    https://gitlab.com/Dwyriel
// @version      0.3.1
// @description  Opens gitlab or github files as a userscript on Violentmonkey
// @author       Dwyriel
// @license      MIT
// @match        *://*gitlab.com/*
// @match        *://*github.com/*
// @grant        none
// @run-at       document-idle
// @homepageURL  https://gitlab.com/Dwyriel/Greasyfork-Scripts
// ==/UserScript==

(function () {
    'use strict';
    const imgData = "data:image/png;base64,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";
    const elementID = "OaUS_g893n1g7f561nf";
    const config = { attributes: true, childList: true, subtree: true };
    function openUrl(url) {
        var newWindow = window.open(url, "File as UserScript");
        let intervalHandler = setInterval(() => {
            if (newWindow.closed) {
                clearInterval(intervalHandler);
                return;
            }
            newWindow.close();
        }, 1000);
    }
    function genUrlFromGitlab() {
        let url = window.location.toString().replace('blob', 'raw');
        return url.includes("?") ? `${url}&file=as/script.user.js` : `${url}?file=as/script.user.js`;
    }
    function genUrlFromGithub() {
        let url = window.location.toString().replace('github.com', 'raw.githubusercontent.com').replace('blob/', '');
        return url.includes("?") ? `${url}&file=as/script.user.js` : `${url}?file=as/script.user.js`;
    }
    function gitlabCallback() {
        if (document.getElementById(elementID))
            return;
        let btnToClone = document.querySelector(`div[data-testid="default-actions-container"]`)?.querySelector("[title*='raw']");
        if (!btnToClone)
            return;
        let clonedNode = btnToClone.cloneNode(true);
        let img = document.createElement("img");
        let svg = clonedNode.children[0];
        img.classList = svg.classList;
        img.setAttribute('src', imgData);
        svg.after(img);
        svg.remove();
        clonedNode.id = elementID;
        clonedNode.removeAttribute('href');
        clonedNode.setAttribute('aria-label', "Open as Userscript");
        clonedNode.setAttribute('title', "Open as Userscript");
        clonedNode.onclick = function () { openUrl(genUrlFromGitlab()) };
        btnToClone.after(clonedNode);
    }
    function githubCallbcak() {
        if (document.getElementById(elementID))
            return;
        let btnToClone = document.querySelectorAll('[class*="ButtonGroup"]')[0]?.parentNode.querySelector('[data-testid*="copy-raw"]');
        if (!btnToClone)
            return;
        let clonedNode = btnToClone.cloneNode(true);
        let img = document.createElement("img");
        let svg = clonedNode.children[0];
        img.classList = svg.classList;
        img.setAttribute('src', imgData);
        img.setAttribute('width', 16);
        img.setAttribute('height', 16);
        svg.after(img);
        svg.remove();
        clonedNode.id = elementID;
        clonedNode.removeAttribute('data-hotkey');
        clonedNode.removeAttribute('aria-describeby');
        clonedNode.setAttribute('aria-label', "Open as Userscript");
        clonedNode.setAttribute('title', "Open as Userscript");
        clonedNode.setAttribute('data-testid', "open-as-userscript");
        clonedNode.onclick = function () { openUrl(genUrlFromGithub()) };
        btnToClone.after(clonedNode);
    }
    if (window.location.toString().includes("//gitlab.com/"))
        new MutationObserver(gitlabCallback).observe(document.body, config);
    else
        new MutationObserver(githubCallbcak).observe(document.body, config);
})();