(Translated by https://www.hiragana.jp/)
User:Ericliu1912/link-ts.js - 维基百科,自由的百科全书 とべ转到内容ないよう

User:Ericliu1912/link-ts.js

维基百科ひゃっか自由じゆうてき百科ひゃっかぜん

注意ちゅうい保存ほぞんきさき,你必须清じょ浏览缓存才能さいのういた做出てき更改こうかいGoogle ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具こうぐ栏的“刷新さっしん”按钮。まいりHelp:绕过浏览缓存以获取さら帮助。

/*
 * 
 * 連結れんけつ翻譯ほんやく(tsl off ver.)
 *  https://zh.wikipedia.org/w/index.php?title=MediaWiki:Gadget-link-ts.js&oldid=63948978
 * 
 */

mw.loader.using(['jquery.ui']).then(function () {
    'use strict';

    var LTUI;
    switch (mw.config.get('wgUserLanguage')) {
        case 'zh':
        case 'zh-cn':
        case 'zh-hans':
        case 'zh-my':
        case 'zh-sg':
            LTUI = {
                Translate:              'こぼし译',
                TranslateLinks:         'こぼし译链せっ',
                LinkTranslator:         '链接こぼし译器',
                TLTitle:                '动翻译来语言维基百科文本中的链接',
                SourceLanguageCode:     '标维もとてき语言だい码:',
                OriginalLink:           'はら链接:',
                NOLINKINPAGE:           '此页ぼつゆう链接',
                Done:                   '完成かんせい',
                NoVE:                   'link-ts支持しじ视化しき,请切换到げんだい码模しき。',
                EditMessage:            '[[User:逆襲ぎゃくしゅうてき天邪鬼あまのじゃく/js/link-ts.js|こぼし译]]そとぶん链接',

                // OPTION
                SelectedTextOnly:       'ただ处理选中ぶんほん',
                IfFound:                '如果找到对应ちゅうぶん条目じょうもくてき话——',
                KeepOriginalText2:      '以原文げんぶん显示蓝链([[ちゅうぶん|Original Text]])',
                CommentOriginalLink:    'ちゅう释原链接',
                IfNotFound:             'いや则的话——',
                UseLangLink:            '转成またが语言链接(そく{{tsl}}ある{{link-xx}})',
                UseTsl:                 '使用しよう{{tsl}}而非{{link-xx}}',
                KeepOriginalText:       '以原文げんぶん显示绿链({{tsl|en|Orin||Orin text}})',
                MarkWrongPage:          '如果转成またが语言链接,而且(ざい原文げんぶんあるなかぶんぞく于红链,么把它标记出来でき',

                // STATUS
                PARSEFAILED:            '解析かいせきしつ败',
                ERROR:                  '错误',
                NOLINK:                 'ぼつゆう链接',
                MULTIPLELINK:           '个连せっ',
                PAGESAME:               '页面しょうどう',
                PAGEDIFF:               '页面不同ふどう',
                DONTEXIST:              '页面存在そんざい',
            };
            break;
        default:
            LTUI = {
                Translate:              '翻譯ほんやく',
                TranslateLinks:         '翻譯ほんやく連結れんけつ',
                LinkTranslator:         '連結れんけつ翻譯ほんやく',
                TLTitle:                '自動じどう翻譯ほんやくらい其他げん維基百科ひゃっかぶん本中ほんなかてき連結れんけつ',
                SourceLanguageCode:     '目標もくひょう維基てきげんだい碼:',
                OriginalLink:           'はら連結れんけつ:',
                NOLINKINPAGE:           '此頁ぼつゆうにんなん連結れんけつ',
                Done:                   '完成かんせい',
                NoVE:                   'link-ts支援しえん視覺しかくしき,請切かわいた原始げんし碼模しき。',
                EditMessage:            '使用しよう[[User:Ericliu1912/link-ts.js|連結れんけつ翻譯ほんやく]]翻譯ほんやくがいぶん連結れんけつ',

                // OPTION
                SelectedTextOnly:       'ただ處理しょりせんちゅうぶんほん',
                IfFound:                '如果找到對應たいおうちゅうぶん條目じょうもくてきばなし——',
                KeepOriginalText2:      '以原文げんぶん顯示けんじあいれん([[ちゅうぶん|Original Text]])',
                CommentOriginalLink:    '註釋ちゅうしゃくげん連結れんけつ',
                IfNotFound:             'いやのりてき话——',
                UseLangLink:            '轉成てんせいまたがげん連結れんけつそく{{tsl}}ある{{link-xx}})',
                UseTsl:                 '使用しよう{{tsl}}而非{{link-xx}}',
                KeepOriginalText:       '以原文げんぶん顯示けんじみどりれん({{tsl|en|Orin||Orin text}})',
                MarkWrongPage:          '如果轉成てんせいまたがげん連結れんけつ,而且(ざい原文げんぶんあるなかぶんぞく於紅れん麼把它標記ひょうき出來でき',

                // STATUS
                PARSEFAILED:            '解析かいせき失敗しっぱい',
                ERROR:                  '錯誤さくご',
                NOLINK:                 'ぼつゆう連結れんけつ',
                MULTIPLELINK:           '連結れんけつ',
                PAGESAME:               'ぺーじ面相めんそうどう',
                PAGEDIFF:               'ぺーじめん不同ふどう',
                DONTEXIST:              'ぺーじめん存在そんざい',
            };
    }

    var LTConf = {
        SourceLanguageCode:     'en',
        KeepOriginalText:       'checked', // 'checked' OR ''
        KeepOriginalText2:      'checked',
        CommentOriginalLink:    '',
        UseLangLink:            'checked',
        UseTsl:                 '',
        SelectedTextOnly:       'checked',
        MarkWrongPage:          'checked',
    };


    // variables
    var currentJobid = 0;
    var LDSB = '__LEFT_DOUBLE_SQUARE_BRACKETS__';
    var EXEConf;

    /**
     * 调用维基百科ひゃっかAPIらい转换条目じょうもく标题
     */
    var callApi = function (options) {
        var links = options.links || [];
        var callback = options.callback || (function () {});
        var failure = options.failure || (function () {});
        var lang = options.lang || 'en';
        var tolang = options.tolang || mw.config.get('wgContentLanguage');
        var jobid = options.jobid || currentJobid;

        // 标题おもどう时将这些标题ぶん组,いん为APIただまこと许一次性最多提交50个标题
        var map = {};
        var i;
        for (i=0; i<links.length; i++) {
            map[links[i]] = true;
        }

        var queue = [];
        var queue2 = [];
        var m = 0, n = 0;
        for (var j in map) {
            queue.push(j);
            m++;
            if (m === 50) {
                m = 0;
                queue2.push(queue);
                queue = [];
                n++;
            }
        }
        if (queue.length > 0) {
            queue2.push(queue);
            n++;
        }

        // 开始处理
        var stop = false;
        var langlinks = {};

        var done = function (data) {
            if (data.query) {
                // げんてき標題ひょうだい
                var orinTitle = {};
                var convert = function (arr) {
                    if (arr) {
                        for (var i=0; i<arr.length; i++) {
                            if (orinTitle[arr[i].from]) {
                                orinTitle[arr[i].to] = orinTitle[arr[i].from];
                            } else {
                                orinTitle[arr[i].to] = arr[i].from;
                            }
                        }
                    }
                };
                convert(data.query.normalized);
                convert(data.query.redirects);

                // しめぎあきら翻譯ほんやく情況じょうきょう
                var pages = data.query.pages;
                for (var pageid in pages) {
                    var page = pages[pageid];
                    var title = page.title;
                    if (orinTitle[title]) {
                        title = orinTitle[title];
                    }

                    if (page.missing !== undefined) {
                        // 页面存在そんざい
                        langlinks[title] = undefined;
                    } else if (page.langlinks) {
                        langlinks[title] = page.langlinks[0]['*'];
                    } else {
                        // ぼつゆう对应条目じょうもく
                        langlinks[title] = null;
                    }
                }
            }

            n--;
            if (n === 0 && !stop) {
                callback(langlinks);
            }
        };

        var error = function (jqXHR, textStatus, errorThrown) {
            stop = true;
            if (jobid === currentJobid) {
                failure(langlinks);
            }
        };

        var process = function (links) {
            if (jobid !== currentJobid) {
                stop = true;
                return;
            }

            $.ajax({
                data: {
                    action: 'query',
                    prop: 'langlinks',
                    lllang: tolang,
                    format: 'json',
                    redirects: true,
                    lllimit: 50,
                    titles: links.join('|'),
                },
                dataType: 'jsonp',
                type: 'POST',
                url: 'https://' + lang + '.wikipedia.org/w/api.php',
                success: done,
                error: error,
            });
        };

        for (i=0; i<queue2.length && !stop; i++) {
            process(queue2[i]);
        }
    };

    /**
     * すえ要求ようきゅうはたまたが语言链接变成普通ふつう链接、{{tsl}}ある{{link}}。Categoryかい特殊とくしゅ处理。
     */
    var makeLink = function (options) {
        var link = options.link || { target: '', display: '' };
        var lang = options.lang || '';
        var newTarget = options.newTarget;
        var output = '';

        if (!link) {
            return '';
        }

        var makeNormalLink = function (target, display) {
            if (target === display || display === '') {
                return LDSB + target + ']]';
            } else {
                return LDSB + target + '|' + display + ']]';
            }
        };

        // 禁止きんし页面ぶん类变なりまたが语言链接,あるものざい其后めん附加ふか文字もじじょ[Category:XXX|*]种)
        if (link.target.toLowerCase().indexOf('category:') === 0) {
            options.useLangLink = false;
            options.keepOriginalText2 = (link.display !== '' && link.display !== link.target);
        }

        if (newTarget === null) {
            // ぼつゆう对应ちゅうぶん条目じょうもく
            if (options.useLangLink) {
                if (options.useTsl) {
                    if (options.keepOriginalText) {
                        return '{{tsl|' + lang + '|' + link.target + '||' + link.display + '}}';
                    } else {
                        return '{{tsl|' + lang + '|' + link.target + '|}}';
                    }
                } else {
                    if (options.keepOriginalText) {
                        return '{{link-' + lang + '||' + link.target + '|' + link.display + '}}';
                    } else {
                        return '{{link-' + lang + '||' + link.target + '}}';
                    }
                }
            } else {
                if (options.markWrongPage) {
                    return '<!-- ' + LTUI.NOLINK + ' -->' + makeNormalLink(link.target, link.display);
                } else {
                    return makeNormalLink(link.target, link.display);
                }
            }
        } else if (newTarget === undefined) {
            // 页面存在そんざい
            if (options.markWrongPage) {
                return '<!-- ' + LTUI.DONTEXIST + ' -->' + makeNormalLink(link.target, link.display);
            } else {
                return makeNormalLink(link.target, link.display);
            }
        } else {
            if (options.keepOriginalText2) {
                output = makeNormalLink(newTarget, link.display || link.target);
            } else {
                output = makeNormalLink(newTarget, '');
            }
        }

        if (options.commentOriginalLink) {
            output = '<!-- ' + makeNormalLink(link.target, link.display) + ' -->' + output;
        }

        return output;
    };

    /**
     * 开始进行处理
     */
    var processLinks = function (event) {
        var jobid = currentJobid;

        EXEConf = {
            KeepOriginalText:       $('#linktranslator-keep-original').prop('checked'),
            KeepOriginalText2:      $('#linktranslator-keep-original2').prop('checked'),
            CommentOriginalLink:    $('#linktranslator-comment-link').prop('checked'),
            UseLangLink:            $('#linktranslator-lang-link').prop('checked'),
            UseTsl:                 $('#linktranslator-tsl').prop('checked'),
            SelectedTextOnly:       $('#linktranslator-selected-text').prop('checked'),
            MarkWrongPage:          $('#linktranslator-markwrongpage').prop('checked'),
        };

        LTConf.SourceLanguageCode = $('#linktranslator-source-lang').val();

        var wikitext = wikitextEditor.text;
        if (EXEConf.SelectedTextOnly) {
            wikitext = wikitextEditor.selectionText;
        }

        var links = wikitext.match(/(\[\[)(?!\:?.?.?\:)(?!Image:)(?!File:)(.+?)(\|.+?)?(\]\])/g);

        if (links === null) {
            $('#linktranslator').text(LTUI.NOLINKINPAGE);
            return;
        } else {
            $('#linktranslator').dialog( 'option', 'position', { my: 'top', at: 'top'} );
            $('#linktranslator').html('<div id="linktranslator-progressbar"></div>');
            $('#linktranslator-progressbar').progressbar();
        }

        // 整合せいごうかくlinks
        var realLinks = [];
        var links2 = [];
        for (var i=0; i<links.length; i++) {
            var link = links[i].slice(2, -2);

            var linktarget = link;
            var linkdisplay = link;

            var idx = link.indexOf('|');
            if (idx !== -1) {
                linktarget = link.substring(0, idx);
                linkdisplay = link.substring(idx + 1);
            }
            // 通常つうじょう情況じょうきょうがいぶん維基てきいかりてんいたちゅうぶん維基就沒ようりょう
            idx = linktarget.indexOf('#');
            if (idx !== -1) {
                linktarget = link.substring(0, idx);
            }
            $('#linktranslator').append('<div id="linktranslator-item-' + i + '"></div>');
            $('#linktranslator-item-' + i).text(links[i] + ' -> ')
                .append('<span class="linktranslator-item-newlink">...</span>');

            realLinks.push(linktarget);
            links2.push({ target: linktarget, display: linkdisplay });
        }

        var apiCallback = function (langlinks) {
            var code = wikitext + '';

            for (var i=0; i<links2.length; i++) {
                var link = links2[i];

                // 处理ぶんない链接
                var linkCode = makeLink({
                    link: link,
                    newTarget: langlinks[link.target],
                    lang: LTConf.SourceLanguageCode,
                    useLangLink: EXEConf.UseLangLink,
                    useTsl: EXEConf.UseTsl,
                    keepOriginalText: EXEConf.KeepOriginalText,
                    keepOriginalText2: EXEConf.KeepOriginalText2,
                    commentOriginalLink: EXEConf.CommentOriginalLink,
                    markWrongPage: EXEConf.MarkWrongPage,
                });

                //mark on dialogue
                $('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(linkCode.replace(new RegExp(LDSB, 'g'), '[[')).css('color', '#0645ad');

                if (langlinks[link.target] === null) {
                    // ぼつゆう对应ちゅうぶん条目じょうもく
                    $('#linktranslator-item-' + i + ' .linktranslator-item-newlink').addClass('ilh-tool');
                    if (!EXEConf.UseLangLink) {
                        $('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(LTUI.NOLINK);
                    }
                } else if (langlinks[link.target] === undefined) {
                    // 页面存在そんざい
                    $('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(LTUI.DONTEXIST).css('color', '#ba0000');
                } else if (langlinks[link.target] === link) {
                    $('#linktranslator-item-' + i + ' .linktranslator-item-newlink').text(LTUI.PAGESAME);
                }

                // only replacing the first is ok, we will run this many times
                code = code.replace(links[i], linkCode);
            }

            return code.replace(new RegExp(LDSB, 'g'), '[[');
        };

        // 开始处理
        // 过去一个条目调用一次API,现在いちせい处理全部ぜんぶ所以ゆえん滚动じょうやめ经没有意ゆうい义。
        // var respcount = 0;
        callApi({
            links: realLinks,
            lang: LTConf.SourceLanguageCode,
            jobid: jobid,
            callback: function (langlinks) {
                if (jobid !== currentJobid) {
                    return;
                }

                var newtext = apiCallback(langlinks);

                //$('#linktranslator-progressbar').progressbar('value', respcount * 100 / links.length);
                $('#linktranslator-progressbar').progressbar('value', 100);
                $('#linktranslator').prepend('<div id="linktranlator-done"><strong>' + LTUI.Done + '</strong></div>');

                if (EXEConf.SelectedTextOnly) {
                    wikitextEditor.selectionText = newtext;
                } else {
                    wikitextEditor.text = newtext;
                }
                if (!wikitextEditor.summary) {
                    wikitextEditor.summary = LTUI.EditMessage;
                }

                // はりたいVE進行しんこうHack
                wikitextEditor.keepSelection = false;
            },
            failure: function (langlinks) {
                $('#linktranslator').prepend('<div id="linktranlator-done" style="color:red;"><strong>' + LTUI.ERROR + '</strong></div>');
            },
        });
    };

    // clear previous button
    $('#wpLinktranslator').remove();

    var callDialog = function (event) {
        if (event && event.preventDefault) {
            event.preventDefault();
        }
        $('#linktranslator').remove();

        if (wikitextEditor.mode === 'visual') {
            alert(LTUI.NoVE);
            return;
        }

        // はりたいVE進行しんこうHack
        wikitextEditor.keepSelection = true;

        if (wikitextEditor.selectionText.length > 0) {
            LTConf.SelectedTextOnly = 'checked';
        } else {
            LTConf.SelectedTextOnly = '';
        }

        $('<div id="linktranslator" title="' + LTUI.LinkTranslator + '">' +
            '<label for="linktranslator-source-lang">' + LTUI.SourceLanguageCode + '</label> ' +
            '<input id="linktranslator-source-lang" value="' + LTConf.SourceLanguageCode + '" type="text" /><br><br>' +
            '<input type="checkbox" id="linktranslator-selected-text" ' + LTConf.SelectedTextOnly + '/> ' +
            '<label for="linktranslator-selected-text">' + LTUI.SelectedTextOnly + '</label><br>' +
            '<br>' + LTUI.IfFound + '<br><br>' +
            '<input type="checkbox" id="linktranslator-comment-link" ' + LTConf.CommentOriginalLink + '/> ' +
            '<label for="linktranslator-comment-link">' + LTUI.CommentOriginalLink + '</label><br>' +
            '<input type="checkbox" id="linktranslator-keep-original2" ' + LTConf.KeepOriginalText2 + '/> ' +
            '<label for="linktranslator-keep-original2">' + LTUI.KeepOriginalText2 + '</label><br>' +
            '<br>' + LTUI.IfNotFound + '<br><br>' +
            '<input type="checkbox" id="linktranslator-lang-link" ' + LTConf.UseLangLink + '/> ' +
            '<label for="linktranslator-lang-link">' + LTUI.UseLangLink + '</label><br>' +
            '<input type="checkbox" id="linktranslator-tsl" ' + LTConf.UseTsl + '/> ' +
            '<label for="linktranslator-tsl">' + LTUI.UseTsl + '</label><br>' +
            '<input type="checkbox" id="linktranslator-keep-original" ' + LTConf.KeepOriginalText + '/> ' +
            '<label for="linktranslator-keep-original">' + LTUI.KeepOriginalText + '</label><br>' +
            '<input type="checkbox" id="linktranslator-markwrongpage" ' + LTConf.MarkWrongPage + '/> ' +
            '<label for="linktranslator-markwrongpage">' + LTUI.MarkWrongPage + '</label><br>'
        ).dialog({
            modal: false,
            close: function() {
                currentJobid++;
            },
            width: 500,
            buttons: [
                {
                    text: LTUI.Translate,
                    click: function () {
                        $('#linktranslator').dialog('option', 'buttons', []);
                        processLinks();
                    }
                }
            ]
        });
    };


    // しつらえほう支援しえんかくみち編輯へんしゅう
    mw.hook('editorapi.ready').add(function () {
        if (['wikitext', 'wikEd', 'codemirror'].indexOf(wikitextEditor.mode) !== -1) {
            $('#wpLinktranslator').remove();
            $('#wpLinktranslatorFUCK').remove();
            var FUCKYOU = $('#wpDiffWidget').length > 0;
            if (FUCKYOU) {
                $('#wpDiffWidget').after('<span id="wpLinktranslatorFUCK" aria-disabled="false" class="oo-ui-widget oo-ui-widget-enabled oo-ui-inputWidget oo-ui-buttonElement oo-ui-buttonElement-framed oo-ui-labelElement oo-ui-buttonInputWidget"><input id="wpLinktranslator" value="' + LTUI.TranslateLinks + '" title="' + LTUI.TLTitle + '" type="button" class="oo-ui-inputWidget-input oo-ui-buttonElement-button"/></span>');
            } else {
                $('#wpDiff').after('\n<input id="wpLinktranslator" value="' + LTUI.TranslateLinks + '" title="' + LTUI.TLTitle + '" type="button"/>');
            }
            $('#wpLinktranslator').click(callDialog);
        }
        $('#p-link-ts').remove();
        $(mw.util.addPortletLink('p-cactions', '#', LTUI.TranslateLinks, 'p-link-ts')).click(callDialog);

        currentJobid++;
        try {
            $('#linktranslator').dialog('close');
        } catch (ex) {

        }
    });
    mw.loader.load('https://zh.wikipedia.org/w/index.php?title=MediaWiki:Gadget-EditorAPIs.js&action=raw&ctype=text/javascript');
});