跳转到内容

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

勤求古训,博采众方
无编辑摘要
标签已被回退
无编辑摘要
标签手工回退
 
(未显示同一用户的3个中间版本)
第1行: 第1行:
/*! PrintDialog v3.0 - 支持多语言&快捷键 */
(function () {
(function (mw, $) {
     'use strict';
     'use strict';
      
      
     // 🌐 本地化文本库
     var windowManager;
     var i18n = {
     var printDialog;
        'title': mw.message('printdialog-title').plain() || '打印选项',
      
        'print-btn': mw.message('printdialog-print-btn').plain() || '打印',
     var printOptions = {
        'cancel-btn': mw.message('printdialog-cancel-btn').plain() || '取消',
         install: function () {
        'loading': mw.message('printdialog-loading').plain() || '准备打印中...',
             var $printLink = $('#t-print a');
        'print-error': mw.message('printdialog-error').plain() || '打印失败:$1',
             if ($printLink.length === 0) return;
        'no-print-support': mw.message('printdialog-no-support').plain() || '您的浏览器不支持直接打印',
        // 选项文本
        'options': {
            'hideImages': mw.message('printdialog-opt-hide-images').plain() || '隐藏图片',
            'hideRefs': mw.message('printdialog-opt-hide-refs').plain() || '隐藏参考文献'
            // 可继续扩展其他选项...
        },
        'help': {
            'hideImages': mw.message('printdialog-help-hide-images').plain() || '不打印页面中的图片和缩略图'
        }
     };
 
     var PrintDialog = {
         // ⚙️ 配置项
        config: {
             debug: false,
            dependencies: ['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'],
            hotkeys: {
                print: 'ctrl+enter', // 打印快捷键
                cancel: 'esc'       // 取消快捷键
            }
        },
       
        // 🚀 初始化
        init: function () {
             if (!this.shouldInit()) return;
              
              
             // 绑定打印按钮
             $printLink
            $('#t-print a').first()
                .text('可打印版本')
                 .text(mw.message('printdialog-link-text').plain() || '可打印版本')
                .off('click')
                .off('click.print')
                 .on('click', function (e) {
                .on('click.print', this.onPrintClick.bind(this));
                    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();
                });
              
              
             // 预加载资源
             // 预加载资源
             if (!this.isDepsLoaded()) {
             mw.loader.load(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows']);
                mw.loader.load(this.config.dependencies);
            }
           
            // 注册全局快捷键(需确保唯一性)
            this.registerHotkeys();
        },
       
        // 🔥 快捷键支持
        registerHotkeys: function () {
            $(document).off('keydown.printdialog')
                .on('keydown.printdialog', function (e) {
                    if (!PrintDialog.dialog || !PrintDialog.windowManager) return;
                   
                    // ESC - 取消
                    if (e.key === 'Escape') {
                        PrintDialog.dialog.executeAction('cancel');
                        e.preventDefault();
                    }
                   
                    // Ctrl+Enter - 打印
                    if (e.ctrlKey && e.key === 'Enter') {
                        PrintDialog.dialog.executeAction('print');
                        e.preventDefault();
                    }
                });
         },
         },
          
          
         // 🏗️ 创建对话框
         createWindow: function () {
        createDialog: function () {
             function PrintDialog(config) {
            if (this.dialog) {
                 PrintDialog.super.call(this, config);
                this.windowManager.openWindow(this.dialog);
                return;
            }
           
            // 对话框构造函数
             function Dialog(config) {
                 Dialog.super.call(this, config);
             }
             }
             OO.inheritClass(Dialog, OO.ui.ProcessDialog);
             OO.inheritClass(PrintDialog, OO.ui.ProcessDialog);
              
              
             // 静态配置(使用本地化文本)
             PrintDialog.static.name = 'printdialog';
            Dialog.static.name = 'printDialog';
             PrintDialog.static.title = '打印此页面';
             Dialog.static.title = i18n.title;
             PrintDialog.static.actions = [
             Dialog.static.actions = [
                 { action: 'print', label: '打印', flags: ['primary', 'progressive'] },
                 {  
                 { action: 'cancel', label: '取消', flags: 'safe' }
                    action: 'print',  
                    label: i18n['print-btn'],
                    flags: ['primary', 'progressive'],
                    icon: 'printer'
                },
                 {  
                    action: 'cancel',  
                    label: i18n['cancel-btn'],  
                    flags: 'safe',
                    icon: 'close'
                }
             ];
             ];
              
              
             // 初始化内容
             PrintDialog.prototype.initialize = function () {
            Dialog.prototype.initialize = function () {
                 PrintDialog.super.prototype.initialize.apply(this, arguments);
                 Dialog.super.prototype.initialize.apply(this, arguments);
                 this.panel = new OO.ui.PanelLayout({ padded: true, expanded: false });
                 this.buildForm();
                 this.content = new OO.ui.FieldsetLayout();
            };
           
            // 构建表单(本地化选项)
            Dialog.prototype.buildForm = function () {
                var panel = new OO.ui.PanelLayout({ padded: true });
                 var fieldset = new OO.ui.FieldsetLayout();
                  
                  
                 PrintDialog.options.forEach(function (opt) {
                 printOptions.questions.forEach(function (question) {
                     if (opt.type === 'checkbox') {
                     if (question.type === 'checkbox') {
                         var widget = new OO.ui.CheckboxInputWidget({
                         var checkbox = new OO.ui.CheckboxInputWidget({
                             selected: !!opt.default
                             selected: question.checked
                         });
                         });
                          
                         question.widget = checkbox;
                         fieldset.addItems([
                         this.content.addItems([
                             new OO.ui.FieldLayout(widget, {
                             new OO.ui.FieldLayout(checkbox, {
                                 label: i18n.options[opt.id] || opt.id,
                                 label: question.label,
                                 align: 'inline',
                                 align: 'inline'
                                help: i18n.help[opt.id] ?
                                    new OO.ui.LabelWidget({ label: i18n.help[opt.id] }) : null
                             })
                             })
                         ]);
                         ]);
                       
                        opt.widget = widget; // 保存引用
                     }
                     }
                 });
                 }, this);
                  
                  
                 panel.$element.append(fieldset.$element);
                 this.panel.$element.append(this.content.$element);
                 this.$body.append(panel.$element);
                 this.$body.append(this.panel.$element);
             };
             };
              
              
             // 处理动作(含快捷键支持)
             // ✅ 修复点:明确处理取消动作
             Dialog.prototype.getActionProcess = function (action) {
             PrintDialog.prototype.getActionProcess = function (action) {
                 if (action === 'print') {
                 if (action === 'print') {
                     return new OO.ui.Process(function () {
                     return new OO.ui.Process(function () {
                         return this.executePrintAction();
                        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));
                     }.bind(this));
                 }
                 }
                 return Dialog.super.prototype.getActionProcess.call(this, action);
                 return PrintDialog.super.prototype.getActionProcess.call(this, action);
             };
             };
              
              
             // 执行打印(拆分为独立方法)
             if (!windowManager) {
            Dialog.prototype.executePrintAction = function () {
                 windowManager = new OO.ui.WindowManager();
                 // 保存设置
                 $('body').append(windowManager.$element);
                PrintDialog.options.forEach(function (opt) {
             }
                    PrintDialog.settings[opt.id] = opt.widget.isSelected();
             if (!printDialog) {
                 });
                 printDialog = new PrintDialog({ size: 'medium' });
               
                 windowManager.addWindows([printDialog]);
                // 关闭窗口并处理打印
                return this.close({ action: 'print' })
                    .then(PrintDialog.applyPrintStyles)
                    .then(function () {
                        if (typeof window.print === 'function') {
                            window.print();
                        } else {
                            mw.notify(i18n['no-print-support'], { type: 'warning' });
                        }
                    })
                    .catch(function (err) {
                        mw.notify(i18n['print-error'].replace('$1', err.message), { type: 'error' });
                    });
             };
           
            // 初始化窗口管理器
             if (!this.windowManager) {
                 this.windowManager = new OO.ui.WindowManager();
                 $('body').append(this.windowManager.$element);
             }
             }
              
             windowManager.openWindow(printDialog);
            // 创建对话框实例
            this.dialog = new Dialog({ size: 'medium' });
            this.windowManager.addWindows([this.dialog]);
            this.windowManager.openWindow(this.dialog);
         },
         },
          
          
         // 🎨 应用打印样式
         changePrintCSS: function () {
        applyPrintStyles: function () {
            /* 原有CSS处理逻辑 */
             var style = [];
             var printStyle = '';
              
             if (this.noimages) printStyle += 'img, .thumb { display:none !important; }\n';
             if (PrintDialog.settings.hideImages) {
             if (this.norefs) printStyle += '.references, .reference { display:none !important; }\n';
                style.push('img, .thumb { display:none !important; }');
            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(); // 清理旧样式
             $('style.print-styles').remove();
             if (printStyle) {
             if (style.length) {
                 $('head').append('<style media="print">' + printStyle + '</style>');
                 $('<style>')
                    .addClass('print-styles')
                    .attr('media', 'print')
                    .text(style.join('\n'))
                    .appendTo('head');
             }
             }
           
            return Promise.resolve();
         },
         },
          
          
         // ✅ 工具方法
         otherEnhancements: function () {
        shouldInit: function () {
             var $link = $('div.printfooter a');
             return mw.config.get('wgNamespaceNumber') >= 0;
            try {
                $link.text(decodeURIComponent($link.text()));
            } catch (e) {
                mw.log.warn('URL解码失败:', e);
            }
         },
         },
          
          
         isDepsLoaded: function () {
         questions: [
             return this.config.dependencies.every(function (dep) {
             {
                 return mw.loader.getState(dep) === 'ready';
                 label: '隐藏界面元素',
            });
                type: 'checkbox',
        },
                checked: true,
       
                returnvalue: 'enhanced'
        // 🖨️ 主入口处理
             },
        onPrintClick: function (e) {
             {
             e.preventDefault();
                 label: '隐藏图像',
              
                 type: 'checkbox',
            var notification = mw.notify(
                checked: false,
                 new OO.ui.ProgressBarWidget({ progress: false }).$element,  
                 returnvalue: 'noimages'
                 {
             },
                    title: i18n.loading,
             {
                    autoHide: false
                label: '隐藏引用',
                 }
                 type: 'checkbox',
             );
                 checked: false,
              
                returnvalue: 'norefs'
            mw.loader.using(this.config.dependencies)
            },
                 .then(this.createDialog.bind(this))
            {
                 .catch(function (err) {
                label: '隐藏目录',
                    mw.notify(i18n['print-error'].replace('$1', err.message), { type: 'error' });
                type: 'checkbox',
                 })
                 checked: false,
                 .always(function () {
                 returnvalue: 'notoc'
                    notification.close();
            },
                });
        },
       
        // ⚙️ 可配置选项
        options: [
             {
             {
                 id: 'hideImages',
                 label: '删除背景(部分浏览器可能无效)',
                 type: 'checkbox',
                 type: 'checkbox',
                 default: false
                 checked: false,
                returnvalue: 'nobackground'
             },
             },
             {
             {
                 id: 'hideRefs',
                 label: '强制文本为黑色',
                 type: 'checkbox',
                 type: 'checkbox',
                 default: false
                 checked: true,
            }
                returnvalue: 'blacktext'
        ],
       
        // 🗃️ 状态存储
        settings: {},
       
        // ♻️ 清理方法
        destroy: function () {
            $(document).off('keydown.printdialog');
            if (this.windowManager) {
                this.windowManager.destroy();
                this.windowManager = null;
             }
             }
            this.dialog = null;
         ]
         }
     };
     };
      
      
     // 📅 延迟初始化
     // 延迟初始化以避免冲突
     mw.hook('wikipage.content').add(function () {
     $(function () {
        setTimeout(PrintDialog.init.bind(PrintDialog), 300);
        if (mw.config.get('wgNamespaceNumber') >= 0) {
            setTimeout(printOptions.install, 100);
        }
     });
     });
   
})();
    // 🖇️ 暴露到全局(可选)
    window.PrintDialog = PrintDialog;
})(mediaWiki, jQuery);

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