diff --git a/packages/css-syntax-patches-for-csstree/CHANGELOG.md b/packages/css-syntax-patches-for-csstree/CHANGELOG.md index 637ab2e55..65ab3ff1c 100644 --- a/packages/css-syntax-patches-for-csstree/CHANGELOG.md +++ b/packages/css-syntax-patches-for-csstree/CHANGELOG.md @@ -1,5 +1,11 @@ # Changes to CSS Syntax Patches For CSSTree +### Unreleased (patch) + +- Patch `clip: rect()` to preserve legacy syntax +- Patch color functions to support relative color component keywords + + ### 1.0.17 _November 21, 2025_ diff --git a/packages/css-syntax-patches-for-csstree/dist/index.json b/packages/css-syntax-patches-for-csstree/dist/index.json index ab90c317a..d9210ade0 100644 --- a/packages/css-syntax-patches-for-csstree/dist/index.json +++ b/packages/css-syntax-patches-for-csstree/dist/index.json @@ -165,7 +165,7 @@ "caret": "<'caret-color'> || <'caret-animation'> || <'caret-shape'>", "caret-animation": "auto | manual", "clear": "| block-start | block-end | top | bottom | both-inline | both-block", - "clip": "rect( , , , ) | auto", + "clip": "rect( , , , ) | rect( ) | auto", "color-adjust": "<'print-color-adjust'>", "color-interpolation": "auto | sRGB | linearRGB", "column-count": "auto | ", @@ -508,7 +508,7 @@ "types": { "dashed-ident": "", "unicode-range-token": "", - "alpha()": "alpha( [ from ] [ / [ | none ] ]? )", + "alpha()": "alpha( [ from ] [ / [ | alpha | none ] ]? )", "anchor-size()": "anchor-size( [ || ]? , ? )", "anchor()": "anchor( ? && , ? )", "anchored-feature": "fallback : <'position-try-fallbacks'>", @@ -561,7 +561,7 @@ "color-stop-angle": "[ | ]{1,2}", "color-stop-list": " , [ ? , ]#?", "color-stripe": " && [ | ]?", - "color()": "color( [ from ]? [ / [ | none ] ]? )", + "color()": "color( [ from ]? [ | [ [ | | r | g | b | alpha | none ]{3} [ / [ | r | g | b | alpha | none ] ]? ] | [ [ | | x | y | z | alpha | none ]{3} [ / [ | x | y | z | alpha | none ] ]? ] ] )", "colorspace-params": "[ | | ]", "command-end-point": "[ to | by ]", "compat-special": "textfield | menulist-button", @@ -632,7 +632,7 @@ "hsl()": "[ | ]", "hsla()": "[ | ]", "hue-rotate()": "hue-rotate( [ | ]? )", - "hwb()": "hwb( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "hwb()": "hwb( [ from ]? [ | h | w | b | alpha | none ] [ | | h | w | b | alpha | none ] [ | | h | w | b | alpha | none ] [ / [ | h | w | b | alpha | none ] ]? )", "ictcp()": "ictcp( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", "ident-arg": " | | ", "ident()": "ident( + )", @@ -658,9 +658,9 @@ "jzazbz()": "jzazbz( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", "jzczhz()": "jzczhz( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", "keyframe-selector": "from | to | | ", - "lab()": "lab( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "lab()": "lab( [ from ]? [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ / [ | l | a | b | alpha | none ] ]? )", "layout-box": " | margin-box", - "lch()": "lch( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", + "lch()": "lch( [ from ]? [ | | l | c | h | alpha | none ] [ | | l | c | h | alpha | none ] [ | l | c | h | alpha | none ] [ / [ | l | c | h | alpha | none ] ]? )", "legacy-border-radius-syntax": "{1,2}", "legacy-hsl-syntax": "hsl( , , , ? )", "legacy-hsla-syntax": "hsla( , , , ? )", @@ -691,15 +691,15 @@ "mf-gt": "'>' '='?", "mf-lt": "'<' '='?", "mf-range": " | | | ", - "modern-hsl-syntax": "hsl( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "modern-hsla-syntax": "hsla( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "modern-rgb-syntax": "rgb( [ from ]? [ | | none ]{3} [ / [ | none ] ]? )", - "modern-rgba-syntax": "rgba( [ from ]? [ | | none ]{3} [ / [ | none ] ]? )", + "modern-hsl-syntax": "hsl( [ from ]? [ | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ / [ | h | s | l | alpha | none ] ]? )", + "modern-hsla-syntax": "hsla( [ from ]? [ | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ / [ | h | s | l | alpha | none ] ]? )", + "modern-rgb-syntax": "rgb( [ from ]? [ | | r | g | b | alpha | none ]{3} [ / [ | r | g | b | alpha | none ] ]? )", + "modern-rgba-syntax": "rgba( [ from ]? [ | | r | g | b | alpha | none ]{3} [ / [ | r | g | b | alpha | none ] ]? )", "move-command": "move ", "mq-boolean": "", "number-optional-number": " ?", - "oklab()": "oklab( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "oklch()": "oklch( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", + "oklab()": "oklab( [ from ]? [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ / [ | l | a | b | alpha | none ] ]? )", + "oklch()": "oklch( [ from ]? [ | | l | c | h | alpha | none ] [ | | l | c | h | alpha | none ] [ | l | c | h | alpha | none ] [ / [ | l | c | h | alpha | none ] ]? )", "opacity-value": " | ", "opacity()": "opacity( [ | ]? )", "opentype-tag": "", diff --git a/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-properties.json b/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-properties.json index f21215094..306b0f988 100644 --- a/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-properties.json +++ b/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-properties.json @@ -1678,12 +1678,15 @@ "type": "modified", "comment": "", "syntax-b": " | auto", - "syntax-a": "rect( , , , ) | auto", - "syntax-m": "rect( , , , ) | auto", + "syntax-a": "rect( , , , ) | rect( ) | auto", + "syntax-m": "rect( , , , ) | rect( ) | auto", "tests": { "passing": [ { "value": "rect(1px, 2px, 3px, 4px)" + }, + { + "value": "rect(1px 2px 3px 4px)" } ], "failing": [] diff --git a/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-types.json b/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-types.json index 2f8247dcf..795b1db46 100644 --- a/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-types.json +++ b/packages/css-syntax-patches-for-csstree/patches/webref-over-csstree-types.json @@ -4,10 +4,28 @@ "comment": "", "syntax-b": "", "syntax-a": "alpha( [ from ] [ / [ | none ] ]? )", - "syntax-m": "alpha( [ from ] [ / [ | none ] ]? )", + "syntax-m": "alpha( [ from ] [ / [ | alpha | none ] ]? )", "tests": { - "passing": [], - "failing": [] + "passing": [ + { + "property": "color", + "value": "alpha(from oklch(60% 0.25 315 / 0.3) / 80%)" + }, + { + "property": "color", + "value": "alpha(from oklch(60% 0.25 315 / 0.3) / alpha)" + }, + { + "property": "color", + "value": "alpha(from oklch(60% 0.25 315 / 0.3) / calc(alpha / 2))" + } + ], + "failing": [ + { + "property": "color", + "value": "alpha(from oklch(60% 0.25 315 / 0.3) / a)" + } + ] } }, "an+b": { @@ -908,7 +926,7 @@ "comment": "", "syntax-b": "color( [ / [ | none ] ]? )", "syntax-a": "color( [ from ]? [ / [ | none ] ]? )", - "syntax-m": "color( [ from ]? [ / [ | none ] ]? )", + "syntax-m": "color( [ from ]? [ | [ [ | | r | g | b | alpha | none ]{3} [ / [ | r | g | b | alpha | none ] ]? ] | [ [ | | x | y | z | alpha | none ]{3} [ / [ | x | y | z | alpha | none ] ]? ] ] )", "tests": { "passing": [ { @@ -918,12 +936,28 @@ { "property": "color", "value": "color(from red xyz 0 0 0)" + }, + { + "property": "color", + "value": "color(from red xyz x y z / alpha)" + }, + { + "property": "color", + "value": "color(from red srgb r g b / alpha)" } ], "failing": [ { "property": "color", "value": "color(red from xyz 0 0 0)" + }, + { + "property": "color", + "value": "color(from red xyz r g b)" + }, + { + "property": "color", + "value": "color(from red srgb x y z)" } ] } @@ -1935,7 +1969,7 @@ "comment": "", "syntax-b": "hwb( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? )", "syntax-a": "hwb( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "syntax-m": "hwb( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "syntax-m": "hwb( [ from ]? [ | h | w | b | alpha | none ] [ | | h | w | b | alpha | none ] [ | | h | w | b | alpha | none ] [ / [ | h | w | b | alpha | none ] ]? )", "tests": { "passing": [ { @@ -2304,7 +2338,7 @@ "comment": "", "syntax-b": "lab( [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", "syntax-a": "lab( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "syntax-m": "lab( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "syntax-m": "lab( [ from ]? [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ / [ | l | a | b | alpha | none ] ]? )", "tests": { "passing": [ { @@ -2356,7 +2390,7 @@ "comment": "", "syntax-b": "lch( [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", "syntax-a": "lch( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", - "syntax-m": "lch( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", + "syntax-m": "lch( [ from ]? [ | | l | c | h | alpha | none ] [ | | l | c | h | alpha | none ] [ | l | c | h | alpha | none ] [ / [ | l | c | h | alpha | none ] ]? )", "tests": { "passing": [ { @@ -2892,7 +2926,7 @@ "comment": "", "syntax-b": "", "syntax-a": "hsl( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "syntax-m": "hsl( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "syntax-m": "hsl( [ from ]? [ | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ / [ | h | s | l | alpha | none ] ]? )", "tests": { "passing": [ { @@ -2926,6 +2960,10 @@ { "property": "color", "value": "hsl(from hsl(0.5turn 5 10) 0.5turn 5 10)" + }, + { + "property": "color", + "value": "hsl(from hsl(0.5turn 5 10) h s l / alpha)" } ], "failing": [ @@ -2941,7 +2979,7 @@ "comment": "", "syntax-b": "", "syntax-a": "hsla( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "syntax-m": "hsla( [ from ]? [ | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "syntax-m": "hsla( [ from ]? [ | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ | | h | s | l | alpha | none ] [ / [ | h | s | l | alpha | none ] ]? )", "tests": { "passing": [ { @@ -2975,6 +3013,10 @@ { "property": "color", "value": "hsla(from hsla(0.5turn 5 10) 0.5turn 5 10)" + }, + { + "property": "color", + "value": "hsla(from hsla(0.5turn 5 10) h s l / alpha)" } ], "failing": [ @@ -2990,7 +3032,7 @@ "comment": "", "syntax-b": "", "syntax-a": "rgb( [ from ]? [ | | none ]{3} [ / [ | none ] ]? )", - "syntax-m": "rgb( [ from ]? [ | | none ]{3} [ / [ | none ] ]? )", + "syntax-m": "rgb( [ from ]? [ | | r | g | b | alpha | none ]{3} [ / [ | r | g | b | alpha | none ] ]? )", "tests": { "passing": [ { @@ -3024,12 +3066,32 @@ { "property": "color", "value": "rgb(from rgb(20% 5 10) 20% 5 10)" + }, + { + "property": "color", + "value": "rgb(from rgb(20% 5 10) r g b / alpha)" + }, + { + "property": "color", + "value": "rgb(from rgb(20% 5 10) alpha alpha alpha / alpha)" + }, + { + "property": "color", + "value": "rgb(from rgb(20% 5 10) r r r / r)" + }, + { + "property": "color", + "value": "rgb(from rgb(20% 5 10) calc(r / 2) calc(g / 2) calc(b / 2) / calc(alpha / 2))" } ], "failing": [ { "property": "color", "value": "rgb(20% 10 5, 0.5)" + }, + { + "property": "color", + "value": "rgb(from rgb(20% 5 10) red green blue / a)" } ] } @@ -3039,7 +3101,7 @@ "comment": "", "syntax-b": "", "syntax-a": "rgba( [ from ]? [ | | none ]{3} [ / [ | none ] ]? )", - "syntax-m": "rgba( [ from ]? [ | | none ]{3} [ / [ | none ] ]? )", + "syntax-m": "rgba( [ from ]? [ | | r | g | b | alpha | none ]{3} [ / [ | r | g | b | alpha | none ] ]? )", "tests": { "passing": [ { @@ -3073,12 +3135,32 @@ { "property": "color", "value": "rgba(from rgba(20% 5 10) 20% 5 10)" + }, + { + "property": "color", + "value": "rgba(from rgb(20% 5 10) r g b / alpha)" + }, + { + "property": "color", + "value": "rgba(from rgb(20% 5 10) alpha alpha alpha / alpha)" + }, + { + "property": "color", + "value": "rgba(from rgb(20% 5 10) r r r / r)" + }, + { + "property": "color", + "value": "rgba(from rgb(20% 5 10) calc(r / 2) calc(g / 2) calc(b / 2) / calc(alpha / 2))" } ], "failing": [ { "property": "color", "value": "rgba(20% 10 5, 0.5)" + }, + { + "property": "color", + "value": "rgb(from rgb(20% 5 10) red green blue / a)" } ] } @@ -3121,7 +3203,7 @@ "comment": "", "syntax-b": "oklab( [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", "syntax-a": "oklab( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", - "syntax-m": "oklab( [ from ]? [ | | none ] [ | | none ] [ | | none ] [ / [ | none ] ]? )", + "syntax-m": "oklab( [ from ]? [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ | | l | a | b | alpha | none ] [ / [ | l | a | b | alpha | none ] ]? )", "tests": { "passing": [ { @@ -3162,7 +3244,7 @@ "comment": "", "syntax-b": "oklch( [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", "syntax-a": "oklch( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", - "syntax-m": "oklch( [ from ]? [ | | none ] [ | | none ] [ | none ] [ / [ | none ] ]? )", + "syntax-m": "oklch( [ from ]? [ | | l | c | h | alpha | none ] [ | | l | c | h | alpha | none ] [ | l | c | h | alpha | none ] [ / [ | l | c | h | alpha | none ] ]? )", "tests": { "passing": [ { diff --git a/packages/css-syntax-patches-for-csstree/raw-data/webref-over-csstree-properties.json b/packages/css-syntax-patches-for-csstree/raw-data/webref-over-csstree-properties.json index 166009aa5..ff9063afe 100644 --- a/packages/css-syntax-patches-for-csstree/raw-data/webref-over-csstree-properties.json +++ b/packages/css-syntax-patches-for-csstree/raw-data/webref-over-csstree-properties.json @@ -632,7 +632,7 @@ "clip": { "type": "modified", "syntax-b": " | auto", - "syntax-a": "rect( , , , ) | auto", + "syntax-a": "rect( , , , ) | rect( ) | auto", "comment": "" }, "color-adjust": { diff --git a/packages/css-syntax-patches-for-csstree/raw-data/webref-properties.json b/packages/css-syntax-patches-for-csstree/raw-data/webref-properties.json index 0e12d7e0d..2821d4751 100644 --- a/packages/css-syntax-patches-for-csstree/raw-data/webref-properties.json +++ b/packages/css-syntax-patches-for-csstree/raw-data/webref-properties.json @@ -573,7 +573,7 @@ "syntax": "inline-start | inline-end | block-start | block-end | left | right | top | bottom | both-inline | both-block | both | none" }, "clip": { - "syntax": "rect( , , , ) | auto" + "syntax": "rect( , , , ) | rect( ) | auto" }, "clip-path": { "syntax": " | [ || ] | none" diff --git a/packages/css-syntax-patches-for-csstree/scripts/generate-webref-sets.mjs b/packages/css-syntax-patches-for-csstree/scripts/generate-webref-sets.mjs index 37dc72995..9b659ad94 100644 --- a/packages/css-syntax-patches-for-csstree/scripts/generate-webref-sets.mjs +++ b/packages/css-syntax-patches-for-csstree/scripts/generate-webref-sets.mjs @@ -109,7 +109,7 @@ export async function generate_webref_sets() { } if (property.name === 'clip') { - property.syntax = 'rect( , , , ) | auto'; + property.syntax = 'rect( , , , ) | rect( ) | auto'; } if (!property.syntax) { diff --git a/packages/css-syntax-patches-for-csstree/tests/e2e.test.mjs b/packages/css-syntax-patches-for-csstree/tests/e2e.test.mjs index 3c10f9741..cfa6a319b 100644 --- a/packages/css-syntax-patches-for-csstree/tests/e2e.test.mjs +++ b/packages/css-syntax-patches-for-csstree/tests/e2e.test.mjs @@ -3,7 +3,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import postcss from 'postcss'; -import { find, fork, parse, walk } from 'css-tree'; +import { find, fork, parse } from 'css-tree'; async function get_files(dir, recursive = true) { dir = path.resolve(dir); @@ -108,7 +108,6 @@ for (const css_file of css_files) { const { prop, value, parent } = decl; const csstree_value_node = parse(value, { context: 'value' }); - patch_relative_color_keywords(csstree_value_node); if (contains_unsupported_function(csstree_value_node)) { continue; @@ -141,47 +140,3 @@ for (const css_file of css_files) { } }); } - -function patch_relative_color_keywords(csstree_value_node) { - let color_function_stack = 0; - let relative_color_functions = /^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)$/i; - let relative_color_channel_keywords = /^(?:r|g|b|h|s|l|a|b|c|w|b|x|y|z)$/i; - - walk( - csstree_value_node, - { - enter: function (node) { - if ( - node.type === 'Function' && - relative_color_functions.test(node.name) - ) { - color_function_stack++; - - return; - } - - if ( - node.type === 'Identifier' && - color_function_stack > 0 && - relative_color_channel_keywords.test(node.name) - ) { - node.type = 'Number'; - node.value = '0'; - delete node.name; - - return; - } - }, - exit: function (node) { - if ( - node.type === 'Function' && - relative_color_functions.test(node.name) - ) { - color_function_stack--; - - return; - } - }, - }, - ); -}