Fix bug in jquery.byteLimit.js for Safari 4
authorKrinkle <krinkle@users.mediawiki.org>
Fri, 12 Aug 2011 20:34:23 +0000 (20:34 +0000)
committerKrinkle <krinkle@users.mediawiki.org>
Fri, 12 Aug 2011 20:34:23 +0000 (20:34 +0000)
* Browsers should ignore the maxLength when the .value is set manually through JavaScript, but for some reason Safari 4 (not 5 and later) is enforcing the limit even when the value property is set from JavaScript. Usually this bug doesn't become visible in this module because the byteLength can't be lower than the number of characters, so we'd never see the bug. However since r94066 we're supporting callbacks, and callbacks could do anything to the calculation, including but not limited to making the string that is being checked shorter (ie. suppose maxLength/byteLimit is 8, value is 'User:Sam', and callback filters like "return new mw.Title(val).getName()". If we set it to 'User:Samp' (+p) then Safari 4 would chop the value, because the total string is longer than 8. Whereas all other browsers ignore maxLength (like they should) and let it be and would allow our callback to happen and instead give byteLimit 'Samp' which is length 4 and we still have 4 more characters to go until we reach 8.

The fix is easy, simply do not set the maxLength property if there's a callback.

resources/jquery/jquery.byteLimit.js

index dd7242a..3f18ab1 100644 (file)
                // Default limit to current attribute value
                if ( limit === undefined ) {
                        limit = this.attr( 'maxLength' );
+               }
 
-               // If limit passed, update/set attribute value instead
-               } else {
+               // Update/set attribute value, but only if there is no callback set.
+               // If there's a callback set, it's possible that the limit being enforced
+               // is too low (ie. if the callback would return "Foo" for "User:Foo").
+               // Usually this isn't a problem since browsers ignore maxLength when setting
+               // the value property through JavaScript, but Safari 4 violates that rule, so
+               // we have to remove or not set the property if we have a callback.
+               if ( fn === undefined ) {
                        this.attr( 'maxLength', limit );
+               } else {
+                       this.removeAttr( 'maxLength' );
                }
 
                // Nothing passed and/or empty attribute, return without binding an event.