Skip to main content

Bug Tracker

Side navigation

#13182 closed bug (fixed)

Opened January 08, 2013 08:50PM UTC

Closed January 16, 2013 05:17AM UTC

Last modified January 18, 2013 08:43PM UTC

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.

Attachments (0)
Change History (12)

Changed January 08, 2013 08:56PM UTC by dmethvin comment:1

owner: → 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?

Changed January 09, 2013 05:01PM UTC by anonymous comment:2

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.

Changed January 09, 2013 05:21PM UTC by anonymous comment:3

correction, try this one instead:

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

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

Changed January 09, 2013 05:32PM UTC by dmethvin comment:4

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/

Changed January 09, 2013 06:29PM UTC by gibson042 comment:5

Replying to [comment:3 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.

Changed January 10, 2013 09:32PM UTC by anonymous comment:6

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.

Changed January 11, 2013 09:50PM UTC by anonymous comment:7

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...

Changed January 16, 2013 03:17AM UTC by gibson042 comment:8

_comment0: 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 [https://github.com/jquery/sizzle/blob/5c51caa03824a86ca841aa9613b05f1ad5750228/test/unit/selector.js#L672 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 [http://jsfiddle.net/XcNCz/2/ achieved] with descendant selectors—is always unnecessary.1358310223582739
component: unfiledselector
milestone: None1.next
owner: anonymousgibson042
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.

Changed January 16, 2013 05:17AM UTC by Richard Gibson comment:9

resolution: → fixed
status: assignedclosed

Fix #13182: update Sizzle

Changeset: d8690344b7ba8c0b4a1eb7d57c7c0fcdbbc0ba7c

Changed January 16, 2013 05:18AM UTC by Richard Gibson comment:10

Fix #13182: update Sizzle

Changeset: 2f0756b5341eb94ae540de20b9756762dc0a4144

Changed January 16, 2013 05:21AM UTC by gibson042 comment:11

milestone: 1.next1.9.1

Changed January 18, 2013 08:43PM UTC by anonymous comment:12

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!!