跳转到内容

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

勤求古训,博采众方
无编辑摘要
无编辑摘要
 
(未显示同一用户的10个中间版本)
第1行: 第1行:
// ==UserScript==
/**
// @name        MediaWiki打印增强
* 打印选项是一个由 Derk-Jan Hartman / User:TheDJ 编写的小工具
// @description 为MediaWiki添加高级打印选项(优化布局、图片控制等)
* 更多信息参见 [[User:TheDJ/Print_options]]
// @namespace    https://github.com/yourname/
*
// @version      1.1
* 采用 MIT 和/或 CC-by-SA 4.0 许可协议
// @license      MIT
  *
// @match        *://*/*
* 版权所有 (c) 2010-2017 Derk-Jan Hartman / User:TheDJ
// @grant        none
*
// ==/UserScript==
* 特此免费授予任何获得本软件及相关文档文件(以下简称“软件”)副本的人,不受限制地处理本软件,
* 包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件的副本,
* 并允许向其提供本软件的人这样做,但须符合以下条件:
*
* 上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
*
* 本软件按“原样”提供,不提供任何形式的明示或暗示担保,
* 包括但不限于对适销性、特定用途适用性和非侵权性的担保。
* 在任何情况下,作者或版权持有人均不对因使用本软件而产生的任何索赔、损害或其他责任承担责任,
* 无论是在合同诉讼、侵权诉讼还是其他诉讼中。
*/


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


    // ============== 核心配置 ==============
