We generate a significant amount of CSS-related code, taking in one or more .json files in
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
.
They are run automatically as part of the build, and most of the time you can ignore them.
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) |
The Web Animations spec 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 |
These are two separate concepts, with unfortunately similar names:
font-stretch
was renamed to font-width
, so font-stretch
is now a legacy name alias for font-width
.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.The Quirks spec defines these.
Spec term | JSON value |
---|---|
The hashless hex color quirk | hashless-hex-color |
The unitless length quirk | unitless-length |
The valid-types
array lists the names of CSS value types, as defined in the latest
CSS Values and Units spec, without the <>
around them.
For numeric types, we use the bracketed range notation,
for example width
can take any non-negative length, so it has "length [0,∞]"
in its valid-types
array.
For <custom-ident>
s, the excluded identifiers are placed within ![]
, for example "custom-ident ![all,none]"
.
Descriptors are basically properties, but for at-rules instead of style. The overall structure is a JSON object, with keys being at-rule names and the values being data about those at-rules. The main part is the data about the descriptors that the at-rule can have.
The generated code provides:
AtRuleID
enum, mostly used as a parameter for parsing descriptors, as multiple at-rules may have descriptors with
the same name.FlyString to_string(AtRuleID)
, mostly for debug logging.DescriptorID
enum, listing every descriptor.Optional<DescriptorID> descriptor_id_from_string(AtRuleID, StringView)
for getting a DescriptorID from a string, if
it exists in that at-rule.FlyString to_string(DescriptorID)
for serializing descriptor names.bool at_rule_supports_descriptor(AtRuleID, DescriptorID)
to query if the given at-rule allows the descriptor.RefPtr<CSSStyleValue> descriptor_initial_value(AtRuleID, DescriptorID)
for getting a descriptor's initial value.DescriptorMetadata get_descriptor_metadata(AtRuleID, DescriptorID)
returns data used for parsing the descriptor.Each at-rule object has the following fields. Both are required.
Field | Description |
---|---|
spec |
String. URL to the spec that defines this at-rule. |
descriptors |
Object, with keys being descriptor names and values being objects of their properties. See below. |
Each descriptor object can have the following fields:
Field | Required | Description |
---|---|---|
initial |
No | String. The descriptor's initial value if none is provided. |
legacy-alias-for |
No | String. The name of a different descriptor that this is an alias for. |
syntax |
Yes | Array of strings. Each string is one option, taken from the spec. |
FIXME or NOTE |
No | Strings, for when you want to leave a note. |
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:
Keyword
enum as used by CSSKeywordValue
Optional<Keyword> keyword_from_string(StringView)
to attempt to convert a string into a KeywordStringView string_from_keyword(Keyword)
to convert a Keyword back into a stringbool is_css_wide_keyword(StringView)
which returns whether the string is one of the special "CSS-wide keywords"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:
Foo
enum for its valuesOptional<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 stringThis 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:
PseudoClass
enum listing every pseudo-class nameOptional<PseudoClass> pseudo_class_from_string(StringView)
to parse a string as a PseudoClass
nameStringView pseudo_class_name(PseudoClass)
to convert a PseudoClass
back into a stringPseudoClassMetadata
struct which holds a representation of the data from the JSON filePseudoClassMetadata pseudo_class_metadata(PseudoClass)
to retrieve that dataThis is a single JSON object, with pseudo-element names as keys and the values being objects with fields for the pseudo-element.
This generated PsuedoElement.h
and PseudoElement.cpp
.
Each entry has the following properties:
Field | Required | Default | Description |
---|---|---|---|
alias-for |
No | Nothing | Use to specify that this should be treated as an alias for the named pseudo-element. |
function-syntax |
No | Nothing | Syntax for the function arguments if this is a function-type pseudo-element. Copied directly from the spec. |
is-generated |
No | false |
Whether this is a generated pseudo-element. |
is-allowed-in-has |
No | false |
Whether this is a :has -allowed pseudo-element. |
property-whitelist |
No | Nothing | Some pseudo-elements only permit certain properties. If so, name them in an array here. Some special values are allowed here for categories of properties - see below. |
spec |
No | Nothing | Link to the spec definition, for reference. Not used in generated code. |
type |
No | "identifier" |
What type of pseudo-element is this. Either "identifier", "function", or "both". |
The generated code provides:
PseudoElement
enum listing every pseudo-element nameOptional<PseudoElement> pseudo_element_from_string(StringView)
to parse a string as a PseudoElement
nameOptional<PseudoElement> aliased_pseudo_element_from_string(StringView)
is similar, but returns the PseudoElement
this name is an alias forStringView pseudo_element_name(PseudoElement)
to convert a PseudoElement
back into a stringbool is_has_allowed_pseudo_element(PseudoElement)
returns whether the pseudo-element is valid inside :has()
bool pseudo_element_supports_property(PseudoElement, PropertyID)
returns whether the property can be applied to this pseudo-elementGeneratedPseudoElement
enum listing only the pseudo-elements that are generated contentOptional<GeneratedPseudoElement> to_generated_pseudo_element(PseudoElement)
for converting from PseudoElement
to GeneratedPseudoElement
. Returns nothing if it's not a generated pseudo-elementPseudoElement to_pseudo_element(GeneratedPseudoElement)
does the opposite conversionThis is an array of strings. Properties can be named directly ("color"), or categories of properties with a leading #
("#font-properties"), as the specs often says a group is allowed instead of listing the properties exactly.
Any properties we don't support yet can be prefixed with "FIXME:" and will be ignored.
The following categories are supported:
#background-properties
: background
and its longhands#border-properties
: border
, border-radius
, and their longhands#custom-properties
: Custom properties, AKA CSS variables#font-properties
: font
, its longhands, and other font-*
properties#inline-layout-properties
: Properties defined in CSS Inline#inline-typesetting-properties
: Properties defined in CSS Text#margin-properties
: margin
and its longhands#padding-properties
: padding
and its longhands#text-decoration-properties
: text-decoration
and its longhandsThis 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 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:
MediaFeatureValueType
enum listing the possible value typesMediaFeatureID
enum, listing each media-featureOptional<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 stringbool media_feature_type_is_range(MediaFeatureID)
returns whether the media feature is a range
type, as opposed to a discrete
typebool media_feature_accepts_type(MediaFeatureID, MediaFeatureValueType)
returns whether the media feature will accept values of this typebool media_feature_accepts_keyword(MediaFeatureID, Keyword)
returns whether the media feature accepts this keywordThis is a single JSON object, describing each CSS 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:
MathFunction
enum listing the math functionsparse_math_function()
methodThis is a single JSON object, describing each CSS transform function,
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:
TransformFunction
enum listing the transform functionsOptional<TransformFunction> transform_function_from_string(StringView)
to parse a string as a TransformFunction
StringView to_string(TransformFunction)
to convert a TransformFunction
back to a stringTransformFunctionMetadata transform_function_metadata(TransformFunction)
to obtain metadata about the transform function, such as its parameter list