MediaWiki:Gadget-HotCatCustomizer.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/*
HotCat Customizer
Author: Mark W. Datysgeld
License: GPL-3.0
Purpose:
- Keep (+) "add" and (−) "remove" buttons.
- Suppress (↑) (↓) "arrows" and/or (±) "change".
- No API monkey-patching or constructor overrides.
Configuration:
- window.hotcat_customize = {
removeArrows: true, // default: remove ↑ ↓
removeChange: true // default: remove ±
};
*/
(function ($, mw) {
'use strict';
// # Configuration
var cfg = (function resolveConfig () {
// Defaults: true
var defaults = { removeArrows: true, removeChange: true };
var obj = (window.hotcat_customize && typeof window.hotcat_customize === 'object') ? window.hotcat_customize : {};
return {
removeArrows: typeof obj.removeArrows === 'boolean' ? obj.removeArrows : defaults.removeArrows,
removeChange: typeof obj.removeChange === 'boolean' ? obj.removeChange : defaults.removeChange
};
}());
// # Helpers
function getLabels() {
var HC = window.HotCat || {};
var links = HC.links || {};
// Fallbacks mirror HotCat defaults
return {
add: (typeof links.add === 'string') ? links.add : '(+)',
remove:(typeof links.remove === 'string') ? links.remove: '(\u2212)',
change:(typeof links.change === 'string') ? links.change: '(±)',
up: (typeof links.up === 'string') ? links.up : '(\u2191)',
down: (typeof links.down === 'string') ? links.down : '(\u2193)'
};
}
// Remove adjacent leading whitespace text node (HotCat tends to add ' ' around anchors)
function removeLeadingSpace(node) {
var prev = node && node.previousSibling;
if (prev && prev.nodeType === 3 && !/\S/.test(prev.nodeValue)) {
prev.parentNode.removeChild(prev);
}
}
// Conservative pruning
function pruneUI(scope) {
var root = scope || document;
var labels = getLabels();
var removeTexts = new Set();
if (cfg.removeArrows) {
removeTexts.add(labels.up);
removeTexts.add(labels.down);
}
if (cfg.removeChange) {
removeTexts.add(labels.change);
}
if (!removeTexts.size) return;
// Limit scope to category links container for safety
var container = root.querySelector ? (root.querySelector('#mw-normal-catlinks') || root.querySelector('#catlinks') || root) : root;
var anchors = container.querySelectorAll ? container.querySelectorAll('.hotcatlink a') : [];
for (var i = 0; i < anchors.length; i++) {
var a = anchors[i];
var text = (a.textContent || '').trim();
if (removeTexts.has(text)) {
removeLeadingSpace(a);
if (a.parentNode) a.parentNode.removeChild(a);
}
}
// Light cleanup to remove empty inline spans inside .hotcatlink (no anchors and only whitespace)
var spans = container.querySelectorAll ? container.querySelectorAll('.hotcatlink span') : [];
for (var j = 0; j < spans.length; j++) {
var span = spans[j];
if (!span.querySelector('a') && !/\S/.test(span.textContent || '')) {
if (span.parentNode) span.parentNode.removeChild(span);
}
}
}
// Prefer configuration to prevent arrows being created at all
function preConfig() {
if (!window.HotCat) return;
try {
if (cfg.removeArrows) {
window.HotCat.use_up_down = false;
}
// Do not alter suggestions
} catch (e) {}
}
// Observe only the category links area
function observe() {
var target = document.getElementById('mw-normal-catlinks') || document.getElementById('catlinks') || document.body;
if (!target || typeof MutationObserver !== 'function') return;
var obs = new MutationObserver(function (mutations) {
for (var m = 0; m < mutations.length; m++) {
var rec = mutations[m];
if (!rec.addedNodes || !rec.addedNodes.length) continue;
// Prune once per mutation batch; scope to the container or added subtree
pruneUI(target);
break;
}
});
obs.observe(target, { childList: true, subtree: true });
}
function init() {
preConfig();
pruneUI(document);
observe();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
if (mw && mw.hook) {
mw.hook('hotcat.ready').add(function () {
preConfig();
pruneUI(document);
});
mw.hook('postEdit').add(function () {
pruneUI(document);
});
}
})(jQuery, mediaWiki);