var printOptions = {
    const PrintEnhancer = {
/**
        config: {
* 安装打印选项功能
            enhanced: true,
* - 找到页面上的打印链接
            noimages: false,
* - 重写打印链接的点击事件
            norefs: false,
* - 预加载必要的 OOUI 组件
            notoc: false,
*/
            nobackground: false,
install: function () {
            blacktext: true
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 ); // 使用捕获阶段,以优先于其他点击处理程序


        questions: [
// 延迟预加载 OOUI 组件
            {
mw.loader.load( [ 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows' ] );
                type: 'checkbox',
},
                returnvalue: 'enhanced',
label: mw.message('print-option-enhance').plain(),
                help: 'print-option-enhance-help'
            },
            {
                type: 'checkbox',
                returnvalue: 'noimages',
                label: mw.message('print-option-noimages').plain()
            },
            {
                type: 'checkbox',
                returnvalue: 'norefs',
                label: mw.message('print-option-norefs').plain()
            },
            {
                type: 'checkbox',
                returnvalue: 'notoc',
                label: mw.message('print-option-notoc').plain()
            },
            {
                type: 'checkbox',
                returnvalue: 'nobackground',
                label: mw.message('print-option-nobg').plain(),
                help: 'print-option-nobg-help'
            },
            {
                type: 'checkbox',
                returnvalue: 'blacktext',
                label: mw.message('print-option-blacktext').plain()
            }
        ],


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


            mw.loader.using(['oojs-ui', 'oojs-ui-windows']).then(() => {
// 对话框静态配置
                const $printLink = $('#t-print a');
PrintDialog.static.name = 'printdialog';
                $printLink
PrintDialog.static.title = '打印此页面';
                    .text(mw.message('print-version').plain())
PrintDialog.static.actions = [
                    .off('click')
{ action: 'print', label: '打印', flags: 'primary' }, // 打印按钮(主要操作)
                    .on('click', (e) => {
{ label: '取消', flags: 'safe' } // 取消按钮(安全操作)
                        e.preventDefault();
];
                        e.stopPropagation();
                        this.createDialog();
                    });
            });
        },


        // ============== 对话框 ==============
/**
        createDialog() {
* 初始化对话框内容
            function PrintDialog(config) {
* - 创建面板和字段集
                PrintDialog.super.call(this, config);
* - 根据 questions 数组创建复选框
            }
* - 将字段集添加到对话框中
            OO.inheritClass(PrintDialog, OO.ui.ProcessDialog);
*/
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();


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


            PrintDialog.prototype.initialize = function() {
// 将内容添加到面板,面板添加到对话框主体
                PrintDialog.super.prototype.initialize.apply(this, arguments);
this.panel.$element.append( this.content.$element );
                const panel = new OO.ui.PanelLayout({ padded: true });
this.$body.append( this.panel.$element );
                const fieldset = new OO.ui.FieldsetLayout({
};
                    label: mw.message('print-options').plain()
                });


                PrintEnhancer.questions.forEach(q => {
/**
                    const checkbox = new OO.ui.CheckboxInputWidget({
* 处理对话框操作
                        selected: PrintEnhancer.config[q.returnvalue]
* @param {string} action - 操作名称
                    });
* @returns {OO.ui.Process} 处理过程
                    fieldset.addItems([
*/
                        new OO.ui.FieldLayout(checkbox, {
PrintDialog.prototype.getActionProcess = function ( action ) {
                            label: q.label,
var dialog = this;
                            align: 'inline',
if ( action === 'print' ) {
                            help: q.help ? mw.message(q.help).plain() : null
return new OO.ui.Process( function () {
                        })
// 获取复选框的值
                    ]);
var question;
                    q.widget = checkbox;
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 );
};


                panel.$element.append(fieldset.$element);
// 初始化窗口管理器(如果未创建)
                this.$body.append(panel.$element);
if ( !windowManager ) {
            };
windowManager = new OO.ui.WindowManager();
$( 'body' ).append( windowManager.$element );
}
// 创建打印对话框(如果未创建)
if ( !printDialog ) {
printDialog = new PrintDialog( {
size: 'medium' // 设置对话框大小为中等
} );


            PrintDialog.prototype.getActionProcess = function(action) {
windowManager.addWindows( [ printDialog ] ); // 将对话框添加到窗口管理器
                const dialog = this;
}
                return new OO.ui.Process(() => {
windowManager.openWindow( printDialog ); // 打开对话框
                    if (action === 'print') {
},
                        PrintEnhancer.questions.forEach(q => {
                            PrintEnhancer.config[q.returnvalue] = q.widget.isSelected();
                        });
                        return dialog.close({ action }).then(() => {
                            PrintEnhancer.applyPrintStyles();
                            setTimeout(() => {
                                window.print();
                                setTimeout(() => location.reload(), 1000);
                            }, 500);
                        });
                    }
                    return dialog.close({ action }); // 处理cancel
                });
            };


            if (!this.windowManager) {
/**
                this.windowManager = new OO.ui.WindowManager();
* 修改打印样式表
                $('body').append(this.windowManager.$element);
* - 禁用仅打印样式表
            }
* - 为屏幕样式表添加打印介质
            this.windowManager.addWindows([new PrintDialog({ size: 'medium' })]);
* - 删除仅打印的样式规则
            this.windowManager.openWindow(this.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++ ) {
        applyPrintStyles() {
stylesheet = stylesheets[ i ];
            let css = '@media print { ';
if ( !stylesheet.media ) {
            const c = this.config;
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';
}
}
}


            if (c.enhanced) css += `
/* 现在处理单个样式规则 */
                .noprint, #siteNotice, .mw-indicators,
try {
                .mw-editsection, .firstHeading .mw-headline {  
rules = stylesheet.cssRules || stylesheet.rules;
                    display: none !important;  
} catch ( e ) {
                }
/* 跨域问题 */
            `;
mw.log.warn( '由于跨域限制,无法修正样式表' );
            if (c.noimages) css += 'img, .video-container { display: none !important; }';
continue;
            if (c.norefs) css += 'sup.reference, .references { display: none !important; }';
}
            if (c.notoc) css += '#toc, .toc { display: none !important; }';
// 兼容不同浏览器的删除规则方法
            if (c.nobackground) css += 'body { background: white !important; }';
stylesheet.compatdelete = stylesheet.deleteRule || stylesheet.removeRule;
            if (c.blacktext) css += 'body { color: black !important; }';
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';
}


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


    // ============== 消息初始化 ==============
/**
    mw.messages.set({
* 其他增强处理
        'print-version': '可打印版本',
* - 将 "retrieved from" 链接转换为可读文本
        'print-dialog-title': '打印设置',
*/
        'print-options': '自定义打印选项',
otherEnhancements: function () {
        'print-action-print': '打印',
var link = $( 'div.printfooter a' );
        'print-action-cancel': '取消',
link.text( decodeURI( link.text() ) );
        'print-option-enhance': '优化打印布局',
},
        'print-option-enhance-help': '隐藏编辑按钮等非必要元素',
        'print-option-noimages': '隐藏所有图片',
        'print-option-norefs': '隐藏参考文献',
        'print-option-notoc': '隐藏目录',
        'print-option-nobg': '移除背景色',
        'print-option-nobg-help': '节省墨水,但可能影响部分内容可见性',
        'print-option-blacktext': '强制纯黑色文字'
    });


    // ============== 启动 ==============
/**
    mw.hook('wikipage.content').add(() => PrintEnhancer.init());
* 打印选项问题配置
})();
* 每个对象包含:
* - 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 );
} );
} );
}
}() );

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