編集の要約なし |
編集の要約なし |
||
1行目: | 1行目: | ||
// | /* ✅ Citizenスキン完全対応版 Common.js */ | ||
mw.hook('wikipage.content').add(function ($content) { | |||
console.log("✅ Citizen hook fired"); | |||
// トップに戻るボタン | |||
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) { | |||
// | |||
if(toc.length){ | |||
toc.before('<button id="toggle-toc">目次を開閉</button>'); | toc.before('<button id="toggle-toc">目次を開閉</button>'); | ||
$('#toggle-toc').css({ | $('#toggle-toc').css({ margin: '5px', padding: '3px 6px', cursor: 'pointer' }) | ||
.on('click', function () { | |||
toc.slideToggle(); | |||
}); | |||
} | } | ||
// | // 画像に Lightbox 属性を追加 | ||
$content.find('a.image').attr('data-lightbox', 'image-gallery'); | |||
// | // セクション折りたたみ | ||
$content.find('.mw-headline').css('cursor', 'pointer').on('click', function () { | |||
$(' | |||
$(this).parent().nextUntil('h2, h3, h4, h5, h6').slideToggle(); | $(this).parent().nextUntil('h2, h3, h4, h5, h6').slideToggle(); | ||
}); | }); | ||
// | // 最近の更新ポップアップボタン | ||
const recentBtn = $('<button id="recent-popup">最近の更新</button>').css({ | |||
position: 'fixed', bottom: '50px', right: '20px', | |||
padding: '5px 10px', background: '#444', color: '#fff', borderRadius: '4px', cursor: 'pointer', zIndex: 1000 | |||
}).appendTo('body'); | }).appendTo('body'); | ||
recentBtn.on('click', function () { | |||
window.open(mw.util.getUrl('特別:最近の更新'), 'recentChanges', 'width=800,height=600'); | |||
}); | }); | ||
/ | // 閲覧数表示 | ||
$( | $.getJSON(mw.util.wikiScript('api'), { | ||
action: 'query', prop: 'pageviews', titles: mw.config.get('wgPageName'), format: 'json' | |||
}, function (data) { | |||
const views = Object.values(data.query.pages)[0].pageviews; | |||
const total = Object.values(views).reduce((a, b) => a + (b || 0), 0); | |||
$('<div id="view-count">👀 閲覧数: ' + total + '</div>').css({ | |||
position: 'fixed', bottom: '150px', right: '20px', | |||
padding: '4px 8px', background: '#333', color: '#fff', | |||
borderRadius: '5px', zIndex: 1000 | |||
}).appendTo('body'); | |||
} | |||
}); | }); | ||
// 読了時間表示 | |||
// | 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'), { | $.getJSON(mw.util.wikiScript('api'), { | ||
action: 'query', | action: 'query', list: 'allpages', aplimit: 'max', apnamespace: 0, format: 'json' | ||
}, function (data) { | }, function (data) { | ||
const pages = data.query.allpages; | const pages = data.query.allpages; | ||
const titles = pages.map(p => p.title).filter(title => title.length >= 3); | 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('([^>])(' + safeTitle + ')([^<])', 'g'); | |||
const link = '$1<a href="' + mw.util.getUrl(title) + '">$2</a>$3'; | |||
html = html.replace(regex, link); | |||
}); | }); | ||
$content.html(html); | |||
}); | }); | ||
}); | }); | ||
// Lightbox 読み込み(外部) | |||
mw.loader.load('https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.4/js/lightbox.min.js'); | |||
$('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.4/css/lightbox.min.css" />'); |
2025年3月28日 (金) 01:46時点における版
/* ✅ Citizenスキン完全対応版 Common.js */ mw.hook('wikipage.content').add(function ($content) { console.log("✅ Citizen hook fired"); // トップに戻るボタン 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', 'image-gallery'); // セクション折りたたみ $content.find('.mw-headline').css('cursor', 'pointer').on('click', function () { $(this).parent().nextUntil('h2, h3, h4, h5, h6').slideToggle(); }); // 最近の更新ポップアップボタン const recentBtn = $('<button id="recent-popup">最近の更新</button>').css({ position: 'fixed', bottom: '50px', right: '20px', padding: '5px 10px', background: '#444', color: '#fff', borderRadius: '4px', cursor: 'pointer', zIndex: 1000 }).appendTo('body'); recentBtn.on('click', function () { window.open(mw.util.getUrl('特別:最近の更新'), 'recentChanges', 'width=800,height=600'); }); // 閲覧数表示 $.getJSON(mw.util.wikiScript('api'), { action: 'query', prop: 'pageviews', titles: mw.config.get('wgPageName'), format: 'json' }, function (data) { const views = Object.values(data.query.pages)[0].pageviews; const total = Object.values(views).reduce((a, b) => a + (b || 0), 0); $('<div id="view-count">👀 閲覧数: ' + total + '</div>').css({ position: 'fixed', bottom: '150px', right: '20px', padding: '4px 8px', background: '#333', color: '#fff', borderRadius: '5px', zIndex: 1000 }).appendTo('body'); }); // 読了時間表示 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('([^>])(' + safeTitle + ')([^<])', 'g'); const link = '$1<a href="' + mw.util.getUrl(title) + '">$2</a>$3'; html = html.replace(regex, link); }); $content.html(html); }); }); // Lightbox 読み込み(外部) mw.loader.load('https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.4/js/lightbox.min.js'); $('head').append('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.11.4/css/lightbox.min.css" />');