mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/AbuseFilter.git
synced 2024-11-25 06:26:03 +00:00
20dabefe22
The API provides more details about HTTP errors, so show these to the user instead of a generic "An unknown error occurred." Bug: 68767 Change-Id: I3188b9729c815a07c65a7dbef4d40deebe29b87d
311 lines
8 KiB
JavaScript
311 lines
8 KiB
JavaScript
/**
|
|
* AbuseFilter editing JavaScript
|
|
*
|
|
* @author John Du Hart
|
|
* @author Marius Hoch <hoo@online.de>
|
|
*/
|
|
|
|
( function( mw, $ ) {
|
|
'use strict';
|
|
|
|
// Filter textarea
|
|
// @var {jQuery}
|
|
var $filterBox;
|
|
|
|
/**
|
|
* Returns the currently selected warning message
|
|
*
|
|
* @returns {string} current warning message
|
|
*/
|
|
function getCurrentWarningMessage() {
|
|
var message = $( '#mw-abusefilter-warn-message-existing' ).val();
|
|
|
|
if ( message === 'other' ) {
|
|
message = $( '#mw-abusefilter-warn-message-other' ).val();
|
|
}
|
|
|
|
return message;
|
|
}
|
|
|
|
/**
|
|
* Sends the current filter text to be checked for syntax issues.
|
|
*
|
|
* @context HTMLElement
|
|
* @param {jQuery.Event} e
|
|
*/
|
|
function doSyntaxCheck() {
|
|
/*jshint validthis:true */
|
|
var filter = $filterBox.val(),
|
|
api = new mw.Api();
|
|
|
|
$( this )
|
|
.attr( 'disabled', 'disabled' )
|
|
.injectSpinner( 'abusefilter-syntaxcheck' );
|
|
|
|
api.post( {
|
|
action: 'abusefilterchecksyntax',
|
|
filter: filter
|
|
} )
|
|
.done( processSyntaxResult )
|
|
.fail( processSyntaxResultFailure );
|
|
}
|
|
|
|
/**
|
|
* Things always needed after syntax checks
|
|
*
|
|
* @param {string} resultText
|
|
* @param {string} className Class to add
|
|
* @param {bool} syntaxOk Is the syntax ok?
|
|
*/
|
|
function processSyntaxResultAlways( resultText, className, syntaxOk ) {
|
|
$.removeSpinner( 'abusefilter-syntaxcheck' );
|
|
$( '#mw-abusefilter-syntaxcheck' ).removeAttr( 'disabled' );
|
|
|
|
$( '#mw-abusefilter-syntaxresult' )
|
|
.show()
|
|
.removeClass( 'mw-abusefilter-syntaxresult-ok mw-abusefilter-syntaxresult-error' )
|
|
.text( resultText )
|
|
.addClass( className )
|
|
.data( 'syntaxOk', syntaxOk );
|
|
}
|
|
|
|
/**
|
|
* Takes the data retrieved in doSyntaxCheck and processes it
|
|
*
|
|
* @param {Object} data Data returned from the AJAX request
|
|
*/
|
|
function processSyntaxResult( data ) {
|
|
data = data.abusefilterchecksyntax;
|
|
|
|
if ( data.status === 'ok' ) {
|
|
// Successful
|
|
processSyntaxResultAlways(
|
|
mw.msg( 'abusefilter-edit-syntaxok' ),
|
|
'mw-abusefilter-syntaxresult-ok',
|
|
true
|
|
);
|
|
} else {
|
|
// Set a custom error message as we're aware of the actual problem
|
|
processSyntaxResultAlways(
|
|
mw.message( 'abusefilter-edit-syntaxerr', data.message ).toString(),
|
|
'mw-abusefilter-syntaxresult-error',
|
|
false
|
|
);
|
|
|
|
$filterBox
|
|
.focus()
|
|
.textSelection( 'setSelection', { start: data.character } );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Acts on errors after doSyntaxCheck
|
|
*
|
|
* @param {string} error Error code returned from the AJAX request
|
|
* @param {Object} details Details about the error
|
|
*/
|
|
function processSyntaxResultFailure( error, details ) {
|
|
var msg = error === 'http' ? 'abusefilter-http-error' : 'unknown-error';
|
|
processSyntaxResultAlways(
|
|
mw.msg( msg, details && details.exception ),
|
|
'mw-abusefilter-syntaxresult-error',
|
|
false
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Adds text to the filter textarea
|
|
* Fired by a change event from the #wpFilterBuilder dropdown
|
|
*/
|
|
function addText() {
|
|
var $filterBuilder = $( '#wpFilterBuilder' );
|
|
|
|
if ( $filterBuilder.prop( 'selectedIndex' ) === 0 ) {
|
|
return;
|
|
}
|
|
|
|
$filterBox.textSelection(
|
|
'encapsulateSelection', { 'pre': $filterBuilder.val() + ' ' }
|
|
);
|
|
$filterBuilder.prop( 'selectedIndex', 0 );
|
|
}
|
|
|
|
/**
|
|
* Fetches a filter from the API and inserts it into the filter box.
|
|
*
|
|
* @context HTMLElement
|
|
* @param {jQuery.Event} e
|
|
*/
|
|
function fetchFilter() {
|
|
/*jshint validthis:true */
|
|
var filterId = $.trim( $( '#mw-abusefilter-load-filter' ).val() ),
|
|
api;
|
|
|
|
if ( filterId === '' ) {
|
|
return;
|
|
}
|
|
|
|
$( this ).injectSpinner( 'fetch-spinner' );
|
|
|
|
// We just ignore errors or unexisting filters over here
|
|
api = new mw.Api();
|
|
api.get( {
|
|
action: 'query',
|
|
list: 'abusefilters',
|
|
abfprop: 'pattern',
|
|
abfstartid: filterId,
|
|
abfendid: filterId,
|
|
abflimit: 1
|
|
} )
|
|
.always( function() {
|
|
$.removeSpinner( 'fetch-spinner' );
|
|
} )
|
|
.done( function( data ) {
|
|
if ( data.query.abusefilters[0] !== undefined ) {
|
|
$filterBox.val( data.query.abusefilters[0].pattern );
|
|
}
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Cycles through all action checkboxes and hides parameter divs
|
|
* that don't have checked boxes
|
|
*/
|
|
function hideDeselectedActions() {
|
|
$( 'input.mw-abusefilter-action-checkbox' ).each( function() {
|
|
// mw-abusefilter-action-checkbox-{$action}
|
|
var action = this.id.substr( 31 ),
|
|
$params = $( '#mw-abusefilter-' + action + '-parameters' );
|
|
|
|
if ( $params.length ) {
|
|
if ( this.checked ) {
|
|
$params.show();
|
|
} else {
|
|
$params.hide();
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Fetches the selected warning message for previewing
|
|
*/
|
|
function previewWarnMessage() {
|
|
$.get(
|
|
mw.config.get( 'wgScript' ), {
|
|
title: 'MediaWiki:' + getCurrentWarningMessage(),
|
|
action: 'render'
|
|
}
|
|
)
|
|
.done( function( messageHtml ) {
|
|
// Replace $1 with the description of the filter
|
|
messageHtml = messageHtml.replace(
|
|
/\$1/g,
|
|
mw.html.escape( $( 'input[name=wpFilterDescription]' ).val() )
|
|
);
|
|
|
|
$( '#mw-abusefilter-warn-preview' ).html( messageHtml );
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Redirects the browser to the warning message for editing
|
|
*/
|
|
function editWarnMessage() {
|
|
var message = getCurrentWarningMessage();
|
|
|
|
window.location = mw.config.get( 'wgScript' ) + '?title=MediaWiki:' + mw.util.wikiUrlencode( message ) + '&action=edit&preload=MediaWiki:abusefilter-warning';
|
|
}
|
|
|
|
/**
|
|
* Called if the filter group (#mw-abusefilter-edit-group-input) is changed.
|
|
*
|
|
* @context HTMLELement
|
|
* @param {jQuery.Event} e
|
|
*/
|
|
function onFilterGroupChange() {
|
|
/*jshint validthis:true */
|
|
var $afWarnMessageExisting, $afWarnMessageOther, newVal;
|
|
|
|
if ( !$( '#mw-abusefilter-action-warn-checkbox' ).is( ':checked' ) ) {
|
|
$afWarnMessageExisting = $( '#mw-abusefilter-warn-message-existing' );
|
|
$afWarnMessageOther = $( '#mw-abusefilter-warn-message-other' );
|
|
newVal = mw.config.get( 'wgAbuseFilterDefaultWarningMessage' )[$( this ).val()];
|
|
|
|
if ( $afWarnMessageExisting.find( 'option[value=\'' + newVal + '\']' ).length ) {
|
|
$afWarnMessageExisting.val( newVal );
|
|
$afWarnMessageOther.val( '' );
|
|
} else {
|
|
$afWarnMessageExisting.val( 'other' );
|
|
$afWarnMessageOther.val( newVal );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove the options for warning messages if the filter is set to global
|
|
*/
|
|
function toggleCustomMessages() {
|
|
// Use the table over here as hideDeselectedActions might alter the visibility of the div
|
|
var $warnOptions = $( '#mw-abusefilter-warn-parameters > table' );
|
|
|
|
if ( $( '#wpFilterGlobal' ).is( ':checked' ) ) {
|
|
// It's a global filter, so use the default message and hide the option from the user
|
|
$( '#mw-abusefilter-warn-message-existing option[value="abusefilter-warning"]' )
|
|
.prop( 'selected', true );
|
|
|
|
$warnOptions.hide();
|
|
} else {
|
|
$warnOptions.show();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called if the user presses a key in the load filter field
|
|
*
|
|
* @context HTMLELement
|
|
* @param {jQuery.Event} e
|
|
*/
|
|
function onFilterKeypress( e ) {
|
|
if ( e.type === 'keypress' && e.which === 13 ) {
|
|
e.preventDefault();
|
|
$( '#mw-abusefilter-load' ).click();
|
|
}
|
|
}
|
|
|
|
// On ready initialization
|
|
$( document ).ready( function() {
|
|
var $exportBox = $( '#mw-abusefilter-export' );
|
|
$filterBox = $( '#' + mw.config.get( 'abuseFilterBoxName' ) );
|
|
// Hide the syntax ok message when the text changes
|
|
$filterBox.keyup( function() {
|
|
var $el = $( '#mw-abusefilter-syntaxresult' );
|
|
|
|
if ( $el.data( 'syntaxOk' ) ) {
|
|
$el.hide();
|
|
}
|
|
} );
|
|
|
|
$( '#mw-abusefilter-load' ).click( fetchFilter );
|
|
$( '#mw-abusefilter-load-filter' ).keypress( onFilterKeypress );
|
|
$( '#mw-abusefilter-warn-preview-button' ).click( previewWarnMessage );
|
|
$( '#mw-abusefilter-warn-edit-button' ).click( editWarnMessage );
|
|
$( 'input.mw-abusefilter-action-checkbox' ).click( hideDeselectedActions );
|
|
hideDeselectedActions();
|
|
|
|
$( '#wpFilterGlobal' ).change( toggleCustomMessages );
|
|
toggleCustomMessages();
|
|
|
|
$( '#mw-abusefilter-syntaxcheck' ).click( doSyntaxCheck );
|
|
$( '#wpFilterBuilder' ).change( addText );
|
|
$( '#mw-abusefilter-edit-group-input' ).change( onFilterGroupChange );
|
|
|
|
$( '#mw-abusefilter-export-link' ).click(
|
|
function( e ) {
|
|
e.preventDefault();
|
|
$exportBox.toggle();
|
|
}
|
|
);
|
|
} );
|
|
} ( mediaWiki, jQuery ) );
|