본문으로 이동

사용자:Hsl0/연구소/1.js: 두 판 사이의 차이

리버티게임, 모두가 만들어가는 자유로운 게임
imported>Hsl0
편집 요약 없음
Hsl0 (토론 | 기여)
잔글편집 요약 없음
 
(같은 사용자의 중간 판 12개는 보이지 않습니다)
1번째 줄: 1번째 줄:
var api = new mw.Api();
/* #REDIRECT */mw.loader.load( "https://libertyga.me/index.php?title=%EC%82%AC%EC%9A%A9%EC%9E%90:Hsl0/%EC%97%B0%EA%B5%AC%EC%86%8C/2.js&action=raw" );
var gadgetsList = Object.keys(mw.loader.moduleRegistry).reduce(function(arr, key) {
    if(key.startsWith('ext.gadget.')) arr.push(key.slice(11));
    return arr;
}, []);
var needed = [];
var ignored = mw.user.options.get('userjs-gadgethelper-ignored');
ignored = ignored? ignored.split('|') : [];
var allowed = getAllowedGadgets();
var ignoredChanged = 0;
 
function getAllowedGadgets() {
    var allowed = [];
    var options = mw.user.options.values;
 
    for(var key in options) {
        if(key.startsWith('gadget-') && +options[key]) allowed.push(key.slice(7));
    }
 
    return allowed;
}
 
function getSelected(form) {
    return $(form).find('input[type=checkbox]:checked').map(function() {
        return this.name;
    }).get().filter(function(name) {
        return name;
    });
}
 
function getUnselected(form) {
    return $(form).find('input[type=checkbox]:not(:checked)').map(function() {
        return this.name;
    }).get().filter(function(name) {
        return name;
    });
}
 
 
$('.gadgethelper').each(function() {
    needed = needed.concat(this.dataset.using.split(' '));
});
 
needed = needed.filter(function(gadget) {
    return gadgetsList.includes(gadget) && !allowed.includes(gadget);
});
 
function SelectDialog(config) {
    SelectDialog.super.call(this, config);
}
OO.inheritClass(SelectDialog, OO.ui.ProcessDialog);
 
SelectDialog.static.name = 'GadgetSelectDialog';
SelectDialog.static.title = '소도구 선택';
SelectDialog.static.actions = [
    {
        modes: 'default',
        action: 'execute',
        label: '실행',
        flags: ['primary', 'progressive']
    },
    {
        modes: 'ignored',
        action: 'clear',
        label: '해제',
        flags: ['primary', 'progressive']
    },
    {
        modes: 'default',
        action: 'close',
        label: '닫기',
        flags: 'safe'
    },
    {
        modes: 'ignored',
        action: 'cancel',
        label: '취소',
        flags: 'safe'
    },
    {
        modes: 'default',
        action: 'go-ignored',
        label: '무시된 소도구 보기'
    },
 
];
if(!mw.user.isAnon()) SelectDialog.static.actions.push({
    modes: 'default',
    action: 'go-allowed',
    label: '항상 실행하는 소도구 관리'
});
 
SelectDialog.prototype.initialize = function() {
    SelectDialog.super.prototype.initialize.apply(this, arguments);
 
    this.defaultMessage = new OO.ui.PanelLayout({
        expanded: false,
        classes: ['gadgethelper-message'],
        text: '이 문서가 정상적으로 작동하려면 다음 소도구가 필요합니다. 일시적으로 실행할 소도구를 선택해 주세요.'
    });
    this.defaultForm = new OO.ui.FormLayout();
    this.defaultPanel = new OO.ui.PanelLayout({
        padded: true,
        expanded: true,
        content: [this.defaultMessage, this.defaultForm]
    });
   
    this.loading = new OO.ui.PanelLayout({
        padded: true,
        expanded: false,
        text: '소도구 정보를 불러오고 있습니다... 잠시만 기다려 주세요.'
    });
    this.executing = new OO.ui.PanelLayout({
        padded: true,
        expanded: false,
        hidden: true,
        text: '소도구를 실행하는 중입니다...'
    });
    this.executing.toggle(false);
    this.saving = new OO.ui.PanelLayout({
        padded: true,
        expanded: false,
        hidden: true,
        text: '설정을 저장하고 있습니다...'
    });
    this.saving.toggle(false);
 
    this.ignoredMessage = new OO.ui.PanelLayout({
        expanded: false,
        classes: ['gadgethelper-message'],
        text: '무시한 소도구의 목록입니다. 해제할 소도구를 선택해 주세요.'
    });
    this.ignoredForm = new OO.ui.FormLayout();   
    this.ignoredPanel = new OO.ui.PanelLayout({
        padded: true,
        expanded: true,
        content: [this.ignoredMessage, this.ignoredForm]
    });
 
    this.stackLayout = new OO.ui.StackLayout({
        expanded: false,
        items: [this.loading, this.defaultPanel, this.ignoredPanel]
    })
 
    this.$body.append(this.executing.$element)
              .append(this.saving.$element)
              .append(this.stackLayout.$element);
};
 
