sparklemotion / nokogiri

Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby.

Home Page:https://nokogiri.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[feature] using "of <complex-selector-list>" for `:nth-child` and `:nth-last-child`

G-Rath opened this issue · comments

Please describe the bug

:nth-child and :nth-last-child support an optional "of " argument, which currently results in an error with nokogiri.

Help us reproduce what you're seeing

#! /usr/bin/env ruby

require 'nokogiri'
require 'minitest/autorun'

class Test < Minitest::Spec
  describe "Node#css" do
    it "should find a div using chained classes" do
      html = <<~HEREDOC
        <html>
          <body>
            <span>hello world!</span>
            <div class="foo"> one</div>
            <div class="bar">two</div>
            <div class="foo bar">three</div>
      HEREDOC

      doc = Nokogiri::HTML::Document.parse(html)

      assert_equal "two", doc.css(':nth-child(2 of div)').text
      assert_equal 1, doc.css("div.foo.bar").length
      assert_equal "three", doc.at_css("div.foo.bar").text
    end
  end
end
❯ bundle exec rails test test/my_test.rb
Run options: --seed 16242

# Running:

E

Error:
Node#css#test_0001_should find a div using chained classes:
Nokogiri::CSS::SyntaxError: unexpected ' ' after '2'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/css/parser_extras.rb:86:in `on_error'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/racc-1.7.3/lib/racc/parser.rb:267:in `_racc_do_parse_c'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/racc-1.7.3/lib/racc/parser.rb:267:in `do_parse'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/css/parser_extras.rb:68:in `parse'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/css/parser_extras.rb:78:in `xpath_for'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/css.rb:52:in `xpath_for'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:251:in `block in xpath_query_from_css_rule'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:250:in `map'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:250:in `xpath_query_from_css_rule'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:242:in `block in css_rules_to_xpath'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:242:in `map'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:242:in `css_rules_to_xpath'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:211:in `css_internal'
    /home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/lib/nokogiri/xml/searchable.rb:132:in `css'
    /home/jones/workspace/projects/my_app/test/my_test.rb:20:in `block (2 levels) in <class:Test>'


bin/rails test /home/jones/workspace/projects/my_app/test/my_test.rb:8



Finished in 0.006674s, 149.8387 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

Expected behavior

It passes

Environment

# Nokogiri (1.15.5)
    ---
    warnings: []
    nokogiri:
      version: 1.15.5
      cppflags:
      - "-I/home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/ext/nokogiri"
      - "-I/home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/ext/nokogiri/include"
      - "-I/home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/ext/nokogiri/include/libxml2"
      ldflags: []
    ruby:
      version: 3.1.4
      platform: x86_64-linux
      gem_platform: x86_64-linux
      description: ruby 3.1.4p223 (2023-03-30 revision 957bb7cb81) [x86_64-linux]
      engine: ruby
    libxml:
      source: packaged
      precompiled: true
      patches:
      - 0001-Remove-script-macro-support.patch
      - 0002-Update-entities-to-remove-handling-of-ssi.patch
      - 0003-libxml2.la-is-in-top_builddir.patch
      - '0009-allow-wildcard-namespaces.patch'
      - 0010-update-config.guess-and-config.sub-for-libxml2.patch
      - 0011-rip-out-libxml2-s-libc_single_threaded-support.patch
      libxml2_path: "/home/jones/.rbenv/versions/3.1.4/lib/ruby/gems/3.1.0/gems/nokogiri-1.15.5-x86_64-linux/ext/nokogiri"
      memory_management: ruby
      iconv_enabled: true
      compiled: 2.11.6
      loaded: 2.11.6
    libxslt:
      source: packaged
      precompiled: true
      patches:
      - 0001-update-config.guess-and-config.sub-for-libxslt.patch
      datetime_enabled: true
      compiled: 1.1.39
      loaded: 1.1.39
    other_libraries:
      zlib: 1.2.13
      libgumbo: 1.0.0-nokogiri

Additional context

I've confirmed this works in a real browser:

image

This would be a great feature to add! If you're interested in implementing it, I would be happy to give some suggestions and review a pull request.

However, I won't be able to spend time implementing this myself anytime soon. Please let me know how I can help you contribute!