MediaWiki:Reports.js

/** Also found at soap Wiki, but here is slightly customized **/ require(['jquery', 'mw'], function ($, mw) { var c = mw.config.get([ 'wgNamespaceNumber', 'wgPageName', 'wgServer', 'wgUserName', 'wgUserLanguage' ]), options = { profile: {}, vandalism: {}, spam: {}, phalanx: {}, wiki: {} }, reportDropdown; /** function setOptions { if(typeof window.dev === 'undefined' || typeof window.dev.i18n === 'undefined') { importScriptPage('MediaWiki:I18n-js/code.js', 'dev'); } mw.hook('dev.i18n').add(function(i18no) { i18no.loadMessages('u:soap:MediaWiki:Custom-Reports/i18n.json').done(function(i18n) { options = { /* //BEGIN EXAMPLE example: { page: 'Page name the form is for', buttonText: 'Text for button to open form', form: 'HTML form for reporting users. Each input/textarea should have an id. any optional inputs should be marked with the `optional` class. If any attributes need URI encoding, the relevant inputs should have the `data-encode` attribute set to `true`.', // this is where the input ids in the form are matched to numbers // for use in the summary/submitted text formParams: { '$1': 'foo', '$2': 'bar' }, submitText: 'Text to submit to the page. Any form parameters can be inserted via the key names in `formParams`', summary: 'Text used for the edit summary. Any form parameters can be inserted via the key names in `formParams`', sectionTitle: 'Text used as the section title. Any form parameters can be inserted via the key names in `formParams`' }, // END EXAMPLE profile: { page: 'Report:User_profile_headers', buttonText: i18n.msg("buttonProfile").escape, form: '' + ' ' + ' ' + ' ' + i18n.msg("formSocial").escape + ' ' + ' ' + i18n.msg("formWikiName").escape + ' ' + '' + ' ' + ' ' + i18n.msg("formWikiURL").escape + ' ' + '' + ' ' + ' ' + i18n.msg("formUsername").escape + ' ' + i18n.msg("formOfBadUser").escape + ' (' + i18n.msg("formMultipleUsers").escape + ') ' + ' ' + ' ' + ' ' + i18n.msg("formReason").escape + ' ' + ' ' + ' ' + ' ' + '  ' + i18n.msg("formSockpuppet").escape + ' ' + ' ' + i18n.msg("formUsername").escape + ' ' + i18n.msg("formOfSock").escape + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ', formParams: { '$1': 'wikiurl', '$2': 'wikiname', '$3': 'user', '$4': 'comment', '$5': 'user', // for different styling '$7': 'socks', '$8': 'sockusers' }, submitText: '', summary: 'New profile report ($2, $5)', sectionTitle: '$2' }, vandalism: { page: 'Report:Vandalism', buttonText: i18n.msg("buttonVandalism").escape, form: '' + ' ' + ' ' + ' ' + i18n.msg("formWikiName").escape + ' ' + '' + ' ' + ' ' + i18n.msg("formWikiURL").escape + ' ' + '' + ' ' + ' ' + i18n.msg("formUsername").escape + ' ' + i18n.msg("formOfBadUser").escape + ' (' + i18n.msg("formMultipleUsers").escape + ') ' + ' ' + ' ' + ' ' + i18n.msg("formReason").escape + ' ' + ' ' + ' ' + ' ' + '  ' + i18n.msg("formCrossWiki").escape + ' ' + ' ' + ' ' + '  ' + i18n.msg("formSockpuppet").escape + ' ' + ' ' + i18n.msg("formUsername").escape + ' ' + i18n.msg("formOfSock").escape + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ', formParams: { '$1': 'wikiurl', '$2': 'wikiname', '$3': 'user', '$4': 'comment', '$5': 'user', // for different styling '$6': 'crosswiki', '$7': 'socks', '$8': 'sockusers' }, submitText: '', summary: 'New vandalism report ($1, $5)', sectionTitle: '$5 at $2' }, spam: { page: 'Report:Spam', buttonText: i18n.msg("buttonSpam").escape, form: '' + ' ' + ' ' + ' ' + i18n.msg("formWikiName").escape + ' ' + '<input id="wikiname" class="rf-wikiname optional" type="text" placeholder="Applemasterexpert Wiki"/>' + ' ' + ' ' + i18n.msg("formWikiURL").escape + ' ' + '<input id="wikiurl" class="rf-wikiurl" type="text" placeholder="applemasterexpert.fandom.com"/>' + ' ' + ' ' + i18n.msg("formUsername").escape + ' ' + i18n.msg("formOfBadUser").escape + ' (' + i18n.msg("formMultipleUsers").escape + ') ' + '<textarea name="" id="user" class="rf-wikiuser" type="text" placeholder="Applemasterexpert\nApplemasterBot"> ' + ' ' + ' ' + i18n.msg("formReason").escape + ' ' + '<textarea name="" id="comment" placeholder="' + i18n.msg("formphReason").escape + '" class="optional"> ' + ' ' + ' ' + ' <input type="checkbox" id="crosswiki" class="option-input optional"/> ' + i18n.msg("formCrossWiki").escape + ' ' + ' ' + ' ' + ' ' + ' ', formParams: { '$1': 'wikiurl', '$2': 'wikiname', '$3': 'user', '$4': 'comment', '$5': 'user', // for different styling '$6': 'crosswiki', }, submitText: '', summary: 'New spam report ($1, $5)', sectionTitle: '$5 at $2' }, phalanx: { page: 'Report:AbuseFilter', buttonText: i18n.msg("buttonFalsePositive").escape, form: '<form class="WikiaForm ReportForm" method="" name="" id="phalanx">' + ' ' + ' ' + ' ' + i18n.msg("formWikiName").escape + ' ' + '<input id="wikiname" class="rf-wikiname optional" type="text" placeholder="Applemasterexpert Wiki"/>' + ' ' + ' ' + i18n.msg("formWikiPage").escape + ' ' + '<input id="wikiurl" class="rf-wikiurl" type="text" placeholder="applemasterexpert.fandom.com"/>' + ' /wiki/ ' + '<input id="wikipage" class="rf-wikiurl" type="text" placeholder="Report:AbuseFilter"/>' + ' ' + ' ' + i18n.msg("formBlockID").escape + ' ' + '<input id="blockid" class="rf-wikiurl" type="text" placeholder="6" data-encode="true"/>' + ' ' + ' ' + i18n.msg("formPhalanxReason").escape + ' ' + '<textarea name="" id="comment" placeholder="' + i18n.msg("formphReason").escape + '" class="optional"> ' + ' ' + ' ' + ' ' + ' ', formParams: { '$1': 'wikiurl', '$2': 'wikiname', '$5': 'wikipage', '$3': 'blockid', '$4': 'comment' }, submitText: '', summary: 'New filter report ($2, #$3)', sectionTitle: 'Block #$3 on $2' }, wiki: { page: 'Report:Wiki', buttonText: i18n.msg("buttonWiki").escape, form: '<form class="WikiaForm ReportForm" method="" name="" id="wiki">' + ' ' + ' ' + ' ' + i18n.msg("formWikiName").escape + ' ' + '<input id="wikiname" class="rf-wikiname optional" type="text" placeholder="Applemasterexpert Wiki"/>' + ' ' + ' ' + i18n.msg("formWikiURL").escape + ' ' + '<input id="wikiurl" class="rf-wikiurl" type="text" placeholder="applemasterexpert.fandom.com"/>' + ' ' + ' ' + i18n.msg("formReason").escape + ' ' + '<input name="" id="comment" placeholder="' + i18n.msg("formphReason").escape + '" class="optional"> ' + ' ' + ' N.B.; Guidelines: ' + 'Please add to this list if you believe a wiki violates Fandom\'s <a href="https://www.fandom.com/terms-of-use">Terms of Use</a>. ' + '<ol><li>1. Do not use this page to report <a href="https://www.fandom.com/community-creation-policy">duplicate wikis</a>.</li>' + '<li>2. Do not add wikis just because you feel that they are "unproductive." This list is for <a href="https://www.fandom.com/terms-of-use">Terms of Use</a> violations only -- advertisement spam, harassment wikis, or obscene and illegal content.</li>' + '<li>3. Do not add wikis where you feel the administrators are being unfair. Please <a href="/Special:Contact/general">contact Staff</a> about bad admins.</li>' + '<li>4. New entries may be added to the <a href="#New reports (To be soap checked)">non-soap checked section</a> only. Check to ensure you are not duplicating an entry already there.</li></ol>' + ' ' + ' ' + ' ' + ' ', formParams: { '$1': 'wikiname', '$2': 'wikiurl', '$3': 'comment' }, submitText: '', summary: 'New bad wiki report ($1, comment: $3)', sectionTitle: '' }, }; reportDropdown = ' ' + '<div class="wds-dropdown__toggle wds-button">' + ' ' + i18n.msg("buttonReport").escape + ' ' + '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12" class="wds-icon wds-icon-tiny wds-dropdown__toggle-chevron"><path d="M1 3h10L6 9z"> ' + ' ' + '<div class="wds-dropdown__content">' + '<ul class="wds-list wds-is-linked" id="rf-dropdown-list">' + '</ul>' + ' ' + ' ' }).done(init); }); } /** function submitForm(opts) { var $form = $('#requestWindow form'), $inputs = $form.find('input, textarea'), $button = $('#submit'), params = {}, x, y, $input, text; if (($button).attr('disabled') === 'disabled') { return; } $button.attr('disabled', true); var keyedValueCount = 0, sockCount = 0; for (x in opts.formParams) { if (opts.formParams.hasOwnProperty(x)) { $input = $inputs.filter('#' + opts.formParams[x]); if (!$input.length) { console.log('An error has been found in the form config. Please check the formParams and input ids'); $button.attr('disabled', false); return; } text = $input.val; if ($input.is(':checkbox')) { text = $input.prop("checked"); } if (!text && !$input.hasClass('optional')) { console.log($input); alert('One or more required fields are missing. Please check your submission and try again.'); $button.attr('disabled', false); return; } /* Specific customisations for each form output */ if ($input.attr('data-encode') === 'true') { text = encodeURIComponent(text); } // default wikiname if($input.attr('id') == "wikiurl") { re = /\/\/(.*)\.(wikia|fandom)\./; domain = re.exec(text); if(domain != null) { params[x] = domain[1]; continue; } } else if($input.attr('id') === "wikiname") { if (!text) { text = $inputs.filter('#wikiurl').val; } re = /\/\/(.*)\.(wikia|fandom)\./; domain = re.exec(text); if(domain != null) { params[x] = domain[1].charAt(0).toUpperCase + domain[1].slice(1) + " Wiki"; continue; } } // handle multiple users if($input.attr('id') == "user" && text.indexOf('\n') !== -1) { if (x === '$5') { text = (text.match(/(?:\r\n|\r|\n)/g) || []).length + 1 + ' users'; } else { text = text.replace(/\n$/g, ''); // fix blank last user text = text.replace(/(?:\r\n|\r|\n)/g,'\n|'); } } // handle checkboxes if ($input.attr('id') == "crosswiki") { if (text) { text = "\\crosswiki=yes\n" keyedValueCount++; } else { text = "" } } if ($input.attr('id') == "socks") { if (text) { sockCount = 1; keyedValueCount++; } text = "" } // handle socks if ($input.attr('id') == "sockusers") { if (text === "" && sockCount) { console.log($input); alert('One or more required fields are missing. Please check your submission and try again.'); $button.attr('disabled', false); return; } else if (sockCount) { text = "\\socks=" + text + '\n'; } else { text = ""; } } // patch | in reason if ($input.attr('id') == "comment") { text = text.replace(/\|/g, '\\\\'); } params[x] = text; } } for (x in params) { if (params.hasOwnProperty(x)) { // convert to regex so the same parameter can be used multiple times in each string y = new RegExp(x.replace(/\$/, '\\$'), 'g'); opts.submitText = opts.submitText.replace(y, params[x]); opts.summary = opts.summary.replace(y, params[x]); opts.sectionTitle = opts.sectionTitle.replace(y, params[x]); } } // Fix when template thinks = is a key if (opts.submitText.match(/=/g) != null && opts.submitText.match(/=/g).length > keyedValueCount) { var templateParam = 0; opts.submitText = opts.submitText.replace(/\|/g, function (match, i, original) { templateParam++; return '|' + templateParam + '='; }); } if (keyedValueCount) { opts.submitText = opts.submitText.replace(/\\crosswiki/g, '|crosswiki'); opts.submitText = opts.submitText.replace(/\\socks/g, '|socks'); } console.log(opts.submitText, opts.summary); if(opts.page === "Report:Wiki") { (new mw.Api) .post({ action: 'edit', title: opts.page, appendtext: '\n' + opts.submitText, summary: opts.summary, token: mw.user.tokens.get('editToken') }) .done(function (res) { if (c.wgPageName == "soap_Wiki") { location.replace('https://soap.wikia.com/wiki/' + opts.page + '?action=purge'); } else { location.reload(location + '?action=purge'); } }); } else { (new mw.Api) .post({ action: 'edit', title: opts.page, section: 'new', sectiontitle: opts.sectionTitle, text: opts.submitText, summary: opts.summary, token: mw.user.tokens.get('editToken') }) .done(function (res) { if (c.wgPageName == "soap_Wiki") { location.replace('https://soap.wikia.com/wiki/' + opts.page + '?action=purge'); } else { location.reload(location + '?action=purge'); } }); } } /** function loadForm { var $this = $(this), type = $this.attr('id').split('-')[2], opts = options[type]; $.showCustomModal( opts.buttonText, opts.form, { id: 'requestWindow', width: 650, buttons: [{ id: 'cancel', message: 'Cancel', handler: function { $('#requestWindow').closeModal; } }, { id: 'submit', defaultButton: true, message: 'Save', handler: function  { submitForm(opts); } }], callback: function { // Fire hook for scripts that use the form mw.hook('soap.reportsform').fire; } } ); } /** function loadButton(type) { var opts = options[type]; var $newButton = $(' ', { 'class': 'wds-button', click: loadForm, id: 'soap-report-' + type, text: opts.buttonText }); $('.rb-' + type) .empty .append($newButton); // Fire hook for scripts that use the button mw.hook('soap.reports').fire($newButton); } /** function loadDropdown { $('.rf-dropdown') .empty .append(reportDropdown); var x; for (x in options) { var opts = options[x]; if (options.hasOwnProperty(x)) { $('#rf-dropdown-list').append( $('<li>') .attr('id', 'soap-report-' + x) .attr('class', 'wds-global-navigation__dropdown-link') .on('click',loadForm) .text(opts.buttonText) ); } } } /** function init { for (var x in options) { if ($('.rb-' + x).length > 0) { loadButton(x); } } if ($('.rf-dropdown').length > 0) { loadDropdown(x); } importStylesheetURI('https://soap.wikia.com/index.php?title=MediaWiki:Reports.css&action=raw&ctype=text/css'); } $(setOptions); });
 * Set up options for use in forms, buttons
 * Report form submission handler
 * @param opts {object}
 * @param opts {object}
 * Loads the report form
 * Loads the report form button
 * @param type {string}
 * @param type {string}
 * loads dropdown of all report possibilities
 * start up method