User:ZheiZhei/test.js:修订间差异

来自偶像大师中文维基
跳转到导航 跳转到搜索
无编辑摘要
无编辑摘要
第1行: 第1行:
// <nowiki>
/* globals TranslateVariants:true */
/**
/**
  * 使用說明請見 https://zh.wikipedia.org/wiki/User:Xiplus/js/TranslateVariants
  * When you need to load multiple scripts and css from wiki pages at the same time,
* please use the `/load.php?modules=wiki:PageName` combination instead of multiple `action=raw` requests.
*
* @example
* ```
* // before:
* mw.loader.load( "/index.php?action=raw&ctype=text/javascript&title=SomeScripts.js" );
* mw.loader.load( "/index.php?action=raw&ctype=text/css&title=SomeStyles.css", "text/css" );
* // after:
* mw.loader.load( "/load.php?modules=wiki:SomeScripts.js|wiki:SomeStyles.css" );
* ```
  */
  */
Promise.all( [
/**
$.ready,
* 在编辑时,对{{LyricsKai}}提供一个编辑窗口,原文与翻译并排排列,再进行翻译等工作无需滚动页面查看原文,方便编辑。
mw.loader.using( [ 'ext.gadget.HanAssist', 'mediawiki.api', 'mediawiki.util', 'mediawiki.ForeignApi', 'mediawiki.diff.styles' ] ),
* 默认匹配第一个出现个的{{LyricsKai}},如需匹配其他请使用鼠标选中相应代码。
] ).then(
* 很可能有bug,提交前请预览。
function( [ _, require ] ) {
*/
const { conv } = require('ext.gadget.HanAssist');
// <nowiki>
 
$(function () {
if (mw.config.get('wgPageName').match(/^MediaWiki:[^/]+(\/zh)?$/)) {
    if (mw.config.values.wgAction == "edit" || mw.config.values.wgAction == "submit") {
let link = mw.util.addPortletLink(
        var btn = $('<li><a title="LyricsKai可视化编辑">歌词编辑</a></li>');
'p-cactions',
        btn.click(showLyricsKaiEditor);
'#',
        $('#p-cactions ul').append(btn);
conv( { hans: '转换变体', hant: '轉換變體' } )
    }
);
$(link).on('click', function() {
this.remove();
main();
});
} else {
return;
}
 
if (typeof (TranslateVariants) == 'undefined') {
TranslateVariants = {};
}
if (typeof (TranslateVariants.summary) != 'string') {
TranslateVariants.summary = conv( { hans: '自动转换变体自', hant: '自動轉換變體自' } ) + '[[$1]] via [[User:Dabao_qian/TranslateVariants-zhwiki.js|TranslateVariants]]';
}
 
async function main() {
const langs = ['zh', 'zh-hans', 'zh-cn', 'zh-my', 'zh-sg', 'zh-hant', 'zh-hk', 'zh-mo', 'zh-tw'];
const langname = {
'zh': '原始',
'zh-hans': '简体',
'zh-cn': '大陆简体',
'zh-my': '大马简体',
'zh-sg': '新加坡简体',
'zh-hant': '繁體',
'zh-hk': '香港繁體',
'zh-mo': '澳門繁體',
'zh-tw': '臺灣正體',
};
let result = {};
 
var api = new mw.Api();
var zhwpapi;
if (mw.config.get('wgDBname') === 'zhwiki') {
zhwpapi = new mw.Api();
} else {
zhwpapi = new mw.ForeignApi('//zh.wikipedia.org/w/api.php');
}
var basepagetext = '';
let table = $('<div id="TranslateVariants">').prependTo('#bodyContent');
 
let submitall = $('<button>' + conv( { hans: '保存所有更改', hant: '儲存所有變更' } ) + '</button>');
submitall.on('click', function() {
let buttons = $('.TranslateVariants-publish-changes');
if (buttons.length === 0) {
mw.notify(conv( { hans: '没有任何更改可保存', hant: '沒有任何變更可儲存' } ), { type: 'error' });
return;
}
if (!confirm(conv( { hans: '保存 ', hant: '儲存 ' } ) + buttons.length + conv( { hans: ' 个更改?', hant: ' 個變更?' } ))) {
mw.notify(conv( { hans: '已取消保存', hant: '已取消儲存' } ), { type: 'warn' });
return;
}
buttons.each(function(_, button) {
$(button).click();
});
});
table.append($('<div style="text-align: right;">').append(submitall));
 
$('<div style="color:red">' + conv( { hans: '提醒:TranslateVariants工具使用IT、MediaWiki及specialpages三个转换组进行自动转换,请确认转换结果是否正确!', hant: '提醒:TranslateVariants工具使用IT、MediaWiki及specialpages三個轉換組進行自動轉換,請確認轉換結果是否正確!' } ) + '</div>').appendTo(table);


var defaultlangs = 'zh,zh-hans,zh-hant';
    function showLyricsKaiEditor() {
var runlangs = prompt(conv( { hans: '转换以下语言(以逗号隔开):', hant: '轉換以下語言(以逗號隔開):' } ), defaultlangs);
        var textbox = document.getElementById('wpTextbox1');
if (runlangs === null) {
        var regex = /(\{\{[Ll]yrics*?\|original=)([\s\S]*?)(\|translated=)([\s\S]*?)\}\}/;
runlangs = defaultlangs;
        var codeContent = '';
}
        if (textbox.selectionStart == textbox.selectionEnd) {
            codeContent = $(textbox).val();
        } else {
            codeContent = textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
            if (!regex.test(codeContent)) {
                mw.notify('所选代码没有LyricsKai,尝试在所有代码中搜寻');
                codeContent = $(textbox).val();
            }
        }
        if (!regex.test(codeContent)) {
            mw.notify('代码没有LyricsKai');
        }
        var original_str, translated_str;
        [_, _, original_str, _, translated_str] = codeContent.match(regex);
        var original = trim(original_str).split('\n');
        var translated = trim(translated_str).split('\n');
        var n = Math.max(original.length, translated.length);


var langqueue = runlangs.split(',').map(function(lang) {
        var editor = $('<div />');
return lang.trim();
        editor.css({
}).filter(function(lang) {
            'overflow': 'auto',
return langs.indexOf(lang) !== -1;
            'padding': '16px 24px 16px 24px',
});
            'max-height': '100%',
            'box-sizing': 'border-box',
            'line-height': '1.6'
        });
        editor.addClass('Lyrics');
        editor.addClass('Lyrics-no-ruby');
        editor.append('<style data-mw-deduplicate="TemplateStyles:r2208000">.Lyrics.Lyrics-has-ruby .Lyrics-original,.Lyrics.Lyrics-has-ruby .Lyrics-translated{line-height:2.1}.Lyrics.Lyrics-no-ruby .Lyrics-original,.Lyrics.Lyrics-no-ruby .Lyrics-translated{vertical-align:top}.Lyrics .Lyrics-original,.Lyrics .Lyrics-translated{width:100%;display:inline-block;white-space:pre-wrap}@media all and (max-width:720px){.Lyrics{min-width:100%}}@media all and (min-width:720px){.Lyrics .Lyrics-original,.Lyrics .Lyrics-translated{width:49.85%}}</style>');
        editor.append(
            '<style>' +
            '  #LyricsKaiEditor .Lyrics-original:hover, #LyricsKaiEditor .Lyrics-translated:hover {' +
            '      box-shadow: inset 0px 0px 0.2em #004eff;' +
            '  }' +
            '  #LyricsKaiEditor .Lyrics-line {' +
            '      margin-top: 5px;' +
            '  }' +
            '</style>');


let text;
        for (i = 0; i < n; i++) {
if ($('#wpTextbox1').length === 1) {
            var line = $('<div />');
text = $('#wpTextbox1').val();
            line.addClass('Lyrics-line');
} else {
let data = await api.get({
action: 'query',
prop: 'revisions',
rvprop: ['content', 'timestamp'],
titles: [mw.config.get('wgPageName')],
formatversion: '2',
curtimestamp: true,
});
if (!data.query || !data.query.pages) {
alert('unknown error');
return;
}
let page = data.query.pages[0];
if (!page || page.invalid) {
alert('invalidtitle');
return;
}
if (page.missing) {
alert('nocreate-missing');
return;
}
let revision = page.revisions[0];
text = revision.content;
}
result.zh = text;


text = text.replace(/[[\]{}<>|:*'_#&\s]/gim, function(s) {
            var original_line = $('<div />');
return "&#" + s.charCodeAt(0) + ";";
            original_line.addClass('Lyrics-original');
});
            original_line.attr('contenteditable', 'true');
text = text.replace(/(&#91;&#91;)((?:(?!&#124;)(?!&#93;).)+?)(&#124;(?:(?!&#93;).)+?&#93;&#93;)/g, '$1-{$2}-$3');
            original_line.text(original[i] || '');
text = text.replace(/-&#123;(.*?)&#125;-/g, function(s) {
return s
.replace('-&#123;', '-{')
.replace('&#125;-', '}-')
.replace(/&#124;/g, '|')
.replace(/&#32;/g, ' ')
.replace(/&#61;/g, '=')
.replace(/&#62;/g, '>')
.replace(/&#58;/g, ':');
});
basepagetext = text;
process();


function process() {
            var translated_line = $('<div />');
if (langqueue.length === 0) {
            translated_line.addClass('Lyrics-translated');
return;
            translated_line.attr('contenteditable', 'true');
}
            translated_line.text(translated[i] || '');


var lang = langqueue.shift();
            line.append(original_line);
var diffTable = $('<div id="TranslateVariants-diff-' + lang + '">').appendTo(table);
            line.append(translated_line);
$('<hr>').appendTo(table);
            editor.append(line);
        }
        var close = $('<span />');
        close.text('x');
        close.css({
            'cursor': 'pointer',
            'position': 'absolute',
            'top': '0px',
            'right': '0px',
            'margin': '0px 3px',
            'font-size': '20px'
        });
        close.on('click', function () {
            save();
            container.remove();
        });
        var container = $('<div />')
        container.attr('id', 'LyricsKaiEditor');
        container.css({
            'position': 'fixed',
            'left': '50px',
            'bottom': '50px',
            'top': '50px',
            'right': '50px',
            'width': 'calc(100% - 100px)',
            'height': 'calc(100% - 100px)',
            'padding-top': '20px',
            'box-sizing': 'border-box',
            'box-shadow': '3px 3px 5px',
            'background': 'white'
        });
        container.append(close);
        container.append('<div style="clear:both;"></div>');
        container.append(editor);
        $('body').append(container);


const basename = mw.config.get('wgPageName').replace(/\/zh$/, '');
        container.on('keypress', '.Lyrics-original, .Lyrics-translated', function (e) {
var targetTitle;
            if (e.which == 13) { // enter
if (lang == 'zh') {
                var line = $('<div />');
targetTitle = basename + '';
                line.addClass('Lyrics-line');
} else {
targetTitle = basename + '/' + lang;
}


var contentlang, newtext;
                var original_line = $('<div />');
if (lang == 'zh') {
                original_line.addClass('Lyrics-original');
contentlang = 'zh-cn';
                original_line.attr('contenteditable', 'true');
} else if (lang == 'zh-hans') {
                original_line.text('');
contentlang = 'zh-cn';
} else if (lang == 'zh-hant') {
contentlang = 'zh-tw';
} else {
contentlang = lang;
}


zhwpapi.parse(
                var translated_line = $('<div />');
'{{NoteTA|G1=IT|G2=MediaWiki|G3=specialpages}}<div id="TVcontent">' + basepagetext + '</div>',
                translated_line.addClass('Lyrics-translated');
{
                translated_line.attr('contenteditable', 'true');
'uselang': contentlang,
                translated_line.text('');
'prop': 'text',
}
).then(function(data) {
newtext = $('<div/>').html(data).find('#TVcontent').text();


return api.post({
                line.append(original_line);
action: 'query',
                line.append(translated_line);
prop: 'revisions',
                $(this).parent('.Lyrics-line').after(line);
titles: [targetTitle],
                if ($(this).is('.Lyrics-original')) {
rvdifftotext: newtext,
                    original_line.focus();
formatversion: '2',
                } else {
});
                    translated_line.focus();
}, function(err) {
                }
mw.notify('解析' + lang + conv( { hans: '时发生错误:', hant: '時發生錯誤:' } ) + err);
                return false;
}).then(function(data) {
            }
let tool = $('<div><a href="' + mw.util.getUrl(targetTitle) + '">' + lang + '(' + langname[lang] + ')</a>(<a href="' + mw.util.getUrl(targetTitle, { action: 'edit' }) + '">' + conv( { hans: '编', hant: '編' } ) + '</a>)</div>').appendTo(diffTable);
        });
let page = data.query.pages[0];
        container.on('keyup', '.Lyrics-original, .Lyrics-translated', function (e) {
if (page.missing) {
            if (e.which == 38) { // up
let submit = $('<button style="float: right;">' + conv( { hans: '保存页面', hant: '儲存頁面' } ) + '</button>').appendTo(tool);
                if ($(this).is('.Lyrics-original')) {
submit.on('click', function() {
                    $(this).parent('.Lyrics-line').prev('.Lyrics-line').find('.Lyrics-original').focus();
this.remove();
                } else {
api.create(
                    $(this).parent('.Lyrics-line').prev('.Lyrics-line').find('.Lyrics-translated').focus();
targetTitle,
                }
{ summary: TranslateVariants.summary.replace(/\$1/g, mw.config.get('wgPageName')) },
            } else if (e.which == 40) { // down
newtext
                if ($(this).is('.Lyrics-original')) {
).then(function() {
                    $(this).parent('.Lyrics-line').next('.Lyrics-line').find('.Lyrics-original').focus();
mw.notify(conv( { hans: '已编辑 ', hant: '已編輯 ' } ) + targetTitle);
                } else {
}, function(e) {
                    $(this).parent('.Lyrics-line').next('.Lyrics-line').find('.Lyrics-translated').focus();
mw.notify(conv( { hans: '编辑 ', hant: '編輯 ' } ) + targetTitle + conv( { hans: ' 发生错误:', hant: ' 發生錯誤:' } ) + e);
                }
});
            }
});
        })
$('<pre>').html(newtext.replace(/[<>&]/gim, function(s) {
return "&#" + s.charCodeAt(0) + ";";
})).appendTo(diffTable);
return;
}
let diff = page.revisions[0].diff.body;
if (diff == '') {
$('<span style="float: right;">' + conv( { hans: '无更改', hant: '無變更' } ) + '</span>').appendTo(tool);
} else {
let submit = $('<button class="TranslateVariants-publish-changes" style="float: right;">' + conv( { hans: '保存更改', hant: '儲存變更' } ) + '</button>').appendTo(tool);
submit.on('click', function() {
this.remove();
api.edit(
targetTitle,
function() {
return {
text: newtext,
summary: TranslateVariants.summary.replace(/\$1/g, mw.config.get('wgPageName')),
nocreate: false,
};
}
).then(function() {
mw.notify(conv( { hans: '已编辑 ', hant: '已編輯 ' } ) + targetTitle);
}, function(e) {
mw.notify(conv( { hans: '编辑 ', hant: '編輯 ' } ) + targetTitle + conv( { hans: ' 发生错误:', hant: ' 發生錯誤:' } ) + e);
});
});
$('<table class="diff">').html(diff).prepend('<colgroup><col class="diff-marker"><col class="diff-content"><col class="diff-marker"><col class="diff-content"></colgroup>').appendTo(diffTable);
}
}, function(err) {
mw.notify(conv( { hans: '获取', hant: '取得' } ) + lang + conv( { hans: '差异时发生错误:', hant: '差異時發生錯誤:' } ) + err);
}).always(function() {
process();
});
}
}


},
        function trim(str) {
);
            return str.replace(/(^\s*)|(\s*$)/g, '');
        }
        function save() {
            var original_new = '';
            var translated_new = '';
            editor.find('.Lyrics-line').each(function () {
                original_new = original_new + '\n' + $(this).find('.Lyrics-original').text();
                translated_new = translated_new + '\n' + $(this).find('.Lyrics-translated').text();
            });
            original_new = trim(original_new);
            translated_new = trim(translated_new);
            var codeContent_new = codeContent.replace(regex, '$1\n' + original_new + '\n$3\n' + translated_new + '\n}}')
            $('#wpTextbox1').val($('#wpTextbox1').val().replace(codeContent, codeContent_new));
        }
    }
});
// </nowiki>
// </nowiki>

2025年10月19日 (日) 20:42的版本

/**
 * When you need to load multiple scripts and css from wiki pages at the same time,
 * please use the `/load.php?modules=wiki:PageName` combination instead of multiple `action=raw` requests.
 *
 * @example
 * ```
 * // before:
 * mw.loader.load( "/index.php?action=raw&ctype=text/javascript&title=SomeScripts.js" );
 * mw.loader.load( "/index.php?action=raw&ctype=text/css&title=SomeStyles.css", "text/css" );
 * // after:
 * mw.loader.load( "/load.php?modules=wiki:SomeScripts.js|wiki:SomeStyles.css" );
 * ```
 */
/**
 * 在编辑时,对{{LyricsKai}}提供一个编辑窗口,原文与翻译并排排列,再进行翻译等工作无需滚动页面查看原文,方便编辑。
 * 默认匹配第一个出现个的{{LyricsKai}},如需匹配其他请使用鼠标选中相应代码。
 * 很可能有bug,提交前请预览。
 */
 // <nowiki>
$(function () {
    if (mw.config.values.wgAction == "edit" || mw.config.values.wgAction == "submit") {
        var btn = $('<li><a title="LyricsKai可视化编辑">歌词编辑</a></li>');
        btn.click(showLyricsKaiEditor);
        $('#p-cactions ul').append(btn);
    }

    function showLyricsKaiEditor() {
        var textbox = document.getElementById('wpTextbox1');
        var regex = /(\{\{[Ll]yrics*?\|original=)([\s\S]*?)(\|translated=)([\s\S]*?)\}\}/;
        var codeContent = '';
        if (textbox.selectionStart == textbox.selectionEnd) {
            codeContent = $(textbox).val();
        } else {
            codeContent = textbox.value.substring(textbox.selectionStart, textbox.selectionEnd);
            if (!regex.test(codeContent)) {
                mw.notify('所选代码没有LyricsKai,尝试在所有代码中搜寻');
                codeContent = $(textbox).val();
            }
        }
        if (!regex.test(codeContent)) {
            mw.notify('代码没有LyricsKai');
        }
        var original_str, translated_str;
        [_, _, original_str, _, translated_str] = codeContent.match(regex);
        var original = trim(original_str).split('\n');
        var translated = trim(translated_str).split('\n');
        var n = Math.max(original.length, translated.length);

        var editor = $('<div />');
        editor.css({
            'overflow': 'auto',
            'padding': '16px 24px 16px 24px',
            'max-height': '100%',
            'box-sizing': 'border-box',
            'line-height': '1.6'
        });
        editor.addClass('Lyrics');
        editor.addClass('Lyrics-no-ruby');
        editor.append('<style data-mw-deduplicate="TemplateStyles:r2208000">.Lyrics.Lyrics-has-ruby .Lyrics-original,.Lyrics.Lyrics-has-ruby .Lyrics-translated{line-height:2.1}.Lyrics.Lyrics-no-ruby .Lyrics-original,.Lyrics.Lyrics-no-ruby .Lyrics-translated{vertical-align:top}.Lyrics .Lyrics-original,.Lyrics .Lyrics-translated{width:100%;display:inline-block;white-space:pre-wrap}@media all and (max-width:720px){.Lyrics{min-width:100%}}@media all and (min-width:720px){.Lyrics .Lyrics-original,.Lyrics .Lyrics-translated{width:49.85%}}</style>');
        editor.append(
            '<style>' +
            '   #LyricsKaiEditor .Lyrics-original:hover, #LyricsKaiEditor .Lyrics-translated:hover {' +
            '      box-shadow: inset 0px 0px 0.2em #004eff;' +
            '   }' +
            '   #LyricsKaiEditor .Lyrics-line {' +
            '      margin-top: 5px;' +
            '   }' +
            '</style>');

        for (i = 0; i < n; i++) {
            var line = $('<div />');
            line.addClass('Lyrics-line');

            var original_line = $('<div />');
            original_line.addClass('Lyrics-original');
            original_line.attr('contenteditable', 'true');
            original_line.text(original[i] || '');

            var translated_line = $('<div />');
            translated_line.addClass('Lyrics-translated');
            translated_line.attr('contenteditable', 'true');
            translated_line.text(translated[i] || '');

            line.append(original_line);
            line.append(translated_line);
            editor.append(line);
        }
        var close = $('<span />');
        close.text('x');
        close.css({
            'cursor': 'pointer',
            'position': 'absolute',
            'top': '0px',
            'right': '0px',
            'margin': '0px 3px',
            'font-size': '20px'
        });
        close.on('click', function () {
            save();
            container.remove();
        });
        var container = $('<div />')
        container.attr('id', 'LyricsKaiEditor');
        container.css({
            'position': 'fixed',
            'left': '50px',
            'bottom': '50px',
            'top': '50px',
            'right': '50px',
            'width': 'calc(100% - 100px)',
            'height': 'calc(100% - 100px)',
            'padding-top': '20px',
            'box-sizing': 'border-box',
            'box-shadow': '3px 3px 5px',
            'background': 'white'
        });
        container.append(close);
        container.append('<div style="clear:both;"></div>');
        container.append(editor);
        $('body').append(container);

        container.on('keypress', '.Lyrics-original, .Lyrics-translated', function (e) {
            if (e.which == 13) { // enter
                var line = $('<div />');
                line.addClass('Lyrics-line');

                var original_line = $('<div />');
                original_line.addClass('Lyrics-original');
                original_line.attr('contenteditable', 'true');
                original_line.text('');

                var translated_line = $('<div />');
                translated_line.addClass('Lyrics-translated');
                translated_line.attr('contenteditable', 'true');
                translated_line.text('');

                line.append(original_line);
                line.append(translated_line);
                $(this).parent('.Lyrics-line').after(line);
                if ($(this).is('.Lyrics-original')) {
                    original_line.focus();
                } else {
                    translated_line.focus();
                }
                return false;
            }
        });
        container.on('keyup', '.Lyrics-original, .Lyrics-translated', function (e) {
            if (e.which == 38) { // up
                if ($(this).is('.Lyrics-original')) {
                    $(this).parent('.Lyrics-line').prev('.Lyrics-line').find('.Lyrics-original').focus();
                } else {
                    $(this).parent('.Lyrics-line').prev('.Lyrics-line').find('.Lyrics-translated').focus();
                }
            } else if (e.which == 40) { // down
                if ($(this).is('.Lyrics-original')) {
                    $(this).parent('.Lyrics-line').next('.Lyrics-line').find('.Lyrics-original').focus();
                } else {
                    $(this).parent('.Lyrics-line').next('.Lyrics-line').find('.Lyrics-translated').focus();
                }
            }
        })

        function trim(str) {
            return str.replace(/(^\s*)|(\s*$)/g, '');
        }
        function save() {
            var original_new = '';
            var translated_new = '';
            editor.find('.Lyrics-line').each(function () {
                original_new = original_new + '\n' + $(this).find('.Lyrics-original').text();
                translated_new = translated_new + '\n' + $(this).find('.Lyrics-translated').text();
            });
            original_new = trim(original_new);
            translated_new = trim(translated_new);
            var codeContent_new = codeContent.replace(regex, '$1\n' + original_new + '\n$3\n' + translated_new + '\n}}')
            $('#wpTextbox1').val($('#wpTextbox1').val().replace(codeContent, codeContent_new));
        }
    }
});
// </nowiki>