Commit graph

81 commits

Author SHA1 Message Date
Sam Atkins
168865dbdc LibWeb: Implement and use BorderRadiusStyleValue
This parses the elliptical border-radius values, though currently we
only support circular ones. So, to_length() is overloaded to return the
horizontal-radius. This means the code in Layout/Node.cpp does not need
to change for now.
2021-08-14 12:45:01 +02:00
Sam Atkins
cb3e097663 LibWeb: Implement and use BorderStyleValue 2021-08-14 12:45:01 +02:00
Sam Atkins
c27f99fc1d LibWeb: Implement and use FlexFlowStyleValue 2021-08-14 12:45:01 +02:00
Sam Atkins
2644d2c221 LibWeb: Implement and use FlexStyleValue
This is not just moving the code from StyleResolver to Parser. The logic
has changed to allow for the `flex-basis` to come before or after the
`flex-grow/shrink` values, as well as handle the special one-value
cases.

Also added test cases to flex.html to check the parsing. It does parse
correctly, but elements with `flex-basis: auto` do not calculate their
width correctly.
2021-08-14 12:45:01 +02:00
Sam Atkins
44a082391b LibWeb: Implement and use TextDecorationStyleValue
Modified text-decoration.html to better test that the values can be in
any order, and that it adopts the color from the `color` property if no
decoration color is specified. Right now, it always does because we do
not support a different decoration color. Later, we need to support the
`currentcolor` special CSS value for this purpose.
2021-08-14 12:45:01 +02:00
Sam Atkins
0e15561df0 LibWeb: Implement and use ListStyleStyleValue
Yes, the name is silly, but it's a StyleValue for list-style, so...
yeah. :^)

Since `list-style-type` and `list-style-image` can both have `none` as a
value, and can appear in any order, we have to handle it separately, and
then assign either or both of those to `none` depending on how many
`none`s there are, and whether those sub-properties already have values.

Added some extra test cases to lists.html to cover list-style-image and
list-style-position parts of the list-style shorthand, and the `none`
values.
2021-08-14 12:45:01 +02:00
Sam Atkins
dcbfb61816 LibWeb: Implement and use BackgroundStyleValue
This one represents one secton of a `background` property, since it can
have multiple background values separated by commas. Eventually, we will
represent that as a List of BackgroundStyleValues.

Also modified some background-foo properties in StyleResolver so that
the is_background_x() functions could be removed.

I realized that our handling of var() in shorthand properties is wrong,
so have been removing the is_builtin_or_dynamic() calls from the parsing
code for shorthands. This broke our var() test page, so I have replaced
the use of 'background' with 'background-color' there.
2021-08-14 12:45:01 +02:00
Sam Atkins
59501f1940 LibWeb: Implement and use FontStyleValue
After working with the code for a while, it makes more sense to put all
the parsing in Parser, instead of some of it living in StyleResolver.
That means our current ValueListStyleValue needs to be replaced with
specific StyleValue types for the properties that are shorthands or
otherwise combine several values together.

Here we implement FontStyleProperty, which represents a `font` CSS
property.

Also adjusted the fonts.html test page so that font-weights are featured
in test cases without things we do not yet support.
2021-08-14 12:45:01 +02:00
Sam Atkins
ed962be0fa LibWeb: Make 'auto' be both a Length and Identifier in CSS
I had accidentally parsed it in `parse_builtin_or_dynamic_value()`
instead of `parse_length()` before, which was confusing, so now it's
parsed along with other Lengths.

Whether it should be a Length is up for debate, and has been tripping me
up a few times, but a lot of code expects it to be one. For now, an
'auto' Length value (or any other value which overloads `is_auto()`)
also claims to be a `ValueID::Auto` identifier.
2021-08-14 12:45:01 +02:00
Sam Atkins
c8c2a8df56 LibWeb: Make '0' always be both a number and a length in CSS
A '0' token can be interpreted both as a Number, and as a Length. This
is problematic as in our CSS parser, we often call parse_css_value()
first, to figure out what something is, and then assign it. So we do not
know in advance whether we want a Length or not. Previously, it always
got parsed as a Length, and then every place that expected a
NumericStyleValue had to also check for a Length(0), which is easy to
forget to do.

In particular, this was causing issues with the `flex` property parsing.

To solve this, we now always parse 0 as a NumericStyleValue, and NSVs of
0 pretend to be a Length(0px) when asked. In two places, we were casting
to a LengthStyleValue* based on is_length(), which no longer works, so
those have been adjusted to use `StyleValue::to_length()` instead. They
also now check for `is_numeric()` first, to avoid the extra conversion
to a Length and back.

