Skip to content

Commit

Permalink
Merge 00b7b67 into ee0a030
Browse files Browse the repository at this point in the history
  • Loading branch information
dmethvin committed Apr 28, 2016
2 parents ee0a030 + 00b7b67 commit 146fd76
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 37 deletions.
28 changes: 24 additions & 4 deletions src/core.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

var oldInit = jQuery.fn.init,
oldIsNumeric = jQuery.isNumeric,
rattrHash = /\[\s*\w+\s*[~|^$*]?=\s*(?![\s'"])[^#\]]*#/;
rattrHash = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]+)\s*\]/g;

jQuery.fn.init = function( selector ) {
var args = Array.prototype.slice.call( arguments );
Expand All @@ -12,11 +12,31 @@ jQuery.fn.init = function( selector ) {
migrateWarn( "jQuery( '#' ) is not a valid selector" );
args[ 0 ] = selector = [];

} else if ( rattrHash.test( selector ) ) {
// Can't use .test here because rattrHash is //g and in global scope
} else if ( rattrHash.exec( selector ) ) {

// The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
// Note that this doesn't actually fix the selector due to potential false positives
migrateWarn( "Attribute selectors with '#' must be quoted: '" + selector + "'" );
// First see if qS thinks it's a valid selector, if so avoid a false positive
try {
document.querySelector( selector );
} catch ( err1 ) {

// Didn't *look* valid to qSA, warn and try quoting what we think is the value
migrateWarn( "Attribute selectors with '#' must be quoted: `" + selector + "`" );

selector = selector.replace( rattrHash, function( _, attr, op, value ) {
return "[" + attr + op + "\"" + value + "\"]";
} );

// If the regexp *may* have created an invalid selector, don't update it
// Note that there may be false alarms if selector uses jQuery extensions
try {
document.querySelector( selector );
args[ 0 ] = selector;
} catch ( err2 ) {
migrateWarn( "Unquoted attribute repair failed: `" + args[ 0 ] + "`" );
}
}
}

return oldInit.apply( this, args );
Expand Down
90 changes: 57 additions & 33 deletions test/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,45 +27,69 @@ test( "jQuery( '#' )", function() {
} );
} );

test( "attribute selectors with naked '#'", function() {
expect( 6 );

// These are wrapped in try/catch because they throw on jQuery 1.12.0+

expectWarning( "attribute equals", function() {
try {
jQuery( "a[href=#]" );
} catch ( e ) {}
} );

expectWarning( "attribute contains", function() {
try {
jQuery( "link[rel*=#stuff]" );
} catch ( e ) {}
} );

expectWarning( "attribute starts, with spaces", function() {
try {
jQuery( "a[href ^= #junk]" );
} catch ( e ) {}
QUnit.test( "Attribute selectors with unquoted hashes", function( assert ) {
expect( 4 );

var

// No warning, no need to fix
okays = [
"a[href='#junk']",
"div[data-id=\"#junk\"]",
"div[data-selector='a[href=#main]']",
"input[value~= '[strange*=#stuff]']"
],

// Fixable, and gives warning
fixables = [
"a[href=#]",
"a[href*=#]:not([href=#])",
".class a[href=#anchor]",
"a[href=#some-anchor]",
"link[rel*=#stuff]",
"p[class ^= #junk]",
"a[href=space#junk]"
],

// False positives that still work
positives = [
"div[data-selector='a[href=#main]']:first",
"input[value= '[strange*=#stuff]']:eq(1)"
],

// Failures due to quotes and jQuery extensions combined
failures = [
"p[class ^= #junk]:first",
"a[href=space#junk]:eq(1)"
];

// TODO: ensure these actually select what they should

expectNoWarning( "Perfectly cromulent selectors are unchanged", function() {
okays.forEach( function( okay ) {
jQuery( okay );
} );
} );

expectWarning( "attribute equals, hash not starting", function() {
try {
jQuery( "a[href=space#junk]" );
} catch ( e ) {}
expectWarning( "Values with unquoted hashes are quoted", fixables.length, function() {
fixables.forEach( function( fixable ) {
jQuery( fixable );
} );
} );

expectNoWarning( "attribute equals, with single quotes", function() {
try {
jQuery( "a[href='#junk']" );
} catch ( e ) {}
expectWarning( "False positives", 2 * positives.length, function() {
positives.forEach( function( positive ) {
jQuery( positive );
} );
} );

expectNoWarning( "attribute equals, with double quotes", function() {
try {
jQuery( "a[href=\"#junk\"]" );
} catch ( e ) {}
expectWarning( "Unfixable cases", 2 * failures.length, function() {
failures.forEach( function( failure ) {
try {
jQuery( failure );
assert.ok( false, "No Mr. Bond I expect you to die!" );
} catch ( err ) { }
} );
} );
} );

Expand Down

0 comments on commit 146fd76

Please sign in to comment.