102 lines
3 KiB
JavaScript
102 lines
3 KiB
JavaScript
// ==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);
|
|
}
|
|
|
|
})();
|