byteLimit/byteLength improvements:
authorKrinkle <krinkle@users.mediawiki.org>
Thu, 30 Jun 2011 01:06:47 +0000 (01:06 +0000)
committerKrinkle <krinkle@users.mediawiki.org>
Thu, 30 Jun 2011 01:06:47 +0000 (01:06 +0000)
* Split the byte length logic into a seperate method to allow it to be called directly on a string (easier to test and easier re-use)
* Added basic unit tests for it.

resources/Resources.php
resources/jquery/jquery.byteLength.js [new file with mode: 0644]
resources/jquery/jquery.byteLimit.js
tests/qunit/index.html
tests/qunit/suites/resources/jquery/jquery.byteLength.js [new file with mode: 0644]

index 24e121b..88ec765 100644 (file)
@@ -79,8 +79,12 @@ return array(
                'scripts' => 'resources/jquery/jquery.autoEllipsis.js',
                'dependencies' => 'jquery.highlightText',
        ),
+       'jquery.byteLength' => array(
+               'scripts' => 'resources/jquery/jquery.byteLength.js',
+       ),
        'jquery.byteLimit' => array(
                'scripts' => 'resources/jquery/jquery.byteLimit.js',
+               'dependencies' => 'jquery.byteLength',
        ),
        'jquery.checkboxShiftClick' => array(
                'scripts' => 'resources/jquery/jquery.checkboxShiftClick.js',
diff --git a/resources/jquery/jquery.byteLength.js b/resources/jquery/jquery.byteLength.js
new file mode 100644 (file)
index 0000000..20fa5c8
--- /dev/null
@@ -0,0 +1,19 @@
+/**
+ * jQuery.byteLength
+ *
+ * Calculate the byte length of a string (accounting for UTF-8).
+ *
+ * @author Jan Paul Posma
+ */
+jQuery.byteLength = function( str ) {
+
+       // This basically figures out how many bytes a UTF-16 string (which is what js sees)
+       // will take in UTF-8 by replacing a 2 byte character with 2 *'s, etc, and counting that.
+       // Note, surrogate (\uD800-\uDFFF) characters are counted as 2 bytes, since there's two of them
+       // and the actual character takes 4 bytes in UTF-8 (2*2=4). Might not work perfectly in
+       // edge cases such as illegal sequences, but that should never happen.
+       return str
+               .replace( /[\u0080-\u07FF\uD800-\uDFFF]/g, '**' )
+               .replace( /[\u0800-\uD7FF\uE000-\uFFFF]/g, '***' )
+               .length;
+}
index e45aa63..907ceb6 100644 (file)
@@ -1,5 +1,7 @@
 /**
  * jQuery byteLimit
+ *
+ * @author Jan Paul Posma
  */
 ( function( $ ) {
 
@@ -17,7 +19,7 @@
                        this.attr( 'maxLength', limit );
                }
 
-               // Nothing passed and/or empty attribute, return this for further chaining.
+               // Nothing passed and/or empty attribute, return without binding an event.
                if ( limit == null ) {
                        return this;
                }
                                return true; //a special key (backspace, etc) so don't interfere.
                        }
        
-                       // This basically figures out how many bytes a UTF-16 string (which is what js sees)
-                       // will take in UTF-8 by replacing a 2 byte character with 2 *'s, etc, and counting that.
-                       // Note, surrogate (\uD800-\uDFFF) characters are counted as 2 bytes, since there's two of them
-                       // and the actual character takes 4 bytes in UTF-8 (2*2=4). Might not work perfectly in
-                       // edge cases such as illegal sequences, but that should never happen.
-       
-                       var len = this.value
-                               .replace( /[\u0080-\u07FF\uD800-\uDFFF]/g, '**' )
-                               .replace( /[\u0800-\uD7FF\uE000-\uFFFF]/g, '***' )
-                               .length;
+                       var len = $.byteLength( this.value );
 
                        // limit-3 as this doesn't count the character about to be inserted.
                        if ( len > ( limit-3 ) ) {
index c05ae31..f27aa99 100644 (file)
@@ -40,6 +40,7 @@
 
        <!-- MW: Non-default modules -->
        <script src="../../resources/jquery/jquery.autoEllipsis.js"></script>
+       <script src="../../resources/jquery/jquery.byteLength.js"></script>
        <script src="../../resources/jquery/jquery.colorUtil.js"></script>
        <script src="../../resources/jquery/jquery.tabIndex.js"></script>
        <script src="../../resources/jquery/jquery.tablesorter.js"></script>
@@ -60,6 +61,7 @@
        <script src="suites/resources/mediawiki/mediawiki.util.js"></script>
 
        <script src="suites/resources/jquery/jquery.autoEllipsis.js"></script>
+       <script src="suites/resources/jquery/jquery.byteLength.js"></script>
        <script src="suites/resources/jquery/jquery.colorUtil.js"></script>
        <script src="suites/resources/jquery/jquery.tabIndex.js"></script>
        <script src="suites/resources/jquery/jquery.tablesorter.test.js" charset="UTF-8"></script>
diff --git a/tests/qunit/suites/resources/jquery/jquery.byteLength.js b/tests/qunit/suites/resources/jquery/jquery.byteLength.js
new file mode 100644 (file)
index 0000000..10628b0
--- /dev/null
@@ -0,0 +1,38 @@
+module( 'jquery.byteLength.js' );
+
+test( '-- Initial check', function() {
+       expect(1);
+       ok( $.byteLength, 'jQuery.byteLength defined' );
+} );
+
+test( 'Simple text', function() {
+       expect(5);
+
+       var     azLc = 'abcdefghijklmnopqrstuvwxyz',
+               azUc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+               num = '0123456789',
+               x = '*',
+               space = '   ';
+
+       equal( $.byteLength( azLc ), 26, 'Lowercase a-z' );
+       equal( $.byteLength( azUc ), 26, 'Uppercase A-Z' );
+       equal( $.byteLength( num ), 10, 'Numbers 0-9' );
+       equal( $.byteLength( x ), 1, 'An asterisk' );
+       equal( $.byteLength( space ), 3, '3 spaces' );
+
+} );
+
+test( 'Special text', window.foo = function() {
+       expect(4);
+
+       // http://en.wikipedia.org/wiki/UTF-8 
+       var     U_0024 = '\u0024',
+               U_00A2 = '\u00A2',
+               U_20AC = '\u20AC',
+               U_024B62 = '\u024B62';
+
+       strictEqual( $.byteLength( U_0024 ), 1, 'U+0024: 1 byte (dollar sign) $' );
+       strictEqual( $.byteLength( U_00A2 ), 2, 'U+00A2: 2 bytes (cent sign) &#162;' );
+       strictEqual( $.byteLength( U_20AC ), 3, 'U+20AC: 3 bytes (euro sign) &#8364;' );
+       strictEqual( $.byteLength( U_024B62 ), 4, 'U+024B62: 4 bytes &#150370; \U00024B62 ' );
+} );