SelectDialog.prototype.createDefaultForm = function() {
    var form = this.defaultForm;
    var auto = false;
 
    this.defaultForm.clearItems();
 
    var all = new OO.ui.CheckboxInputWidget({
        selected: true
    });
    all.on('change', function(state) {
        if(!auto) {
            auto = true;
            form.items.forEach(function(item) {
                if(item instanceof OO.ui.HorizontalLayout) {
                    var checkbox = item.items[0].fieldWidget;
                    if(!checkbox.isDisabled()) checkbox.setSelected(state);
                }
            });
            auto = false;
        }
    });
 
    this.defaultForm.addItems([
        new OO.ui.FieldLayout(all, {
            label: '모두 선택',
            align: 'inline',
            classes: ['gadgethelper-selectall']
        })
    ]);
    this.defaultForm.addItems(needed.filter(function(gadget) {
        return !ignored.includes(gadget);
    }).map(function(gadget) {
        var ignore = new OO.ui.ButtonWidget({
            classes: ['gadgethelper-ignorebutton'],
            label: '무시',
            flags: 'destructive',
            framed: false
        });
        ignore.on('click', function() {
            ignore.clearFlags();
            if(input.isDisabled()) {
                var index = ignored.indexOf(gadget);
                if(index > -1) ignored.splice(index, 1);
                input.setDisabled(false);
 
                if(index > 0) ignoredChanged--;
 
                ignore.setLabel('무시');
                ignore.setFlags('destructive');
            } else {
                ignoredChanged++;
                ignored.push(gadget);
                input.setSelected(false);
                input.setDisabled(true);
 
                ignore.setLabel('무시 해제');
                ignore.setFlags('progressive');
            }
        });
 
        var input = new OO.ui.CheckboxInputWidget({
            name: gadget,
            selected: true,
            classes: ['gadgethelper-checkbox']
        });
        input.on('change', function() {
            if(!auto) {
                auto = true;
                all.setSelected(false);
                auto = false;
            }
        });
 
        return new OO.ui.HorizontalLayout({
            classes: ['gadgethelper-item'],
            items: [
                new OO.ui.FieldLayout(input, {
                    label: mw.msg('gadget-' + gadget),
                    align: 'inline'
                }),
                ignore
            ]
        });
    }));
};
 
SelectDialog.prototype.getSetupProcess = function(data) {
    var dialog = this;
 
    return SelectDialog.super.prototype.getSetupProcess.call(this, data)
        .next(this.waitFor('load', api.loadMessagesIfMissing(needed.map(function(key) {
            return 'gadget-' + key;
        }))))
        .next(function() {
            dialog.createDefaultForm();
 
            dialog.stackLayout.setItem(dialog.defaultPanel);
            dialog.actions.setMode('default');
        });
};
 
SelectDialog.prototype.saveIgnored = function() {
    if(ignoredChanged) {
        ignoredChanged = 0;
        return api.saveOption('userjs-gadgethelper-ignored', ignored.join('|')).then(function() {
            mw.user.options.set('userjs-gadgethelper-ignored', ignored.join('|'));
 
            dialog.ignoredForm.clearItems();
            dialog.createDefaultForm();
        });
    } else return Promise.resolve();
}
 
SelectDialog.prototype.waitFor = function(action, process) {
    var dialog = this;
    this.actions.setMode('wait');
 
    switch(action) {
        case 'load':
            this.stackLayout.setItem(this.loading);
            return process;
            break;
 
        case 'save':
            this.saving.toggle(true);
            return process.then(function() {
                dialog.saving.toggle(false);
            })
            break;
 
        case 'execute':
            this.executing.toggle(true);
            return process.then(function() {
                dialog.executing.toggle(false);
            })
            break;
 
        default:
            throw new TypeError('잘못된 동작입니다');
    }
};
 
