Bug Tracker

Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#13182 closed bug (fixed)

nested has selectors broken in IE7 & IE8 in versions 1.8.2+

Reported by: anonymous Owned by: gibson042
Priority: low Milestone: 1.9.1
Component: selector Version: 1.8.2
Keywords: Cc:
Blocked by: Blocking:

Description

I have a rather complex DOM structure and I am doing some rather involved queries to get to data stored in this structure. (Questionable, I know) I recently took the initiative and updated our reference to jQuery to use the latest version and suddenly things started breaking. Specifically, queries that were looking for attributes inside of a :has. Below is a sample query that works flawlessly (albeit slowly) in 1.8.1 but fails in 1.8.2+.

This fails in IE7 but works for IE8 $('.SomeClass:has(div:has(div[SomeAttr=SomeValue]))');

The following works in IE8 but not in IE7 $('.SomeClass:has(div:has(div [SomeAttr=SomeValue]))');

Note the additional space after the last div.

In addition, I cannot get the following slightly more complex query to work at all in IE7 or IE8 using 1.8.2+.

$('.SomeClass:has(div:has(div[SomeAttr=SomeValue],div[SomeOtherAttr=SomeOtherValue]))');

I have not had the time to step through the developer versions of the code to see if I can find the culprit, but I did step back through versions of jQuery and found that the problems went away when I stepped back into 1.8.1. (We had been on 1.7.x before I jumped up to 1.8.3)

I'll try to monitor this ticket and respond to any questions the jQuery team may have.

Change History (12)

comment:1 Changed 11 years ago by dmethvin

Owner: set to anonymous
Status: newpending

The first thing we'd want is a simple test case that demonstrates the problem. Can you create one on jsfiddle.net or jsbin.com?

comment:2 Changed 11 years ago by anonymous

Status: pendingnew

Sorry, I thought I had provided enough information. As it turns out, I had the bug a bit off. But it is similar. The error just goes in the other direction. below is the link to the fiddler for this:

http://jsfiddle.net/RwR8U/

Just in case things do not work right, here is my html and js:

-HTML-

<div class="tile">
  <div>
    <div someAttr='boo'>
  </div>
</div>
<div class="tile">
  <div>
    <div someAttr='foo'>
  </div>
</div>
<div class="tile">
  <div>
    <div someAttr='boo'>
  </div>
</div>
<div class="tile">
  <div>
    <div someAttr='boo'>
  </div>
</div>
<div id="result"></div>

-JS-

$(document).ready(function(){
  $('#result').html($( '.tile:has(div:has(div [someAttr=foo]))' ).length);
});

To verify that things work right and then to reproduce the bug, do the following:

  • Launch this fiddler in IE9 (I used IE9 as its emulators for older versions matched the behavior i was seeing in native IE7).
  • Verify that JQ version 1.7.2 is currently being utilized
  • run the script
  • note that the result is 1 item (this is what it should be)
  • Launch the IE Dev Tools (F12) and switch the IE version to 7
  • Execute the script again against 1.7.2
  • note that the result is still 1 item (still good)
  • now switch the version to 1.8.2
  • run the script again (still in IE7 mode)
  • note that the result is now 2 (this value is incorrect!)
  • for an additional twist, remove the space between the last div and the [ and you will now get 0 items. However, after a bit of playing, I do believe that the space is required for proper use of this feature. Is this correct?

Please let me know if I can provide any additional information.

comment:3 Changed 11 years ago by anonymous

correction, try this one instead:

http://jsfiddle.net/RwR8U/5/

it should have the space between the last div and the [ as described...

comment:4 Changed 11 years ago by dmethvin

Status: newpending

Can you confirm that this test case works as you expect, once all the divs are properly closed?

http://jsfiddle.net/RwR8U/7/

comment:5 in reply to:  3 Changed 11 years ago by gibson042

Replying to anonymous:

correction, try this one instead:

http://jsfiddle.net/RwR8U/5/

it should have the space between the last div and the [ as described...

Whitespace between div and [someAttr=foo] is not meaningless; it is a descendant combinator. div [someAttr=foo] matches any element with attribute "someAttr" having value "foo" that is contained within a div. Any past interpretation of it as equivalent to div[someAttr=foo] (which matches a div with attribute "someAttr" having value "foo") was a bug on our part.

comment:6 Changed 11 years ago by anonymous

Status: pendingnew

erg... copy, paste and fast editing. I'll get back to this in a few days when i have time again. I can guarantee that the odd behavior is there and that swapping out versions will make it go away though.

And at least i know that there was some weirdness around the spaces in the past. in my case, the div should contain an attribute with the value. and i was not seeing consistent behavior. Again, I'll run some tests in a few days when i have time to breathe again.

Thanks jQuery team.

comment:7 Changed 11 years ago by anonymous

Ended up with a little free time today so, start by visiting this:

http://jsfiddle.net/XcNCz/

  • Then fire up IE7
  • Verify that JQ 1.7.2 is being utilized
  • Run the test
  • Note 2 cats are found and that 3 cats and dogs are found (correct)
  • Switch the version to 1.8.2
  • Run the test
  • Note that zero of either are located (bad)

This is what I was seeing originally in my app, and you were right about my quickly hacked tags creating a separate issue.

I've rolled back to version 1.7.2 for now in my app as I know for a fact that it works. And I only see this bad behavior in IE7 (Tested IE7, 8, 9, FF and Chrome). I would love to get all stabby on that darn browser...

comment:8 Changed 11 years ago by gibson042

Component: unfiledselector
Milestone: None1.next
Owner: changed from anonymous to gibson042
Priority: undecidedlow
Status: newassigned
Summary: complex has attribute selectors broken in IE7 & IE8 in versions 1.8.2+nested has selectors broken in IE7 & IE8 in versions 1.8.2+
Version: git1.8.2

Well, you sure get my vote for most obscure bug of the month. This one was a doozy, basically coming down to element ancestry cache keys conflicting for sub-runs within a parent selector containing nested :has checks... even writing a unit test took about 15 minutes!

This will be fixed in 1.9.1, but I strongly recommend refactoring. Even non-nested :has selectors exhibit pretty bad performance, but nesting makes it an order of magnitude worse, and—since the same can be achieved with descendant combinators—is always unnecessary.

Last edited 11 years ago by gibson042 (previous) (diff)

comment:9 Changed 11 years ago by Richard Gibson

Resolution: fixed
Status: assignedclosed

Fix #13182: update Sizzle

Changeset: d8690344b7ba8c0b4a1eb7d57c7c0fcdbbc0ba7c

comment:10 Changed 11 years ago by Richard Gibson

Fix #13182: update Sizzle

Changeset: 2f0756b5341eb94ae540de20b9756762dc0a4144

comment:11 Changed 11 years ago by gibson042

Milestone: 1.next1.9.1

comment:12 Changed 11 years ago by anonymous

Hey, thanks for looking into that so quickly. Yes, I know that the selector is HORRID and i really should not be doing it. I will be refactoring that chunk of code at the very next chance i get. was a very bad design decision on my part to do what i did. live and learn. Thanks again jQuery team!!

Note: See TracTickets for help on using tickets.