Skip to content

Commit

Permalink
Core: rnotwhite -> rhtmlnotwhite and jQuery.trim -> stripAndCollapse
Browse files Browse the repository at this point in the history
- Renames and changes rnotwhite to focus on HTML whitespace chars
- Change internal use of jQuery.trim to more accurate strip and collapse
- Adds tests to ensure HTML space characters are retained where valid
- Doesn't add tests where the difference is inconsequential and
  existing tests are adequate.

Fixes jquerygh-3003
Fixes jquerygh-3072
Close jquerygh-3316
  • Loading branch information
timmywil committed Sep 15, 2016
1 parent 2d4f534 commit 3bbcce6
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 51 deletions.
8 changes: 4 additions & 4 deletions src/ajax.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
define( [
"./core",
"./var/document",
"./var/rnotwhite",
"./var/rnothtmlwhite",
"./ajax/var/location",
"./ajax/var/nonce",
"./ajax/var/rquery",
Expand All @@ -11,7 +11,7 @@ define( [
"./event/trigger",
"./deferred",
"./serialize" // jQuery.param
], function( jQuery, document, rnotwhite, location, nonce, rquery ) {
], function( jQuery, document, rnothtmlwhite, location, nonce, rquery ) {

"use strict";

Expand Down Expand Up @@ -64,7 +64,7 @@ function addToPrefiltersOrTransports( structure ) {

var dataType,
i = 0,
dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];

if ( jQuery.isFunction( func ) ) {

Expand Down Expand Up @@ -532,7 +532,7 @@ jQuery.extend( {
s.type = options.method || options.type || s.method || s.type;

// Extract dataTypes list
s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];

// A cross-domain request is in order when the origin doesn't match the current origin.
if ( s.crossDomain == null ) {
Expand Down
5 changes: 3 additions & 2 deletions src/ajax/load.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
define( [
"../core",
"../core/stripAndCollapse",
"../core/parseHTML",
"../ajax",
"../traversing",
"../manipulation",
"../selector"
], function( jQuery ) {
], function( jQuery, stripAndCollapse ) {

"use strict";

Expand All @@ -18,7 +19,7 @@ jQuery.fn.load = function( url, params, callback ) {
off = url.indexOf( " " );

if ( off > -1 ) {
selector = jQuery.trim( url.slice( off ) );
selector = stripAndCollapse( url.slice( off ) );
url = url.slice( 0, off );
}

Expand Down
9 changes: 6 additions & 3 deletions src/attributes/attr.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ define( [
"../core",
"../core/access",
"./support",
"../var/rnotwhite",
"../var/rnothtmlwhite",
"../selector"
], function( jQuery, access, support, rnotwhite ) {
], function( jQuery, access, support, rnothtmlwhite ) {

"use strict";

Expand Down Expand Up @@ -89,7 +89,10 @@ jQuery.extend( {
removeAttr: function( elem, value ) {
var name,
i = 0,
attrNames = value && value.match( rnotwhite );

// Attribute names can contain non-HTML whitespace characters
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
attrNames = value && value.match( rnothtmlwhite );

if ( attrNames && elem.nodeType === 1 ) {
while ( ( name = attrNames[ i++ ] ) ) {
Expand Down
29 changes: 12 additions & 17 deletions src/attributes/classes.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
define( [
"../core",
"../var/rnotwhite",
"../core/stripAndCollapse",
"../var/rnothtmlwhite",
"../data/var/dataPriv",
"../core/init"
], function( jQuery, rnotwhite, dataPriv ) {
], function( jQuery, stripAndCollapse, rnothtmlwhite, dataPriv ) {

"use strict";

var rclass = /[\t\r\n\f]/g;

function getClass( elem ) {
return elem.getAttribute && elem.getAttribute( "class" ) || "";
}
Expand All @@ -25,12 +24,11 @@ jQuery.fn.extend( {
}

if ( typeof value === "string" && value ) {
classes = value.match( rnotwhite ) || [];
classes = value.match( rnothtmlwhite ) || [];

while ( ( elem = this[ i++ ] ) ) {
curValue = getClass( elem );
cur = elem.nodeType === 1 &&
( " " + curValue + " " ).replace( rclass, " " );
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

if ( cur ) {
j = 0;
Expand All @@ -41,7 +39,7 @@ jQuery.fn.extend( {
}

// Only assign if different to avoid unneeded rendering.
finalValue = jQuery.trim( cur );
finalValue = stripAndCollapse( cur );
if ( curValue !== finalValue ) {
elem.setAttribute( "class", finalValue );
}
Expand All @@ -67,14 +65,13 @@ jQuery.fn.extend( {
}

if ( typeof value === "string" && value ) {
classes = value.match( rnotwhite ) || [];
classes = value.match( rnothtmlwhite ) || [];

while ( ( elem = this[ i++ ] ) ) {
curValue = getClass( elem );

// This expression is here for better compressibility (see addClass)
cur = elem.nodeType === 1 &&
( " " + curValue + " " ).replace( rclass, " " );
cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );

if ( cur ) {
j = 0;
Expand All @@ -87,7 +84,7 @@ jQuery.fn.extend( {
}

// Only assign if different to avoid unneeded rendering.
finalValue = jQuery.trim( cur );
finalValue = stripAndCollapse( cur );
if ( curValue !== finalValue ) {
elem.setAttribute( "class", finalValue );
}
Expand Down Expand Up @@ -122,7 +119,7 @@ jQuery.fn.extend( {
// Toggle individual class names
i = 0;
self = jQuery( this );
classNames = value.match( rnotwhite ) || [];
classNames = value.match( rnothtmlwhite ) || [];

while ( ( className = classNames[ i++ ] ) ) {

Expand Down Expand Up @@ -165,10 +162,8 @@ jQuery.fn.extend( {
className = " " + selector + " ";
while ( ( elem = this[ i++ ] ) ) {
if ( elem.nodeType === 1 &&
( " " + getClass( elem ) + " " ).replace( rclass, " " )
.indexOf( className ) > -1
) {
return true;
( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
return true;
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/attributes/val.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
define( [
"../core",
"../core/stripAndCollapse",
"./support",
"../core/init"
], function( jQuery, support ) {
], function( jQuery, stripAndCollapse, support ) {

"use strict";

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

jQuery.fn.extend( {
val: function( value ) {
Expand Down Expand Up @@ -91,7 +91,7 @@ jQuery.extend( {
// 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, " " );
stripAndCollapse( jQuery.text( elem ) );
}
},
select: {
Expand Down
6 changes: 3 additions & 3 deletions src/callbacks.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
define( [
"./core",
"./var/rnotwhite"
], function( jQuery, rnotwhite ) {
"./var/rnothtmlwhite"
], function( jQuery, rnothtmlwhite ) {

"use strict";

// Convert String-formatted options into Object-formatted ones
function createOptions( options ) {
var object = {};
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
object[ flag ] = true;
} );
return object;
Expand Down
12 changes: 12 additions & 0 deletions src/core/stripAndCollapse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
define( function() {
"use strict";

// Strip and collapse whitespace according to HTML spec
// https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
var rhtmlSpace = /[\x20\t\r\n\f]+/g,
stripAndCollapse = function( value ) {
return ( " " + value + " " ).replace( rhtmlSpace, " " ).slice( 1, -1 );
};

return stripAndCollapse;
} );
6 changes: 3 additions & 3 deletions src/data/Data.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
define( [
"../core",
"../var/rnotwhite",
"../var/rnothtmlwhite",
"./var/acceptData"
], function( jQuery, rnotwhite, acceptData ) {
], function( jQuery, rnothtmlwhite, acceptData ) {

"use strict";

Expand Down Expand Up @@ -127,7 +127,7 @@ Data.prototype = {
// Otherwise, create an array by matching non-whitespace
key = key in cache ?
[ key ] :
( key.match( rnotwhite ) || [] );
( key.match( rnothtmlwhite ) || [] );
}

i = key.length;
Expand Down
6 changes: 3 additions & 3 deletions src/effects.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ define( [
"./core",
"./var/document",
"./var/rcssNum",
"./var/rnotwhite",
"./var/rnothtmlwhite",
"./css/var/cssExpand",
"./css/var/isHiddenWithinTree",
"./css/var/swap",
Expand All @@ -17,7 +17,7 @@ define( [
"./manipulation",
"./css",
"./effects/Tween"
], function( jQuery, document, rcssNum, rnotwhite, cssExpand, isHiddenWithinTree, swap,
], function( jQuery, document, rcssNum, rnothtmlwhite, cssExpand, isHiddenWithinTree, swap,
adjustCSS, dataPriv, showHide ) {

"use strict";
Expand Down Expand Up @@ -415,7 +415,7 @@ jQuery.Animation = jQuery.extend( Animation, {
callback = props;
props = [ "*" ];
} else {
props = props.match( rnotwhite );
props = props.match( rnothtmlwhite );
}

var prop,
Expand Down
8 changes: 4 additions & 4 deletions src/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ define( [
"./core",
"./var/document",
"./var/documentElement",
"./var/rnotwhite",
"./var/rnothtmlwhite",
"./var/slice",
"./data/var/dataPriv",

"./core/init",
"./selector"
], function( jQuery, document, documentElement, rnotwhite, slice, dataPriv ) {
], function( jQuery, document, documentElement, rnothtmlwhite, slice, dataPriv ) {

"use strict";

Expand Down Expand Up @@ -147,7 +147,7 @@ jQuery.event = {
}

// Handle multiple events separated by a space
types = ( types || "" ).match( rnotwhite ) || [ "" ];
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
tmp = rtypenamespace.exec( types[ t ] ) || [];
Expand Down Expand Up @@ -229,7 +229,7 @@ jQuery.event = {
}

// Once for each type.namespace in types; type may be omitted
types = ( types || "" ).match( rnotwhite ) || [ "" ];
types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
tmp = rtypenamespace.exec( types[ t ] ) || [];
Expand Down
8 changes: 8 additions & 0 deletions src/var/rnothtmlwhite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
define( function() {
"use strict";

// Only count HTML whitespace
// Other whitespace should count in values
// https://html.spec.whatwg.org/multipage/infrastructure.html#space-character
return ( /[^\x20\t\r\n\f]+/g );
} );
5 changes: 0 additions & 5 deletions src/var/rnotwhite.js

This file was deleted.

1 change: 1 addition & 0 deletions test/data/test3.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
<div class="user">This is a user</div>
<div class="teacher">This is a teacher</div>
<div id="superuser">This is a superuser</div>
<div id="whitespace\xA0">This is a superuser with non-HTML whitespace</div>
11 changes: 11 additions & 0 deletions test/unit/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -2327,6 +2327,17 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
} );

// Selector should be trimmed to avoid leading spaces (#14773)
// Selector should include any valid non-HTML whitespace (#3003)
QUnit.test( "jQuery.fn.load( URL_SELECTOR with non-HTML whitespace(#3003) )", function( assert ) {
assert.expect( 1 );
var done = assert.async();
jQuery( "#first" ).load( "data/test3.html #whitespace\\\\xA0 ", function() {
assert.strictEqual( jQuery( this ).children( "div" ).length, 1, "Verify that specific elements were injected" );
done();
} );
} );

QUnit.asyncTest( "jQuery.fn.load( String, Function ) - simple: inject text into DOM", 2, function( assert ) {
jQuery( "#first" ).load( url( "data/name.html" ), function() {
assert.ok( /^ERROR/.test( jQuery( "#first" ).text() ), "Check if content was injected into the DOM" );
Expand Down
Loading

0 comments on commit 3bbcce6

Please sign in to comment.