Bug Tracker

Opened 7 years ago

Closed 5 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 7 years ago by dmethvin

Component: unfiledselector

comment:2 Changed 7 years ago by snover

Milestone: 1.4.3
Priority: low
Status: newopen

comment:3 Changed 7 years ago by Rick Waldron

Owner: set to dept42
Status: openpending

Please provide a reduced test case on jsFiddle

comment:4 Changed 7 years ago by anonymous

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 7 years ago by jitter

Milestone: 1.4.5
Priority: lowhigh
Status: pendingopen
Version: 1.4.21.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 6 years ago by dmethvin

Status: openpending

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 6 years ago by dmethvin

Status: pendingopen

comment:8 Changed 6 years ago by dmethvin

Status: openpending

comment:9 Changed 6 years ago by dept42

Status: pendingnew

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 6 years ago by dmethvin

Priority: highlow
Resolution: patchwelcome
Status: newclosed

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:11 Changed 6 years ago by john

#8132 is a duplicate of this ticket.

comment:12 Changed 6 years ago by john

Resolution: patchwelcome
Status: closedreopened

This seems to be a larger issue - it seems like many bugs are happening related to :has() containing other :foo() expressions.

comment:13 Changed 6 years ago by dmethvin

Status: reopenedopen

comment:14 Changed 6 years ago by timmywil

#10020 is a duplicate of this ticket.

comment:15 Changed 6 years ago by AlistairB

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 Changed 6 years ago by 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.

comment:17 in reply to:  16 Changed 6 years ago by AlistairB

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 6 years ago by dmethvin

Blocked by: 10697 added
Milestone: 1.next1.8

comment:19 Changed 5 years ago by T.J. Crowder <tj@…>

#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

Live copy | source

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 5 years ago by timmywil

Blocked by: 10697 removed

comment:21 Changed 5 years ago by timmywil

Milestone: 1.81.next
Owner: changed from dept42 to timmywil
Status: openassigned

comment:22 Changed 5 years ago by timmywil

Resolution: fixed
Status: assignedclosed

Sizzle: fix multiple nested pseudos. Fixes #7010.

Changeset: accb3c4932055692221ba7d21e207680df8017b3

Note: See TracTickets for help on using tickets.