跳转到内容

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

来自电棍ottowiki
第1行: 第1行:
// MediaWiki:Gadget-AudioText.js
// MediaWiki:Gadget-AudioText.js
(function() {
(function() {
     // 预缓存音频URL(提升隐私模式下的成功率)
     // 强制声明依赖并确保mw.util可用
     let cachedAudioUrl = null;
     mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() {
        alert("🎉 JS脚本已加载!"); // 确保依赖加载完成后才提示


    mw.hook('wikipage.content').add(function() {
        // 主初始化函数
        alert("🎉 JS脚本已加载!"); // 保留初始提示
        function initAudioTriggers() {
       
            try {
        document.querySelectorAll('.audio-trigger').forEach(element => {
                const triggers = document.querySelectorAll('.audio-trigger');
            element.addEventListener('click', async function() {
                 if (triggers.length === 0) {
                 try {
                    alert("⚠️ 未找到任何音频触发器元素!检查模板类名是否正确");
                    // 立即尝试播放缓存(减少API请求)
                    return;
                    if (cachedAudioUrl) {
                }
                        await playAudio(cachedAudioUrl);
                        return showDebugInfo(element, "✅ 使用缓存播放成功"); // [!code focus]
                    }


                    // 首次加载流程
                triggers.forEach(element => {
                     const audioFile = element.dataset.audioFile;
                     if (element._initialized) return;
                     const apiUrl = mw.util.wikiScript('api') + '?action=query&titles=' +
                     element._initialized = true;
                        encodeURIComponent(audioFile) + '&prop=imageinfo&iiprop=url&format=json';


                     // 并行处理:立即播放 + 后台更新缓存
                     // 绑定标准化事件(兼容移动端)
                     const audioUrl = await fetch(apiUrl)
                     const handler = async (event) => {
                         .then(response => response.json())
                         event.preventDefault();
                         .then(data => {
                         alert("🖱️ 点击事件已触发!"); // 确保事件触发可见
                            const pages = data.query.pages;
                        await handleClick(element);
                            const pageId = Object.keys(pages)[0];
                    };
                            return pages[pageId].imageinfo[0].url;
                        });
                      
                      
                     cachedAudioUrl = audioUrl; // 更新缓存
                     element.addEventListener('touchstart', handler, { passive: false });
                   
                    element.addEventListener('click', handler);
                    // 立即播放不等待调试提示
                });
                    await playAudio(audioUrl);
               
                      
            } catch (error) {
                     // 播放成功后显示调试信息
                alert(`💥 初始化失败: ${error.message}`);
                     showDebugInfo(element, `🎵 音频URL: ${audioUrl}\n✅ 实时播放成功`); // [!code focus]
            }
                      
        }
                 } catch (error) {
 
                    showDebugInfo(element, `❌ 错误: ${error.message}\n⚠️ 请关闭防跟踪功能后重试`);
        // 点击处理核心逻辑
        async function handleClick(element) {
            try {
                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(带重试机制)
        async function getAudioUrl(audioFile) {
            try {
                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 pageId = Object.keys(pages)[0];
               
                if (!pages[pageId].imageinfo) {
                     throw new Error("文件不存在或无查看权限");
                 }
               
                return pages[pageId].imageinfo[0].url;
               
            } catch (error) {
                throw new Error(`获取URL失败: ${error.message}`);
            }
        }
 
        // 专用播放器(兼容iOS)
        async function playAudio(url) {
            try {
                // iOS特殊处理
                if (/iPad|iPhone|iPod/.test(navigator.userAgent)) {
                    const emptyAudio = new Audio();
                    await emptyAudio.play().catch(() => {});
                 }
                 }
            });
        });
    });


    // 专用播放函数
                const audio = new Audio(url);
    async function playAudio(url) {
                await audio.play();
        const audio = new Audio(url);
               
        await audio.play().catch(e => {
            } catch (error) {
            throw new Error(`播放被阻止 (${e.message})`);
                throw new Error(`浏览器阻止播放: ${error.message}`);
         });
            }
    }
        }
 
        // 双重初始化保障
        mw.hook('wikipage.content').add(initAudioTriggers);
        if (document.readyState === 'complete') {
            initAudioTriggers();
         } else {
            document.addEventListener('DOMContentLoaded', initAudioTriggers);
        }


     // 延迟显示调试信息(不影响播放)
     }).catch(error => {
    function showDebugInfo(element, message) { // [!code focus]
        alert(`💣 核心依赖加载失败: ${error.message}`);
        setTimeout(() => { // 延迟500ms确保播放已触发
    });
            alert(message);
            element.style.backgroundColor = "#f0f8ff"; // 可视化反馈
            setTimeout(() => element.style.backgroundColor = "", 1000);
        }, 500);
    }
})();
})();

2025年5月24日 (六) 22:42的版本

// MediaWiki:Gadget-AudioText.js
(function() {
    // 强制声明依赖并确保mw.util可用
    mw.loader.using(['mediawiki.util', 'mediawiki.api']).then(function() {
        alert("🎉 JS脚本已加载!"); // 确保依赖加载完成后才提示

        // 主初始化函数
        function initAudioTriggers() {
            try {
                const triggers = document.querySelectorAll('.audio-trigger');
                if (triggers.length === 0) {
                    alert("⚠️ 未找到任何音频触发器元素!检查模板类名是否正确");
                    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}`);
            }
        }

        // 点击处理核心逻辑
        async function handleClick(element) {
            try {
                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(带重试机制)
        async function getAudioUrl(audioFile) {
            try {
                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 pageId = Object.keys(pages)[0];
                
                if (!pages[pageId].imageinfo) {
                    throw new Error("文件不存在或无查看权限");
                }
                
                return pages[pageId].imageinfo[0].url;
                
            } catch (error) {
                throw new Error(`获取URL失败: ${error.message}`);
            }
        }

        // 专用播放器(兼容iOS)
        async function playAudio(url) {
            try {
                // iOS特殊处理
                if (/iPad|iPhone|iPod/.test(navigator.userAgent)) {
                    const emptyAudio = new Audio();
                    await emptyAudio.play().catch(() => {});
                }

                const audio = new Audio(url);
                await audio.play();
                
            } catch (error) {
                throw new Error(`浏览器阻止播放: ${error.message}`);
            }
        }

        // 双重初始化保障
        mw.hook('wikipage.content').add(initAudioTriggers);
        if (document.readyState === 'complete') {
            initAudioTriggers();
        } else {
            document.addEventListener('DOMContentLoaded', initAudioTriggers);
        }

    }).catch(error => {
        alert(`💣 核心依赖加载失败: ${error.message}`);
    });
})();