| 2932 | * @returns {void} |
| 2933 | */ |
| 2934 | const emitKnownPropertyExports = (decl, declPropertyName) => { |
| 2935 | /** @type {Record<string, number>} */ |
| 2936 | let parsedKeywords = Object.create(null); |
| 2937 | const isGridProperty = Boolean(declPropertyName.startsWith("grid")); |
| 2938 | const isGridTemplate = isGridProperty |
| 2939 | ? Boolean( |
| 2940 | declPropertyName === "grid" || |
| 2941 | declPropertyName === "grid-template" || |
| 2942 | declPropertyName === "grid-template-columns" || |
| 2943 | declPropertyName === "grid-template-rows" |
| 2944 | ) |
| 2945 | : false; |
| 2946 | const keywords = |
| 2947 | /** @type {Record<string, number>} */ |
| 2948 | (knownProperties.get(declPropertyName)); |
| 2949 | let afterExclamation = false; |
| 2950 | /** |
| 2951 | * Emit the ICSS export for one collected name span (a quoted string drops its delimiters). Called inline during the walk so no intermediate `values` array / per-name tuples are allocated. |
| 2952 | * @param {number} start name start offset |
| 2953 | * @param {number} end name end offset |
| 2954 | * @param {boolean=} isString whether the span is a quoted string |
| 2955 | * @returns {void} |
| 2956 | */ |
| 2957 | const emit = (start, end, isString) => { |
| 2958 | const { line: sl, column: sc } = locConverter.get(start); |
| 2959 | const { line: el, column: ec } = locConverter.get(end); |
| 2960 | const name = unescapeRange( |
| 2961 | isString ? start + 1 : start, |
| 2962 | isString ? end - 1 : end |
| 2963 | ); |
| 2964 | addCssExport( |
| 2965 | sl, |
| 2966 | sc, |
| 2967 | el, |
| 2968 | ec, |
| 2969 | name, |
| 2970 | getReexport(name), |
| 2971 | [start, end], |
| 2972 | true, |
| 2973 | CssIcssExportDependency.EXPORT_MODE.ONCE, |
| 2974 | isGridProperty |
| 2975 | ? CssIcssExportDependency.EXPORT_TYPE.GRID_CUSTOM_IDENTIFIER |
| 2976 | : CssIcssExportDependency.EXPORT_TYPE.NORMAL |
| 2977 | ); |
| 2978 | }; |
| 2979 | // Collect idents/strings to export — top-level only, except grid-template recurses (`[line-name]` blocks live in `repeat(…)`). |
| 2980 | /** @type {(cvs: AstNode[]) => void} */ |
| 2981 | const walkExports = (cvs) => { |
| 2982 | for (const cv of cvs) { |
| 2983 | switch (A.type(cv)) { |
| 2984 | case NodeType.Comma: |
| 2985 | parsedKeywords = Object.create(null); |
| 2986 | break; |
| 2987 | case NodeType.Delim: |
| 2988 | afterExclamation = A.value(cv) === "!"; |
| 2989 | break; |
| 2990 | case NodeType.Ident: { |
| 2991 | if (isGridTemplate) break; |