User:DreamRimmer/EFFPRH.js

//

// 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($('

').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 = $('').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: `

`

});

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: `


Loading preview of {{ wikitext }}
`

};

},

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 EFFPRH.js)`,

appendtext: wikitextToAdd,

token: mw.user.tokens.get('csrfToken')

};

new mw.Api().postWithEditToken(editParams).then(resolve, reject);

});

}

};

EFFPRH.init();

});

//