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);
});
})();