Opened 12 years ago
Closed 11 years ago
#7010 closed bug (fixed)
:not(:has(:has(*))) fails
Reported by: | dept42 | Owned by: | timmywil |
---|---|---|---|
Priority: | low | Milestone: | 1.next |
Component: | selector | Version: | 1.4.4 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
While :not(:has(*)) works fine to find nodes with no children, and :has(:has(*)) works to find nodes with grandchildren, :not(:has(:has(*))) returns nothing, instead of returning only nodes without grandchildren.
It seems like this may be due to a chunker bug which parses the filter into [":not", ":has(:has(*)))"], which seems wrong (note unbalanced closing paren) -- but I couldn't follow what was happening in the code past that point.
Interestingly, :not(:has(:has(*)) does return something, although not the expected result.
Change History (22)
comment:1 Changed 12 years ago by
Component: | unfiled → selector |
---|
comment:2 Changed 12 years ago by
Milestone: | 1.4.3 |
---|---|
Priority: | → low |
Status: | new → open |
comment:3 Changed 12 years ago by
Owner: | set to dept42 |
---|---|
Status: | open → pending |
comment:4 Changed 12 years ago by
Here is the jsfiddle for this bug. http://jsfiddle.net/9uxcr/ Tested against 1.4.3 and the jquery 0 GIT versions, and the bug still persists.
comment:5 Changed 12 years ago by
Milestone: | → 1.4.5 |
---|---|
Priority: | low → high |
Status: | pending → open |
Version: | 1.4.2 → 1.4.4 |
test case. :not(:has(:has(*)))
throws an exception under 1.4.4 (under 1.4.3 it incorrectly returned an empty set).
comment:6 Changed 12 years ago by
Status: | open → pending |
---|
Can you come up with a more realistic test case? It does seem like this fails but it seems unlikely that anyone would use it in real life. It's hard to justify spending time on it otherwise.
comment:7 Changed 12 years ago by
Status: | pending → open |
---|
comment:8 Changed 12 years ago by
Status: | open → pending |
---|
comment:9 Changed 12 years ago by
Status: | pending → new |
---|
FWIW, I ran across this bug precisely because I needed to find all nodes without grandchildren in a real application. IIRC, the use case was that I was looking for date information in HTML of variable structure, where sometimes it would be in a leaf node, or sometimes split across a couple adjacent leaf nodes (e.g. because part of it was italicized). So I wanted to get a list of all nodes in the bottom two levels of the hierarchy (those without grandchildren), so that I could then check the text() of each against the date formats I was able to parse.
comment:10 Changed 12 years ago by
Priority: | high → low |
---|---|
Resolution: | → patchwelcome |
Status: | new → closed |
This isn't going to be a priority so we're going to close this patchwelcome. A better way to solve the original problem would be to use filter with a function.
comment:12 Changed 12 years ago by
Resolution: | patchwelcome |
---|---|
Status: | closed → reopened |
This seems to be a larger issue - it seems like many bugs are happening related to :has() containing other :foo() expressions.
comment:13 Changed 12 years ago by
Status: | reopened → open |
---|
comment:15 Changed 11 years ago by
Stupid question. Why is a core selector engine bug, effecting all browsers, of which many duplicate bugs have been raised, only a low priority to fix?
More test cases: http://jsfiddle.net/AlistairB/F7gzn/5/
comment:16 follow-up: 17 Changed 11 years ago by
It's low priority because very few people use selectors that complex. It's also hard to fix.
Since these selectors are not part of any standard (they're not CSS3) we might also just define away the non-working cases by restricting the allowed sub-selectors.
comment:17 Changed 11 years ago by
Replying to dmethvin:
It's low priority because very few people use selectors that complex. It's also hard to fix.
Since these selectors are not part of any standard (they're not CSS3) we might also just define away the non-working cases by restricting the allowed sub-selectors.
Thanks for your response.
Unfortunately it's a fairly common case in AJAXy web applications IMO.
Say you have a table of people attending an event and you click on the button 'change to female only event'. You want to do something like this.
$(".person-table > tr:has(.sex:contains(man))").each(function() { var personId = $(this).children(".person-id").text(); removePersonFromEventViaAJAX(personId); $(this).remove(); });
But due to this bug, you are forced to select the .sex cells themselves and traverse from this in the each block. (Not a massive deal, but I think cases like this are relatively common.)
comment:18 Changed 11 years ago by
Blocked by: | 10697 added |
---|---|
Milestone: | 1.next → 1.8 |
comment:19 Changed 11 years ago by
#8132 was closed as a duplicate of this bug, although this one doesn't throw a syntax error (it just returns incorrect results), whereas in #8132, Sizzle actually throws an error. Are we sure the syntax error variant really is a duplicate of this same bug?
If so, another quite simple failing test case -- give me all divs that have a span as their first child:
var elms = $('div:has(span:nth-child(1))');
Result:
Syntax error, unrecognized expression: :has(span:nth-child
And note that although the syntax error suggests it's a problem with nested parentheses, some other nested parentheses work, such as:
var elms = $('div:has(p:not(.b))');
...works just fine (Live copy | source).
comment:20 Changed 11 years ago by
Blocked by: | 10697 removed |
---|
comment:21 Changed 11 years ago by
Milestone: | 1.8 → 1.next |
---|---|
Owner: | changed from dept42 to timmywil |
Status: | open → assigned |
comment:22 Changed 11 years ago by
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Sizzle: fix multiple nested pseudos. Fixes #7010.
Changeset: accb3c4932055692221ba7d21e207680df8017b3
Please provide a reduced test case on jsFiddle