MediaWiki:Gadget-HotCatCustomizer.js

来自WikiFur
跳转至: 导航搜索

注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox/Safari:按住“Shift”的同时单击“刷新”,或按“Ctrl-F5”或“Ctrl-R”(Mac为“⌘-R”)
  • Google Chrome:按“Ctrl-Shift-R”(Mac为“⌘-Shift-R”)
  • Internet Explorer:按住“Ctrl”的同时单击“刷新”,或按“Ctrl-F5”
  • Opera:在“工具→首选项”中清除缓存
/*
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);