2 var simpleSample
, U_20AC
, mbSample
;
4 module( 'jquery.byteLimit', QUnit
.newMwEnvironment() );
6 // Simple sample (20 chars, 20 bytes)
7 simpleSample
= '12345678901234567890';
9 // 3 bytes (euro-symbol)
12 // Multi-byte sample (22 chars, 26 bytes)
13 mbSample
= '1234567890' + U_20AC
+ '1234567890' + U_20AC
;
15 // Basic sendkey-implementation
16 function addChars( $input
, charstr
) {
17 var len
, i
, prevVal
, code
, event
;
19 for ( i
= 0; i
< len
; i
+= 1 ) {
20 // Keep track of the previous value
21 prevVal
= $input
.val();
24 code
= charstr
.charCodeAt( i
);
26 // Trigger event and undo if prevented
27 event
= new jQuery
.Event( 'keypress', {
32 $input
.trigger( event
);
33 if ( !event
.isDefaultPrevented() ) {
34 $input
.val( prevVal
+ charstr
.charAt( i
) );
40 * Test factory for $.fn.byteLimit
42 * @param $input {jQuery} jQuery object in an input element
43 * @param hasLimit {Boolean} Wether a limit should apply at all
44 * @param limit {Number} Limit (if used) otherwise undefined
45 * The limit should be less than 20 (the sample data's length)
47 function byteLimitTest( options
) {
57 test( opt
.description
, function () {
58 var rawVal
, fn
, newVal
;
60 opt
.$input
.appendTo( '#qunit-fixture' );
62 // Simulate pressing keys for each of the sample characters
63 addChars( opt
.$input
, opt
.sample
);
64 rawVal
= opt
.$input
.val();
65 fn
= opt
.$input
.data( 'byteLimit-callback' );
66 newVal
= $.isFunction( fn
) ? fn( rawVal
) : rawVal
;
72 $.byteLength( newVal
),
74 'Prevent keypresses after byteLimit was reached, length never exceeded the limit'
77 $.byteLength( rawVal
),
78 $.byteLength( opt
.expected
),
79 'Not preventing keypresses too early, length has reached the expected length'
81 equal( rawVal
, opt
.expected
, 'New value matches the expected string' );
85 equal( newVal
, opt
.expected
, 'New value matches the expected string' );
87 $.byteLength( newVal
),
88 $.byteLength( opt
.expected
),
89 'Unlimited scenarios are not affected, expected length reached'
95 test( '-- Initial check', function () {
97 ok( $.fn
.byteLimit
, 'jQuery.fn.byteLimit defined' );
101 description
: 'Plain text input',
102 $input
: $( '<input>' )
103 .attr( 'type', 'text' ),
104 sample
: simpleSample
,
106 expected
: simpleSample
110 description
: 'Plain text input. Calling byteLimit with no parameters and no maxLength property (bug 36310)',
111 $input
: $( '<input>' )
112 .attr( 'type', 'text' )
114 sample
: simpleSample
,
116 expected
: simpleSample
120 description
: 'Limit using the maxlength attribute',
121 $input
: $( '<input>' )
122 .attr( 'type', 'text' )
123 .prop( 'maxLength', '10' )
125 sample
: simpleSample
,
128 expected
: '1234567890'
132 description
: 'Limit using a custom value',
133 $input
: $( '<input>' )
134 .attr( 'type', 'text' )
136 sample
: simpleSample
,
139 expected
: '1234567890'
143 description
: 'Limit using a custom value, overriding maxlength attribute',
144 $input
: $( '<input>' )
145 .attr( 'type', 'text' )
146 .prop( 'maxLength', '10' )
148 sample
: simpleSample
,
151 expected
: '123456789012345'
155 description
: 'Limit using a custom value (multibyte)',
156 $input
: $( '<input>' )
157 .attr( 'type', 'text' )
162 expected
: '1234567890' + U_20AC
+ '1'
166 description
: 'Limit using a custom value (multibyte) overlapping a byte',
167 $input
: $( '<input>' )
168 .attr( 'type', 'text' )
173 expected
: '1234567890' + '12'
177 description
: 'Pass the limit and a callback as input filter',
178 $input
: $( '<input>' )
179 .attr( 'type', 'text' )
180 .byteLimit( 6, function ( val
) {
186 // Return without namespace prefix
187 return new mw
.Title( String( val
) ).getMain();
189 sample
: 'User:Sample',
191 limit
: 6, // 'Sample' length
192 expected
: 'User:Sample'
196 description
: 'Limit using the maxlength attribute and pass a callback as input filter',
197 $input
: $( '<input>' )
198 .attr( 'type', 'text' )
199 .prop( 'maxLength', '6' )
200 .byteLimit( function ( val
) {
206 // Return without namespace prefix
207 return new mw
.Title( String( val
) ).getMain();
209 sample
: 'User:Sample',
211 limit
: 6, // 'Sample' length
212 expected
: 'User:Sample'
215 test( 'Confirm properties and attributes set', function () {
221 .attr( 'type', 'text' )
222 .prop( 'maxLength', '7' )
223 .appendTo( '#qunit-fixture' )
226 strictEqual( $el
.prop( 'maxLength' ), 7, 'Pre-set maxLength property unchanged' );
229 .attr( 'type', 'text' )
230 .prop( 'maxLength', '7' )
231 .appendTo( '#qunit-fixture' )
234 strictEqual( $el
.prop( 'maxLength' ), 12, 'maxLength property updated if value was passed to $.fn.byteLimit' );
236 $elA
= $( '<input>' )
237 .addClass( 'mw-test-byteLimit-foo' )
238 .attr( 'type', 'text' )
239 .prop( 'maxLength', '7' )
240 .appendTo( '#qunit-fixture' );
242 $elB
= $( '<input>' )
243 .addClass( 'mw-test-byteLimit-foo' )
244 .attr( 'type', 'text' )
245 .prop( 'maxLength', '12' )
246 .appendTo( '#qunit-fixture' );
248 $el
= $( '.mw-test-byteLimit-foo' );
250 strictEqual( $el
.length
, 2, 'Verify that there are no other elements clashing with this test suite' );
254 // Before bug 35294 was fixed, both $elA and $elB had maxLength set to 7,
255 // because $.fn.byteLimit sets:
256 // `limit = limitArg || this.prop( 'maxLength' ); this.prop( 'maxLength', limit )`
257 // and did so outside the each() loop.
258 strictEqual( $elA
.prop( 'maxLength' ), 7, 'maxLength was not incorrectly set on #1 when calling byteLimit on multiple elements (bug 35294)' );
259 strictEqual( $elB
.prop( 'maxLength' ), 12, 'maxLength was not incorrectly set on #2 when calling byteLimit on multiple elements (bug 35294)' );