jquery/sizzle — Issue #86: Expr.relative truncates prematurely
Author: gibson042
Created: 2012-01-07 03:17:18+00:00
State: open

Copied from http://bugs.jquery.com/ticket/11109

Test case: http://jsfiddle.net/JBBM8/

Because `Sizzle.selectors.relative` functions "return" only a single match, Sizzle can be trapped into a false negative with respect to preceding parts of the full selector when the relative selector tests against multiple elements (e.g., `"~"` and `""`).

I'm pretty sure that fixing this will require changing the `Sizzle.selectors.relative` Extension API to allow "returning" *arrays*, so I will hold off working on this until the core team weighs in with their comments/approval.

Technical explanation: Given a query like `"A + B ~ C"`, Sizzle:

1. Gets a set of all `C`, then
2. Uses `Sizzle.selectors.relative["~"]` to replace each element with the first preceding sibling element matching `B` (or `false` if nonexistent), then
3. Uses `Sizzle.selectors.relative["+"]` to replace each element with the preceding sibling element if it matches `A` (or `false` if it doesn't), then
4. Returns all elements from the set at step 1 that stayed non-`false` through all subsequent steps

The problem here is that step 2 fails to report back *all* preceding siblings matching `B`, erroneously restricting the input set for subsequent step 3.