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

来自偶像大师中文维基
跳转到导航 跳转到搜索
创建页面,内容为“/* 载入该插件后,将对wikitext语法所使用的符号和html标签进行成对的补全。 该插件并不会计算整个源代码中的html标签配对情况,标签的补全仅发生在输入大于号(>)时,补全距离最近的html标签。 在输入无其他信息的标签后(如:<div></div>),若按下退格(backspace)键,可以直接删除这一组标签。 注意:因为每次输入时都会对整个源代码进行查找匹…”
 
无编辑摘要
 
(未显示同一用户的4个中间版本)
第1行: 第1行:
/*
/**
载入该插件后,将对wikitext语法所使用的符号和html标签进行成对的补全。
* When you need to load multiple scripts and css from wiki pages at the same time,
该插件并不会计算整个源代码中的html标签配对情况,标签的补全仅发生在输入大于号(>)时,补全距离最近的html标签。
  * please use the `/load.php?modules=wiki:PageName` combination instead of multiple `action=raw` requests.
在输入无其他信息的标签后(如:<div></div>),若按下退格(backspace)键,可以直接删除这一组标签。
*
注意:因为每次输入时都会对整个源代码进行查找匹配,为了防止卡顿,默认限制为500个字符,但这会导致当标签过长(例如在节点上添加了大量css代码)时,无法自动补全。
* @example
过长的源代码会使输入时性能大幅下降,造成卡顿。当总字符数大于20000时,将自动关闭补全,请合理使用段落编辑的功能。
* ```
*/
* // before:
   
