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

Szkt (トーク) による版 1051 を取り消し
タグ: 取り消し
編集の要約なし
 
(同じ利用者による、間の3版が非表示)
172行目: 172行目:
                 // 匿名ユーザーのみ投稿フォームの上部に表示される
                 // 匿名ユーザーのみ投稿フォームの上部に表示される
                 const anonSettingsHtml = isAnon ? `<details id="f-name-settings" style="margin-bottom:.8em;border:1px solid #ccc;padding:.5em;border-radius:3px;">
                 const anonSettingsHtml = isAnon ? `<details id="f-name-settings" style="margin-bottom:.8em;border:1px solid #ccc;padding:.5em;border-radius:3px;">
<summary style="cursor:pointer;font-weight:bold;user-select:none;">名前・トリップの設定</summary>
<summary style="cursor:pointer;font-weight:bold;user-select:none;">名前・トリップの設定</summary>
<div style="margin-top:.5em;">
<div style="margin-top:.5em;">
   <p style="margin:.2em 0 .5em;font-size:.9em;color:#555;">
   <p style="margin:.2em 0 .5em;font-size:.9em;color:#555;">
209行目: 209行目:
                     deletesummary: 'delete post',
                     deletesummary: 'delete post',
                     deletethreadsummary: 'スレッドの削除',
                     deletethreadsummary: 'スレッドの削除',
                     toppage_css: "<style>.f-sticky>td:first-child>a::before{content:'';background-image:url(https://upload.wikimedia.org/wikipedia/commons/a/a5/OOjs_UI_icon_pushPin.svg);width:.8em;height:.8em;margin-right:.2em;display:inline-block;background-size:.8em}#f-loadmore{display:block;margin-left:auto;margin-right:auto;}</style>",
                     toppage_css: "<style>.f-sticky>td:first-child>a::before{content:'';background-image:url(https://upload.wikimedia.org/wikipedia/commons/a/a5/OOjs_UI_icon_pushPin.svg);width:.8em;height:.8em;margin-right:.2em;display:inline-block;background-size:.8em}#f-loadmore{display:block;margin-left:auto;margin-right:auto;}#f-create-btn-mobile{display:none;margin:1em 0;text-align:right;}@media (max-width:768px){.mw-indicators{display:block!important;}#f-create-btn-mobile{display:block;}}#f-notice{background:#fffacd;border:1px solid #daa520;border-radius:4px;padding:1em;margin:1em 0;font-size:.95em;line-height:1.6;}</style>",
                    toppage_notice: mw.forum.notice ? `<div id="f-notice">${mw.forum.notice}</div>` : '',
                     load_more: '<input type="button" value="もっと読み込む" class="mw-ui-button" id="f-loadmore">',
                     load_more: '<input type="button" value="もっと読み込む" class="mw-ui-button" id="f-loadmore">',
                     create: '<input type="button" class="mw-ui-button mw-ui-progressive" value="スレッドを作成">',
                     create: '<input type="button" class="mw-ui-button mw-ui-progressive" value="スレッドを作成">',
