MediaWiki:Gadget-PrintOptions.js
外观
	
	
注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
 - Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
 - Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5。
 
// ==UserScript==
// @name         Safe Web Audio Implementation
// @namespace    https://github.com/
// @version      1.0
// @description  Proper AudioContext initialization with full error handling
// @author       You
// @match        *://*/*
// @grant        none
// @require      https://cdn.jsdelivr.net/npm/web-audio-api-shim@0.2.6/build/WebAudioAPI.min.js
// ==/UserScript==
(function() {
    'use strict';
    // 🔊 Audio Context Manager Class
    class AudioSystem {
        constructor(options = {}) {
            this.options = {
                latencyHint: 'interactive',
                sampleRate: 44100,
                ...options
            };
            this.context = null;
            this.init();
        }
        // 🔍 Detect supported AudioContext class
        static getAudioContextClass() {
            const prefixes = ['', 'webkit', 'moz', 'ms'];
            for (const prefix of prefixes) {
                const name = prefix ? `${prefix}AudioContext` : 'AudioContext';
                if (window[name]) return window[name];
            }
            return null;
        }
        // 🏗️ Initialize audio system
        init() {
            const AudioContextClass = AudioSystem.getAudioContextClass();
            if (!AudioContextClass) {
                console.warn('Web Audio API not supported');
                return;
            }
            try {
                this.context = new AudioContextClass(this.options);
                this.setupEventListeners();
                this.log('AudioContext created');
            } catch (error) {
                console.error('AudioContext initialization failed:', error);
            }
        }
        // 🎛️ Setup state management
        setupEventListeners() {
            if (!this.context) return;
            // Monitor state changes
            this.context.onstatechange = () => {
                this.log(`State changed: ${this.context.state}`);
                
                if (this.context.state === 'suspended') {
                    this.addActivationTriggers();
                }
            };
            // Initial activation check
            if (this.context.state === 'suspended') {
                this.addActivationTriggers();
            }
        }
        // 🖱️ Add user interaction triggers
        addActivationTriggers() {
            const events = ['click', 'keydown', 'touchstart'];
            const handler = () => {
                if (this.context && this.context.state === 'suspended') {
                    this.context.resume()
                        .then(() => this.log('Audio resumed successfully'))
                        .catch(err => console.error('Resume failed:', err));
                }
                
                // Remove after first activation
                events.forEach(e => document.removeEventListener(e, handler));
            };
            events.forEach(e => document.addEventListener(e, handler));
        }
        // 📝 Logging helper
        log(message) {
            console.log(`[AudioSystem] ${message}`);
        }
        // 🎵 Safe audio playback
        playBuffer(buffer) {
            if (!this.context || this.context.state !== 'running') {
                console.warn('Audio not ready');
                return null;
            }
            try {
                const source = this.context.createBufferSource();
                source.buffer = buffer;
                source.connect(this.context.destination);
                source.start();
                return source;
            } catch (error) {
                console.error('Playback failed:', error);
                return null;
            }
        }
    }
    // 🚀 Startup sequence
    document.addEventListener('DOMContentLoaded', () => {
        const audioSystem = new AudioSystem({
            latencyHint: 'balanced',
            sampleRate: 48000
        });
        // Example usage
        setTimeout(() => {
            if (audioSystem.context) {
                // Load and play dummy sound
                const buffer = audioSystem.context.createBuffer(
                    1, 
                    audioSystem.context.sampleRate * 0.5, 
                    audioSystem.context.sampleRate
                );
                audioSystem.playBuffer(buffer);
            }
        }, 3000);
    });
})();