(bug 36310) jquery.byteLimit should skip < 0 due to Firefox bug.
authorTimo Tijhof <ttijhof@wikimedia.org>
Fri, 22 Jun 2012 20:16:18 +0000 (22:16 +0200)
committerTimo Tijhof <ttijhof@wikimedia.org>
Fri, 22 Jun 2012 20:16:18 +0000 (22:16 +0200)
* Firefox returns -1 if an element has no maxLength property set.
  (instead of undefined). This is especially problematic because
  roundtripping that value (e.g. setting elem.maxLength = -1;)
  causes a DOMException to be thrown.
  That exception is expected (and happens also in Chrome), but Chrome
  and other standard browsers don't return -1 for the getter, so it
  would never end up in the setter.

* Moved the check to before the property set/removal. Otherwise
  the exception would still be thrown. This should've been before
  anyway.

* This fixes:
  - (bug 36310) Can't enter a log summary on Special:MovePage
  in Firefox.

  Even though we do set maxLength for that field from PHP. Recently
  the input field was changed from <input> to <textarea>. And since
  English Wikipedia has wgHtml5 disabled and maxLength on <textarea>
  is new in HTML5, that property was stripped by the Html class, and
  the javascript incorrectly assumed  that the property would be there
  and thus caused the DOMException in Firefox.

* Added unit test for this (which fails in Firefox without this fix).

Change-Id: I28490b61bd5a20dd1d84c4730615514d3822aa77

resources/jquery/jquery.byteLimit.js
tests/qunit/suites/resources/jquery/jquery.byteLimit.test.js

index 45df39a..d8f4bfc 100644 (file)
                        // that affects the next each() iteration as well.
                        elLimit = limit === undefined ? $el.prop( 'maxLength' ) : limit;
        
+                       // If there is no (valid) limit passed or found in the property,
+                       // skip this. The < 0 check is required for Firefox, which returns
+                       // -1  (instead of undefined) for maxLength if it is not set.
+                       if ( !elLimit || elLimit < 0 ) {
+                               return;
+                       }
+
                        // 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").
                                $el.removeProp( 'maxLength' );
                        }
        
-                       // Nothing passed and/or empty attribute, return without binding an event.
-                       if ( elLimit === undefined ) {
-                               return;
-                       }
-       
                        // Save function for reference
                        $el.data( 'byteLimit-callback', fn );
        
index 21effdb..2cb94d1 100644 (file)
                expected: simpleSample
        });
 
+       byteLimitTest({
+               description: 'Plain text input. Calling byteLimit with no parameters and no maxLength property (bug 36310)',
+               $input: $( '<input>' )
+                       .attr( 'type', 'text' )
+                       .byteLimit(),
+               sample: simpleSample,
+               hasLimit: false,
+               expected: simpleSample
+       });
+
        byteLimitTest({
                description: 'Limit using the maxlength attribute',
                $input: $( '<input>' )