X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=resources%2Fsrc%2Fjquery%2Fjquery.byteLimit.js;h=3ce6e7fca56dbc67d04137816a407faadfa48366;hb=1954cff1d9ee8fb2645043a60bdddf507f59dc5a;hp=c75246c0f65a1ecaadb92c0ed7f7e547a484e1a1;hpb=8bb5a6c461c31ee5ce6874548246fc2c520686f6;p=lhc%2Fweb%2Fwiklou.git diff --git a/resources/src/jquery/jquery.byteLimit.js b/resources/src/jquery/jquery.byteLimit.js index c75246c0f6..3ce6e7fca5 100644 --- a/resources/src/jquery/jquery.byteLimit.js +++ b/resources/src/jquery/jquery.byteLimit.js @@ -14,6 +14,20 @@ '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 ); + } + } + /** * Utility function to trim down a string, based on byteLimit * and given a safe start position. It supports insertion anywhere @@ -32,7 +46,7 @@ * @return {boolean} return.trimmed */ $.trimByteLength = function ( safeVal, newVal, byteLimit, fn ) { - var startMatches, endMatches, matchesLen, inpParts, + var startMatches, endMatches, matchesLen, inpParts, chopOff, oldChar, newChar, oldVal = safeVal; // Run the hook if one was provided, but only on the length @@ -61,18 +75,22 @@ // Count same characters from the left, first. // (if "foo" -> "foofoo", assume addition was at the end). - while ( - startMatches < matchesLen && - oldVal.charAt( startMatches ) === newVal.charAt( startMatches ) - ) { - startMatches += 1; + while ( startMatches < matchesLen ) { + oldChar = codePointAt( oldVal, startMatches, false ); + newChar = codePointAt( newVal, startMatches, false ); + if ( oldChar !== newChar ) { + break; + } + startMatches += oldChar.length; } - while ( - endMatches < ( matchesLen - startMatches ) && - oldVal.charAt( oldVal.length - 1 - endMatches ) === newVal.charAt( newVal.length - 1 - endMatches ) - ) { - endMatches += 1; + 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 = [ @@ -89,11 +107,15 @@ if ( fn ) { // stop, when there is nothing to slice - T43450 while ( $.byteLength( fn( inpParts.join( '' ) ) ) > byteLimit && inpParts[ 1 ].length > 0 ) { - inpParts[ 1 ] = inpParts[ 1 ].slice( 0, -1 ); + // 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 ) { - inpParts[ 1 ] = inpParts[ 1 ].slice( 0, -1 ); + // 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 ); } }