MediaWiki:Gadget-SettingsDialog.js

Bhsd讨论 | 贡献2021年2月4日 (四) 11:53的版本

注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件
//<nowiki>
// 由ResourceLoader直接调用,不可使用ES6语法
/**
 * @Function: 定义小工具设置对话框
 * @Methods: constructor:构建mw.SettingsDialog对象
 *           initialize:初始化html
 *           getActionProcess:点击按钮时执行动作
 *           getIndex:获取小工具编号
 *           getName:获取小工具名称
 *           getObject:获取小工具对象
 *           addTab:添加小工具
 *           buildForm:生成表单
 *           removeTab:移除小工具
 *           saveOptions:将设置保存到localStorage
 *           clearOptions:还原设置
 * @Dependencies: mediawiki.util, mediawiki.storage, oojs-ui-windows, oojs-ui-widgets, ext.gadget.site-lib, user
 * @Author: [[User:Bhsd]]
 */
"use strict";
/* global OO, wgULS */
//避免使用API加载消息,直接手动添加
mw.messages.set( wgULS({
    'gadget-sd-title': '小工具设置', 'gadget-sd-notify': '您的设置已保存!新设置将于刷新页面后生效。',
    'gadget-sd-tooltip': '为当前浏览器设置小工具偏好', 'gadget-sd-help': '您可以在这里修改小工具偏好,修改仅对当前浏览器有效。',
    'gadget-sd-back': '还原', 'gadget-sd-helppage': '如果想要修改设置对所有浏览器生效,请查阅', 'gadget-sd-save': '保存',
    'gadget-sd-helptext': '帮助页面'
}, {
    'gadget-sd-title': '小工具偏好設定', 'gadget-sd-notify': '您的偏好設定已儲存!新設定將於重新載入頁面後生效。',
    'gadget-sd-tooltip': '為當前瀏覽器設定小工具偏好', 'gadget-sd-help': '您可以在這裡修改小工具偏好,修改僅對當前瀏覽器有效。',
    'gadget-sd-back': '復原', 'gadget-sd-helppage': '如果想要修改設定對所有瀏覽器生效,請查閱', 'gadget-sd-save': '儲存',
    'gadget-sd-helptext': '說明頁面'
}) );
// constructor只添加一个CSS类,剩下的交给addTab方法逐一添加小工具
function SettingsDialog() {
    SettingsDialog.super.call(this, {classes: ['settingsDialog']});
    this.gadgets = [];
}
OO.inheritClass(SettingsDialog, OO.ui.ProcessDialog);
// initialize只创建一个OO.ui.IndexLayout对象,剩下的交给addTab方法填入内容
SettingsDialog.prototype.initialize = function() {
    SettingsDialog.super.prototype.initialize.apply(this, arguments);
    this.content = new OO.ui.IndexLayout();
    this.$body.append( this.content.$element );
};
SettingsDialog.prototype.getActionProcess = function(action) {
    const dialog = this,
        gadgets = this.gadgets.filter(function(ele) { return ele.ready; }); // 忽略未加载的小工具
    if (action == 'save') { gadgets.forEach(function(ele) { dialog.saveOptions(ele); }); }
    else { gadgets.forEach(function(ele) { dialog.clearOptions(ele); }); }
    this.close();
    return new OO.ui.Process();
};
// 需要同时添加数据和HTML
SettingsDialog.prototype.addTab = function(params) {
    const dialog = this,
        panel = new OO.ui.TabPanelLayout( params.name, {label: mw.msg( params.label )} );
    this.content.addTabPanels( [panel] );
    this.gadgets.push( params );
    // 必要时才开始加载表单
    panel.on('active', function() { dialog.buildForm( params ); });
};
SettingsDialog.prototype.buildForm = function(params) {
    if (params.ready) { return; }
    const dialog = this,
        Help = params.help,
        $element = this.content.getTabPanel( params.name ).$element.append(
        $('<div>', {html: [mw.msg('gadget-sd-help')].concat( Help ? [mw.msg('gadget-sd-helppage'),
        $('<a>', {href: mw.util.getUrl('Help:小工具/' + Help), target: '_blank', text: mw.msg('gadget-sd-helptext')}),
    '。'] : [] )}) );
    (params.items || []).forEach(function(ele) {
        ele.widget = new OO.ui[ele.type + 'InputWidget']( ele.config );
        $element.append( new OO.ui.FieldLayout(ele.widget, {label: mw.msg( ele.label ), help: ele.help,
            helpInline: true}).$element );
    });
    (params.fields || []).forEach(function(ele) {
        ele.field = new OO.ui.FieldsetLayout({label: mw.msg( ele.label ), help: ele.help, helpInline: true});
        ele.field.addItems( (ele.items || []).map(function(e) {
            e.widget = new OO.ui[e.type + 'InputWidget']( e.config );
            return new OO.ui.FieldLayout(e.widget, {label: mw.msg( ele.label ), help: e.help, helpInline: true})
                .$element;
        }) );
        $element.append( ele.field.$element );
    });
    $('<div>', {class: 'panel-btns', html: [
        new OO.ui.ButtonWidget({label: mw.msg('gadget-sd-back'), flags: 'destructive'}).on('click', function() {
        dialog.clearOptions( params.name );
    }), new OO.ui.ButtonWidget({label: mw.msg('gadget-sd-save'), flags: 'progressive'}).on('click', function() {
        dialog.saveOptions( params.name );
    })].map(function(ele) { return ele.$element; })}).appendTo( $element );
    params.ready = true;
    mw.hook( 'settings.dialog' ).fire( params ); // 生成一个Hook
};
SettingsDialog.prototype.getIndex = function(arg) {
    if (typeof arg == 'string') { return this.gadgets.findIndex(function(ele) { return ele.name == arg; }); }
    else if (typeof arg == 'number') { return arg; }
    else { return this.gadgets.indexOf( arg ); }
};
SettingsDialog.prototype.getName = function(arg) {
    if (typeof arg == 'string') { return arg; }
    else if (typeof arg == 'number') { return this.gadgets[ arg ].name; }
    else { return arg.name; }
};
SettingsDialog.prototype.getObject = function(arg) {
    if (typeof arg == 'string') { return this.gadgets.find(function(ele) { return ele.name == arg; }); }
    else if (typeof arg == 'number') { return this.gadgets[ arg ]; }
    else { return arg; }
};
SettingsDialog.prototype.removeTab = function(arg) {
    const name = this.getName(arg),
        index = this.getIndex(arg);
    if (index == -1) {
        console.warn( '无法删除不存在的小工具设置!' );
        return;
    }
    // 需要同时移除数据和对应的HTML元素
    this.gadgets.splice(index, 1);
    this.content.removeTabPanels( this.content.getTabPanel( name ) );
};
SettingsDialog.prototype.clearOptions = function(arg) {
    const gadget = this.getObject(arg);
    if (!gadget) {
        console.warn( '无法还原不存在的小工具设置!' );
        return;
    }
    (gadget.clearOptions || function() {
        const name = gadget.name,
            settings = mw.gadgets[ name ];
        gadget.items.forEach(function(ele) { ele.widget.setValue( (ele.parent || settings)[ ele.key ] ); });
    })();
};
SettingsDialog.prototype.saveOptions = function(arg) {
    const gadget = this.getObject(arg);
    if (!gadget) {
        console.warn( '无法保存不存在的小工具设置!' );
        return;
    }
    (gadget.saveOptions || function() {
        const name = gadget.name,
            settings = mw.gadgets[ name ];
        gadget.items.filter(function(ele) { return !ele.widget.isDisabled(); })
            .forEach(function(ele) { (ele.parent || settings)[ ele.key ] = ele.widget.getValue(); });
        mw.storage.setObject('gadget-' + name, settings);
        mw.notify(mw.msg( 'gadget-sd-notify' ), {type: 'success', tag: 'gadget-settings'});
    })();
};
SettingsDialog.static = {name: 'settingsDialog', tagName: 'div', title: mw.msg('gadget-sd-title'),
    actions: [{action: 'save', label: mw.msg('gadget-sd-save'), flags: ['primary', 'progressive']},
        {action: 'cancel', label: mw.msg('ooui-dialog-message-reject'), flags: 'safe'}]
};
mw.settingsDialog = new SettingsDialog();
if (!mw.windowManager) {
    mw.windowManager = mw.windowmanager || new OO.ui.WindowManager();
    mw.windowManager.$element.appendTo( 'body' );
}
mw.windowManager.addWindows( [mw.settingsDialog] ); // 此时已经初始化
// 添加按钮,注意手机版的执行时机
if (mw.config.get('skin') == 'minerva') {
    mw.hook( 'mobile.menu' ).add(function($menu) {
        console.log('Hook: mobile.menu, 开始添加小工具设置按钮');
        mw.addMobileLinks([{icon: 'user-cog', msg: 'gadget-sd-title', attr: {id: 'ca-settingsDialog'}}])[0]
            .appendTo( $menu.find('ul:not(.hlist)').last() );
    });
} else {
    mw.util.addPortletLink('p-cactions', '#', mw.msg('gadget-sd-title'), 'ca-settingsDialog',
        mw.msg('gadget-sd-tooltip'));
}
$(document.body).on('click', '#ca-settingsDialog', function(e) {
    e.preventDefault();
    const dialog = mw.settingsDialog,
        params = dialog.getObject( dialog.content.getCurrentTabPanelName() );
    dialog.open().opening.then(function() {
        if (params.ready) { return; }
        dialog.buildForm( params );
    });
});
//</nowiki>
// [[category:作为模块的小工具]] [[category:桌面版小工具]] [[category:手机版小工具]] [[category:系统工具]]
// {{DEFAULTSORT:SettingsDialog.js}}