跳转到内容

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

来自电棍ottowiki
 
(未显示同一用户的7个中间版本)
第1行: 第1行:
// MediaWiki:Gadget-AudioText.js
// MediaWiki:Gadget-AudioText.js
(function() {
(function() {
     // ========== 阶段1:全局初始化追踪 ==========
     const audioUrlCache = new Map();
    alert("[0/5] Gadget脚本开始执行");


     // ========== 阶段2:基础环境检测 ==========
     // 播放音频核心逻辑
     if (typeof mw === 'undefined') {
     function handlePlay(element) {
         alert("[1/5] ❌ 致命错误:MediaWiki核心对象未定义");
         const audioFile = element.dataset.audioFile;
        return;
    }
    alert("[2/5] ✅ 检测到MediaWiki核心对象");
 
    // ========== 阶段3:强制加载依赖 ==========
    mw.loader.using(['mediawiki.util', 'mediawiki.api'], function() {
        alert("[3/5] ✅ 核心依赖已加载");
          
          
         // ========== 阶段4:主逻辑定义 ==========
         // 优先使用缓存
         const initAudioSystem = function() {
         if (audioUrlCache.has(audioFile)) {
             try {
             new Audio(audioUrlCache.get(audioFile)).play();
                // 调试:检查页面元素
            return;
                const elements = document.querySelectorAll('.audio-trigger');
        }
                if (elements.length === 0) {
                    alert("[4/5] ⚠️ 未找到.audio-trigger元素");
                    return;
                }
                alert(`[4/5] ✅ 找到${elements.length}个音频元素`);


                // 定义播放逻辑
        // 通过API获取真实URL
                const handleClick = async (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("[播放1] 模板参数: " + audioFile);


                        // 构造API请求
        fetch(apiUrl)
                        const apiUrl = mw.util.wikiScript('api') +
            .then(response => response.json())
                            '?action=query&format=json&titles=' +
            .then(data => {
                            encodeURIComponent(audioFile) +
                const pages = data.query.pages;
                            '&prop=imageinfo&iiprop=url';
                const pageId = Object.keys(pages)[0];
                        alert("[播放2] 请求API: " + apiUrl);
                const audioUrl = pages[pageId].imageinfo[0].url;
                audioUrlCache.set(audioFile, audioUrl);
                new Audio(audioUrl).play();
            });
    }


                        // 获取音频URL
    // 初始化事件绑定
                        const response = await fetch(apiUrl);
    function initAudioTriggers() {
                        const data = await response.json();
        document.querySelectorAll('.audio-trigger').forEach(element => {
                        const pages = data.query.pages;
            if (element._audioBound) return;
                        const pageId = Object.keys(pages)[0];
            element._audioBound = true;
                        const audioUrl = pages[pageId].imageinfo[0].url;
                        alert("[播放3] 解析URL: " + audioUrl);


                        // 立即播放
            // 统一事件处理器(不阻止冒泡和默认行为)
                        const audio = new Audio(audioUrl);
            const handler = (event) => {
                        audio.play().then(() => {
                handlePlay(element);
                            alert("[播放4] ✅ 播放成功");
                // 不调用 event.stopPropagation() 或 event.preventDefault()
                        }).catch(e => {
            };
                            alert("[播放5] ❌ 播放失败: " + e.message);
                        });


                    } catch(e) {
            // 同时绑定touch和click(passive模式提升移动端性能)
                        alert("[播放X] 💥 全局错误: " + e.message);
            element.addEventListener('touchstart', handler, { passive: true });
                    }
            element.addEventListener('click', handler);
                };
 
                // ========== 阶段5:事件绑定 ==========
                elements.forEach(element => {
                    if (element._bound) return;
                    element._bound = true;
 
                    // 桌面端点击
                    element.addEventListener('click', (e) => {
                        e.preventDefault();
                        alert("[事件] 点击事件触发");
                        handleClick(element);
                    });
 
                    // 移动端触摸
                    element.addEventListener('touchstart', (e) => {
                        e.preventDefault();
                        alert("[事件] 触摸事件触发");
                        handleClick(element);
                    }, { passive: false });
 
                    alert(`[绑定] 元素已绑定: ${element.textContent}`);
                });
 
            } catch(e) {
                alert("[初始化X] 💣 系统崩溃: " + e.message);
            }
        };
 
        // ========== 强制初始化机制 ==========
        if (document.readyState === 'complete') {
            alert("[5/5] ⚡ 文档已就绪,立即初始化");
            initAudioSystem();
        } else {
            alert("[5/5] ⏳ 等待文档加载完成");
            document.addEventListener('DOMContentLoaded', initAudioSystem);
        }
 
        // 动态内容监听
        mw.hook('wikipage.content').add(() => {
            alert("[动态] 检测到新内容,重新初始化");
            initAudioSystem();
         });
         });
    }


     }, function(error) {
     // 页面加载时初始化
        alert("[依赖X] ❌ 依赖加载失败: " + error.toString());
    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);
})();