跳转到内容

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

勤求古训,博采众方
无编辑摘要
无编辑摘要
标签手工回退
 
(未显示同一用户的7个中间版本)
第1行: 第1行:
// ==UserScript==
(function () {
// @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';
     'use strict';
 
   
     // 🔊 Audio Context Manager Class
    var windowManager;
     class AudioSystem {
    var printDialog;
         constructor(options = {}) {
      
             this.options = {
     var printOptions = {
                 latencyHint: 'interactive',
         install: function () {
                 sampleRate: 44100,
            var $printLink = $('#t-print a');
                ...options
             if ($printLink.length === 0) return;
            };
           
            this.context = null;
            $printLink
            this.init();
                .text('可打印版本')
        }
                 .off('click')
 
                 .on('click', function (e) {
        // 🔍 Detect supported AudioContext class
                    mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'])
        static getAudioContextClass() {
                        .then(printOptions.createWindow)
            const prefixes = ['', 'webkit', 'moz', 'ms'];
                        .catch(function (err) {
            for (const prefix of prefixes) {
                            mw.notify('打印功能加载失败: ' + err.message, { type: 'error' });
                const name = prefix ? `${prefix}AudioContext` : 'AudioContext';
                        });
                 if (window[name]) return window[name];
                    e.preventDefault();
                });
           
            // 预加载资源
            mw.loader.load(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows']);
        },
       
        createWindow: function () {
            function PrintDialog(config) {
                 PrintDialog.super.call(this, config);
             }
             }
             return null;
             OO.inheritClass(PrintDialog, OO.ui.ProcessDialog);
        }
           
 
            PrintDialog.static.name = 'printdialog';
        // 🏗️ Initialize audio system
             PrintDialog.static.title = '打印此页面';
        init() {
             PrintDialog.static.actions = [
             const AudioContextClass = AudioSystem.getAudioContextClass();
                { action: 'print', label: '打印', flags: ['primary', 'progressive'] },
             if (!AudioContextClass) {
                 { action: 'cancel', label: '取消', flags: 'safe' }
                 console.warn('Web Audio API not supported');
            ];
                return;
              
             }
             PrintDialog.prototype.initialize = function () {
 
                 PrintDialog.super.prototype.initialize.apply(this, arguments);
             try {
                 this.panel = new OO.ui.PanelLayout({ padded: true, expanded: false });
                 this.context = new AudioContextClass(this.options);
                 this.content = new OO.ui.FieldsetLayout();
                 this.setupEventListeners();
               
                 this.log('AudioContext created');
                printOptions.questions.forEach(function (question) {
            } catch (error) {
                    if (question.type === 'checkbox') {
                console.error('AudioContext initialization failed:', error);
                        var checkbox = new OO.ui.CheckboxInputWidget({
            }
                            selected: question.checked
        }
                        });
 
                        question.widget = checkbox;
        // 🎛️ Setup state management
                        this.content.addItems([
        setupEventListeners() {
                            new OO.ui.FieldLayout(checkbox, {
            if (!this.context) return;
                                label: question.label,
 
                                align: 'inline'
            // Monitor state changes
                            })
            this.context.onstatechange = () => {
                        ]);
                this.log(`State changed: ${this.context.state}`);
                    }
                }, this);
                  
                  
                 if (this.context.state === 'suspended') {
                 this.panel.$element.append(this.content.$element);
                     this.addActivationTriggers();
                this.$body.append(this.panel.$element);
            };
           
            // ✅ 修复点:明确处理取消动作
            PrintDialog.prototype.getActionProcess = function (action) {
                if (action === 'print') {
                     return new OO.ui.Process(function () {
                        printOptions.questions.forEach(function (question) {
                            if (question.widget) {
                                printOptions[question.returnvalue] = question.widget.isSelected();
                            }
                        });
                        return this.close({ action: action }).then(function () {
                            printOptions.changePrintCSS();
                            printOptions.otherEnhancements();
                            setTimeout(window.print, 100);
                        });
                    }.bind(this));
                 }
                 }
                // 🔥 关键修复:取消时直接关闭对话框
                if (action === 'cancel') {
                    return new OO.ui.Process(function () {
                        return this.close({ action: action });
                    }.bind(this));
                }
                return PrintDialog.super.prototype.getActionProcess.call(this, action);
             };
             };
 
              
             // Initial activation check
             if (!windowManager) {
             if (this.context.state === 'suspended') {
                windowManager = new OO.ui.WindowManager();
                this.addActivationTriggers();
                $('body').append(windowManager.$element);
             }
             }
         }
            if (!printDialog) {
 
                printDialog = new PrintDialog({ size: 'medium' });
         // 🖱️ Add user interaction triggers
                windowManager.addWindows([printDialog]);
         addActivationTriggers() {
            }
             const events = ['click', 'keydown', 'touchstart'];
            windowManager.openWindow(printDialog);
             const handler = () => {
         },
                if (this.context && this.context.state === 'suspended') {
          
                    this.context.resume()
         changePrintCSS: function () {
                        .then(() => this.log('Audio resumed successfully'))
             /* 原有CSS处理逻辑 */
                        .catch(err => console.error('Resume failed:', err));
            var printStyle = '';
                }
             if (this.noimages) printStyle += 'img, .thumb { display:none !important; }\n';
               
            if (this.norefs) printStyle += '.references, .reference { display:none !important; }\n';
                // Remove after first activation
            if (this.notoc) printStyle += '#toc, .toc { display:none !important; }\n';
                events.forEach(e => document.removeEventListener(e, handler));
            if (this.nobackground) printStyle += 'body { background: white !important; }\n';
            };
             if (this.blacktext) printStyle += '* { color: black !important; }\n';
 
           
             events.forEach(e => document.addEventListener(e, handler));
            $('style[media="print"]').remove(); // 清理旧样式
        }
            if (printStyle) {
 
                $('head').append('<style media="print">' + printStyle + '</style>');
        // 📝 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;
             }
             }
 
        },
       
        otherEnhancements: function () {
            var $link = $('div.printfooter a');
             try {
             try {
                 const source = this.context.createBufferSource();
                 $link.text(decodeURIComponent($link.text()));
                 source.buffer = buffer;
            } catch (e) {
                source.connect(this.context.destination);
                 mw.log.warn('URL解码失败:', e);
                 source.start();
            }
                 return source;
        },
             } catch (error) {
       
                 console.error('Playback failed:', error);
        questions: [
                 return null;
            {
                label: '隐藏界面元素',
                type: 'checkbox',
                checked: true,
                returnvalue: 'enhanced'
            },
            {
                label: '隐藏图像',
                type: 'checkbox',
                checked: false,
                returnvalue: 'noimages'
            },
            {
                label: '隐藏引用',
                type: 'checkbox',
                checked: false,
                returnvalue: 'norefs'
            },
            {
                label: '隐藏目录',
                type: 'checkbox',
                checked: false,
                 returnvalue: 'notoc'
            },
            {
                label: '删除背景(部分浏览器可能无效)',
                type: 'checkbox',
                checked: false,
                 returnvalue: 'nobackground'
             },
            {
                 label: '强制文本为黑色',
                type: 'checkbox',
                checked: true,
                 returnvalue: 'blacktext'
             }
             }
        ]
    };
   
    // 延迟初始化以避免冲突
    $(function () {
        if (mw.config.get('wgNamespaceNumber') >= 0) {
            setTimeout(printOptions.install, 100);
         }
         }
    }
    // 🚀 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);
     });
     });
})();
})();

