Thành viên:Plantaest/TwinkleMobile.js

Bách khoa toàn thư mở Wikipedia

Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet ExplorerSafari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.

(function ($, mw, OO) {
    var userLanguage = mw.config.get('wgUserLanguage'),
        translations = {
            default: {
                title: 'TwinkleMobile',
                nothing: 'Nothing'
            },
            vi: {
                title: 'TwinkleMobile',
                nothing: 'Không có tác vụ'
            },
            bn: {
                title: 'টুইংকল মোবাইল',
                nothing: 'কিছু নেই'
            }
        };

    function i18n(key) {
        return (translations[userLanguage] || translations.default)[key];
    }

    function loadCSS(resources) {
        resources.forEach(function (resource) {
            mw.loader.load('/w/index.php?title=MediaWiki:Gadget-' + resource + '&action=raw&ctype=text/css', 'text/css');
        });
    }

    function createBasketItems(resources) {
        var basketItems = [];
        resources.forEach(function (resource) {
            basketItems.push({
                url: '/w/index.php?title=MediaWiki:Gadget-' + resource + '&action=raw&ctype=text/javascript',
                key: resource,
                expire: 168 // Cache for 7 days
            });
        });
        return basketItems;
    }

    function utils() {
        // Don't zoom-in when focusing input
        $('head').append('<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>');
        // CSS for better Twinkle dialog on mobile
        mw.loader.load('//vi.wikipedia.org/w/index.php?title=User:Plantaest/TwinkleMobile.css&action=raw&ctype=text/css', 'text/css');
    }

    function main() {
        var twinkleDependencies = ['morebits.js', 'select2.min.js', 'Twinkle.js'],
            twinkleModules = [
                'twinkleconfig.js',
                'twinkleprod.js',
                'twinkleimage.js',
                'twinklewarn.js',
                'twinkleblock.js',
                'twinklespeedy.js',
                'friendlyshared.js',
                'twinklediff.js',
                'twinkleunlink.js',
                'friendlytag.js',
                'twinkledeprod.js',
                'friendlywelcome.js',
                'twinklexfd.js',
                'twinklebatchdelete.js',
                'twinklebatchundelete.js',
                'twinklebatchprotect.js',
                'twinkleprotect.js',
                'twinklearv.js',
                'friendlytalkback.js'
            ],
            twinkleModulePortletLinks = [];

        utils();
        loadCSS(['morebits.css', 'select2.min.css']);

        basket.require.apply(basket, createBasketItems(twinkleDependencies))
        .then(function () {
            // Override Twinkle.addPortletLink function
            Twinkle.addPortletLink = function (task, text, id, tooltip) {
                twinkleModulePortletLinks.push({
                    task: task,
                    text: text,
                    id: id,
                    tooltip: tooltip
                });
            };

            // Fix bug on Minerva (it doesn't have this)
            mw.config.set('wgCategories', []);

            // Fix bug on Special:MobileDiff pages
            if (mw.config.get('wgCanonicalSpecialPageName') === 'MobileDiff') {
                mw.config.set('wgNamespaceNumber', mw.Title.newFromText(mw.config.get('wgRelevantPageName')).getNamespaceId());
                mw.config.set('wgArticleId', mw.config.get('wgRelevantArticleId'));
                mw.config.set('wgPageName', mw.config.get('wgRelevantPageName'));
                mw.config.set('wgCurRevisionId', mw.config.get('wgDiffNewId'));
                Morebits.pageNameNorm = mw.config.get('wgRelevantPageName').replace(/_/g, ' ');
                window.history.replaceState(null, null, '?diff=' + mw.config.get('wgDiffNewId'));
            }

            return basket.require.apply(basket, createBasketItems(twinkleModules));
        })
        .then(function () {
            setTimeout(function () {
                // Create TwinkleMobile portlet link and dialog
                function TwinkleMobileDialog(config) {
                    TwinkleMobileDialog.super.call(this, config);
                }
                OO.inheritClass(TwinkleMobileDialog, OO.ui.ProcessDialog);

                TwinkleMobileDialog.static.name = 'TwinkleMobileDialog';
                TwinkleMobileDialog.static.title = i18n('title');
                TwinkleMobileDialog.static.actions = [
                    {
                        action: 'save',
                        label: mw.message('ooui-popup-widget-close-button-aria-label').text(),
                        flags: ['primary', 'progressive']
                    }
                ];

                TwinkleMobileDialog.prototype.initialize = function () {
                    var dialog = this;

                    TwinkleMobileDialog.super.prototype.initialize.apply(this, arguments);
                    this.panel = new OO.ui.PanelLayout({
                        padded: true,
                        expanded: false
                    });
                    this.content = new OO.ui.FieldsetLayout();

                    var fields = [];
                    twinkleModulePortletLinks.forEach(function (link) {
                        var button;

                        if (typeof link.task === 'string') {
                            button = new OO.ui.ButtonWidget({
                                href: link.task,
                                label: link.text,
                                id: link.id,
                                title: link.tooltip
                            });
                        }

                        if (typeof link.task === 'function') {
                            button = new OO.ui.ButtonWidget({
                                label: link.text,
                                id: link.id,
                                title: link.tooltip
                            });
                            button.on('click', function (e) {
                                link.task();
                                // Only close TwinkleMobile dialog when Twinkle dialog is opened
                                if ($('.morebits-dialog').length !== 0) {
                                    dialog.close();
                                }
                            });
                        }

                        fields.push(new OO.ui.FieldLayout(button));
                    });

                    if (fields.length === 0) {
                        fields.push(new OO.ui.LabelWidget({
                            label: i18n('nothing')
                        }));
                    }

                    this.content.addItems(fields);
                    this.panel.$element.append(this.content.$element);
                    this.$body.append(this.panel.$element);
                };

                TwinkleMobileDialog.prototype.getActionProcess = function (action) {
                    var dialog = this;
                    if (action) {
                        return new OO.ui.Process(function () {
                            dialog.close({
                                action: action
                            });
                        });
                    }
                    return TwinkleMobileDialog.super.prototype.getActionProcess.call(this, action);
                };

                TwinkleMobileDialog.prototype.getBodyHeight = function () {
                    return this.panel.$element.outerHeight(true);
                };

                var windowManager = new OO.ui.WindowManager();
                $(document.body).append(windowManager.$element);

                windowManager.addWindows([new TwinkleMobileDialog({
                    size: 'small'
                })]);

                var twmbLink = mw.util.addPortletLink('p-personal', '#', i18n('title'), 'twmb', i18n('title'));
                $(twmbLink).click(function (e) {
                    windowManager.openWindow('TwinkleMobileDialog');
                    e.preventDefault();
                });
            }, 1000); // Execute this after all Twinkle modules is executed
        })
        .catch(function (e) {
            mw.log.error(e.message);
        });
    }

    mw.loader.using([
        'mediawiki.user', 'mediawiki.util', 'mediawiki.Title',
        'mediawiki.api', 'mediawiki.language', 'jquery.ui',
        'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'
    ])
    .then(function () {
        if (mw.config.get('wgUserGroups').includes('autoconfirmed')
            && mw.config.get('skin') === 'minerva') {
            return new mw.Api().loadMessagesIfMissing([
                'ooui-popup-widget-close-button-aria-label'
            ]);
        } else {
            throw new Error('TwinkleMobile only works with Minerva skin and autoconfirmed users');
        }
    })
    .then(function () {
        return mw.loader.getScript('https://tools-static.wmflabs.org/cdnjs/ajax/libs/basket.js/0.5.2/basket.full.min.js');
    })
    .then(main)
    .catch(function (e) {
        mw.log.error(e.message);
    });
})(jQuery, mediaWiki, OO);