Skip to content

eq(), get() and slice() ignore negative indexes; slice(-2) returns the whole set #142

Open

Description

@gravitypdf-bot

Description

eq(), get() and slice() don't support negative indexes. jQuery counts a negative index back from the end of the set. QueryPath returns nothing for eq() and get(), and the whole set for slice():

$xml = '<?xml version="1.0"?><r><i id="a"/><i id="b"/><i id="c"/><i id="d"/><i id="e"/></r>';
$qp  = qp($xml, 'i');
Call jQuery 3.7.1 QueryPath main
eq(-1) e (empty)
eq(-5) a (empty)
get(-1) e NULL
slice(-2) d, e a, b, c, d, e
slice(-9) a, b, c, d, e a, b, c, d, e

The slice(-2) result is the worst of these: the call returns a set, just the wrong one, so nothing signals the mistake.

Cause

  • DOM::getNthMatch() (src/DOM.php) returns NULL for any $index < 0. Both eq() and get($index) go through it.
  • slice() (src/Helpers/QueryFilters.php) keeps every match where $i >= $start. That is true for every $i when $start is negative.

Expected

As in jQuery (and array_slice(), which the slice() DocBlock cites), a negative index counts from the end:

  • eq(-n) and get(-n) mean the match at count() - n.
  • slice(-n) starts n from the end.
  • An index still out of range after that gives an empty set, or NULL from get().

No working code passes a negative index today, so this should be safe to fix in a minor release. The meaning of slice()'s second argument is a separate difference from jQuery (#144).

QueryPath version

main at 4d05c9e. The jQuery values come from jQuery 3.7.1 on jsdom.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions