跳转到内容

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

勤求古训,博采众方
无编辑摘要
无编辑摘要
标签手工回退
 
(未显示同一用户的8个中间版本)
第1行: 第1行:
// ==UserScript==
(function () {
// @name        MediaWiki打印增强
// @description  高级打印选项(优化布局/隐藏图片等)
// @namespace    https://github.com/yourname/
// @version      2.0
// @match        *://*/*
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
// ==/UserScript==
 
(function() {
     'use strict';
     'use strict';
 
   
     // ============== 核心配置 ==============
     var windowManager;
    const PrintEnhancer = {
    var printDialog;
         // 默认配置
   
         config: {
    var printOptions = {
             enhanced: true,
        install: function () {
             noimages: false,
            var $printLink = $('#t-print a');
             norefs: false,
            if ($printLink.length === 0) return;
             notoc: false,
           
             nobackground: false,
            $printLink
             blacktext: true
                .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: [
         questions: [
             {
             {
                label: '隐藏界面元素',
                 type: 'checkbox',
                 type: 'checkbox',
                 name: 'enhanced',
                 checked: true,
                 label: '优化打印布局',
                 returnvalue: 'enhanced'
                help: '隐藏编辑按钮等非必要元素'
             },
             },
             {
             {
                label: '隐藏图像',
                 type: 'checkbox',
                 type: 'checkbox',
                 name: 'noimages',
                 checked: false,
                 label: '隐藏所有图片'
                 returnvalue: 'noimages'
             },
             },
             {
             {
                label: '隐藏引用',
                 type: 'checkbox',
                 type: 'checkbox',
                 name: 'norefs',
                 checked: false,
                 label: '隐藏参考文献'
                 returnvalue: 'norefs'
             },
             },
             {
             {
                label: '隐藏目录',
                 type: 'checkbox',
                 type: 'checkbox',
                 name: 'notoc',
                 checked: false,
                 label: '隐藏目录'
                 returnvalue: 'notoc'
             },
             },
             {
             {
                label: '删除背景(部分浏览器可能无效)',
                 type: 'checkbox',
                 type: 'checkbox',
                 name: 'nobackground',
                 checked: false,
                 label: '移除背景色',
                 returnvalue: 'nobackground'
                help: '节省墨水,但可能影响部分内容可见性'
             },
             },
             {
             {
                label: '强制文本为黑色',
                 type: 'checkbox',
                 type: 'checkbox',
                 name: 'blacktext',
                 checked: true,
                 label: '强制纯黑色文字'
                 returnvalue: 'blacktext'
             }
             }
         ],
         ]
 
    };
        // ============== 初始化 ==============
   
        init() {
    // 延迟初始化以避免冲突
            const $printLink = $('#t-print a, .vector-menu-tabs a[href*="printable=yes"]').first();
    $(function () {
            if (!$printLink.length) {
        if (mw.config.get('wgNamespaceNumber') >= 0) {
                console.warn('找不到打印链接');
            setTimeout(printOptions.install, 100);
                return;
            }
 
            $printLink
                .text('可打印版本')
                .off('click.mwprint')
                .on('click.mwprint', (e) => {
                    e.preventDefault();
                    this.openDialog();
                });
        },
 
        // ============== 对话框控制 ==============
        openDialog() {
            // 动态加载OOUI库
            if (!window.OO) {
                mw.loader.using(['oojs-ui', 'oojs-ui-windows']).then(() => {
                    this._createDialog();
                }).catch(err => {
                    console.error('加载OOUI失败:', err);
                    alert('打印功能初始化失败,请刷新页面重试');
                });
            } else {
                this._createDialog();
            }
        },
 
        _createDialog() {
            // 1. 创建对话框类
            function PrintDialog(config) {
                PrintDialog.super.call(this, config);
            }
            OO.inheritClass(PrintDialog, OO.ui.ProcessDialog);
 
            // 2. 对话框配置
            PrintDialog.static.name = 'PrintEnhancerDialog';
            PrintDialog.static.title = '打印设置';
            PrintDialog.static.actions = [
                {
                    action: 'print',
label: '打印',
                    flags: ['primary', 'progressive']
                },
                {
                    action: 'cancel',
                    label: '取消',
                    flags: 'safe'
                }
            ];
 
            // 3. 构建对话框内容
            PrintDialog.prototype.initialize = function() {
                PrintDialog.super.prototype.initialize.apply(this, arguments);
               
                const panel = new OO.ui.PanelLayout({
                    padded: true,
                    expanded: false
                });
               
                const fieldset = new OO.ui.FieldsetLayout({
                    label: '打印选项'
                });
 
                // 添加所有复选框
                PrintEnhancer.questions.forEach(q => {
                    const checkbox = new OO.ui.CheckboxInputWidget({
                        selected: PrintEnhancer.config[q.name]
                    });
                   
                    const field = new OO.ui.FieldLayout(checkbox, {
                        label: q.label,
                        align: 'inline',
                        help: q.help ? new OO.ui.HtmlSnippet(q.help) : null
                    });
                   
                    fieldset.addItems([field]);
                    this[q.name] = checkbox; // 保存引用
                });
 
                panel.$element.append(fieldset.$element);
                this.$body.append(panel.$element);
            };
 
            // 4. 处理按钮动作
            PrintDialog.prototype.getActionProcess = function(action) {
                const dialog = this;
                return new OO.ui.Process(() => {
                    if (action === 'print') {
                        // 保存用户选择
                        PrintEnhancer.questions.forEach(q => {
                            PrintEnhancer.config[q.name] = dialog[q.name].isSelected();
                        });
                    }
                    dialog.close({ action });
                });
            };
 
            // 5. 创建窗口管理器
            if (!this.windowManager) {
                this.windowManager = new OO.ui.WindowManager();
                $(document.body).append(this.windowManager.$element);
            }
 
            // 6. 显示对话框
            const dialog = new PrintDialog({ size: 'medium' });
            this.windowManager.addWindows([dialog]);
            this.windowManager.openWindow(dialog).then(() => {
                if (dialog.action === 'print') {
                    this.applyPrintStyles();
                    setTimeout(() => window.print(), 300);
                }
            });
        },
 
        // ============== 打印样式应用 ==============
        applyPrintStyles() {
            const cssRules = [];
            const c = this.config;
 
            if (c.enhanced) cssRules.push(`
                .noprint, #siteNotice, .mw-editsection,
                .mw-indicators, .firstHeading .mw-headline {
                    display: none !important;
                }
            `);
            if (c.noimages) cssRules.push('img, video, .video-container { display: none !important; }');
            if (c.norefs) cssRules.push('sup.reference, .references { display: none !important; }');
            if (c.notoc) cssRules.push('#toc, .toc { display: none !important; }');
            if (c.nobackground) cssRules.push('body { background: white !important; }');
            if (c.blacktext) cssRules.push('body, body * { color: black !important; }');
 
            const styleId = 'mw-print-styles';
            let style = document.getElementById(styleId);
            if (!style) {
                style = document.createElement('style');
                style.id = styleId;
                document.head.appendChild(style);
            }
            style.textContent = `@media print { ${cssRules.join('')} }`;
         }
         }
    };
    // ============== 自动启动 ==============
    $(document).ready(function() {
        // 确保在DOM加载后运行
        setTimeout(() => PrintEnhancer.init(), 300);
    });
    // 兼容皮肤动态加载
    mw.hook('wikipage.content').add(function() {
        PrintEnhancer.init();
     });
     });
})();
})();

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