# CSS Generated Files

We generate a significant amount of CSS-related code, taking in one or more .json files in
[`Libraries/LibWeb/CSS`](../Libraries/LibWeb/CSS) and producing C++ code from them, located in
`Build/<build-preset>/Lagom/Libraries/LibWeb/CSS/`.
It's likely that you'll need to work with these if you add or modify a CSS property or its values.

The generators are found in [`Meta/Lagom/Tools/CodeGenerators/LibWeb`](../Meta/Lagom/Tools/CodeGenerators/LibWeb).
They are run automatically as part of the build, and most of the time you can ignore them.

## Properties.json

Each CSS property has an entry here, which describes what values it accepts, whether it's inherited, and similar data.
This generates `PropertyID.h`, `PropertyID.cpp`, `GeneratedCSSStyleProperties.h`, `GeneratedCSSStyleProperties.cpp` and `GeneratedCSSStyleProperties.idl`.
Most of this data is found in the information box for that property in the relevant CSS spec.

The file is organized as a single JSON object, with keys being property names, and the values being the data for that property.
Each property will have some set of these fields on it:

(Note that required fields are not required on properties with `legacy-alias-for` or `logical-alias-for` set.)

| Field                      | Required | Default | Description                                                                                                                               | Generated functions                                                         |
|----------------------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------|
| `affects-layout`           | No       | `true`  | Boolean. Whether changing this property will invalidate the element's layout.                                                             | `bool property_affects_layout(PropertyID)`                                  |
| `affects-stacking-context` | No       | `false` | Boolean. Whether this property can cause a new stacking context for the element.                                                          | `bool property_affects_stacking_context(PropertyID)`                        |
| `animation-type`           | Yes      |         | String. How the property should be animated. Defined by the spec. See below.                                                              | `AnimationType animation_type_from_longhand_property(PropertyID)`           |
| `inherited`                | Yes      |         | Boolean. Whether the property is inherited by its child elements.                                                                         | `bool is_inherited_property(PropertyID)`                                    |
| `initial`                  | Yes      |         | String. The property's initial value if it is not specified.                                                                              | `NonnullRefPtr<CSSStyleValue> property_initial_value(PropertyID)`           |
| `legacy-alias-for`         | No       | Nothing | String. The name of a property this is an alias for. See below.                                                                           |                                                                             |
| `logical-alias-for`        | No       | Nothing | Array of strings. The name of a property this is an alias for. See below.                                                                 |                                                                             |
| `longhands`                | No       | `[]`    | Array of strings. If this is a shorthand, these are the property names that it expands out into.                                          | `Vector<PropertyID> longhands_for_shorthand(PropertyID)`                    |
| `max-values`               | No       | `1`     | Integer. How many values can be parsed for this property. eg, `margin` can have up to 4 values.                                           | `size_t property_maximum_value_count(PropertyID)`                           |
| `percentages-resolve-to`   | No       | Nothing | String. What type percentages get resolved to. eg, for `width` percentages are resolved to `length` values.                               | `Optional<ValueType> property_resolves_percentages_relative_to(PropertyID)` |
| `quirks`                   | No       | `[]`    | Array of strings. Some properties have special behavior in "quirks mode", which are listed here. See below.                               | `bool property_has_quirk(PropertyID, Quirk)`                                |
| `valid-identifiers`        | No       | `[]`    | Array of strings. Which keywords the property accepts. Consider defining an enum instead and putting its name in the `valid-types` array. | `bool property_accepts_keyword(PropertyID, Keyword)`                        |
| `valid-types`              | No       | `[]`    | Array of strings. Which value types the property accepts. See below.                                                                      | `bool property_accepts_type(PropertyID, ValueType)`                         |

### `animation-type`

