MediaWiki:Gadget-PrintOptions.js:修订间差异
外观
删除的内容 添加的内容
创建页面,内容为“/** * 打印选项是一个由 Derk-Jan Hartman / User:TheDJ 编写的小工具 * 更多信息参见 User:TheDJ/Print_options * * 采用 MIT 和/或 CC-by-SA 4.0 许可协议 * * 版权所有 (c) 2010-2017 Derk-Jan Hartman / User:TheDJ * * 特此免费授予任何获得本软件及相关文档文件(以下简称“软件”)副本的人,不受限制地处理本软件, * 包括但不限于使用、复制、修改、合并、发布、分发…” |
无编辑摘要 |
||
| 第1行: | 第1行: | ||
/** |
/** |
||
* SPDX-License-Identifier: CC-BY-SA-4.0 |
|||
* 打印选项是一个由 Derk-Jan Hartman / User:TheDJ 编写的小工具 |
|||
* _addText: '{{Gadget Header|license=CC-BY-SA-4.0}}' |
|||
* 更多信息参见 [[User:TheDJ/Print_options]] |
|||
* |
* |
||
* @base {@link https://en.wikipedia.org/wiki/MediaWiki:Gadget-PrintOptions.js} |
|||
* 采用 MIT 和/或 CC-by-SA 4.0 许可协议 |
|||
* @source {@link https://git.qiuwen.net.cn/InterfaceAdmin/QiuwenGadgets/src/branch/master/src/PrintOptions} |
|||
* @author Derk-Jan Hartman, English Wikipedia Contributors and Qiuwen Baike Contributors. |
|||
*/ |
|||
/** |
|||
* Print options is a Gadget writen by Derk-Jan Hartman |
|||
* |
* |
||
* Licensed MIT and/or CC-BY-SA-4.0 |
|||
* 版权所有 (c) 2010-2017 Derk-Jan Hartman / User:TheDJ |
|||
* |
* |
||
* Copyright (c) 2010-2017 Derk-Jan Hartman |
|||
* 特此免费授予任何获得本软件及相关文档文件(以下简称“软件”)副本的人,不受限制地处理本软件, |
|||
* 包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件的副本, |
|||
* 并允许向其提供本软件的人这样做,但须符合以下条件: |
|||
* |
* |
||
* Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
* 上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。 |
|||
* of this software and associated documentation files (the "Software"), to deal |
|||
* in the Software without restriction, including without limitation the rights |
|||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
* copies of the Software, and to permit persons to whom the Software is |
|||
* furnished to do so, subject to the following conditions: |
|||
* |
* |
||
* The above copyright notice and this permission notice shall be included in all |
|||
* 本软件按“原样”提供,不提供任何形式的明示或暗示担保, |
|||
* copies or substantial portions of the Software. |
|||
* 包括但不限于对适销性、特定用途适用性和非侵权性的担保。 |
|||
* |
|||
* 在任何情况下,作者或版权持有人均不对因使用本软件而产生的任何索赔、损害或其他责任承担责任, |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* 无论是在合同诉讼、侵权诉讼还是其他诉讼中。 |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|||
* SOFTWARE. |
|||
* @license CC-BY-SA-4.0 {@link https://www.qiuwenbaike.cn/wiki/H:CC-BY-SA-4.0} |
|||
*/ |
*/ |
||
/** |
|||
* +------------------------------------------------------------+ |
|||
* | === WARNING: GLOBAL GADGET FILE === | |
|||
* +------------------------------------------------------------+ |
|||
* | All changes should be made in the repository, | |
|||
* | otherwise they will be lost. | |
|||
* +------------------------------------------------------------+ |
|||
* | Changes to this page may affect many users. | |
|||
* | Please discuss changes by opening an issue before editing. | |
|||
* +------------------------------------------------------------+ |
|||
*/ |
|||
/* <nowiki> */ |
|||
( |
(() => { |
||
'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'; |
|||
} |
|||
"use strict"; |
|||
// 添加自定义样式到页面 |
|||
if ( printStyle ) { |
|||
$( 'head' ).append( '<style type="text/css" media="print">' + printStyle + '</style>' ); |
|||
} |
|||
}, |
|||
// dist/PrintOptions/PrintOptions.js |
|||
/** |
|||
//! src/PrintOptions/PrintOptions.ts |
|||
* 其他增强处理 |
|||
function _createForOfIteratorHelper(r, e) { |
|||
* - 将 "retrieved from" 链接转换为可读文本 |
|||
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; |
|||
*/ |
|||
if (!t) { |
|||
otherEnhancements: function () { |
|||
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { |
|||
var link = $( 'div.printfooter a' ); |
|||
t && (r = t); |
|||
link.text( decodeURI( link.text() ) ); |
|||
var n = 0, F = function() { |
|||
}, |
|||
}; |
|||
return { s: F, n: function() { |
|||
return n >= r.length ? { done: true } : { done: false, value: r[n++] }; |
|||
}, e: function(r2) { |
|||
throw r2; |
|||
}, f: F }; |
|||
} |
|||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); |
|||
} |
|||
var o, a = true, u = false; |
|||
return { s: function() { |
|||
t = t.call(r); |
|||
}, n: function() { |
|||
var r2 = t.next(); |
|||
return a = r2.done, r2; |
|||
}, e: function(r2) { |
|||
u = true, o = r2; |
|||
}, f: function() { |
|||
try { |
|||
a || null == t.return || t.return(); |
|||
} finally { |
|||
if (u) throw o; |
|||
} |
|||
} }; |
|||
} |
|||
function _unsupportedIterableToArray(r, a) { |
|||
if (r) { |
|||
if ("string" == typeof r) return _arrayLikeToArray(r, a); |
|||
var t = {}.toString.call(r).slice(8, -1); |
|||
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; |
|||
} |
|||
} |
|||
function _arrayLikeToArray(r, a) { |
|||
(null == a || a > r.length) && (a = r.length); |
|||
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; |
|||
return n; |
|||
} |
|||
var import_ext_gadget2 = require("ext.gadget.Util"); |
|||
//! src/PrintOptions/modules/i18n.ts |
|||
var import_ext_gadget = require("ext.gadget.i18n"); |
|||
var getI18nMessages = () => { |
|||
return { |
|||
Print: (0, import_ext_gadget.localize)({ |
|||
en: "Print", |
|||
ja: "印刷", |
|||
"zh-hans": "打印", |
|||
"zh-hant": "列印" |
|||
}), |
|||
"Print this page": (0, import_ext_gadget.localize)({ |
|||
en: "Print this page", |
|||
ja: "このページを印刷に", |
|||
"zh-hans": "打印此页面", |
|||
"zh-hant": "列印此頁面" |
|||
}), |
|||
Cancel: (0, import_ext_gadget.localize)({ |
|||
en: "Cancel", |
|||
ja: "キャンセル", |
|||
zh: "取消" |
|||
}) |
|||
}; |
|||
}; |
|||
var i18nMessages = getI18nMessages(); |
|||
var getMessage = (key) => { |
|||
return i18nMessages[key] || key; |
|||
}; |
|||
//! src/PrintOptions/PrintOptions.ts |
|||
var getPrintOptions = ($body) => { |
|||
let windowManager; |
|||
let printDialog; |
|||
const printOptions = { |
|||
enhanced: true, |
|||
noimages: false, |
|||
norefs: false, |
|||
notoc: false, |
|||
nobackground: false, |
|||
blacktext: true, |
|||
install: () => { |
|||
var _$printLink$off$get; |
|||
const $printLink = $body.find("#t-print a"); |
|||
if (!$printLink.length) { |
|||
return; |
|||
} |
|||
(_$printLink$off$get = $printLink.off("click").get(0)) === null || _$printLink$off$get === void 0 || _$printLink$off$get.addEventListener( |
|||
"click", |
|||
(event) => { |
|||
event.stopPropagation(); |
|||
event.preventDefault(); |
|||
printOptions.createWindow(); |
|||
}, |
|||
// Use capturing phase, to beat the other click listener |
|||
true |
|||
); |
|||
}, |
|||
createWindow: () => { |
|||
class PrintDialog extends OO.ui.ProcessDialog { |
|||
panel; |
|||
content; |
|||
$body; |
|||
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" |
|||
}]; |
|||
initialize() { |
|||
let checkboxInputWidget; |
|||
const fieldLayouts = []; |
|||
super.initialize(); |
|||
this.panel = new OO.ui.PanelLayout({ |
|||
expanded: false, |
|||
padded: true |
|||
}); |
|||
this.content = new OO.ui.FieldsetLayout(); |
|||
var _iterator = _createForOfIteratorHelper(this.questions), _step; |
|||
try { |
|||
for (_iterator.s(); !(_step = _iterator.n()).done; ) { |
|||
const question = _step.value; |
|||
const { |
|||
checked, |
|||
label, |
|||
type |
|||
} = question; |
|||
if (type !== "checkbox") { |
|||
continue; |
|||
} |
|||
checkboxInputWidget = new OO.ui.CheckboxInputWidget({ |
|||
selected: checked |
|||
}); |
|||
question.widget = checkboxInputWidget; |
|||
fieldLayouts[fieldLayouts.length] = new OO.ui.FieldLayout(checkboxInputWidget, { |
|||
label, |
|||
align: "inline" |
|||
}); |
|||
} |
|||
} catch (err) { |
|||
_iterator.e(err); |
|||
} finally { |
|||
_iterator.f(); |
|||
} |
|||
this.content.addItems(fieldLayouts); |
|||
this.panel.$element.append(this.content.$element); |
|||
this.panel.$element.appendTo(this.$body); |
|||
return this; |
|||
} |
|||
getActionProcess(action) { |
|||
const self = this; |
|||
if (action === "print") { |
|||
return new OO.ui.Process(() => { |
|||
var _iterator2 = _createForOfIteratorHelper(this.questions), _step2; |
|||
try { |
|||
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) { |
|||
const question = _step2.value; |
|||
if (question.type === "checkbox" && question.widget) { |
|||
Object.defineProperty(printOptions, question.returnvalue, { |
|||
value: question.widget.isSelected(), |
|||
writable: true |
|||
}); |
|||
} |
|||
} |
|||
} catch (err) { |
|||
_iterator2.e(err); |
|||
} finally { |
|||
_iterator2.f(); |
|||
} |
|||
void self.close({ |
|||
action |
|||
}).closed.then(() => { |
|||
printOptions.changePrintCSS(); |
|||
printOptions.otherEnhancements(); |
|||
window.print(); |
|||
}); |
|||
}); |
|||
} |
|||
return super.getActionProcess(action); |
|||
} |
|||
} |
|||
PrintDialog.static = { |
|||
...OO.ui.ProcessDialog.static |
|||
}; |
|||
PrintDialog.static.name = "PrintDialog"; |
|||
PrintDialog.static.title = getMessage("Print this page"); |
|||
PrintDialog.static.actions = [{ |
|||
action: "print", |
|||
label: getMessage("Print"), |
|||
flags: ["primary", "progressive"] |
|||
}, { |
|||
label: getMessage("Cancel"), |
|||
flags: ["safe", "close"] |
|||
}]; |
|||
if (!windowManager) { |
|||
windowManager = new OO.ui.WindowManager(); |
|||
$body.append(windowManager.$element); |
|||
} |
|||
if (!printDialog) { |
|||
printDialog = new PrintDialog({ |
|||
size: "medium" |
|||
}); |
|||
windowManager.addWindows([printDialog]); |
|||
} |
|||
void windowManager.openWindow(printDialog); |
|||
}, |
|||
changePrintCSS() { |
|||
if (this.enhanced === false) { |
|||
var _iterator3 = _createForOfIteratorHelper(document.styleSheets), _step3; |
|||
try { |
|||
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) { |
|||
const stylesheet = _step3.value; |
|||
const { |
|||
media |
|||
} = stylesheet; |
|||
if (!media) { |
|||
continue; |
|||
} |
|||
if (media.mediaText && media.mediaText.includes("print")) { |
|||
if (!media.mediaText.includes("screen")) { |
|||
stylesheet.disabled = true; |
|||
} |
|||
} else if (media.mediaText && media.mediaText.includes("screen") && !media.mediaText.includes("print")) { |
|||
try { |
|||
media.appendMedium("print"); |
|||
} catch { |
|||
media.mediaText += ",print"; |
|||
} |
|||
} |
|||
let rules; |
|||
try { |
|||
rules = stylesheet.cssRules || stylesheet.rules; |
|||
} catch { |
|||
mw.log.warn("Not possible to correct stylesheet due to cross origin restrictions."); |
|||
continue; |
|||
} |
|||
if (!rules) { |
|||
continue; |
|||
} |
|||
for (let j = 0; j < rules.length; j++) { |
|||
const rule = rules[j]; |
|||
let hasPrint = false; |
|||
let hasScreen = false; |
|||
if (!rule) { |
|||
continue; |
|||
} |
|||
if (rule.type === CSSRule.MEDIA_RULE && rule.media) { |
|||
var _iterator4 = _createForOfIteratorHelper(rule.media), _step4; |
|||
try { |
|||
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) { |
|||
const ruleMedia = _step4.value; |
|||
if (ruleMedia === "print") { |
|||
hasPrint = true; |
|||
} else if (ruleMedia === "screen") { |
|||
hasScreen = true; |
|||
} |
|||
} |
|||
} catch (err) { |
|||
_iterator4.e(err); |
|||
} finally { |
|||
_iterator4.f(); |
|||
} |
|||
} else { |
|||
continue; |
|||
} |
|||
if (hasPrint && !hasScreen) { |
|||
stylesheet.deleteRule(j); |
|||
j--; |
|||
} else if (rule && hasScreen && !hasPrint) { |
|||
try { |
|||
rule.media.appendMedium("print"); |
|||
} catch { |
|||
rule.media.mediaText += ",print"; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} catch (err) { |
|||
_iterator3.e(err); |
|||
} finally { |
|||
_iterator3.f(); |
|||
} |
|||
} |
|||
let printStyle = ""; |
|||
if (this.noimages) { |
|||
printStyle += "img,.thumb{display:none}"; |
|||
} |
|||
if (this.norefs) { |
|||
printStyle += '.mw-headline[id="References"],ol.references,.reference{display:none}'; |
|||
} |
|||
if (this.notoc) { |
|||
printStyle += "#toc,.toc{display:none}"; |
|||
} |
|||
if (this.nobackground) { |
|||
printStyle += "*{background:none !important}"; |
|||
} |
|||
if (this.blacktext) { |
|||
printStyle += "*{color:#000 !important}"; |
|||
} |
|||
if (printStyle) { |
|||
var _document$querySelect; |
|||
(_document$querySelect = document.querySelector("#printStyle")) === null || _document$querySelect === void 0 || _document$querySelect.remove(); |
|||
const styleTag = document.createElement("style"); |
|||
styleTag.id = "printStyle"; |
|||
styleTag.media = "print"; |
|||
styleTag.append(document.createTextNode(printStyle)); |
|||
document.head.append(styleTag); |
|||
} |
|||
}, |
|||
/* Rewrite the "retrieved from" url to be readable */ |
|||
otherEnhancements: () => { |
|||
const link = $body.find("div.printfooter a"); |
|||
link.text(decodeURI(link.text())); |
|||
} |
|||
}; |
|||
return printOptions; |
|||
}; |
|||
void (0, import_ext_gadget2.getBody)().then(function printOptionsLoad($body) { |
|||
if (mw.config.get("wgNamespaceNumber") < 0) { |
|||
return; |
|||
} |
|||
const printOptions = getPrintOptions($body); |
|||
setTimeout(printOptions.install, 0); |
|||
}); |
|||
})(); |
|||
/** |
|||
* 打印选项问题配置 |
|||
* 每个对象包含: |
|||
* - 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' |
|||
} |
|||
] |
|||
}; |
|||
/* </nowiki> */ |
|||
// 仅在主命名空间(ns >= 0)加载 |
|||
if ( mw.config.get( 'wgNamespaceNumber' ) >= 0 ) { |
|||
$( function () { |
|||
// 这可能在 MW 安装点击处理程序之前执行 |
|||
// 因此,将自己重新添加到 document.ready 队列的末尾 |
|||
// 使用异步超时来实现 |
|||
setTimeout( function () { |
|||
$( printOptions.install ); |
|||
} ); |
|||
} ); |
|||
} |
|||
}() ); |
|||
2026年6月14日 (日) 18:55的最新版本
/**
* SPDX-License-Identifier: CC-BY-SA-4.0
* _addText: '{{Gadget Header|license=CC-BY-SA-4.0}}'
*
* @base {@link https://en.wikipedia.org/wiki/MediaWiki:Gadget-PrintOptions.js}
* @source {@link https://git.qiuwen.net.cn/InterfaceAdmin/QiuwenGadgets/src/branch/master/src/PrintOptions}
* @author Derk-Jan Hartman, English Wikipedia Contributors and Qiuwen Baike Contributors.
*/
/**
* Print options is a Gadget writen by Derk-Jan Hartman
*
* Licensed MIT and/or CC-BY-SA-4.0
*
* Copyright (c) 2010-2017 Derk-Jan Hartman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* @license CC-BY-SA-4.0 {@link https://www.qiuwenbaike.cn/wiki/H:CC-BY-SA-4.0}
*/
/**
* +------------------------------------------------------------+
* | === WARNING: GLOBAL GADGET FILE === |
* +------------------------------------------------------------+
* | All changes should be made in the repository, |
* | otherwise they will be lost. |
* +------------------------------------------------------------+
* | Changes to this page may affect many users. |
* | Please discuss changes by opening an issue before editing. |
* +------------------------------------------------------------+
*/
/* <nowiki> */
(() => {
"use strict";
// dist/PrintOptions/PrintOptions.js
//! src/PrintOptions/PrintOptions.ts
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var n = 0, F = function() {
};
return { s: F, n: function() {
return n >= r.length ? { done: true } : { done: false, value: r[n++] };
}, e: function(r2) {
throw r2;
}, f: F };
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o, a = true, u = false;
return { s: function() {
t = t.call(r);
}, n: function() {
var r2 = t.next();
return a = r2.done, r2;
}, e: function(r2) {
u = true, o = r2;
}, f: function() {
try {
a || null == t.return || t.return();
} finally {
if (u) throw o;
}
} };
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
var import_ext_gadget2 = require("ext.gadget.Util");
//! src/PrintOptions/modules/i18n.ts
var import_ext_gadget = require("ext.gadget.i18n");
var getI18nMessages = () => {
return {
Print: (0, import_ext_gadget.localize)({
en: "Print",
ja: "印刷",
"zh-hans": "打印",
"zh-hant": "列印"
}),
"Print this page": (0, import_ext_gadget.localize)({
en: "Print this page",
ja: "このページを印刷に",
"zh-hans": "打印此页面",
"zh-hant": "列印此頁面"
}),
Cancel: (0, import_ext_gadget.localize)({
en: "Cancel",
ja: "キャンセル",
zh: "取消"
})
};
};
var i18nMessages = getI18nMessages();
var getMessage = (key) => {
return i18nMessages[key] || key;
};
//! src/PrintOptions/PrintOptions.ts
var getPrintOptions = ($body) => {
let windowManager;
let printDialog;
const printOptions = {
enhanced: true,
noimages: false,
norefs: false,
notoc: false,
nobackground: false,
blacktext: true,
install: () => {
var _$printLink$off$get;
const $printLink = $body.find("#t-print a");
if (!$printLink.length) {
return;
}
(_$printLink$off$get = $printLink.off("click").get(0)) === null || _$printLink$off$get === void 0 || _$printLink$off$get.addEventListener(
"click",
(event) => {
event.stopPropagation();
event.preventDefault();
printOptions.createWindow();
},
// Use capturing phase, to beat the other click listener
true
);
},
createWindow: () => {
class PrintDialog extends OO.ui.ProcessDialog {
panel;
content;
$body;
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"
}];
initialize() {
let checkboxInputWidget;
const fieldLayouts = [];
super.initialize();
this.panel = new OO.ui.PanelLayout({
expanded: false,
padded: true
});
this.content = new OO.ui.FieldsetLayout();
var _iterator = _createForOfIteratorHelper(this.questions), _step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done; ) {
const question = _step.value;
const {
checked,
label,
type
} = question;
if (type !== "checkbox") {
continue;
}
checkboxInputWidget = new OO.ui.CheckboxInputWidget({
selected: checked
});
question.widget = checkboxInputWidget;
fieldLayouts[fieldLayouts.length] = new OO.ui.FieldLayout(checkboxInputWidget, {
label,
align: "inline"
});
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
this.content.addItems(fieldLayouts);
this.panel.$element.append(this.content.$element);
this.panel.$element.appendTo(this.$body);
return this;
}
getActionProcess(action) {
const self = this;
if (action === "print") {
return new OO.ui.Process(() => {
var _iterator2 = _createForOfIteratorHelper(this.questions), _step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done; ) {
const question = _step2.value;
if (question.type === "checkbox" && question.widget) {
Object.defineProperty(printOptions, question.returnvalue, {
value: question.widget.isSelected(),
writable: true
});
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
void self.close({
action
}).closed.then(() => {
printOptions.changePrintCSS();
printOptions.otherEnhancements();
window.print();
});
});
}
return super.getActionProcess(action);
}
}
PrintDialog.static = {
...OO.ui.ProcessDialog.static
};
PrintDialog.static.name = "PrintDialog";
PrintDialog.static.title = getMessage("Print this page");
PrintDialog.static.actions = [{
action: "print",
label: getMessage("Print"),
flags: ["primary", "progressive"]
}, {
label: getMessage("Cancel"),
flags: ["safe", "close"]
}];
if (!windowManager) {
windowManager = new OO.ui.WindowManager();
$body.append(windowManager.$element);
}
if (!printDialog) {
printDialog = new PrintDialog({
size: "medium"
});
windowManager.addWindows([printDialog]);
}
void windowManager.openWindow(printDialog);
},
changePrintCSS() {
if (this.enhanced === false) {
var _iterator3 = _createForOfIteratorHelper(document.styleSheets), _step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done; ) {
const stylesheet = _step3.value;
const {
media
} = stylesheet;
if (!media) {
continue;
}
if (media.mediaText && media.mediaText.includes("print")) {
if (!media.mediaText.includes("screen")) {
stylesheet.disabled = true;
}
} else if (media.mediaText && media.mediaText.includes("screen") && !media.mediaText.includes("print")) {
try {
media.appendMedium("print");
} catch {
media.mediaText += ",print";
}
}
let rules;
try {
rules = stylesheet.cssRules || stylesheet.rules;
} catch {
mw.log.warn("Not possible to correct stylesheet due to cross origin restrictions.");
continue;
}
if (!rules) {
continue;
}
for (let j = 0; j < rules.length; j++) {
const rule = rules[j];
let hasPrint = false;
let hasScreen = false;
if (!rule) {
continue;
}
if (rule.type === CSSRule.MEDIA_RULE && rule.media) {
var _iterator4 = _createForOfIteratorHelper(rule.media), _step4;
try {
for (_iterator4.s(); !(_step4 = _iterator4.n()).done; ) {
const ruleMedia = _step4.value;
if (ruleMedia === "print") {
hasPrint = true;
} else if (ruleMedia === "screen") {
hasScreen = true;
}
}
} catch (err) {
_iterator4.e(err);
} finally {
_iterator4.f();
}
} else {
continue;
}
if (hasPrint && !hasScreen) {
stylesheet.deleteRule(j);
j--;
} else if (rule && hasScreen && !hasPrint) {
try {
rule.media.appendMedium("print");
} catch {
rule.media.mediaText += ",print";
}
}
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
}
let printStyle = "";
if (this.noimages) {
printStyle += "img,.thumb{display:none}";
}
if (this.norefs) {
printStyle += '.mw-headline[id="References"],ol.references,.reference{display:none}';
}
if (this.notoc) {
printStyle += "#toc,.toc{display:none}";
}
if (this.nobackground) {
printStyle += "*{background:none !important}";
}
if (this.blacktext) {
printStyle += "*{color:#000 !important}";
}
if (printStyle) {
var _document$querySelect;
(_document$querySelect = document.querySelector("#printStyle")) === null || _document$querySelect === void 0 || _document$querySelect.remove();
const styleTag = document.createElement("style");
styleTag.id = "printStyle";
styleTag.media = "print";
styleTag.append(document.createTextNode(printStyle));
document.head.append(styleTag);
}
},
/* Rewrite the "retrieved from" url to be readable */
otherEnhancements: () => {
const link = $body.find("div.printfooter a");
link.text(decodeURI(link.text()));
}
};
return printOptions;
};
void (0, import_ext_gadget2.getBody)().then(function printOptionsLoad($body) {
if (mw.config.get("wgNamespaceNumber") < 0) {
return;
}
const printOptions = getPrintOptions($body);
setTimeout(printOptions.install, 0);
});
})();
/* </nowiki> */