MediaWiki:Common.js:修订间差异
MediaWiki界面页面
更多操作
小 |
|||
| (未显示同一用户的19个中间版本) | |||
| 第63行: | 第63行: | ||
$(MetaCaixaInit); | $(MetaCaixaInit); | ||
//BMV模板script | //BMV模板script | ||
(function(mw, $) { | (function(mw, $) { | ||
'use strict'; | 'use strict'; | ||
| 第69行: | 第69行: | ||
function initBmvPlayer(wrapper) { | function initBmvPlayer(wrapper) { | ||
var $wrapper = $(wrapper); | var $wrapper = $(wrapper); | ||
var songName = $wrapper.data('song-name'); | var songName = $wrapper.data('song-name'); | ||
var rawDifficulties = $wrapper.data('difficulties'); | var rawDifficulties = $wrapper.data('difficulties'); | ||
var $difficultyDiv = $wrapper.find('.difficulty-div'); | var $difficultyDiv = $wrapper.find('.difficulty-div'); | ||
var $ratioDiv = $wrapper.find('.ratio-div'); | var $ratioDiv = $wrapper.find('.ratio-div'); | ||
var $outputSpan = $wrapper.find('.output-span'); | var $outputSpan = $wrapper.find('.output-span'); | ||
var difficultyColors = { "EZ": "#57E4C4", "HD": "#FDBA61", "IN": "#FE8661", "AT": "#4C364B" }; | |||
function parseDifficulties(input) { if (!input) return null; try { return input.split(',').map(function(item) { var match = item.trim().match(/^([A-Za-z]+)([\d]+[+-]?)$/); if (!match) { throw new Error('Invalid difficulty format for item: ' + item); } return (match[1].toUpperCase() + ' ' + match[2]); }); } catch (e) { console.error("Error parsing difficulties:", input, e); return null; } } | var difficultyColors = { | ||
"EZ": "#57E4C4", "HD": "#FDBA61", "IN": "#FE8661", "AT": "#4C364B" | |||
}; | |||
function parseDifficulties(input) { | |||
if (!input) return null; | |||
try { | |||
return input.split(',').map(function(item) { | |||
var match = item.trim().match(/^([A-Za-z]+)([\d]+[+-]?)$/); | |||
if (!match) { | |||
throw new Error('Invalid difficulty format for item: ' + item); | |||
} | |||
return (match[1].toUpperCase() + ' ' + match[2]); | |||
}); | |||
} catch (e) { | |||
console.error("Error parsing difficulties:", input, e); | |||
return null; | |||
} | |||
} | |||
var difficultyStates = parseDifficulties(rawDifficulties); | var difficultyStates = parseDifficulties(rawDifficulties); | ||
if (!songName || !difficultyStates || difficultyStates.length === 0) { $wrapper.find('table').html('<div style="color:red; padding:10px; text-align:center;">错误: 缺少或无效的曲名/难度参数。</div>'); return; } | |||
if (!songName || !difficultyStates || difficultyStates.length === 0) { | |||
$wrapper.find('table').html('<div style="color:red; padding:10px; text-align:center;">错误: 缺少或无效的曲名/难度参数。</div>'); | |||
return; | |||
} | |||
$difficultyDiv.attr('data-states', JSON.stringify(difficultyStates)); | $difficultyDiv.attr('data-states', JSON.stringify(difficultyStates)); | ||
function updateOutput() { | |||
var difficulty = $difficultyDiv.text().split(' ')[0]; | |||
var ratio = $ratioDiv.text().replace(':', '-'); | |||
$(' | var processedSongName = songName.replace(/[\\/:\*\?"<>\|]/g, '-'); | ||
var encodedSongName = encodeURIComponent(processedSongName); | |||
var videoUrl = 'https://pan.rizwiki.cn/d/' + ratio + '_' + encodedSongName + '_' + difficulty + '.mp4'; | |||
var isMobile = window.matchMedia("(max-width: 600px)").matches; | |||
var videoHeightStyle = isMobile ? '' : 'height:100%;'; | |||
$outputSpan.html('<video class="html5media-video" src="' + videoUrl + '" controls preload="metadata" loading="lazy" style="' + videoHeightStyle + ' object-fit:contain;"></video>'); | |||
} | |||
function cycleDifficulty() { | |||
$(' | var states = JSON.parse($difficultyDiv.attr('data-states')); | ||
var current = parseInt($difficultyDiv.attr('data-current'), 10); | |||
current = (current + 1) % states.length; | |||
var nextState = states[current]; | |||
$difficultyDiv.text(nextState); | |||
$difficultyDiv.attr('data-current', current.toString()); | |||
var difficultyType = nextState.split(' ')[0]; | |||
$difficultyDiv.parent().css('background-color', difficultyColors[difficultyType] || '#FFFFFF'); | |||
updateOutput(); | |||
} | |||
function cycleRatio() { | |||
var states = JSON.parse($ratioDiv.attr('data-states')); | |||
var current = parseInt($ratioDiv.attr('data-current'), 10); | |||
current = (current + 1) % states.length; | |||
$ratioDiv.text(states[current]); | |||
$ratioDiv.attr('data-current', current.toString()); | |||
updateOutput(); | |||
} | } | ||
$difficultyDiv.on('click', cycleDifficulty); | |||
$ratioDiv.parent().on('click', cycleRatio); | |||
// 初始化 | |||
(function initialize() { | |||
var firstDiff = difficultyStates[0]; | |||
var diffType = firstDiff.split(' ')[0]; | |||
$difficultyDiv.text(firstDiff); | |||
$difficultyDiv.parent().css('background-color', difficultyColors[diffType]); | |||
updateOutput(); | |||
})(); | |||
} | } | ||
| 第120行: | 第166行: | ||
}); | }); | ||
// | /* 绿豆诡计播放器js */ | ||
var $player = $('#riz-player'); | |||
if ($player.length > 0) { | |||
if ($player.parent().is('body') === false) { | |||
$player.appendTo('body'); | |||
} | |||
if ($player.data('initialized')) return; | |||
$player.data('initialized', true); | |||
console.log("RizPlayer found, initializing..."); | |||
var lastScrollTop = 0; | |||
var scrollThreshold = 10; | |||
$(window).on('scroll resize', function() { | |||
if (window.innerWidth > 768) { | |||
$player.removeClass('rp-scroll-down'); | |||
return; | |||
} | |||
var st = $(this).scrollTop(); | |||
if (Math.abs(lastScrollTop - st) <= scrollThreshold) return; | |||
if (st > lastScrollTop && st > 50) { | |||
$player.addClass('rp-scroll-down'); | |||
} else { | |||
$player.removeClass('rp-scroll-down'); | |||
} | |||
lastScrollTop = st; | |||
}); | |||
var songUrl = $player.data('url'); | |||
if (!songUrl) { | |||
console.error("RizPlayer Error: No audio URL found."); | |||
return; | |||
} | |||
// 封面图修复逻辑 | |||
var $coverImg = $player.find('.rp-cover-img'); | |||
if ($coverImg.length === 0) $coverImg = $player.find('.rp-cover img'); | |||
var backupSrc = $player.data('image'); | |||
function fixCoverImage() { | |||
var currentSrc = $coverImg.attr('src'); | |||
if ((!currentSrc || currentSrc === "" || currentSrc === "undefined") && backupSrc) { | |||
console.log("修复封面图,使用 data-image:", backupSrc); | |||
$coverImg.attr('src', backupSrc); | |||
} | |||
} | |||
fixCoverImage(); | |||
var audio = new Audio(songUrl); | |||
audio.preload = "none"; | |||
// 获取元素 | |||
var $toggleBtn = $player.find('.rp-btn-toggle'); | |||
var $sideBtn = $player.find('.rp-side-ctrl'); | |||
var $progressWrap = $player.find('.rp-progress-wrap'); | |||
var $progressBar = $player.find('.rp-progress-bar'); | |||
var $progressCurrent = $player.find('.rp-progress-current'); | |||
var $progressHandle = $player.find('.rp-progress-handle'); | |||
var $curTime = $player.find('.rp-cur'); | |||
var $durTime = $player.find('.rp-dur'); | |||
// 显示播放器 | |||
$player.css('display', 'flex'); | |||
function formatTime(seconds) { | |||
if (isNaN(seconds)) return "00:00"; | |||
var m = Math.floor(seconds / 60); | |||
var s = Math.floor(seconds % 60); | |||
return (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s); | |||
} | |||
// 播放/暂停 | |||
function togglePlay(e) { | |||
if(e) e.stopPropagation(); | |||
if (audio.paused) { | |||
var playPromise = audio.play(); | |||
if (playPromise !== undefined) { | |||
playPromise.then(function() { | |||
$player.addClass('playing'); | |||
if (!$player.hasClass('riz-player-expanded')) { | |||
$player.addClass('riz-player-expanded'); | |||
} | |||
}).catch(function(error) { | |||
console.error("播放失败:", error); | |||
}); | |||
} | |||
} else { | |||
audio.pause(); | |||
$player.removeClass('playing'); | |||
} | |||
} | |||
// 绑定点击事件 | |||
$toggleBtn.on('click', togglePlay); | |||
$sideBtn.on('click', togglePlay); | |||
// 展开/折叠 | |||
$player.on('click', function(e) { | |||
if ($(e.target).closest('.rp-progress-wrap, .rp-side-ctrl, .rp-btn-toggle').length > 0) return; | |||
$player.toggleClass('riz-player-expanded'); | |||
}); | |||
var isDragging = false; | |||
$progressWrap.on('mousedown touchstart', function(e) { | |||
isDragging = true; | |||
$progressWrap.addClass('dragging'); | |||
updateProgressFromEvent(e); | |||
}); | |||
$(document).on('mousemove touchmove', function(e) { | |||
if (isDragging) { | |||
e.preventDefault(); | |||
updateProgressFromEvent(e); | |||
} | |||
}); | |||
$(document).on('mouseup touchend', function(e) { | |||
if (isDragging) { | |||
isDragging = false; | |||
$progressWrap.removeClass('dragging'); | |||
if (audio.duration) { | |||
var percent = parseFloat($progressCurrent[0].style.width) / 100; | |||
audio.currentTime = percent * audio.duration; | |||
if(audio.paused) { | |||
audio.play(); | |||
$player.addClass('playing'); | |||
} | |||
} | |||
} | |||
}); | |||
function updateProgressFromEvent(e) { | |||
var clientX = e.clientX; | |||
if (e.type.includes('touch')) { | |||
clientX = e.originalEvent.touches[0].clientX; | |||
} | |||
var offset = $progressWrap.offset(); | |||
var width = $progressWrap.width(); | |||
var relX = clientX - offset.left; | |||
var percent = (relX / width) * 100; | |||
if (percent < 0) percent = 0; | |||
if (percent > 100) percent = 100; | |||
$progressCurrent.css('width', percent + '%'); | |||
$progressHandle.css('left', percent + '%'); | |||
if (audio.duration) { | |||
var dragTime = (percent / 100) * audio.duration; | |||
$curTime.text(formatTime(dragTime)); | |||
} | |||
} | |||
audio.addEventListener('timeupdate', function() { | |||
if (!isDragging && audio.duration) { | |||
var percent = (audio.currentTime / audio.duration) * 100; | |||
$progressCurrent.css('width', percent + '%'); | |||
$progressHandle.css('left', percent + '%'); | |||
$curTime.text(formatTime(audio.currentTime)); | |||
} | |||
}); | |||
audio.addEventListener('loadedmetadata', function() { | |||
$durTime.text(formatTime(audio.duration)); | |||
}); | |||
audio.addEventListener('ended', function() { | |||
$player.removeClass('playing'); | |||
$progressCurrent.css('width', '0%'); | |||
$progressHandle.css('left', '0%'); | |||
}); | |||
audio.addEventListener('error', function(e) { | |||
console.error("音频加载错误:", audio.src); | |||
}); | |||
} | |||
}); | }); | ||
})(mediaWiki, jQuery); | })(mediaWiki, jQuery); | ||
/* PWA */ | |||
if ('serviceWorker' in navigator) { | |||
window.addEventListener('load', function() { | |||
navigator.serviceWorker.register('/sw.js').then(function(registration) { | |||
console.log('PWA Ready:', registration.scope); | |||
}, function(err) { | |||
console.log('PWA Fail:', err); | |||
}); | |||
}); | |||
} | |||
// 点击短链接复制 | |||
mw.hook('wikipage.content').add(function() { | |||
var shortlink = document.querySelector('.title-shortlink') | |||
if (shortlink) { | |||
shortlink.removeAttribute('href') | |||
shortlink.style.cursor = 'pointer' | |||
shortlink.title = '点击复制' | |||
shortlink.addEventListener('click', function(e) { | |||
e.preventDefault() | |||
navigator.clipboard.writeText(this.textContent).then(function() { | |||
var parent = shortlink.parentNode | |||
parent.removeChild(shortlink) | |||
parent.insertBefore(shortlink, shortlink.nextSibling) | |||
shortlink.title = '已复制' | |||
setTimeout(function() { | |||
shortlink.title = '点击复制' | |||
}, 1000) | |||
}).catch(function(err) { | |||
console.error('复制失败: ', err) | |||
shortlink.title = '复制失败' | |||
var parent = shortlink.parentNode | |||
parent.removeChild(shortlink) | |||
parent.insertBefore(shortlink, shortlink.nextSibling) | |||
}) | |||
}) | |||
} | |||
}) | |||
2025年12月6日 (六) 20:41的最新版本
/* 这里的任何JavaScript将为所有用户在每次页面加载时加载。 */
/* JavaScript used for https://zh.wikipedia.org/wiki/MediaWiki:Common.js : */
/** metaBox
*
* Funcionament de la Plantilla:Metacaixa
* Implementat per: Usuari:Peleguer.
* Actualitzat per Joanjoc seguint les indicacions d'en Martorell
*/
document.querySelector('.mw-logo-wordmark').textContent=''
function MetaCaixaInit() {
// S'executa al carregar-se la pàgina, si hi ha metacaixes,
// s'assignen els esdeveniments als botons
//alert("MetaCaixaInit");
var i = 0; // Inicialitzem comptador de caixes
for (i = 0; i <= 9; i++) {
var vMc = document.getElementById("mc" + i);
if (!vMc) break;
//alert("MetaCaixaInit, trobada Metacaixa mc"+i);
var j = 1; // Inicialitzem comptador de botons dins de la caixa
var vPsIni = 0; // Pestanya visible inicial
for (j = 1; j <= 9; j++) {
var vBt = document.getElementById("mc" + i + "bt" + j);
if (!vBt) break;
//alert("MetaCaixaInit, trobat botó mc"+i+"bt"+j);
vBt.onclick = MetaCaixaMostraPestanya; // A cada botó assignem l'esdeveniment onclick
//alert (vBt.className);
if (vBt.className == "mcBotoSel") vPsIni = j; // Si tenim un botó seleccionat, en guardem l'index
}
//alert ("mc="+i+", ps="+j+", psini="+vPsIni );
if (vPsIni === 0) { // Si no tenim cap botó seleccionat, n'agafem un aleatòriament
vPsIni = 1 + Math.floor((j - 1) * Math.random());
//alert ("Activant Pestanya a l'atzar; _mc"+i+"bt"+vPsIni +"_");
document.getElementById("mc" + i + "ps" + vPsIni).style.display = "block";
document.getElementById("mc" + i + "ps" + vPsIni).style.visibility = "visible";
document.getElementById("mc" + i + "bt" + vPsIni).className = "mcBotoSel";
}
}
}
function MetaCaixaMostraPestanya() {
// S'executa al clicar una pestanya,
// aquella es fa visible i les altres s'oculten
var vMcNom = this.id.substr(0, 3); // A partir del nom del botó, deduïm el nom de la caixa
var vIndex = this.id.substr(5, 1); // I l'index
var i = 1;
for (i = 1; i <= 9; i++) { // busquem totes les pestanyes d'aquella caixa
//alert(vMcNom+"ps"+i);
var vPsElem = document.getElementById(vMcNom + "ps" + i);
if (!vPsElem) break;
if (vIndex == i) { // Si és la pestanya bona la mostrem i canviem la classe de botó
vPsElem.style.display = "block";
vPsElem.style.visibility = "visible";
document.getElementById(vMcNom + "bt" + i).className = "mcBotoSel";
} else { // Sinó, l'ocultem i canviem la classe de botó
vPsElem.style.display = "none";
vPsElem.style.visibility = "hidden";
document.getElementById(vMcNom + "bt" + i).className = "mcBoto";
}
}
return false; // evitem la recàrrega de la pàgina
}
$(MetaCaixaInit);
//BMV模板script
(function(mw, $) {
'use strict';
function initBmvPlayer(wrapper) {
var $wrapper = $(wrapper);
var songName = $wrapper.data('song-name');
var rawDifficulties = $wrapper.data('difficulties');
var $difficultyDiv = $wrapper.find('.difficulty-div');
var $ratioDiv = $wrapper.find('.ratio-div');
var $outputSpan = $wrapper.find('.output-span');
var difficultyColors = {
"EZ": "#57E4C4", "HD": "#FDBA61", "IN": "#FE8661", "AT": "#4C364B"
};
function parseDifficulties(input) {
if (!input) return null;
try {
return input.split(',').map(function(item) {
var match = item.trim().match(/^([A-Za-z]+)([\d]+[+-]?)$/);
if (!match) {
throw new Error('Invalid difficulty format for item: ' + item);
}
return (match[1].toUpperCase() + ' ' + match[2]);
});
} catch (e) {
console.error("Error parsing difficulties:", input, e);
return null;
}
}
var difficultyStates = parseDifficulties(rawDifficulties);
if (!songName || !difficultyStates || difficultyStates.length === 0) {
$wrapper.find('table').html('<div style="color:red; padding:10px; text-align:center;">错误: 缺少或无效的曲名/难度参数。</div>');
return;
}
$difficultyDiv.attr('data-states', JSON.stringify(difficultyStates));
function updateOutput() {
var difficulty = $difficultyDiv.text().split(' ')[0];
var ratio = $ratioDiv.text().replace(':', '-');
var processedSongName = songName.replace(/[\\/:\*\?"<>\|]/g, '-');
var encodedSongName = encodeURIComponent(processedSongName);
var videoUrl = 'https://pan.rizwiki.cn/d/' + ratio + '_' + encodedSongName + '_' + difficulty + '.mp4';
var isMobile = window.matchMedia("(max-width: 600px)").matches;
var videoHeightStyle = isMobile ? '' : 'height:100%;';
$outputSpan.html('<video class="html5media-video" src="' + videoUrl + '" controls preload="metadata" loading="lazy" style="' + videoHeightStyle + ' object-fit:contain;"></video>');
}
function cycleDifficulty() {
var states = JSON.parse($difficultyDiv.attr('data-states'));
var current = parseInt($difficultyDiv.attr('data-current'), 10);
current = (current + 1) % states.length;
var nextState = states[current];
$difficultyDiv.text(nextState);
$difficultyDiv.attr('data-current', current.toString());
var difficultyType = nextState.split(' ')[0];
$difficultyDiv.parent().css('background-color', difficultyColors[difficultyType] || '#FFFFFF');
updateOutput();
}
function cycleRatio() {
var states = JSON.parse($ratioDiv.attr('data-states'));
var current = parseInt($ratioDiv.attr('data-current'), 10);
current = (current + 1) % states.length;
$ratioDiv.text(states[current]);
$ratioDiv.attr('data-current', current.toString());
updateOutput();
}
$difficultyDiv.on('click', cycleDifficulty);
$ratioDiv.parent().on('click', cycleRatio);
// 初始化
(function initialize() {
var firstDiff = difficultyStates[0];
var diffType = firstDiff.split(' ')[0];
$difficultyDiv.text(firstDiff);
$difficultyDiv.parent().css('background-color', difficultyColors[diffType]);
updateOutput();
})();
}
mw.hook('wikipage.content').add(function($content) {
// 初始化 BMV 播放器
$content.find('.bmv-player-uninitialized').each(function() {
initBmvPlayer(this);
$(this).removeClass('bmv-player-uninitialized');
});
/* 绿豆诡计播放器js */
var $player = $('#riz-player');
if ($player.length > 0) {
if ($player.parent().is('body') === false) {
$player.appendTo('body');
}
if ($player.data('initialized')) return;
$player.data('initialized', true);
console.log("RizPlayer found, initializing...");
var lastScrollTop = 0;
var scrollThreshold = 10;
$(window).on('scroll resize', function() {
if (window.innerWidth > 768) {
$player.removeClass('rp-scroll-down');
return;
}
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= scrollThreshold) return;
if (st > lastScrollTop && st > 50) {
$player.addClass('rp-scroll-down');
} else {
$player.removeClass('rp-scroll-down');
}
lastScrollTop = st;
});
var songUrl = $player.data('url');
if (!songUrl) {
console.error("RizPlayer Error: No audio URL found.");
return;
}
// 封面图修复逻辑
var $coverImg = $player.find('.rp-cover-img');
if ($coverImg.length === 0) $coverImg = $player.find('.rp-cover img');
var backupSrc = $player.data('image');
function fixCoverImage() {
var currentSrc = $coverImg.attr('src');
if ((!currentSrc || currentSrc === "" || currentSrc === "undefined") && backupSrc) {
console.log("修复封面图,使用 data-image:", backupSrc);
$coverImg.attr('src', backupSrc);
}
}
fixCoverImage();
var audio = new Audio(songUrl);
audio.preload = "none";
// 获取元素
var $toggleBtn = $player.find('.rp-btn-toggle');
var $sideBtn = $player.find('.rp-side-ctrl');
var $progressWrap = $player.find('.rp-progress-wrap');
var $progressBar = $player.find('.rp-progress-bar');
var $progressCurrent = $player.find('.rp-progress-current');
var $progressHandle = $player.find('.rp-progress-handle');
var $curTime = $player.find('.rp-cur');
var $durTime = $player.find('.rp-dur');
// 显示播放器
$player.css('display', 'flex');
function formatTime(seconds) {
if (isNaN(seconds)) return "00:00";
var m = Math.floor(seconds / 60);
var s = Math.floor(seconds % 60);
return (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s);
}
// 播放/暂停
function togglePlay(e) {
if(e) e.stopPropagation();
if (audio.paused) {
var playPromise = audio.play();
if (playPromise !== undefined) {
playPromise.then(function() {
$player.addClass('playing');
if (!$player.hasClass('riz-player-expanded')) {
$player.addClass('riz-player-expanded');
}
}).catch(function(error) {
console.error("播放失败:", error);
});
}
} else {
audio.pause();
$player.removeClass('playing');
}
}
// 绑定点击事件
$toggleBtn.on('click', togglePlay);
$sideBtn.on('click', togglePlay);
// 展开/折叠
$player.on('click', function(e) {
if ($(e.target).closest('.rp-progress-wrap, .rp-side-ctrl, .rp-btn-toggle').length > 0) return;
$player.toggleClass('riz-player-expanded');
});
var isDragging = false;
$progressWrap.on('mousedown touchstart', function(e) {
isDragging = true;
$progressWrap.addClass('dragging');
updateProgressFromEvent(e);
});
$(document).on('mousemove touchmove', function(e) {
if (isDragging) {
e.preventDefault();
updateProgressFromEvent(e);
}
});
$(document).on('mouseup touchend', function(e) {
if (isDragging) {
isDragging = false;
$progressWrap.removeClass('dragging');
if (audio.duration) {
var percent = parseFloat($progressCurrent[0].style.width) / 100;
audio.currentTime = percent * audio.duration;
if(audio.paused) {
audio.play();
$player.addClass('playing');
}
}
}
});
function updateProgressFromEvent(e) {
var clientX = e.clientX;
if (e.type.includes('touch')) {
clientX = e.originalEvent.touches[0].clientX;
}
var offset = $progressWrap.offset();
var width = $progressWrap.width();
var relX = clientX - offset.left;
var percent = (relX / width) * 100;
if (percent < 0) percent = 0;
if (percent > 100) percent = 100;
$progressCurrent.css('width', percent + '%');
$progressHandle.css('left', percent + '%');
if (audio.duration) {
var dragTime = (percent / 100) * audio.duration;
$curTime.text(formatTime(dragTime));
}
}
audio.addEventListener('timeupdate', function() {
if (!isDragging && audio.duration) {
var percent = (audio.currentTime / audio.duration) * 100;
$progressCurrent.css('width', percent + '%');
$progressHandle.css('left', percent + '%');
$curTime.text(formatTime(audio.currentTime));
}
});
audio.addEventListener('loadedmetadata', function() {
$durTime.text(formatTime(audio.duration));
});
audio.addEventListener('ended', function() {
$player.removeClass('playing');
$progressCurrent.css('width', '0%');
$progressHandle.css('left', '0%');
});
audio.addEventListener('error', function(e) {
console.error("音频加载错误:", audio.src);
});
}
});
})(mediaWiki, jQuery);
/* PWA */
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
console.log('PWA Ready:', registration.scope);
}, function(err) {
console.log('PWA Fail:', err);
});
});
}
// 点击短链接复制
mw.hook('wikipage.content').add(function() {
var shortlink = document.querySelector('.title-shortlink')
if (shortlink) {
shortlink.removeAttribute('href')
shortlink.style.cursor = 'pointer'
shortlink.title = '点击复制'
shortlink.addEventListener('click', function(e) {
e.preventDefault()
navigator.clipboard.writeText(this.textContent).then(function() {
var parent = shortlink.parentNode
parent.removeChild(shortlink)
parent.insertBefore(shortlink, shortlink.nextSibling)
shortlink.title = '已复制'
setTimeout(function() {
shortlink.title = '点击复制'
}, 1000)
}).catch(function(err) {
console.error('复制失败: ', err)
shortlink.title = '复制失败'
var parent = shortlink.parentNode
parent.removeChild(shortlink)
parent.insertBefore(shortlink, shortlink.nextSibling)
})
})
}
})