You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 1be874a
Browse filesBrowse the repository at this point in the historyBrowse files
* Make :has() match related elements in DOMTraverser
PseudoClass::has() ran its argument in initialized mode against the
element itself, so ul:has(li) asked whether the ul is an li and never
matched. It now reads the argument as a relative selector anchored to
the element: a descendant by default, or a child, next sibling or later
sibling for a leading >, + or ~. :not() and :matches() keep testing the
element itself.
:has() is no longer a set filter when its argument is positional: the
argument is searched for around each element, as in jQuery.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Test a later sibling itself against a sibling-relative :has()
find() now searches descendants only (#73), so the per-sibling search in
:has(+ ...) and :has(~ ...) no longer saw the sibling it started from.
Test the sibling itself first, and search below it only when the group
goes on to a child or descendant.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Return whether a :has() group starts at a sibling, not its combinator
has() only ever asked whether the anchor combinator was + or ~, so
relativeSelector() now answers that, and the descendant and sibling
searches become the two arms of one if/else.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Share the sibling index with the queries :has() runs
findsAny() built each per-element and per-sibling traverser with its own
PseudoClass, so with #119's index every one re-indexed its sibling list:
li:has(~ li:nth-child(1)) over 400 siblings took about 9 s. It now passes
its own handler, as is() does, which also lets a nested :has() reuse the
parsed-argument cache (about 0.26 s).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -52,6 +52,7 @@ QueryPath Changelog
52
52
- Fix `not()` keeping only the given nodes, instead of removing them, when passed an `SplObjectStorage` such as `get(null, true)` returns (issue #75)
53
53
- Fix selectors with two or more levels of nested parentheses, such as `li:not(:not(:nth-child(1)))` or `ul:has(li:not(:nth-child(1)))`, throwing "Recursion error detected" (issue #120). The scanner skipped the character after every nested argument, so the outer argument never saw its closing paren. This also stops `li:not(:nth-child(1)) b` from folding ` b` into the `:not()` argument, and lets quoted arguments contain parentheses, as in `:contains("a)b")`
54
54
- Fix `QueryPath::VERSION` and `QueryPath::VERSION_MAJOR` still reporting `3.2.2` and `3`. They now report `4.2.0` and `4`, and both are deprecated in favour of `\Composer\InstalledVersions::getPrettyVersion('gravitypdf/querypath')`, which cannot drift from the installed version (issue #83)
55
+
-**Behaviour change.** Fix `:has()` never matching in `find()`, `filter()` and the other methods that use `QueryPath\CSS\DOMTraverser`, so that `ul:has(li)` selected nothing and `:not(:has(li))` selected everything (issue #121). `:has()` now matches an element with a descendant matching its argument, and supports relative selectors: `ul:has(> li)` (a child), `h2:has(+ p)` (the next sibling) and `h2:has(~ p)` (a later sibling). A positional pseudo-class in the argument indexes each element's own matches, so `ul:has(li:eq(2))` selects every list with at least three items
0 commit comments