]> source.dussan.org Git - jquery.git/commitdiff
Attributes: strip/collapse whitespace for set values on selects
authorTimmy Willison <timmywillisn@gmail.com>
Tue, 15 Mar 2016 22:15:02 +0000 (18:15 -0400)
committerTimmy Willison <timmywillisn@gmail.com>
Thu, 17 Mar 2016 16:24:51 +0000 (12:24 -0400)
Fixes gh-2978
Close gh-3002

src/attributes/val.js
test/unit/attributes.js

index 5f0b73e008bac2ae6c6e31b230a8662f8f78ac6b..a8a2e12fbae25f035e66575756d56f41804ef6db 100644 (file)
@@ -4,7 +4,8 @@ define( [
        "../core/init"
 ], function( jQuery, support ) {
 
-var rreturn = /\r/g;
+var rreturn = /\r/g,
+       rspaces = /[\x20\t\r\n\f]+/g;
 
 jQuery.fn.extend( {
        val: function( value ) {
@@ -80,9 +81,15 @@ jQuery.extend( {
                option: {
                        get: function( elem ) {
 
-                               // Support: IE<11
-                               // option.value not trimmed (#14858)
-                               return jQuery.trim( elem.value );
+                               var val = jQuery.find.attr( elem, "value" );
+                               return val != null ?
+                                       val :
+
+                                       // Support: IE10-11+
+                                       // option.text throws exceptions (#14686, #14858)
+                                       // Strip and collapse whitespace
+                                       // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+                                       jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
                        }
                },
                select: {
@@ -134,7 +141,7 @@ jQuery.extend( {
                                while ( i-- ) {
                                        option = options[ i ];
                                        if ( option.selected =
-                                                       jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
+                                               jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
                                        ) {
                                                optionSet = true;
                                        }
index 23c13a7cd743484e1f2772478b6a9d05410d5059..d9a036476255353d0a217212d795566823d88b85 100644 (file)
@@ -1107,6 +1107,71 @@ QUnit.test( "val(select) after form.reset() (Bug #2551)", function( assert ) {
        jQuery( "#kk" ).remove();
 } );
 
+QUnit.test( "select.val(space characters) (gh-2978)", function( assert ) {
+       assert.expect( 35 );
+
+       var $select = jQuery( "<select/>" ).appendTo( "#qunit-fixture" ),
+               spaces = {
+                       "\\t": {
+                               html: "&#09;",
+                               val: "\t"
+                       },
+                       "\\n": {
+                               html: "&#10;",
+                               val: "\n"
+                       },
+                       "\\r": {
+                               html: "&#13;",
+                               val: "\r"
+                       },
+                       "\\f": "\f",
+                       "space": " ",
+                       "\\u00a0": "\u00a0",
+                       "\\u1680": "\u1680"
+               },
+               html = "";
+       jQuery.each( spaces, function( key, obj ) {
+               var value = obj.html || obj;
+               html += "<option value='attr" + value + "'></option>";
+               html += "<option value='at" + value + "tr'></option>";
+               html += "<option value='" + value + "attr'></option>";
+       } );
+       $select.html( html );
+
+       jQuery.each( spaces, function( key, obj ) {
+               var val = obj.val || obj;
+               $select.val( "attr" + val );
+               assert.equal( $select.val(), "attr" + val, "Value ending with space character (" + key + ") selected (attr)" );
+
+               $select.val( "at" + val + "tr" );
+               assert.equal( $select.val(), "at" + val + "tr", "Value with space character (" + key + ") in the middle selected (attr)" );
+
+               $select.val( val + "attr" );
+               assert.equal( $select.val(), val + "attr", "Value starting with space character (" + key + ") selected (attr)" );
+       } );
+
+       jQuery.each( spaces, function( key, obj ) {
+               var value = obj.html || obj,
+                       val = obj.val || obj;
+               html = "";
+               html += "<option>text" + value + "</option>";
+               html += "<option>te" + value + "xt</option>";
+               html += "<option>" + value + "text</option>";
+               $select.html( html );
+
+               $select.val( "text" );
+               assert.equal( $select.val(), "text", "Value with space character at beginning or end is stripped (" + key + ") selected (text)" );
+
+               if ( /^\\u/.test( key ) ) {
+                       $select.val( "te" + val + "xt" );
+                       assert.equal( $select.val(), "te" + val + "xt", "Value with non-space whitespace character (" + key + ") in the middle selected (text)" );
+               } else {
+                       $select.val( "te xt" );
+                       assert.equal( $select.val(), "te xt", "Value with space character (" + key + ") in the middle selected (text)" );
+               }
+       } );
+} );
+
 var testAddClass = function( valueObj, assert ) {
        assert.expect( 9 );
 
@@ -1523,17 +1588,22 @@ QUnit.test( "option value not trimmed when setting via parent select", function(
        assert.equal( jQuery( "<select><option> 2</option></select>" ).val( "2" ).val(), "2" );
 } );
 
-QUnit.test( "Insignificant white space returned for $(option).val() (#14858)", function( assert ) {
-       assert.expect( 3 );
+QUnit.test( "Insignificant white space returned for $(option).val() (#14858, gh-2978)", function( assert ) {
+       assert.expect( 16 );
 
        var val = jQuery( "<option></option>" ).val();
        assert.equal( val.length, 0, "Empty option should have no value" );
 
-       val = jQuery( "<option>  </option>" ).val();
-       assert.equal( val.length, 0, "insignificant white-space returned for value" );
+       jQuery.each( [ " ", "\n", "\t", "\f", "\r" ], function( i, character ) {
+               var val = jQuery( "<option>" + character + "</option>" ).val();
+               assert.equal( val.length, 0, "insignificant white-space returned for value" );
+
+               val = jQuery( "<option>" + character + "test" + character + "</option>" ).val();
+               assert.equal( val.length, 4, "insignificant white-space returned for value" );
 
-       val = jQuery( "<option>  test  </option>" ).val();
-       assert.equal( val.length, 4, "insignificant white-space returned for value" );
+               val = jQuery( "<option>te" + character + "st</option>" ).val();
+               assert.equal( val, "te st", "Whitespace is collapsed in values" );
+       } );
 } );
 
 QUnit.test( "SVG class manipulation (gh-2199)", function( assert ) {