跳转到内容

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

勤求古训,博采众方
无编辑摘要
标签已被回退
无编辑摘要
 
(未显示同一用户的3个中间版本)
第1行: 第1行:
/*! PrintDialog v3.0 - 支持多语言&快捷键 */
/**
(function (mw, $) {
* 打印选项是一个由 Derk-Jan Hartman / User:TheDJ 编写的小工具
    'use strict';
* 更多信息参见 [[User:TheDJ/Print_options]]
   
*
    // 🌐 本地化文本库
* 采用 MIT 和/或 CC-by-SA 4.0 许可协议
    var i18n = {
*
        'title': mw.message('printdialog-title').plain() || '打印选项',
* 版权所有 (c) 2010-2017 Derk-Jan Hartman / User:TheDJ
        'print-btn': mw.message('printdialog-print-btn').plain() || '打印',
*
        'cancel-btn': mw.message('printdialog-cancel-btn').plain() || '取消',
* 特此免费授予任何获得本软件及相关文档文件(以下简称“软件”)副本的人,不受限制地处理本软件,
        'loading': mw.message('printdialog-loading').plain() || '准备打印中...',
* 包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件的副本,
        'print-error': mw.message('printdialog-error').plain() || '打印失败:$1',
* 并允许向其提供本软件的人这样做,但须符合以下条件:
        '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() || '不打印页面中的图片和缩略图',
*/
            'hideRefs': mw.message('printdialog-help-hide-refs').plain() || '不打印参考文献和引用部分'
        }
    };


    var PrintDialog = {
( function () {
        // ⚙️ 配置项
'use strict';
        config: {
var windowManager; // 窗口管理器实例
            debug: false,
var printDialog; // 打印对话框实例
            dependencies: ['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'],
 
            hotkeys: {
var printOptions = {
                print: 'ctrl+enter',
/**
                cancel: 'esc'
* 安装打印选项功能
            }
* - 找到页面上的打印链接
        },
* - 重写打印链接的点击事件
       
* - 预加载必要的 OOUI 组件
        // 🚀 初始化
*/
        init: function () {
install: function () {
            if (!this.shouldInit()) return;
var $printLink = $( '#t-print a' );
           
if ( $printLink.length === 0 ) {
            // 预加载依赖
return;
            if (!this.isDepsLoaded()) {
}
                mw.loader.load(this.config.dependencies);
$printLink
            }
.text( '打印页面' )
           
.off( 'click' )
            // 绑定打印按钮
.get( 0 ).addEventListener( 'click', function ( e ) {
            $('#t-print a').first()
// 加载 OOUI 核心组件、窗口组件和控件组件
                .text(mw.message('printdialog-link-text').plain() || '可打印版本')
mw.loader.using( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] ).done( printOptions.createWindow );
                .off('click.print')
e.stopPropagation();
                .on('click.print', this.onPrintClick.bind(this));
e.preventDefault();
           
}, true ); // 使用捕获阶段,以优先于其他点击处理程序
            this.registerHotkeys();
 
           
// 延迟预加载 OOUI 组件
            if (this.config.debug) {
mw.loader.load( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] );
                console.log('PrintDialog initialized');
},
            }
 
        },
/**
       
* 创建打印选项对话框
        // 🔥 快捷键支持
* - 定义对话框类
        registerHotkeys: function () {
* - 设置对话框标题和操作按钮
            $(document).off('keydown.printdialog')
* - 添加选项复选框
                .on('keydown.printdialog', function (e) {
* - 初始化窗口管理器并打开对话框
                    if (!PrintDialog.dialog || !PrintDialog.windowManager) return;
*/
                   
createWindow: function () {
                    // ESC - 取消
// 定义打印对话框类
                    if (e.key === 'Escape') {
function PrintDialog( config ) {
                        PrintDialog.dialog.executeAction('cancel');
PrintDialog.super.call( this, config );
                        e.preventDefault();
}
                    }
// 继承 OO.ui.ProcessDialog
                   
OO.inheritClass( PrintDialog, OO.ui.ProcessDialog );
                    // Ctrl+Enter - 打印
 
                    if (e.ctrlKey && e.key === 'Enter') {
// 对话框静态配置
                        PrintDialog.dialog.executeAction('print');
PrintDialog.static.name = 'printdialog';
                        e.preventDefault();
PrintDialog.static.title = '打印此页面';
                    }
PrintDialog.static.actions = [
                });
{ action: 'print', label: '打印', flags: 'primary' }, // 打印按钮(主要操作)
        },
{ label: '取消', flags: 'safe' } // 取消按钮(安全操作)
       
];
        // 🏗️ 创建对话框类
 
        createDialogClass: function () {
/**
            var self = this;
* 初始化对话框内容
           
* - 创建面板和字段集
            function Dialog(config) {
* - 根据 questions 数组创建复选框
                Dialog.super.call(this, config);
* - 将字段集添加到对话框中
            }
*/
            OO.inheritClass(Dialog, OO.ui.ProcessDialog);
PrintDialog.prototype.initialize = function () {
           
var checkbox, fieldset = [];
            // 静态配置
PrintDialog.super.prototype.initialize.apply( this, arguments );
            Dialog.static.name = 'printDialog';
// 创建面板布局
            Dialog.static.title = i18n.title;
this.panel = new OO.ui.PanelLayout( { padded: true, expanded: false } );
            Dialog.static.actions = [
// 创建字段集布局
                {
this.content = new OO.ui.FieldsetLayout();
                    action: 'print',
 
                    label: i18n['print-btn'],
// 遍历问题数组,创建复选框
                    flags: ['primary', 'progressive'],
for ( var i = 0; i < printOptions.questions.length; i++ ) {
                    icon: 'printer'
if ( printOptions.questions[ i ].type === 'checkbox' ) {
                },
checkbox = new OO.ui.CheckboxInputWidget( {
                {  
selected: printOptions.questions[ i ].checked // 设置默认选中状态
                    action: 'cancel',
} );
                    label: i18n['cancel-btn'],
// 保存复选框实例到问题对象中
                    flags: 'safe',
printOptions.questions[ i ].widget = checkbox;
                    icon: 'close'
// 创建字段布局并添加到字段集
                }
fieldset.push( new OO.ui.FieldLayout( checkbox, { label: printOptions.questions[ i ].label, align: 'inline' } ) );
            ];
}
           
}
            // 初始化内容
// 将字段集添加到内容布局
            Dialog.prototype.initialize = function () {
this.content.addItems( fieldset );
                Dialog.super.prototype.initialize.apply(this, arguments);
 
                this.buildForm();
// 将内容添加到面板,面板添加到对话框主体
               
this.panel.$element.append( this.content.$element );
                if (self.config.debug) {
this.$body.append( this.panel.$element );
                    console.log('PrintDialog: Dialog initialized');
};
                }
 
            };
/**
           
* 处理对话框操作
            // 构建表单
* @param {string} action - 操作名称
            Dialog.prototype.buildForm = function () {
* @returns {OO.ui.Process} 处理过程
                var panel = new OO.ui.PanelLayout({ padded: true });
*/
                var fieldset = new OO.ui.FieldsetLayout({
PrintDialog.prototype.getActionProcess = function ( action ) {
                    label: mw.message('printdialog-options-title').plain() || '打印选项'
var dialog = this;
                });
if ( action === 'print' ) {
               
return new OO.ui.Process( function () {
                // 初始化选项部件存储
// 获取复选框的值
                self.optionWidgets = {};
var question;
               
for ( var i = 0; i < printOptions.questions.length; i++ ) {
                self.options.forEach(function (opt) {
question = printOptions.questions[ i ];
                    if (opt.type === 'checkbox') {
if ( question.type === 'checkbox' && question.widget ) {
                        var widget = new OO.ui.CheckboxInputWidget({
printOptions[ question.returnvalue ] = question.widget.isSelected();
                            selected: !!opt.default
}
                        });
}
                       
// 关闭对话框后执行打印操作
                        // 保存部件引用
dialog.close( { action: action } ).done( function () {
                        self.optionWidgets[opt.id] = widget;
printOptions.changePrintCSS(); // 修改打印样式
                       
printOptions.otherEnhancements(); // 其他增强处理
                        var fieldLayout = new OO.ui.FieldLayout(widget, {
window.print(); // 触发浏览器打印
                            label: i18n.options[opt.id] || opt.id,
window.location = window.location; // 刷新页面恢复原始状态
                            align: 'inline',
} );
                            help: i18n.help[opt.id] ?
} );
                                new OO.ui.LabelWidget({
}
                                    label: i18n.help[opt.id]
// 调用父类方法处理其他操作
                                }) : null
return PrintDialog.super.prototype.getActionProcess.call( this, action );
                        });
};
                       
 
                        fieldset.addItems([fieldLayout]);
// 初始化窗口管理器(如果未创建)
                    }
if ( !windowManager ) {
                });
windowManager = new OO.ui.WindowManager();
               
$( 'body' ).append( windowManager.$element );
                panel.$element.append(fieldset.$element);
}
                this.$body.append(panel.$element);
// 创建打印对话框(如果未创建)
               
if ( !printDialog ) {
                if (self.config.debug) {
printDialog = new PrintDialog( {
                    console.log('PrintDialog: Form built with options', self.options);
size: 'medium' // 设置对话框大小为中等
                }
} );
            };
 
           
windowManager.addWindows( [ printDialog ] ); // 将对话框添加到窗口管理器
            // 处理动作
}
            Dialog.prototype.getActionProcess = function (action) {
windowManager.openWindow( printDialog ); // 打开对话框
                if (action === 'print') {
},
                    return new OO.ui.Process(function () {
 
                        return this.executePrintAction();
/**
                    }.bind(this));
* 修改打印样式表
                }
* - 禁用仅打印样式表
                return Dialog.super.prototype.getActionProcess.call(this, action);
* - 为屏幕样式表添加打印介质
            };
* - 删除仅打印的样式规则
           
* - 为屏幕样式规则添加打印介质
            // 执行打印
* - 根据选项添加自定义打印样式
            Dialog.prototype.executePrintAction = function () {
*/
                var process = new OO.ui.Process();
changePrintCSS: function () {
               
/* 此处我们:
                // 保存设置
- 禁用仅用于打印的样式表
                if (self.optionWidgets) {
- 使屏幕样式表也适用于打印介质
                    Object.keys(self.optionWidgets).forEach(function (key) {
- 删除仅用于打印的样式规则
                        self.settings[key] = self.optionWidgets[key].isSelected();
- 使屏幕样式规则也适用于打印介质
                    });
*/
                }
var printStyle = '';
               
if ( this.enhanced === false ) {
                if (self.config.debug) {
var i, j, k,
                    console.log('PrintDialog: Settings saved', self.settings);
rule,
                }
hasPrint, // 是否包含打印介质
               
hasScreen, // 是否包含屏幕介质
                // 关闭窗口
rules, // 样式规则集合
                return this.close({ action: 'print' })
stylesheet, // 当前样式表
                    .then(function () {
stylesheets = document.styleSheets; // 所有样式表
                        return self.applyPrintStyles();
 
                    })
for ( i = 0; i < stylesheets.length; i++ ) {
                    .then(function () {
stylesheet = stylesheets[ i ];
                        // 延迟确保样式已应用
if ( !stylesheet.media ) {
                        return new Promise(function (resolve) {
continue;
                            setTimeout(function () {
}
                                if (typeof window.print === 'function') {
// 处理样式表的介质类型
                                    window.print();
if ( stylesheet.media.mediaText && stylesheet.media.mediaText.indexOf( 'print' ) !== -1 ) {
                                    resolve();
// 如果是仅打印样式表,禁用它
                                } else {
if ( stylesheet.media.mediaText.indexOf( 'screen' ) === -1 ) {
                                    throw new Error(i18n['no-print-support']);
stylesheet.disabled = true;
                                }
}
                            }, 100);
} else if ( stylesheet.media.mediaText && stylesheet.media.mediaText.indexOf( 'screen' ) !== -1 ) {
                        });
// 如果是仅屏幕样式表,添加打印介质
                    })
if ( stylesheet.media.mediaText.indexOf( 'print' ) === -1 ) {
                    .catch(function (err) {
try {
                        mw.notify(
stylesheet.media.appendMedium( 'print' );
                            i18n['print-error'].replace('$1', err.message),
} catch ( e ) {
                            { type: 'error', tag: 'printdialog' }
stylesheet.media.mediaText += ',print';
                        );
}
                        throw err; // 重新抛出以保持错误链
}
                    });
}
            };
 
           
/* 现在处理单个样式规则 */
            return Dialog;
try {
        },
rules = stylesheet.cssRules || stylesheet.rules;
       
} catch ( e ) {
        // 🏗️ 创建对话框实例
/* 跨域问题 */
        createDialog: function () {
mw.log.warn( '由于跨域限制,无法修正样式表' );
            if (this.dialog && this.windowManager) {
continue;
                this.windowManager.openWindow(this.dialog);
}
                return Promise.resolve();
// 兼容不同浏览器的删除规则方法
            }
stylesheet.compatdelete = stylesheet.deleteRule || stylesheet.removeRule;
           
for ( j = 0; rules && j < rules.length; j++ ) {
            // 初始化窗口管理器
rule = rules[ j ];
            if (!this.windowManager) {
hasPrint = false;
                this.windowManager = new OO.ui.WindowManager();
hasScreen = false;
                $('body').append(this.windowManager.$element);
// 检查媒体规则
            }
if ( rule.type === CSSRule.MEDIA_RULE && rule.media ) {
           
for ( k = 0; k < rule.media.length; k++ ) {
            // 创建对话框类(如果不存在)
if ( rule.media[ k ] === 'print' ) {
            if (!this.DialogClass) {
hasPrint = true;
                this.DialogClass = this.createDialogClass();
} else if ( rule.media[ k ] === 'screen' ) {
            }
hasScreen = true;
           
}
            // 创建对话框实例
}
            this.dialog = new this.DialogClass({
} else {
                size: 'medium'  
continue;
            });
}
           
// 删除仅打印的规则
            this.windowManager.addWindows([this.dialog]);
if ( hasPrint && !hasScreen ) {
            return this.windowManager.openWindow(this.dialog);
stylesheet.compatdelete( j );
        },
j--; // 索引回退,因为删除了一个规则
       
} else if ( hasScreen && !hasPrint ) {
        // 🎨 应用打印样式
// 为仅屏幕规则添加打印介质
        applyPrintStyles: function () {
try {
            var style = [];
rule.media.appendMedium( 'print' );
           
} catch ( e ) {
            // 隐藏图片
rule.media.mediaText += ',print';
            if (this.settings.hideImages) {
}
                style.push(
}
                    'img, .thumb, .gallery, .image, .thumbinner, .thumbimage { ' +
}
                    'display:none !important; }'
}
                );
}
            }
/* 根据选项添加自定义打印样式 */
           
// 隐藏图片
            // 隐藏参考文献
if ( this.noimages ) {
            if (this.settings.hideRefs) {
printStyle += 'img, .thumb {display:none;}\n';
                style.push(
}
                    '.references, .ref-list, #References, .reflist, .citation { ' +
// 隐藏引用标记和引用列表
                    'display:none !important; }'
if ( this.norefs ) {
                );
printStyle += '.mw-heading:has(#References), ol.references, .reference {display:none;}\n';
            }
}
           
// 隐藏目录
            // 清理旧样式
if ( this.notoc ) {
            $('style.print-styles').remove();
printStyle += '#toc, .toc {display:none;}\n';
           
}
            // 添加新样式
// 移除背景
            if (style.length > 0) {
if ( this.nobackground ) {
                $('<style>')
printStyle += '* {background:none !important;}\n';
                    .addClass('print-styles')
}
                    .attr('media', 'print')
// 强制文本为黑色
                    .attr('type', 'text/css')
if ( this.blacktext ) {
                    .text(style.join('\n'))
printStyle += '* {color:black !important;}\n';
                    .appendTo('head');
}
                   
 
                if (this.config.debug) {
// 添加自定义样式到页面
                    console.log('PrintDialog: Applied print styles', style);
if ( printStyle ) {
                }
$( 'head' ).append( '<style type="text/css" media="print">' + printStyle + '</style>' );
            }
}
           
},
            return Promise.resolve();
 
        },
/**
       
* 其他增强处理
        // 🖨️ 主入口处理
* - 将 "retrieved from" 链接转换为可读文本
        onPrintClick: function (e) {
*/
            e.preventDefault();
otherEnhancements: function () {
           
var link = $( 'div.printfooter a' );
            if (this.config.debug) {
link.text( decodeURI( link.text() ) );
                console.log('PrintDialog: Print button clicked');
},
            }
 
           
/**
            // 创建加载通知
* 打印选项问题配置
            var progressBar = new OO.ui.ProgressBarWidget({ progress: false });
* 每个对象包含:
            var notification = mw.notify(progressBar.$element, {
* - label: 复选框标签
                title: i18n.loading,
* - type: 输入类型(checkbox)
                autoHide: false,
* - checked: 默认选中状态
                tag: 'printdialog-loading'
* - returnvalue: 存储结果的属性名
            });
*/
           
questions: [
            // 确保依赖已加载并创建对话框
{
            mw.loader.using(this.config.dependencies)
label: '隐藏界面元素',
                .then(this.createDialog.bind(this))
type: 'checkbox',
                .catch(function (err) {
checked: true,
                    console.error('PrintDialog: Error creating dialog', err);
returnvalue: 'enhanced'
                    mw.notify(
},
                        i18n['print-error'].replace('$1', err.message),  
{
                        { type: 'error', tag: 'printdialog' }
label: '隐藏图片',
                    );
type: 'checkbox',
                })
checked: false,
                .always(function () {
returnvalue: 'noimages'
                    notification.close();
},
                });
{
        },
label: '隐藏引用',
       
type: 'checkbox',
        // ✅ 工具方法
checked: false,
        shouldInit: function () {
returnvalue: 'norefs'
            // 只在内容命名空间显示
},
            return mw.config.get('wgNamespaceNumber') >= 0 &&
{
                  $('#t-print').length > 0;
label: '隐藏目录',
        },
type: 'checkbox',
       
checked: false,
        isDepsLoaded: function () {
returnvalue: 'notoc'
            return this.config.dependencies.every(function (dep) {
},
                var state = mw.loader.getState(dep);
{
                return state === 'ready' || state === 'loaded';
label: '移除背景(您的浏览器可能会覆盖此设置)',
            });
type: 'checkbox',
        },
checked: false,
       
returnvalue: 'nobackground'
        // ⚙️ 可配置选项
},
        options: [
{
            {
label: '强制所有文本为黑色',
                id: 'hideImages',
type: 'checkbox',
                type: 'checkbox',
checked: true,
                default: false,
returnvalue: 'blacktext'
                description: 'Hide images and thumbnails in print'
}
            },
]
            {
};
                id: 'hideRefs',
 
                type: 'checkbox',
// 仅在主命名空间(ns >= 0)加载
                default: false,
if ( mw.config.get( 'wgNamespaceNumber' ) >= 0 ) {
                description: 'Hide references and citations in print'
$( function () {
            }
// 这可能在 MW 安装点击处理程序之前执行
        ],
// 因此,将自己重新添加到 document.ready 队列的末尾
       
// 使用异步超时来实现
        // 🗃️ 状态存储
setTimeout( function () {
        settings: {},
$( printOptions.install );
        optionWidgets: null,
} );
       
} );
        // ♻️ 清理方法
}
        destroy: function () {
}() );
            $(document).off('keydown.printdialog');
           
            if (this.windowManager) {
                this.windowManager.destroy();
                this.windowManager = null;
            }
           
            $('style.print-styles').remove();
           
            this.dialog = null;
            this.DialogClass = null;
            this.optionWidgets = null;
           
            if (this.config.debug) {
                console.log('PrintDialog: Destroyed');
            }
        }
    };
   
    // 📅 延迟初始化
    mw.hook('wikipage.content').add(function () {
        // 等待页面完全加载后再初始化
        if (document.readyState === 'loading') {
            $(document).ready(function () {
                setTimeout(PrintDialog.init.bind(PrintDialog), 300);
            });
        } else {
            setTimeout(PrintDialog.init.bind(PrintDialog), 300);
        }
    });
   
    // 🖇️ 暴露到全局
    window.PrintDialog = PrintDialog;
   
    if (PrintDialog.config.debug) {
        console.log('PrintDialog: Module loaded');
    }
})(mediaWiki, jQuery);

