11import fs from "node:fs" ;
22import path from "node:path" ;
33import css from "@webref/css" ;
4+ import { definitionSyntax } from "css-tree" ;
45
5- const { properties } = await css . listAll ( ) ;
6- const definitions = properties . map ( ( definition ) => [ definition . name , definition ] ) ;
6+ const caseSensitiveTypes = [ "custom-ident" , "dashed-ident" , "string" ] ;
7+ const typeList = new Set ( [ ...caseSensitiveTypes ] ) ;
8+
9+ const { properties, types } = await css . listAll ( ) ;
10+ const syntaxes = new Map ( [ ...types . map ( ( definition ) => [ `<${ definition . name } >` , definition ] ) ] ) ;
11+ const definitions = properties . map ( prepareDefinition ) ;
712
813const [ dateTodayFormatted ] = new Date ( ) . toISOString ( ) . split ( "T" ) ;
914const output = `"use strict";
@@ -14,3 +19,67 @@ module.exports = new Map(${JSON.stringify(definitions, null, 2)});
1419
1520const { dirname } = import . meta;
1621fs . writeFileSync ( path . resolve ( dirname , "../lib/generated/propertyDefinitions.js" ) , output ) ;
22+
23+ /**
24+ * Transforms the raw property definitions in @webref/css into the format needed for css-tree and jsdom,
25+ * while removing unnecessary fields.
26+ *
27+ * @param {object } definition - The CSS property definition object.
28+ * @returns {Array } A key-value pair consisting of the property name and the property definition.
29+ */
30+ function prepareDefinition ( definition ) {
31+ const { name, syntax } = definition ;
32+ if ( syntax ) {
33+ const collectedTypes = collectTypes ( syntax ) ;
34+ if ( collectedTypes . size ) {
35+ for ( const type of caseSensitiveTypes ) {
36+ if ( collectedTypes . has ( type ) ) {
37+ definition . caseSensitive = true ;
38+ break ;
39+ }
40+ }
41+ }
42+ }
43+ delete definition . extended ;
44+ return [ name , definition ] ;
45+ }
46+
47+ /**
48+ * Collects CSS data types from syntax.
49+ * NOTE: Returns a map as we plan to collect dimensions etc. in the near future.
50+ *
51+ * @param {string } syntax - The CSS syntax definition.
52+ * @returns {Map } The collection of types.
53+ */
54+ function collectTypes ( syntax ) {
55+ const collectedTypes = new Map ( ) ;
56+ const ast = definitionSyntax . parse ( syntax ) ;
57+ if ( ast . type === "Group" ) {
58+ const subList = new Set ( ) ;
59+ definitionSyntax . walk ( ast , {
60+ enter ( node ) {
61+ if ( node . type === "Type" ) {
62+ if ( typeList . has ( node . name ) ) {
63+ collectedTypes . set ( node . name , node ) ;
64+ } else if ( ! node . name . endsWith ( "()" ) ) {
65+ subList . add ( node . name ) ;
66+ }
67+ }
68+ }
69+ } ) ;
70+ if ( subList . size ) {
71+ for ( const type of subList ) {
72+ const { syntax : typeSyntax } = syntaxes . get ( `<${ type } >` ) ;
73+ if ( typeSyntax ) {
74+ const expandedList = collectTypes ( typeSyntax ) ;
75+ if ( expandedList . size ) {
76+ for ( const [ key , value ] of expandedList ) {
77+ collectedTypes . set ( key , value ) ;
78+ }
79+ }
80+ }
81+ }
82+ }
83+ }
84+ return collectedTypes ;
85+ }
0 commit comments