// ==UserScript== // @name Open Fedi In My Instance // @namespace http://pix.solarpunk.moe // @version 0.1 // @description Open a Pixelfed post on your own instance by clicking the external link icon! For now, this is Pixelfed only. // @author Vivi // @match https://*/* // @icon https://www.google.com/s3/favicons?sz=64&domain=pixelfed.social // @grant GM_xmlhttpRequest // @connect pix.solarpunk.moe // ==/UserScript== (function() { 'use strict'; const MY_INSTANCE = 'https://pix.solarpunk.moe'; if (document.URL.startsWith(`${MY_INSTANCE}/`)) { return; } var MutationObserver = window.MutationObserver; var myObserver = new MutationObserver (mutationHandler); var obsConfig = { childList: true, attributes: true, subtree: true, attributeFilter: ['class'] }; myObserver.observe (document, obsConfig); function mutationHandler (mutationRecords) { mutationRecords.forEach ( (mutation) => { if (mutation.type == "childList" && typeof mutation.addedNodes == 'object' && mutation.addedNodes.length) { for (let node of mutation.addedNodes) { processNode(node); } } else if (mutation.type == 'attributes') { processNode(mutation.target); } } ); } function processNode (node) { if (node.nodeType !== 1) { return; } if (node.classList.contains('container-fluid')) { for (let n of node.querySelectorAll('.timeline-status-component')) { processNode(n); } return; } if (!node.classList.contains('timeline-status-component')) { return; } let linkNode = node.querySelector('.timestamp'); if (!linkNode) { return; } let link = linkNode.href; let externalButton = document.createElement('button'); let icon = document.createElement('i'); externalButton.appendChild(icon); icon.classList = 'far fa-external-link'; externalButton.classList = 'btn btn-dark'; externalButton.onclick = () => { icon.classList = 'far fa-spinner fa-pulse'; GM_xmlhttpRequest({ method: 'GET', url: `${MY_INSTANCE}/api/search?scope=remote&v=2&src=metro&q=${encodeURIComponent(link)}`, responseType: 'json', onerror: (e) => { console.error(e); icon.classList = 'far fa-external-link'; }, onload: (r) => { window.open(`${MY_INSTANCE}${r.response.posts[0].url}`,'popup','width=365,height=960'); icon.classList = 'far fa-external-link'; } }); }; // Find the dot menu let dotMenu = node.querySelector('.card-header > .media > .btn-link'); dotMenu.before(externalButton); } })();