🌐 AI搜索 & 代理 主页
Skip to content

Commit 02f1756

Browse files
committed
Selector: Make empty attribute selectors work in IE 11/Edge again
qSA in IE 11/Edge often (but not always) don't find elements with an empty name attribute selector (`[name=""]`). Detect that & fall back to Sizzle traversal. Interestingly, IE 10 & older don't seem to have the issue. Fixes gh-4435
1 parent 2d5ad6d commit 02f1756

File tree

7 files changed

+46
-12
lines changed

7 files changed

+46
-12
lines changed

src/selector.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ define( [
66
"./var/indexOf",
77
"./var/pop",
88
"./var/push",
9+
"./selector/var/whitespace",
910
"./selector/rbuggyQSA",
1011
"./selector/support",
1112

@@ -14,7 +15,7 @@ define( [
1415
"./selector/escapeSelector",
1516
"./selector/uniqueSort"
1617
], function( jQuery, nodeName, document, documentElement, indexOf, pop, push,
17-
rbuggyQSA, support ) {
18+
whitespace, rbuggyQSA, support ) {
1819

1920
"use strict";
2021

@@ -46,9 +47,6 @@ var i,
4647

4748
// Regular expressions
4849

49-
// https://www.w3.org/TR/css3-selectors/#whitespace
50-
whitespace = "[\\x20\\t\\r\\n\\f]",
51-
5250
// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
5351
identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
5452
"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",

src/selector/rbuggyQSA.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
define( [
22
"../var/document",
3-
"../var/isIE"
4-
], function( document, isIE ) {
3+
"../var/isIE",
4+
"./var/whitespace"
5+
], function( document, isIE, whitespace ) {
56

67
"use strict";
78

89
var rbuggyQSA = [],
9-
testEl = document.createElement( "div" );
10+
testEl = document.createElement( "div" ),
11+
input = document.createElement( "input" );
1012

1113
testEl.innerHTML = "<a href=''></a>";
1214

@@ -23,6 +25,18 @@ if ( isIE ) {
2325
rbuggyQSA.push( ":enabled", ":disabled" );
2426
}
2527

28+
// Support: IE 11+, Edge 15 - 18+
29+
// IE 11/Edge don't find elements on a `[name='']` query in some cases.
30+
// Adding a temporary attribute to the document before the selection works
31+
// around the issue.
32+
// Interestingly, IE 10 & older don't seem to have the issue.
33+
input.setAttribute( "name", "" );
34+
testEl.appendChild( input );
35+
if ( !testEl.querySelectorAll( "[name='']" ).length ) {
36+
rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
37+
whitespace + "*(?:''|\"\")" );
38+
}
39+
2640
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
2741

2842
return rbuggyQSA;

src/selector/var/whitespace.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
define( function() {
2+
"use strict";
3+
4+
// https://www.w3.org/TR/css3-selectors/#whitespace
5+
return "[\\x20\\t\\r\\n\\f]";
6+
} );

test/data/qunit-fixture.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@
116116
<input type="radio" name="R1" value="2" />
117117
<input type="text" name="My Name" value="me" />
118118
<input type="reset" name="reset" value="NO" />
119+
<div class="empty-name-container">
120+
<div id="empty-name-parent">
121+
<input type="text" id="name-empty" name="" value="" />
122+
</div>
123+
</div>
119124
<select name="S1">
120125
<option value="abc">ABC</option>
121126
<option value="abc">ABC</option>

test/data/qunit-fixture.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/unit/attributes.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ QUnit.test( "addClass(Array)", function( assert ) {
12551255
} );
12561256

12571257
QUnit.test( "addClass(Function) with incoming value", function( assert ) {
1258-
assert.expect( 57 );
1258+
assert.expect( 59 );
12591259
var pass, i,
12601260
div = jQuery( "#qunit-fixture div" ),
12611261
old = div.map( function() {
@@ -1330,7 +1330,7 @@ QUnit.test( "removeClass(Array) - simple", function( assert ) {
13301330
} );
13311331

13321332
QUnit.test( "removeClass(Function) with incoming value", function( assert ) {
1333-
assert.expect( 57 );
1333+
assert.expect( 59 );
13341334

13351335
var $divs = jQuery( "#qunit-fixture div" ).addClass( "test" ), old = $divs.map( function() {
13361336
return jQuery( this ).attr( "class" );

test/unit/selector.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ QUnit.test( "attributes - special characters", function( assert ) {
720720
} );
721721

722722
QUnit.test( "attributes - others", function( assert ) {
723-
assert.expect( 10 );
723+
assert.expect( 14 );
724724

725725
var div = document.getElementById( "foo" );
726726

@@ -750,6 +750,17 @@ QUnit.test( "attributes - others", function( assert ) {
750750
assert.ok( !jQuery( "<input type='checkbox'/>" ).prop( "checked", true ).is( "[checked]" ),
751751
"[checked] selects by attribute (negative)"
752752
);
753+
754+
assert.t( "empty name", "[name='']", [ "name-empty" ] );
755+
assert.t( "prefixed empty name", "#empty-name-parent [name='']", [ "name-empty" ] );
756+
757+
var emptyNameContainer = jQuery( ".empty-name-container" );
758+
assert.deepEqual( emptyNameContainer.find( "[name='']" ).get(),
759+
q( "name-empty" ),
760+
"empty name with context" );
761+
assert.deepEqual( emptyNameContainer.find( "#empty-name-parent [name='']" ).get(),
762+
q( "name-empty" ),
763+
"prefixed empty name with context" );
753764
} );
754765

755766
QUnit.test( "pseudo - (parent|empty)", function( assert ) {
@@ -1257,7 +1268,7 @@ QUnit[ QUnit.jQuerySelectorsPos ? "test" : "skip" ]( "pseudo - position", functi
12571268

12581269
assert.t( "Check element position", "#qunit-fixture div div:eq(0)", [ "nothiddendivchild" ] );
12591270
assert.t( "Check element position", "#select1 option:eq(3)", [ "option1d" ] );
1260-
assert.t( "Check element position", "#qunit-fixture div div:eq(10)", [ "names-group" ] );
1271+
assert.t( "Check element position", "#qunit-fixture div div:eq(10)", [ "no-clone-exception" ] );
12611272
assert.t( "Check element position", "#qunit-fixture div div:first", [ "nothiddendivchild" ] );
12621273
assert.t( "Check element position", "#qunit-fixture div > div:first", [ "nothiddendivchild" ] );
12631274
assert.t( "Check element position", "#qunit-fixture div:first a:first", [ "yahoo" ] );

0 commit comments

Comments
 (0)