2025年11月23日 (日) 19:40的最新版本

/**
 * 打印选项是一个由 Derk-Jan Hartman / User:TheDJ 编写的小工具
 * 更多信息参见 [[User:TheDJ/Print_options]]
 *
 * 采用 MIT 和/或 CC-by-SA 4.0 许可协议
 *
 * 版权所有 (c) 2010-2017 Derk-Jan Hartman / User:TheDJ
 *
 * 特此免费授予任何获得本软件及相关文档文件(以下简称“软件”)副本的人,不受限制地处理本软件,
 * 包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件的副本,
 * 并允许向其提供本软件的人这样做,但须符合以下条件:
 *
 * 上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
 *
 * 本软件按“原样”提供,不提供任何形式的明示或暗示担保,
 * 包括但不限于对适销性、特定用途适用性和非侵权性的担保。
 * 在任何情况下,作者或版权持有人均不对因使用本软件而产生的任何索赔、损害或其他责任承担责任,
 * 无论是在合同诉讼、侵权诉讼还是其他诉讼中。
 */

( function () {
	'use strict';
	var windowManager; // 窗口管理器实例
	var printDialog; // 打印对话框实例

	var printOptions = {
		/**
		 * 安装打印选项功能
		 * - 找到页面上的打印链接
		 * - 重写打印链接的点击事件
		 * - 预加载必要的 OOUI 组件
		 */
		install: function () {
			var $printLink = $( '#t-print a' );
			if ( $printLink.length === 0 ) {
				return;
			}
			$printLink
				.text( '打印页面' )
				.off( 'click' )
				.get( 0 ).addEventListener( 'click', function ( e ) {
					// 加载 OOUI 核心组件、窗口组件和控件组件
					mw.loader.using( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] ).done( printOptions.createWindow );
					e.stopPropagation();
					e.preventDefault();
				}, true ); // 使用捕获阶段,以优先于其他点击处理程序

			// 延迟预加载 OOUI 组件
			mw.loader.load( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] );
		},

		/**
		 * 创建打印选项对话框
		 * - 定义对话框类
		 * - 设置对话框标题和操作按钮
		 * - 添加选项复选框
		 * - 初始化窗口管理器并打开对话框
		 */
		createWindow: function () {
			// 定义打印对话框类
			function PrintDialog( config ) {
				PrintDialog.super.call( this, config );
			}
			// 继承 OO.ui.ProcessDialog
			OO.inheritClass( PrintDialog, OO.ui.ProcessDialog );

			// 对话框静态配置
			PrintDialog.static.name = 'printdialog';
			PrintDialog.static.title = '打印此页面';
			PrintDialog.static.actions = [
				{ action: 'print', label: '打印', flags: 'primary' }, // 打印按钮(主要操作)
				{ label: '取消', flags: 'safe' } // 取消按钮(安全操作)
			];

			/**
			 * 初始化对话框内容
			 * - 创建面板和字段集
			 * - 根据 questions 数组创建复选框
			 * - 将字段集添加到对话框中
			 */
			PrintDialog.prototype.initialize = function () {
				var checkbox, fieldset = [];
				PrintDialog.super.prototype.initialize.apply( this, arguments );
				// 创建面板布局
				this.panel = new OO.ui.PanelLayout( { padded: true, expanded: false } );
				// 创建字段集布局
				this.content = new OO.ui.FieldsetLayout();

				// 遍历问题数组,创建复选框
				for ( var i = 0; i < printOptions.questions.length; i++ ) {
					if ( printOptions.questions[ i ].type === 'checkbox' ) {
						checkbox = new OO.ui.CheckboxInputWidget( {
							selected: printOptions.questions[ i ].checked // 设置默认选中状态
						} );
						// 保存复选框实例到问题对象中
						printOptions.questions[ i ].widget = checkbox;
						// 创建字段布局并添加到字段集
						fieldset.push( new OO.ui.FieldLayout( checkbox, { label: printOptions.questions[ i ].label, align: 'inline' } ) );
					}
				}
				// 将字段集添加到内容布局
				this.content.addItems( fieldset );

				// 将内容添加到面板,面板添加到对话框主体
				this.panel.$element.append( this.content.$element );
				this.$body.append( this.panel.$element );
			};

			/**
			 * 处理对话框操作
			 * @param {string} action - 操作名称
			 * @returns {OO.ui.Process} 处理过程
			 */
			PrintDialog.prototype.getActionProcess = function ( action ) {
				var dialog = this;
				if ( action === 'print' ) {
					return new OO.ui.Process( function () {
						// 获取复选框的值
						var question;
						for ( var i = 0; i < printOptions.questions.length; i++ ) {
							question = printOptions.questions[ i ];
							if ( question.type === 'checkbox' && question.widget ) {
								printOptions[ question.returnvalue ] = question.widget.isSelected();
							}
						}
						// 关闭对话框后执行打印操作
						dialog.close( { action: action } ).done( function () {
							printOptions.changePrintCSS(); // 修改打印样式
							printOptions.otherEnhancements(); // 其他增强处理
							window.print(); // 触发浏览器打印
							window.location = window.location; // 刷新页面恢复原始状态
						} );
					} );
				}
				// 调用父类方法处理其他操作
				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 () {
			/* 此处我们:
				 - 禁用仅用于打印的样式表
				 - 使屏幕样式表也适用于打印介质
				 - 删除仅用于打印的样式规则
				 - 使屏幕样式规则也适用于打印介质
			*/
			var printStyle = '';
			if ( this.enhanced === false ) {
				var i, j, k,
					rule,
					hasPrint, // 是否包含打印介质
					hasScreen, // 是否包含屏幕介质
					rules, // 样式规则集合
					stylesheet, // 当前样式表
					stylesheets = document.styleSheets; // 所有样式表

				for ( i = 0; i < stylesheets.length; i++ ) {
					stylesheet = stylesheets[ i ];
					if ( !stylesheet.media ) {
						continue;
					}
					// 处理样式表的介质类型
					if ( stylesheet.media.mediaText && stylesheet.media.mediaText.indexOf( 'print' ) !== -1 ) {
						// 如果是仅打印样式表,禁用它
						if ( stylesheet.media.mediaText.indexOf( 'screen' ) === -1 ) {
							stylesheet.disabled = true;
						}
					} else if ( stylesheet.media.mediaText && stylesheet.media.mediaText.indexOf( 'screen' ) !== -1 ) {
						// 如果是仅屏幕样式表,添加打印介质
						if ( stylesheet.media.mediaText.indexOf( 'print' ) === -1 ) {
							try {
								stylesheet.media.appendMedium( 'print' );
							} catch ( e ) {
								stylesheet.media.mediaText += ',print';
							}
						}
					}

					/* 现在处理单个样式规则 */
					try {
						rules = stylesheet.cssRules || stylesheet.rules;
					} catch ( e ) {
						/* 跨域问题 */
						mw.log.warn( '由于跨域限制,无法修正样式表' );
						continue;
					}
					// 兼容不同浏览器的删除规则方法
					stylesheet.compatdelete = stylesheet.deleteRule || stylesheet.removeRule;
					for ( j = 0; rules && j < rules.length; j++ ) {
						rule = rules[ j ];
						hasPrint = false;
						hasScreen = false;
						// 检查媒体规则
						if ( rule.type === CSSRule.MEDIA_RULE && rule.media ) {
							for ( k = 0; k < rule.media.length; k++ ) {
								if ( rule.media[ k ] === 'print' ) {
									hasPrint = true;
								} else if ( rule.media[ k ] === 'screen' ) {
									hasScreen = true;
								}
							}
						} else {
							continue;
						}
						// 删除仅打印的规则
						if ( hasPrint && !hasScreen ) {
							stylesheet.compatdelete( j );
							j--; // 索引回退,因为删除了一个规则
						} else if ( hasScreen && !hasPrint ) {
							// 为仅屏幕规则添加打印介质
							try {
								rule.media.appendMedium( 'print' );
							} catch ( e ) {
								rule.media.mediaText += ',print';
							}
						}
					}
				}
			}
			/* 根据选项添加自定义打印样式 */
			// 隐藏图片
			if ( this.noimages ) {
				printStyle += 'img, .thumb {display:none;}\n';
			}
			// 隐藏引用标记和引用列表
			if ( this.norefs ) {
				printStyle += '.mw-heading:has(#References), ol.references, .reference {display:none;}\n';
			}
			// 隐藏目录
			if ( this.notoc ) {
				printStyle += '#toc, .toc {display:none;}\n';
			}
			// 移除背景
			if ( this.nobackground ) {
				printStyle += '* {background:none !important;}\n';
			}
			// 强制文本为黑色
			if ( this.blacktext ) {
				printStyle += '* {color:black !important;}\n';
			}

			// 添加自定义样式到页面
			if ( printStyle ) {
				$( 'head' ).append( '<style type="text/css" media="print">' + printStyle + '</style>' );
			}
		},

		/**
		 * 其他增强处理
		 * - 将 "retrieved from" 链接转换为可读文本
		 */
		otherEnhancements: function () {
			var link = $( 'div.printfooter a' );
			link.text( decodeURI( link.text() ) );
		},

		/**
		 * 打印选项问题配置
		 * 每个对象包含:
		 * - label: 复选框标签
		 * - type: 输入类型(checkbox)
		 * - checked: 默认选中状态
		 * - returnvalue: 存储结果的属性名
		 */
		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'
			}
		]
	};

	// 仅在主命名空间(ns >= 0)加载
	if ( mw.config.get( 'wgNamespaceNumber' ) >= 0 ) {
		$( function () {
			// 这可能在 MW 安装点击处理程序之前执行
			// 因此,将自己重新添加到 document.ready 队列的末尾
			// 使用异步超时来实现
			setTimeout( function () {
				$( printOptions.install );
			} );
		} );
	}
}() );