( function ( $, mw ) {
var simpleSample, U_20AC, mbSample;
QUnit.module( 'jquery.byteLimit', QUnit.newMwEnvironment() );
// Simple sample (20 chars, 20 bytes)
simpleSample = '12345678901234567890';
// 3 bytes (euro-symbol)
U_20AC = '\u20AC';
// Multi-byte sample (22 chars, 26 bytes)
mbSample = '1234567890' + U_20AC + '1234567890' + U_20AC;
// Basic sendkey-implementation
function addChars( $input, charstr ) {
var c, len;
function x( $input, i ) {
// Add character to the value
return $input.val() + charstr.charAt( i );
}
for ( c = 0, len = charstr.length; c < len; c += 1 ) {
$input
.val( x( $input, c ) )
.trigger( 'change' );
}
}
/**
* Test factory for $.fn.byteLimit
*
* @param {Object} options
* @param {string} options.description Test name
* @param {jQuery} options.$input jQuery object in an input element
* @param {string} options.sample Sequence of characters to simulate being
* added one by one
* @param {string} options.expected Expected final value of `$input`
*/
function byteLimitTest( options ) {
var opt = $.extend( {
description: '',
$input: null,
sample: '',
expected: ''
}, options );
QUnit.asyncTest( opt.description, 1, function ( assert ) {
setTimeout( function () {
opt.$input.appendTo( '#qunit-fixture' );
// Simulate pressing keys for each of the sample characters
addChars( opt.$input, opt.sample );
assert.equal(
opt.$input.val(),
opt.expected,
'New value matches the expected string'
);
QUnit.start();
}, 10 );
} );
}
byteLimitTest( {
description: 'Plain text input',
$input: $( '' ),
sample: simpleSample,
expected: simpleSample
} );
byteLimitTest( {
description: 'Plain text input. Calling byteLimit with no parameters and no maxlength attribute (bug 36310)',
$input: $( '' )
.byteLimit(),
sample: simpleSample,
expected: simpleSample
} );
byteLimitTest( {
description: 'Limit using the maxlength attribute',
$input: $( '' )
.attr( 'maxlength', '10' )
.byteLimit(),
sample: simpleSample,
expected: '1234567890'
} );
byteLimitTest( {
description: 'Limit using a custom value',
$input: $( '' )
.byteLimit( 10 ),
sample: simpleSample,
expected: '1234567890'
} );
byteLimitTest( {
description: 'Limit using a custom value, overriding maxlength attribute',
$input: $( '' )
.attr( 'maxlength', '10' )
.byteLimit( 15 ),
sample: simpleSample,
expected: '123456789012345'
} );
byteLimitTest( {
description: 'Limit using a custom value (multibyte)',
$input: $( '' )
.byteLimit( 14 ),
sample: mbSample,
expected: '1234567890' + U_20AC + '1'
} );
byteLimitTest( {
description: 'Limit using a custom value (multibyte) overlapping a byte',
$input: $( '' )
.byteLimit( 12 ),
sample: mbSample,
expected: '1234567890' + '12'
} );
byteLimitTest( {
description: 'Pass the limit and a callback as input filter',
$input: $( '' )
.byteLimit( 6, function ( val ) {
var title = mw.Title.newFromText( String( val ) );
// Return without namespace prefix
return title ? title.getMain() : '';
} ),
sample: 'User:Sample',
expected: 'User:Sample'
} );
byteLimitTest( {
description: 'Limit using the maxlength attribute and pass a callback as input filter',
$input: $( '' )
.attr( 'maxlength', '6' )
.byteLimit( function ( val ) {
var title = mw.Title.newFromText( String( val ) );
// Return without namespace prefix
return title ? title.getMain() : '';
} ),
sample: 'User:Sample',
expected: 'User:Sample'
} );
byteLimitTest( {
description: 'Pass the limit and a callback as input filter',
$input: $( '' )
.byteLimit( 6, function ( val ) {
var title = mw.Title.newFromText( String( val ) );
// Return without namespace prefix
return title ? title.getMain() : '';
} ),
sample: 'User:Example',
// The callback alters the value to be used to calculeate
// the length. The altered value is "Exampl" which has
// a length of 6, the "e" would exceed the limit.
expected: 'User:Exampl'
} );
byteLimitTest( {
description: 'Input filter that increases the length',
$input: $( '' )
.byteLimit( 10, function ( text ) {
return 'prefix' + text;
} ),
sample: simpleSample,
// Prefix adds 6 characters, limit is reached after 4
expected: '1234'
} );
// Regression tests for bug 41450
byteLimitTest( {
description: 'Input filter of which the base exceeds the limit',
$input: $( '' )
.byteLimit( 3, function ( text ) {
return 'prefix' + text;
} ),
sample: simpleSample,
hasLimit: true,
limit: 6, // 'prefix' length
expected: ''
} );
QUnit.test( 'Confirm properties and attributes set', 4, function ( assert ) {
var $el, $elA, $elB;
$el = $( '' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' )
.byteLimit();
assert.strictEqual( $el.attr( 'maxlength' ), '7', 'maxlength attribute unchanged for simple limit' );
$el = $( '' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' )
.byteLimit( 12 );
assert.strictEqual( $el.attr( 'maxlength' ), '12', 'maxlength attribute updated for custom limit' );
$el = $( '' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' )
.byteLimit( 12, function ( val ) {
return val;
} );
assert.strictEqual( $el.attr( 'maxlength' ), undefined, 'maxlength attribute removed for limit with callback' );
$elA = $( '' )
.addClass( 'mw-test-byteLimit-foo' )
.attr( 'maxlength', '7' )
.appendTo( '#qunit-fixture' );
$elB = $( '' )
.addClass( 'mw-test-byteLimit-foo' )
.attr( 'maxlength', '12' )
.appendTo( '#qunit-fixture' );
$el = $( '.mw-test-byteLimit-foo' );
assert.strictEqual( $el.length, 2, 'Verify that there are no other elements clashing with this test suite' );
$el.byteLimit();
} );
QUnit.test( 'Trim from insertion when limit exceeded', 2, function ( assert ) {
var $el;
// Use a new because the bug only occurs on the first time
// the limit it reached (bug 40850)
$el = $( '' )
.appendTo( '#qunit-fixture' )
.byteLimit( 3 )
.val( 'abc' ).trigger( 'change' )
.val( 'zabc' ).trigger( 'change' );
assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 0), not the end' );
$el = $( '' )
.appendTo( '#qunit-fixture' )
.byteLimit( 3 )
.val( 'abc' ).trigger( 'change' )
.val( 'azbc' ).trigger( 'change' );
assert.strictEqual( $el.val(), 'abc', 'Trim from the insertion point (at 1), not the end' );
} );
}( jQuery, mediaWiki ) );