From 64ff0446736627d7d3f65c1ee17e8449a630911f Mon Sep 17 00:00:00 2001 From: Francois Daoust Date: Wed, 17 Dec 2025 18:13:37 +0100 Subject: [PATCH] [CSS syntax patches] Fix `sameAs`, handle `legacyAliasOf` links The `sameAs` logic was *almost* correct but failed to report the syntax in the end. While reviewing differences with `mdn/data` to update CSSTree, it also occurred to me that we never set the syntax of properties defined as "legacy name aliases", even though we could with the same (very slighty extended) patching logic. Done here too (it could be argued that this could be done by Reffy as post-processing, done here for the time being to reuse the logic). This would set the syntax of legacy properties: - `-webkit-align-items` to that of `align-items` - `-webkit-align-content` to that of `align-content` - `-webkit-align-self` to that of `align-self` - `-webkit-animation-name` to that of `animation-name` - `-webkit-animation-duration` to that of `animation-duration` - `-webkit-animation-timing-function` to that of `animation-timing-function` - `-webkit-animation-iteration-count` to that of `animation-iteration-count` - `-webkit-animation-direction` to that of `animation-direction` - `-webkit-animation-play-state` to that of `animation-play-state` - `-webkit-animation-delay` to that of `animation-delay` - `-webkit-animation-fill-mode` to that of `animation-fill-mode` - `-webkit-animation` to that of `animation` - `-webkit-backface-visibility` to that of `backface-visibility` - `-webkit-background-clip` to that of `background-clip` - `-webkit-background-origin` to that of `background-origin` - `-webkit-background-size` to that of `background-size` - `-webkit-border-bottom-left-radius` to that of `border-bottom-left-radius` - `-webkit-border-bottom-right-radius` to that of `border-bottom-right-radius` - `-webkit-border-top-left-radius` to that of `border-top-left-radius` - `-webkit-border-top-right-radius` to that of `border-top-right-radius` - `-webkit-border-radius` to that of `border-radius` - `-webkit-box-shadow` to that of `box-shadow` - `-webkit-box-sizing` to that of `box-sizing` - `-webkit-flex` to that of `flex` - `-webkit-flex-basis` to that of `flex-basis` - `-webkit-flex-direction` to that of `flex-direction` - `-webkit-flex-flow` to that of `flex-flow` - `-webkit-flex-grow` to that of `flex-grow` - `-webkit-flex-shrink` to that of `flex-shrink` - `-webkit-flex-wrap` to that of `flex-wrap` - `-webkit-filter` to that of `filter` - `-webkit-justify-content` to that of `justify-content` - `-webkit-mask` to that of `mask` - `-webkit-mask-box-image` to that of `mask-border` - `-webkit-mask-box-image-outset` to that of `mask-border-outset` - `-webkit-mask-box-image-repeat` to that of `mask-border-repeat` - `-webkit-mask-box-image-slice` to that of `mask-border-slice` - `-webkit-mask-box-image-source` to that of `mask-border-source` - `-webkit-mask-box-image-width` to that of `mask-border-width` - `-webkit-mask-clip` to that of `mask-clip` - `-webkit-mask-composite` to that of `mask-composite` - `-webkit-mask-image` to that of `mask-image` - `-webkit-mask-origin` to that of `mask-origin` - `-webkit-mask-position` to that of `mask-position` - `-webkit-mask-repeat` to that of `mask-repeat` - `-webkit-mask-size` to that of `mask-size` - `-webkit-order` to that of `order` - `-webkit-perspective` to that of `perspective` - `-webkit-perspective-origin` to that of `perspective-origin` - `-webkit-transform-origin` to that of `transform-origin` - `-webkit-transform-style` to that of `transform-style` - `-webkit-transform` to that of `transform` - `-webkit-transition-delay` to that of `transition-delay` - `-webkit-transition-duration` to that of `transition-duration` - `-webkit-transition-property` to that of `transition-property` - `-webkit-transition-timing-function` to that of `transition-timing-function` - `-webkit-transition` to that of `transition` - `-webkit-text-size-adjust` to that of `text-size-adjust` - `grid-row-gap` to that of `row-gap` - `grid-column-gap` to that of `column-gap` - `grid-gap` to that of `gap` - `font-stretch` to that of `font-width` --- tools/amend-css-syntaxes.js | 48 ++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/tools/amend-css-syntaxes.js b/tools/amend-css-syntaxes.js index 5f13f7169a88..a570fff1d69c 100644 --- a/tools/amend-css-syntaxes.js +++ b/tools/amend-css-syntaxes.js @@ -49,12 +49,52 @@ function findCssConstruct(key, currentRoot) { return null; } +/** + * More generic version for findCssConstruct that looks for the construct + * across all given specs. + */ +function findCssConstructAcrossSpecs(key, specs) { + for (const spec of specs) { + if (spec.css) { + const construct = findCssConstruct(key, spec.css); + if (construct) { + return construct; + } + } + } + return null; +} + +/** + * Go through all CSS properties defined in the specs that are flagged as + * legacy aliases of another CSS property and set their syntax to that of + * the newer property. + */ +function setLegacyPropertySyntaxes(specs) { + for (const spec of specs) { + if (!spec.css) { + continue; + } + for (const legacyProperty of spec.css.properties) { + if (legacyProperty.legacyAliasOf && !legacyProperty.value) { + const property = findCssConstructAcrossSpecs(legacyProperty.legacyAliasOf, specs); + if (!property || !property.value) { + continue; + } + console.log(`- set syntax of legacy property ${legacyProperty.name} to that of ${property.name}`); + legacyProperty.value = property.value; + spec.needsSaving = true; + } + } + } +} + /** * Apply patches that apply to the given spec. * * The function returns a list of errors, an empty array if all went fine. */ -function applyCssSyntaxPatches(spec) { +function applyCssSyntaxPatches(spec, specs) { let errors = []; console.log(`- applying CSS syntax patches for ${spec.shortname}`); for (let [key, patch] of Object.entries(patches[spec.shortname])) { @@ -107,7 +147,7 @@ function applyCssSyntaxPatches(spec) { construct.value = construct.values.map(v => v.value).join(' | '); } else if (patch.sameAs) { - const sameConstruct = findCssConstruct(patch.sameAs, spec.css); + const sameConstruct = findCssConstructAcrossSpecs(patch.sameAs, specs); if (!sameConstruct) { errors.push(`The CSS syntax patch for ${key} in ${spec.shortname} cannot be applied: could not find "sameAs" target ${patch.sameAs}`); continue; @@ -116,6 +156,7 @@ function applyCssSyntaxPatches(spec) { errors.push(`The CSS syntax patch for ${key} in ${spec.shortname} cannot be applied: "sameAs" target ${patch.sameAs} has no syntax`); continue; } + construct.value = sameConstruct.value; } else { construct.value = trimSyntax(patch.value); @@ -166,6 +207,7 @@ async function amendCssSyntaxes(folder) { const rawIndex = await loadJSON(path.join(folder, 'index.json')); const index = JSON.parse(JSON.stringify(rawIndex)); await expandCrawlResult(index, folder, ['css']); + setLegacyPropertySyntaxes(index.results); let errors = []; for (const specShortname of Object.keys(patches)) { @@ -178,7 +220,7 @@ async function amendCssSyntaxes(folder) { errors.push(`Could not find any CSS in spec with shortname ${specShortname} for CSS syntax patching`); continue; } - errors = errors.concat(applyCssSyntaxPatches(spec)); + errors = errors.concat(applyCssSyntaxPatches(spec, index.results)); } for (const spec of index.results) {