265行目: 266行目:
                         const source = await (await fetch(mw.config.get('wgScript') + `?title=${mw.config.get('wgPageName')}&action=raw`)).text();
                         const source = await (await fetch(mw.config.get('wgScript') + `?title=${mw.config.get('wgPageName')}&action=raw`)).text();
                         const newText = source.replace(new RegExp(`(\\{\\{post\\|(.*?)\\|${postId}\\|(.*?)\\|4=)((.|\n)*?)(}})`), '$1[Deleted]$6');
                         const newText = source.replace(new RegExp(`(\\{\\{post\\|(.*?)\\|${postId}\\|(.*?)\\|4=)((.|\n)*?)(}})`), '$1[Deleted]$6');
                         fetch('/mediawiki/forum-proxy.php', {
                         fetch('/wiki/forum-proxy.php', {
                             method: 'POST',
                             method: 'POST',
                             headers: { 'Content-Type': 'application/json' },
                             headers: { 'Content-Type': 'application/json' },
287行目: 288行目:
                         const threadName = mw.config.get('wgPageName').replace(mw.forum.toppage + '/', '');
                         const threadName = mw.config.get('wgPageName').replace(mw.forum.toppage + '/', '');
                         if (!confirm(`スレッド「${threadName}」を削除しますか?\nこの操作は取り消せません。`)) return;
                         if (!confirm(`スレッド「${threadName}」を削除しますか?\nこの操作は取り消せません。`)) return;
                         fetch('/mediawiki/forum-proxy.php', {
                         fetch('/wiki/forum-proxy.php', {
                             method: 'POST',
                             method: 'POST',
                             headers: { 'Content-Type': 'application/json' },
                             headers: { 'Content-Type': 'application/json' },
399行目: 400行目:
                             const anonParam = isAnon ? '|anon=1' : '';
                             const anonParam = isAnon ? '|anon=1' : '';
                             content += `{{post|${mw.forum.username}|1|{{subst:#timel:Y/m/d H:i:s}}|4=${document.querySelector('#wpTextbox1').value}${anonParam}}}`;
                             content += `{{post|${mw.forum.username}|1|{{subst:#timel:Y/m/d H:i:s}}|4=${document.querySelector('#wpTextbox1').value}${anonParam}}}`;
                             fetch('/mediawiki/forum-proxy.php', {
                             fetch('/wiki/forum-proxy.php', {
                                 method: 'POST',
                                 method: 'POST',
                                 headers: { 'Content-Type': 'application/json' },
                                 headers: { 'Content-Type': 'application/json' },
422行目: 423行目:
                     mc.innerHTML = msg.loading;
                     mc.innerHTML = msg.loading;
                     func.getthreads().then((res) => {
                     func.getthreads().then((res) => {
                         mc.innerHTML = res[0] + msg.toppage_css;
                         mc.innerHTML = msg.toppage_notice + res[0] + msg.toppage_css;
                       
                        // モバイル用の「スレッドを作成」ボタンを追加
                        const mobileBtn = document.createElement('div');
                        mobileBtn.id = 'f-create-btn-mobile';
                        mobileBtn.innerHTML = msg.create;
                        mc.insertBefore(mobileBtn, mc.firstChild);
                        mobileBtn.querySelector('input').onclick = function () {
                            const url = new URL(window.location.href);
                            url.searchParams.set('newthread', '1');
                            location.href = url;
                        };
                       
                         if (res[1]) {
                         if (res[1]) {
                             document.querySelector('#mw-content-text').innerHTML += msg.load_more;
                             document.querySelector('#mw-content-text').innerHTML += msg.load_more;
497行目: 510行目:
                             postBody.appendtext = `\n{{post|${mw.forum.username}|${lp}|{{subst:#timel:Y/m/d H:i:s}}|4=${document.querySelector('#wpTextbox1').value}${document.querySelector('#f-reply-cb').checked ? '|re=' + document.querySelector('#f-reply').value : ''}${anonParam}}}`;
                             postBody.appendtext = `\n{{post|${mw.forum.username}|${lp}|{{subst:#timel:Y/m/d H:i:s}}|4=${document.querySelector('#wpTextbox1').value}${document.querySelector('#f-reply-cb').checked ? '|re=' + document.querySelector('#f-reply').value : ''}${anonParam}}}`;
                         }
                         }
                         fetch('/mediawiki/forum-proxy.php', {
                         fetch('/wiki/forum-proxy.php', {
                             method: 'POST',
                             method: 'POST',
                             headers: { 'Content-Type': 'application/json' },
                             headers: { 'Content-Type': 'application/json' },
574行目: 587行目:


                         const showPopup = (anchorEl, postId) => {
                         const showPopup = (anchorEl, postId) => {
                            const target = document.querySelector(`#post-${postId}`);
    const target = document.querySelector(`#post-${postId}`);
                            if (!target) return;
    if (!target) return;


                            // 対象投稿をクローンしてポップアップに表示
    // 対象投稿をクローンしてポップアップに表示
                            // 編集・削除リンクは除いてすっきり見せる
    const clone = target.cloneNode(true);
                            const clone = target.cloneNode(true);
    clone.querySelectorAll('a[href*="fedit"], span[style*="#d33"]').forEach(el => el.remove());
                            clone.querySelectorAll('a[href*="fedit"], span[style*="#d33"]').forEach(el => el.remove());
    popup.innerHTML = '';
                            popup.innerHTML = '';
    popup.appendChild(clone);
                            popup.appendChild(clone);


                            // ポップアップの位置をリンクの近くに配置
    // ポップアップの位置をリンクの近くに配置(モバイル対応)
                            const rect = anchorEl.getBoundingClientRect();
    const rect = anchorEl.getBoundingClientRect();
                            const popupHeight = 200; // 表示前は高さ不明なので仮値
    const viewportWidth = window.innerWidth;
                            const spaceBelow = window.innerHeight - rect.bottom;
    const viewportHeight = window.innerHeight;
                            const top = spaceBelow > popupHeight
   
                                ? rect.bottom + 4         // 下に余裕あり → リンクの下
    // ポップアップの最大幅を画面幅の90%に制限
                                : rect.top - popupHeight; // 余裕なし → リンクの上
    const maxWidth = Math.min(480, viewportWidth * 0.9);
                            popup.style.left = Math.min(rect.left, window.innerWidth - 500) + 'px';
    popup.style.maxWidth = maxWidth + 'px';
                            popup.style.top  = Math.max(4, top) + 'px';
   
                            popup.style.display = 'block';
    // 一度表示して実際の高さを取得
                        };
    popup.style.display = 'block';
    popup.style.visibility = 'hidden';
    const popupHeight = popup.offsetHeight;
    popup.style.visibility = 'visible';
   
    // 縦位置:下に余裕があれば下、なければ上
    const spaceBelow = viewportHeight - rect.bottom;
    const top = spaceBelow > popupHeight + 10
        ? rect.bottom + 4
        : Math.max(4, rect.top - popupHeight - 4);
   
    // 横位置:画面からはみ出ないように調整
    let left = rect.left;
    if (left + maxWidth > viewportWidth - 10) {
        left = viewportWidth - maxWidth - 10;
    }
    if (left < 10) {
        left = 10;
    }
   
    popup.style.left = left + 'px';
    popup.style.top = top + 'px';
};


                         const hidePopup = () => {
                         const hidePopup = () => {