メニューを切り替える
Toggle preferences menu
個人設定を切り替える
ログインしていません
編集を行うと、IPアドレスが公開されます。

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

MediaWikiインターフェイスページ
編集の要約なし
編集の要約なし
1行目: 1行目:
mw.hook('wikipage.content').add(function ($content) {
mw.hook('wikipage.content').add(function ($content) {
   // すべての中身をここに入れて動かす
   // すべての中身をここに入れて動かす




$(function () {
$(function () {
  // 記事本文を対象にする
   const content = document.querySelector('.mw-parser-output'); // ← Citizen対応
   const content = document.querySelector('#mw-content-text');
   if (!content) return;
   if (!content) return;


  // 現在のページタイトルを取得(他の候補を手動で指定してもOK)
  const title = mw.config.get('wgTitle');
   const api = new mw.Api();
   const api = new mw.Api();


  // すべてのテキストノードを再帰的に処理する関数
   function linkifyTitles(node, titlesSet) {
   function linkifyTitles(node, titlesSet) {
     if (node.nodeType === Node.TEXT_NODE) {
     if (node.nodeType === Node.TEXT_NODE) {
32行目: 32行目:
   }
   }


  // 記事の一覧を取得(カテゴリなどでフィルターしてもOK)
   api.get({
   api.get({
     action: 'query',
     action: 'query',
40行目: 39行目:
   }).done(function (data) {
   }).done(function (data) {
     const titles = data.query.allpages.map(p => p.title);
     const titles = data.query.allpages.map(p => p.title);
     const titlesSet = new Set(titles); // たくさんあると高速化できる
     const titlesSet = new Set(titles);
     linkifyTitles(content, titlesSet);
     linkifyTitles(content, titlesSet);
   });
   });
});
});





2025年3月28日 (金) 03:26時点における版

mw.hook('wikipage.content').add(function ($content) {
  // すべての中身をここに入れて動かす






$(function () {
  const content = document.querySelector('.mw-parser-output'); // ← Citizen対応
  if (!content) return;

  const api = new mw.Api();

  function linkifyTitles(node, titlesSet) {
    if (node.nodeType === Node.TEXT_NODE) {
      const text = node.nodeValue;
      for (const title of titlesSet) {
        const regex = new RegExp(`\\b(${title})\\b`, 'g');
        if (regex.test(text)) {
          const span = document.createElement('span');
          span.innerHTML = text.replace(regex, `<a href="/wiki/$1">$1</a>`);
          node.replaceWith(span);
          return;
        }
      }
    } else if (node.nodeType === Node.ELEMENT_NODE && node.tagName !== 'A') {
      for (const child of Array.from(node.childNodes)) {
        linkifyTitles(child, titlesSet);
      }
    }
  }

  api.get({
    action: 'query',
    list: 'allpages',
    aplimit: 500,
    format: 'json'
  }).done(function (data) {
    const titles = data.query.allpages.map(p => p.title);
    const titlesSet = new Set(titles);
    linkifyTitles(content, titlesSet);
  });
});








  // 全角スペースを黒四角に
mw.hook('wikipage.content').add(function ($content) {
  $content.find('.mw-parser-output').each(function () {
    const $this = $(this);
    const html = $this.html().replace(/ /g, '■');
    $this.html(html);
  });
});

  // スクロール進捗バー
$(function(){
  var progressBar = $('<div id="progress-bar"></div>').css({
    position:'fixed', top:'0', left:'0', height:'4px',
    background:'#6cf', width:'0%', zIndex:1000
  }).appendTo('body');

  $(window).scroll(function(){
    var winScroll = $(window).scrollTop();
    var height = $(document).height() - $(window).height();
    var scrolled = (winScroll / height) * 100;
    progressBar.css('width', scrolled + '%');
  });
});
  
  // 読了時間表示
$(function(){
  var text = $('#mw-content-text').text();
  var minutes = Math.ceil(text.length / 500); //500文字/分で計算
  $('<div id="read-time">⏳ 読了目安: ' + minutes + '分</div>').css({
    padding: '5px', background: '#e2f0ff', borderRadius: '5px',
    display: 'inline-block', marginBottom: '10px'
  }).prependTo('#mw-content-text');
});

  
  // スムーズスクロール
$(function(){
  $('a[href^="#"]').click(function(e){
    e.preventDefault();
    var target = $(this.hash);
    if(target.length){
      $('html, body').animate({scrollTop:target.offset().top},600);
    }
  });
});
  
  // ツールチップ機能
$(function(){
  $('[data-tooltip]').hover(function(){
    var tooltip = $('<div class="tooltip"></div>').text($(this).attr('data-tooltip')).css({
      position: 'absolute',
      background: '#444',
      color: '#fff',
      padding: '4px 8px',
      borderRadius: '5px',
      zIndex: 1000,
      whiteSpace: 'nowrap'
    }).appendTo('body').hide().fadeIn(200);

    $(this).mousemove(function(e){
      tooltip.css({top:e.pageY+10, left:e.pageX+10});
    });
  }, function(){
    $('.tooltip').fadeOut(200,function(){ $(this).remove(); });
  });
});

  
// ユーザー名歓迎表示
$(function(){
    if(mw.config.get('wgUserName')){
        $('#header-top').prepend(
            '<div style="padding:5px;background:#1a73e8;color:#fff;text-align:center;">ようこそ、' +
            mw.config.get('wgUserName') + 'さん!</div>'
        );
    }
});


  // 折りたたみ可能セクション
$(function() {
  $('.mw-headline').click(function() {
    $(this).parent().nextUntil('h2, h3, h4, h5, h6').slideToggle();
  }).css('cursor', 'pointer');
});

  
// 目次トグル機能追加
$(function(){
  var toc = $('#toc');
  if(toc.length){
    toc.before('<button id="toggle-toc">目次を開閉</button>');
    $('#toggle-toc').css({
      margin: '5px', padding: '3px 6px', cursor: 'pointer'
    }).click(function(){
      toc.slideToggle();
    });
  }
});


// 外部リンクを新規タブで開く
$(function() {
  $('a.external').attr('target', '_blank');
});


// ユーステラ風✨星キラキラカーソル(頻度調整+水色強化版)
var lastStarTime = 0;
$(document).mousemove(function(e) {
    var now = Date.now();
    if (now - lastStarTime < 100) return; // 出現頻度を調整(100を大きくすればさらに少なくなる)
    lastStarTime = now;

    var colors = ['#6ff', '#9cf', '#cff', '#8df', '#7af']; // より水色っぽく調整
    var star = $('<div>').text('✦').css({
        position: 'absolute',
        top: e.pageY - 10,
        left: e.pageX - 10,
        color: colors[Math.floor(Math.random() * colors.length)],
        fontSize: '14px',
        pointerEvents: 'none',
        opacity: 1,
        zIndex: 9999,
        userSelect: 'none',
        textShadow: '0 0 6px #8df, 0 0 12px #6ff'
    }).appendTo('body');

    star.animate({
        top: e.pageY - (Math.random() * 40 - 20),
        left: e.pageX - (Math.random() * 40 - 20),
        opacity: 0,
        fontSize: '4px'
    }, 1000, function() {
        $(this).remove();
    });
});
});