MediaWiki:Common.js
From Tuyin Archives
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/* Any JavaScript here will be loaded for all users on every page load. */ // Audio Player System // Audio Player System /* Any JavaScript here will be loaded for all users on every page load. */ // Audio Player System // Mobile audio unlocker /* Any JavaScript here will be loaded for all users on every page load. */ // Audio Player System // Mobile audio unlocker (optional but harmless) document.addEventListener('DOMContentLoaded', function () { var isMobile = /Mobi|Android|iPhone|iPad/i.test(navigator.userAgent); if (isMobile) { var unlockAudio = document.createElement('audio'); unlockAudio.src = "data:audio/ogg;base64,T2dnUwACAAAAAAAAAABVDxXAAAAAAACf5tYBHgF2b3JiaXMAAAAAAkSsAAAAAAD+/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; unlockAudio.muted = true; unlockAudio.playsInline = true; unlockAudio.autoplay = true; unlockAudio.preload = "auto"; document.body.appendChild(unlockAudio); unlockAudio.play().catch(() => {}); } }); mw.hook('wikipage.content').add(function($content) { $content.find('.audioplayer').each(function() { var $container = $(this); var filename = $container.attr('data-filename'); var caption = $container.attr('data-caption') || 'Audio File'; if (!filename) return; var baseName = filename.replace(/\.\w+$/, ''); // remove extension if present // Generate unique ID var playerId = 'audio_' + Math.random().toString(36).substr(2, 9); // Create player HTML var $player = $('<div>').css({ 'display': 'inline-flex', 'align-items': 'center', 'gap': '12px' }); var $playerBox = $('<div>').css({ 'border': '1px solid #8B7355', 'padding': '8px', 'border-radius': '4px', 'background-color': '#F5F0E8', 'width': '200px' }); var $button = $('<button>').attr('id', playerId + '_btn').text('▶️').css({ 'padding': '4px 8px', 'margin-right': '8px', 'font-size': '12px', 'border': '1px solid #8B7355', 'background': '#D4C4A8', 'color': '#5D4E37' }); var $progressContainer = $('<div>').css({ 'display': 'inline-block', 'width': '120px', 'height': '6px', 'background-color': '#D4C4A8', 'border-radius': '3px', 'vertical-align': 'middle' }); var $progress = $('<div>').attr('id', playerId + '_progress').css({ 'height': '100%', 'background-color': '#8B7355', 'border-radius': '3px', 'width': '0%', 'transition': 'width 0.1s' }); var $caption = $('<span>').text(caption).css({ 'color': '#8B7355', 'font-style': 'italic' }); // Build structure $progressContainer.append($progress); $playerBox.append($button).append($progressContainer); $player.append($playerBox).append($caption); // Replace container content $container.empty().append($player); // Create real DOM <audio> element with both sources var $realAudio = $('<audio preload="metadata" playsinline style="display:none;">') .append($('<source>').attr('src', 'https://tuyin.online/images/' + baseName + '.ogg').attr('type', 'audio/ogg')) .append($('<source>').attr('src', 'https://tuyin.online/images/' + baseName + '.mp3').attr('type', 'audio/mpeg')); $container.append($realAudio); var audio = $realAudio[0]; var isPlaying = false; $button.click(function() { if (isPlaying) { audio.pause(); $button.text('▶️'); isPlaying = false; } else { audio.play().then(function() { $button.text('⏸️'); isPlaying = true; }).catch(function(error) { alert('Could not play audio: ' + error.message); }); } }); audio.addEventListener('timeupdate', function() { if (audio.duration) { var percentage = (audio.currentTime / audio.duration) * 100; $progress.css('width', percentage + '%'); } }); audio.addEventListener('ended', function() { $button.text('▶️'); $progress.css('width', '0%'); isPlaying = false; }); }); }); //Translator Tool mw.hook('wikipage.content').add(function ($content) { if (mw.config.get('wgPageName') !== 'Translator') return; const languages = ['dwarven', 'orcian', 'ratik', 'elvic', 'snekian', 'trogian']; const dictionaries = {}; let loaded = 0; // UI setup const container = $('<div>').css({ padding: '1em', background: '#f5f0e8', border: '1px solid #ccc' }); const dropdown = $('<select>').css({ marginBottom: '1em', padding: '0.4em', display: 'block' }); dropdown.append($('<option>').val('').text('Select a language')); languages.forEach(lang => { dropdown.append($('<option>').val(lang).text(lang.charAt(0).toUpperCase() + lang.slice(1))); }); const input = $('<textarea>') .attr('placeholder', 'Enter English text...') .css({ width: '100%', height: '80px', marginBottom: '1em' }); const output = $('<div>').attr('id', 'translator-output'); container.append(dropdown).append(input).append(output); $content.prepend(container); // Load dictionaries languages.forEach(lang => { $.get(`/wiki/index.php?title=${lang.charAt(0).toUpperCase() + lang.slice(1)}&action=render`, html => { const dict = {}; $(html).find('table.wikitable tr').each(function () { const cells = $(this).find('td'); if (cells.length >= 2) { const english = $(cells[0]).text().trim().toLowerCase(); const translated = $(cells[1]).text().trim(); if (english && translated) { dict[english] = translated; } } }); dictionaries[lang] = dict; loaded++; }); }); function updateOutput() { const lang = dropdown.val(); const text = input.val().trim().toLowerCase(); if (!lang || !text || !dictionaries[lang]) { output.empty(); return; } const dict = dictionaries[lang]; const words = text.split(/\s+/); const normal = words.map(w => dict[w] || w).join(' '); const script = words.map(w => (dict[w] || w).toUpperCase()).join(' '); const block = $('<div>').css({ marginTop: '1em' }); block.append( $('<div>').css({ fontWeight: 'bold', marginBottom: '0.3em' }) .text(lang.charAt(0).toUpperCase() + lang.slice(1) + ':') ); block.append($('<div>').text(normal)); block.append( $('<div>').addClass(lang).css({ fontSize: '160%', marginTop: '0.5em' }).text(script) ); output.html(block); } input.on('input', updateOutput); dropdown.on('change', updateOutput); });