打开/关闭菜单
Toggle preferences menu
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

MediaWiki:Gadget-tikuInlineEditModule.js

MediaWiki界面页面
Cirno.9讨论 | 贡献2023年1月14日 (六) 17:50的版本

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer或Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:Ctrl-F5
editUrl = 'http://dav.medforest.cn/medf/api.php'
editOrigin = 'http://dav.medforest.cn'
function editThis(id){
    $('#'+id).fadeOut(100)
    var data = $('.data')
    var dataLength = data.length
    var singleData = $(data[id]).html()
    var html = singleData
    if($(data[id]).children().length>0){
        $(data[id]).children().each(
            function (id,v) {
                console.log(v)
                var innerHTML = entityToString(v)
                console.log(innerHTML)
                var escape  = ''
                escape = innerHTML.replace(/"/g,'\\"')
                console.log(escape)
                singleData = singleData.replace(innerHTML,escape)
            }
        )
    }
    $(data[id]).html(html)
    console.log(singleData)
    var jsonData = $.parseJSON(singleData)
    console.log(jsonData)
    var o = eval('newInlineEditor('+id+','+JSON.stringify(jsonData)+').'+jsonData.type+'()')
    render(id,jsonData.type,o)
    console.log('加载题目:'+(id+1)+'/'+dataLength)
}
function confirmEdit(id) {
    var pageTitle = $('#firstHeading').text()
    var data = formToJSON('#edit-'+id, true,'s')
    console.log(data)
    var formatedData = formatEditText(data)
    var template = JSONtoTemplate(formatedData)
    console.log(template)
    var pageData = getOriginalText(pageTitle,formatedData.type,formatedData.source, template)
    if(pageData !== false){
        loadModule({before:pageData.inner,after:template})
        uploadEdit(pageTitle, pageData.replacedText, formatedData)
    }

}
function getOriginalText(pageTitle, type, source, editedText) {
    var latestPageData = getLatestPageRevision(editUrl,pageTitle)
    console.log(latestPageData)
    var regMatchInner = new RegExp('(?<=\\{\\{'+type+'型题\\n\\|source='+source+'\\n)[^}}]*(?=\\}\\}?)','g')
    var regMatchFull = new RegExp('(\\{\\{'+type+'型题\\n\\|source='+source+'\\n)[^}}]*(\\}\\})','g')
    var inner = latestPageData.match(regMatchInner)
    var full = latestPageData.match(regMatchFull)
    console.log(inner)
    console.log(full)
    if(inner.length === 1 && full.length === 1){
        latestPageData = latestPageData.replace(regMatchInner, editedText)
        return {full:full[0],inner:inner[0],replacedText:latestPageData}
    }else {
        console.log('匹配到重复内容,请手动处理')
        return false
    }
}
function uploadEdit(pageTitle,data, timuData) {
    var confirmEdit = confirm('即将开始上传编辑,您的编辑会对所有题库用户产生影响,请再次确认您的编辑是否有误。\n感谢您对医林拾薪题库建设的贡献!')
    if(confirmEdit){
        var token = get_token(editUrl,editOrigin)
        editpage_common(false,editUrl,token,pageTitle,data,undefined,'题库|网页内单个题目编辑'
            ,'来自网页内题目的题目编辑,题目类型:'+timuData.type+';题号:'+timuData.source+';题目:'+timuData.title)
    }

}
function loadModule(data) {
    var mask = $('<div id="mask" style="background: #000; position: absolute; left: 0px; top: 0px; width: 100%; filter: alpha(opacity=30); opacity: 0.3; display: none; z-index: 2;"></div>')
    mask.css('height','100%')
    mask.prependTo('body')
    $('#mask').fadeIn(500)
    confirmEditModule(data)
}
function dismissModule() {
    $('#mask').fadeOut(700)
    $('.confirmEditContainer').fadeOut(300)
}
function confirmEditModule(data) {
    if(data.before === undefined){
        data.before = '无内容'
    }else if(data.after === undefined){
        data.after = '无内容'
    }
    var container = $('<div class="confirmEditContainer"></div>')
    var header = $('<div class="confirmEditHeader"><h3>以下为修改结果 请认真耐心检查核对!</h3><hr></div>')
    var changesContainer = $('<div class="changesContainer"></div>')
    var changes = $('<div class="changes"></div>')
    var before = $('<div class="before-edit change"><b>编辑前:</b><br><textarea>'+data.before+'</textarea></div>')
    var after = $('<div class="after-edit change"><b>编辑后:</b><br><textarea>'+data.after+'</textarea></div>')
    var appendix = $('<div class="confirmEditAppendix"><hr></div>')
    var btnSubmit = $('<button id="confirmEditAndSubmit" class="confirmEditBtn button button-primary button-rounded button-small">确认并提交更改</button>')
    var btnCancel = $('<button id="confirmEditDismiss" class="button button-caution button-rounded button-small">关闭本窗口</button>')
    changes.append(before,after)
    changes.appendTo(changesContainer)
    appendix.append(btnCancel,btnSubmit)
    container.append(header,changesContainer,appendix)
    container.prependTo('body')
    $('#confirmEditDismiss').bind('click',function () {
        dismissModule()
    })
    $('#confirmEditAndSubmit').bind('click',function () {
        submitChanges()
        dismissModule()
    })
    var width = container.width()
    var left = ($(window).width()*1-width*1)/2
    container.css('left',left+'px')
    console.log(left)
    $('.confirmEditContainer').fadeIn(500)
}
function formatEditText(json) {
    var result = {}
    var choices = {}
    var title = {}
    var answer = {}
    var explain = {}
    for(var i in json){
        var data = formToJSON(i,true,'t')
        if((result.id&&result.type) === undefined){
            result.id = data.id
            result.type = data.type
            result.source = data.source
        }
    }
    console.log(result)
    var transor = {
        A : function () {
            for(var i in json){
                var data = formToJSON(i,true,'t')
                if(data.key==='choices'){
                    choices[data.value] = json[i]
                }else {
                    result[data.key] = json[i].replace(/\\/g,'\\'+'\\').replace(/"/g,'\\'+'"')
                }
                console.log(data)
            }
            JSON.stringify(choices).match(/(?<=\{)([^}]*)(?=\})/g)
            result.choices = RegExp.$1
            console.log(result)
        },
        X : function () {
            transor.A()
        },
        B:function () {
            for(var i in json){
                var data = formToJSON(i,true,'t')
                eval(data.key+'[data.value] = json[i]')
                console.log(data)
            }
            JSON.stringify(choices).match(/(?<=\{)([^}]*)(?=\})/g)
            result.choices = RegExp.$1
            result.title = arrayToString(dicValueToList(title))
            result.answer = arrayToString(dicValueToList(answer))
            result.explain = arrayToString(dicValueToList(explain))
            console.log(result)
        },
        C:function () {
            transor.B()
        }
    }
    transor[result.type]()

    return result
}
function arrayToString(array){
    var text = ''
    for(var i=0;i<array.length;i++){
        if(i != 0){
            text += ','
        }
        text += '"'+array[i].trim()+'"'
    }
    return text
}
function dicValueToList(obj) {
    var result = []
    for(var i in obj){
        result.push(obj[i])
    }
    return result
}
function formToJSON(selector,decode,mode) {
    var result = {}
    var data = ''
    if(mode === 's'){
        data = $(selector).serialize()
    }else if(mode === 't'){
        data = selector
    }

    console.log(data)
    var dataSplitted = data.split('&')
    for (var i=0;i<dataSplitted.length;i++){
        var value = dataSplitted[i].split('=')[1]
        var key = dataSplitted[i].split('=')[0]
        if(decode===true){
            key = decodeURIComponent(key)
            value = decodeURIComponent(value)
        }
        result[key] = value
    }
    return result
}
function JSONtoTemplate(json, templateName) {
    var order = ['inputbox','sourceRange','title','choices','answer','explain','info']
    // var result = '{{'+templateName +'\n'
    var result = ''
    for(var i=0;i<order.length;i++){
        if (json[order[i]]!==undefined){
            result += '|' + order[i] + '=' + json[order[i]].replace('\n') + '\n'
        }
    }
    // result += '}}\n\n'
    return result
}
function newInlineEditor(id,json,hideButton,addHr,parent){
    parent = parent !== undefined ? parent : ''
    if(addHr===undefined){addHr=true}
    if(hideButton===undefined){hideButton=false}
    var type = json.type
    var o = new Object()
    o.temp = {
        main:$('<form id="edit-'+id+'" class="type'+type+' timuEditContainer"></form>'),
        subject:$('<div class="subject"></div>'),
        range:$('<div class="sourceRange"></div>'),
        info:$('<textarea name="id='+id+'&source='+json.source+'&type='+type+'&key=info" class="info oo-ui-inputWidget-input"></textarea>'),
        titleCon:$('<div class="titleContainer"></div>'),
        source:$('<p class="source"></p>'),
        title:$('<textarea name="id='+id+'&source='+json.source+'&type='+type+'&key=title" class="title-edit oo-ui-inputWidget-input" ></textarea>'),
        options:$('<div class="options"></div>'),
        btn:$('<button class="mw-htmlform-submit" id="showSingle-' + id + '">确认更改</button>'),
        ansCon:$('<div id="ansContainer" class="ansContainer"></div>'),
        correct:$('<p style="display:inline;"><b>正确答案:</b></p><textarea name="id='+id+'&source='+json.source+'&type='+type+'&key=answer" class="correctAnswer oo-ui-inputWidget-input"></textarea><br>'),
        explain:$('<p style="display:inline;"><b>解析: </b></p><textarea name="id='+id+'&source='+json.source+'&type='+type+'&key=explain" class="explain oo-ui-inputWidget-input"></textarea><br>'),
        select:$('<select class="button-small button-rounded button"></select>'),
        subTitle:$('<div id=""></div>')
    }
    o.hideButton = hideButton
    o.parent = parent
    if(type!=='A3'&&type!=='PD'){
        o.temp.btn.bind("click",function (){
            confirmEdit(id)
        })
    }

    o.A = function () {
        this.temp.source.text(json.source)
        this.temp.title.html(json.title)
        this.temp.correct.nextAll('.correctAnswer').val(json.answer)
        this.temp.explain.nextAll('.explain').val(json.explain)
        var options = formatAnsDic(json.choices)
        for(var k in options) {
            var label = '<label id="' + k + '">'+k+':<input class="oo-ui-inputWidget-input" name="id='+id+'&source='+json.source+'&type='+type+'&key=choices&value='+ k +'"  class="options-edit" type="text" value="' + options[k] + '" /></label>'
            this.temp.options.append(label)
        }
        this.temp.titleCon.append(this.temp.source,this.temp.title)
        this.temp.ansCon.append(this.temp.correct,this.temp.explain)
        this.temp.subject.append(this.temp.titleCon,this.temp.options)
        this.temp.main.append(this.temp.subject,this.temp.ansCon)
        this.temp.main = $('<div></div>').append(this.temp.main,this.temp.btn)
        if(addHr){this.temp.main.append('<hr>')}
        console.log(this.temp.main)
        return this.temp.main
    }
    o.A3 = function () {
        var subIDs = []
        var s = json.source*1;var e = json.source*1+json.sourceRange*1 -1
        this.temp.range.text('第 '+s+' 到 '+e+' 题')
        for(var i=0;i<json.title.length;i++){
            subIDs.push(id+'-'+i)
            if(json.explain[i]==undefined){
                json.explain[i] = '暂无解析'
            }
            var data = {
                "type":"A",
                "source":json.source+'-'+(i+1),
                "title":json.title[i],
                "answer":json.answer[i],
                "explain":json.explain[i],
                "choices":json.choices[i],
            }
            var newA = newTimu(id+'-'+i,data,true,false).A()
            render(id+'-'+i,'A',newA,this.temp.titleCon)
        }
        o.temp.btn.bind("click",function (){
            showChoiceAnswer(subIDs,type,json.answer)
        })
        this.temp.info.text(json.info)
        this.temp.subject.append(this.temp.range,this.temp.info,this.temp.titleCon)
        if(!hideButton){this.temp.main.append(this.temp.btn)}
        this.temp.main.append(this.temp.subject)

        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    o.B = function () {
        var s = json.source*1;var e = json.source*1+json.sourceRange*1 -1
        this.temp.range.text('第 '+s+' 到 '+e+' 题')

        var options = formatAnsDic(json.choices)
        for(var k in options){
            var label = '<li id="'+k+'">'+k+':<input class="oo-ui-inputWidget-input" name="id='+id+'&source='+json.source+'&type='+type+'&key=choices&value='+ k +'"  class="options-edit" type="text" value="' + options[k] + '" /></li>'
            this.temp.options.append(label)
            this.temp.select.append('<option value="'+k+'">'+k+'</option>')
        }
        for(var i=0;i<json.title.length;i++){
            var reg1 = /\(\)/g
            var text = '<textarea name="id='+id+'&source='+json.source+'&type='+type+'&key=title&value='+i+'" class="title-edit oo-ui-inputWidget-input" >'+json.title[i]+'</textarea>'
            this.temp.subTitle.attr('id',id+'-'+i)
            this.temp.source.text(s+i)
            this.temp.subTitle.html(this.temp.source.prop("outerHTML")+text)
            this.temp.titleCon.append(this.temp.subTitle.prop("outerHTML"))
        }
        var correctAnsEditor = $('<div class="correctAnsEditor"><p>编辑答案</p></div>')
        for(var i=0;i<json.answer.length;i++){
            correctAnsEditor.append('<span>'+(s+i)+':'+'<input name="id='+id+'&source='+json.source+'&type='+type+'&key=answer&value='+i+'" value="'+json.answer[i]+'"></span><br>')
        }
        this.temp.correct = correctAnsEditor
        var explain = $('<div class="correctExpEditor"><p>编辑解释</p></div>')
        for(var i=0;i<json.explain.length;i++){
            explain.append('<span>'+(s+i)+':'+'<textarea class="title-edit oo-ui-inputWidget-input" name="id='+id+'&source='+json.source+'&type='+type+'&key=explain&value='+i+'">'+json.explain[i]+'</textarea></span><br>')
        }
        this.temp.explain = explain

        this.temp.subject.append(this.temp.range,this.temp.options,this.temp.titleCon)

        this.temp.ansCon.append(this.temp.correct,this.temp.explain)
        this.temp.main.append(this.temp.subject,this.temp.ansCon)
        this.temp.main = $('<div></div>').append(this.temp.main,this.temp.btn)
        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    o.C = function () {
        var s = json.source*1;var e = json.source*1+json.sourceRange*1 -1
        this.temp.range.text('第 '+s+' 到 '+e+' 题')

        var options = formatAnsDic(json.choices)
        for(var k in options){
            var label = '<li id="'+k+'">'+k+':<input class="oo-ui-inputWidget-input" name="id='+id+'&source='+json.source+'&type='+type+'&key=choices&value='+ k +'"  class="options-edit" type="text" value="' + options[k] + '" /></li>'
            this.temp.options.append(label)
            this.temp.select.append('<option value="'+k+'">'+k+'</option>')
        }
        for(var i=0;i<json.title.length;i++){
            var reg1 = /\(\)/g
            var text = '<textarea name="id='+id+'&type='+type+'&source='+json.source+'&key=title&value='+i+'" class="title-edit oo-ui-inputWidget-input" >'+json.title[i]+'</textarea>'
            this.temp.subTitle.attr('id',id+'-'+i)
            this.temp.source.text(s+i)
            this.temp.subTitle.html(this.temp.source.prop("outerHTML")+text)
            this.temp.titleCon.append(this.temp.subTitle.prop("outerHTML"))
        }
        var correctAnsEditor = $('<div class="correctAnsEditor"><p>编辑答案</p></div>')
        for(var i=0;i<json.answer.length;i++){
            correctAnsEditor.append('<span>'+(s+i)+':'+'<input name="id='+id+'&type='+type+'&source='+json.source+'&key=answer&value='+i+'" value="'+json.answer[i]+'"></span><br>')
        }
        this.temp.correct = correctAnsEditor
        var explain = $('<div class="correctExpEditor"><p>编辑解释</p></div>')
        for(var i=0;i<json.explain.length;i++){
            explain.append('<span>'+(s+i)+':'+'<textarea class="title-edit oo-ui-inputWidget-input" name="id='+id+'&source='+json.source+'&type='+type+'&key=explain&value='+i+'">'+json.explain[i]+'</textarea></span><br>')
        }
        this.temp.explain = explain
        this.temp.subject.append(this.temp.range,this.temp.titleCon,this.temp.options)
        this.temp.ansCon.append(this.temp.correct,this.temp.explain)
        this.temp.main.append(this.temp.subject,this.temp.ansCon)
        this.temp.main = $('<div></div>').append(this.temp.main,this.temp.btn)
        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    o.X = function () {
        this.temp.source.text(json.source)
        this.temp.title.text(json.title)
        this.temp.correct.nextAll('.correctAnswer').text(json.answer)
        this.temp.explain.nextAll('.correctAnswer').text(json.explain)
        var options = formatAnsDic(json.choices)
        for(var k in options){
            var label = '<label id="' + k + '">'+k+':<input class="oo-ui-inputWidget-input" name="id='+id+'&source='+json.source+'&type='+type+'&key=choices&value='+ k +'"  class="options-edit" type="text" value="' + options[k] + '" /></label>'
            this.temp.options.append(label)
        }

        this.temp.titleCon.append(this.temp.source,this.temp.title)
        this.temp.ansCon.append(this.temp.correct,this.temp.explain)
        this.temp.subject.append(this.temp.titleCon,this.temp.options)
        this.temp.main.append(this.temp.subject,this.temp.ansCon)
        this.temp.main = $('<div></div>').append(this.temp.main,this.temp.btn)
        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    o.PD = function () {
        this.temp.source.text(json.source)
        this.temp.title.text(json.title)
        this.temp.explain.nextAll('.correctAnswer').text(json.explain)
        var ans = ''
        if(json.answer=='T' || json.answer=='正确' || json.answer=='1' || json.answer=='√'){
            ans = '正确'
        }else if(json.answer=='F' || json.answer=='错误' || json.answer=='0' || json.answer=='×'){
            ans = '错误'
        }
        this.temp.correct.nextAll('.correctAnswer').text(ans)
        o.temp.btn.bind("click",function (){
            showChoiceAnswer(id,'A',ans)
        })
        this.temp.options.append('<label id="正确" style="display: inline;"><input name="singelChoice-'+id+'" type="radio" value="正确" />正确</label>' +
            '<label id="错误" style="display: inline;"><input name="singelChoice-'+id+'" type="radio" value="错误" />错误</label>')
        this.temp.titleCon.append(this.temp.source,this.temp.title)
        this.temp.ansCon.append(this.temp.correct,this.temp.explain)
        this.temp.subject.append(this.temp.titleCon,this.temp.options)
        if(!hideButton){this.temp.main.append(this.temp.btn)}
        this.temp.main.append(this.temp.subject,this.temp.ansCon)

        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    o.TK = function () {
        this.temp.source.text(json.source)
        var form = $('<form id="form-'+id+'" class="title"></form>')
        var pos = json.pos
        var posReg = new RegExp(pos,'g')
        var posCount = json.title.match(posReg).length
        for(var i=0;i<posCount;i++){
            json.title = json.title.replace(pos,'<input name="'+id+'-'+i+'" id="'+id+'-'+i+'" type="text" form="form-'+id+'"/>')
        }
        form.html(json.title)
        this.temp.title.text(json.title)
        this.temp.correct.nextAll('.correctAnswer').text(json.answer)
        this.temp.explain.nextAll('.correctAnswer').text(json.explain)

        this.temp.titleCon.append(this.temp.source,form)
        this.temp.ansCon.append(this.temp.correct,this.temp.explain)
        this.temp.subject.append(this.temp.titleCon,this.temp.options)
        if(!hideButton){this.temp.main.append(this.temp.btn)}
        this.temp.main.append(this.temp.subject,this.temp.ansCon)

        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    o.MJ = function () {
        this.temp.source.text(json.source)
        this.temp.title.html(json.title + ':<span class="blur" tabindex="0" style="display:inline;outline=0;" onclick="">' + json.answer +'</span>')
        this.temp.titleCon.append(this.temp.source,this.temp.title)
        this.temp.subject.append(this.temp.titleCon,this.temp.options)
        this.temp.main.append(this.temp.subject)

        if(addHr){this.temp.main.append('<hr>')}
        return this.temp.main
    }
    return o
}

//获取某个页面的历史版本
function getPageRevision(url, title, pageCount){
    pageCount = pageCount !== undefined ? pageCount :1
    var PARAMS = {
        "action": "query",
        "format": "json",
        "prop": "revisions",
        "titles": title,
        "utf8": 1,
        "rvprop": "content",
        "rvlimit": pageCount,
        "rvdir": "older",
        'origin':'*',
    }
    var isSuccess = {}
    $.ajax(
        {
            url: url,
            method: "post",
            async: false,
            data: PARAMS,
            timeout: 5000,
            success: function (results){
                if('-1' in results.query.pages){
                    console.log('===无此页面===')
                    isSuccess = {isSuccess:false, result:results}
                }else {
                    isSuccess = {isSuccess:true, result:results}
                }
            }
        })
    return isSuccess
}
function getLatestPageRevision(url, title) {
    var pages = getPageRevision(url,title,1)
    if (pages.isSuccess) {
        pages = pages.result.query.pages
        for (var key in pages) {
            var page = pages[key].revisions[0]['*']
        }
        return page
    }else {
        return false
    }
}

//编辑页面
function editpage_common(async,url,token,title, content,model,tags,summary,message) {
    async = async !== undefined ? async:true
    model = model !== undefined ? model:'wikitext'
    tags = tags !== undefined ? tags:''
    summary = summary !== undefined ? summary:''
    message = message !== undefined ? message:''
    var isSuccess = [false,0]
    var PARAMS = {
        "action": "edit",
        "format": "json",
        "title": title,
        "text": content,
        "token": token,
        'contentmodel':model,
        "summary": summary,
        "tags": tags,
    }
    $.ajax({
        url: url,
        method: "post",
        async: async,
        data: PARAMS,
        timeout: 5000,
        beforeSend:function (){
            processingOn(message)
        },
        success: function (results){
            var apiResult = results['edit']['result']
            if(apiResult=="Success"){
                isSuccess = [true,results["edit"]["result"]]
                console.log("===editpage_common 成功===")
                // newMessage('成功:上传成功','#88F888')
                newToast('上传','now','上传成功!',1000,'<i class="bi bi-cloud-upload"></i>','#88F888')
            }else{
                newToast('错误:上传','now','失败:上传失败(服务端返回错误)',4000,'<i class="bi bi-cloud-upload"></i>','#ffaca6')
                isSuccess = [false,results["edit"]["result"]]
            }
            processingOff()
        },
        error: function (){
            // newMessage('失败:上传失败','#ffaca6')
            newToast('错误:上传','now','失败:上传失败(网络错误)',4000,'<i class="bi bi-cloud-upload"></i>','#ffaca6')
            processingOff()
        }

    })

    return isSuccess
}

//获取token
function get_token(url,origin){
    var isSuccess = [false, '0']
    var PARAMS = {
        "action": "query",
        "format": "json",
        'meta':'tokens',
        'origin':origin,
    }
    $.ajax(
        {
            url: url,
            method: "post",
            async: false,
            data: PARAMS,
            timeout: 5000,
            success: function (results) {
                var token = results.query.tokens.csrftoken
                if(token.length >= 5){
                    isSuccess = {isSuccess:true,token:token}
                }
            }
        })
    return isSuccess
}