The [Web Animations spec](https://www.w3.org/TR/web-animations/#animation-type) defines the valid values here:

| Spec term         | JSON value          |
|-------------------|---------------------|
| not animatable    | `none`              |
| discrete          | `discrete`          |
| by computed value | `by-computed-value` |
| repeatable list   | `repeatable-list`   |
| (See prose)       | `custom`            |

### `legacy-alias-for` and `logical-alias-for`

These are two separate concepts, with unfortunately similar names:
- [Legacy name aliases](https://drafts.csswg.org/css-cascade-5/#legacy-name-alias) are properties whose spec names have changed,
  but the syntax has not, so setting the old one is defined as setting the new one directly.
  For example, `font-stretch` was renamed to `font-width`, so `font-stretch` is now a legacy name alias for `font-width`.
- Logical aliases are properties like `margin-block-start`, which may assign a value to one of several other properties
  (`margin-top`, `margin-bottom`, `margin-left`, or `margin-right`) depending on the element they are applied to.
  List all the properties that they can alias.

### `quirks`

The [Quirks spec](https://quirks.spec.whatwg.org/#css) defines these.

| Spec term                    | JSON value           |
|------------------------------|----------------------|
| The hashless hex color quirk | `hashless-hex-color` |
| The unitless length quirk    | `unitless-length`    |

### `valid-types`

The `valid-types` array lists the names of CSS value types, as defined in the latest
[CSS Values and Units spec](https://www.w3.org/TR/css-values/), without the `<>` around them.
For numeric types, we use the [bracketed range notation](https://www.w3.org/TR/css-values-4/#css-bracketed-range-notation),
for example `width` can take any non-negative length, so it has `"length [0,∞]"` in its `valid-types` array.

## Keywords.json

This is a single JSON array of strings, each of which is a CSS keyword, for example `auto`, `none`, `medium`, or `currentcolor`.
This generates `Keyword.h` and `Keyword.cpp`.
All keyword values used by any property or media-feature need to be defined here.

The generated code provides:
- A `Keyword` enum as used by `CSSKeywordValue`
- `Optional<Keyword> keyword_from_string(StringView)` to attempt to convert a string into a Keyword
- `StringView string_from_keyword(Keyword)` to convert a Keyword back into a string
- `bool is_css_wide_keyword(StringView)` which returns whether the string is one of the special "CSS-wide keywords"

## Enums.json

This is a single JSON object, with enum names as keys and the values being arrays of keyword names.
This generates `Enums.h` and `Enums.cpp`.

We often want to define an enum that's a set of a few keywords.
`Enums.json` allows you to generate these enums automatically, along with functions to convert them to and from a Keyword,
or convert them to a string.
These enums also can be used in property definitions in `Properties.json` by putting their name in the `valid-types` array.
This helps reduce repetition, for example the `border-*-style` properties all accept the same set of keywords, so they
are implemented as a `line-style` enum.

The generated code provides these for each enum, using "foo" as an example:
- A `Foo` enum for its values
- `Optional<Foo> keyword_to_foo(Keyword)` to convert a `Keyword` to a `Foo`
- `Keyword to_keyword(Foo)` to convert the `Foo` back to a `Keyword`
- `StringView to_string(Foo)` to convert the `Foo` directly to a string

## PseudoClasses.json

This is a single JSON object, with selector pseudo-class names as keys and the values being objects with fields for the pseudo-class.
This generates `PseudoClass.h` and `PseudoClass.cpp`.

Each entry has a single required property, `argument`, which is a string containing the grammar for the pseudo-class's
function parameters - for identifier-style pseudo-classes it is left blank.
The grammar is taken directly from the spec.

The generated code provides:
- A `PseudoClass` enum listing every pseudo-class name
- `Optional<PseudoClass> pseudo_class_from_string(StringView)` to parse a string as a `PseudoClass` name
- `StringView pseudo_class_name(PseudoClass)` to convert a `PseudoClass` back into a string
- The `PseudoClassMetadata` struct which holds a representation of the data from the JSON file
- `PseudoClassMetadata pseudo_class_metadata(PseudoClass)` to retrieve that data

## MediaFeatures.json

This is a single JSON object, with media-feature names as keys and the values being objects with fields for the media-feature.
This generates `MediaFeatureID.h` and `MediaFeatureID.cpp`.

A `<media-feature>` is a value that a media query can inspect.
They are listed in the [`@media` descriptor table](https://www.w3.org/TR/mediaqueries-5/#media-descriptor-table) in the latest Media Queries spec.

The definitions here are like a simplified version of the `Properties.json` definitions.

| Field    | Description                                                                                                                                                                                       |
|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `type`   | String. How the media-feature is evaluated, either `discrete` or `range`.                                                                                                                         |
| `values` | Array of strings. These are directly taken from the spec, with keywords as they are, and `<>` around type names. Types may be `<boolean>`, `<integer>`, `<length>`, `<ratio>`, or `<resolution>`. |

The generated code provides:
- A `MediaFeatureValueType` enum listing the possible value types
- A `MediaFeatureID` enum, listing each media-feature
- `Optional<MediaFeatureID> media_feature_id_from_string(StringView)` to convert a string to a `MediaFeatureID`
- `StringView string_from_media_feature_id(MediaFeatureID)` to convert a `MediaFeatureID` back to a string
- `bool media_feature_type_is_range(MediaFeatureID)` returns whether the media feature is a `range` type, as opposed to a `discrete` type
- `bool media_feature_accepts_type(MediaFeatureID, MediaFeatureValueType)` returns whether the media feature will accept values of this type
- `bool media_feature_accepts_keyword(MediaFeatureID, Keyword)` returns whether the media feature accepts this keyword

## MathFunctions.json

This is a single JSON object, describing each [CSS math function](https://www.w3.org/TR/css-values/#math-function),
with the keys being the function name and the values being objects describing that function's properties.
This generates `MathFunctions.h` and `MathFunctions.cpp`.

Each entry has two properties:

| Field                  | Description                                                                                                                                                                                                            |
|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `parameter-validation` | Optional string. Either "same" or "consistent", depending on whether the spec says the input calculations should be the same type or consistent types. Defaults to "same". Ignore this if there is only one parameter. |
| `parameters`           | An array of parameter definition objects, see below.                                                                                                                                                                   |

Parameter definitions have the following properties:

| Field      | Description                                                                      |
|------------|----------------------------------------------------------------------------------|
| `name`     | String. Name of the parameter, as given in the spec.                             |
| `type`     | String. Accepted types for the parameter, as a single string, separated by `\|`. |
| `required` | Boolean. Whether this parameter is required.                                     |

The generated code provides:
- A `MathFunction` enum listing the math functions
- The implementation of the CSS Parser's `parse_math_function()` method

## TransformFunctions.json

This is a single JSON object, describing each [CSS transform function](https://www.w3.org/TR/css-transforms/#transform-functions),
with the keys being the function name and the values being objects describing that function's properties.
This generates `TransformFunctions.h` and `TransformFunctions.cpp`.

Each entry currently has a single property, `parameters`, which is an array of parameter definition objects.
Parameter definitions have the following properties:

| Field      | Description                                  |
|------------|----------------------------------------------|
| `type`     | String. Accepted type for the parameter.     |
| `required` | Boolean. Whether this parameter is required. |

The generated code provides:
- A `TransformFunction` enum listing the transform functions
- `Optional<TransformFunction> transform_function_from_string(StringView)` to parse a string as a `TransformFunction`
- `StringView to_string(TransformFunction)` to convert a `TransformFunction` back to a string
- `TransformFunctionMetadata transform_function_metadata(TransformFunction)` to obtain metadata about the transform function, such as its parameter list
