/**
* @class jQuery.plugin.byteLimit
*/
-( function ( $ ) {
-
- var eventKeys = [
- 'keyup.byteLimit',
- 'keydown.byteLimit',
- 'change.byteLimit',
- 'mouseup.byteLimit',
- 'cut.byteLimit',
- 'paste.byteLimit',
- 'focus.byteLimit',
- 'blur.byteLimit'
- ].join( ' ' );
-
- // Like String#charAt, but return the pair of UTF-16 surrogates for characters outside of BMP.
- function codePointAt( string, offset, backwards ) {
- // We don't need to check for offsets at the beginning or end of string,
- // String#slice will simply return a shorter (or empty) substring.
- var maybePair = backwards ?
- string.slice( offset - 1, offset + 1 ) :
- string.slice( offset, offset + 2 );
- if ( /^[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test( maybePair ) ) {
- return maybePair;
- } else {
- return string.charAt( offset );
- }
- }
+( function ( $, mw ) {
+
+ var
+ eventKeys = [
+ 'keyup.byteLimit',
+ 'keydown.byteLimit',
+ 'change.byteLimit',
+ 'mouseup.byteLimit',
+ 'cut.byteLimit',
+ 'paste.byteLimit',
+ 'focus.byteLimit',
+ 'blur.byteLimit'
+ ].join( ' ' ),
+ trimByteLength = require( 'mediawiki.String' ).trimByteLength;
/**
* Utility function to trim down a string, based on byteLimit
* "fobo", not "foba". Basically emulating the native maxlength by
* reconstructing where the insertion occurred.
*
+ * @method trimByteLength
+ * @deprecated Use `require( 'mediawiki.String' ).trimByteLength` instead.
* @static
* @param {string} safeVal Known value that was previously returned by this
* function, if none, pass empty string.
* @return {string} return.newVal
* @return {boolean} return.trimmed
*/
- $.trimByteLength = function ( safeVal, newVal, byteLimit, fn ) {
- var startMatches, endMatches, matchesLen, inpParts, chopOff, oldChar, newChar,
- oldVal = safeVal;
-
- // Run the hook if one was provided, but only on the length
- // assessment. The value itself is not to be affected by the hook.
- if ( $.byteLength( fn ? fn( newVal ) : newVal ) <= byteLimit ) {
- // Limit was not reached, just remember the new value
- // and let the user continue.
- return {
- newVal: newVal,
- trimmed: false
- };
- }
-
- // Current input is longer than the active limit.
- // Figure out what was added and limit the addition.
- startMatches = 0;
- endMatches = 0;
-
- // It is important that we keep the search within the range of
- // the shortest string's length.
- // Imagine a user adds text that matches the end of the old value
- // (e.g. "foo" -> "foofoo"). startMatches would be 3, but without
- // limiting both searches to the shortest length, endMatches would
- // also be 3.
- matchesLen = Math.min( newVal.length, oldVal.length );
-
- // Count same characters from the left, first.
- // (if "foo" -> "foofoo", assume addition was at the end).
- while ( startMatches < matchesLen ) {
- oldChar = codePointAt( oldVal, startMatches, false );
- newChar = codePointAt( newVal, startMatches, false );
- if ( oldChar !== newChar ) {
- break;
- }
- startMatches += oldChar.length;
- }
-
- while ( endMatches < ( matchesLen - startMatches ) ) {
- oldChar = codePointAt( oldVal, oldVal.length - 1 - endMatches, true );
- newChar = codePointAt( newVal, newVal.length - 1 - endMatches, true );
- if ( oldChar !== newChar ) {
- break;
- }
- endMatches += oldChar.length;
- }
-
- inpParts = [
- // Same start
- newVal.slice( 0, startMatches ),
- // Inserted content
- newVal.slice( startMatches, newVal.length - endMatches ),
- // Same end
- newVal.slice( newVal.length - endMatches )
- ];
-
- // Chop off characters from the end of the "inserted content" string
- // until the limit is statisfied.
- if ( fn ) {
- // stop, when there is nothing to slice - T43450
- while ( $.byteLength( fn( inpParts.join( '' ) ) ) > byteLimit && inpParts[ 1 ].length > 0 ) {
- // Do not chop off halves of surrogate pairs
- chopOff = /[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test( inpParts[ 1 ] ) ? 2 : 1;
- inpParts[ 1 ] = inpParts[ 1 ].slice( 0, -chopOff );
- }
- } else {
- while ( $.byteLength( inpParts.join( '' ) ) > byteLimit ) {
- // Do not chop off halves of surrogate pairs
- chopOff = /[\uD800-\uDBFF][\uDC00-\uDFFF]$/.test( inpParts[ 1 ] ) ? 2 : 1;
- inpParts[ 1 ] = inpParts[ 1 ].slice( 0, -chopOff );
- }
- }
-
- return {
- newVal: inpParts.join( '' ),
- // For pathological fn() that always returns a value longer than the limit, we might have
- // ended up not trimming - check for this case to avoid infinite loops
- trimmed: newVal !== inpParts.join( '' )
- };
- };
+ mw.log.deprecate( $, 'trimByteLength', trimByteLength,
+ 'Use require( \'mediawiki.String\' ).trimByteLength instead.', '$.trimByteLength' );
/**
* Enforces a byte limit on an input field, so that UTF-8 entries are counted as well,
// See https://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for
// the order and characteristics of the key events.
$el.on( eventKeys, function () {
- var res = $.trimByteLength(
+ var res = trimByteLength(
prevSafeVal,
this.value,
elLimit,
* @class jQuery
* @mixins jQuery.plugin.byteLimit
*/
-}( jQuery ) );
+}( jQuery, mediaWiki ) );