跳转到内容

User:Hamish/MergeMarkTool.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
// <nowiki>
// 打開條目頁面或其討論頁 => 右上角 更多 => 標記已合併的條目

(function() {
    'use strict';

    if ((mw.config.get('wgNamespaceNumber') !== 0 && mw.config.get('wgNamespaceNumber') !== 1) || mw.config.get('wgAction') !== 'view') {
        return;
    }

    var now = new Date();
    var year = now.getFullYear();
    var month = String(now.getMonth() + 1).padStart(2, '0');
    var day = String(now.getDate()).padStart(2, '0');
    var currentDate = `${year}/${month}/${day}`;

    mw.loader.using(['oojs-ui', 'mediawiki.api'], function() {
        var $portletDiv = $('#p-cactions .vector-menu-content-list');

        if ($portletDiv.length) {
            var $mergeButton = $('<li>')
                .addClass('mw-list-item')
                .append(
                    $('<a>')
                        .attr('href', '#')
                        .text('標記已合併的條目')
                        .click(e => {
                            e.preventDefault();
                            Dialog();
                        })
                );

            $portletDiv.append($mergeButton);
        }
    });

    function Dialog() {
        var Dialog = function(config) {
            Dialog.super.call(this, config);
        };
        OO.inheritClass(Dialog, OO.ui.ProcessDialog);

        Dialog.static.name = 'merge-mark-tool';
        Dialog.static.title = '已合併條目標記工具';
        Dialog.static.actions = [
            { action: 'submit', label: '標記', flags: ['primary', 'progressive'] },
            { action: 'cancel', label: '取消', flags: ['safe', 'close'] }
        ];
        Dialog.static.size = 'medium';

        Dialog.prototype.initialize = function() {
            Dialog.super.prototype.initialize.call(this);

            this.articleInput = new OO.ui.TextInputWidget({
                placeholder: '輸入目標條目名稱'
            });

            this.dateInput = new OO.ui.TextInputWidget({
                value: currentDate
            });

            this.redirectCheckbox = new OO.ui.CheckboxInputWidget();

            this.redirectInput = new OO.ui.TextInputWidget({
                placeholder: '輸入重新導向目標'
            });

            this.addDiscussionCheckbox = new OO.ui.CheckboxInputWidget();

            this.talkLinkInput = new OO.ui.TextInputWidget({
                placeholder: '輸入討論頁永久連結'
            });

            this.articleField = new OO.ui.FieldLayout(this.articleInput, {
                label: '新條目名:',
                align: 'top'
            });

            this.dateField = new OO.ui.FieldLayout(this.dateInput, {
                label: '合併日期:',
                align: 'top'
            });

            this.redirectField = new OO.ui.FieldLayout(this.redirectCheckbox, {
                label: '重新導向目標和條目名稱不同',
                align: 'inline'
            });

            this.redirectTargetField = new OO.ui.FieldLayout(this.redirectInput, {
                label: '重新導向目標:',
                align: 'top'
            });
            this.discussionField = new OO.ui.FieldLayout(this.addDiscussionCheckbox, {
                label: '添加討論連結到{{merged from}}模板',
                align: 'inline'
            });

            this.talkLinkField = new OO.ui.FieldLayout(this.talkLinkInput, {
                label: '討論連結,無需輸入[[]]',
                align: 'top'
            });

            this.formPanel = new OO.ui.PanelLayout({
                padded: true,
                expanded: false
            });

            this.formPanel.$element.append(
                this.articleField.$element,
                this.dateField.$element,
                this.redirectField.$element,
                this.redirectTargetField.$element,
                this.discussionField.$element,
                this.talkLinkField.$element
            );

            this.addDiscussionCheckbox.connect(this, { change: 'onCheckboxChange' });
            this.redirectCheckbox.connect(this, { change: 'onRedirectCheckboxChange' });

            this.$body.append(this.formPanel.$element);

            this.onCheckboxChange();
            this.onRedirectCheckboxChange();
        };

        Dialog.prototype.onCheckboxChange = function() {
            var isChecked = this.addDiscussionCheckbox.isSelected();
            this.talkLinkField.toggle(isChecked);
        };

        Dialog.prototype.onRedirectCheckboxChange = function() {
            var isChecked = this.redirectCheckbox.isSelected();
            this.redirectTargetField.toggle(isChecked);
        };

        Dialog.prototype.getBodyHeight = function() {
            return 300;
        };

        Dialog.prototype.getActionProcess = function(action) {
            if (action === 'cancel') {
                return new OO.ui.Process(() => {
                    this.close({ action: action });
                });
            } else if (action === 'submit') {
                return new OO.ui.Process(() => {
                    var targetArticle = this.articleInput.getValue().trim();
                    var date = this.dateInput.getValue().trim();
                    var addDiscussion = this.addDiscussionCheckbox.isSelected();
                    var permalink = this.talkLinkInput.getValue().trim();
                    var createRedirect = this.redirectCheckbox.isSelected();
                    var redirectTarget = this.redirectInput.getValue().trim();

                    if (!targetArticle) {
                        return new OO.ui.Error('請輸入新條目名');
                    }

                    if (!date || !/^\d{4}\/\d{2}\/\d{2}$/.test(date)) {
                        return new OO.ui.Error('請輸入正確格式的日期 (YYYY/MM/DD)');
                    }

                    if (addDiscussion && !permalink) {
                        return new OO.ui.Error('請輸入討論頁永久連結');
                    }

                    if (createRedirect && !redirectTarget) {
                        return new OO.ui.Error('請輸入重新導向目標');
                    }

                    applyTemplates(targetArticle, date, permalink, addDiscussion, createRedirect, redirectTarget);

                    this.close({ action: action });
                });
            }

            return Dialog.super.prototype.getActionProcess.call(this, action);
        };

        Dialog.prototype.getSetupProcess = function(data) {
            return Dialog.super.prototype.getSetupProcess.call(this, data)
                .next(() => {
                    this.articleInput.setValue('');
                    this.dateInput.setValue(currentDate);
                    this.redirectCheckbox.setSelected(false);
                    this.redirectInput.setValue('');
                    this.onRedirectCheckboxChange();
                    this.addDiscussionCheckbox.setSelected(false);
                    this.talkLinkInput.setValue('');
                    this.onCheckboxChange();
                }, this);
        };

        var windowManager = new OO.ui.WindowManager();
        $(document.body).append(windowManager.$element);
        var mergeDialog = new Dialog();
        windowManager.addWindows([mergeDialog]);
        windowManager.openWindow(mergeDialog);
    }

    function applyTemplates(targetArticle, date, talkLink, addDiscussion, createRedirect, redirectTarget) {
        var currentArticle, currentArticleTalk;

        if (mw.config.get('wgNamespaceNumber') === 0 && mw.config.get('wgAction') === 'view') {
            currentArticle = mw.config.get('wgPageName');
            currentArticleTalk = 'Talk:' + currentArticle;
        } else if (mw.config.get('wgNamespaceNumber') === 1 && mw.config.get('wgAction') === 'view') {
            currentArticleTalk = mw.config.get('wgPageName');
            currentArticle = mw.config.get('wgTitle');
        } else {
            mw.notify('請在條目頁或討論頁使用此工具', {type: 'error'});
            return;
        }

        var targetArticleTalk = 'Talk:' + targetArticle;

        var mergedToTemplate = `{{merged to|${targetArticle}|${date}}}`;
        var mergedFromTemplate;
        if (addDiscussion && talkLink) {
            mergedFromTemplate = `{{merged from|${currentArticle}|${date}|afd=${talkLink}}}`;
        } else {
            mergedFromTemplate = `{{merged from|${currentArticle}|${date}}}`;
        }

        var redirectContent;
        if (createRedirect) {
            redirectContent = `#REDIRECT [[${redirectTarget}]]`;
        } else {
            redirectContent = `#REDIRECT [[${targetArticle}]]`;
        }

        mw.notify('正在添加標記...');

        var api = new mw.Api();
        editSubmit(api, currentArticleTalk, mergedToTemplate, '添加合併標記 via [[User:Hamish/MergeMarkTool.js|MergeMarkTool]]')
            .then(() => editSubmit(api, targetArticleTalk, mergedFromTemplate, '添加合併標記 via [[User:Hamish/MergeMarkTool.js|MergeMarkTool]]'))
            .then(() => editSubmit(api, currentArticle, redirectContent, '建立合併條目的重新導向 via [[User:Hamish/MergeMarkTool.js|MergeMarkTool]]'))
            .then(() => {
                mw.notify('標記已添加,刷新頁面以顯示更改', { type: 'success' });

                setTimeout(() => {
                    location.reload();
                }, 2000);
            })
            .catch(error => {
                mw.notify('添加合併標記時出錯: ' + error, { type: 'error' });
            });
    }

    function editSubmit(api, pageName, template, editSummary) {
        return api.get({
            action: 'query',
            prop: 'revisions',
            rvprop: 'content',
            titles: pageName,
            formatversion: '2'
        }).then(data => {
            var pageContent = '';

            if (data.query && data.query.pages && data.query.pages.length > 0) {
                var page = data.query.pages[0];

                if (page.revisions && page.revisions.length > 0) {
                    pageContent = page.revisions[0].content;
                }
            }

            var newContent;
            if (template.startsWith('#REDIRECT')) {
                newContent = template;
            } else {
                newContent = template + '\n' + (pageContent || '');
            }

            return api.postWithToken('csrf', {
                action: 'edit',
                title: pageName,
                text: newContent,
                summary: editSummary,
                format: 'json'
            });
        });
    }
})();
// </nowiki>