Bug Tracker

Ticket #13182 (closed bug: fixed)

Opened 2 years ago

Last modified 2 years ago

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:
Blocking: Blocked by:

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

comment:1 Changed 2 years ago by dmethvin

  • Owner set to anonymous
  • Status changed from new to pending

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 2 years ago by anonymous

  • Status changed from pending to new

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 follow-up: ↓ 5 Changed 2 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 2 years ago by dmethvin

  • Status changed from new to pending

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 2 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 2 years ago by anonymous

  • Status changed from pending to new

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 2 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 2 years ago by gibson042

  • Status changed from new to assigned
  • Component changed from unfiled to selector
  • Summary changed from complex has attribute selectors broken in IE7 & IE8 in versions 1.8.2+ to nested has selectors broken in IE7 & IE8 in versions 1.8.2+
  • Priority changed from undecided to low
  • Version changed from git to 1.8.2
  • Milestone changed from None to 1.next
  • Owner changed from anonymous to gibson042

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 2 years ago by gibson042 (previous) (diff)

comment:9 Changed 2 years ago by Richard Gibson

  • Status changed from assigned to closed
  • Resolution set to fixed

Fix #13182: update Sizzle

Changeset: d8690344b7ba8c0b4a1eb7d57c7c0fcdbbc0ba7c

comment:10 Changed 2 years ago by Richard Gibson

Fix #13182: update Sizzle

Changeset: 2f0756b5341eb94ae540de20b9756762dc0a4144

comment:11 Changed 2 years ago by gibson042

  • Milestone changed from 1.next to 1.9.1

comment:12 Changed 2 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.