Possibly this opens up new issues elsewhere. In my testing it seems
fine, but until we can get CSS test suites running, it's hard to know
for certain.
2021-08-14 12:45:01 +02:00
Ali Mohammad Pur
15f95220ae AK+Everywhere: Delete Variant's default constructor
This was exposed to the user by mistake, and even accumulated a bunch of
users that didn't blow up out of sheer luck.
2021-08-13 17:31:39 +04:30
Tobias Christiansen
2a77abf85e Everywhere: Use tobyase@serenityos.org for my copyright headers 2021-08-09 21:43:05 +02:00
Sam Atkins
4065eb169c LibWeb: Implement CSS parsing convenience functions
These mostly match the API in `DeprecatedCSSParser.h`. The exception is
that `parse_selector()` returns a `SelectorList` instead of just one
`Selector`. The only uses of that are in
`ParentNode::query_selector[_all]()` which should be matching against a
list, according to the spec.

`parse_html_length()` is an odd case. It's used for `width="200"` cases
in HTML, so is not really CSS related, but does produce a StyleValue.
The values allowed in `width/height` in HTML vary per element, but they
are a lot more restricted than in CSS, so it's slightly inappropriate to
use the CSS parser for them, even though it's convenient.

We also ignore a few functions:

- `parse_line_width()`
- `parse_line_style()`
- `parse_color()`

These are all only used in `StyleResolver`, when it is given a property
value as a String. That won't happen once the old parser is removed.
2021-08-02 19:01:25 +04:30
Sam Atkins
eadcdd21e3 LibWeb: Clarify naming and publicity of CSS Parser methods
`parse_as_foo()` implies that the Parser's internal data is used,
whereas `parse_a_foo()` implies that the passed-in data is used.

Also, made all the `parse_a_foo()` methods private, as they are only
required within the Parser, and this makes the API clearer to outsiders.

The `parse_a(s)_foo()` naming is a little awkward, but it comes from
section 5.3 of the spec, so seemed worth keeping:
https://www.w3.org/TR/css-syntax-3/#parser-entry-points
2021-08-02 19:01:25 +04:30
Sam Atkins
f4b3ab19c0 LibWeb: Only dump parsed CSS stylesheet if logging is enabled 2021-08-02 19:01:25 +04:30
Sam Atkins
4c4482c7f6 LibWeb: Ignore unquoted data urls in CSS
Previously we were only ignoring quoted ones (eg `url("data:...")`), so
now we ignore unquoted ones (eg `url(data:...)`) too.
2021-07-31 00:18:11 +02:00
Sam Atkins
23d869138f LibWeb: Parse calc() values in new CSS Parser
This is a port of the code from DeprecatedCSSParser, to work with CSS
Tokens and TokenStream. I've modified it as little as possible.
2021-07-31 00:18:11 +02:00
Sam Atkins
21c59efbb9 LibWeb: Treat CSS calc() values as "builtin_or_dynamic" 2021-07-31 00:18:11 +02:00
Sam Atkins
d6668dbc56 LibWeb: Allow peeking more than 1 token ahead in CSS Parser 2021-07-31 00:18:11 +02:00
Sam Atkins
919eb7c0aa LibWeb: Parse box-shadow property in new CSS Parser
Previous multi-value properties use a ValueListStyleValue, which then
gets parsed into its sub-properties in the StyleResolver. However, that
is not ideal, especially as it exposes StyleResolver to the inner
workings of the Parser and Tokenizer, which it should not need to know
about.

The way `box-shadow` was implemented as a StyleValue subclass means that
the parsing can happen inside the Parser instead, which seems like a
better solution. Converting the other complicated cases (background,
font, list-style) is on my todo list for later.
2021-07-31 00:18:11 +02:00
Sam Atkins
697bffa3bd LibWeb: Convert CSS parse_{color,length}() lambdas into methods
This lets us get the Length and Color values directly, without having to
create a StyleValue object and then throw it away again, when parsing
the box-shadow property in the next commit.
2021-07-31 00:18:11 +02:00
Sam Atkins
1b72766e4e LibWeb: Fix issues with CSS attribute selector handling
This is three small, related changes:

1. Element::has_attribute() now returns true if the attribute exists but
has no value. (eg, `<div foo />` -> `has_attribute("foo")`)

2. SelectorEngine::matches_attribute() now makes sure there is a first
segment before comparing it, fixing a crash.

3. CSS::Parser now converts attribute names in attribute selectors to
lowercase, to match the expectations of the rest of the system.
Converting to lowercase is not always correct, depending on language,
but since we only currently support HTML, and that expects them to be
case-insensitive, it is fine for now.
2021-07-31 00:18:11 +02:00
Sam Atkins
6034fc0ee6 LibWeb: Make CSS 'An+B' parsing spec-compliant
Parsing this pattern from CSS tokens turns out to be slightly crazy, but
thankfully well documented in the spec.

The spec lists the cases in order of simple -> complicated, but this
would cause problems in code, since `<n-dimension> <signed-.integer>`
would never by reached, as `<n-dimension>` comes before. Instead, I
have grouped them by their first token.

Also renamed the NthChildPattern class to ANPlusBPattern, to match spec
terminology.
2021-07-31 00:18:11 +02:00
Sam Atkins
8d0ff98eff LibWeb: Parse CSS selectors according to the spec
The spec does not directly tell us how to parse selectors, so there are
likely some bugs here, but I've used the spec language where possible.
This is very much based on the previous selector parsing code.

Any parse error inside a selector makes the entire SelectorList
invalid, so nothing is returned.
2021-07-31 00:18:11 +02:00
Sam Atkins
6ea5d03f43 LibWeb: Bring Selector terminology in line with the CSS spec
- CompoundSelector -> *deleted*
- ComplexSelector -> CompoundSelector
- Relation -> Combinator

Our Selector is really a ComplexSelector, but only the Parser and
SelectorEngine need to know that, so keeping it named Selector makes it
more understandable for users.

Our CompoundSelector is really a CompoundSelectorAndCombinator.
Combining the two makes sense in our codebase, but the accurate name is
so long that I think it makes the code less readable.

Renamed some Combinators to also match the spec terminology:

- AdjacentSibling -> NextSibling
- GeneralSibling -> SubsequentSibling

The previous names are somewhat ambiguous, so hopefully this is clearer.
2021-07-31 00:18:11 +02:00
Sam Atkins
ca436afeb5 LibWeb: Stop parsing integer CSS values as Lengths
This was a hack copied over from the old parser, but it was causing
problems with flex-grow, and probably other properties that accept
numbers. Removing it does not seem to break anything, so lets' remove
it! :^)
2021-07-31 00:18:11 +02:00
Sam Atkins
e54531244f LibWeb: Define proper debug symbols for CSS Parser and Tokenizer
You can now turn debug logging for them on using `CSS_PARSER_DEBUG` and
`CSS_TOKENIZER_DEBUG`.
2021-07-31 00:18:11 +02:00
Sam Atkins
af045cee22 LibWeb: Use references to CSS tokens instead of copying by value
A couple of places required a logic change to make this work, but mostly
it's a simple case of adding &.
2021-07-31 00:18:11 +02:00
Sam Atkins
7439fbd896 LibWeb: Get CSS @import rules working in new parser
Also added css-import.html, which tests the 3 syntax variations on
`@import` statements. Note that the optional media-query parameter to
`@import` is not handled yet.
2021-07-31 00:18:11 +02:00
stelar7
8264511d32 LibWeb: Dont try to parse "data" urls as links 2021-07-23 14:18:17 +02:00
Sam Atkins
6e08b200d4 LibWeb: Implement ImageStyleValue parsing
Later we will want to make a distinction between URL and Image values,
but this works for now.
2021-07-22 23:09:01 +02:00
Sam Atkins
a44d7670ab LibWeb: Resolve CSS list-style from value list
This resolves the three sub-properties, appearing in any order:

- list-style-image
- list-style-position
- list-style-type

Added `list-style-position` values to support this, though they are not
yet used in rendering.
2021-07-22 23:09:01 +02:00
Sam Atkins
7abfb18656 LibWeb: Implement CSS color parsing from Tokens
This was broken when we switched away from using StringStyleValues.
While I was at it, I have implemented hsl/a() and the percentage
syntax for rgb/a().

As a bonus, added `colors.html` as a test page for the various CSS
color syntaxes, since nothing was testing rgb() or rgba() before.

Much of the parsing code in LibGFX/Color.h seems to be centered
around CSS color values, but this is not used by the new Parser.
(And can't be used, because it requires a String value and we have
a list of Tokens of some kind instead.) Maybe that should be removed
from there when the new CSS parser is operational.
2021-07-22 23:09:01 +02:00
Sam Atkins
6e0376361a LibWeb: Expose StyleValue parsing method in CSS Parser
Now that StyleResolver is going to deal with StyleComponentValueRules,
it will need to be able to parse those into StyleValues, using
`parse_css_value()`.

Also added StyleValue::is_builtin_or_dynamic(), which returns true for
values that are valid anywhere - things like `initial` and `inherit`,
along with `var()`, `attr()` and `calc()` - which we want to test for
easily.
2021-07-22 23:09:01 +02:00
Sam Atkins
d72ce7b989 LibWeb: Generate a ValueListStyleValue when parsing CSS values
We skip whitespace tokens while doing this. As far as I can tell,
whitespace is not useful once we get to this point, and it legally
may or may not appear between any two tokens. By not including it
in the ValueListStyleValue, we make the "if it has 3 parts"-type
checks a lot more straightforward.
2021-07-22 23:09:01 +02:00
Sam Atkins
ffc81cbfad LibWeb: Use Selectors instead of a String for :not() selectors
Rather than parsing the selector every time we want to check it, we
now parse it once at the beginning.

A bonus effect of this is that we now support a selector list in
:not(), instead of just a single selector, though only when using
the new parser.
2021-07-14 13:31:00 +02:00
Sam Atkins
776b1f4548 LibWeb: Make CSS::Selector reference counted
The end goal is to make the PseudoClass::not_selector be a Selector
instead of a String that is repeatedly re-parsed. But since Selector
contains a Vector of ComplexSelectors, which each have a Vector of
SimpleSelectors, it's probably a good idea to not be passing them
around by value anyway. :^)
2021-07-14 13:31:00 +02:00
Sam Atkins
8cae79cc8d LibWeb: Add 'PseudoElement' as a CSS SimpleSelector::Type
Same reasoning again! This is the last one.

While I was at it, I added the two remaining CSS2.2 pseudo-elements,
::first-line and ::first-letter. All 4 are handled in the new CSS
parser, including with the compatibility single-colon syntax. I have
not added support to the old parser.
2021-07-14 13:31:00 +02:00
Sam Atkins
4af7d41879 LibWeb: Add 'PseudoClass' as a CSS SimpleSelector::Type
Same reasoning as the previous commit.
2021-07-14 13:31:00 +02:00
Sam Atkins
96b2356cbb LibWeb: Add 'Attribute' as a CSS SimpleSelector::Type
Previously, SimpleSelectors optionally had Attribute-selector data
as well as their main type. Now, they're either one or the other,
which better matches the spec, and makes parsing and matching more
straightforward.
2021-07-14 13:31:00 +02:00
Sam Atkins
86994336a7 LibWeb: Correct parsing invalid list of declarations
We were only discarding at most one token when a declaration is
invalid, when we should discard all until we see a ; or EOF.
2021-07-11 23:19:56 +02:00
Sam Atkins
e381ca258f LibWeb: Add more logging to CSS parser 2021-07-11 23:19:56 +02:00
Sam Atkins
9cfbc07c24 LibWeb: Implement CSS::Parse::parse_nth_child_pattern()
This is a modified copy of the code from Selector.cpp, to work on a
TokenStream instead of a String.
2021-07-11 23:19:56 +02:00
Sam Atkins
cf333574ac LibWeb: Convert StyleFunctionRule.m_values to ComponentValues
The input is ComponentValues, and the output is too, so storing as
a String in the middle was inefficient and unnecessary.
2021-07-11 23:19:56 +02:00
Sam Atkins
fabc09a593 LibWeb: Increase clarity with CSS token debug logging
Had to adjust some places that were using Token.to_string() for
non-debug-logging purposes. Changed its name to to_debug_string()
to make the usage clearer.
2021-07-11 23:19:56 +02:00
Sam Atkins
e5ac5e1fab LibWeb: Fix CSS attribute and ID selector parsing
There were several crashes here from out-of-bounds memory access.
2021-07-11 23:19:56 +02:00
Sam Atkins
78d191554a LibWeb: Remove non-compliant whitespace stripping in CSS Parser 2021-07-11 23:19:56 +02:00
Sam Atkins
7e4f75c78c LibWeb: Fix whitespace handling in CSS selectors
Whitespace marks the end of a compound-selector, no matter where
it occurs. `check_for_eof_or_whitespace()` reconsumes the whitespace
token for convenience.
2021-07-11 23:19:56 +02:00
Sam Atkins
57f6d86996 LibWeb: Implement remaining CSS parse_as...() entry points 2021-07-11 23:19:56 +02:00
Sam Atkins
65fe3895e6 LibWeb: Enabling @import in new CSS parser 2021-07-11 23:19:56 +02:00