MediaWiki:Common.js
注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5。
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
// Cloudflare Web Analytics
var script = document.createElement('script');
script.defer = true;
script.src = 'https://static.cloudflareinsights.com/beacon.min.js';
script.setAttribute('data-cf-beacon', '{"token": "6180aa28fe1943b48c4059a5056f4738"}');
document.head.appendChild(script);
// End Cloudflare Web Analytics
$(function () {
// 只在 Special:Search 页面运行
if (mw.config.get("wgCanonicalSpecialPageName") === "Search") {
const searchTerm = mw.util.getParamValue("search");
const googleUrl = "https://www.google.com/search?q=" + encodeURIComponent(searchTerm);
const $googleLink = $("<p>").html(
`你也可以到 <a href="${googleUrl}" target="_blank" rel="noopener">Google 中搜索“${searchTerm}”</a>。`
);
// 优先在有搜索结果时插入
if ($(".mw-search-results").length) {
$googleLink.insertAfter(".mw-search-results");
}
// 否则在没有结果提示后插入
else if ($(".mw-search-nonefound").length) {
$googleLink.insertAfter(".mw-search-nonefound");
}
}
});
// logo 切换逻辑
// Common.js - footer logo 切换逻辑(支持 dark/light + compact/normal + Citizen)
$(function () {
// ======================
// 工具函数
// ======================
// 获取当前主题:dark / light
function getEffectiveTheme() {
const cls = document.documentElement.classList;
if (cls.contains('skin-theme-clientpref-night')) return 'dark';
if (cls.contains('skin-theme-clientpref-day')) return 'light';
if (cls.contains('skin-theme-clientpref-os')) {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark';
return 'light';
}
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) return 'dark';
return 'light';
}
// 判断是否小屏(compact)
function isCompactMode() {
return window.matchMedia && window.matchMedia('(max-width: 500px)').matches;
}
// 设置 <img> src
function setImgSrc($img, src) {
if ($img.length) $img.attr('src', src);
}
// 设置 <source> srcset
function setSourceSrcset($source, srcset) {
if ($source.length) $source.attr('srcset', srcset);
}
// ======================
// 主更新逻辑
// ======================
function updateLogos() {
const theme = getEffectiveTheme();
const compact = isCompactMode();
// 尺寸逻辑:大屏用 source 横版,宽度 88x31;小屏 fallback img 用 25x25
// 注意:compact 状态下实际用 img,小屏时尺寸固定为 25x25
const sizeNormal = { width: 88, height: 31 };
const sizeCompact = { width: 25, height: 25 };
// ----------------------
// 公共 Logo
// ----------------------
['copyright', 'poweredby', 'poweredbysmw'].forEach(id => {
const $li = $(`#footer-${id}ico`);
if (!$li.length) return;
const $picture = $li.find('picture');
if (!$picture.length) return;
const $source = $picture.find('source');
const $img = $picture.find('img');
// 构造文件名
let baseName = '';
switch(id) {
case 'copyright': baseName = 'cc-by-nc-sa'; break;
case 'poweredby': baseName = 'poweredby-mediawiki'; break;
case 'poweredbysmw': baseName = 'poweredby-smw'; break;
}
const normalFile = `/resources/assets/${baseName}${theme === 'dark' ? '-dark' : ''}.svg`;
const compactFile = `/resources/assets/${baseName}-compact${theme === 'dark' ? '-dark' : ''}.svg`;
// 设置 source -> 大屏横版
setSourceSrcset($source, normalFile);
$source.attr('width', sizeNormal.width);
$source.attr('height', sizeNormal.height);
// 设置 img -> 小屏紧凑版
setImgSrc($img, compactFile);
$img.attr('width', sizeCompact.width);
$img.attr('height', sizeCompact.height);
});
// ----------------------
// Citizen 专属
// ----------------------
if (document.body.classList.contains('skin-Citizen')) {
const $li = $('#footer-poweredbycitizenico');
if ($li.length) {
const $picture = $li.find('picture');
const $img = $picture.length ? $picture.find('img') : $li.find('img');
const normalFile = `/resources/assets/poweredby-citizen${theme === 'dark' ? '-dark' : ''}.svg`;
const compactFile = `/resources/assets/poweredby-citizen-compact${theme === 'dark' ? '-dark' : ''}.svg`;
if ($picture.length) {
const $source = $picture.find('source');
setSourceSrcset($source, normalFile);
$source.attr('width', sizeNormal.width);
$source.attr('height', sizeNormal.height);
}
setImgSrc($img, compactFile);
$img.attr('width', sizeCompact.width);
$img.attr('height', sizeCompact.height);
}
}
}
// ======================
// 触发时机
// ======================
updateLogos();
// 监听 <html> class 变化(主题切换)
new MutationObserver(() => updateLogos()).observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
// 监听 body DOM 变动(footer 异步插入)
new MutationObserver(() => updateLogos()).observe(document.body, { childList: true, subtree: true });
// 监听系统主题 & 屏幕宽度变化
if (window.matchMedia) {
const mqDark = window.matchMedia('(prefers-color-scheme: dark)');
const mqCompact = window.matchMedia('(max-width: 500px)');
if (mqDark.addEventListener) mqDark.addEventListener('change', updateLogos);
else if (mqDark.addListener) mqDark.addListener(updateLogos);
if (mqCompact.addEventListener) mqCompact.addEventListener('change', updateLogos);
else if (mqCompact.addListener) mqCompact.addListener(updateLogos);
}
// MediaWiki hook
if (window.mw && mw.hook) mw.hook('user.preferencesSaved').add(updateLogos);
// 兜底
$(window).on('load', updateLogos);
setTimeout(updateLogos, 1500);
});
// 移除深色模式反馈提示
$(function () {
function removeBetaNotice() {
var $node = $('#skin-theme-beta-notice');
if ($node.length) {
$node.remove();
// 如果移除了,就断开观察器(可选)
if (observer) {
observer.disconnect();
}
}
}
// 第一次尝试
removeBetaNotice();
// 设置 MutationObserver 观察 body 或 document.body,监视 childList 增删
var observer = new MutationObserver(function (mutations) {
// 每次改变 DOM 时尝试移除
removeBetaNotice();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// 作为兜底:在页面加载完成后一段时间再试一次
$(window).on('load', function () {
removeBetaNotice();
});
// 再加一个延时
setTimeout(removeBetaNotice, 2000);
});
$(function () {
// 移除上传文件、固定链接、引用此页
$('#t-upload, #t-permalink, #t-cite').remove();
});