Skip to content

Commit 7052698

Browse files
committed
Attributes: strip/collapse whitespace for set values on selects
Fixes gh-2978 Close gh-3002
1 parent 055cb75 commit 7052698

File tree

2 files changed

+88
-11
lines changed

2 files changed

+88
-11
lines changed

src/attributes/val.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ define( [
44
"../core/init"
55
], function( jQuery, support ) {
66

7-
var rreturn = /\r/g;
7+
var rreturn = /\r/g,
8+
rspaces = /[\x20\t\r\n\f]+/g;
89

910
jQuery.fn.extend( {
1011
val: function( value ) {
@@ -80,9 +81,15 @@ jQuery.extend( {
8081
option: {
8182
get: function( elem ) {
8283

83-
// Support: IE<11
84-
// option.value not trimmed (#14858)
85-
return jQuery.trim( elem.value );
84+
var val = jQuery.find.attr( elem, "value" );
85+
return val != null ?
86+
val :
87+
88+
// Support: IE10-11+
89+
// option.text throws exceptions (#14686, #14858)
90+
// Strip and collapse whitespace
91+
// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
92+
jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
8693
}
8794
},
8895
select: {
@@ -134,7 +141,7 @@ jQuery.extend( {
134141
while ( i-- ) {
135142
option = options[ i ];
136143
if ( option.selected =
137-
jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
144+
jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
138145
) {
139146
optionSet = true;
140147
}

test/unit/attributes.js

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,71 @@ QUnit.test( "val(select) after form.reset() (Bug #2551)", function( assert ) {
11071107
jQuery( "#kk" ).remove();
11081108
} );
11091109

1110+
QUnit.test( "select.val(space characters) (gh-2978)", function( assert ) {
1111+
assert.expect( 35 );
1112+
1113+
var $select = jQuery( "<select/>" ).appendTo( "#qunit-fixture" ),
1114+
spaces = {
1115+
"\\t": {
1116+
html: "&#09;",
1117+
val: "\t"
1118+
},
1119+
"\\n": {
1120+
html: "&#10;",
1121+
val: "\n"
1122+
},
1123+
"\\r": {
1124+
html: "&#13;",
1125+
val: "\r"
1126+
},
1127+
"\\f": "\f",
1128+
"space": " ",
1129+
"\\u00a0": "\u00a0",
1130+
"\\u1680": "\u1680"
1131+
},
1132+
html = "";
1133+
jQuery.each( spaces, function( key, obj ) {
1134+
var value = obj.html || obj;
1135+
html += "<option value='attr" + value + "'></option>";
1136+
html += "<option value='at" + value + "tr'></option>";
1137+
html += "<option value='" + value + "attr'></option>";
1138+
} );
1139+
$select.html( html );
1140+
1141+
jQuery.each( spaces, function( key, obj ) {
1142+
var val = obj.val || obj;
1143+
$select.val( "attr" + val );
1144+
assert.equal( $select.val(), "attr" + val, "Value ending with space character (" + key + ") selected (attr)" );
1145+
1146+
$select.val( "at" + val + "tr" );
1147+
assert.equal( $select.val(), "at" + val + "tr", "Value with space character (" + key + ") in the middle selected (attr)" );
1148+
1149+
$select.val( val + "attr" );
1150+
assert.equal( $select.val(), val + "attr", "Value starting with space character (" + key + ") selected (attr)" );
1151+
} );
1152+
1153+
jQuery.each( spaces, function( key, obj ) {
1154+
var value = obj.html || obj,
1155+
val = obj.val || obj;
1156+
html = "";
1157+
html += "<option>text" + value + "</option>";
1158+
html += "<option>te" + value + "xt</option>";
1159+
html += "<option>" + value + "text</option>";
1160+
$select.html( html );
1161+
1162+
$select.val( "text" );
1163+
assert.equal( $select.val(), "text", "Value with space character at beginning or end is stripped (" + key + ") selected (text)" );
1164+
1165+
if ( /^\\u/.test( key ) ) {
1166+
$select.val( "te" + val + "xt" );
1167+
assert.equal( $select.val(), "te" + val + "xt", "Value with non-space whitespace character (" + key + ") in the middle selected (text)" );
1168+
} else {
1169+
$select.val( "te xt" );
1170+
assert.equal( $select.val(), "te xt", "Value with space character (" + key + ") in the middle selected (text)" );
1171+
}
1172+
} );
1173+
} );
1174+
11101175
var testAddClass = function( valueObj, assert ) {
11111176
assert.expect( 9 );
11121177

@@ -1523,17 +1588,22 @@ QUnit.test( "option value not trimmed when setting via parent select", function(
15231588
assert.equal( jQuery( "<select><option> 2</option></select>" ).val( "2" ).val(), "2" );
15241589
} );
15251590

1526-
QUnit.test( "Insignificant white space returned for $(option).val() (#14858)", function( assert ) {
1527-
assert.expect( 3 );
1591+
QUnit.test( "Insignificant white space returned for $(option).val() (#14858, gh-2978)", function( assert ) {
1592+
assert.expect( 16 );
15281593

15291594
var val = jQuery( "<option></option>" ).val();
15301595
assert.equal( val.length, 0, "Empty option should have no value" );
15311596

1532-
val = jQuery( "<option> </option>" ).val();
1533-
assert.equal( val.length, 0, "insignificant white-space returned for value" );
1597+
jQuery.each( [ " ", "\n", "\t", "\f", "\r" ], function( i, character ) {
1598+
var val = jQuery( "<option>" + character + "</option>" ).val();
1599+
assert.equal( val.length, 0, "insignificant white-space returned for value" );
1600+
1601+
val = jQuery( "<option>" + character + "test" + character + "</option>" ).val();
1602+
assert.equal( val.length, 4, "insignificant white-space returned for value" );
15341603

1535-
val = jQuery( "<option> test </option>" ).val();
1536-
assert.equal( val.length, 4, "insignificant white-space returned for value" );
1604+
val = jQuery( "<option>te" + character + "st</option>" ).val();
1605+
assert.equal( val, "te st", "Whitespace is collapsed in values" );
1606+
} );
15371607
} );
15381608

15391609
QUnit.test( "SVG class manipulation (gh-2199)", function( assert ) {

0 commit comments

Comments
 (0)