SelectDialog.prototype.getActionProcess = function(action) {
    var process = SelectDialog.super.prototype.getActionProcess.call(this, action);
    var dialog = this;
 
    switch(action) {
        case 'execute':
            return process
                .next(function() {
                    dialog.defaultMessage.toggle(false);
                    dialog.defaultForm.items.forEach(function(item) {
                        if(item instanceof OO.ui.HorizontalLayout) {
                            item.items[0].fieldWidget.setDisabled(true);
                            item.items[1].setDisabled(true);
                        } else item.fieldWidget.setDisabled(true);
                    });
                })
                .next(Promise.all([
                    this.waitFor('save', this.saveIgnored()),
                    this.waitFor('execute', mw.loader.using(getSelected(this.defaultForm.$element).map(function(gadget) {
                        return 'ext.gadget.' + gadget;
                    })))
                ]))
                .next(function() {
                    dialog.close();
                });
            break;
 
        case 'clear':
            return process.next(function() {
                dialog.ignoredMessage.toggle(false);
                dialog.ignoredForm.items.forEach(function(item) {
                    if(item instanceof OO.ui.HorizontalLayout) {
                        item.items[0].fieldWidget.setDisabled(true);
                        item.items[1].setDisabled(true);
                    } else item.fieldWidget.setDisabled(true);
                });
               
                ignored = getUnselected(dialog.ignoredForm.$element);
                ignoredChanged = true;
 
                return dialog.waitFor('save', dialog.saveIgnored());
            }).next(function() {
                dialog.ignoredMessage.toggle(true);
                dialog.stackLayout.setItem(dialog.defaultPanel);
                dialog.actions.setMode('default');
            });
            break;
       
        case 'close':
            return process.next(function() {
                dialog.defaultMessage.toggle(false);
                dialog.defaultForm.items.forEach(function(item) {
                    if(item instanceof OO.ui.HorizontalLayout) {
                        item.items[0].fieldWidget.setDisabled(true);
                        item.items[1].setDisabled(true);
                    } else item.fieldWidget.setDisabled(true);
                });
            }).next(this.waitFor('save', this.saveIgnored())).next(function() {
                dialog.close();
            });
            break;
 
        case 'cancel':
            return process.next(function() {
                dialog.stackLayout.setItem(dialog.defaultPanel);
                dialog.actions.setMode('default');
            });
            break;
       
        case 'go-ignored':
            return process.next(Promise.all([
                this.waitFor('save', this.saveIgnored()),
                this.waitFor('load', api.loadMessagesIfMissing(ignored.map(function(key) {
                    return 'gadget-' + key;
                })))
            ])).next(function() {
                if(!dialog.ignoredForm.items.length) {
                    var all = new OO.ui.CheckboxInputWidget();
                    all.on('change', function(checked) {
                        dialog.ignoredForm.$element.find('input[type=checkbox]').prop('checked', checked);
                    });
                    dialog.ignoredForm.addItems([
                        new OO.ui.FieldLayout(all, {
                            label: '모두 선택',
                            align: 'inline'
                        })
                    ]);
 
                    dialog.ignoredForm.addItems(ignored.map(function(gadget) {
                        return new OO.ui.FieldLayout(new OO.ui.CheckboxInputWidget({
                            name: gadget
                        }), {
                            label: mw.msg('gadget-' + gadget),
                            align: 'inline'
                        });
                    }));
 
                }
 
                dialog.stackLayout.setItem(dialog.ignoredPanel);
                dialog.actions.setMode('ignored');     
            });
            break;
        case 'go-allowed':
            return process.next(function() {
                open('/wiki/%ED%8A%B9%EC%88%98:%ED%99%98%EA%B2%BD%EC%84%A4%EC%A0%95#mw-prefsection-gadgets');
            });
            break;
    }
 
    return process.next(function() {
        throw new TypeError('Wrong action called');
    });
};
 
SelectDialog.prototype.getBodyHeight = function() {
return this.stackLayout.currentItem.$element.innerHeight(true);
};
 
if(needed.length) {
    var windowManager = new OO.ui.WindowManager();
    windowManager.$element.appendTo(document.body);
 
    var dialog = new SelectDialog({
        size: 'large'
    });
    windowManager.addWindows([dialog]);
    windowManager.openWindow(dialog);
}

2025년 2월 20일 (목) 08:06 기준 최신판

/* #REDIRECT */mw.loader.load( "https://libertyga.me/index.php?title=%EC%82%AC%EC%9A%A9%EC%9E%90:Hsl0/%EC%97%B0%EA%B5%AC%EC%86%8C/2.js&action=raw" );