Skip to content

:scope always refers to the document element, so find(':scope > li') matches nothing #133

Open

Description

@gravitypdf-bot

Description of the bug

:scope always refers to the document element, never to the element find() was called on. So it can't be used to anchor a search at the current match set, as jQuery's $(el).find(':scope > li') does:

$xml = '<?xml version="1.0"?><root><ul id="u1"><li id="a"/><li id="b"/></ul><ul id="u2"><li id="c"/></ul></root>';

qp($xml, '#u1')->find(':scope > li');              // (none), expected a, b
qp($xml, 'ul')->find(':scope > li');               // (none), expected a, b, c
qp($xml, '#u1')->find('li:not(:scope > li)');      // a, b, expected (none)
qp($xml, '#u1')->find('li:matches(:scope > li)');  // (none), expected a, b
qp($xml)->find(':scope > ul');                     // u1, u2 (correct only because the scope is the root)

Cause

DOMQuery::find() / findInPlace() and DOM's constructor build new DOMTraverser($this->matches) without a scope node, so DOMTraverser falls back to $this->dom->documentElement. The nested traversers for :not() / :matches() (PseudoClass::is()) also pass null, so :scope inside them is the document element even when the outer query had a real scope. Noted in #128.

With more than one element in the set, :scope should match each of them (jQuery runs .find() per element).

QueryPath version

main at 9d04ccf.

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