Skip to content

Instantly share code, notes, and snippets.

@Shog9
Last active September 5, 2018 18:32
Show Gist options
  • Save Shog9/c13c28c33f466ba7195cb9fd0eafc93a to your computer and use it in GitHub Desktop.
Save Shog9/c13c28c33f466ba7195cb9fd0eafc93a to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Reorderable favorite tags
// @description Allow the CPU to overheat when holding down the spacebar
// @author Shog9
// @namespace https://github.com/Shog9/
// @version 1.2
// @include http*://stackoverflow.com/*
// @include http*://*.stackoverflow.com/*
// @include http*://dev.stackoverflow.com/*
// @include http*://askubuntu.com/*
// @include http*://superuser.com/*
// @include http*://serverfault.com/*
// @include http*://mathoverflow.net/*
// @include http*://*.stackexchange.com/*
// @exclude http*://chat.*.com/*
// ==/UserScript==
// this serves only to avoid embarassing mistakes caused by inadvertently loading this script onto a page that isn't a Stack Exchange page
var isSEsite = false;
for (var s of document.querySelectorAll("script")) isSEsite = isSEsite||/StackExchange\.ready\(/.test(s.textContent);
// don't bother running this if this isn't a scripted SE page
if (!isSEsite)
{
return;
}
function with_jquery(f)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "if (window.jQuery) (" + f.toString() + ")(window.jQuery)" + "\n\n//# sourceURL=" + encodeURI(GM_info.script.namespace.replace(/\/?$/, "/")) + encodeURIComponent(GM_info.script.name); // make this easier to debug
document.body.appendChild(script);
}
with_jquery(function()
{
if ( !$(".js-watched-tag-list").length) return;
// load saved preferences, if any
var prefsKey = "ReorderableFavoriteTags" + (StackExchange.options.site.routePrefix||"");
var tagOrder = localStorage[prefsKey]||"";
tagOrder = tagOrder.split(",");
ApplyOrder();
// known bug: when editing ends, tags remain sortable
$(".js-edit-all-tags, .js-edit-watched-tags, .js-show-add-watched").click(function()
{
// What's gotta happen here:
// 1. Autocomplete plugin has to load: this almost certainly means that the event has to pass through to default handler before we do anything.
// 2. We have to load jQueryUI without stomping on the default autocomplete plugin
// 3. Finally, we can make the list sortable
waitForAutocomplete(function()
{
// the tag editor uses a very old version (somewhat patched) of jQuery.autocomplete
// jQueryUI uses a newer one
// they aren't compatible, at least not to the extent that the old one can initialize data and the new one can use it
// so, save before loading jQueryUI and restore afterwards
var oldAutocomplete = $.fn.autocomplete;
var oldAutocompleter = $.Autocompleter;
StackExchange.loadJqueryUi().then(function()
{
if ( oldAutocomplete ) $.fn.autocomplete = oldAutocomplete;
if ( oldAutocompleter ) $.fn.Autocompleter = oldAutocompleter;
$(".js-watched-tag-list").sortable({helper: "clone", update: SaveOrder});
});
});
});
// capture saving of tag additions / removals, trigger re-application and then saving of order thus imposing consistency
$(document)
.ajaxSuccess(function(event, XMLHttpRequest, ajaxOptions)
{
if (ajaxOptions.url.indexOf("/users/save-preference") == 0
|| /\/tags\/[^\/]\/favorite/.test(ajaxOptions.url)
|| /\/tags\/[^\/]\/prefs/.test(ajaxOptions.url) )
{
setTimeout(function() { ApplyOrder(); SaveOrder(); }, 0);
}
});
function waitForAutocomplete(callback, delay)
{
delay = delay ? Math.max(delay*10, 1000) : 1;
if ( $.fn.autocomplete ) callback();
else setTimeout(() => waitForAutocomplete(callback, delay), delay);
}
function ApplyOrder()
{
var tagsOnPage=$(".js-watched-tag-list>.js-tag");
for (let i=tagOrder.length-1; i>= 0; --i)
{
tagsOnPage.filter(function() { return this.textContent==tagOrder[i]}).prependTo(".js-watched-tag-list");
}
}
function SaveOrder()
{
tagOrder = $(".js-watched-tag-list>.js-tag").map(function() { return this.textContent }).toArray();
localStorage[prefsKey] = tagOrder.join();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment