From f4790167f2f6af22ff22b1857db6ee327c004557 Mon Sep 17 00:00:00 2001 From: Will Bamberg Date: Sun, 9 Oct 2022 20:41:44 -0700 Subject: [PATCH 1/2] Support at-rules and at-rule descriptors on the formal syntax --- kumascript/macros/CSSSyntax.ejs | 145 ++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 44 deletions(-) diff --git a/kumascript/macros/CSSSyntax.ejs b/kumascript/macros/CSSSyntax.ejs index 2180665162a8..d008f9c9e55b 100644 --- a/kumascript/macros/CSSSyntax.ejs +++ b/kumascript/macros/CSSSyntax.ejs @@ -78,6 +78,100 @@ for (const spec of Object.values(parsedWebRef)) { valuespaces = {...valuespaces, ...spec.valuespaces}; } +/** + * Get the spec shortnames for an item, given: + * @param {string} itemName - the name of the item + * @param {string} itemType - this can only be "properties" or "atrules" + */ +function getSpecsForItem(itemName, itemType) { + // 1) Get all specs which list this item + let specsForItem = []; + for (const [shortname, data] of Object.entries(parsedWebRef)) { + const itemNames = Object.keys(data[itemType]); + if (itemNames.includes(itemName)) { + specsForItem.push(shortname); + } + } + // 2) If we have more than one spec, filter out specs that end "-n" where n is a number + if (specsForItem.length > 1) { + specsForItem = specsForItem.filter( specName => !(/-\d+$/.test(specName)) ); + } + return specsForItem; +} + + +/** + * Get the formal syntax for a property from the webref data, given: + * @param {string} propertyName - the name of the property + */ + function getPropertySyntax(propertyName) { + // Get all specs which list this property + const specsForProp = getSpecsForItem(propertyName, "properties"); + // If we have only one spec, return the syntax it lists + if (specsForProp.length === 1) { + return parsedWebRef[specsForProp[0]].properties[propertyName].value; + } + // If we have > 1 spec, assume that: + // - one of them is the base spec, which defines `values`, + // - the others define incremental additions as `newValues` + let syntax = ''; + let newSyntaxes = ''; + for (const specName of specsForProp) { + const baseValue = parsedWebRef[specName].properties[propertyName].value; + if (baseValue) { + syntax = baseValue; + } + const newValues = parsedWebRef[specName].properties[propertyName].newValues; + if (newValues) { + newSyntaxes += ` | ${newValues}`; + } + } + // Concatenate newValues onto values to return a single syntax string + if (newSyntaxes) { + syntax += newSyntaxes; + } + return syntax; +} + +/** + * Get the formal syntax for an at-rule from the webref data, given: + * @param {string} atRuleName - the name of the at-rule + */ +function getAtRuleSyntax(atRuleName) { + // An at-rule may appear in more than one spec: for example, if extra descriptors + // are defined in different specs. But we assume that the at-rule's own syntax, + // defined in the `value` property, only appears in one of them. + const specs = getSpecsForItem(atRuleName, "atrules"); + for (const spec of specs) { + if (parsedWebRef[spec].atrules[atRuleName].value) { + return parsedWebRef[spec].atrules[atRuleName].value; + } + } + return ''; +} + +/** + * Get the formal syntax for an at-rule descriptor from the webref data, given: + * @param {string} atRuleDescriptorName - the name of the at-rule descriptor + */ +function getAtRuleDescriptorSyntax(atRuleDescriptorName) { + // We assume that the at-rule descriptor page is directly under + // the page for its at-rule. + const atRuleName = env.slug.split('/').at(-2); + const specs = getSpecsForItem(atRuleName, "atrules"); + // Look through all the specs that define the at-rule, for the one + // that defines this descriptor. + for (const spec of specs) { + const atRule = parsedWebRef[spec].atrules[atRuleName]; + for (const descriptor of atRule.descriptors) { + if (descriptor.name === atRuleDescriptorName) { + return descriptor.value; + } + } + } + return ''; +} + /** * Get the formal syntax and properly formatted name for an item. */ @@ -88,7 +182,7 @@ function getNameAndSyntax() { switch (env["page-type"]) { case "css-shorthand-property": case "css-property": - itemSyntax = getPropertySyntax(itemName, parsedWebRef); + itemSyntax = getPropertySyntax(itemName); break; case "css-type": // some CSS data type slugs have a `_value` suffix @@ -108,6 +202,12 @@ function getNameAndSyntax() { itemSyntax = valuespaces[itemName].value; } break; + case "css-at-rule": + itemSyntax = getAtRuleSyntax(itemName); + break; + case "css-at-rule-descriptor": + itemSyntax = getAtRuleDescriptorSyntax(itemName); + break; } return { name: itemName, @@ -115,49 +215,6 @@ function getNameAndSyntax() { } } -/** - * Get the formal syntax for a property from the webref data, given: - * @param {string} propertyName - the name of the property - */ -function getPropertySyntax(propertyName) { - // 1) get all specs which list this property - let specsForProp = []; - for (const [shortname, data] of Object.entries(parsedWebRef)) { - const propNames = Object.keys(data.properties); - if (propNames.includes(propertyName)) { - specsForProp.push(shortname); - } - } - // 2) If we have more than one spec, filter out specs that end "-n" where n is a number - if (specsForProp.length > 1) { - specsForProp = specsForProp.filter( specName => !(/-\d+$/.test(specName)) ); - } - // 3) If we now have only one spec, return the syntax it lists - if (specsForProp.length === 1) { - return parsedWebRef[specsForProp[0]].properties[propertyName].value; - } - // 4) If we still have > 1 spec, assume that: - // - one of them is the base spec, which defines `values`, - // - the others define incremental additions as `newValues` - let syntax = ''; - let newSyntaxes = ''; - for (const specName of specsForProp) { - const baseValue = parsedWebRef[specName].properties[propertyName].value; - if (baseValue) { - syntax = baseValue; - } - const newValues = parsedWebRef[specName].properties[propertyName].newValues; - if (newValues) { - newSyntaxes += ` | ${newValues}`; - } - } - // Concatenate newValues onto values to return a single syntax string - if (newSyntaxes) { - syntax += newSyntaxes; - } - return syntax; -} - /** * Get the markup for a multiplier, including links to the value definition syntax. */ From 3a35485ebb76edf0706a50cd5f92d6bc2f2eb407 Mon Sep 17 00:00:00 2001 From: Will Bamberg Date: Mon, 10 Oct 2022 14:51:49 -0700 Subject: [PATCH 2/2] at-rules want all specs --- kumascript/macros/CSSSyntax.ejs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/kumascript/macros/CSSSyntax.ejs b/kumascript/macros/CSSSyntax.ejs index d008f9c9e55b..37cc4b8620ad 100644 --- a/kumascript/macros/CSSSyntax.ejs +++ b/kumascript/macros/CSSSyntax.ejs @@ -84,18 +84,14 @@ for (const spec of Object.values(parsedWebRef)) { * @param {string} itemType - this can only be "properties" or "atrules" */ function getSpecsForItem(itemName, itemType) { - // 1) Get all specs which list this item - let specsForItem = []; + // Get all specs which list this item + const specsForItem = []; for (const [shortname, data] of Object.entries(parsedWebRef)) { const itemNames = Object.keys(data[itemType]); if (itemNames.includes(itemName)) { specsForItem.push(shortname); } } - // 2) If we have more than one spec, filter out specs that end "-n" where n is a number - if (specsForItem.length > 1) { - specsForItem = specsForItem.filter( specName => !(/-\d+$/.test(specName)) ); - } return specsForItem; } @@ -105,13 +101,17 @@ function getSpecsForItem(itemName, itemType) { * @param {string} propertyName - the name of the property */ function getPropertySyntax(propertyName) { - // Get all specs which list this property - const specsForProp = getSpecsForItem(propertyName, "properties"); - // If we have only one spec, return the syntax it lists + // 1) Get all specs which list this property + let specsForProp = getSpecsForItem(propertyName, "properties"); + // 2) If we have more than one spec, filter out specs that end "-n" where n is a number + if (specsForProp.length > 1) { + specsForProp = specsForProp.filter( specName => !(/-\d+$/.test(specName)) ); + } + // 3) If we have only one spec, return the syntax it lists if (specsForProp.length === 1) { return parsedWebRef[specsForProp[0]].properties[propertyName].value; } - // If we have > 1 spec, assume that: + // 4) If we have > 1 spec, assume that: // - one of them is the base spec, which defines `values`, // - the others define incremental additions as `newValues` let syntax = '';