跳转到内容

MediaWiki:Gadget-AudioText.js:修订间差异

来自电棍ottowiki
 
(未显示同一用户的12个中间版本)
第1行: 第1行:
// MediaWiki:Gadget-AudioText.js
// MediaWiki:Gadget-AudioText.js
(function() {
(function() {
     // 强制声明依赖并确保mw.util可用
     const audioUrlCache = new Map();
    mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() {
        alert("🎉 JS脚本已加载!"); // 确保依赖加载完成后才提示


        // 主初始化函数
    // 播放音频核心逻辑
        function initAudioTriggers() {
    function handlePlay(element) {
            try {
        const audioFile = element.dataset.audioFile;
                const triggers = document.querySelectorAll('.audio-trigger');
       
                if (triggers.length === 0) {
        // 优先使用缓存
                    alert("⚠️ 未找到任何音频触发器元素!检查模板类名是否正确");
        if (audioUrlCache.has(audioFile)) {
                    return;
            new Audio(audioUrlCache.get(audioFile)).play();
                }
             return;
 
                triggers.forEach(element => {
                    if (element._initialized) return;
                    element._initialized = true;
 
                    // 绑定标准化事件(兼容移动端)
                    const handler = async (event) => {
                        event.preventDefault();
                        alert("🖱️ 点击事件已触发!"); // 确保事件触发可见
                        await handleClick(element);
                    };
                   
                    element.addEventListener('touchstart', handler, { passive: false });
                    element.addEventListener('click', handler);
                });
               
             } catch (error) {
                alert(`💥 初始化失败: ${error.message}`);
            }
         }
         }


         // 点击处理核心逻辑
         // 通过API获取真实URL
         async function handleClick(element) {
         const apiUrl = mw.util.wikiScript('api') + '?action=query&titles=' +
            try {
             encodeURIComponent(audioFile) + '&prop=imageinfo&iiprop=url&format=json';
                const audioFile = element.dataset.audioFile;
                alert(`📁 模板参数: ${audioFile}`);
 
                // 获取音频URL
                const audioUrl = await getAudioUrl(audioFile);
                alert(`🎵 最终音频地址: ${audioUrl}`);
 
                // 立即播放不等待调试
                await playAudio(audioUrl);
               
                // 延迟显示成功提示
                setTimeout(() => {
                    alert("✅ 播放成功!");
                    element.style.backgroundColor = "#e6ffe6";
                    setTimeout(() => element.style.backgroundColor = "", 1000);
                }, 300);
               
             } catch (error) {
                alert(`❌ 播放失败: ${error.message}`);
                element.style.backgroundColor = "#ffe6e6";
                setTimeout(() => element.style.backgroundColor = "", 1000);
            }
        }


         // 获取音频URL(带重试机制)
         fetch(apiUrl)
        async function getAudioUrl(audioFile) {
             .then(response => response.json())
             try {
            .then(data => {
                const apiUrl = mw.util.wikiScript('api') + '?action=query&titles=' +
                    encodeURIComponent(audioFile) + '&prop=imageinfo&iiprop=url&format=json';
               
                const response = await fetch(apiUrl);
                if (!response.ok) throw new Error(`API返回${response.status}状态`);
               
                const data = await response.json();
                 const pages = data.query.pages;
                 const pages = data.query.pages;
                 const pageId = Object.keys(pages)[0];
                 const pageId = Object.keys(pages)[0];
                  
                 const audioUrl = pages[pageId].imageinfo[0].url;
                if (!pages[pageId].imageinfo) {
                 audioUrlCache.set(audioFile, audioUrl);
                    throw new Error("文件不存在或无查看权限");
                 new Audio(audioUrl).play();
                }
             });
               
    }
                return pages[pageId].imageinfo[0].url;
                  
            } catch (error) {
                 throw new Error(`获取URL失败: ${error.message}`);
             }
        }


        // 专用播放器(兼容iOS)
    // 初始化事件绑定
        async function playAudio(url) {
    function initAudioTriggers() {
            try {
        document.querySelectorAll('.audio-trigger').forEach(element => {
                // iOS特殊处理
            if (element._audioBound) return;
                if (/iPad|iPhone|iPod/.test(navigator.userAgent)) {
            element._audioBound = true;
                    const emptyAudio = new Audio();
                    await emptyAudio.play().catch(() => {});
                }


                const audio = new Audio(url);
            // 统一事件处理器(不阻止冒泡和默认行为)
                 await audio.play();
            const handler = (event) => {
                  
                 handlePlay(element);
            } catch (error) {
                 // 不调用 event.stopPropagation() 或 event.preventDefault()
                throw new Error(`浏览器阻止播放: ${error.message}`);
             };
             }
        }


        // 双重初始化保障
            // 同时绑定touch和click(passive模式提升移动端性能)
        mw.hook('wikipage.content').add(initAudioTriggers);
            element.addEventListener('touchstart', handler, { passive: true });
        if (document.readyState === 'complete') {
             element.addEventListener('click', handler);
            initAudioTriggers();
         });
        } else {
    }
             document.addEventListener('DOMContentLoaded', initAudioTriggers);
         }


     }).catch(error => {
     // 页面加载时初始化
        alert(`💣 核心依赖加载失败: ${error.message}`);
    mw.hook('wikipage.content').add(initAudioTriggers);
    });
    mw.loader.using('mediawiki.api').then(initAudioTriggers);
})();
})();

2025年5月24日 (六) 23:56的最新版本

// MediaWiki:Gadget-AudioText.js
(function() {
    const audioUrlCache = new Map();

    // 播放音频核心逻辑
    function handlePlay(element) {
        const audioFile = element.dataset.audioFile;
        
        // 优先使用缓存
        if (audioUrlCache.has(audioFile)) {
            new Audio(audioUrlCache.get(audioFile)).play();
            return;
        }

        // 通过API获取真实URL
        const apiUrl = mw.util.wikiScript('api') + '?action=query&titles=' + 
            encodeURIComponent(audioFile) + '&prop=imageinfo&iiprop=url&format=json';

        fetch(apiUrl)
            .then(response => response.json())
            .then(data => {
                const pages = data.query.pages;
                const pageId = Object.keys(pages)[0];
                const audioUrl = pages[pageId].imageinfo[0].url;
                audioUrlCache.set(audioFile, audioUrl);
                new Audio(audioUrl).play();
            });
    }

    // 初始化事件绑定
    function initAudioTriggers() {
        document.querySelectorAll('.audio-trigger').forEach(element => {
            if (element._audioBound) return;
            element._audioBound = true;

            // 统一事件处理器(不阻止冒泡和默认行为)
            const handler = (event) => {
                handlePlay(element);
                // 不调用 event.stopPropagation() 或 event.preventDefault()
            };

            // 同时绑定touch和click(passive模式提升移动端性能)
            element.addEventListener('touchstart', handler, { passive: true });
            element.addEventListener('click', handler);
        });
    }

    // 页面加载时初始化
    mw.hook('wikipage.content').add(initAudioTriggers);
    mw.loader.using('mediawiki.api').then(initAudioTriggers);
})();