Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export CSS properties and values into reffy-reports #113

Closed
foolip opened this issue Aug 8, 2018 · 7 comments
Closed

Export CSS properties and values into reffy-reports #113

foolip opened this issue Aug 8, 2018 · 7 comments

Comments

@foolip
Copy link
Member

foolip commented Aug 8, 2018

https://github.com/web-platform-tests/wpt/projects/1 is progressing nicely and has been helped immensely be reffy-reports providing daily updates of IDLs from specs.

Having a machine-readable list of all CSS properties and values would facilitate creating something similar for CSS, tracking by web-platform-tests/wpt#9113.

@tidoust
Copy link
Member

tidoust commented Aug 8, 2018

@dontcallmedom and I added support for the extraction of CSS property definitions in Reffy a few weeks ago. I had not noticed the discussion on a possible cssharness.js but that's precisely one of the possible usages that we were wondering about.

Reffy now has a CSS grammar parser. Now, while it's easy to extract all properties, some value definitions cannot be parsed. See #110 for a list of issues we bumped into, and w3c/csswg-drafts#2921 where we wondered about possible improvements to the Value Syntax Definition.

The result of the parsing appears in the crawl.json file that Reffy generates. The tool now also generates a css folder similar to the idl folder, with .cvds text files (the extension is meant to mean "CSS Value Definition Syntax") that contain the definitions extracted from each spec. For instance, for CSS Display Module Level 3, Reffy creates a css-display.cvds file that contains:

display = [ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy>

<display-outside> = block | inline | run-in ;

<display-inside> = flow | flow-root | table | flex | grid | ruby ;

<display-listitem> = <display-outside>? && [ flow | flow-root ]? && list-item ;

<display-internal> = table-row-group | table-header-group | table-footer-group | table-row | table-cell | table-column-group | table-column | table-caption | ruby-base | ruby-text | ruby-base-container | ruby-text-container ;

<display-box> = contents | none ;

<display-legacy> = inline-block | inline-table | inline-flex | inline-grid ;

The content is mostly a direct copy-and-paste of how things are defined in CSS specs, with a couple of conventions of our own (notably the |= operator to mean "New values"). That format could be changed entirely, e.g. in favor of a JSON-based format if that seems preferrable. It could also include other information in property tables (such as the "Initial value", the "Applies to") if needed.

We did not add the css folder to reffy-reports at this point because that seemed a bit premature:

  1. We did not know whether anyone would be interested. I guess this issue shows someone is :)
  2. We did not know exactly how to write that machine-readable dump.
  3. The extraction is not perfect. The list of property definitions extracted by Reffy should be complete, but it also extracts "@rules" definitions from time to time, which seem to follow a slightly different syntax. There's still some work to do in that area.
  4. There remain a few hiccups, typically with levels: Reffy only creates one file for the latest level of a given spec, e.g. css-grid.cvds, but then the CSS Grid Level 2 ED notes in its intro that properties defined in level 1 have not yet been incorporated in the draft, so they don't show up. Not sure whether we should ignore Level 2 for now, create one file per level, or something else.

In short, yes, we can easily add a css folder with a machine-readable dump of CSS property definitions. If you already have a clear set of requirements for that dump, I'm happy to generate the right dump. If not, we could start with what Reffy already generates and improve gradually.

@foolip
Copy link
Member Author

foolip commented Aug 9, 2018

That's great, thanks @tidoust! Is there something we could use to parse those .cvds files, can https://github.com/tidoust/reffy/blob/master/src/lib/css-grammar-parser.js do it?

@tidoust
Copy link
Member

tidoust commented Aug 9, 2018

The CSS grammar parser can parse the right-hand side of equations in these files. But rather than extending it to support complete parsing of that file, I'm wondering if we shouldn't rather dump a JSON structure similar to the one created during the crawl.

The textual dump was an attempt to create an IDL-like format that could then get used in CSS specs, but I'm not clear that's a good goal at all:

  • Reffy extracts properties, descriptors and "value spaces" definitions from CSS specs. Properties and descriptors typically need to be kept separated because, for instance, CSS Fonts defines a font-family property and a font-family descriptor. The .cvds files currently fail to keep that separation, meaning it looks like font-family is defined twice.
  • Also, I suspect some other parameters might prove useful for automated tests, for instance the "Initial" value of a property, or whether the property is "Inherited" or "Animatable".

The crawler creates the following structure (here for CSS Animations):

{
  "properties": {
    "animation-composition": {
      "Name": "animation-composition",
      "Value": "<single-animation-composition>#",
      "Initial": "replace",
      "Applies to": "all elements, ::before and ::after pseudo-elements",
      "Inherited": "none",
      "Percentages": "N/A",
      "Computed value": "As specified",
      "Canonical order": "per grammar",
      "Animatable": "no"
    }
  },
  "descriptors": {},
  "valuespaces": {
    "<single-animation-composition>": {
      "Value": "replace | add | accumulate"
    }
  }
}

I propose to dump that structure to a JSON file instead of creating .cvds files. That structure should have all the information that a cssharness.js could need.

The CSS grammar parser can be applied to Value fields in that structure to create a parsed value, as done in the crawler.

The result of parsing the animation-composition property is:

{
  "type": "array",
  "items": {
    "type": "valuespace",
    "name": "single-animation-composition"
  },
  "separator": ","
}

See css-grammar-parse-tree.schema.json for the definition of the schema followed by the CSS grammar parser.

