We originally had special handling for `:host()` as that had been the
only pseudo-class that could be both an identifier or a function.
However, this meant duplicating the serialization logic, and also we
had to manually remember to add the same hack for any other
identifier-and-function cases. Which I forgot to do with `:heading()`!
So instead, for these cases, detect if they actually have arguments
specified and use that to determine which form to serialize as. We do
still have to write a check for each one of these pseudo-classes, but
the VERIFY should make it easier to remember.
Selector::serialize() is used for both normal and relative selectors.
For the latter, we need to serialize their initial combinator, and for
the former, we always set the initial combinator as None anyway, so
this would be a no-op there.
Gets us 3 WPT passes.
The spec requires us to accept any ident here, not just ltr/rtl, and
also serialize it back out. That means we need to keep the original
string around.
In order to not call keyword_from_string() every time we want to match
a :dir() selector, we still attempt to parse the keyword and keep it
around.
A small behaviour change is that now we'll serialize the ident with its
original casing, instead of always lowercase. Chrome and Firefox
disagree on this, so I think either is fine until that can be
officially decided.
Gets us 2 WPT passes (including 1 from the as-yet-unmerged :dir() test).
The spec gives us a hard-coded list of functional pseudo-classes and how
to serialize them - but this list is incomplete and likely to always be
outdated compared to the list of pseudo-classes that exist. So instead,
use the generated metadata we already have to serialize their arguments
based on their type.
This fixes :dir() and :has(), which previously did not serialize their
arguments.
Gets us 26 passes (including 6 from that as-yet-unmerged :dir() test).
Previously we only matched against the first attribute with a given
local name. What we actually want to do is look at each attribute with
that local name in turn and only return false if none of them match.
Also remove a hack for HTML elements in HTML documents, where we would
refuse to match any namespaced attributes. This doesn't seem to be
based on the spec, but we had regressions without it, until now. :^)
Gets us 21 more WPT subtest passes.
The HTML spec gives us a list of HTML attributes that must have their
values compared case-insensitively by default (when the attribute
selector does not specify a case-sensitiveness). However, ifwe have a
namespace, then we are not looking for an HTML attribute, so this
should not apply.
Gets us 8 more WPT subtest passes.
This fixes three WPT test cases at html/dom/elements/global-attributes/dir-assorted.window.html
Update test expectations for Tests/LibWeb/Text/expected/wpt-import/css/selectors/dir-pseudo-on-bdi-element.txt
This allows us to disable test output, which performs expensive assert
tracking. This was making our imported tests run significantly slower
than tests run via `WPT.sh`.
Formatting the output ourselves also allows us to remove unnecessary
information from the test output.
This commit also rebaselines all existing imported WPT tests to follow
the new format.
We can't invalidate after the removal has taken effect, since that means
invalidation won't be able to find potentially affected siblings and
ancestors by traversing from the invalidation target.
...when running in test mode. This cuts down on the time it takes to run
the imported WPT tests, and you can still get the full error by opening
tests in the browser.
1. We were not propagating selectedness updates from option to select
if the option was inside an optgroup.
2. When two or more options were selected, we were always favoring the
last one in tree order, instead of the last one that got checked.
3. We were neglecting to return in the `display size is 1` case when
all elements were disabled.
This was covered by some of the :has() selector tests. :^)
We basically need to do this for every invocation of invalidate_style()
right now, so let's just do it inside invalidate_style() itself.
Fixes one missing invalidation issue caught by a WPT test. :^)