Utilisateur:DreZhsh/AbuseFilterEditTools.js
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;
Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5./* eslint-disable no-jquery/no-global-selector */
/* jshint esversion: 9 */
$(
/**
* @name AbuseFilterEditTools
* @author DreZhsh <https://fr.wikipedia.org/wiki/Utilisateur:DreZhsh>
*
* Améiore l'interface d'édition des filtres
* en ajoutant différents outils :
* - Transformation des variables dépréciées par leurs alternatives
* - Mise en forme du code (séparation des opérateurs, mots-clés... par des espaces)
* - Amélioration de « Vérifier la syntaxe »
* - Diviser une chaîne => outil pour corriger les mauvaises séparations
* - Test de `ccnorm()`
*
* {{Catégorisation JS}}
*/
function () {
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'AbuseFilter' && ( /\/(test|[0-9]+|tools)/ ).test( mw.config.get( 'wgPageName' ) ) ) {
mw.loader.using( [ 'mediawiki.api', 'ext.abuseFilter.edit', 'oojs-ui-core' ], function () {
mw.user.getRights().then( ( rights ) => {
const buttonDeprecate = new OO.ui.ButtonWidget( {
label: 'Corriger le code'
} ),
progressWidget = new OO.ui.ProgressBarWidget( { id: 'progressBarRqAf' } ),
formContent = makeConcatString(),
ccnormForm = makeCcnormTest();
/**
* getInputContent
*
* Extrait le contenu de
* Ace Editor
*
* @return {string} Le contenu de Ace Editor
*/
function getInputContent() {
const useAce = $( '#wpFilterRules' ).css( 'display' ) === 'none';
if ( useAce ) {
const globalArray = [];
$( document.getElementsByClassName( 'ace_line' ) ).each( function () {
const content = $( this ).text()
.replace( /^\u0020{4}/, '\t' )
.replace( /\u0020*$/, '' );
globalArray.push( content );
} );
return globalArray.join( '\n' );
} else {
return document.getElementById( 'wpFilterRules' ).value;
}
}
/**
* beautifyCode
*
* @return {string} Le contenu de Ace Editor
* mais avec les éléments de la syntaxe séparés par
* des espaces
*/
function beautifyCode() {
const globalArray = [];
$( '.ace_line' ).each( function () {
const textParse = String( $( this ).text() );
const inputContent = String( $( this ).html() )
.replace(
/<span class="ace_keyword ace_operator">!<\/span>/,
'!'
)
.replace(
// eslint-disable-next-line max-len
/(<span class="ace_support ace_function">)([a-z_]*)<\/span>[\s]*<span class="ace_paren ace_lparen">\((<\/span>)/gi,
'$1$2($3'
)
.replace(
// eslint-disable-next-line max-len
/<\/span><span class="ace_constant ace_language ace_escape">(\\[\s\S]+?)<\/span>(?:<span class="ace_string">)?/g,
'$1'
)
// HTML
.replace( /&/g, '&' )
.replace( />/g, '>' )
.replace( /</g, '<' )
// pas d'espace devant une ,
.replace( /\u0020?(<\/span>),\u0020{1,2}/g, '$1,' )
.replace( /<\/span>[\s]*,([\s]*)<span/g, ',$1</span><span' )
.replace( /,(<\/span>)?<span/g, ',\u0020$1<span' );
if ( Boolean( inputContent ) === false ) {
return;
}
// Division de la chaîne
const array = inputContent.split( /<\/span>/ );
array.forEach( ( text, i ) => {
array[ i ] = text.replace( /<span class="[^"]*">/, '' ).replace( /(^\u0020*|\u0020*$)/g, '' );
} );
let string = array.join( ' ' );
string = string.replace( /[\s]+;$/g, ';' );
if (
( /^\u0020{2,4}/ ).test( textParse ) ||
( /^\t/ ).test( textParse )
) {
const tabMatch = textParse.match( /^(\u0020{2,4}|\t)*/ ),
tab = tabMatch[ 0 ].replace( /(\u0020{2,4}|\t)/g, '\t' ).replace( /(\t+)\u0020/, '$1' );
string = string
.replace( /^(\u0020{2,4}|\t)*/g, tab );
}
string = string.replace( /\u0020*$/, '' );
globalArray.push( string );
} );
return globalArray.join( '\n' )
// set( 'name', value ) || set_var( 'name', value ) => name := value
.replace(
// eslint-disable-next-line max-len
/set(?:_var)?[\s]*\([\s]*["']([\S\s]*?)['"][\s]*,[\s]*(['"][\S\s]*?(?<!\\)['"])[\s]*\)/i,
'$1 := $2'
)
.replace( /^(\t+)\u0020/gm, '$1' );
}
/**
* makeConcatString
*
* Crée le formulaire "concat string"
*
* @return {Object} Les éléments utilisés dans le reste du code
*/
function makeConcatString() {
const input1 = new OO.ui.MultilineTextInputWidget( {
autosize: true,
placeholder: 'test|example|br|img'
} ),
input2 = new OO.ui.TextInputWidget( {
placeholder: '50',
type: 'number'
} ),
submit = new OO.ui.ButtonInputWidget( {
label: 'Diviser',
flags: [ 'primary', 'progressive' ]
} ),
fieldset = new OO.ui.FieldsetLayout( {
label: 'Diviser un chaîne de caractères'
} );
const inputJoinString = new OO.ui.MultilineTextInputWidget( {
autosize: true,
placeholder: '\'test|example|br|im\' + \'g|span|b|center|i\''
} ),
inputSubstr = new OO.ui.TextInputWidget( {
placeholder: 'img|',
type: 'text'
} ),
submitJoin = new OO.ui.ButtonInputWidget( {
label: 'Envoyer',
flags: [ 'primary', 'progressive' ]
} ),
fieldsetJoin = new OO.ui.FieldsetLayout( {
label: 'Modifier la division de chaînes de caractères',
help: new OO.ui.HtmlSnippet( `Modifier la division entre deux chaînes (obtenues avec le champ ci-dessus).
Le contenu du champ "Sous-chaîne" doit être intégré dans "Chaîne". "Sous-chaîne" sera la dernière instance de la première chaîne.
Exemple : <dl>
<dt>Chaîne</dt>
<dd><code>'test|example|br|im' + 'g|span|dl|center|dd'</code></dd>
<dt>Sous-chaîne</dt>
<dd><code>img|</code></dd>
<dt>Résultat</dt>
<dd><pre>
'test|example|br|img|' +
'span|dl|center|dd'
</pre></dd>
</dl>
` )
} );
fieldset.addItems( [
new OO.ui.FieldLayout( input1, {
label: 'Chaîne à diviser :',
align: 'top',
help: `Une chaîne unique
(les caractères « + » seront considérés comme faisant partie de la chaîne).
`
} ),
new OO.ui.FieldLayout( input2, {
label: 'Nombre de caractères par ligne :',
align: 'top',
help: 'Le maximum de caractères dans chaque chaîne.'
} ),
new OO.ui.FieldLayout( submit )
] );
fieldsetJoin.addItems( [
new OO.ui.FieldLayout( inputJoinString, {
label: 'Chaîne :',
align: 'top'
} ),
new OO.ui.FieldLayout( inputSubstr, {
label: 'Sous-chaîne :',
align: 'top'
} ),
new OO.ui.FieldLayout( submitJoin )
] );
const form = new OO.ui.PanelLayout( {
expanded: false,
framed: true,
padded: true,
$content: $( '<div>' ).append( fieldset.$element ).append( fieldsetJoin.$element )
} );
return {
form: form,
submit: submit,
input1: input1,
input2: input2,
inputString: inputJoinString,
inputSubstr: inputSubstr,
submit2: submitJoin
};
}
/**
* makeCcnormTest
*
* Crée le formulaire "ccnorm test"
*
* @return {Object} Les éléments utilisés dans le reste du code
*/
function makeCcnormTest() {
const input1 = new OO.ui.MultilineTextInputWidget( {
autosize: true,
placeholder: 'aäâã'
} ),
submit = new OO.ui.ButtonInputWidget( {
label: 'Tester',
flags: [ 'primary', 'progressive' ]
} ),
fieldset = new OO.ui.FieldsetLayout( {
label: 'Tester une chaîne avec ccnorm',
help: new OO.ui.HtmlSnippet( `Un message d'erreur sera affiché si la chaîne contient une lettre
ou un chiffre non supporté par la fonction « ccnorm ». Entrer <code>FORCELOAD</code> forcera le chargement
de la liste <code>equivset</code>.` )
} );
fieldset.addItems( [
new OO.ui.FieldLayout( input1, {
label: 'Chaîne à tester :',
align: 'top'
} ),
new OO.ui.FieldLayout( submit )
] );
const form = new OO.ui.PanelLayout( {
expanded: false,
framed: true,
padded: true,
$content: fieldset.$element
} );
return { form: form, submit: submit, input1: input1 };
}
/**
* getEquivset
*
* Récupère la liste d'`equivset` avec l'API Fetch
* et la transforme pour utilisation ultérieure
*
* @async
*/
async function getEquivset() {
const response = await fetch( 'https://raw.githubusercontent.com/wikimedia/Equivset/master/dist/equivset.json' ),
data = await response.json();
let arrayTo = [],
arrayFrom = [];
// eslint-disable-next-line no-underscore-dangle
delete data._readme;
const arrayKeys = Object.keys( data );
for ( const key of arrayKeys ) {
arrayFrom.push( key );
arrayTo.push( data[ key ] );
}
arrayTo = arrayTo.filter(
( item, index ) => arrayTo.indexOf( item ) === index
);
arrayFrom = arrayFrom.filter(
( item, index ) => arrayFrom.indexOf( item ) === index
);
let availableCaracters = arrayTo.concat( arrayFrom );
availableCaracters = availableCaracters.sort().join( '' );
mw.storage.set( 'ccnormAvailable', availableCaracters );
mw.cookie.set( 'ccnormUpdate', '1', 604800 );
}
/**
* ccnormProcess
*
* Fonction utilisé dans le gestionnaire d'évènements du bouton de ccnormTest
* pour pouvoir la réexécuter si la liste de ccnorm est obsolète ou indisponible
*/
function ccnormProcess() {
if ( ( /^\s*$/ ).test( ccnormForm.input1.getValue() ) === true ) {
$( '.aftoolsCcnorm, .aftoolsCcnormEval' ).hide();
$( '#aftoolsCcnormCheck, #aftoolsCcnormEval, #aftoolsCcnorm' ).empty();
ccnormForm.input1.setValidityFlag( false );
return;
}
if ( ccnormForm.input1.getValue() === 'FORCELOAD' ) {
$( '.aftoolsCcnorm, .aftoolsCcnormEval' ).hide();
$( '#aftoolsCcnormCheck, #aftoolsCcnormEval, #aftoolsCcnorm' ).empty();
getEquivset().then( () => {
mw.notify( 'Liste equivset mise à jour.',
{ autoHide: true, autoHideSeconds: 'long', title: 'Succès', type: 'success' } );
} );
return;
}
if ( mw.cookie.get( 'ccnormUpdate' ) === null ) {
getEquivset().then( ccnormProcess );
return;
}
const regexCcnorm = new RegExp( `[^${mw.storage.get( 'ccnormAvailable' )}\\s]`, 'g' ),
stringToTest = ccnormForm.input1
.getValue()
.replace( /(?<!\\)\\(?!['"\\])/g, '\\\\' )
.replace( /^['"]|(?<!\\)['"]$/g, '' )
.replace( /([^\\])?'/g, '$1\\\'' ),
arrayMatch = stringToTest.match( regexCcnorm ),
regex2 = /(?:\p{L}|\p{N}|\p{M})|\p{C}/ug;
new mw.Api().get( {
action: 'abusefilterevalexpression',
format: 'json',
expression: `ccnorm('${stringToTest}')`,
formatversion: '2'
} ).then( function ( response ) {
$( '#aftoolsCcnormCheck, #aftoolsCcnormEval, #aftoolsCcnorm' ).empty();
if (
regexCcnorm.test( stringToTest ) === true &&
( regex2 ).test( arrayMatch.join( '' ) ) === true
) {
const errorUnsupported = new OO.ui.MessageWidget( {
type: 'error',
inline: true,
label: new OO.ui.HtmlSnippet(
'La chaîne contient des caractères non supportés : ces caractères ne seront pas normalisés.'
)
} );
$( '#aftoolsCcnormCheck' ).append( errorUnsupported.$element );
$( '.aftoolsCcnorm, .aftoolsCcnormEval' ).show();
$( '#aftoolsCcnorm' ).text( arrayMatch.join().match( regex2 ).join( ' ' ) );
$( '#aftoolsCcnormEval' ).text( response.abusefilterevalexpression.result );
} else {
const success = new OO.ui.MessageWidget( {
type: 'success',
inline: true,
label: new OO.ui.HtmlSnippet( 'Test effectué avec succès.' )
} );
$( '#aftoolsCcnormCheck' ).append( success.$element );
$( '.aftoolsCcnorm' ).hide();
$( '.aftoolsCcnormEval' ).show();
$( '#aftoolsCcnormEval' ).text( response.abusefilterevalexpression.result );
}
} );
}
// Initalisation
if ( rights.indexOf( 'abusefilter-modify' ) !== 1 ) {
$( '#mw-abusefilter-switcheditor' ).parent().before( progressWidget.$element );
$( progressWidget.$element ).after( '<br>' );
progressWidget.toggle( false );
progressWidget.setProgress( 0 );
$( '#mw-abusefilter-syntaxcheck' ).after( buttonDeprecate.$element );
$( '.mw-abusefilter-javascript-tools' ).first().after(
$( '<span>' )
.attr( 'id', 'abusefilter-checksyntaxresultfield' )
);
if ( ( /\/(tools)/ ).test( mw.config.get( 'wgPageName' ) ) ) {
$( '.printfooter' ).before( formContent.form.$element );
$( formContent.submit.$element ).append( $( '<pre>' ).attr( 'id', 'aftoolsConcat' ) );
$( formContent.submit.$element ).append( '<br>' );
$( '#aftoolsConcat' ).hide();
$( formContent.submit2.$element ).append( $( '<pre>' ).attr( 'id', 'aftoolsJoin' ) );
$( formContent.submit2.$element ).append( '<br>' );
$( '#aftoolsJoin' ).hide();
$( '.printfooter' ).before( ccnormForm.form.$element );
$( ccnormForm.submit.$element )
.append( '<br>' )
.append( '<br>' )
.append(
$( '<div>' )
.append(
$( '<div>' )
.attr( 'id', 'aftoolsCcnormCheck' )
)
.append(
$( '<h5>' )
.attr( 'class', 'aftoolsCcnorm' )
.text( 'Caractères non supportés' )
)
.append(
$( '<pre>' )
.attr( { class: 'aftoolsCcnorm', id: 'aftoolsCcnorm' } )
)
.append(
$( '<h5>' )
.attr( 'class', 'aftoolsCcnormEval' )
.html( 'Résultat de l\'exécution de <code>ccnorm()</code>' )
).append(
$( '<pre>' )
.attr( { class: 'aftoolsCcnormEval', id: 'aftoolsCcnormEval' } )
)
);
$( '.aftoolsCcnorm, .aftoolsCcnormEval' ).hide();
}
} else {
mw.log.warn( 'You must be AbuseFilter editor to use this script' );
}
// Corriger le code
buttonDeprecate.on( 'click', () => {
const useAce = $( document.getElementById( 'wpFilterRules' ) ).css( 'display' ) === 'none';
if ( $( '.ace_text-layer' ).children().find( '.ace_deprecated' ).length !== 0 ) {
const articleVar = {
articleid: 'page_id',
namespace: 'page_namespace',
text: 'page_title',
prefixedtext: 'page_prefixedtitle',
restrictionsEdit: 'page_restrictions_edit',
restrictionsMove: 'page_restrictions_move',
restrictionsUpload: 'page_restrictions_upload',
restrictionsCreate: 'page_restrictions_create',
recentContributors: 'page_recent_contributors',
firstContributor: 'page_first_contributor'
},
moved = {
toArticleid: 'moved_to_id',
toText: 'moved_to_title',
toPrefixedtext: 'moved_to_prefixedtitle',
fromArticleid: 'moved_from_id',
fromText: 'moved_from_title',
fromPrefixedtext: 'moved_from_prefixedtitle'
},
extensions = {
boardArticleid: 'board_id',
boardText: 'board_title',
boardPrefixedtext: 'board_prefixedtitle',
articleViews: 'page_views'
};
// article_
const abusefilterNewText = getInputContent()
.replace( /article_articleid/ig, articleVar.articleid )
.replace( /article_namespace/ig, articleVar.namespace )
.replace( /article_text/ig, articleVar.text )
.replace( /article_prefixedtext/ig, articleVar.prefixedtext )
.replace(
/article_restrictions_edit/ig,
articleVar.restrictionsEdit
)
.replace(
/article_restrictions_move/ig,
articleVar.restrictionsMove
)
.replace(
/article_restrictions_upload/ig,
articleVar.restrictionsUpload
)
.replace(
/article_restrictions_create/ig,
articleVar.restrictionsCreate
)
.replace(
/article_recent_contributors/ig,
articleVar.recentContributors
)
.replace(
/article_first_contributor/ig,
articleVar.firstContributor
)
// moved_
.replace( /moved_to_articleid/ig, moved.toArticleid )
.replace( /moved_to_text/ig, moved.toText )
.replace( /moved_to_prefixedtext/ig, moved.toPrefixedtext )
.replace( /moved_from_articleid/ig, moved.fromArticleid )
.replace( /moved_from_text/ig, moved.fromText )
.replace( /moved_from_prefixedtext/ig, moved.fromPrefixedtext )
// extensions
.replace( /board_articleid/ig, extensions.boardArticleid )
.replace( /board_text/ig, extensions.boardText )
.replace( /board_prefixedtext/ig, extensions.boardPrefixedtext )
.replace( /article_views/ig, extensions.articleViews );
// Application des modifications
if ( useAce === true ) {
ace.edit( 'wpAceFilterEditor' ).session.setValue( abusefilterNewText );
} else {
document.getElementById( 'wpFilterRules' ).value = abusefilterNewText;
}
} else {
if ( useAce ) {
ace.edit( 'wpAceFilterEditor' ).session.setValue( getInputContent() );
ace.edit( 'wpAceFilterEditor' ).session.setValue( beautifyCode() );
}
}
} );
// ccnorm
ccnormForm.submit.on( 'click', ccnormProcess );
// Réunir des chaînes
formContent.submit2.on( 'click', function () {
if ( formContent.inputString.getValue() === '' && formContent.inputSubstr.getValue() === '' ) {
formContent.inputString.setValidityFlag( false );
formContent.inputSubstr.setValidityFlag( false );
$( '#aftoolsJoin' ).hide();
return;
} else if ( formContent.inputString.getValue() === '' ) {
formContent.inputString.setValidityFlag( false );
$( '#aftoolsJoin' ).hide();
return;
} else if ( formContent.inputSubstr.getValue() === '' ) {
formContent.inputSubstr.setValidityFlag( false );
$( '#aftoolsJoin' ).hide();
return;
}
const stringToSplit = formContent.inputString
.getValue()
.replace( /^["']|(?<!\\)["']$/g, '' )
.replace( /(?<!\\)["'][\s]*\+[\s]*["']/g, '' ),
subString = formContent.inputSubstr
.getValue()
.replace( /^["']|(?<!\\)["']$/g, '' ),
arraySubstr = stringToSplit.split( subString );
arraySubstr[ 0 ] += subString;
const newString = arraySubstr.join( '\' + \n\'' );
$( '#aftoolsJoin' ).show();
$( '#aftoolsJoin' ).text( newString.replace( /^|$/g, '\'' ) );
} );
// Diviser un chaîne
formContent.submit.on( 'click', function () {
if ( ( /[0-9]+/ ).test( formContent.input2.getValue() ) !== true && formContent.input1.getValue() === '' ) {
formContent.input2.setValidityFlag( false );
formContent.input1.setValidityFlag( false );
$( '#aftoolsConcat' ).hide();
return;
} else if ( ( /[0-9]+/ ).test( formContent.input2.getValue() ) !== true ) {
formContent.input2.setValidityFlag( false );
$( '#aftoolsConcat' ).hide();
return;
} else if ( formContent.input1.getValue() === '' ) {
formContent.input1.setValidityFlag( false );
$( '#aftoolsConcat' ).hide();
return;
}
let index,
stringToSlice = formContent.input1
.getValue()
.replace( /(^["']|["']$)/g, '' )
.replace( /(?<!\\)'/g, '\\\'' ),
stringConcat = '';
const number = Number( formContent.input2.getValue() ),
numberMatch = Math.floor( stringToSlice.length / number ),
string = [];
for ( index = 0; index < numberMatch; index++ ) {
string.push( stringToSlice.slice( 0, number ) );
stringToSlice = stringToSlice.slice( number );
}
string.push( stringToSlice );
for ( const text of string ) {
stringConcat += `'${text}' +\n`;
}
stringConcat = stringConcat.replace( / [+]\n?$/, '' );
$( '#aftoolsConcat' ).show();
$( '#aftoolsConcat' ).text( stringConcat );
} );
// Vérifier la syntaxe
$( '#mw-abusefilter-syntaxcheck' ).off();
$( '#mw-abusefilter-syntaxcheck' ).on( 'click', function () {
const text = $( '#wpFilterRules' ).val(),
useAce = $( '#wpFilterRules' ).css( 'display' ) === 'none',
filterEditor = ace.edit( 'wpAceFilterEditor' );
if ( progressWidget.isPending() === false ) {
progressWidget.pushPending();
progressWidget.setProgress( false );
} else {
return;
}
if ( progressWidget.isVisible() === false ) {
progressWidget.toggle();
}
new mw.Api().post( {
action: 'abusefilterchecksyntax',
format: 'json',
filter: text,
formatversion: '2'
} ).then( ( result ) => {
const data = result.abusefilterchecksyntax,
// eslint-disable-next-line max-len
regexDeprecated = /(?<![A-Za-z_])(article_(articleid|namespace|text|prefixedtext|restrictions_(edit|move|upload|create)|recent_contributors|first_contributor)|moved_(to|from)_(articleid|text|prefixedtext)|board_(articleid|text|prefixedtext)|article_views)/g,
// eslint-disable-next-line max-len
performanceVariable = /(?<![A-Za-z_])((edit_diff|added_lines|new)_pst|(added|removed)_links|page_(recent_contributors|first_contributor)|new_(html|text)|(old|new)_wikitext)/g,
// eslint-disable-next-line max-len
fileVariable = /(?<![A-Za-z_])(file_(width|size|sha1|mime|mediatype|height|bits_per_channel))/g,
// eslint-disable-next-line max-len
uploadAction = /(?<![A-Za-z_])action[\s]*===?[\s]*['"](upload|stashupload)['"]/g,
// eslint-disable-next-line max-len
moveVariable = /(?<![A-Za-z_])(moved_(from|to)_(age|first_contributor|id|namespace|prefixedtitle|recent_contributors|restrictions_create|restrictions_edit|restrictions_move|restrictions_upload|title))/g,
moveAction = /(?<![A-Za-z_])action[\s]*===?[\s]*['"]move['"]/g,
// eslint-disable-next-line max-len
editVariable = /(?<![A-Za-z_])((old|new)_(wikitext|size)|edit_diff(_pst)?|edit_delta|(added|removed)_lines(_pst)?|(all|old|added|removed)_links|new_(pst|html|text))/g,
editAction = /(?<![A-Za-z_])action[\s]*===?[\s]*['"]edit['"]/g;
$( '#abusefilter-checksyntaxresultfield' ).empty();
if ( data.status === 'ok' ) {
const messageOk = new OO.ui.MessageWidget( {
type: 'success',
inline: true,
label: mw.msg( 'abusefilter-edit-syntaxok' )
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messageOk.$element );
} else if ( data.status === 'error' ) {
const messageError = new OO.ui.MessageWidget( {
type: 'error',
inline: true,
label: mw.message( 'abusefilter-edit-syntaxerr' ).params( [ data.message ] ).text()
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messageError.$element );
if ( useAce === true ) {
const position = filterEditor
.session
.getDocument()
.indexToPosition( data.character );
filterEditor.focus();
filterEditor.navigateTo( position.row, position.column );
filterEditor.scrollToRow( position.row );
} else {
$( document.getElementById( 'wpFilterRules' ) ).trigger( 'focus' ).textSelection( 'setSelection', {
start: data.character
} );
}
}
// Variables obsolètes
if ( regexDeprecated.test( text ) ) {
const deprectatedArray = text.match( regexDeprecated );
const messageDeprecated = new OO.ui.MessageWidget( {
type: 'warning',
inline: true,
label: `Problème potentiel identifié : Ce code contient des variables obsolètes (${deprectatedArray.join( ', ' )}).`
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messageDeprecated.$element );
}
// Performances
if (
( /\/\*[\s]?aftools-disable-perfs[\s]?\*\//ig )
.test( text ) === false &&
performanceVariable.test( text )
) {
let isPst, isLinks, isPreferLines, isGeneral;
const pstVar = [],
pstAlt = [],
linksVar = [],
preferLinesVar = [],
generalVar = [];
const performanceArray = text.match( performanceVariable );
for ( const variable of performanceArray ) {
if ( ( /_pst$/i ).test( variable ) === true ) {
isPst = true;
pstVar.push( variable );
pstAlt.push( variable.replace( /_pst$/i, '' ) );
} else if (
( /_links$/i ).test( variable ) === true
) {
isLinks = true;
linksVar.push( variable );
} else if (
( /(?:_wikitext|_text|_html)$/i )
.test( variable )
) {
isPreferLines = true;
preferLinesVar.push( variable );
} else {
isGeneral = true;
generalVar.push( variable );
}
}
let stringMsg = 'Suggestion d\'amélioration : ';
if ( isPst === true ) {
stringMsg += `Ce filtre contient des variables <code>_pst</code> (${pstVar.join( ', ' )}) :
remplacez-les par leurs alternatives (${pstAlt.join( ', ' )}) dans la mesure du possible ou vérifiez les alternatives
avant les variables <code>_pst</code>. `;
}
if ( isLinks === true ) {
stringMsg += `Ce filtre contient des variables <code>_links</code> (${linksVar.join( ', ' )}) :
ne les utilisez que si vous avez besoin d'une grande précision ou que l'utilisation d'<code>added_lines</code> ou
<code>removed_lines</code> pourrait conduire à des dysfonctionnements. `;
}
if ( isPreferLines === true ) {
stringMsg += `Ce filtre contient des variables potentiellement lourdes (${preferLinesVar.join( ', ' )}) :
utilisez <code>added_lines</code> ou <code>removed_lines</code> si possible. `;
}
if ( isGeneral === true ) {
stringMsg += `Ce filtre contient des variables nécessitant une requête à la base de données
(${generalVar.join( ', ' )}) : formulez les conditions de la façon la plus stricte possible pour éviter des requêtes superflues. `;
}
stringMsg += `
Lire <a href="https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:AbuseFilter/Rules_format#Performance">ceci</a> pour plus de détails.
Ajoutez <code>/* aftools-disable-perfs */</code> au début du code après avoir effectué les corrections.`;
const messagePerformance = new OO.ui.MessageWidget( {
type: 'notice',
inline: true,
label: new OO.ui.HtmlSnippet( stringMsg )
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messagePerformance.$element );
}
// Variables restreintes
if (
uploadAction.test( text ) === false &&
fileVariable.test( text ) === true
) {
const fileVariableArray = text.match( fileVariable );
const messageRestrictedVariable = new OO.ui.MessageWidget( {
type: 'warning',
inline: true,
label: new OO.ui.HtmlSnippet( `
Problème potentiel identifié : Ce code contient des variables à l'utilisation restreinte (${fileVariableArray.join( ', ' )}),
ces variables ne peuvent être utilisées qu'avec les actions <code>upload</code> et <code>stashupload</code>.
Pour résoudre ce problème, ajoutez <code>action === 'upload'</code> ou <code>action === 'stashupload'</code> ou <code>action === 'stashupload' | action === 'upload'</code>
au code conditionnel.` )
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messageRestrictedVariable.$element );
}
if (
moveAction.test( text ) === false &&
moveVariable.test( text ) === true
) {
const moveVariableArray = text.match( moveVariable );
const messageRestrictedVariable = new OO.ui.MessageWidget( {
type: 'warning',
inline: true,
label: new OO.ui.HtmlSnippet( `
Problème potentiel identifié : Ce code contient des variables à l'utilisation restreinte (${moveVariableArray.join( ', ' )}),
ces variables ne peuvent être utilisées qu'avec l'action <code>move</code>.
Pour résoudre ce problème, ajoutez <code>action === 'move'</code> au code conditionnel.` )
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messageRestrictedVariable.$element );
}
if (
editAction.test( text ) === false &&
editVariable.test( text ) === true
) {
const editVariableArray = text.match( editVariable );
const messageRestrictedVariable = new OO.ui.MessageWidget( {
type: 'warning',
inline: true,
label: new OO.ui.HtmlSnippet( `
Problème potentiel identifié : Ce code contient des variables à l'utilisation restreinte (${editVariableArray.join( ', ' )}),
ces variables ne peuvent être utilisées qu'avec l'action <code>edit</code>.
Pour résoudre ce problème, ajoutez <code>action === 'edit'</code> au code conditionnel.` )
} );
$( '#abusefilter-checksyntaxresultfield' ).append( messageRestrictedVariable.$element );
}
progressWidget.toggle();
progressWidget.popPending();
progressWidget.setProgress( false );
}, () => {
progressWidget.toggle();
progressWidget.popPending();
progressWidget.setProgress( false );
} );
} );
} );
} );
}
} );