* mw.loader.load( "/index.php?action=raw&ctype=text/javascript&title=SomeScripts.js" );
$(function(){
* mw.loader.load( "/index.php?action=raw&ctype=text/css&title=SomeStyles.css", "text/css" );
console.log("Loaded")
* // after:
    if(/action=(edit|submit)/.test(location.href)){
* mw.loader.load( "/load.php?modules=wiki:SomeScripts.js|wiki:SomeStyles.css" );
    var wpText = $('#wpTextbox1')
* ```
    console.log(wpText.val)
*/
    if(wpText.val().length > 20000){
/**
    mw.notify('因源代码过长,补全功能被关闭!', { type : 'warn' })
* 在编辑时,对{{LyricsKai}}提供一个编辑窗口,原文与翻译并排排列,再进行翻译等工作无需滚动页面查看原文,方便编辑。
    return
* 默认匹配第一个出现个的{{LyricsKai}},如需匹配其他请使用鼠标选中相应代码。
    }
* 很可能有bug,提交前请预览。
   
*/
var retrospect = 500
// <nowiki>
var pattern = [
$(function () {
['-{', '}-'],
    if (mw.config.values.wgAction == "edit" || mw.config.values.wgAction == "submit") {
['[', ']'],
        var btn = $('<li class="mw-list-item"><a title="LyricsKai可视化编辑">歌词编辑</a></li>');
['{', '}'],
        btn.click(showLyricsKaiEditor);
["'", "'"],
        $('#p-cactions ul').append(btn);
['"', '"'],
['(', ')'],
['<!--', '-->']
]
    //光标后插入信息
    function insertText(obj, str){
var content = obj.value,
position = obj.selectionEnd,
left = content.substring(0, position),
right = content.substring(position)
obj.value = left + str + right
    }
var original = null
wpText.one('click', function(){
original = {
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
}
})
    // 缓存输入内容 & 判断
var end = 0,
thisLength = 0,
lastLength = 0,
code = '',
thisCode = '',
deletedKeyword = '',
// 需要暂停补全的状态
typewritingMode = false,
cutPaste = false,
selectInput = false,
selectDelete = false,
inputFinish = false
var codeSave = [{
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
}],
inputMark = false
    function selectionReset(){
        end = wpText[0].selectionEnd
        lastLength = wpText.val().length
}
    wpText.click(function(){
        selectionReset()
    }).keyup(function(e){
        if(e.keyCode > 36 && e.keyCode < 41){
            selectionReset()
            code = ''
        }
    }).on('keydown keyup', function(e){
if(e.keyCode == 8){
var subStart = (this.selectionEnd - 1) < 0 ? 0 : (this.selectionEnd - 1)
var left = thisCode.substring(subStart, this.selectionEnd)
deletedKeyword = left
selectionReset()
}
}).on('compositionstart', function(){
typewritingMode = true
}).on('compositionend', function(){
typewritingMode = false
            inputFinish = true
            $(this).trigger('input')
            selectionReset()
}).on('cut paste', function(){
cutPaste = true
codeSave.push({
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
})
inputMark = false
setTimeout(selectionReset, 0)
}).on('keydown', function(e){
selectInput = !! document.getSelection().toString()
if(selectInput){ end = wpText[0].selectionStart}
if(selectInput && (e.keyCode == 8 || e.keyCode == 46)){ selectDelete = true }
}).on('input', function(){
;(function(_this){
                if(typewritingMode){ return }
                if(inputFinish){ inputFinish = false; return }
if(cutPaste){ cutPaste = false; return }
if(selectDelete){ selectDelete = false; return }
        thisCode = $(_this).val()
        var right = thisCode.substring(end)
        thisLength = $(_this).val().length
        if(thisLength - lastLength == 1 || selectInput){
code += right.substring(0, 1)
        }else{
            code = ''
           
            if(lastLength - thisLength == 1){
            var subStart = (_this.selectionEnd - 20) < 0 ? 0 : (_this.selectionEnd - 20),
            subEnd = (_this.selectionEnd + 20) > thisLength ? thisLength : (_this.selectionEnd + 20)
           
            var subLeft = thisCode.substring(0, subStart),
            subRight = thisCode.substring(subEnd)
           
            var left = thisCode.substring(subStart, _this.selectionEnd),
            right = thisCode.substring(_this.selectionEnd, subEnd),
            leftRE = /([\s\S]*)<(.+)$/,
rightRE = /^\<\/(.+?)>([\s\S]*)/
            var tagLeft = left.replace(leftRE, '$2')
var tagRight = right.replace(rightRE, '$1')
            if(tagLeft == tagRight){
            var leftCode = left.replace(leftRE, '$1')
            var rightCode = right.replace(rightRE, '$2')
            $(_this).val(subLeft + leftCode + rightCode + subRight)
            var cursorPos = new String(subLeft + leftCode).length
            _this.selectionStart = _this.selectionEnd = cursorPos
            }
$.each(pattern, function(){
var $this = wpText[0]
if(lastLength - thisLength == 1){
var subStart = $this.selectionEnd < 0 ? 0 : $this.selectionEnd
var subEnd = ($this.selectionEnd + 1) > thisLength ? thisLength : ($this.selectionEnd + 1)
$this.selectionEnd == subEnd && subEnd++
var subLeft = thisCode.substring(0, $this.selectionEnd),
subRight = thisCode.substring(subEnd)
var left = thisCode.substring(subStart, $this.selectionEnd),
right = thisCode.substring($this.selectionEnd, subEnd)
if(deletedKeyword == this[0] && right == this[1]){
$($this).val(subLeft + subRight)
$this.selectionStart = $this.selectionEnd = subLeft.length
selectionReset()
}
}
})
            }
           
        }
        function pair(keyword, char, num){
            if(code.indexOf(keyword) != -1){
var num = num || char.length
var position = wpText[0].selectionEnd
                insertText(wpText[0], char)
                wpText[0].selectionStart = wpText[0].selectionEnd = position
                selectionReset()
                code = ''
            }
        }
 
        function addPair(arr){
        $.each(arr, function(){
pair(this[0], this[1], this[2])
})
        }
            selectionReset()
        addPair(pattern)
           
// 配对标签
            if(code.indexOf('>') != -1){
            var start = (end - retrospect) < 0 ? 0 : (end - retrospect)
                var left = wpText.val().substring(start, end)
                var ptn = /[\s\S]*<((?!br|hr|img|references|templatestyles|\!--|\/|\>)[^\s<>]+)[^>]*?>$/
                if(ptn.test(left)){
var tagEnd = '</' + left.replace(ptn, '$1') + '>'
var position = wpText[0].selectionEnd
                    insertText(wpText[0], tagEnd)
                wpText[0].selectionStart = wpText[0].selectionEnd = position
                    selectionReset()
                    code = ''                       
                }                
            }
})(this)
           
codeSave.push({
code : wpText.val(),
start : wpText[0].selectionStart,
end : wpText[0].selectionEnd
})
inputMark = true           
input = false
})
wpText.on('keydown', function(e){
if(e.ctrlKey && e.keyCode == 90){
e.preventDefault()
if(inputMark){
codeSave.pop()
inputMark = false
}
var history = codeSave.pop() || original
if(history){
wpText.val(history.code).focus()
wpText[0].selectionStart = history.start
wpText[0].selectionEnd = history.end
}
}
})
     }
     }
})
 
    function showLyricsKaiEditor() {
        var textbox = document.getElementById('wpTextbox1');
        var regex = /(\{\{[Ll]yrics[\s\S]*?\|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>

2025年10月19日 (日) 20:47的最新版本

/**
 * 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 class="mw-list-item"><a title="LyricsKai可视化编辑">歌词编辑</a></li>');
        btn.click(showLyricsKaiEditor);
        $('#p-cactions ul').append(btn);
    }

    function showLyricsKaiEditor() {
        var textbox = document.getElementById('wpTextbox1');
        var regex = /(\{\{[Ll]yrics[\s\S]*?\|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>