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

提供: トラwiki
最新更新一覧・IPコピー・記事作成ボタンJS実装
 
軽量な最新更新読み込みスクリプトに刷新
1行目: 1行目:
/**
/**
  * トラwiki (tora22.com) - Custom JavaScript
  * MediaWiki:Common.js
  */
  */
(function() {
(function() {
   'use strict';
   'use strict';
  function initCopyIp() {
    var copyBtn = document.getElementById('tw-copy-ip-btn');
    if (!copyBtn) return;
    copyBtn.addEventListener('click', function(e) {
      e.preventDefault();
      var ip = 'tora22.com';
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(ip).then(function() {
          var origText = copyBtn.innerHTML;
          copyBtn.innerHTML = '✅ コピー完了!';
          copyBtn.style.backgroundColor = '#10b981';
          setTimeout(function() {
            copyBtn.innerHTML = origText;
            copyBtn.style.backgroundColor = '';
          }, 2000);
        });
      } else {
        var input = document.createElement('input');
        input.value = ip;
        document.body.appendChild(input);
        input.select();
        document.execCommand('copy');
        document.body.removeChild(input);
        alert('サーバーアドレス (tora22.com) をコピーしました!');
      }
    });
  }


   function loadRecentUpdates() {
   function loadRecentUpdates() {
38行目: 9行目:
     if (!container) return;
     if (!container) return;


     fetch('/api.php?action=query&list=recentchanges&rcnamespace=0&rclimit=6&rcprop=title|timestamp|user|comment&format=json')
     fetch('/api.php?action=query&list=recentchanges&rcnamespace=0&rclimit=6&rcprop=title|timestamp|user&format=json')
       .then(function(res) { return res.json(); })
       .then(function(res) { return res.json(); })
       .then(function(data) {
       .then(function(data) {
45行目: 16行目:
         if (rcs.length === 0) return;
         if (rcs.length === 0) return;


         var html = '<ul class="tw-updates-list">';
         var html = '<ul class="tw-recent-feed">';
         for (var i = 0; i < rcs.length; i++) {
         for (var i = 0; i < rcs.length; i++) {
           var item = rcs[i];
           var item = rcs[i];
           var titleEnc = encodeURIComponent(item.title);
           var titleEnc = encodeURIComponent(item.title);
           var dateObj = new Date(item.timestamp);
           var dateObj = new Date(item.timestamp);
           var timeStr = formatRelativeTime(dateObj);
           var timeStr = formatTime(dateObj);


           html += '<li class="tw-update-item">';
           html += '<li class="tw-recent-feed-item">';
           html += '  <div class="tw-update-main">';
           html += '  <span><a href="/index.php/' + titleEnc + '">' + escapeHtml(item.title) + '</a></span>';
          html += '    <div class="tw-update-title"><a href="/index.php/' + titleEnc + '">' + escapeHtml(item.title) + '</a></div>';
           html += ' <span class="tw-recent-feed-time">' + timeStr + '</span>';
          html += '    <div class="tw-update-meta">';
          html += '      <span class="tw-update-user">👤 ' + escapeHtml(item.user) + '</span>';
           if (item.comment) {
            html += '     <span class="tw-update-comment" style="max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">' + escapeHtml(item.comment) + '</span>';
          }
          html += '    </div>';
          html += '  </div>';
          html += '  <div class="tw-update-time">' + timeStr + '</div>';
           html += '</li>';
           html += '</li>';
         }
         }
69行目: 32行目:
       })
       })
       .catch(function(err) {
       .catch(function(err) {
         console.warn('Recent updates live fetch failed:', err);
         console.warn('Recent changes load error:', err);
       });
       });
   }
   }


   function formatRelativeTime(date) {
   function formatTime(d) {
     var now = new Date();
     var m = (d.getMonth() + 1);
    var diffMs = now - date;
     var day = d.getDate();
    var diffSec = Math.floor(diffMs / 1000);
     var h = ('0' + d.getHours()).slice(-2);
    var diffMin = Math.floor(diffSec / 60);
     var min = ('0' + d.getMinutes()).slice(-2);
     var diffHr = Math.floor(diffMin / 60);
     return m + '/' + day + ' ' + h + ':' + min;
     var diffDay = Math.floor(diffHr / 24);
 
    if (diffMin < 1) return 'たった今';
    if (diffMin < 60) return diffMin + '分前';
    if (diffHr < 24) return diffHr + '時間前';
    if (diffDay < 7) return diffDay + '日前';
     return (date.getMonth() + 1) + '' + date.getDate() + '日';
  }
 
  function escapeHtml(str) {
    if (!str) return '';
     return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
   }
   }


   function addSidebarCreateButton() {
   function escapeHtml(s) {
    var navPortlet = document.querySelector('#p-ナビゲーション .mw-portlet-body');
     if (!s) return '';
     if (navPortlet && !document.getElementById('n-create-custom-btn')) {
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
      var btn = document.createElement('a');
      btn.id = 'n-create-custom-btn';
      btn.href = '#tw-article-creator';
      btn.className = 'tw-sidebar-create-btn';
      btn.innerHTML = '✏️ 新規記事を作成';
      btn.addEventListener('click', function(e) {
        var createInput = document.querySelector('.createboxInput');
        if (createInput) {
          createInput.focus();
          createInput.scrollIntoView({ behavior: 'smooth', block: 'center' });
        } else {
          window.location.href = '/index.php/メインページ#tw-article-creator';
        }
      });
      navPortlet.insertBefore(btn, navPortlet.firstChild);
    }
   }
   }


   if (document.readyState === 'loading') {
   if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', function() {
     document.addEventListener('DOMContentLoaded', loadRecentUpdates);
      initCopyIp();
      loadRecentUpdates();
      addSidebarCreateButton();
    });
   } else {
   } else {
    initCopyIp();
     loadRecentUpdates();
     loadRecentUpdates();
    addSidebarCreateButton();
   }
   }
})();
})();

2026年8月26日 (水) 15:54時点における版

/**
 * MediaWiki:Common.js
 */
(function() {
  'use strict';

  function loadRecentUpdates() {
    var container = document.getElementById('tw-live-recent-updates');
    if (!container) return;

    fetch('/api.php?action=query&list=recentchanges&rcnamespace=0&rclimit=6&rcprop=title|timestamp|user&format=json')
      .then(function(res) { return res.json(); })
      .then(function(data) {
        if (!data || !data.query || !data.query.recentchanges) return;
        var rcs = data.query.recentchanges;
        if (rcs.length === 0) return;

        var html = '<ul class="tw-recent-feed">';
        for (var i = 0; i < rcs.length; i++) {
          var item = rcs[i];
          var titleEnc = encodeURIComponent(item.title);
          var dateObj = new Date(item.timestamp);
          var timeStr = formatTime(dateObj);

          html += '<li class="tw-recent-feed-item">';
          html += '  <span><a href="/index.php/' + titleEnc + '">' + escapeHtml(item.title) + '</a></span>';
          html += '  <span class="tw-recent-feed-time">' + timeStr + '</span>';
          html += '</li>';
        }
        html += '</ul>';
        container.innerHTML = html;
      })
      .catch(function(err) {
        console.warn('Recent changes load error:', err);
      });
  }

  function formatTime(d) {
    var m = (d.getMonth() + 1);
    var day = d.getDate();
    var h = ('0' + d.getHours()).slice(-2);
    var min = ('0' + d.getMinutes()).slice(-2);
    return m + '/' + day + ' ' + h + ':' + min;
  }

  function escapeHtml(s) {
    if (!s) return '';
    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', loadRecentUpdates);
  } else {
    loadRecentUpdates();
  }
})();