タグ: 置換 差し戻し済み |
編集の要約なし タグ: 差し戻し済み |
||
1行目: | 1行目: | ||
/* | /* Citizenスキン対応のMediaWiki:Common.js */ | ||
mw.hook('wikipage.content').add(function ($content) { | |||
console.log('✅ JS loaded for Citizen skin'); | |||
// トップに戻るボタン | |||
const toTopButton = $('<a href="#" id="toTop">↑ トップへ戻る</a>').css({ | |||
position: 'fixed', bottom: '20px', right: '20px', background: '#555', | |||
color: '#fff', padding: '5px 10px', borderRadius: '4px', textDecoration: 'none', display: 'none', zIndex: 1000 | |||
}).appendTo('body'); | |||
$(window).on('scroll', function () { | |||
toTopButton.toggle($(this).scrollTop() > 200); | |||
}); | |||
toTopButton.on('click', function () { | |||
$('html, body').animate({ scrollTop: 0 }, 500); | |||
return false; | |||
}); | |||
// コピーコードボタン | |||
$content.find('pre').each(function () { | |||
const copyBtn = $('<button class="copy-btn">コピー</button>'); | |||
$(this).before(copyBtn); | |||
copyBtn.on('click', () => { | |||
navigator.clipboard.writeText($(this).text()).then(() => { | |||
copyBtn.text('コピー済'); | |||
setTimeout(() => copyBtn.text('コピー'), 2000); | |||
}); | |||
}); | |||
}); | |||
// 外部リンク新規タブ | |||
$content.find('a.external').attr('target', '_blank'); | |||
// 目次トグル | |||
const toc = $content.find('#toc'); | |||
if (toc.length) { | |||
toc.before('<button id="toggle-toc">目次を開閉</button>'); | |||
$('#toggle-toc').css({ margin: '5px', padding: '3px 6px', cursor: 'pointer' }).on('click', function () { | |||
toc.slideToggle(); | |||
}); | |||
} | |||
// 画像 Lightbox | |||
$content.find('a.image').attr('data-lightbox', 'gallery'); | |||
// 折りたたみセクション | |||
$content.find('.mw-headline').css('cursor', 'pointer').on('click', function () { | |||
$(this).parent().nextUntil('h2, h3, h4, h5, h6').slideToggle(); | |||
}); | |||
// 読了時間 | |||
const text = $content.text(); | |||
const minutes = Math.ceil(text.length / 500); | |||
$('<div id="read-time">⏳ 読了目安: ' + minutes + '分</div>').css({ | |||
padding: '5px', background: '#e2f0ff', borderRadius: '5px', display: 'inline-block', marginBottom: '10px' | |||
}).prependTo($content); | |||
// 自動リンク化 | |||
$.getJSON(mw.util.wikiScript('api'), { | |||
action: 'query', list: 'allpages', aplimit: 'max', apnamespace: 0, format: 'json' | |||
}, function (data) { | |||
const pages = data.query.allpages; | |||
const titles = pages.map(p => p.title).filter(title => title.length >= 3); | |||
let html = $content.html(); | |||
titles.forEach(title => { | |||
const safeTitle = title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); | |||
const regex = new RegExp(`(?<!href=["'][^>]{0,500})(${safeTitle})(?![^<]*?>)`, 'g'); | |||
const link = `<a href="${mw.util.getUrl(title)}">$1</a>`; | |||
html = html.replace(regex, link); | |||
}); | |||
$content.html(html); | |||
}); | |||
}); |
2025年3月28日 (金) 01:12時点における版
/* Citizenスキン対応のMediaWiki:Common.js */ mw.hook('wikipage.content').add(function ($content) { console.log('✅ JS loaded for Citizen skin'); // トップに戻るボタン const toTopButton = $('<a href="#" id="toTop">↑ トップへ戻る</a>').css({ position: 'fixed', bottom: '20px', right: '20px', background: '#555', color: '#fff', padding: '5px 10px', borderRadius: '4px', textDecoration: 'none', display: 'none', zIndex: 1000 }).appendTo('body'); $(window).on('scroll', function () { toTopButton.toggle($(this).scrollTop() > 200); }); toTopButton.on('click', function () { $('html, body').animate({ scrollTop: 0 }, 500); return false; }); // コピーコードボタン $content.find('pre').each(function () { const copyBtn = $('<button class="copy-btn">コピー</button>'); $(this).before(copyBtn); copyBtn.on('click', () => { navigator.clipboard.writeText($(this).text()).then(() => { copyBtn.text('コピー済'); setTimeout(() => copyBtn.text('コピー'), 2000); }); }); }); // 外部リンク新規タブ $content.find('a.external').attr('target', '_blank'); // 目次トグル const toc = $content.find('#toc'); if (toc.length) { toc.before('<button id="toggle-toc">目次を開閉</button>'); $('#toggle-toc').css({ margin: '5px', padding: '3px 6px', cursor: 'pointer' }).on('click', function () { toc.slideToggle(); }); } // 画像 Lightbox $content.find('a.image').attr('data-lightbox', 'gallery'); // 折りたたみセクション $content.find('.mw-headline').css('cursor', 'pointer').on('click', function () { $(this).parent().nextUntil('h2, h3, h4, h5, h6').slideToggle(); }); // 読了時間 const text = $content.text(); const minutes = Math.ceil(text.length / 500); $('<div id="read-time">⏳ 読了目安: ' + minutes + '分</div>').css({ padding: '5px', background: '#e2f0ff', borderRadius: '5px', display: 'inline-block', marginBottom: '10px' }).prependTo($content); // 自動リンク化 $.getJSON(mw.util.wikiScript('api'), { action: 'query', list: 'allpages', aplimit: 'max', apnamespace: 0, format: 'json' }, function (data) { const pages = data.query.allpages; const titles = pages.map(p => p.title).filter(title => title.length >= 3); let html = $content.html(); titles.forEach(title => { const safeTitle = title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const regex = new RegExp(`(?<!href=["'][^>]{0,500})(${safeTitle})(?![^<]*?>)`, 'g'); const link = `<a href="${mw.util.getUrl(title)}">$1</a>`; html = html.replace(regex, link); }); $content.html(html); }); });