2025年11月1日 (六) 22:56的最新版本

(function () {
    'use strict';
    
    var windowManager;
    var printDialog;
    
    var printOptions = {
        install: function () {
            var $printLink = $('#t-print a');
            if ($printLink.length === 0) return;
            
            $printLink
                .text('可打印版本')
                .off('click')
                .on('click', function (e) {
                    mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'])
                        .then(printOptions.createWindow)
                        .catch(function (err) {
                            mw.notify('打印功能加载失败: ' + err.message, { type: 'error' });
                        });
                    e.preventDefault();
                });
            
            // 预加载资源
            mw.loader.load(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows']);
        },
        
        createWindow: function () {
            function PrintDialog(config) {
                PrintDialog.super.call(this, config);
            }
            OO.inheritClass(PrintDialog, OO.ui.ProcessDialog);
            
            PrintDialog.static.name = 'printdialog';
            PrintDialog.static.title = '打印此页面';
            PrintDialog.static.actions = [
                { action: 'print', label: '打印', flags: ['primary', 'progressive'] },
                { action: 'cancel', label: '取消', flags: 'safe' }
            ];
            
            PrintDialog.prototype.initialize = function () {
                PrintDialog.super.prototype.initialize.apply(this, arguments);
                this.panel = new OO.ui.PanelLayout({ padded: true, expanded: false });
                this.content = new OO.ui.FieldsetLayout();
                
                printOptions.questions.forEach(function (question) {
                    if (question.type === 'checkbox') {
                        var checkbox = new OO.ui.CheckboxInputWidget({
                            selected: question.checked
                        });
                        question.widget = checkbox;
                        this.content.addItems([
                            new OO.ui.FieldLayout(checkbox, {
                                label: question.label,
                                align: 'inline'
                            })
                        ]);
                    }
                }, this);
                
                this.panel.$element.append(this.content.$element);
                this.$body.append(this.panel.$element);
            };
            
            // ✅ 修复点:明确处理取消动作
            PrintDialog.prototype.getActionProcess = function (action) {
                if (action === 'print') {
                    return new OO.ui.Process(function () {
                        printOptions.questions.forEach(function (question) {
                            if (question.widget) {
                                printOptions[question.returnvalue] = question.widget.isSelected();
                            }
                        });
                        return this.close({ action: action }).then(function () {
                            printOptions.changePrintCSS();
                            printOptions.otherEnhancements();
                            setTimeout(window.print, 100);
                        });
                    }.bind(this));
                }
                // 🔥 关键修复:取消时直接关闭对话框
                if (action === 'cancel') {
                    return new OO.ui.Process(function () {
                        return this.close({ action: action });
                    }.bind(this));
                }
                return PrintDialog.super.prototype.getActionProcess.call(this, action);
            };
            
            if (!windowManager) {
                windowManager = new OO.ui.WindowManager();
                $('body').append(windowManager.$element);
            }
            if (!printDialog) {
                printDialog = new PrintDialog({ size: 'medium' });
                windowManager.addWindows([printDialog]);
            }
            windowManager.openWindow(printDialog);
        },
        
        changePrintCSS: function () {
            /* 原有CSS处理逻辑 */
            var printStyle = '';
            if (this.noimages) printStyle += 'img, .thumb { display:none !important; }\n';
            if (this.norefs) printStyle += '.references, .reference { display:none !important; }\n';
            if (this.notoc) printStyle += '#toc, .toc { display:none !important; }\n';
            if (this.nobackground) printStyle += 'body { background: white !important; }\n';
            if (this.blacktext) printStyle += '* { color: black !important; }\n';
            
            $('style[media="print"]').remove(); // 清理旧样式
            if (printStyle) {
                $('head').append('<style media="print">' + printStyle + '</style>');
            }
        },
        
        otherEnhancements: function () {
            var $link = $('div.printfooter a');
            try {
                $link.text(decodeURIComponent($link.text()));
            } catch (e) {
                mw.log.warn('URL解码失败:', e);
            }
        },
        
        questions: [
            {
                label: '隐藏界面元素',
                type: 'checkbox',
                checked: true,
                returnvalue: 'enhanced'
            },
            {
                label: '隐藏图像',
                type: 'checkbox',
                checked: false,
                returnvalue: 'noimages'
            },
            {
                label: '隐藏引用',
                type: 'checkbox',
                checked: false,
                returnvalue: 'norefs'
            },
            {
                label: '隐藏目录',
                type: 'checkbox',
                checked: false,
                returnvalue: 'notoc'
            },
            {
                label: '删除背景(部分浏览器可能无效)',
                type: 'checkbox',
                checked: false,
                returnvalue: 'nobackground'
            },
            {
                label: '强制文本为黑色',
                type: 'checkbox',
                checked: true,
                returnvalue: 'blacktext'
            }
        ]
    };
    
    // 延迟初始化以避免冲突
    $(function () {
        if (mw.config.get('wgNamespaceNumber') >= 0) {
            setTimeout(printOptions.install, 100);
        }
    });
})();