fb55/css-select

"* html" incorrectly matches elements

SLaks opened this issue · 10 comments

(tested using Cheerio & htmlparser2)

The selector * html will incorrectly match the <html> element, because it picks up the virtual type: 'root' element as a parent.
* * html will correctly not match anything.

I think the fix would be to change universal to return a function that checks that elem.type !== 'root'.

However, I'm not sure.

fb55 commented

This is actually a cheerio issue, as the default DOM returned by my DomHandler module has no elements of the type root.

:root shouldn't work with cheerio, either.

@matthewmueller Does cheerio need the root element?

I was wondering about that...

Having a root simplifies a lot of the top-level logic and allows you to append and prepend on single DOM Nodes.

var plum = '<li class="plum">Plum</li>',
     apple = '<li class="apple">Apple</li>',
     $ = cheerio.load(plum);

$.root().append(apple)
$.html() // <li class="plum">Plum</li><li class="apple">Apple</li>

This isn't often necessary in the jquery work because you're not adding things to <html>, but it turns out to be useful when you're doing HTML manipulations with fragments.

Any idea what the best way to work around this issue is?

CSSselect could have special-case code for Cheerio's type="root" element

what's your use case for matching $('* html') ? that seems a bit bizarre to me

I'm trying to make the Acid2 test pass in my server-side HTML mangler.

Did you try the other equivalents: $('*').find('html'), $('html', '*')?

I'm running Cheerio on all of the CSS selectors in the test, and this selector is incorrectly matching elements.

fb55 commented

This won't be fixed in CSSselect. I opened a cheerio issue (cheeriojs/cheerio#162), everything else should be discussed there.