ผู้ใช้:Bebiezaza/iScript/modules/revert.js
< ผู้ใช้:Bebiezaza | iScript
หมายเหตุ: หลังเผยแพร่ คุณอาจต้องล้างแคชเว็บเบราว์เซอร์ของคุณเพื่อดูการเปลี่ยนแปลง
- ไฟร์ฟอกซ์ / ซาฟารี: กด Shift ค้างขณะคลิก Reload หรือกด Ctrl-F5 หรือ Ctrl-R (⌘-R บนแมค)
- กูเกิล โครม: กด Ctrl-Shift-R (⌘-Shift-R บนแมค)
- อินเทอร์เน็ตเอกซ์พลอเรอร์ และ Edge: กด Ctrl ค้างขณะคลิก Refresh หรือกด Ctrl-F5
- โอเปร่า: กด Ctrl-F5
// ========================================================
// สคริปต์จัดให้: revert module
//
// Copyright (C) 2006-2022, Jutiphan Mongkolsuthree
// 2021-2022, Bebiezaza
// Certain functions are copyrighted by their
// respective copyright holders
//
// Created: 25/02/2007
// Rewritten: 28/10/2021
// Replaced: original twinklefluff
//
// Additional Credits Information:
// ==============================================================
// Original code taken from Wikipedia:WikiProject User scripts/Scripts/Twinkle
// [[User:AzaToth/twinklefluff.js]]
// ========================================================
/* <pre><nowiki> */
var revertWhitelist = ['BotKung', 'TBot', 'JBot', 'NongBot', 'Chobot', 'Escarbot', 'Idioma-bot', 'Nullzerobot', 'Robbot', 'RoboDick', 'SieBot', 'Thijs!bot', 'TuvicBot', 'VolkovBot', 'YurikBot', 'Zwobot', 'InternetArchiveBot'];
function getRevNotice(state, text, error) {
var gettingRev = "กำลังดึงข้อมูลรุ่นก่อนหน้านี้";
if (error) {
if (text) return mw.notify($("<b><span class='" + state + "'>" + gettingRev + ": " + text + "</span></b>"), { tag: 'twinkle_revert_state' });
else return mw.notify($("<b><span class='" + state + "'>" + gettingRev + "</span></b>"), { tag: 'twinkle_revert_state' });
} else {
if (text) return mw.notify($("<span class='" + state + "'>" + gettingRev + ": " + text + "</span>"), { tag: 'twinkle_revert_state' });
else return mw.notify($("<span class='" + state + "'>" + gettingRev + "</span>"), { tag: 'twinkle_revert_state' });
}
}
function getCurrentRevInfo(pageName) {
var info;
$.ajax({
url: mw.util.wikiScript('api'),
dataType: 'json',
async: false,
data: {
format: 'json',
action: 'query',
prop: 'revisions',
indexpageids: true,
titles: pageName,
rvprop: 'ids',
rvslots: 'main'
},
success: function(data) {
var id = data.query.pageids[0];
if (id == -1) {
info = "";
} else {
info = {
revid: data.query.pages[id].revisions[0].revid,
};
}
}
});
return info;
}
// this is the first place to get experimental asynchronous API call
function getRevertInfo(revID) {
var api = new mw.Api();
return api.get({
action: 'query',
prop: 'revisions',
indexpageids: true,
revids: revID,
rvprop: 'ids|user|content',
rvslots: 'main'
}).then(function(data) {
var info;
var id = data.query.pageids[0];
if (id == -1) {
info = "";
} else {
info = {
title: data.query.pages[id].title,
revid: data.query.pages[id].revisions[0].revid,
user: data.query.pages[id].revisions[0].user,
content: data.query.pages[id].revisions[0].slots.main['*']
};
}
return info;
});
}
function getRollbackInfo(pageName) {
var info = [];
$.ajax({
url: mw.util.wikiScript('api'),
dataType: 'json',
async: false,
data: {
format: 'json',
action: 'query',
prop: 'revisions',
indexpageids: true,
titles: pageName,
rvprop: 'ids|user',
rvlimit: 50
},
success: function(data) {
var id = data.query.pageids[0];
if (id == -1) {
info = "";
} else {
for (var i in data.query.pages[id].revisions) {
var parser = {
revid: data.query.pages[id].revisions[i].revid,
user: data.query.pages[id].revisions[i].user
};
info.push(parser);
}
}
}
});
return info;
}
function revertPage(pageName, editedText, summary, isMinor, willReload, undoRev, undoafterRev) {
var api = new mw.Api();
api.postWithEditToken({
action: "edit",
title: pageName,
summary: summary,
text: editedText,
minor: isMinor,
nocreate: true,
undo: undoRev, // the newer revision
undoafter: undoafterRev // the older revision
}).done(function(a, b) {
mw.log("Saved successfully");
if (willReload) {
mw.notify($("<span class='revert_status_confirm'><b>ดำเนินการย้อนเรียบร้อยแล้ว</b> กำลังรีโหลดหน้าใหม่...</span>"), { tag: 'twinkle_revert_editing' });
window.setTimeout(function() {
// window.location = Morebits.wiki.actionCompleted.redirect;
location.reload();
}, 5000);
} else {
mw.notify($("<span class='revert_status_confirm'><b>ดำเนินการย้อนเรียบร้อยแล้ว</b></span>"), { tag: 'twinkle_revert_editing' });
}
}).fail(function(a, b) {
if (a === "http") {
mw.log("HTTP error: " + b.textStatus);
mw.notify($("<span class='revert_status_warn'>ขออภัย พบเจอปัญหาทำให้ไม่สามารถบันทึกได้: " + b.textStatus + " กรุณาลองใหม่อีกครั้ง</span>"));
} else if (a === "ok-but-empty") {
mw.log("Got an empty response from the server");
mw.notify($("<span class='revert_status_warn'>ขออภัย พบเจอปัญหาทำให้ไม่สามารถทำเรื่องได้ กรุณาลองใหม่อีกครั้ง</span>"));
} else {
mw.log("API error: " + a);
mw.notify($("<span class='revert_status_warn'>ขออภัย พบเจอปัญหาทำให้ไม่สามารถบันทึกได้: " + a + " กรุณาลองใหม่อีกครั้ง</span>"));
}
});
}
function revertToRevision(diffVersion) {
if (diffVersion === "old") var link = document.querySelector("#mw-diff-otitle1 a").href;
else if (diffVersion === "new") var link = document.querySelector("#mw-diff-ntitle1 a").href;
else return mw.notify($("<span class='revert_status_warn'>พบข้อผิดพลาดที่ไม่คาดคิด ยกเลิกการย้อน<br>กรุณาตรวจสอบและลองใหม่อีกครั้ง</span>"));
getRevNotice('revert_status_status', "");
var revID = link.slice(link.lastIndexOf("oldid") + 6);
getRevertInfo(revID).then(function(revertInfo) {
var currentRevInfo = getCurrentRevInfo(mw.config.get('wgPageName'));
if (revID != revertInfo.revid) return getRevNotice('revert_status_warn', "พบข้อผิดพลาด รุ่นที่ดึงข้อมูลมา ไม่ตรงกับรุ่นที่ต้องการ ยกเลิกการย้อน", true);
var reason = prompt("กรุณาระบุสาเหตุที่ต้องการย้อนการแก้ไข (เว้นว่างหากไม่ระบุ): ", ""); // padded out to widen prompt in Firefox
if (reason === null) return getRevNotice('revert_status_warn', "ยกเลิกการย้อนกลับโดยผู้ใช้", true);
var userInfo = "[[Special:Contributions/" + revertInfo.user + "|" + revertInfo.user + "]] ([[User talk:" + revertInfo.user + "|พูดคุย]])";
var summary = "ย้อนกลับไปรุ่นที่ " + revID + " โดย " + userInfo + " " + iScriptConfig.Tagline;
if (reason) summary += ": " + reason;
// push source
getRevNotice('revert_status_confirm', "สำเร็จ");
mw.notify($("<span class='revert_status_status'>กำลังบันทึกข้อมูล...</span>"), { tag: 'twinkle_revert_editing' });
revertPage(revertInfo.title, revertInfo.content, summary, false, false, currentRevInfo.revid, revertInfo.revid);
});
}
function rollback(type) {
var pageName = mw.config.get('wgPageName');
var currentRevID = mw.config.get('wgCurRevisionId');
getRevNotice('revert_status_status', "");
var rollbackInfo = getRollbackInfo(pageName);
var currentRevInfo = getCurrentRevInfo(pageName);
if (rollbackInfo.length < 1) return getRevNotice('revert_status_warn', "ข้อผิดพลาด: ไม่มีรุ่นก่อนหน้านี้ให้ย้อนกลับได้ จึงไม่สามารถดำเนินการได้ ยกเลิกการย้อน", true);
if (currentRevID < rollbackInfo[0].revid) return mw.notify($("<b><span class='revert_status_warn'>ข้อผิดพลาด: เนื่องจากว่ารุ่น <strong>" + currentRevID + "</strong> ที่ต้องการย้อนนั้นไม่ใช่รุ่นล่าสุด ซึ่งอาจถูกลบไปแล้ว หรือมีปัญหาการเชื่อมต่อ กรุณาตรวจสอบและลองใหม่อีกครั้ง ยกเลิกการย้อน</span>"));
if (currentRevID != rollbackInfo[0].revid) return mw.notify($("<span class='revert_status_warn'>คำเตือน: รุ่นล่าสุดที่ " + currentRevID + " ไม่ตรงกับรุ่น " + rollbackInfo[0].revid + " ที่ต้องการ" + /* the original does not have this and continues revert, but I do not have the handler for this part yet */" ยกเลิกการย้อน" + "</span>"));
if (revertWhitelist.indexOf(rollbackInfo[0].user) !== -1) {
switch (type) {
case 'vand':
mw.notify($("<span class='revert_status_confirm'>ข้อมูล: คุณได้เลือกให้ย้อนการก่อกวนของ <span style='font-weight: bold;'>" + rollbackInfo[0].user + "</span> ซึ่งเป็นบอตที่ได้รับการอนุมัติ ดังนั้นเราเชื่อว่าคุณต้องการย้อนกลับการแก้ไขของผู้ใช้ก่อนหน้านี้แทน</span>"));
rollbackInfo.shift();
break;
case 'agf':
mw.notify($("<span class='revert_status_warn'>แจ้งให้ทราบ: คุณได้เลือกย้อนเจตนาดีของ <span style='font-weight: bold;'>" + rollbackInfo[0].user + "</span> ซึ่งเป็นบอตที่ได้รับการอนุมัติและมีเจตนาดีโดยเสมอ หากพบว่าการแก้ไขบอตไม่ถูกต้อง และต้องการย้อนกลับ ให้เลือกการย้อนปกติแทน</span>"));
return;
case 'norm':
/* falls through */
default:
var skipBot = confirm("การแก้ไขล่าสุดเป็นของ " + rollbackInfo[0].user + " ซึ่งเป็นบอตที่ได้รับการอนุมัติ คุณต้องการย้อนการแก้ไขของผู้ใช้ก่อนหน้านี้ (OK) หรือการแก้ไขของบอต (Cancel)");
if (skipBot) {
rollbackInfo.shift();
mw.notify($("<span class='revert_status_confirm'>ข้อมูล: ตามที่คุณยืนยัน เราจะทำการย้อนการแก้ไขไปรุ่นก่อนการแก้ไขของ <span style='font-weight: bold;'>" + rollbackInfo[0].user + "</span></span>"));
} else mw.notify($("<span class='revert_status_warn'>แจ้งให้ทราบ: คุณได้ยืนยันย้อนการแก้ไขของ <span style='font-weight: bold;'>" + rollbackInfo[0].user + "</span> ซึ่งเป็นบอตที่ได้รับการอนุมัติ แต่คุณยืนยันจึงดำเนินการต่อ</span>"));
break;
}
}
var offender = rollbackInfo[0].user;
var revertToInfo;
var revisionCount = -1;
for (var i in rollbackInfo) {
revisionCount++;
if (rollbackInfo[i].user != offender) {
revertToInfo = {
revid: rollbackInfo[i].revid,
user: rollbackInfo[i].user
};
break;
}
}
if (!revertToInfo) return getRevNotice('revert_status_warn', "ไม่พบเจอรุ่นที่จะย้อนกลับ หยุดดำเนินการ อาจเป็นเพราะว่า " + rollbackInfo[0].user + " เป็นผู้แก้ไขหน้านี้แต่เพียงผู้เดียว หรือได้แก้ไขติดต่อกันมากกว่า 50 ครั้ง", true);
// from here, we use modified revert code
getRevertInfo(revertToInfo.revid).then(function(revertInfo) {
if (revisionCount == 0) return mw.notify($("<b><span class='revert_status_warn'>ข้อผิดพลาด: ไม่พบเจอรุ่นที่จะย้อนกลับ หยุดการดำเนินการ ซึ่งอาจเป็นเพราะว่าการแก้ไขได้ถูกย้อนกลับไปแล้ว แต่รหัสรุ่นยังเหมือนเดิม</span></b>"));
if (type !== 'vand' && revisionCount > 1) {
if (!confirm(offender + ' ได้ทำการแก้ไขทั้งหมด ' + revisionCount + ' ครั้งติดต่อกัน คุณแน่ใจว่าต้องการย้อนการแก้ไขดังกล่าวทั้งหมด?')) {
return mw.notify($("<span class='revert_status_confirm'>แจ้งให้ทราบ: ยกเลิกการย้อนกลับตามความต้องการของผู้ใช้</span>"));
}
}
getRevNotice('revert_status_status', "พบเจอรุ่นที่ <strong>" + revertToInfo.revid + "</strong> ซึ่งเป็น <strong>" + revisionCount + "</strong> การแก้ไขที่แล้วโดย <strong>" + revertToInfo.user + "</strong>");
var offenderInfo = "[[Special:Contributions/" + offender + "|" + offender + "]] ([[User talk:" + offender + "|พูดคุย]])";
var summary;
switch (type) {
case 'agf':
summary = "ย้อนการแก้ไข[[w:th:WP:AGF|เจตนาดี]]ของ " + offenderInfo + " " + iScriptConfig.Tagline;
break;
case 'vand':
summary = "ย้อน[[w:th:WP:VAND|การก่อกวน]] " + revisionCount + " ครั้งของ " + offenderInfo + " ไปยังรุ่นโดย " + revertToInfo.user + " " + iScriptConfig.Tagline;
break;
case 'norm':
default:
summary = "ย้อน " + revisionCount + " การแก้ไขของ " + offenderInfo + " ไปยังการแก้ไขของ " + revertToInfo.user + " " + iScriptConfig.Tagline;
break;
}
if (type == "agf" || type == "norm") {
var reason = prompt("กรุณาระบุสาเหตุที่ต้องการย้อนการแก้ไข (เว้นว่างหากไม่ระบุ): ", ""); // padded out to widen prompt in Firefox
if (reason === null) return getRevNotice('revert_status_warn', "ยกเลิกการย้อนกลับโดยผู้ใช้", true);
}
if (reason) summary += ": " + reason;
getRevNotice('revert_status_confirm', "สำเร็จ");
if (iScriptConfig.Edition == Editions.Wikipedia) {
// open user page
mw.notify($("<span class='revert_status_confirm'>ข้อมูล: กำลังเปิดหน้าพูดคุยกับผู้ใช้ของ <b>" + offender + "</b></span"));
var r = {
'title': 'User talk:' + offender,
'action': 'edit',
'iScriptAction': 'rollback-' + type,
// 'preview': 'yes',
'vanarticle': pageName.replace(/_/g, ' '),
// 'vanarticlerevid': a.params.revid,
// 'vanarticlegoodrevid': a.params.goodid,
// 'type': a.params.type,
// 'count': a.params.count
}
openInNewWindow(mw.util.getUrl('', r));
}
// push source
mw.notify($("<span class='revert_status_status'>กำลังบันทึกข้อมูล...</span>"), { tag: 'twinkle_revert_editing' });
revertPage(revertInfo.title, revertInfo.content, summary, false, true, currentRevInfo.revid, revertInfo.revid);
});
}
function makeTwinkleLink(color, text) {
var before = createElement('span', "[", {
'style': "color: black;"
});
var main = createElement('span', text, {
'style': "color: " + color + ";"
});
var after = createElement('span', "]", {
'style': "color: black;"
});
var link = createElement('a', [before, main, after], {
'href': "#",
'style': "font-weight: bold;"
});
return link;
}
function twinkleStarter() {
if (!document.getElementById('mw-diff-otitle1') || !document.getElementById('mw-diff-ntitle1')) return;
var diffOld = document.getElementById('mw-diff-otitle1').parentNode;
var diffNew = document.getElementById('mw-diff-ntitle1').parentNode;
var revertToOld = makeTwinkleLink("SaddleBrown", "ย้อนกลับมาเป็นรุ่นนี้");
var revertToOldDiv = createElement('div', revertToOld, { 'id': "iS-tw-revert-orevision" });
diffOld.insertBefore(revertToOldDiv, diffOld.firstChild);
if (document.getElementById('differences-nextlink')) {
var revertToNew = makeTwinkleLink("SaddleBrown", "ย้อนกลับมาเป็นรุ่นนี้");
var revertToNewDiv = createElement('div', revertToNew, { 'id': "iS-tw-revert-nrevision" });
diffNew.insertBefore(revertToNewDiv, diffNew.firstChild);
} else {
var rollbackAGF = createElement('span', makeTwinkleLink("DarkOliveGreen", "ย้อนเจตนาดี"), { 'id': "iS-tw-rollback-agf" });
var rollbackNorm = createElement('span', makeTwinkleLink("SteelBlue", "ย้อน"), { 'id': "iS-tw-rollback-normal" });
var rollbackVand = createElement('span', makeTwinkleLink("Red", "ย้อนก่อกวน"), { 'id': "iS-tw-rollback-vand" });
var rollbackButton = createElement('div', [rollbackAGF, " || ", rollbackNorm, " || ", rollbackVand], { 'id': "iS-tw-revert" });
diffNew.insertBefore(rollbackButton, diffNew.firstChild);
}
$(revertToOld).click(function() {
revertToRevision("old");
});
$(revertToNew).click(function() {
revertToRevision("new");
});
$(rollbackAGF).click(function() {
rollback("agf");
});
$(rollbackNorm).click(function() {
rollback("norm");
});
$(rollbackVand).click(function() {
rollback("vand");
});
}
$(document).ready(function() {
if (mw.config.get('wgIsProbablyEditable')) {
twinkleStarter();
}
});