diff --git a/schemas/browserlib/extract-cssdfn.json b/schemas/browserlib/extract-cssdfn.json index 0de91ef3..f619f7c1 100644 --- a/schemas/browserlib/extract-cssdfn.json +++ b/schemas/browserlib/extract-cssdfn.json @@ -18,6 +18,7 @@ "value": { "$ref": "../common.json#/$defs/cssValue" }, "newValues": { "$ref": "../common.json#/$defs/cssValue" }, "values": { "$ref": "../common.json#/$defs/cssValues" }, + "legacyAliasOf": { "$ref": "../common.json#/$defs/cssPropertyName" }, "styleDeclaration": { "type": "array", "items": { "type": "string" }, diff --git a/src/browserlib/extract-cssdfn.mjs b/src/browserlib/extract-cssdfn.mjs index 89d7c5af..12f25d4d 100644 --- a/src/browserlib/extract-cssdfn.mjs +++ b/src/browserlib/extract-cssdfn.mjs @@ -18,13 +18,17 @@ export default function () { const warnings = []; const res = { - // Properties are always defined in dedicated tables in modern CSS specs - properties: extractDfns({ - selector: 'table.propdef:not(.attrdef)', - extractor: extractTableDfns, - duplicates: 'merge', - warnings - }), + // Properties are always defined in dedicated tables in modern CSS specs, + // Legacy properties are always defined in prose in a dfn with a nearby + // reference to "legacy name alias" + properties: [] + .concat(extractDfns({ + selector: 'table.propdef:not(.attrdef)', + extractor: extractTableDfns, + duplicates: 'merge', + warnings + })) + .concat(extractLegacyProperties(document)), // At-rules, selectors, functions and types are defined through dfns with // the right "data-dfn-type" attribute @@ -826,3 +830,56 @@ const extractProductionRules = root => { return rules; } + + +/** + * Extract legacy alias relationships, looking for occurrences of the term + * "legacy name alias". + * + * Next to it, there should be: + * 1. a dfn for a property followed by a reference to the aliased property; or + * 2. a table with two columns: dfns in the first column, references to the + * aliased properties in the second column. + */ +const extractLegacyProperties = doc => + [...doc.querySelectorAll('a[href*="#legacy-name-alias"]')] + .map(el => el.parentElement) + .map(el => { + const dfn = el.querySelector('dfn[data-dfn-type="property"]'); + const alias = el.querySelector('a[data-link-type="property"]'); + if (dfn && alias) { + // Aliasing is defined in prose + return { + name: normalize(dfn.textContent), + href: getAbsoluteUrl(dfn), + legacyAliasOf: normalize(alias.textContent) + }; + } + else { + // Look for a compat table right after the paragraph + const table = el.nextElementSibling; + if (!table || table.nodeName !== 'TABLE') { + return null; + } + if ([...table.querySelectorAll('thead > tr > th')].length !== 2) { + return null; + } + return [...table.querySelectorAll('tbody > tr')] + .map(row => { + const dfn = row.querySelector('dfn[data-dfn-type="property"]'); + const alias = row.querySelector('a[data-link-type="property"]'); + if (dfn && alias) { + return { + name: normalize(dfn.textContent), + href: getAbsoluteUrl(dfn), + legacyAliasOf: normalize(alias.textContent) + }; + } + else { + return null; + } + }); + } + }) + .flat() + .filter(prop => !!prop); diff --git a/tests/extract-css.js b/tests/extract-css.js index 9faa156d..4d57ed12 100644 --- a/tests/extract-css.js +++ b/tests/extract-css.js @@ -1580,6 +1580,69 @@ that spans multiple lines */ "value": "currentColor | [] | inherit", "initial": "white" }] + }, + + { + title: 'extracts a legacy name alias', + html: `

+ The good-old + property is a legacy name alias of + the brand-new property. +

+ `, + css: [{ + name: 'good-old', + href: 'about:blank#old', + legacyAliasOf: 'brand-new' + }] + }, + + { + title: 'extracts legacy name aliases from a suitable table', + html: `

+ The following properties must be supported as + legacy name aliases of the + corresponding unprefixed property: +

+ + + + + + + + + + + + + + +
First columnSecond column
good-oldbrand-new
-webkit-oldbrand-new
+ `, + css: [ + { + name: 'good-old', + href: 'about:blank#old', + legacyAliasOf: 'brand-new' + }, + { + name: '-webkit-old', + href: 'about:blank#webkit', + legacyAliasOf: 'brand-new' + } + ] + }, + + { + title: 'avoids legacy name alias references in prose without a dfn', + html: `

+ The good-old + property is a legacy name alias of + the brand-new property. +

+ `, + css: [] } ];