<div class="BCBT">
<div class="title">
<span>从Excel中复制粘贴↓</span>
<div class="modeOption">
模式:
<label><input type="radio" name="bcbtMode" value="text" checked><b>新建</b>页面/<b>覆盖</b>已有页面</label>
<label><input type="radio" name="bcbtMode" value="prependtext">在页面<b>开头</b>追加内容</label>
<label><input type="radio" name="bcbtMode" value="appendtext">在页面<b>末尾</b>追加内容</label>
</div>
</div>
<textarea class="input"></textarea>
<div class="display row"></div>
<button class="submit">提交</button>
</div>
<style>
.BCBT .title {
display: flex;
}
.BCBT .title .modeOption {
margin-left: 2em;
display: flex;
}
.BCBT .title .modeOption {
margin-left: 2em;
}
.BCBT .title .modeOption label {
margin-right: 0.5em;
font-weight: normal;
}
.BCBT .display pre.created {
background: #5CB85C;
}
.BCBT .input {
width: 100%;
height: 300px;
}
.BCBT .submit, .BCBT .reset {
padding: 0.5em 1em;
}
</style>
<script>class BCBT {
state = "ready"
option = {
mode: "text"
}
data = {
template: "",
key: [],
page: {},
}
promise = Promise.resolve()
constructor(dom, wiki) {
this.dom = $(dom)
this.dom.data("BCBT", this)
this.wiki = wiki || mw.config.values.wgScriptPath
}
update() {
this.parse()
let $display = this.dom.find(".display")
$display.empty()
for (let key in this.data.page) {
let $pre = $(`<pre class="col-md-3" data-title="${encodeURIComponent(key)}">`)
$pre.append(`[[
${key}]]`)
$pre.append("<hr>")
$pre.append(this.stringify(`${key}`).replace(new RegExp(`^{{${this.data.template}\n`), `{{
${this.data.template}\n`))
$display.append($pre)
}
}
parse() {
let text = this.dom.find(".input").val()
let pages = text.split("\n")
let key = pages.shift().split("\t")
key.forEach((e, i, a) => {
a[i] = e.trim()
})
this.data.template = key.shift()
this.data.key = key
this.data.page = {}
pages.forEach((e) => {
let value = e.split("\t")
value.forEach((e, i, a) => {
a[i] = e.trim()
})
let page = value.shift()
if (!page) {
return
}
this.data.page[page] = value
})
}
stringify(page) {
let str = `{{${this.data.template}`
this.data.key.forEach((e, i) => {
str += `\n|${e ? `${e}=` : ""}${this.data.page[page][i] || ""}`
})
str += "\n}}"
return str
}
submit() {
this.state = "busy"
this.dom.find(".input,.modeOption input").attr("disabled", true)
let url = `https://wiki.biligame.com${this.wiki}/api.php`
for (let key in this.data.page) {
this.promise = this.promise.finally(() => {
return new Promise((resolve, reject) => {
checkToken().then((token) => {
$.ajax({
url: url,
type: "POST",
data: {
token: token,
action: "edit",
title: key,
summary: "通过批量创建工具BCBT创建/编辑",
[this.option.mode]: this.stringify(key)
},
success: () => {
$.get(`${this.wiki}${decodeURI(key)}`, () => {
this.dom.find(`.display pre[data-title="${encodeURIComponent(key)}"]`).addClass("created")
resolve()
})
}
})
})
})
})
}
this.promise = this.promise.finally(() => {
if (confirm("创建完毕,是否重置?")) {
this.reset()
} else {
this.dom.find(".submit")
.removeClass("submit")
.addClass("reset")
.html("重置")
}
})
function checkToken() {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
type: "GET",
data: {
action: "query",
meta: "tokens",
format: "json"
},
success(data) {
resolve(data.query.tokens.csrftoken)
}
})
})
}
}
reset() {
this.state = "ready"
this.dom.find(".input,.modeOption input").attr("disabled", false)
this.dom.find(".input").val("")
this.update()
this.dom.find(".reset")
.removeClass("reset")
.addClass("submit")
.html("提交")
}
}
window.addEventListener("load", () => {
$(() => {
let bcbt = $(".BCBT")
if (mw.config.get('wgUserGroups').indexOf("sysop") === -1) {
bcbt.html("你无权使用这个功能。")
return
}
bcbt.each((i, e) => {
new BCBT(e)
})
$(document).on("input", ".BCBT .input", function () {
$(this).closest(".BCBT").data("BCBT").update()
})
$(document).on("input", `.BCBT .modeOption input[name="bcbtMode"]`, function () {
$(this).closest(".BCBT").data("BCBT").option.mode = $(this).val()
})
$(document).on("click", `.BCBT .submit`, function () {
let bcbt = $(this).closest(".BCBT").data("BCBT")
if (bcbt.state === "ready" && confirm("真的确认了吗?")) {
bcbt.submit()
}
})
$(document).on("click", `.BCBT .reset`, function () {
$(this).closest(".BCBT").data("BCBT").reset()
})
})
})
</script>