What about it?

@foolip
Copy link
Member Author

foolip commented Aug 9, 2018

I think the most basic test we could generate is one that simply checks for property support using 'thing' in getComputedStyle(document.body).

Second easiest would be to test using CSS.supports('property: value'). The challenge there, I think, would be to derive one or more permitted values for each property from the syntax. It's easy to do with keywords, so perhaps start there, or simply with CSS.supports('display:initial').

To test the initial values sounds tricky because they'd be affected by UA style sheets.

tidoust added a commit that referenced this issue Aug 12, 2018
Following discussions in #113, this update dumps the extracted CSS definitions
as JSON files (as opposed to `.cvds` files) in the `css` folder. The JSON file
is a JSON object with `properties`, `descriptors` and `valuespaces` properties
that list the definitions extracted. A typical example:

```json
{
  "properties": {
    "animation-timeline": {
      "name": "animation-timeline",
      "value": "<single-animation-timeline>#",
      "initial": "auto",
      "appliesTo": "all elements, ::before and ::after pseudo-elements",
      "inherited": "none",
      "percentages": "N/A",
      "media": "interactive",
      "computedValue": "As specified",
      "canonicalOrder": "per grammar",
      "animatable": "no"
    }
  },
  "descriptors": {},
  "valuespaces": {
    "<single-animation-timeline>": {
      "value": "auto | scroll([element(<id-selector>)[, <scroll-direction>[, <scroll-offset>[, <scroll-offset>[, <time>[, <single-animation-fill-mode>]]]]]])"
    },
    "<scroll-direction>": {
      "value": "auto | block | inline | horizontal | vertical"
    },
    "<scroll-offset>": {
      "value": "<length> | <percentage> | auto"
    }
  }
}
```

The update also makes sure that all properties extracted from CSS specs use a
lower camel case convention.

When multiple levels of a spec exists, only the contents of the latest level
are dumped for now. There was a bug in the code that made it miss some cases
(where the URL of the different levels did not follow the same pattern) and
that could create file writing conflicts. This should now have been fixed.

Also, the logic that creates CSS and IDL dumps has been separated to dump the
latest level that actually has some related definitions (for instance CSS
Animations Level 2 is currently a delta spec and does not define any IDL,
whereas the first level does). Whether we'll want to keep that behavior later
on for such delta specs is an open question.
tidoust added a commit that referenced this issue Aug 13, 2018
Following discussions in #113, this update dumps the extracted CSS definitions
as JSON files (as opposed to `.cvds` files) in the `css` folder. The JSON file
is a JSON object with `properties`, `descriptors` and `valuespaces` properties
that list the definitions extracted. A typical example:

```json
{
  "properties": {
    "animation-timeline": {
      "name": "animation-timeline",
      "value": "<single-animation-timeline>#",
      "initial": "auto",
      "appliesTo": "all elements, ::before and ::after pseudo-elements",
      "inherited": "none",
      "percentages": "N/A",
      "media": "interactive",
      "computedValue": "As specified",
      "canonicalOrder": "per grammar",
      "animatable": "no"
    }
  },
  "descriptors": {},
  "valuespaces": {
    "<single-animation-timeline>": {
      "value": "auto | scroll([element(<id-selector>)[, <scroll-direction>[, <scroll-offset>[, <scroll-offset>[, <time>[, <single-animation-fill-mode>]]]]]])"
    },
    "<scroll-direction>": {
      "value": "auto | block | inline | horizontal | vertical"
    },
    "<scroll-offset>": {
      "value": "<length> | <percentage> | auto"
    }
  }
}
```

The update also makes sure that all properties extracted from CSS specs use a
lower camel case convention.

When multiple levels of a spec exists, only the contents of the latest level
are dumped for now. There was a bug in the code that made it miss some cases
(where the URL of the different levels did not follow the same pattern) and
that could create file writing conflicts. This should now have been fixed.

Also, the logic that creates CSS and IDL dumps has been separated to dump the
latest level that actually has some related definitions (for instance CSS
Animations Level 2 is currently a delta spec and does not define any IDL,
whereas the first level does). Whether we'll want to keep that behavior later
on for such delta specs is an open question.
tidoust added a commit to w3c/webref that referenced this issue Aug 13, 2018
See discussion in w3c/reffy#113

The dumps follow a simple JSON structure that separates definitions of
properties, descriptors and valuespaces. That structure may evolve and
completely change over time, depending on needs.
@tidoust
Copy link
Member

tidoust commented Aug 13, 2018

@foolip Reffy now generates JSON dumps of CSS definitions, and these dumps have been added to reffy-reports:
https://github.com/tidoust/reffy-reports/tree/master/whatwg/css

As mentioned above, Reffy's CSS grammar parser can be used to parse the value fields in these files, as done in the crawler to produce a parsed structure (or a parse error). There are a number of parse errors for now, notably due to the use of curly quotes in CSS specs (whereas the parser only supports ').

The format followed by these files is entirely open to change. We don't use these files for anything for the time being and don't have any immediate plan either.

Also note the problem with "delta" specs (#117): the dumps only contain the definitions of the latest level of a given spec for now, and thus only contain the delta.

@dontcallmedom
Copy link
Member

@tidoust any reason not to close this issue?

@tidoust
Copy link
Member

tidoust commented Jun 23, 2020

Nope, no one has complained about the format, so let's assume it's good enough...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants