Skip to content

Instantly share code, notes, and snippets.

@thypon
Last active December 19, 2022 23:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thypon/5078cd48c2c73b99293e1e22d17ec7c4 to your computer and use it in GitHub Desktop.
Save thypon/5078cd48c2c73b99293e1e22d17ec7c4 to your computer and use it in GitHub Desktop.
Mastodon HackFix hashtags
// ==UserScript==
// @name Fix Mastodon Hashtags
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Fix the hashtag issue in mastodon
// @author thypon@mastodon.social
// @match https://*/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Enable only if you are in a mastodon server
if (document.querySelector('body > #mastodon')) {
// https://stackoverflow.com/questions/6195729/most-efficient-way-to-prepend-a-value-to-an-array
function prepend(value, array) {
var newArray = array.slice();
newArray.unshift(value);
return newArray;
}
// https://stackoverflow.com/questions/18310484/modify-http-responses-from-a-chrome-extension
var _open = XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, URL) {
var _onreadystatechange = this.onreadystatechange,
_this = this;
_this.onreadystatechange = function () {
// catch only completed 'api/search/universal' requests
let params = new URLSearchParams(URL.split('?')[1]);
if (_this.readyState === 4
&& _this.status === 200
&& ~URL.indexOf('api/v2/search')
&& params.get('q')) {
try {
var data = JSON.parse(_this.responseText);
let nohashes = params.get('q').replaceAll('#', '')
if (data.hashtags) {
let dumbHashtag = {"name": nohashes,"url":`https://mastodon.social/tags/${nohashes}`,"history":[],"following":false}
data.hashtags = prepend(
dumbHashtag,
data.hashtags);
}
// rewrite responseText
Object.defineProperty(_this, 'responseText', {value: JSON.stringify(data)});
/////////////// END //////////////////
} catch (e) {}
console.log('Caught! :)', method, URL/*, _this.responseText*/);
}
// call original callback
if (_onreadystatechange) _onreadystatechange.apply(this, arguments);
};
// detect any onreadystatechange changing
Object.defineProperty(this, "onreadystatechange", {
get: function () {
return _onreadystatechange;
},
set: function (value) {
_onreadystatechange = value;
}
});
return _open.apply(_this, arguments);
};
}
})();
@hughbirkenhead
Copy link

Unfortunately this also breaks the autocomplete suggestions when typing hashtags in the New Post dialog. I added an additional check at Line 34 to exclude these lookups that seems to have resolved it:

if (_this.readyState === 4 && _this.status === 200 && ~URL.indexOf('api/v2/search') && params.get('q') && !params.get('type')) {

@thypon
Copy link
Author

thypon commented Dec 16, 2022

Updated to include the fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment