User:Chaotic Enby/Unblock wizard.js: Difference between revisions
From Test Wiki
Content deleted Content added
Chaotic Enby (talk | contribs) trying... something? |
Chaotic Enby (talk | contribs) yeah |
||
| (107 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
/** |
/** |
||
* |
* MediaWiki:Unblock-wizard.js |
||
* |
* |
||
* JavaScript used for submitting unblock requests. |
* JavaScript used for submitting unblock requests. |
||
* Used on [[ |
* Used on [[Wikipedia:Unblock wizard]]. |
||
* Loaded via [[mw:Snippets/Load JS and CSS by URL]]. |
* Loaded via [[mw:Snippets/Load JS and CSS by URL]]. |
||
* |
* |
||
* Edits can be proposed via |
* Edits can be proposed via [[Wikipedia talk:Unblock wizard]]. |
||
* |
* |
||
* Author: [[User:Chaotic Enby]] (derived from a script by [[User:SD0001]]) |
* Author: [[User:Chaotic Enby]] (derived from a script by [[User:SD0001]]) |
||
* Licence: MIT |
* Licence: MIT (dual-licensed with CC-BY-SA 4.0 and GFDL 1.2) |
||
*/ |
*/ |
||
| Line 16: | Line 16: | ||
/* <nowiki> */ |
/* <nowiki> */ |
||
(function () { |
(async function () { |
||
var wizard = {}, ui = {}, block = {}; |
|||
$.when( |
|||
window.wizard = wizard; |
|||
$.ready, |
|||
wizard.ui = ui; |
|||
mw.loader.using([ |
|||
'mediawiki.util', 'mediawiki.api', 'mediawiki.Title', |
|||
'mediawiki.widgets', 'oojs-ui-core', 'oojs-ui-widgets' |
|||
]) |
|||
).then(function () { |
|||
if (!(mw.config.get('wgPageName').includes('User:Chaotic_Enby/Unblock_wizard/')) || |
|||
mw.config.get('wgAction') !== 'view') { |
|||
return; |
|||
} |
|||
init(); |
|||
}); |
|||
var afc = {}, ui = {}, block = {}; |
|||
window.afc = afc; |
|||
afc.ui = ui; |
|||
var config = { |
var config = { |
||
debounceDelay: 500, |
debounceDelay: 500, |
||
redirectionDelay: 1000, |
redirectionDelay: 1000, |
||
defaultAfcTopic: 'other' |
|||
}; |
}; |
||
var demoMode = !!mw.util.getParamValue("demoMode"); |
|||
var usernameBlock = mw.util.getParamValue("usernameBlock"); |
|||
console.log("console.log"); |
|||
await new mw.Api().loadMessagesIfMissing(['wikimedia-copyrightwarning', 'copyrightwarning']); |
|||
console.log("awawawait"); |
|||
// TODO: move to a separate JSON subpage, would be feasible once [[phab:T198758]] is resolved |
// TODO: move to a separate JSON subpage, would be feasible once [[phab:T198758]] is resolved |
||
var messages = { |
var messages = { |
||
"document-title": "Wikipedia Unblock Wizard", |
"document-title": "Wikipedia Unblock Wizard", |
||
"page-title": "Wikipedia Unblock Wizard", |
"page-title": "Wikipedia Unblock Wizard", |
||
"fieldset-label": "I was blocked for promotional activity", |
|||
"explain-label": "Can you explain, in your own words, what you were blocked for?", |
"explain-label": "Can you explain, in your own words, what you were blocked for?", |
||
"future-label": "If unblocked, what edits would you make |
"future-label": "If unblocked, what edits would you make and what (if applicable) would you do differently?", |
||
"other-label": "Is there anything else that may be helpful to your unblock request?", |
"other-label": "Is there anything else that may be helpful to your unblock request?", |
||
"accounts-label": "Please list all accounts you have used besides this one.", |
|||
"explain-promo-label": "Can you explain, in your own words, why your edits were or were not promotional?", |
|||
"so-label": "Have you taken the standard offer?", |
|||
"explain-promo-label": "Can you explain, in your own words, why your edits were promotional?", |
|||
"coi-label": "What is your relationship with the subjects you have been editing about?", |
"coi-label": "What is your relationship with the subjects you have been editing about?", |
||
"future-promo-label": "If unblocked, |
"future-promo-label": "If you are unblocked, what topic areas will you edit in?", |
||
"username-label": "If |
"username-label": (usernameBlock == "required" ? "What new username do you want to pick?" : "If your username was an issue, what new username do you want to pick?"), |
||
"standalone-username-label": "What new username do you want to pick?", |
|||
"additional-reason-label": "Additional reason to be unblocked", |
|||
"clarification-label": "Is there anything specific you want to ask about your block?", |
|||
"submit-label": "Submit", |
"submit-label": "Submit", |
||
"utrs-necessary": "It is necessary to appeal your block via UTRS. This is because your talk page access is disabled. [[Wikipedia:UTRS|Learn more about UTRS]]]", |
|||
"footer-text": "<small>If you are not sure about what to enter in a field, you can skip it. If you need help, you can ask on <b>[[Special:MyTalk|your talkpage]]</b> with <b>{{[[Template:Help me|Help me]]}}</b> or get live help via <b>[[WP:IRCHELP|IRC]]</b> or <b>[[WP:DISCORD|Discord]]</b>.<br>Facing some issues in using this form? <b>[/w/index.php?title=User_talk:Chaotic_Enby&action=edit§ion=new&preloadtitle=Issue%20with%20submission%20form&editintro=User_talk:Chaotic_Enby/editintro Report it]</b>.</small>", |
|||
"utrs-necessary-confirm": "It is necessary to appeal your block via UTRS. This is because your talk page access is disabled. Select \"Confirm\" to learn more about UTRS.", |
|||
"footer-text": "<small>If you are not sure about what to enter in a field, you can skip it. If you need help, you can ask on <b>[[Special:MyTalk|your talkpage]]</b> with <b>{{[[Template:Help me|Help me]]}}</b> or get live help via <b>[[WP:IRCHELP|IRC]]</b>.<br>Facing some issues in using this form? <b>Report it in {{irc|wikipedia-en-unblock}} on [[WP:IRC|IRC]], in <span style=\"font-family:monospace;\">#technical</span> on [[Wikipedia:Discord|Discord]], or through an issue/pull request on [https://github.com/L235/unblock-wizard GitHub]</b>.</small>", |
|||
"submitting-as": "Submitting as User:$1", |
"submitting-as": "Submitting as User:$1", |
||
"validation-notitle": "User not found", |
"validation-notitle": "User not found", |
||
"validation-invalidtitle": "User page does not exist.", |
"validation-invalidtitle": "User page does not exist.", |
||
"validation-missingtitle": "User page does not exist.", |
"validation-missingtitle": "User page does not exist.", |
||
"warning-norefs": "This draft doesn't appear to contain any references. Please add references, without which it is likely to be declined. See [[Help:Introduction to referencing with Wiki Markup/2|help on adding references]].", |
|||
"status-processing": "Processing ...", |
"status-processing": "Processing ...", |
||
"status-saving": "Saving talk page ...", |
"status-saving": "Saving talk page ...", |
||
"status-blank": "One or several required forms are missing.", |
|||
"editsummary-main": "Submitting using [[User:Chaotic Enby/Unblock wizard]]", |
|||
"editsummary-main": "Submitting using [[Wikipedia:Unblock wizard]]", |
|||
"status-redirecting": "Submission succeeded. Redirecting you to your talk page ...", |
"status-redirecting": "Submission succeeded. Redirecting you to your talk page ...", |
||
"status-redirecting-utrs": "Redirecting you to UTRS ...", |
|||
"status-not-blocked": "You are not currently blocked.", |
|||
"status-not-blocked-confirm": "You are not currently blocked. Select \"OK\" to activate demo mode, which will allow you to check out the workflow without posting a block request.", |
|||
"status-error": "Due to an error, your unblock request could not be parsed. You can try to submit an unblock request manually by {{#if:$2|[$2 clicking this link] or}} pasting the following on [[Special:MyTalk|your talk page]]:<br /><code>$1</code><br />If you are having difficulties, please [[Wikipedia:UTRS|make a request through UTRS]] and inform them of the issues you are encountering.", |
|||
"captcha-label": "Please enter the letters appearing in the box below", |
"captcha-label": "Please enter the letters appearing in the box below", |
||
"captcha-placeholder": "Enter the letters here", |
"captcha-placeholder": "Enter the letters here", |
||
"captcha-helptip": "CAPTCHA security check. Click \"Submit\" again when done.", |
"captcha-helptip": "CAPTCHA security check. Click \"Submit\" again when done.", |
||
"error-saving-main": "An error occurred ($1). Please try again or |
"error-saving-main": "An error occurred ($1). Please try again or ask for help on your talk page.", |
||
"error-main": "An error occurred ($1). Please try again or ask for help on your talk page.", |
|||
"status-saving-talk": "Saving draft talk page ...", |
|||
"copyright-notice": `<small>${mw.message('wikimedia-copyrightwarning').plain()}</small>`, |
|||
"editsummary-talk": "Adding WikiProject tags using [[WP:AFCSW|AfC-submit-wizard]]", |
|||
"status-talk-success": "Successfully added WikiProject tags to talk page", |
|||
"error-saving-talk": "An error occurred in editing the talk page ($1).", |
|||
"error-main": "An error occurred ($1). Please try again or refer to the help desk." |
|||
}; |
}; |
||
console.log("aaaaa"); |
|||
var messagesCache = {}; |
|||
// var infoLevels = { |
|||
// "process": ["0/01", "OOjs_UI_icon_ellipsis-progressive.svg"], |
|||
// "notice": ["4/4b", "OOjs_UI_icon_information-yellow.svg"], |
|||
// "success": ["8/86", "OOjs_UI_icon_speechBubbleAdd-ltr-constructive.svg"], |
|||
// "redirect": ["2/23", "OOjs_UI_icon_articleRedirect-ltr-progressive.svg"], |
|||
// "warning": ["4/4b", "OOjs_UI_icon_information-yellow.svg"], |
|||
// "error": ["4/4e", "OOjs_UI_icon_error-destructive.svg"], |
|||
// }; |
|||
var questionLabels = []; |
var questionLabels = []; |
||
var questionFields = {'explain': 0, 'future': 0, 'other': 0, 'explain-promo': 0, 'coi': 0, 'future-promo': 0, 'username': 1}; |
var questionFields = {'explain': 0, 'future': 0, 'other': 0, 'accounts': 0, 'so': 2, 'explain-promo': 0, 'coi': 0, 'future-promo': 0, 'username': 1, 'clarification': 0, 'standalone-username': 1, 'additional-reason': 0}; |
||
var required = {'explain': true, 'future': true, 'other': false, 'accounts': true, 'so': true, 'explain-promo': true, 'coi': true, 'future-promo': true, 'username': (usernameBlock == "required"), 'additional-reason': false, 'clarification': false, 'standalone-username': true}; |
|||
var blockType = ''; |
var blockType = ''; |
||
var emptyFields = false; |
|||
var emptyFieldsWarned = false; |
|||
var mainPosition = -1; |
|||
console.log("yeah"); |
|||
async function parseAndCacheMsg(key, ...messageArgs) { |
|||
if (messagesCache[key] && [...messageArgs].length == 0) { |
|||
return messagesCache[key]; |
|||
} |
|||
return await new mw.Api().parse("<div>" + mw.message('ubw-' + key, ...messageArgs).plain() + "</div>").then(function (parsedMsg) { |
|||
if ([...messageArgs].length == 0) { |
|||
messagesCache[key] = $(parsedMsg).find("div").eq(0).html(); |
|||
} |
|||
return $(parsedMsg).find("div").eq(0).html(); |
|||
}); |
|||
} |
|||
function init() { |
function init() { |
||
console.log("init"); |
|||
for (var key in messages) { |
for (var key in messages) { |
||
mw.messages.set(' |
mw.messages.set('ubw-' + key, messages[key]); |
||
} |
|||
for (var key in messages) { |
|||
parseAndCacheMsg(key); |
|||
} |
} |
||
var apiOptions = { |
var apiOptions = { |
||
parameters: { |
parameters: { |
||
| Line 93: | Line 123: | ||
ajax: { |
ajax: { |
||
headers: { |
headers: { |
||
'Api-User-Agent': 'w:en: |
'Api-User-Agent': 'w:en:MediaWiki:Unblock-wizard.js' |
||
} |
} |
||
} |
} |
||
| Line 100: | Line 130: | ||
// Two different API objects so that aborts on the lookupApi don't stop the final |
// Two different API objects so that aborts on the lookupApi don't stop the final |
||
// evaluate process |
// evaluate process |
||
wizard.api = new mw.Api(apiOptions); |
|||
wizard.lookupApi = new mw.Api(apiOptions); |
|||
wizard.lookupApi.get({ |
|||
"action": "query", |
"action": "query", |
||
"meta": "userinfo", |
"meta": "userinfo", |
||
"uiprop": "blockinfo" |
"uiprop": "blockinfo" |
||
}).then( setBlockData ).then( function ( block ) { |
}).then( setBlockData ).then( async function ( block ) { |
||
console.log("init?"); |
|||
blockType = mw.config.get('wgPageName').slice(33); |
|||
blockType = mw.config.get('wgPageName').split('/'); |
|||
if (blockType.includes("Demo")) { |
|||
demoMode = true; |
|||
} |
|||
console.log(blockType) |
|||
blockType = blockType[blockType.length - 1]; |
|||
switch (blockType) { |
switch (blockType) { |
||
case "Sockpuppet": |
|||
questionLabels = ['accounts', 'so', 'other']; |
|||
break; |
|||
case "Promo": |
case "Promo": |
||
questionLabels = ['explain-promo', 'coi', 'future-promo', 'other']; |
|||
if(true) { // to replace by an api call to check if the block is username-related |
|||
questionLabels = ['explain-promo', 'coi', 'future-promo', 'username', 'other']; |
|||
} else { |
|||
questionLabels = ['explain-promo', 'coi', 'future-promo', 'other']; |
|||
} |
|||
break; |
break; |
||
case "Autoblock": |
case "Autoblock": |
||
questionLabels = []; |
questionLabels = []; |
||
break; |
break; |
||
case " |
case "IP_hardblock": |
||
questionLabels = []; |
questionLabels = []; |
||
break; |
break; |
||
case "Other": |
case "Other": |
||
questionLabels = ['explain', 'future', 'other']; |
questionLabels = ['explain', 'future', 'other']; |
||
break; |
|||
case "Clarification": |
|||
questionLabels = ['clarification']; |
|||
break; |
|||
case "Username": |
|||
questionLabels = ['standalone-username', 'additional-reason']; |
|||
break; |
break; |
||
default: |
default: |
||
questionLabels = []; |
questionLabels = []; |
||
} |
|||
if(usernameBlock && blockType != "Username" && blockType != "Clarification" && blockType != "IP_hardblock" && blockType != "Autoblock" && blockType != "IP") { |
|||
questionLabels = ['username'].concat(questionLabels); |
|||
} |
} |
||
document.title = msg('document-title'); |
document.title = await msg('document-title'); |
||
$('#firstHeading').text(msg('page-title')); |
$('#firstHeading').text(await msg('page-title')); |
||
mw.util.addCSS( |
mw.util.addCSS( |
||
| Line 144: | Line 188: | ||
'#catlinks { display: none } ' |
'#catlinks { display: none } ' |
||
); |
); |
||
console.log("???"); |
|||
constructUI(); |
constructUI(); |
||
}); |
}); |
||
} |
} |
||
function setBlockData(json) { |
async function setBlockData(json) { |
||
debug('block fetch query', json); |
|||
var userinfo = json.query.userinfo; |
var userinfo = json.query.userinfo; |
||
var errors = errorsFromPageData(userinfo); |
var errors = errorsFromPageData(userinfo); |
||
block.target = userinfo.name; |
|||
if (errors.length) { |
if (errors.length) { |
||
return block; |
return block; |
||
} |
} |
||
if("blockid" in userinfo){ |
if("blockid" in userinfo){ |
||
debug('user block id: ' + userinfo.blockid + ''); |
|||
block.id = userinfo.blockid; |
block.id = userinfo.blockid; |
||
block.by = userinfo.blockedby; |
block.by = userinfo.blockedby; |
||
block.reason = userinfo.blockreason; |
block.reason = userinfo.blockreason; |
||
block.notalk = userinfo.blockowntalk; |
|||
} else { |
|||
debug('user block id: none'); |
|||
} |
} |
||
return block; |
return block; |
||
} |
} |
||
function constructUI() { |
async function constructUI() { |
||
ui.itemsLayout = []; |
ui.itemsLayout = []; |
||
ui.itemsInput = []; |
ui.itemsInput = []; |
||
var copyrightEligible = false; |
|||
for(var label of questionLabels){ |
for(var label of questionLabels){ |
||
| Line 175: | Line 219: | ||
case 0: |
case 0: |
||
ui.itemsInput.push(new OO.ui.MultilineTextInputWidget({ |
ui.itemsInput.push(new OO.ui.MultilineTextInputWidget({ |
||
// placeholder: msg(label + '-placeholder'), |
// placeholder: await msg(label + '-placeholder'), |
||
multiline: true, |
multiline: true, |
||
autosize: true, |
autosize: true, |
||
})); |
})); |
||
copyrightEligible = true; |
|||
break; |
break; |
||
case 1: |
case 1: |
||
ui.itemsInput.push(new OO.ui.TextInputWidget({ |
ui.itemsInput.push(new OO.ui.TextInputWidget({ |
||
// placeholder: msg(label + '-placeholder'), |
// placeholder: await msg(label + '-placeholder'), |
||
maxLength: 85, |
maxLength: 85, |
||
})); |
})); |
||
copyrightEligible = true; |
|||
break; |
|||
case 2: |
|||
ui.itemsInput.push(new OO.ui.RadioSelectInputWidget({ |
|||
align: 'inline', |
|||
})); |
|||
ui.itemsInput[ui.itemsInput.length - 1].setOptions([{label:"Yes", data:"Yes."}, {label:"No", data:"No."}]); |
|||
break; |
break; |
||
default: |
default: |
||
break; |
|||
debug("Field type not found"); |
|||
} |
} |
||
ui.itemsLayout.push(new OO.ui.FieldLayout(ui.itemsInput[ui.itemsInput.length - 1], { |
ui.itemsLayout.push(new OO.ui.FieldLayout(ui.itemsInput[ui.itemsInput.length - 1], { |
||
label: msg(label + '-label'), |
label: await msg(label + '-label') + (required[label] ? " (*)" : ""), |
||
align: 'top', |
align: 'top', |
||
// help: msg(label + '-helptip'), |
// help: await msg(label + '-helptip'), |
||
helpInline: true |
helpInline: true |
||
})); |
})); |
||
| Line 198: | Line 250: | ||
ui.itemsLayout.push(ui.submitLayout = new OO.ui.FieldLayout(ui.submitButton = new OO.ui.ButtonWidget({ |
ui.itemsLayout.push(ui.submitLayout = new OO.ui.FieldLayout(ui.submitButton = new OO.ui.ButtonWidget({ |
||
label: await msg('submit-label'), |
|||
flags: [ 'progressive', 'primary' ], |
|||
}))); |
|||
if(copyrightEligible){ |
|||
ui.itemsLayout.push(new OO.ui.FieldLayout(new OO.ui.LabelWidget({ |
|||
label: $('<div>') |
|||
.append(linkify(await msgParsed('copyright-notice'))) |
|||
}), { |
|||
align: 'top' |
|||
})); |
|||
} |
|||
ui.fieldset = new OO.ui.FieldsetLayout({ |
ui.fieldset = new OO.ui.FieldsetLayout({ |
||
| Line 209: | Line 270: | ||
ui.footerLayout = new OO.ui.FieldLayout(new OO.ui.LabelWidget({ |
ui.footerLayout = new OO.ui.FieldLayout(new OO.ui.LabelWidget({ |
||
label: $('<div>') |
label: $('<div>') |
||
.append(linkify( |
.append(linkify(await msgParsed('footer-text'))) |
||
}), { |
}), { |
||
align: 'top' |
align: 'top' |
||
| Line 215: | Line 276: | ||
var asUser = mw.util.getParamValue('username'); |
var asUser = mw.util.getParamValue('username'); |
||
if (asUser && asUser !== |
if (asUser && asUser !== block.target) { |
||
ui.fieldset.addItems([ |
ui.fieldset.addItems([ |
||
new OO.ui.FieldLayout(new OO.ui.MessageWidget({ |
new OO.ui.FieldLayout(new OO.ui.MessageWidget({ |
||
type: 'notice', |
type: 'notice', |
||
inline: true, |
inline: true, |
||
label: msg('submitting-as', asUser) |
label: await msg('submitting-as', asUser) |
||
})) |
})) |
||
], /* position */ 5); // just before submit button |
], /* position */ 5); // just before submit button |
||
| Line 227: | Line 288: | ||
// Attach |
// Attach |
||
$('#unblock-wizard-container').empty().append(ui.fieldset.$element, ui.footerLayout.$element); |
$('#unblock-wizard-container').empty().append(ui.fieldset.$element, ui.footerLayout.$element); |
||
mw.track('counter.gadget_afcsw.opened'); |
|||
ui.submitButton.on('click', handleSubmit); |
|||
initLookup(); |
initLookup(); |
||
if (blockType != "IP" && !("id" in block) && !demoMode) { |
|||
setMainStatus('warning', await msgParsed('status-not-blocked')); |
|||
demoMode = confirm(await msg('status-not-blocked-confirm')); |
|||
console.log(demoMode) |
|||
} |
|||
if (block.notalk) { |
|||
ui.submitButton.setDisabled(true); |
|||
setMainStatus('error', await msgParsed('utrs-necessary')); |
|||
if (confirm(await msg("utrs-necessary-confirm"))) { |
|||
location.href = mw.config.get("wgArticlePath").replace("$1", "Wikipedia:UTRS"); |
|||
} |
|||
} else { |
|||
ui.submitButton.on('click', handleSubmit); |
|||
} |
|||
// The default font size in monobook and modern are too small at 10px |
// The default font size in monobook and modern are too small at 10px |
||
mw.util.addCSS('.skin-modern .projectTagOverlay, .skin-monobook .projectTagOverlay { font-size: 130%; }'); |
mw.util.addCSS('.skin-modern .projectTagOverlay, .skin-monobook .projectTagOverlay { font-size: 130%; }'); |
||
wizard.beforeUnload = function (e) { |
|||
var changedContent = false; |
|||
e.preventDefault(); |
|||
for (var [i, label] of questionLabels.entries()) { |
|||
if (ui.itemsInput[i].getValue() != "" && questionFields[label] != 2) { |
|||
changedContent = true; |
|||
} |
|||
if (ui.itemsInput[i].getValue() != "Yes." && questionFields[label] == 2) { |
|||
changedContent = true; |
|||
} |
|||
} |
|||
if(changedContent){ |
|||
e.preventDefault(); |
|||
} |
|||
e.returnValue = ''; |
e.returnValue = ''; |
||
return ''; |
return ''; |
||
}; |
}; |
||
$(window).on('beforeunload', |
$(window).on('beforeunload', wizard.beforeUnload); |
||
} |
} |
||
function initLookup() { |
function initLookup() { |
||
wizard.lookupApi.abort(); // abort older API requests |
|||
var userTalk = "User talk:" + |
var userTalk = "User talk:" + block.target; |
||
if (!mw.config.get('wgUserName')) { // empty |
|||
return; // here we should get the ip or something |
|||
} |
|||
debug('user talk page: "' + userTalk + '"'); |
|||
// re-initialize |
// re-initialize |
||
wizard.pagetext = null; |
|||
afc.talktext = null; |
|||
afc.pagetext = null; |
|||
wizard.lookupApi.get({ |
|||
"action": "query", |
"action": "query", |
||
"prop": "revisions|description|info", |
"prop": "revisions|description|info", |
||
| Line 269: | Line 348: | ||
function setPrefillsFromPageData(json) { |
function setPrefillsFromPageData(json) { |
||
debug('page fetch query', json); |
|||
var page = json.query.pages[0]; |
var page = json.query.pages[0]; |
||
var preNormalizedTitle = json.query.normalized && json.query.normalized[0] && |
var preNormalizedTitle = json.query.normalized && json.query.normalized[0] && |
||
json.query.normalized[0].from; |
json.query.normalized[0].from; |
||
debug('page.title: "' + page.title + '"'); |
|||
var errors = errorsFromPageData(page); |
var errors = errorsFromPageData(page); |
||
if (errors.length) { |
if (errors.length) { |
||
| Line 279: | Line 356: | ||
} |
} |
||
wizard.pagetext = page.revisions[0].slots.main.content; |
|||
} |
} |
||
| Line 286: | Line 363: | ||
* @returns {string[]} |
* @returns {string[]} |
||
*/ |
*/ |
||
function errorsFromPageData(page) { |
async function errorsFromPageData(page) { |
||
if (!page || page.invalid) { |
if (!page || page.invalid) { |
||
return [msg('validation-invalidtitle')]; |
return [await msg('validation-invalidtitle')]; |
||
} |
} |
||
if (page.missing) { |
if (page.missing) { |
||
return [msg('validation-missingtitle')]; |
return [await msg('validation-missingtitle')]; |
||
} |
} |
||
return []; |
return []; |
||
} |
|||
/** |
|||
* @param {Object} page - from query API response |
|||
* @returns {string[]} |
|||
*/ |
|||
function warningsFromPageData(page) { |
|||
var pagetext = page.revisions[0].slots.main.content; |
|||
var warnings = []; |
|||
// Show no refs warning |
|||
if (!/<ref/i.test(pagetext) && !/\{\{([Ss]fn|[Hh]arv)/.test(pagetext)) { |
|||
warnings.push('warning-norefs'); |
|||
} |
|||
// TODO: Show warning for use of deprecated/unreliable sources |
|||
// TODO: Show tip for avoiding peacock words or promotional language? |
|||
return warnings.map(function (warning) { |
|||
return new OO.ui.HtmlSnippet(linkify(msg(warning))); |
|||
}); |
|||
} |
} |
||
| Line 323: | Line 378: | ||
*/ |
*/ |
||
function setMainStatus(type, message) { |
function setMainStatus(type, message) { |
||
if (mainPosition == -1) { |
|||
if (!ui.mainStatusLayout || !ui.mainStatusLayout.isElementAttached()) { |
|||
mainPosition = ui.fieldset.items.length; |
|||
ui.fieldset.addItems([ |
ui.fieldset.addItems([ |
||
ui. |
ui.mainLabel = new OO.ui.MessageWidget( { |
||
align: 'top', |
|||
type: type, |
|||
label: $("<span/>").append(linkify(message)) |
|||
}) |
|||
]); |
]); |
||
} else { |
|||
ui.mainLabel.setType(type); |
|||
ui.mainLabel.setLabel($('<span/>').append(linkify(message))); |
|||
} |
} |
||
ui.mainStatusArea.setType(type); |
|||
ui.mainStatusArea.setLabel(message); |
|||
} |
} |
||
async function handleSubmit() { |
|||
if (ui.submitButton.isDisabled()) { |
|||
/** |
|||
return; |
|||
* @param {string} type |
|||
* @param {string} message |
|||
*/ |
|||
function setTalkStatus(type, message) { |
|||
if (!ui.talkStatusLayout) { |
|||
ui.fieldset.addItems([ |
|||
ui.talkStatusLayout = new OO.ui.FieldLayout(ui.talkStatusArea = new OO.ui.MessageWidget()) |
|||
]); |
|||
} |
} |
||
setMainStatus('', await msgParsed('status-processing')); |
|||
ui.talkStatusArea.setType(type); |
|||
ui.talkStatusArea.setLabel(message); |
|||
} |
|||
function handleSubmit() { |
|||
setMainStatus('notice', msg('status-processing')); |
|||
mw.track('counter.gadget_afcsw.submit_attempted'); |
|||
ui.submitButton.setDisabled(true); |
ui.submitButton.setDisabled(true); |
||
ui. |
ui.mainLabel.scrollElementIntoView(); |
||
var url = prepareUserTalkPageLink(); |
|||
if (blockType == "IP hardblock") { |
|||
var text = prepareUserTalkText(); |
|||
setMainStatus('success', msg('status-redirecting')); |
|||
for(var [i, label] of questionLabels.entries()){ |
|||
mw.track('counter.gadget_afcsw.submit_succeeded'); |
|||
if(required[label] && !ui.itemsInput[i].getValue()){ |
|||
location.href = "https://utrs-beta.wmflabs.org/public/appeal/account"; |
|||
emptyFields = true; |
|||
} |
|||
} |
|||
if (emptyFields && !emptyFieldsWarned) { |
|||
setMainStatus('warning', await msgParsed('status-blank')); |
|||
emptyFieldsWarned = true; |
|||
ui.submitButton.setDisabled(false); |
|||
} else { |
} else { |
||
var userTalk = "User talk:" + |
var userTalk = "User talk:" + block.target; |
||
if (! |
if (!block.target) { // empty |
||
ui.fieldset.removeItems([ui. |
ui.fieldset.removeItems([ui.mainLabel]); |
||
ui.submitButton.setDisabled(false); |
ui.submitButton.setDisabled(false); |
||
return; // really get the ip please |
return; // really get the ip please |
||
} |
} |
||
debug('debug user talk page: "' + userTalk + '"'); |
|||
wizard.api.get({ |
|||
"action": "query", |
"action": "query", |
||
"prop": "revisions|description", |
"prop": "revisions|description", |
||
| Line 373: | Line 426: | ||
"rvprop": "content", |
"rvprop": "content", |
||
"rvslots": "main", |
"rvslots": "main", |
||
}).then(function (json) { |
}).then(async function (json) { |
||
var apiPage = json.query.pages[0]; |
var apiPage = json.query.pages[0]; |
||
var errors = errorsFromPageData(apiPage); |
var errors = errorsFromPageData(apiPage); |
||
if (errors.length) { |
if (errors.length) { |
||
ui.fieldset.removeItems([ui. |
// ui.fieldset.removeItems([ui.mainLabel]); |
||
ui.submitButton.setDisabled(false); |
ui.submitButton.setDisabled(false); |
||
setMainStatus('error', await msgParsed('status-error', text, url)); |
|||
debug(errors); |
|||
return; |
return; |
||
} |
} |
||
debug("no errors"); |
|||
setMainStatus('', await msg('status-saving')); |
|||
var text = prepareUserTalkText(apiPage); |
|||
if (demoMode) { |
|||
debug("text[0] = " + text[0]); |
|||
setMainStatus('success', 'Wikitext: <code style="display: block">' + text + '</code>\n\nPreload URL: <a href=\"' + url + '\" target=\"_blank\">' + url.replace("&", "&").replace("<", "<") + '</a>'); |
|||
} else { |
|||
setMainStatus('notice', msg('status-saving')); |
|||
saveUserTalkPage(userTalk, text).then(function () { |
saveUserTalkPage(userTalk, apiPage.revisions[0].slots.main.content + text).then(async function () { |
||
setMainStatus('success', |
setMainStatus('success', await msgParsed('status-redirecting')); |
||
mw.track('counter.gadget_afcsw.submit_succeeded'); |
|||
$(window).off('beforeunload', wizard.beforeUnload); |
|||
setTimeout(function () { |
|||
$(window).off('beforeunload', afc.beforeUnload); |
|||
location.href = mw.util.getUrl(userTalk); |
|||
setTimeout(function () { |
|||
}, config.redirectionDelay); |
|||
location.href = mw.util.getUrl(userTalk); |
|||
}, |
}, async function (code, err) { |
||
if (code === 'captcha') { |
|||
ui.fieldset.removeItems([ui.mainLabel, ui.talkStatusLayout]); |
|||
if (code === 'captcha') { |
|||
ui.captchaLayout.scrollElementIntoView(); |
|||
ui.fieldset.removeItems([ui.mainStatusLayout, ui.talkStatusLayout]); |
|||
} else { |
|||
ui.captchaLayout.scrollElementIntoView(); |
|||
setMainStatus('error', await msgParsed('status-error', text, url)); |
|||
mw.track('counter.gadget_afcsw.submit_captcha'); |
|||
} |
} |
||
ui.submitButton.setDisabled(false); |
|||
setMainStatus('error', msg('error-saving-main', makeErrorMessage(code, err))); |
|||
}); |
|||
mw.track('counter.gadget_afcsw.submit_failed'); |
|||
} |
|||
mw.track('counter.gadget_afcsw.submit_failed_' + code); |
|||
}).catch(async function (code, err) { |
|||
} |
|||
setMainStatus('error', await msgParsed('status-error', text, url)); |
|||
ui.submitButton.setDisabled(false); |
|||
}); |
|||
}).catch(function (code, err) { |
|||
setMainStatus('error', msg('error-main', makeErrorMessage(code, err))); |
|||
ui.submitButton.setDisabled(false); |
ui.submitButton.setDisabled(false); |
||
mw.track('counter.gadget_afcsw.submit_failed'); |
|||
mw.track('counter.gadget_afcsw.submit_failed_' + code); |
|||
}); |
}); |
||
} |
} |
||
} |
} |
||
function saveUserTalkPage(title, text) { |
async function saveUserTalkPage(title, text) { |
||
// TODO: handle edit conflict |
// TODO: handle edit conflict |
||
| Line 425: | Line 472: | ||
"title": title, |
"title": title, |
||
"text": text, |
"text": text, |
||
"summary": msg('editsummary-main') |
"summary": await msg('editsummary-main') |
||
}; |
}; |
||
if (ui.captchaLayout && ui.captchaLayout.isElementAttached()) { |
if (ui.captchaLayout && ui.captchaLayout.isElementAttached()) { |
||
editParams.captchaid = |
editParams.captchaid = wizard.captchaid; |
||
editParams.captchaword = ui.captchaInput.getValue(); |
editParams.captchaword = ui.captchaInput.getValue(); |
||
ui.fieldset.removeItems([ui.captchaLayout]); |
ui.fieldset.removeItems([ui.captchaLayout]); |
||
} |
} |
||
return |
return wizard.api.postWithEditToken(editParams).then(async function (data) { |
||
if (!data.edit || data.edit.result !== 'Success') { |
if (!data.edit || data.edit.result !== 'Success') { |
||
if (data.edit && data.edit.captcha) { |
if (data.edit && data.edit.captcha) { |
||
| Line 438: | Line 485: | ||
var url = data.edit.captcha.url; |
var url = data.edit.captcha.url; |
||
wizard.captchaid = data.edit.captcha.id; // abuse of global? |
|||
ui.fieldset.addItems([ |
ui.fieldset.addItems([ |
||
ui.captchaLayout = new OO.ui.FieldLayout(ui.captchaInput = new OO.ui.TextInputWidget({ |
ui.captchaLayout = new OO.ui.FieldLayout(ui.captchaInput = new OO.ui.TextInputWidget({ |
||
placeholder: msg('captcha-placeholder'), |
placeholder: await msg('captcha-placeholder'), |
||
required: true |
required: true |
||
}), { |
}), { |
||
warnings: [ new OO.ui.HtmlSnippet('<img src=' + url + '>') ], |
warnings: [ new OO.ui.HtmlSnippet('<img src=' + url + '>') ], |
||
label: msg('captcha-label'), |
label: await msg('captcha-label'), |
||
align: 'top', |
align: 'top', |
||
help: msg('captcha-helptip'), |
help: await msg('captcha-helptip'), |
||
helpInline: true, |
helpInline: true, |
||
}), |
}), |
||
| Line 460: | Line 507: | ||
} |
} |
||
}); |
}); |
||
} |
|||
async function prepareUserTalkPageLink() { |
|||
var url = new URL(location.origin + mw.config.get("wgArticlePath").replace("$1", "User_talk:" + mw.config.get("wgUserName"))); |
|||
url.searchParams.set("action", "edit"); |
|||
url.searchParams.set("section", "new"); |
|||
switch(blockType){ |
|||
case "Autoblock": |
|||
if("id" in block){ |
|||
url.searchParams.set("editintro", `Template:Unblock-auto/editintro`); |
|||
url.searchParams.set("preloadtitle", "Autoblock appeal"); |
|||
url.searchParams.set("preload", `Template:Unblock-auto/preload`); |
|||
url.searchParams.set("preloadparams[0]", block.reason); |
|||
url.searchParams.set("preloadparams[1]", block.by); |
|||
url.searchParams.set("preloadparams[2]", block.id); |
|||
} |
|||
break; |
|||
case "Clarification": |
|||
url.searchParams.set("preload", `Help:Contents/helpmepreload2`); |
|||
url.searchParams.set("preloadparams[0]", ui.itemsInput[0].getValue()); |
|||
url.searchParams.set("preloadparams[1]", ""); |
|||
break; |
|||
case "Username": |
|||
url.searchParams.set("editintro", `Template:Unblock-un/editintro`); |
|||
url.searchParams.set("preloadtitle", "Unblock request for change in username"); |
|||
url.searchParams.set("preload", `Template:Unblock-un/preload`); |
|||
url.searchParams.append("preloadparams[0]", ui.itemsInput[1] ? ui.itemsInput[1].getValue() : ''); |
|||
url.searchParams.append("preloadparams[1]", ui.itemsInput[0].getValue()); |
|||
break; |
|||
default: |
|||
url.searchParams.set("editintro", `Template:Unblock/editintro`); |
|||
url.searchParams.set("preloadtitle", "Unblock request"); |
|||
url.searchParams.set("preload", `Template:Unblock/preload`); |
|||
var reason = ''; |
|||
for(var [i, label] of questionLabels.entries()){ |
|||
if(required[label] || ui.itemsInput[i].getValue()) { |
|||
if(label == "username") { |
|||
url.searchParams.set("editintro", `Template:Unblock-un/editintro`); |
|||
url.searchParams.set("preloadtitle", "Unblock request with change in username"); |
|||
url.searchParams.set("preload", `Template:Unblock-un/preload`); |
|||
url.searchParams.append("preloadparams[1]", ui.itemsInput[i].getValue()); |
|||
} else { |
|||
reason += "'''''" + await msg(label + '-label') + "'''''" + "{{pb}}" + ui.itemsInput[i].getValue() + "{{pb}}"; |
|||
} |
|||
} |
|||
} |
|||
url.searchParams.append("preloadparams[0]", reason); |
|||
} |
|||
return url.toString(); |
|||
} |
} |
||
| Line 466: | Line 562: | ||
* @returns {string} final talk page text to save |
* @returns {string} final talk page text to save |
||
*/ |
*/ |
||
function prepareUserTalkText( |
async function prepareUserTalkText() { |
||
var text = page.revisions[0].slots.main.content; |
|||
var unblock = ''; |
var unblock = ''; |
||
| Line 477: | Line 571: | ||
unblock += '\n{{unblock-auto|2=\u003Cnowiki>' + block.reason + '\u003C/nowiki>|3=' + block.by + '|4=' + block.id + '}}\n'; |
unblock += '\n{{unblock-auto|2=\u003Cnowiki>' + block.reason + '\u003C/nowiki>|3=' + block.by + '|4=' + block.id + '}}\n'; |
||
} else { |
} else { |
||
unblock += '\n |
unblock += '\n{{unblock-auto|2=REASON|3=THE BLOCKING ADMIN|4=BLOCK ID}}\n'; |
||
} |
} |
||
break; |
|||
case "Clarification": |
|||
if(ui.itemsInput[0].getValue()){ |
|||
unblock += '\n{{Help me}}\n' + ui.itemsInput[0].getValue() + '\n~~' + '~~'; |
|||
} else { |
|||
unblock += '\n{{Help me}}\n' + 'I would like a more detailed explanation for my block.' + '\n~~' + '~~'; |
|||
} |
|||
break; |
|||
case "Username": |
|||
unblock += `\n{{unblock-un|1=${ui.itemsInput[0].getValue()}|reason=${ui.itemsInput[1] ? ui.itemsInput[1].getValue() : ''}}} \n`; |
|||
break; |
break; |
||
default: |
default: |
||
unblockStart = '\n{{unblock|reason='; |
|||
for(var [i, label] of questionLabels.entries()){ |
for(var [i, label] of questionLabels.entries()){ |
||
if(required[label] || ui.itemsInput[i].getValue()) { |
|||
if(label == "username") { |
|||
unblockStart = '\n{{unblock-un|1=' + ui.itemsInput[i].getValue() + '|reason='; |
|||
} else { |
|||
unblock += "'''''" + await msg(label + '-label') + "'''''" + "{{pb}}" + ui.itemsInput[i].getValue() + "{{pb}}"; |
|||
} |
|||
} |
|||
} |
} |
||
unblock = unblockStart + "<small>The following request was written through the [[Wikipedia:Unblock wizard|unblock wizard]].</small>\n" + unblock + ' ~~' + '~~}}\n'; |
|||
unblock += '}}~~' + '~~\n'; |
|||
} |
} |
||
return unblock; |
|||
// insert it at the bottom |
|||
text = text + unblock; |
|||
debug(text); |
|||
return text; |
|||
} |
} |
||
| Line 504: | Line 610: | ||
**/ |
**/ |
||
function getJSONPage (page) { |
function getJSONPage (page) { |
||
return |
return wizard.api.get({ |
||
action: 'query', |
action: 'query', |
||
titles: page, |
titles: page, |
||
| Line 525: | Line 631: | ||
/** |
/** |
||
* Expands wikilinks and external links into HTML. |
* Expands wikilinks and external links into HTML. |
||
* Used instead of mw.msg(...).parse() because we want links to open in a new tab, |
* Used instead of mw.await msg(...).parse() because we want links to open in a new tab, |
||
* and we don't want tags to be mangled. |
* and we don't want tags to be mangled. |
||
* @param {string} input |
* @param {string} input |
||
| Line 531: | Line 637: | ||
*/ |
*/ |
||
function linkify(input) { |
function linkify(input) { |
||
var $input = $("<span>" + input + "</span>"); |
|||
return input |
|||
$input.find('a').attr('target', '_blank'); |
|||
.replace( |
|||
return $input.html(); |
|||
/\[\[:?(?:([^|\]]+?)\|)?([^\]|]+?)\]\]/g, |
|||
function(_, target, text) { |
|||
if (!target) { |
|||
target = text; |
|||
} |
|||
return '<a target="_blank" href="' + mw.util.getUrl(target) + |
|||
'" title="' + target.replace(/"/g, '"') + '">' + text + '</a>'; |
|||
} |
|||
) |
|||
// for ext links, display text should be given |
|||
.replace( |
|||
/\[(\S*?) (.*?)\]/g, |
|||
function (_, target, text) { |
|||
return '<a target="_blank" href="' + target + '">' + text + '</a>'; |
|||
} |
|||
); |
|||
} |
} |
||
function msg(key) { |
function msg(key, ...messageArgs) { |
||
return mw.message('ubw-' + key, ...messageArgs).plain(); |
|||
var messageArgs = Array.prototype.slice.call(arguments, 1); |
|||
} |
|||
return mw.msg.apply(mw, ['afcsw-' + key].concat(messageArgs)); |
|||
async function msgParsed(key, ...messageArgs) { |
|||
let parsedMsg = await parseAndCacheMsg(key, ...messageArgs); |
|||
return parsedMsg; |
|||
} |
} |
||
| Line 568: | Line 663: | ||
}); |
}); |
||
} |
} |
||
console.log("await $$$"); |
|||
await $.when( |
|||
$.ready, |
|||
mw.loader.using([ |
|||
'mediawiki.util', 'mediawiki.api', 'mediawiki.Title', |
|||
'mediawiki.widgets', 'oojs-ui-core', 'oojs-ui-widgets' |
|||
]) |
|||
); |
|||
console.log("im rich now"); |
|||
if ((!(mw.config.get('wgPageName').includes('Wikipedia:Unblock_wizard/')) && !(mw.config.get('wgPageName').includes('Chaotic_Enby/'))) || |
|||
mw.config.get('wgAction') !== 'view') { |
|||
return; |
|||
} |
|||
console.log("innit"); |
|||
init(); |
|||
})(); // File-level closure to protect functions from being exposed to the global scope or overwritten |
})(); // File-level closure to protect functions from being exposed to the global scope or overwritten |
||