|
// ==UserScript== |
|
// @name Fix Mastodon Hashtags |
|
// @namespace http://tampermonkey.net/ |
|
// @version 0.1 |
|
// @description Fix the hashtag issue in mastodon |
|
// @author [email protected] |
|
// @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); |
|
}; |
|
} |
|
})(); |
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')) {