98 lines
3.5 KiB
JavaScript
98 lines
3.5 KiB
JavaScript
// ==UserScript==
|
|
// @name Remote Instance Actions
|
|
// @namespace https://hollymcfarland.com
|
|
// @version 1.2
|
|
// @description Easily limit a remote instance from your Mastodon instance via the timeline
|
|
// @author monorail
|
|
<?php
|
|
foreach ($_GET["instances"] as $instance) {
|
|
echo "// @match https://*.{$instance}/*" . PHP_EOL;
|
|
}
|
|
?>
|
|
// @grant GM_openInTab
|
|
// @run-at context-menu
|
|
// ==/UserScript==
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
// Check whether the domain is already limited on the instance, and open the relevant form if not
|
|
// This is imperfect, it just does a search of limited domains in the admin backend
|
|
// This means it handles substrings weirdly, and interacts weirdly with suspending subdomains
|
|
// But there's an override so it's not so bad
|
|
function checkStatus(domain, callback) {
|
|
function resultsFound(response) {
|
|
// reconstruct the results page in memory
|
|
const parser = new DOMParser();
|
|
const resultsPage = parser.parseFromString(response, "text/html");
|
|
|
|
// .directory__tag is the class for the div with results, if it exists
|
|
// so its presense indicates that a result was found, and the current domain is likely limited
|
|
return resultsPage.getElementsByClassName("directory__tag").length;
|
|
}
|
|
|
|
// perform a search for limited instances that match the highlighted text
|
|
let url = `https://${window.location.host}/admin/instances?utf8=%E2%9C%93&limited=1&by_domain=${domain}`;
|
|
let request = new XMLHttpRequest();
|
|
request.open('GET', url);
|
|
|
|
request.addEventListener('load', function() {
|
|
if (request.status === 403) {
|
|
alert("You are not logged in to an administrator account.");
|
|
return;
|
|
}
|
|
if (request.status !== 200 && !confirm("Recieved unexpected HTML status code. Continue anyway?")) {
|
|
return;
|
|
}
|
|
|
|
if (!resultsFound(request.response) || confirm(`${domain} may already be limited. Continue anyway?`)) {
|
|
callback(domain);
|
|
}
|
|
});
|
|
|
|
request.send();
|
|
}
|
|
|
|
// Open a new tab to the form for applying moderation actions to the selected domain
|
|
function newBlock(domain) {
|
|
GM_openInTab(`https://${window.location.host}/admin/domain_blocks/new?_domain=${domain}`, false);
|
|
}
|
|
|
|
// Clean up the selected domain
|
|
function sanitize(domain) {
|
|
// clear out accidental whitespace
|
|
domain = domain.trim();
|
|
|
|
// in case it's written like "domain dot tld"
|
|
domain = domain.replace(/\s+dot\s+/, ".");
|
|
|
|
// in case a full link was provided
|
|
domain = domain.replace(/https?:\/\//, "");
|
|
|
|
// in case the domain is being copied from a user@domain string
|
|
domain = domain.split("@").slice(-1)[0];
|
|
|
|
// in case the domain has a path included
|
|
domain = domain.split("/")[0];
|
|
|
|
return domain;
|
|
}
|
|
|
|
// Make sure a domain was actually selected
|
|
// This is imperfect, but can be overridden in case of a false negative
|
|
function validate(domain) {
|
|
// For now just check for a domain + tld and no whitespace
|
|
return domain.includes(".") && !domain.match(/\s/);
|
|
}
|
|
|
|
let domain = sanitize(document.getSelection().toString());
|
|
if (!domain.trim()) {
|
|
alert("Nothing selected.");
|
|
return;
|
|
}
|
|
|
|
if (validate(domain) || confirm(`Are you sure you meant to select "${domain}"?`)) {
|
|
checkStatus(domain, newBlock);
|
|
}
|
|
})();
|