「MediaWiki:Common.js」の版間の差分

提供: 小樽のじかん事典
編集の要約なし
編集の要約なし
55行目: 55行目:


(function () {
(function () {
  function isVisible(el) {
    if (!el) return false;
    var cs = window.getComputedStyle ? getComputedStyle(el) : null;
    return !cs || (cs.display !== 'none' && cs.visibility !== 'hidden' && cs.opacity !== '0');
  }
  function hasVisibleContent(el) {
    if (!el) return false;
    // visibleな要素(入力/ボタン/リンク/セレクト等)が残っていれば空ではない
    var keep = el.querySelectorAll('input, textarea, button, select, a, .oo-ui-widget, .mw-ui-button');
    for (var i = 0; i < keep.length; i++) {
      if (isVisible(keep[i])) return true;
    }
    // 表示テキストが残っていれば空ではない
    var t = (el.textContent || '').replace(/\s+/g, '');
    return t.length > 0;
  }
  function collapseUp(el, maxDepth) {
    var cur = el;
    for (var d = 0; d < (maxDepth || 6); d++) {
      if (!cur || !cur.parentElement) break;
      // 自分自身が見えていて、中身が実質空なら潰す
      if (isVisible(cur) && !hasVisibleContent(cur)) {
        cur.style.display = 'none';
      }
      cur = cur.parentElement;
    }
  }
   function apply() {
   function apply() {
    // Comments のDOMがまだなら何もしない
     var root = document.getElementById('comments-body');
     var root = document.getElementById('comments-body');
     if (!root) return;
     if (!root) return;
81行目: 114行目:
       if (!sel) continue;
       if (!sel) continue;


      // select本体を消す
       sel.style.display = 'none';
       sel.style.display = 'none';


       // 可能なら周辺のラッパも消す(見た目の空きを減らす)
       // 周辺の親を優先的に潰す(ツールバー想定)
       var wrapper = sel.closest ? sel.closest('label, .c-sort, .c-order, .comments-sort, .comments-order, .c-nav, .c-toolbar, .comments-toolbar') : null;
       var w = sel.closest
       if (wrapper) wrapper.style.display = 'none';
        ? sel.closest('.c-nav, .c-toolbar, .comments-toolbar, .comments-header, .c-order, .comments-order, .comments-sort, li, div, span')
        : null;
 
       if (w) {
        collapseUp(w, 6);
      } else {
        collapseUp(sel, 6);
      }
     }
     }


94行目: 133行目:
       var a = links[k];
       var a = links[k];
       var at = (a.textContent || '').trim();
       var at = (a.textContent || '').trim();
       if (at.indexOf('コメントの自動更新を有効化') !== -1) {
       if (at.indexOf('コメントの自動更新を有効化') === -1) continue;
        a.style.display = 'none';
 
      a.style.display = 'none';


        // 可能なら周辺のラッパも消す
      var aw = a.closest
        var aw = a.closest ? a.closest('li, div, span, label') : null;
        ? a.closest('.c-nav, .c-toolbar, .comments-toolbar, .comments-header, li, div, span')
        if (aw) aw.style.display = 'none';
        : null;
 
      if (aw) {
        collapseUp(aw, 6);
      } else {
        collapseUp(a, 6);
      }
    }
 
    // 3) 最後の掃除:コメント領域直下の空コンテナを潰す
    // ここで「== コメント == の下の空白」になっている箱を落とす
    var candidates = root.querySelectorAll('div, li, ul, ol');
    for (var c = 0; c < candidates.length; c++) {
      var box = candidates[c];
      if (!isVisible(box)) continue;
      if (hasVisibleContent(box)) continue;
 
      // 高さ/余白を持つ空箱だけ潰す
      var cs = getComputedStyle(box);
      var hasSpace =
        (parseFloat(cs.marginTop) || 0) +
          (parseFloat(cs.marginBottom) || 0) +
          (parseFloat(cs.paddingTop) || 0) +
          (parseFloat(cs.paddingBottom) || 0) >
        0;
 
      if (hasSpace) {
        box.style.display = 'none';
       }
       }
     }
     }
107行目: 174行目:
     apply();
     apply();


    // Commentsが後からDOMを描画するので監視して再適用
     var watchRoot = document.getElementById('comments-body') ||
     var watchRoot = document.getElementById('comments-body') || document.getElementById('mw-data-after-content') || document.body;
      document.getElementById('mw-data-after-content') ||
      document.body;
 
     if (watchRoot && window.MutationObserver) {
     if (watchRoot && window.MutationObserver) {
       var obs = new MutationObserver(function () { apply(); });
       var obs = new MutationObserver(function () { apply(); });
115行目: 184行目:
   }
   }


  // RLQ優先、なければDOMContentLoaded
   if (window.RLQ && typeof window.RLQ.push === 'function') {
   if (window.RLQ && typeof window.RLQ.push === 'function') {
     window.RLQ.push(boot);
     window.RLQ.push(boot);

2026年1月8日 (木) 09:15時点における版

/**
 * MediaWiki 1.44.3 アカウント作成画面 無限ループ防止版
 * 既に書き換え済みの場合は処理をスキップするように修正しました。
 */
(function() {
    var enforce = function() {
        if (mw.config.get('wgCanonicalSpecialPageName') !== 'CreateAccount') return;

        // 1. メールアドレスの書き換え
        var labels = document.getElementsByTagName('label');
        for (var i = 0; i < labels.length; i++) {
            var label = labels[i];
            // 「(省略可能)」が含まれている場合のみ書き換える(無限ループ防止)
            if (label.getAttribute('for') === 'wpEmail' || label.innerHTML.indexOf('メールアドレス') !== -1) {
                if (label.innerHTML.indexOf('(省略可能)') !== -1) {
                    label.innerHTML = 'メールアドレス';
                }
            }
            // 本名の書き換え
            if (label.getAttribute('for') === 'wpRealName' || label.innerHTML.indexOf('HN') !== -1) {
                if (label.innerHTML.indexOf('(省略可能)') !== -1) {
                    label.innerHTML = 'HN(省略可能)';
                }
            }
        }

        // 2. 必須属性の付与
        var emailInput = document.getElementById('wpEmail');
        if (emailInput && !emailInput.required) {
            emailInput.required = true;
            emailInput.setAttribute('required', 'required');
        }
    };

    if (mw.config.get('wgCanonicalSpecialPageName') === 'CreateAccount') {
        // 初回実行
        enforce();

        // 監視対象を限定し、無限ループを回避
        var observer = new MutationObserver(function(mutations) {
            for (var i = 0; i < mutations.length; i++) {
                if (mutations[i].addedNodes.length > 0) {
                    enforce();
                    break;
                }
            }
        });

        var target = document.getElementById('mw-content-text');
        if (target) {
            observer.observe(target, {childList: true, subtree: true});
        }
    }
})();

(function () {
  function isVisible(el) {
    if (!el) return false;
    var cs = window.getComputedStyle ? getComputedStyle(el) : null;
    return !cs || (cs.display !== 'none' && cs.visibility !== 'hidden' && cs.opacity !== '0');
  }

  function hasVisibleContent(el) {
    if (!el) return false;

    // visibleな要素(入力/ボタン/リンク/セレクト等)が残っていれば空ではない
    var keep = el.querySelectorAll('input, textarea, button, select, a, .oo-ui-widget, .mw-ui-button');
    for (var i = 0; i < keep.length; i++) {
      if (isVisible(keep[i])) return true;
    }

    // 表示テキストが残っていれば空ではない
    var t = (el.textContent || '').replace(/\s+/g, '');
    return t.length > 0;
  }

  function collapseUp(el, maxDepth) {
    var cur = el;
    for (var d = 0; d < (maxDepth || 6); d++) {
      if (!cur || !cur.parentElement) break;

      // 自分自身が見えていて、中身が実質空なら潰す
      if (isVisible(cur) && !hasVisibleContent(cur)) {
        cur.style.display = 'none';
      }

      cur = cur.parentElement;
    }
  }

  function apply() {
    var root = document.getElementById('comments-body');
    if (!root) return;

    // 1) 並べ替えUI:option文言から親selectを特定して消す
    var orderTexts = ['日付順に並べ替え', '得点順に並べ替え'];

    var options = root.querySelectorAll('option');
    for (var i = 0; i < options.length; i++) {
      var opt = options[i];
      var t = (opt.textContent || '').trim();
      if (!t) continue;

      var hit = false;
      for (var j = 0; j < orderTexts.length; j++) {
        if (t.indexOf(orderTexts[j]) !== -1) {
          hit = true;
          break;
        }
      }
      if (!hit) continue;

      var sel = opt.closest ? opt.closest('select') : null;
      if (!sel) continue;

      sel.style.display = 'none';

      // 周辺の親を優先的に潰す(ツールバー想定)
      var w = sel.closest
        ? sel.closest('.c-nav, .c-toolbar, .comments-toolbar, .comments-header, .c-order, .comments-order, .comments-sort, li, div, span')
        : null;

      if (w) {
        collapseUp(w, 6);
      } else {
        collapseUp(sel, 6);
      }
    }

    // 2) 自動更新リンク:文言一致のaを消す
    var links = root.querySelectorAll('a');
    for (var k = 0; k < links.length; k++) {
      var a = links[k];
      var at = (a.textContent || '').trim();
      if (at.indexOf('コメントの自動更新を有効化') === -1) continue;

      a.style.display = 'none';

      var aw = a.closest
        ? a.closest('.c-nav, .c-toolbar, .comments-toolbar, .comments-header, li, div, span')
        : null;

      if (aw) {
        collapseUp(aw, 6);
      } else {
        collapseUp(a, 6);
      }
    }

    // 3) 最後の掃除:コメント領域直下の空コンテナを潰す
    // ここで「== コメント == の下の空白」になっている箱を落とす
    var candidates = root.querySelectorAll('div, li, ul, ol');
    for (var c = 0; c < candidates.length; c++) {
      var box = candidates[c];
      if (!isVisible(box)) continue;
      if (hasVisibleContent(box)) continue;

      // 高さ/余白を持つ空箱だけ潰す
      var cs = getComputedStyle(box);
      var hasSpace =
        (parseFloat(cs.marginTop) || 0) +
          (parseFloat(cs.marginBottom) || 0) +
          (parseFloat(cs.paddingTop) || 0) +
          (parseFloat(cs.paddingBottom) || 0) >
        0;

      if (hasSpace) {
        box.style.display = 'none';
      }
    }
  }

  function boot() {
    apply();

    var watchRoot = document.getElementById('comments-body') ||
      document.getElementById('mw-data-after-content') ||
      document.body;

    if (watchRoot && window.MutationObserver) {
      var obs = new MutationObserver(function () { apply(); });
      obs.observe(watchRoot, { childList: true, subtree: true });
    }
  }

  if (window.RLQ && typeof window.RLQ.push === 'function') {
    window.RLQ.push(boot);
  } else if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', boot);
  } else {
    boot();
  }
})();