mojolicious / mojo

:sparkles: Mojolicious - Perl real-time web framework

Home Page:https://mojolicious.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mojo::DOM doesn't handle :nth-child correctly

mauke opened this issue · comments

commented
  • Mojolicious version: 9.31
  • Perl version: v5.36.0
  • Operating system: Linux (Ubuntu 22.04)

Steps to reproduce the behavior

#!/usr/bin/env perl
use v5.12.0;
use warnings;
use Test::More;
use Mojo::DOM;

my $dom = Mojo::DOM->new(<<'_EOT_');
<!DOCTYPE html>
<ul> <li>Ax1</li> </ul>
<ul> <li>Bx1</li> <li>Bx2</li> </ul>
<ul> <li>Cx1</li> <li>Cx2</li> <li>Cx3</li> </ul>
<ul> <li>Dx1</li> <li>Dx2</li> <li>Dx3</li> <li>Dx4</li> </ul>
<ul> <li>Ex1</li> <li>Ex2</li> <li>Ex3</li> <li>Ex4</li> <li>Ex5</li> </ul>
<ul> <li>Fx1</li> <li>Fx2</li> <li>Fx3</li> <li>Fx4</li> <li>Fx5</li> <li>Fx6</li> </ul>
_EOT_

is_deeply
    $dom->find('li:nth-child(-n+3)')->map(sub { $_->to_string })->to_array,
    [qw(
        <li>Ax1</li>
        <li>Bx1</li> <li>Bx2</li>
        <li>Cx1</li> <li>Cx2</li> <li>Cx3</li>
        <li>Dx1</li> <li>Dx2</li> <li>Dx3</li>
        <li>Ex1</li> <li>Ex2</li> <li>Ex3</li>
        <li>Fx1</li> <li>Fx2</li> <li>Fx3</li>
    )],
    'all first three children';

done_testing;

Expected behavior

Test passes.

https://www.w3.org/TR/selectors-3/#nth-child-pseudo:

The :nth-child(an+b) pseudo-class notation represents an element that has an+b-1 siblings before it in the document tree, for any positive integer or zero value of n.

[...]

The value a can be negative, but only the positive values of an+b, for n≥0, may represent an element in the document tree.

Example:

html|tr:nth-child(-n+6)  /* represents the 6 first rows of XHTML tables */

Actual behavior

not ok 1 - all first three children
#   Failed test 'all first three children'
#   at mojo-dom-bug-3.pl line 18.
#     Structures begin differing at:
#          $got->[0] = '<li>Cx1</li>'
#     $expected->[0] = '<li>Ax1</li>'
1..1
# Looks like you failed 1 test of 1.