Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <nowiki>
// Script to respond to edit filter false positive reports
// Fork of [[User:DannyS712/EFFPRH/sandbox.js]]
$(() => {
const EFFPRH = {
config: {
debug: false
},
responseOptions: [
{ value: 'none', label: 'None' },
{ value: 'nofilterstriggered', label: 'No filters triggered' },
{ value: 'done', label: 'Done (no change to filter)' },
{ value: 'defm', label: 'Done (may need a change to filter)' },
{ value: 'notdone', label: 'Not Done (filter working properly)' },
{ value: 'ndefm', label: 'Not Done (may need a change to filter)' },
{ value: 'redlink', label: 'Not Done (notable people)' },
{ value: 'alreadydone', label: 'Already Done' },
{ value: 'denied', label: 'Decline (edits are vandalism)' },
{ value: 'checking', label: 'Checking' },
{ value: 'blocked', label: 'User blocked' },
{ value: 'talk', label: 'Request on article talk page' },
{ value: 'fixed', label: 'Fixed filter' },
{ value: 'question', label: 'Question' },
{ value: 'note', label: 'Note' },
{ value: 'private', label: 'Private filter' },
{ value: 'pin', label: 'Pin' },
{ value: 'moot', label: 'Moot (filter working properly)' },
{ value: 'mootefm', label: 'Moot (may need a change to filter)' }
],
init() {
const allowedPages = [
'Wikipedia:Edit filter/False positives/Reports',
'User:DannyS712/EFFPRH/sandbox'
];
const currentPage = mw.config.get('wgPageName').replace(/_/g, ' ');
if (!allowedPages.includes(currentPage)) return;
mw.loader.using(['vue', '@wikimedia/codex', 'mediawiki.util', 'mediawiki.api'], this.run.bind(this));
},
run() {
this.addStyle();
$('div.mw-heading h2').each((_, heading) => {
const editLinks = $(heading).parent().find('.mw-editsection');
const sectionNum = this.getSectionNumber(editLinks);
if (sectionNum !== -1) {
$(heading).parent().after($('<div>').attr('id', `script-EFFPRH-${sectionNum}`));
this.addHandlerLink(editLinks, $(heading).text(), sectionNum);
}
});
},
addStyle() {
mw.util.addCSS(`
.script-EFFPRH-handler { background-color: #f5f5f5; border: 1px solid #ccc; margin: 10px 0; padding: 10px; border-radius: 5px; }
.cdx-menu ul { margin-left: 0px; }
.cdx-menu { margin-bottom: 10px; }
.cdx-menu-item__content { line-height: 1em; }
.script-EFFPRH-handler td { vertical-align: middle; padding: 5px; }
.script-EFFPRH-preview { background-color: white; }
`);
},
getSectionNumber(editLinks) {
const editSectionUrl = editLinks.find('a:first').attr('href');
const sectionMatch = editSectionUrl && editSectionUrl.match(/§ion=(\d+)(?:$|&)/);
return sectionMatch ? parseInt(sectionMatch[1]) : -1;
},
addHandlerLink(editLinks, reporterName, sectionNum) {
const handlerLink = $('<a>').attr('id', `script-EFFPRH-launch-${sectionNum}`).text('Review report');
handlerLink.click(() => {
if (!handlerLink.hasClass('script-EFFPRH-disabled')) {
handlerLink.addClass('script-EFFPRH-disabled');
this.showHandler(reporterName, sectionNum);
}
});
editLinks.children().last().before(' | ', handlerLink);
},
showHandler(reporterName, sectionNum) {
const vueAppInstance = Vue.createMwApp({
components: {
CdxButton: mw.loader.require('@wikimedia/codex').CdxButton,
CdxSelect: mw.loader.require('@wikimedia/codex').CdxSelect,
CdxTextInput: mw.loader.require('@wikimedia/codex').CdxTextInput,
CdxToggleButton: mw.loader.require('@wikimedia/codex').CdxToggleButton,
previewRenderer: this.getPreviewComponent()
},
data() {
return {
reporterName,
sectionNum,
responseOptions: EFFPRH.responseOptions,
selectedResponse: 'none',
commentValue: '',
showDebug: EFFPRH.config.debug,
showPreview: false,
haveSubmitted: false,
editMade: false,
editError: false
};
},
computed: {
canSubmit() {
return !this.haveSubmitted && this.selectedResponse !== 'none';
},
previewToggleLabel() {
return this.showPreview ? 'Hide preview' : 'Show preview';
},
responseWikiText() {
return `: {{EFFP|${this.selectedResponse}}} ${this.commentValue} – ~~~~`;
}
},
methods: {
reloadPage() {
location.assign(`${mw.util.getUrl(mw.config.get('wgPageName'))}#${this.reporterName}`);
location.reload();
},
submitHandler() {
this.haveSubmitted = true;
EFFPRH.respondToReport(this.reporterName, this.sectionNum, this.responseWikiText).then(
() => this.editMade = true,
() => this.editError = true
);
},
cancelHandler() {
vueAppInstance && vueAppInstance.unmount();
$(`#script-EFFPRH-launch-${this.sectionNum}`).removeClass('script-EFFPRH-disabled');
}
},
template: `
<div class="script-EFFPRH-handler">
<p>Responding to report by {{ reporterName }}.</p>
<p v-if="showDebug">Section {{ sectionNum }}, selected response: {{ selectedResponse }}, comment: {{ commentValue }}.</p>
<table>
<tr><td><label>Action:</label></td><td><cdx-select v-model:selected="selectedResponse" :menu-items="responseOptions" default-label="Response to report" :disabled="haveSubmitted" /></td></tr>
<tr><td><label>Comment:</label></td><td><cdx-text-input v-model="commentValue" :disabled="haveSubmitted" /></td></tr>
</table>
<ul v-show="haveSubmitted">
<li>Submitting...</li>
<li v-show="editMade">Success! <a v-on:click="reloadPage"><strong>Reload the page</strong></a></li>
<li v-show="editError">Uh-oh, something went wrong. Please check the console for details.</li>
</ul>
<cdx-button weight="primary" action="progressive" :disabled="!canSubmit" v-on:click="submitHandler">Submit</cdx-button>
<cdx-button weight="primary" action="destructive" :disabled="haveSubmitted" v-on:click="cancelHandler">Cancel</cdx-button>
<cdx-toggle-button v-model="showPreview" :disabled="!canSubmit">{{ previewToggleLabel }}</cdx-toggle-button>
<preview-renderer v-if="showPreview && canSubmit" :wikitext="responseWikiText"></preview-renderer>
</div>
`
});
vueAppInstance.mount(`#script-EFFPRH-${sectionNum}`);
},
getPreviewComponent() {
return {
props: { wikitext: { type: String, default: '' } },
data() {
return { previewHtml: '', haveHtml: false };
},
methods: {
loadPreview(wikitextToPreview) {
new mw.Api().get({
action: 'parse',
formatversion: 2,
title: mw.config.get('wgPageName'),
text: wikitextToPreview,
prop: 'text|wikitext',
pst: true,
disablelimitreport: true,
disableeditsection: true,
sectionpreview: true
}).then(res => {
if (res && res.parse && res.parse.wikitext === this.wikitext && res.parse.text) {
this.previewHtml = res.parse.text;
this.haveHtml = true;
}
});
}
},
watch: {
wikitext(newValue) {
this.previewHtml = '';
this.haveHtml = false;
this.loadPreview(newValue);
}
},
mounted() {
this.loadPreview(this.wikitext);
},
template: `<div class="script-EFFPRH-preview"><hr><div v-if="haveHtml" v-html="previewHtml"></div><div v-else>Loading preview of {{ wikitext }}</div></div>`
};
},
respondToReport(reporterName, sectionNum, responseWikiText) {
return new Promise((resolve, reject) => {
const wikitextToAdd = `\n${responseWikiText}`;
const editParams = {
action: 'edit',
title: mw.config.get('wgPageName'),
section: sectionNum,
summary: `/* ${reporterName} */ Respond to false positive report (using [[User:DreamRimmer/EFFPRH|EFFPRH.js]])`,
appendtext: wikitextToAdd,
token: mw.user.tokens.get('csrfToken')
};
new mw.Api().postWithEditToken(editParams).then(resolve, reject);
});
}
};
EFFPRH.init();
});
// </nowiki>