Skip to content

Instantly share code, notes, and snippets.

@jakejarvis
Last active December 17, 2022 15:57
Show Gist options
  • Save jakejarvis/3d715d10de907145e51a1d4ca0ef1ee3 to your computer and use it in GitHub Desktop.
Save jakejarvis/3d715d10de907145e51a1d4ca0ef1ee3 to your computer and use it in GitHub Desktop.
(function() {
/* Mastodon switcher https://homepages.inf.ed.ac.uk/imurray2/code/mastodon.html */
myInstance = 'mastodon.social'; /* usernames are @ this string */
myInstanceURL = myInstance; /* Mastodon instance website with no https:// or trailing slash */
ver3 = false; /* set to true if your instance runs Mastodon v3 */
function getJsonObject(URL){
var req = new XMLHttpRequest();
req.open('GET', URL, false);
req.send(null);
return JSON.parse(req.responseText);
}
function mastodonURL(origURL, myInstance, myInstanceURL, ver3) {
/* If a fancy redirection didn't work, back it out */
mm = origURL.href.match(/.*authorize_interaction\?uri=(.*)/);
if (mm) {
return decodeURIComponent(mm[1]);
}
/* Otherwise try to work out pieces of the URL */
pathname = origURL.pathname;
match = pathname.match(/^\/(@|users\/|web\/@)([^\/@]*)@?([^\/]*)(\/?.*)/);
user = match[2];
extra = match[4];
if (extra.match(/^\/[0-9]+$/)) {
/* post numbers need rewriting between instances, so can't just move URL pieces around */
if (origURL.hostname == myInstanceURL) {
/* Our home instance should already have a link on the page that we can follow. */
datetimeEl = document.getElementsByClassName('detailed-status__datetime')[0];
datetimeURL = new URL(datetimeEl.href);
if (datetimeURL.hostname == origURL.hostname) {
/* In Mastodon from about v4.0.2 datetime link stays on local server, and need to find link in pop-up menu.
It is beginning to feel like chasing webpage changes is a losing battle, and should be using an API to get JSON data instead? */
datetimeEl.parentElement.parentElement.parentElement.parentElement.getElementsByClassName('detailed-status__action-bar-dropdown')[0].children[0].click();
return document.getElementsByClassName('dropdown-menu__item')[0].childNodes[0].href;
} else {
return datetimeURL;
}
} else {
/* Foreign instances won't know what link we want, so ask myInstance to rewrite the link */
return 'https://' + myInstanceURL + '/authorize_interaction?uri=' + encodeURIComponent(origURL);
}
} else {
/* URLs without post numbers, combine pieces of URL ourselves. */
pageOrigInstance = match[3];
if (! pageOrigInstance) {
metas = document.getElementsByTagName('meta');
for (i=0; i < metas.length; i++) {
if (metas[i].getAttribute('property') == 'profile:username') {
pageOrigInstance = metas[i].getAttribute('content').split('@')[1];
}
}
}
pageOrigInstance = pageOrigInstance || origURL.hostname;
if (origURL.hostname == myInstanceURL) {
/* redirecting out. /web/@username/ always works, because in v4 it's the @username@domain.ext form that fails (the .ext gets stripped) */
/* Frustratingly the intance's actual URL might not be the same as the domain in the username.
Across Mastodon versions, hard to reliably pull instance URL out of the page. So have to make another request to be sure :-( */
data = getJsonObject('https://' + origURL.hostname + '/api/v1/accounts/lookup?acct=' + user + '%40' + pageOrigInstance);
pageOrigInstanceURL = (new URL(data.url)).hostname || pageOrigInstance;
return 'https://' + pageOrigInstanceURL + '/web/@' + user + extra;
} else {
/* redirecting in. Bug in v4 redirection https://github.com/mastodon/mastodon/issues/20145 means /web/ paths don't work if myInstance is running an early v4 release, but /web/ needed for v3. */
if (ver3) {
sep = '/web/@'
} else {
sep = '/@'
}
if (pageOrigInstance != myInstance) {
user = user + '@' + pageOrigInstance;
}
return 'https://' + myInstanceURL + sep + user + extra;
}
}
}
newURL = mastodonURL(document.location, myInstance, myInstanceURL, ver3);
/* The `if` is for XSS protection */
if (newURL.match(/^https?:\/\//)) {
document.location = newURL;
}
})()
(function() {
showButtons = document.getElementsByClassName('status__content__spoiler-link--show-more');
hideButtons = document.getElementsByClassName('status__content__spoiler-link--show-less');
if ((showButtons.length + hideButtons.length) == 0) {
/* Either no CW buttons, or using older Mastodon client.
For older Mastodon clients, work out if content after button is hidden in fragile way. */
allButtons = document.getElementsByClassName('status__content__spoiler-link');
showButtons = [];
hideButtons = [];
for (i=0; i < allButtons.length; i++) {
if (allButtons[i].parentElement.nextElementSibling.offsetParent) {
/* currently visible */
hideButtons.push(allButtons[i]);
} else {
showButtons.push(allButtons[i]);
}
}
}
if (showButtons.length == 0) {
buttons = hideButtons;
} else {
buttons = showButtons;
}
for (i = buttons.length - 1; i >= 0; i--) {
buttons[i].click();
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment