diff --git a/packages/css-calc/CHANGELOG.md b/packages/css-calc/CHANGELOG.md index 977a523823..d972b96133 100644 --- a/packages/css-calc/CHANGELOG.md +++ b/packages/css-calc/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to CSS Calc +### Unreleased (patch) + +- Update `random()` to better handle floating point errors. +- Update `random()` to match the latest [specification](https://drafts.csswg.org/css-values-5/#randomness) + ### 2.1.2 _February 23, 2025_ diff --git a/packages/css-calc/dist/index.cjs b/packages/css-calc/dist/index.cjs index b4fab5e577..06ca7f082f 100644 --- a/packages/css-calc/dist/index.cjs +++ b/packages/css-calc/dist/index.cjs @@ -1 +1 @@ -"use strict";var e=require("@csstools/css-parser-algorithms"),n=require("@csstools/css-tokenizer");const t=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(t,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}const o={cm:"px",in:"px",mm:"px",pc:"px",pt:"px",px:"px",q:"px",deg:"deg",grad:"deg",rad:"deg",turn:"deg",ms:"s",s:"s",hz:"hz",khz:"hz"},r=new Map([["cm",e=>e],["mm",e=>10*e],["q",e=>40*e],["in",e=>e/2.54],["pc",e=>e/2.54*6],["pt",e=>e/2.54*72],["px",e=>e/2.54*96]]),i=new Map([["deg",e=>e],["grad",e=>e/.9],["rad",e=>e/180*Math.PI],["turn",e=>e/360]]),u=new Map([["deg",e=>.9*e],["grad",e=>e],["rad",e=>.9*e/180*Math.PI],["turn",e=>.9*e/360]]),a=new Map([["hz",e=>e],["khz",e=>e/1e3]]),s=new Map([["cm",e=>2.54*e],["mm",e=>25.4*e],["q",e=>25.4*e*4],["in",e=>e],["pc",e=>6*e],["pt",e=>72*e],["px",e=>96*e]]),l=new Map([["hz",e=>1e3*e],["khz",e=>e]]),c=new Map([["cm",e=>e/10],["mm",e=>e],["q",e=>4*e],["in",e=>e/25.4],["pc",e=>e/25.4*6],["pt",e=>e/25.4*72],["px",e=>e/25.4*96]]),m=new Map([["ms",e=>e],["s",e=>e/1e3]]),v=new Map([["cm",e=>e/6*2.54],["mm",e=>e/6*25.4],["q",e=>e/6*25.4*4],["in",e=>e/6],["pc",e=>e],["pt",e=>e/6*72],["px",e=>e/6*96]]),T=new Map([["cm",e=>e/72*2.54],["mm",e=>e/72*25.4],["q",e=>e/72*25.4*4],["in",e=>e/72],["pc",e=>e/72*6],["pt",e=>e],["px",e=>e/72*96]]),p=new Map([["cm",e=>e/96*2.54],["mm",e=>e/96*25.4],["q",e=>e/96*25.4*4],["in",e=>e/96],["pc",e=>e/96*6],["pt",e=>e/96*72],["px",e=>e]]),N=new Map([["cm",e=>e/4/10],["mm",e=>e/4],["q",e=>e],["in",e=>e/4/25.4],["pc",e=>e/4/25.4*6],["pt",e=>e/4/25.4*72],["px",e=>e/4/25.4*96]]),f=new Map([["deg",e=>180*e/Math.PI],["grad",e=>180*e/Math.PI/.9],["rad",e=>e],["turn",e=>180*e/Math.PI/360]]),k=new Map([["ms",e=>1e3*e],["s",e=>e]]),d=new Map([["deg",e=>360*e],["grad",e=>360*e/.9],["rad",e=>360*e/180*Math.PI],["turn",e=>e]]),C=new Map([["cm",r],["mm",c],["q",N],["in",s],["pc",v],["pt",T],["px",p],["ms",m],["s",k],["deg",i],["grad",u],["rad",f],["turn",d],["hz",a],["khz",l]]);function convertUnit(e,t){if(!n.isTokenDimension(e))return t;if(!n.isTokenDimension(t))return t;const o=toLowerCaseAZ(e[4].unit),r=toLowerCaseAZ(t[4].unit);if(o===r)return t;const i=C.get(r);if(!i)return t;const u=i.get(o);if(!u)return t;const a=u(t[4].value),s=[n.TokenType.Dimension,"",t[2],t[3],{...t[4],signCharacter:a<0?"-":void 0,type:Number.isInteger(a)?n.NumberType.Integer:n.NumberType.Number,value:a}];return n.mutateUnit(s,e[4].unit),s}function toCanonicalUnit(e){if(!n.isTokenDimension(e))return e;const t=toLowerCaseAZ(e[4].unit),r=o[t];if(t===r)return e;const i=C.get(t);if(!i)return e;const u=i.get(r);if(!u)return e;const a=u(e[4].value),s=[n.TokenType.Dimension,"",e[2],e[3],{...e[4],signCharacter:a<0?"-":void 0,type:Number.isInteger(a)?n.NumberType.Integer:n.NumberType.Number,value:a}];return n.mutateUnit(s,r),s}function addition(t){if(2!==t.length)return-1;const o=t[0].value;let r=t[1].value;if(n.isTokenNumber(o)&&n.isTokenNumber(r)){const t=o[4].value+r[4].value;return new e.TokenNode([n.TokenType.Number,t.toString(),o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number}])}if(n.isTokenPercentage(o)&&n.isTokenPercentage(r)){const t=o[4].value+r[4].value;return new e.TokenNode([n.TokenType.Percentage,t.toString()+"%",o[2],r[3],{value:t}])}if(n.isTokenDimension(o)&&n.isTokenDimension(r)&&(r=convertUnit(o,r),toLowerCaseAZ(o[4].unit)===toLowerCaseAZ(r[4].unit))){const t=o[4].value+r[4].value;return new e.TokenNode([n.TokenType.Dimension,t.toString()+o[4].unit,o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number,unit:o[4].unit}])}return-1}function division(t){if(2!==t.length)return-1;const o=t[0].value,r=t[1].value;if(n.isTokenNumber(o)&&n.isTokenNumber(r)){const t=o[4].value/r[4].value;return new e.TokenNode([n.TokenType.Number,t.toString(),o[2],r[3],{value:t,type:Number.isInteger(t)?n.NumberType.Integer:n.NumberType.Number}])}if(n.isTokenPercentage(o)&&n.isTokenNumber(r)){const t=o[4].value/r[4].value;return new e.TokenNode([n.TokenType.Percentage,t.toString()+"%",o[2],r[3],{value:t}])}if(n.isTokenDimension(o)&&n.isTokenNumber(r)){const t=o[4].value/r[4].value;return new e.TokenNode([n.TokenType.Dimension,t.toString()+o[4].unit,o[2],r[3],{value:t,type:Number.isInteger(t)?n.NumberType.Integer:n.NumberType.Number,unit:o[4].unit}])}return-1}function isCalculation(e){return!!e&&"object"==typeof e&&"inputs"in e&&Array.isArray(e.inputs)&&"operation"in e}function solve(n){if(-1===n)return-1;const t=[];for(let o=0;oconvertUnit(i,e.value)));if(!arrayOfSameNumeric(u))return-1;const a=u.map((e=>e[4].value)),s=Math.hypot(...a);return resultToCalculation(t,i,s)}function solveMax(t,o,r){if(!o.every(e.isTokenNode))return-1;const i=o[0].value;if(!n.isTokenNumeric(i))return-1;if(!r.rawPercentages&&n.isTokenPercentage(i))return-1;const u=o.map((e=>convertUnit(i,e.value)));if(!arrayOfSameNumeric(u))return-1;const a=u.map((e=>e[4].value)),s=Math.max(...a);return resultToCalculation(t,i,s)}function solveMin(t,o,r){if(!o.every(e.isTokenNode))return-1;const i=o[0].value;if(!n.isTokenNumeric(i))return-1;if(!r.rawPercentages&&n.isTokenPercentage(i))return-1;const u=o.map((e=>convertUnit(i,e.value)));if(!arrayOfSameNumeric(u))return-1;const a=u.map((e=>e[4].value)),s=Math.min(...a);return resultToCalculation(t,i,s)}function solveMod(e,t,o){const r=t.value;if(!n.isTokenNumeric(r))return-1;const i=convertUnit(r,o.value);if(!twoOfSameNumeric(r,i))return-1;let u;return u=0===i[4].value?Number.NaN:Number.isFinite(r[4].value)&&(Number.isFinite(i[4].value)||(i[4].value!==Number.POSITIVE_INFINITY||r[4].value!==Number.NEGATIVE_INFINITY&&!Object.is(0*r[4].value,-0))&&(i[4].value!==Number.NEGATIVE_INFINITY||r[4].value!==Number.POSITIVE_INFINITY&&!Object.is(0*r[4].value,0)))?Number.isFinite(i[4].value)?(r[4].value%i[4].value+i[4].value)%i[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solvePow(e,t,o){const r=t.value,i=o.value;if(!n.isTokenNumber(r))return-1;if(!twoOfSameNumeric(r,i))return-1;return numberToCalculation(e,Math.pow(r[4].value,i[4].value))}function solveRem(e,t,o){const r=t.value;if(!n.isTokenNumeric(r))return-1;const i=convertUnit(r,o.value);if(!twoOfSameNumeric(r,i))return-1;let u;return u=0===i[4].value?Number.NaN:Number.isFinite(r[4].value)?Number.isFinite(i[4].value)?r[4].value%i[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solveRound(e,t,o,r,i){const u=o.value;if(!n.isTokenNumeric(u))return-1;if(!i.rawPercentages&&n.isTokenPercentage(u))return-1;const a=convertUnit(u,r.value);if(!twoOfSameNumeric(u,a))return-1;let s;if(0===a[4].value)s=Number.NaN;else if(Number.isFinite(u[4].value)||Number.isFinite(a[4].value))if(!Number.isFinite(u[4].value)&&Number.isFinite(a[4].value))s=u[4].value;else if(Number.isFinite(u[4].value)&&!Number.isFinite(a[4].value))switch(t){case"down":s=u[4].value<0?-1/0:Object.is(-0,0*u[4].value)?-0:0;break;case"up":s=u[4].value>0?1/0:Object.is(0,0*u[4].value)?0:-0;break;default:s=Object.is(0,0*u[4].value)?0:-0}else if(Number.isFinite(a[4].value))switch(t){case"down":s=Math.floor(u[4].value/a[4].value)*a[4].value;break;case"up":s=Math.ceil(u[4].value/a[4].value)*a[4].value;break;case"to-zero":s=Math.trunc(u[4].value/a[4].value)*a[4].value;break;default:{let e=Math.floor(u[4].value/a[4].value)*a[4].value,n=Math.ceil(u[4].value/a[4].value)*a[4].value;if(e>n){const t=e;e=n,n=t}const t=Math.abs(u[4].value-e),o=Math.abs(u[4].value-n);s=t===o?n:t0?1/0:-1/0:Math.tan(s),numberToCalculation(e,s)}function subtraction(t){if(2!==t.length)return-1;const o=t[0].value;let r=t[1].value;if(n.isTokenNumber(o)&&n.isTokenNumber(r)){const t=o[4].value-r[4].value;return new e.TokenNode([n.TokenType.Number,t.toString(),o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number}])}if(n.isTokenPercentage(o)&&n.isTokenPercentage(r)){const t=o[4].value-r[4].value;return new e.TokenNode([n.TokenType.Percentage,t.toString()+"%",o[2],r[3],{value:t}])}if(n.isTokenDimension(o)&&n.isTokenDimension(r)&&(r=convertUnit(o,r),toLowerCaseAZ(o[4].unit)===toLowerCaseAZ(r[4].unit))){const t=o[4].value-r[4].value;return new e.TokenNode([n.TokenType.Dimension,t.toString()+o[4].unit,o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number,unit:o[4].unit}])}return-1}function solveLog(t,o){if(1===o.length){const r=o[0];if(!r||!e.isTokenNode(r))return-1;const i=r.value;if(!n.isTokenNumber(i))return-1;return numberToCalculation(t,Math.log(i[4].value))}if(2===o.length){const r=o[0];if(!r||!e.isTokenNode(r))return-1;const i=r.value;if(!n.isTokenNumber(i))return-1;const u=o[1];if(!u||!e.isTokenNode(u))return-1;const a=u.value;if(!n.isTokenNumber(a))return-1;return numberToCalculation(t,Math.log(i[4].value)/Math.log(a[4].value))}return-1}const g=/^none$/i;function isNone(t){if(Array.isArray(t)){const n=t.filter((n=>!(e.isWhitespaceNode(n)&&e.isCommentNode(n))));return 1===n.length&&isNone(n[0])}if(!e.isTokenNode(t))return!1;const o=t.value;return!!n.isTokenIdent(o)&&g.test(o[4].value)}function solveRandom(e,t,o,r,i,u){const a=o.value;if(!n.isTokenNumeric(a))return-1;const s=convertUnit(a,r.value);if(!twoOfSameNumeric(a,s))return-1;let l,c=null;if(i&&(c=convertUnit(a,i.value),!twoOfSameNumeric(a,c)))return-1;if(Number.isFinite(a[4].value))if(Number.isFinite(s[4].value))if(Number.isFinite(s[4].value-a[4].value))if(c&&!Number.isFinite(c[4].value))l=a[4].value;else{const e=sfc32(crc32([t,n.stringify(a),n.stringify(s),i?`by ${i.toString()}`:""].join(",")),u.randomSeed);let o=a[4].value,r=s[4].value;if(o>r&&([o,r]=[r,o]),c&&(c[4].value<=0||Math.abs(o-r)/c[4].value>1e10)&&(c=null),c){const n=Math.abs(o-r),t=e();l=o+Math.floor(n/c[4].value*t)*c[4].value}else{const n=e();l=Number((n*(r-o)+o).toFixed(5))}}else l=Number.NaN;else l=Number.NaN;else l=Number.NaN;return resultToCalculation(e,a,l)}function sfc32(e=.34944106645296036,n=.19228640875738723,t=.8784393832007205,o=.04850964319275053){return()=>{const r=((e|=0)+(n|=0)|0)+(o|=0)|0;return o=o+1|0,e=n^n>>>9,n=(t|=0)+(t<<3)|0,t=(t=t<<21|t>>>11)+r|0,(r>>>0)/4294967296}}function crc32(e){let n=0,t=0,o=0;n=~n;for(let r=0,i=e.length;r>>8^t;return~n>>>0}const b=new Map([["abs",function abs(e,n,t){return singleNodeSolver(e,n,t,solveAbs)}],["acos",function acos(e,n,t){return singleNodeSolver(e,n,t,solveACos)}],["asin",function asin(e,n,t){return singleNodeSolver(e,n,t,solveASin)}],["atan",function atan(e,n,t){return singleNodeSolver(e,n,t,solveATan)}],["atan2",function atan2(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveATan2)}],["calc",calc$1],["clamp",function clamp(t,o,r){const i=resolveGlobalsAndConstants([...t.value.filter((n=>!e.isWhiteSpaceOrCommentNode(n)))],o),u=[],a=[],s=[];{let t=u;for(let o=0;o!e.isWhiteSpaceOrCommentNode(n)));let u="";const a=[],s=[];for(let t=0;t0&&e.isTokenNode(o)&&n.isTokenIdent(o.value)){const e=o.value[4].value.toLowerCase();if("by"===e||e.startsWith("--")){a.push(...i.slice(t+2));break}}}s.push(o)}const l=twoCommaSeparatedArguments(s,o,r);if(-1===l)return-1;const[c,m]=l;let v=null;if(a.length&&(v=singleArgument(a,o,r),-1===v))return-1;return solveRandom(t,u,c,m,v,r)}],["rem",function rem(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveRem)}],["round",function round(t,o,r){const i=resolveGlobalsAndConstants([...t.value.filter((n=>!e.isWhiteSpaceOrCommentNode(n)))],o);let u="",a=!1;const s=[],l=[];{let t=s;for(let o=0;o!e.isWhiteSpaceOrCommentNode(n)))],o);if(1===i.length&&e.isTokenNode(i[0]))return{inputs:[i[0]],operation:unary};let u=0;for(;u!e.isWhiteSpaceOrCommentNode(n)))],t)),t,o));return-1===r?-1:r}function twoCommaSeparatedNodesSolver(e,n,t,o){const r=twoCommaSeparatedArguments(e.value,n,t);if(-1===r)return-1;const[i,u]=r;return o(e,i,u,t)}function twoCommaSeparatedArguments(t,o,r){const i=resolveGlobalsAndConstants([...t.filter((n=>!e.isWhiteSpaceOrCommentNode(n)))],o),u=[],a=[];{let t=u;for(let o=0;o!e.isWhiteSpaceOrCommentNode(n)))],o),u=[];{const t=[];let a=[];for(let o=0;o{if(!e.isFunctionNode(n))return;const r=b.get(n.getName().toLowerCase());if(!r)return;const i=patchCalcResult(solve(r(n,o,t??{})),t);return-1!==i?i:void 0}))}const y=new Set(b.keys());exports.calc=function calc(t,o){return calcFromComponentValues(e.parseCommaSeparatedListOfComponentValues(n.tokenize({css:t}),{}),o).map((e=>e.map((e=>n.stringify(...e.tokens()))).join(""))).join(",")},exports.calcFromComponentValues=calcFromComponentValues,exports.mathFunctionNames=y; +"use strict";var e=require("@csstools/css-parser-algorithms"),n=require("@csstools/css-tokenizer");const t=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(t,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}const o={cm:"px",in:"px",mm:"px",pc:"px",pt:"px",px:"px",q:"px",deg:"deg",grad:"deg",rad:"deg",turn:"deg",ms:"s",s:"s",hz:"hz",khz:"hz"},r=new Map([["cm",e=>e],["mm",e=>10*e],["q",e=>40*e],["in",e=>e/2.54],["pc",e=>e/2.54*6],["pt",e=>e/2.54*72],["px",e=>e/2.54*96]]),i=new Map([["deg",e=>e],["grad",e=>e/.9],["rad",e=>e/180*Math.PI],["turn",e=>e/360]]),u=new Map([["deg",e=>.9*e],["grad",e=>e],["rad",e=>.9*e/180*Math.PI],["turn",e=>.9*e/360]]),a=new Map([["hz",e=>e],["khz",e=>e/1e3]]),s=new Map([["cm",e=>2.54*e],["mm",e=>25.4*e],["q",e=>25.4*e*4],["in",e=>e],["pc",e=>6*e],["pt",e=>72*e],["px",e=>96*e]]),l=new Map([["hz",e=>1e3*e],["khz",e=>e]]),c=new Map([["cm",e=>e/10],["mm",e=>e],["q",e=>4*e],["in",e=>e/25.4],["pc",e=>e/25.4*6],["pt",e=>e/25.4*72],["px",e=>e/25.4*96]]),m=new Map([["ms",e=>e],["s",e=>e/1e3]]),v=new Map([["cm",e=>e/6*2.54],["mm",e=>e/6*25.4],["q",e=>e/6*25.4*4],["in",e=>e/6],["pc",e=>e],["pt",e=>e/6*72],["px",e=>e/6*96]]),T=new Map([["cm",e=>e/72*2.54],["mm",e=>e/72*25.4],["q",e=>e/72*25.4*4],["in",e=>e/72],["pc",e=>e/72*6],["pt",e=>e],["px",e=>e/72*96]]),p=new Map([["cm",e=>e/96*2.54],["mm",e=>e/96*25.4],["q",e=>e/96*25.4*4],["in",e=>e/96],["pc",e=>e/96*6],["pt",e=>e/96*72],["px",e=>e]]),N=new Map([["cm",e=>e/4/10],["mm",e=>e/4],["q",e=>e],["in",e=>e/4/25.4],["pc",e=>e/4/25.4*6],["pt",e=>e/4/25.4*72],["px",e=>e/4/25.4*96]]),f=new Map([["deg",e=>180*e/Math.PI],["grad",e=>180*e/Math.PI/.9],["rad",e=>e],["turn",e=>180*e/Math.PI/360]]),d=new Map([["ms",e=>1e3*e],["s",e=>e]]),k=new Map([["deg",e=>360*e],["grad",e=>360*e/.9],["rad",e=>360*e/180*Math.PI],["turn",e=>e]]),C=new Map([["cm",r],["mm",c],["q",N],["in",s],["pc",v],["pt",T],["px",p],["ms",m],["s",d],["deg",i],["grad",u],["rad",f],["turn",k],["hz",a],["khz",l]]);function convertUnit(e,t){if(!n.isTokenDimension(e))return t;if(!n.isTokenDimension(t))return t;const o=toLowerCaseAZ(e[4].unit),r=toLowerCaseAZ(t[4].unit);if(o===r)return t;const i=C.get(r);if(!i)return t;const u=i.get(o);if(!u)return t;const a=u(t[4].value),s=[n.TokenType.Dimension,"",t[2],t[3],{...t[4],signCharacter:a<0?"-":void 0,type:Number.isInteger(a)?n.NumberType.Integer:n.NumberType.Number,value:a}];return n.mutateUnit(s,e[4].unit),s}function toCanonicalUnit(e){if(!n.isTokenDimension(e))return e;const t=toLowerCaseAZ(e[4].unit),r=o[t];if(t===r)return e;const i=C.get(t);if(!i)return e;const u=i.get(r);if(!u)return e;const a=u(e[4].value),s=[n.TokenType.Dimension,"",e[2],e[3],{...e[4],signCharacter:a<0?"-":void 0,type:Number.isInteger(a)?n.NumberType.Integer:n.NumberType.Number,value:a}];return n.mutateUnit(s,r),s}function addition(t){if(2!==t.length)return-1;const o=t[0].value;let r=t[1].value;if(n.isTokenNumber(o)&&n.isTokenNumber(r)){const t=o[4].value+r[4].value;return new e.TokenNode([n.TokenType.Number,t.toString(),o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number}])}if(n.isTokenPercentage(o)&&n.isTokenPercentage(r)){const t=o[4].value+r[4].value;return new e.TokenNode([n.TokenType.Percentage,t.toString()+"%",o[2],r[3],{value:t}])}if(n.isTokenDimension(o)&&n.isTokenDimension(r)&&(r=convertUnit(o,r),toLowerCaseAZ(o[4].unit)===toLowerCaseAZ(r[4].unit))){const t=o[4].value+r[4].value;return new e.TokenNode([n.TokenType.Dimension,t.toString()+o[4].unit,o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number,unit:o[4].unit}])}return-1}function division(t){if(2!==t.length)return-1;const o=t[0].value,r=t[1].value;if(n.isTokenNumber(o)&&n.isTokenNumber(r)){const t=o[4].value/r[4].value;return new e.TokenNode([n.TokenType.Number,t.toString(),o[2],r[3],{value:t,type:Number.isInteger(t)?n.NumberType.Integer:n.NumberType.Number}])}if(n.isTokenPercentage(o)&&n.isTokenNumber(r)){const t=o[4].value/r[4].value;return new e.TokenNode([n.TokenType.Percentage,t.toString()+"%",o[2],r[3],{value:t}])}if(n.isTokenDimension(o)&&n.isTokenNumber(r)){const t=o[4].value/r[4].value;return new e.TokenNode([n.TokenType.Dimension,t.toString()+o[4].unit,o[2],r[3],{value:t,type:Number.isInteger(t)?n.NumberType.Integer:n.NumberType.Number,unit:o[4].unit}])}return-1}function isCalculation(e){return!!e&&"object"==typeof e&&"inputs"in e&&Array.isArray(e.inputs)&&"operation"in e}function solve(n){if(-1===n)return-1;const t=[];for(let o=0;oconvertUnit(i,e.value)));if(!arrayOfSameNumeric(u))return-1;const a=u.map((e=>e[4].value)),s=Math.hypot(...a);return resultToCalculation(t,i,s)}function solveMax(t,o,r){if(!o.every(e.isTokenNode))return-1;const i=o[0].value;if(!n.isTokenNumeric(i))return-1;if(!r.rawPercentages&&n.isTokenPercentage(i))return-1;const u=o.map((e=>convertUnit(i,e.value)));if(!arrayOfSameNumeric(u))return-1;const a=u.map((e=>e[4].value)),s=Math.max(...a);return resultToCalculation(t,i,s)}function solveMin(t,o,r){if(!o.every(e.isTokenNode))return-1;const i=o[0].value;if(!n.isTokenNumeric(i))return-1;if(!r.rawPercentages&&n.isTokenPercentage(i))return-1;const u=o.map((e=>convertUnit(i,e.value)));if(!arrayOfSameNumeric(u))return-1;const a=u.map((e=>e[4].value)),s=Math.min(...a);return resultToCalculation(t,i,s)}function solveMod(e,t,o){const r=t.value;if(!n.isTokenNumeric(r))return-1;const i=convertUnit(r,o.value);if(!twoOfSameNumeric(r,i))return-1;let u;return u=0===i[4].value?Number.NaN:Number.isFinite(r[4].value)&&(Number.isFinite(i[4].value)||(i[4].value!==Number.POSITIVE_INFINITY||r[4].value!==Number.NEGATIVE_INFINITY&&!Object.is(0*r[4].value,-0))&&(i[4].value!==Number.NEGATIVE_INFINITY||r[4].value!==Number.POSITIVE_INFINITY&&!Object.is(0*r[4].value,0)))?Number.isFinite(i[4].value)?(r[4].value%i[4].value+i[4].value)%i[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solvePow(e,t,o){const r=t.value,i=o.value;if(!n.isTokenNumber(r))return-1;if(!twoOfSameNumeric(r,i))return-1;return numberToCalculation(e,Math.pow(r[4].value,i[4].value))}function solveRem(e,t,o){const r=t.value;if(!n.isTokenNumeric(r))return-1;const i=convertUnit(r,o.value);if(!twoOfSameNumeric(r,i))return-1;let u;return u=0===i[4].value?Number.NaN:Number.isFinite(r[4].value)?Number.isFinite(i[4].value)?r[4].value%i[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solveRound(e,t,o,r,i){const u=o.value;if(!n.isTokenNumeric(u))return-1;if(!i.rawPercentages&&n.isTokenPercentage(u))return-1;const a=convertUnit(u,r.value);if(!twoOfSameNumeric(u,a))return-1;let s;if(0===a[4].value)s=Number.NaN;else if(Number.isFinite(u[4].value)||Number.isFinite(a[4].value))if(!Number.isFinite(u[4].value)&&Number.isFinite(a[4].value))s=u[4].value;else if(Number.isFinite(u[4].value)&&!Number.isFinite(a[4].value))switch(t){case"down":s=u[4].value<0?-1/0:Object.is(-0,0*u[4].value)?-0:0;break;case"up":s=u[4].value>0?1/0:Object.is(0,0*u[4].value)?0:-0;break;default:s=Object.is(0,0*u[4].value)?0:-0}else if(Number.isFinite(a[4].value))switch(t){case"down":s=Math.floor(u[4].value/a[4].value)*a[4].value;break;case"up":s=Math.ceil(u[4].value/a[4].value)*a[4].value;break;case"to-zero":s=Math.trunc(u[4].value/a[4].value)*a[4].value;break;default:{let e=Math.floor(u[4].value/a[4].value)*a[4].value,n=Math.ceil(u[4].value/a[4].value)*a[4].value;if(e>n){const t=e;e=n,n=t}const t=Math.abs(u[4].value-e),o=Math.abs(u[4].value-n);s=t===o?n:t0?1/0:-1/0:Math.tan(s),numberToCalculation(e,s)}function subtraction(t){if(2!==t.length)return-1;const o=t[0].value;let r=t[1].value;if(n.isTokenNumber(o)&&n.isTokenNumber(r)){const t=o[4].value-r[4].value;return new e.TokenNode([n.TokenType.Number,t.toString(),o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number}])}if(n.isTokenPercentage(o)&&n.isTokenPercentage(r)){const t=o[4].value-r[4].value;return new e.TokenNode([n.TokenType.Percentage,t.toString()+"%",o[2],r[3],{value:t}])}if(n.isTokenDimension(o)&&n.isTokenDimension(r)&&(r=convertUnit(o,r),toLowerCaseAZ(o[4].unit)===toLowerCaseAZ(r[4].unit))){const t=o[4].value-r[4].value;return new e.TokenNode([n.TokenType.Dimension,t.toString()+o[4].unit,o[2],r[3],{value:t,type:o[4].type===n.NumberType.Integer&&r[4].type===n.NumberType.Integer?n.NumberType.Integer:n.NumberType.Number,unit:o[4].unit}])}return-1}function solveLog(t,o){if(1===o.length){const r=o[0];if(!r||!e.isTokenNode(r))return-1;const i=r.value;if(!n.isTokenNumber(i))return-1;return numberToCalculation(t,Math.log(i[4].value))}if(2===o.length){const r=o[0];if(!r||!e.isTokenNode(r))return-1;const i=r.value;if(!n.isTokenNumber(i))return-1;const u=o[1];if(!u||!e.isTokenNode(u))return-1;const a=u.value;if(!n.isTokenNumber(a))return-1;return numberToCalculation(t,Math.log(i[4].value)/Math.log(a[4].value))}return-1}const g=/^none$/i;function isNone(t){if(Array.isArray(t)){const n=t.filter((n=>!(e.isWhitespaceNode(n)&&e.isCommentNode(n))));return 1===n.length&&isNone(n[0])}if(!e.isTokenNode(t))return!1;const o=t.value;return!!n.isTokenIdent(o)&&g.test(o[4].value)}const D=String.fromCodePoint(0);function solveRandom(e,t,o,r,i,u){if(-1===t.fixed&&!u.randomCaching)return-1;u.randomCaching||(u.randomCaching={propertyName:"",propertyN:0,elementID:"",documentID:""}),u.randomCaching&&!u.randomCaching.propertyN&&(u.randomCaching.propertyN=0);const a=o.value;if(!n.isTokenNumeric(a))return-1;const s=convertUnit(a,r.value);if(!twoOfSameNumeric(a,s))return-1;let l=null;if(i&&(l=convertUnit(a,i.value),!twoOfSameNumeric(a,l)))return-1;if(!Number.isFinite(a[4].value))return resultToCalculation(e,a,Number.NaN);if(!Number.isFinite(s[4].value))return resultToCalculation(e,a,Number.NaN);if(!Number.isFinite(s[4].value-a[4].value))return resultToCalculation(e,a,Number.NaN);if(l&&!Number.isFinite(l[4].value))return resultToCalculation(e,a,a[4].value);const c=-1===t.fixed?sfc32(crc32([t.dashedIdent?t.dashedIdent:`${u.randomCaching?.propertyName} ${u.randomCaching.propertyN++}`,t.elementShared?"":u.randomCaching.elementID,u.randomCaching.documentID].join(D))):()=>t.fixed;let m=a[4].value,v=s[4].value;if(m>v&&([m,v]=[v,m]),l&&(l[4].value<=0||Math.abs(m-v)/l[4].value>1e10)&&(l=null),l){const n=Math.max(l[4].value/1e3,1e-9),t=[m];let o=0;for(;;){o+=l[4].value;const e=m+o;if(!(e+nv)break}const r=c();return resultToCalculation(e,a,Number(t[Math.floor(t.length*r)].toFixed(5)))}const T=c();return resultToCalculation(e,a,Number((T*(v-m)+m).toFixed(5)))}function sfc32(e=.34944106645296036,n=.19228640875738723,t=.8784393832007205,o=.04850964319275053){return()=>{const r=((e|=0)+(n|=0)|0)+(o|=0)|0;return o=o+1|0,e=n^n>>>9,n=(t|=0)+(t<<3)|0,t=(t=t<<21|t>>>11)+r|0,(r>>>0)/4294967296}}function crc32(e){let n=0,t=0,o=0;n=~n;for(let r=0,i=e.length;r>>8^t;return~n>>>0}const b=new Map([["abs",function abs(e,n,t){return singleNodeSolver(e,n,t,solveAbs)}],["acos",function acos(e,n,t){return singleNodeSolver(e,n,t,solveACos)}],["asin",function asin(e,n,t){return singleNodeSolver(e,n,t,solveASin)}],["atan",function atan(e,n,t){return singleNodeSolver(e,n,t,solveATan)}],["atan2",function atan2(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveATan2)}],["calc",calc$1],["clamp",function clamp(t,o,r){const i=resolveGlobalsAndConstants([...t.value.filter((n=>!e.isWhiteSpaceOrCommentNode(n)))],o),u=[],a=[],s=[];{let t=u;for(let o=0;o!e.isWhiteSpaceOrCommentNode(n))),t,o);if(-1===r)return-1;const[i,u]=r,a=variadicArguments(u,t,o);if(-1===a)return-1;const[s,l,c]=a;if(!s||!l)return-1;return solveRandom(n,i,s,l,c,o)}],["rem",function rem(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveRem)}],["round",function round(t,o,r){const i=resolveGlobalsAndConstants([...t.value.filter((n=>!e.isWhiteSpaceOrCommentNode(n)))],o);let u="",a=!1;const s=[],l=[];{let t=s;for(let o=0;o!e.isWhiteSpaceOrCommentNode(n)))],o);if(1===i.length&&e.isTokenNode(i[0]))return{inputs:[i[0]],operation:unary};let u=0;for(;u!e.isWhiteSpaceOrCommentNode(n)))],t)),t,o));return-1===r?-1:r}function twoCommaSeparatedNodesSolver(e,n,t,o){const r=twoCommaSeparatedArguments(e.value,n,t);if(-1===r)return-1;const[i,u]=r;return o(e,i,u,t)}function twoCommaSeparatedArguments(t,o,r){const i=resolveGlobalsAndConstants([...t.filter((n=>!e.isWhiteSpaceOrCommentNode(n)))],o),u=[],a=[];{let t=u;for(let o=0;o!e.isWhiteSpaceOrCommentNode(n)))],o),u=[];{const t=[];let a=[];for(let o=0;o1)return-1;i.fixed=Math.max(0,Math.min(a.value[4].value,1-1e-9))}else{if(-1!==i.fixed)return-1;i.elementShared=!0}}return-1}function calcWrapper(t){return new e.FunctionNode([n.TokenType.Function,"calc(",-1,-1,{value:"calc"}],[n.TokenType.CloseParen,")",-1,-1,void 0],t)}function maxWrapper(t,o){return new e.FunctionNode([n.TokenType.Function,"max(",-1,-1,{value:"max"}],[n.TokenType.CloseParen,")",-1,-1,void 0],[t,new e.TokenNode([n.TokenType.Comma,",",-1,-1,void 0]),o])}function patchNaN(t){if(-1===t)return-1;if(e.isFunctionNode(t))return t;const o=t.value;return n.isTokenNumeric(o)&&Number.isNaN(o[4].value)?n.isTokenNumber(o)?new e.FunctionNode([n.TokenType.Function,"calc(",o[2],o[3],{value:"calc"}],[n.TokenType.CloseParen,")",o[2],o[3],void 0],[new e.TokenNode([n.TokenType.Ident,"NaN",o[2],o[3],{value:"NaN"}])]):n.isTokenDimension(o)?new e.FunctionNode([n.TokenType.Function,"calc(",o[2],o[3],{value:"calc"}],[n.TokenType.CloseParen,")",o[2],o[3],void 0],[new e.TokenNode([n.TokenType.Ident,"NaN",o[2],o[3],{value:"NaN"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Delim,"*",o[2],o[3],{value:"*"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Dimension,"1"+o[4].unit,o[2],o[3],{value:1,type:n.NumberType.Integer,unit:o[4].unit}])]):n.isTokenPercentage(o)?new e.FunctionNode([n.TokenType.Function,"calc(",o[2],o[3],{value:"calc"}],[n.TokenType.CloseParen,")",o[2],o[3],void 0],[new e.TokenNode([n.TokenType.Ident,"NaN",o[2],o[3],{value:"NaN"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Delim,"*",o[2],o[3],{value:"*"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Percentage,"1%",o[2],o[3],{value:1}])]):-1:t}function patchInfinity(t){if(-1===t)return-1;if(e.isFunctionNode(t))return t;const o=t.value;if(!n.isTokenNumeric(o))return t;if(Number.isFinite(o[4].value)||Number.isNaN(o[4].value))return t;let r="";return Number.NEGATIVE_INFINITY===o[4].value&&(r="-"),n.isTokenNumber(o)?new e.FunctionNode([n.TokenType.Function,"calc(",o[2],o[3],{value:"calc"}],[n.TokenType.CloseParen,")",o[2],o[3],void 0],[new e.TokenNode([n.TokenType.Ident,r+"infinity",o[2],o[3],{value:r+"infinity"}])]):n.isTokenDimension(o)?new e.FunctionNode([n.TokenType.Function,"calc(",o[2],o[3],{value:"calc"}],[n.TokenType.CloseParen,")",o[2],o[3],void 0],[new e.TokenNode([n.TokenType.Ident,r+"infinity",o[2],o[3],{value:r+"infinity"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Delim,"*",o[2],o[3],{value:"*"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Dimension,"1"+o[4].unit,o[2],o[3],{value:1,type:n.NumberType.Integer,unit:o[4].unit}])]):new e.FunctionNode([n.TokenType.Function,"calc(",o[2],o[3],{value:"calc"}],[n.TokenType.CloseParen,")",o[2],o[3],void 0],[new e.TokenNode([n.TokenType.Ident,r+"infinity",o[2],o[3],{value:r+"infinity"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Delim,"*",o[2],o[3],{value:"*"}]),new e.WhitespaceNode([[n.TokenType.Whitespace," ",o[2],o[3],void 0]]),new e.TokenNode([n.TokenType.Percentage,"1%",o[2],o[3],{value:1}])])}function patchMinusZero(t){if(-1===t)return-1;if(e.isFunctionNode(t))return t;const o=t.value;return n.isTokenNumeric(o)&&Object.is(-0,o[4].value)?("-0"===o[1]||(n.isTokenPercentage(o)?o[1]="-0%":n.isTokenDimension(o)?o[1]="-0"+o[4].unit:o[1]="-0"),t):t}function patchPrecision(t,o=13){if(-1===t)return-1;if(o<=0)return t;if(e.isFunctionNode(t))return t;const r=t.value;if(!n.isTokenNumeric(r))return t;if(Number.isInteger(r[4].value))return t;const i=Number(r[4].value.toFixed(o)).toString();return n.isTokenNumber(r)?r[1]=i:n.isTokenPercentage(r)?r[1]=i+"%":n.isTokenDimension(r)&&(r[1]=i+r[4].unit),t}function patchCanonicalUnit(t){return-1===t?-1:e.isFunctionNode(t)?t:n.isTokenDimension(t.value)?(t.value=toCanonicalUnit(t.value),t):t}function patchCalcResult(e,n){let t=e;return n?.toCanonicalUnits&&(t=patchCanonicalUnit(t)),t=patchPrecision(t,n?.precision),t=patchMinusZero(t),n?.censorIntoStandardRepresentableValues||(t=patchNaN(t),t=patchInfinity(t)),t}function tokenizeGlobals(e){const t=new Map;if(!e)return t;for(const[o,r]of e)if(n.isToken(r))t.set(o,r);else if("string"!=typeof r);else{const e=n.tokenizer({css:r}),i=e.nextToken();if(e.nextToken(),!e.endOfFile())continue;if(!n.isTokenNumeric(i))continue;t.set(o,i)}return t}function calcFromComponentValues(n,t){const o=tokenizeGlobals(t?.globals);return e.replaceComponentValues(n,(n=>{if(!e.isFunctionNode(n))return;const r=b.get(n.getName().toLowerCase());if(!r)return;const i=patchCalcResult(solve(r(n,o,t??{})),t);return-1!==i?i:void 0}))}const h=new Set(b.keys());exports.calc=function calc(t,o){return calcFromComponentValues(e.parseCommaSeparatedListOfComponentValues(n.tokenize({css:t}),{}),o).map((e=>e.map((e=>n.stringify(...e.tokens()))).join(""))).join(",")},exports.calcFromComponentValues=calcFromComponentValues,exports.mathFunctionNames=h; diff --git a/packages/css-calc/dist/index.d.ts b/packages/css-calc/dist/index.d.ts index 0dc9c621f4..246c78553a 100644 --- a/packages/css-calc/dist/index.d.ts +++ b/packages/css-calc/dist/index.d.ts @@ -40,9 +40,28 @@ export declare type conversionOptions = { */ rawPercentages?: boolean; /** - * Seed the pseudo random number generator used in `random()` + * The values used to generate random value cache keys. */ - randomSeed?: number; + randomCaching?: { + /** + * The name of the property the random function is used in. + */ + propertyName: string; + /** + * N is the index of the random function among other random functions in the same property value. + */ + propertyN: number; + /** + * An element ID identifying the element the style is being applied to. + * When omitted any `random()` call will not be computed. + */ + elementID: string; + /** + * A document ID identifying the Document the styles are from. + * When omitted any `random()` call will not be computed. + */ + documentID: string; + }; }; export declare type GlobalsWithStrings = Map; diff --git a/packages/css-calc/dist/index.mjs b/packages/css-calc/dist/index.mjs index b8534d1d44..e3d9e790e0 100644 --- a/packages/css-calc/dist/index.mjs +++ b/packages/css-calc/dist/index.mjs @@ -1 +1 @@ -import{TokenNode as e,isTokenNode as n,isWhitespaceNode as t,isCommentNode as r,isWhiteSpaceOrCommentNode as u,isSimpleBlockNode as a,isFunctionNode as i,FunctionNode as o,WhitespaceNode as l,parseCommaSeparatedListOfComponentValues as s,replaceComponentValues as c}from"@csstools/css-parser-algorithms";import{isTokenDimension as v,TokenType as f,NumberType as m,mutateUnit as p,isTokenNumber as C,isTokenPercentage as g,isTokenIdent as D,isTokenNumeric as B,stringify as N,isTokenOpenParen as A,isTokenDelim as d,isTokenComma as F,isToken as b,tokenizer as h,tokenize as w}from"@csstools/css-tokenizer";const E=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(E,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}const S={cm:"px",in:"px",mm:"px",pc:"px",pt:"px",px:"px",q:"px",deg:"deg",grad:"deg",rad:"deg",turn:"deg",ms:"s",s:"s",hz:"hz",khz:"hz"},I=new Map([["cm",e=>e],["mm",e=>10*e],["q",e=>40*e],["in",e=>e/2.54],["pc",e=>e/2.54*6],["pt",e=>e/2.54*72],["px",e=>e/2.54*96]]),y=new Map([["deg",e=>e],["grad",e=>e/.9],["rad",e=>e/180*Math.PI],["turn",e=>e/360]]),M=new Map([["deg",e=>.9*e],["grad",e=>e],["rad",e=>.9*e/180*Math.PI],["turn",e=>.9*e/360]]),T=new Map([["hz",e=>e],["khz",e=>e/1e3]]),k=new Map([["cm",e=>2.54*e],["mm",e=>25.4*e],["q",e=>25.4*e*4],["in",e=>e],["pc",e=>6*e],["pt",e=>72*e],["px",e=>96*e]]),x=new Map([["hz",e=>1e3*e],["khz",e=>e]]),P=new Map([["cm",e=>e/10],["mm",e=>e],["q",e=>4*e],["in",e=>e/25.4],["pc",e=>e/25.4*6],["pt",e=>e/25.4*72],["px",e=>e/25.4*96]]),O=new Map([["ms",e=>e],["s",e=>e/1e3]]),W=new Map([["cm",e=>e/6*2.54],["mm",e=>e/6*25.4],["q",e=>e/6*25.4*4],["in",e=>e/6],["pc",e=>e],["pt",e=>e/6*72],["px",e=>e/6*96]]),L=new Map([["cm",e=>e/72*2.54],["mm",e=>e/72*25.4],["q",e=>e/72*25.4*4],["in",e=>e/72],["pc",e=>e/72*6],["pt",e=>e],["px",e=>e/72*96]]),U=new Map([["cm",e=>e/96*2.54],["mm",e=>e/96*25.4],["q",e=>e/96*25.4*4],["in",e=>e/96],["pc",e=>e/96*6],["pt",e=>e/96*72],["px",e=>e]]),Z=new Map([["cm",e=>e/4/10],["mm",e=>e/4],["q",e=>e],["in",e=>e/4/25.4],["pc",e=>e/4/25.4*6],["pt",e=>e/4/25.4*72],["px",e=>e/4/25.4*96]]),$=new Map([["deg",e=>180*e/Math.PI],["grad",e=>180*e/Math.PI/.9],["rad",e=>e],["turn",e=>180*e/Math.PI/360]]),z=new Map([["ms",e=>1e3*e],["s",e=>e]]),q=new Map([["deg",e=>360*e],["grad",e=>360*e/.9],["rad",e=>360*e/180*Math.PI],["turn",e=>e]]),G=new Map([["cm",I],["mm",P],["q",Z],["in",k],["pc",W],["pt",L],["px",U],["ms",O],["s",z],["deg",y],["grad",M],["rad",$],["turn",q],["hz",T],["khz",x]]);function convertUnit(e,n){if(!v(e))return n;if(!v(n))return n;const t=toLowerCaseAZ(e[4].unit),r=toLowerCaseAZ(n[4].unit);if(t===r)return n;const u=G.get(r);if(!u)return n;const a=u.get(t);if(!a)return n;const i=a(n[4].value),o=[f.Dimension,"",n[2],n[3],{...n[4],signCharacter:i<0?"-":void 0,type:Number.isInteger(i)?m.Integer:m.Number,value:i}];return p(o,e[4].unit),o}function toCanonicalUnit(e){if(!v(e))return e;const n=toLowerCaseAZ(e[4].unit),t=S[n];if(n===t)return e;const r=G.get(n);if(!r)return e;const u=r.get(t);if(!u)return e;const a=u(e[4].value),i=[f.Dimension,"",e[2],e[3],{...e[4],signCharacter:a<0?"-":void 0,type:Number.isInteger(a)?m.Integer:m.Number,value:a}];return p(i,t),i}function addition(n){if(2!==n.length)return-1;const t=n[0].value;let r=n[1].value;if(C(t)&&C(r)){const n=t[4].value+r[4].value;return new e([f.Number,n.toString(),t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number}])}if(g(t)&&g(r)){const n=t[4].value+r[4].value;return new e([f.Percentage,n.toString()+"%",t[2],r[3],{value:n}])}if(v(t)&&v(r)&&(r=convertUnit(t,r),toLowerCaseAZ(t[4].unit)===toLowerCaseAZ(r[4].unit))){const n=t[4].value+r[4].value;return new e([f.Dimension,n.toString()+t[4].unit,t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number,unit:t[4].unit}])}return-1}function division(n){if(2!==n.length)return-1;const t=n[0].value,r=n[1].value;if(C(t)&&C(r)){const n=t[4].value/r[4].value;return new e([f.Number,n.toString(),t[2],r[3],{value:n,type:Number.isInteger(n)?m.Integer:m.Number}])}if(g(t)&&C(r)){const n=t[4].value/r[4].value;return new e([f.Percentage,n.toString()+"%",t[2],r[3],{value:n}])}if(v(t)&&C(r)){const n=t[4].value/r[4].value;return new e([f.Dimension,n.toString()+t[4].unit,t[2],r[3],{value:n,type:Number.isInteger(n)?m.Integer:m.Number,unit:t[4].unit}])}return-1}function isCalculation(e){return!!e&&"object"==typeof e&&"inputs"in e&&Array.isArray(e.inputs)&&"operation"in e}function solve(e){if(-1===e)return-1;const t=[];for(let r=0;rconvertUnit(u,e.value)));if(!arrayOfSameNumeric(a))return-1;const i=a.map((e=>e[4].value)),o=Math.hypot(...i);return resultToCalculation(e,u,o)}function solveMax(e,t,r){if(!t.every(n))return-1;const u=t[0].value;if(!B(u))return-1;if(!r.rawPercentages&&g(u))return-1;const a=t.map((e=>convertUnit(u,e.value)));if(!arrayOfSameNumeric(a))return-1;const i=a.map((e=>e[4].value)),o=Math.max(...i);return resultToCalculation(e,u,o)}function solveMin(e,t,r){if(!t.every(n))return-1;const u=t[0].value;if(!B(u))return-1;if(!r.rawPercentages&&g(u))return-1;const a=t.map((e=>convertUnit(u,e.value)));if(!arrayOfSameNumeric(a))return-1;const i=a.map((e=>e[4].value)),o=Math.min(...i);return resultToCalculation(e,u,o)}function solveMod(e,n,t){const r=n.value;if(!B(r))return-1;const u=convertUnit(r,t.value);if(!twoOfSameNumeric(r,u))return-1;let a;return a=0===u[4].value?Number.NaN:Number.isFinite(r[4].value)&&(Number.isFinite(u[4].value)||(u[4].value!==Number.POSITIVE_INFINITY||r[4].value!==Number.NEGATIVE_INFINITY&&!Object.is(0*r[4].value,-0))&&(u[4].value!==Number.NEGATIVE_INFINITY||r[4].value!==Number.POSITIVE_INFINITY&&!Object.is(0*r[4].value,0)))?Number.isFinite(u[4].value)?(r[4].value%u[4].value+u[4].value)%u[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,a)}function solvePow(e,n,t){const r=n.value,u=t.value;if(!C(r))return-1;if(!twoOfSameNumeric(r,u))return-1;return numberToCalculation(e,Math.pow(r[4].value,u[4].value))}function solveRem(e,n,t){const r=n.value;if(!B(r))return-1;const u=convertUnit(r,t.value);if(!twoOfSameNumeric(r,u))return-1;let a;return a=0===u[4].value?Number.NaN:Number.isFinite(r[4].value)?Number.isFinite(u[4].value)?r[4].value%u[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,a)}function solveRound(e,n,t,r,u){const a=t.value;if(!B(a))return-1;if(!u.rawPercentages&&g(a))return-1;const i=convertUnit(a,r.value);if(!twoOfSameNumeric(a,i))return-1;let o;if(0===i[4].value)o=Number.NaN;else if(Number.isFinite(a[4].value)||Number.isFinite(i[4].value))if(!Number.isFinite(a[4].value)&&Number.isFinite(i[4].value))o=a[4].value;else if(Number.isFinite(a[4].value)&&!Number.isFinite(i[4].value))switch(n){case"down":o=a[4].value<0?-1/0:Object.is(-0,0*a[4].value)?-0:0;break;case"up":o=a[4].value>0?1/0:Object.is(0,0*a[4].value)?0:-0;break;default:o=Object.is(0,0*a[4].value)?0:-0}else if(Number.isFinite(i[4].value))switch(n){case"down":o=Math.floor(a[4].value/i[4].value)*i[4].value;break;case"up":o=Math.ceil(a[4].value/i[4].value)*i[4].value;break;case"to-zero":o=Math.trunc(a[4].value/i[4].value)*i[4].value;break;default:{let e=Math.floor(a[4].value/i[4].value)*i[4].value,n=Math.ceil(a[4].value/i[4].value)*i[4].value;if(e>n){const t=e;e=n,n=t}const t=Math.abs(a[4].value-e),r=Math.abs(a[4].value-n);o=t===r?n:t0?1/0:-1/0:Math.tan(a),numberToCalculation(e,a)}function subtraction(n){if(2!==n.length)return-1;const t=n[0].value;let r=n[1].value;if(C(t)&&C(r)){const n=t[4].value-r[4].value;return new e([f.Number,n.toString(),t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number}])}if(g(t)&&g(r)){const n=t[4].value-r[4].value;return new e([f.Percentage,n.toString()+"%",t[2],r[3],{value:n}])}if(v(t)&&v(r)&&(r=convertUnit(t,r),toLowerCaseAZ(t[4].unit)===toLowerCaseAZ(r[4].unit))){const n=t[4].value-r[4].value;return new e([f.Dimension,n.toString()+t[4].unit,t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number,unit:t[4].unit}])}return-1}function solveLog(e,t){if(1===t.length){const r=t[0];if(!r||!n(r))return-1;const u=r.value;if(!C(u))return-1;return numberToCalculation(e,Math.log(u[4].value))}if(2===t.length){const r=t[0];if(!r||!n(r))return-1;const u=r.value;if(!C(u))return-1;const a=t[1];if(!a||!n(a))return-1;const i=a.value;if(!C(i))return-1;return numberToCalculation(e,Math.log(u[4].value)/Math.log(i[4].value))}return-1}const j=/^none$/i;function isNone(e){if(Array.isArray(e)){const n=e.filter((e=>!(t(e)&&r(e))));return 1===n.length&&isNone(n[0])}if(!n(e))return!1;const u=e.value;return!!D(u)&&j.test(u[4].value)}function solveRandom(e,n,t,r,u,a){const i=t.value;if(!B(i))return-1;const o=convertUnit(i,r.value);if(!twoOfSameNumeric(i,o))return-1;let l,s=null;if(u&&(s=convertUnit(i,u.value),!twoOfSameNumeric(i,s)))return-1;if(Number.isFinite(i[4].value))if(Number.isFinite(o[4].value))if(Number.isFinite(o[4].value-i[4].value))if(s&&!Number.isFinite(s[4].value))l=i[4].value;else{const e=sfc32(crc32([n,N(i),N(o),u?`by ${u.toString()}`:""].join(",")),a.randomSeed);let t=i[4].value,r=o[4].value;if(t>r&&([t,r]=[r,t]),s&&(s[4].value<=0||Math.abs(t-r)/s[4].value>1e10)&&(s=null),s){const n=Math.abs(t-r),u=e();l=t+Math.floor(n/s[4].value*u)*s[4].value}else{const n=e();l=Number((n*(r-t)+t).toFixed(5))}}else l=Number.NaN;else l=Number.NaN;else l=Number.NaN;return resultToCalculation(e,i,l)}function sfc32(e=.34944106645296036,n=.19228640875738723,t=.8784393832007205,r=.04850964319275053){return()=>{const u=((e|=0)+(n|=0)|0)+(r|=0)|0;return r=r+1|0,e=n^n>>>9,n=(t|=0)+(t<<3)|0,t=(t=t<<21|t>>>11)+u|0,(u>>>0)/4294967296}}function crc32(e){let n=0,t=0,r=0;n=~n;for(let u=0,a=e.length;u>>8^t;return~n>>>0}const R=new Map([["abs",function abs(e,n,t){return singleNodeSolver(e,n,t,solveAbs)}],["acos",function acos(e,n,t){return singleNodeSolver(e,n,t,solveACos)}],["asin",function asin(e,n,t){return singleNodeSolver(e,n,t,solveASin)}],["atan",function atan(e,n,t){return singleNodeSolver(e,n,t,solveATan)}],["atan2",function atan2(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveATan2)}],["calc",calc$1],["clamp",function clamp(t,r,a){const i=resolveGlobalsAndConstants([...t.value.filter((e=>!u(e)))],r),l=[],s=[],c=[];{let e=l;for(let t=0;t!u(e)));let i="";const o=[],l=[];for(let e=0;e0&&n(t)&&D(t.value)){const n=t.value[4].value.toLowerCase();if("by"===n||n.startsWith("--")){o.push(...a.slice(e+2));break}}}l.push(t)}const s=twoCommaSeparatedArguments(l,t,r);if(-1===s)return-1;const[c,v]=s;let f=null;if(o.length&&(f=singleArgument(o,t,r),-1===f))return-1;return solveRandom(e,i,c,v,f,r)}],["rem",function rem(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveRem)}],["round",function round(t,r,a){const i=resolveGlobalsAndConstants([...t.value.filter((e=>!u(e)))],r);let o="",l=!1;const s=[],c=[];{let e=s;for(let t=0;t!u(e)))],t);if(1===o.length&&n(o[0]))return{inputs:[o[0]],operation:unary};let l=0;for(;l!u(e)))],n)),n,t));return-1===r?-1:r}function twoCommaSeparatedNodesSolver(e,n,t,r){const u=twoCommaSeparatedArguments(e.value,n,t);if(-1===u)return-1;const[a,i]=u;return r(e,a,i,t)}function twoCommaSeparatedArguments(e,t,r){const a=resolveGlobalsAndConstants([...e.filter((e=>!u(e)))],t),i=[],o=[];{let e=i;for(let t=0;t!u(e)))],t),i=[];{const e=[];let u=[];for(let t=0;te.map((e=>N(...e.tokens()))).join(""))).join(",")}function calcFromComponentValues(e,n){const t=tokenizeGlobals(n?.globals);return c(e,(e=>{if(!i(e))return;const r=R.get(e.getName().toLowerCase());if(!r)return;const u=patchCalcResult(solve(r(e,t,n??{})),n);return-1!==u?u:void 0}))}const Y=new Set(R.keys());export{calc,calcFromComponentValues,Y as mathFunctionNames}; +import{TokenNode as e,isTokenNode as n,isWhitespaceNode as t,isCommentNode as r,isWhiteSpaceOrCommentNode as a,isSimpleBlockNode as u,isFunctionNode as i,FunctionNode as o,WhitespaceNode as l,parseCommaSeparatedListOfComponentValues as c,replaceComponentValues as s}from"@csstools/css-parser-algorithms";import{isTokenDimension as v,TokenType as f,NumberType as m,mutateUnit as p,isTokenNumber as C,isTokenPercentage as g,isTokenIdent as d,isTokenNumeric as D,isTokenOpenParen as N,isTokenDelim as B,isTokenComma as A,isToken as h,tokenizer as F,tokenize as b,stringify as w}from"@csstools/css-tokenizer";const E=/[A-Z]/g;function toLowerCaseAZ(e){return e.replace(E,(e=>String.fromCharCode(e.charCodeAt(0)+32)))}const I={cm:"px",in:"px",mm:"px",pc:"px",pt:"px",px:"px",q:"px",deg:"deg",grad:"deg",rad:"deg",turn:"deg",ms:"s",s:"s",hz:"hz",khz:"hz"},S=new Map([["cm",e=>e],["mm",e=>10*e],["q",e=>40*e],["in",e=>e/2.54],["pc",e=>e/2.54*6],["pt",e=>e/2.54*72],["px",e=>e/2.54*96]]),y=new Map([["deg",e=>e],["grad",e=>e/.9],["rad",e=>e/180*Math.PI],["turn",e=>e/360]]),M=new Map([["deg",e=>.9*e],["grad",e=>e],["rad",e=>.9*e/180*Math.PI],["turn",e=>.9*e/360]]),T=new Map([["hz",e=>e],["khz",e=>e/1e3]]),x=new Map([["cm",e=>2.54*e],["mm",e=>25.4*e],["q",e=>25.4*e*4],["in",e=>e],["pc",e=>6*e],["pt",e=>72*e],["px",e=>96*e]]),k=new Map([["hz",e=>1e3*e],["khz",e=>e]]),P=new Map([["cm",e=>e/10],["mm",e=>e],["q",e=>4*e],["in",e=>e/25.4],["pc",e=>e/25.4*6],["pt",e=>e/25.4*72],["px",e=>e/25.4*96]]),O=new Map([["ms",e=>e],["s",e=>e/1e3]]),W=new Map([["cm",e=>e/6*2.54],["mm",e=>e/6*25.4],["q",e=>e/6*25.4*4],["in",e=>e/6],["pc",e=>e],["pt",e=>e/6*72],["px",e=>e/6*96]]),L=new Map([["cm",e=>e/72*2.54],["mm",e=>e/72*25.4],["q",e=>e/72*25.4*4],["in",e=>e/72],["pc",e=>e/72*6],["pt",e=>e],["px",e=>e/72*96]]),U=new Map([["cm",e=>e/96*2.54],["mm",e=>e/96*25.4],["q",e=>e/96*25.4*4],["in",e=>e/96],["pc",e=>e/96*6],["pt",e=>e/96*72],["px",e=>e]]),$=new Map([["cm",e=>e/4/10],["mm",e=>e/4],["q",e=>e],["in",e=>e/4/25.4],["pc",e=>e/4/25.4*6],["pt",e=>e/4/25.4*72],["px",e=>e/4/25.4*96]]),Z=new Map([["deg",e=>180*e/Math.PI],["grad",e=>180*e/Math.PI/.9],["rad",e=>e],["turn",e=>180*e/Math.PI/360]]),z=new Map([["ms",e=>1e3*e],["s",e=>e]]),q=new Map([["deg",e=>360*e],["grad",e=>360*e/.9],["rad",e=>360*e/180*Math.PI],["turn",e=>e]]),G=new Map([["cm",S],["mm",P],["q",$],["in",x],["pc",W],["pt",L],["px",U],["ms",O],["s",z],["deg",y],["grad",M],["rad",Z],["turn",q],["hz",T],["khz",k]]);function convertUnit(e,n){if(!v(e))return n;if(!v(n))return n;const t=toLowerCaseAZ(e[4].unit),r=toLowerCaseAZ(n[4].unit);if(t===r)return n;const a=G.get(r);if(!a)return n;const u=a.get(t);if(!u)return n;const i=u(n[4].value),o=[f.Dimension,"",n[2],n[3],{...n[4],signCharacter:i<0?"-":void 0,type:Number.isInteger(i)?m.Integer:m.Number,value:i}];return p(o,e[4].unit),o}function toCanonicalUnit(e){if(!v(e))return e;const n=toLowerCaseAZ(e[4].unit),t=I[n];if(n===t)return e;const r=G.get(n);if(!r)return e;const a=r.get(t);if(!a)return e;const u=a(e[4].value),i=[f.Dimension,"",e[2],e[3],{...e[4],signCharacter:u<0?"-":void 0,type:Number.isInteger(u)?m.Integer:m.Number,value:u}];return p(i,t),i}function addition(n){if(2!==n.length)return-1;const t=n[0].value;let r=n[1].value;if(C(t)&&C(r)){const n=t[4].value+r[4].value;return new e([f.Number,n.toString(),t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number}])}if(g(t)&&g(r)){const n=t[4].value+r[4].value;return new e([f.Percentage,n.toString()+"%",t[2],r[3],{value:n}])}if(v(t)&&v(r)&&(r=convertUnit(t,r),toLowerCaseAZ(t[4].unit)===toLowerCaseAZ(r[4].unit))){const n=t[4].value+r[4].value;return new e([f.Dimension,n.toString()+t[4].unit,t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number,unit:t[4].unit}])}return-1}function division(n){if(2!==n.length)return-1;const t=n[0].value,r=n[1].value;if(C(t)&&C(r)){const n=t[4].value/r[4].value;return new e([f.Number,n.toString(),t[2],r[3],{value:n,type:Number.isInteger(n)?m.Integer:m.Number}])}if(g(t)&&C(r)){const n=t[4].value/r[4].value;return new e([f.Percentage,n.toString()+"%",t[2],r[3],{value:n}])}if(v(t)&&C(r)){const n=t[4].value/r[4].value;return new e([f.Dimension,n.toString()+t[4].unit,t[2],r[3],{value:n,type:Number.isInteger(n)?m.Integer:m.Number,unit:t[4].unit}])}return-1}function isCalculation(e){return!!e&&"object"==typeof e&&"inputs"in e&&Array.isArray(e.inputs)&&"operation"in e}function solve(e){if(-1===e)return-1;const t=[];for(let r=0;rconvertUnit(a,e.value)));if(!arrayOfSameNumeric(u))return-1;const i=u.map((e=>e[4].value)),o=Math.hypot(...i);return resultToCalculation(e,a,o)}function solveMax(e,t,r){if(!t.every(n))return-1;const a=t[0].value;if(!D(a))return-1;if(!r.rawPercentages&&g(a))return-1;const u=t.map((e=>convertUnit(a,e.value)));if(!arrayOfSameNumeric(u))return-1;const i=u.map((e=>e[4].value)),o=Math.max(...i);return resultToCalculation(e,a,o)}function solveMin(e,t,r){if(!t.every(n))return-1;const a=t[0].value;if(!D(a))return-1;if(!r.rawPercentages&&g(a))return-1;const u=t.map((e=>convertUnit(a,e.value)));if(!arrayOfSameNumeric(u))return-1;const i=u.map((e=>e[4].value)),o=Math.min(...i);return resultToCalculation(e,a,o)}function solveMod(e,n,t){const r=n.value;if(!D(r))return-1;const a=convertUnit(r,t.value);if(!twoOfSameNumeric(r,a))return-1;let u;return u=0===a[4].value?Number.NaN:Number.isFinite(r[4].value)&&(Number.isFinite(a[4].value)||(a[4].value!==Number.POSITIVE_INFINITY||r[4].value!==Number.NEGATIVE_INFINITY&&!Object.is(0*r[4].value,-0))&&(a[4].value!==Number.NEGATIVE_INFINITY||r[4].value!==Number.POSITIVE_INFINITY&&!Object.is(0*r[4].value,0)))?Number.isFinite(a[4].value)?(r[4].value%a[4].value+a[4].value)%a[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solvePow(e,n,t){const r=n.value,a=t.value;if(!C(r))return-1;if(!twoOfSameNumeric(r,a))return-1;return numberToCalculation(e,Math.pow(r[4].value,a[4].value))}function solveRem(e,n,t){const r=n.value;if(!D(r))return-1;const a=convertUnit(r,t.value);if(!twoOfSameNumeric(r,a))return-1;let u;return u=0===a[4].value?Number.NaN:Number.isFinite(r[4].value)?Number.isFinite(a[4].value)?r[4].value%a[4].value:r[4].value:Number.NaN,resultToCalculation(e,r,u)}function solveRound(e,n,t,r,a){const u=t.value;if(!D(u))return-1;if(!a.rawPercentages&&g(u))return-1;const i=convertUnit(u,r.value);if(!twoOfSameNumeric(u,i))return-1;let o;if(0===i[4].value)o=Number.NaN;else if(Number.isFinite(u[4].value)||Number.isFinite(i[4].value))if(!Number.isFinite(u[4].value)&&Number.isFinite(i[4].value))o=u[4].value;else if(Number.isFinite(u[4].value)&&!Number.isFinite(i[4].value))switch(n){case"down":o=u[4].value<0?-1/0:Object.is(-0,0*u[4].value)?-0:0;break;case"up":o=u[4].value>0?1/0:Object.is(0,0*u[4].value)?0:-0;break;default:o=Object.is(0,0*u[4].value)?0:-0}else if(Number.isFinite(i[4].value))switch(n){case"down":o=Math.floor(u[4].value/i[4].value)*i[4].value;break;case"up":o=Math.ceil(u[4].value/i[4].value)*i[4].value;break;case"to-zero":o=Math.trunc(u[4].value/i[4].value)*i[4].value;break;default:{let e=Math.floor(u[4].value/i[4].value)*i[4].value,n=Math.ceil(u[4].value/i[4].value)*i[4].value;if(e>n){const t=e;e=n,n=t}const t=Math.abs(u[4].value-e),r=Math.abs(u[4].value-n);o=t===r?n:t0?1/0:-1/0:Math.tan(u),numberToCalculation(e,u)}function subtraction(n){if(2!==n.length)return-1;const t=n[0].value;let r=n[1].value;if(C(t)&&C(r)){const n=t[4].value-r[4].value;return new e([f.Number,n.toString(),t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number}])}if(g(t)&&g(r)){const n=t[4].value-r[4].value;return new e([f.Percentage,n.toString()+"%",t[2],r[3],{value:n}])}if(v(t)&&v(r)&&(r=convertUnit(t,r),toLowerCaseAZ(t[4].unit)===toLowerCaseAZ(r[4].unit))){const n=t[4].value-r[4].value;return new e([f.Dimension,n.toString()+t[4].unit,t[2],r[3],{value:n,type:t[4].type===m.Integer&&r[4].type===m.Integer?m.Integer:m.Number,unit:t[4].unit}])}return-1}function solveLog(e,t){if(1===t.length){const r=t[0];if(!r||!n(r))return-1;const a=r.value;if(!C(a))return-1;return numberToCalculation(e,Math.log(a[4].value))}if(2===t.length){const r=t[0];if(!r||!n(r))return-1;const a=r.value;if(!C(a))return-1;const u=t[1];if(!u||!n(u))return-1;const i=u.value;if(!C(i))return-1;return numberToCalculation(e,Math.log(a[4].value)/Math.log(i[4].value))}return-1}const R=/^none$/i;function isNone(e){if(Array.isArray(e)){const n=e.filter((e=>!(t(e)&&r(e))));return 1===n.length&&isNone(n[0])}if(!n(e))return!1;const a=e.value;return!!d(a)&&R.test(a[4].value)}const V=String.fromCodePoint(0);function solveRandom(e,n,t,r,a,u){if(-1===n.fixed&&!u.randomCaching)return-1;u.randomCaching||(u.randomCaching={propertyName:"",propertyN:0,elementID:"",documentID:""}),u.randomCaching&&!u.randomCaching.propertyN&&(u.randomCaching.propertyN=0);const i=t.value;if(!D(i))return-1;const o=convertUnit(i,r.value);if(!twoOfSameNumeric(i,o))return-1;let l=null;if(a&&(l=convertUnit(i,a.value),!twoOfSameNumeric(i,l)))return-1;if(!Number.isFinite(i[4].value))return resultToCalculation(e,i,Number.NaN);if(!Number.isFinite(o[4].value))return resultToCalculation(e,i,Number.NaN);if(!Number.isFinite(o[4].value-i[4].value))return resultToCalculation(e,i,Number.NaN);if(l&&!Number.isFinite(l[4].value))return resultToCalculation(e,i,i[4].value);const c=-1===n.fixed?sfc32(crc32([n.dashedIdent?n.dashedIdent:`${u.randomCaching?.propertyName} ${u.randomCaching.propertyN++}`,n.elementShared?"":u.randomCaching.elementID,u.randomCaching.documentID].join(V))):()=>n.fixed;let s=i[4].value,v=o[4].value;if(s>v&&([s,v]=[v,s]),l&&(l[4].value<=0||Math.abs(s-v)/l[4].value>1e10)&&(l=null),l){const n=Math.max(l[4].value/1e3,1e-9),t=[s];let r=0;for(;;){r+=l[4].value;const e=s+r;if(!(e+nv)break}const a=c();return resultToCalculation(e,i,Number(t[Math.floor(t.length*a)].toFixed(5)))}const f=c();return resultToCalculation(e,i,Number((f*(v-s)+s).toFixed(5)))}function sfc32(e=.34944106645296036,n=.19228640875738723,t=.8784393832007205,r=.04850964319275053){return()=>{const a=((e|=0)+(n|=0)|0)+(r|=0)|0;return r=r+1|0,e=n^n>>>9,n=(t|=0)+(t<<3)|0,t=(t=t<<21|t>>>11)+a|0,(a>>>0)/4294967296}}function crc32(e){let n=0,t=0,r=0;n=~n;for(let a=0,u=e.length;a>>8^t;return~n>>>0}const j=new Map([["abs",function abs(e,n,t){return singleNodeSolver(e,n,t,solveAbs)}],["acos",function acos(e,n,t){return singleNodeSolver(e,n,t,solveACos)}],["asin",function asin(e,n,t){return singleNodeSolver(e,n,t,solveASin)}],["atan",function atan(e,n,t){return singleNodeSolver(e,n,t,solveATan)}],["atan2",function atan2(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveATan2)}],["calc",calc$1],["clamp",function clamp(t,r,u){const i=resolveGlobalsAndConstants([...t.value.filter((e=>!a(e)))],r),l=[],c=[],s=[];{let e=l;for(let t=0;t!a(e))),n,t);if(-1===r)return-1;const[u,i]=r,o=variadicArguments(i,n,t);if(-1===o)return-1;const[l,c,s]=o;if(!l||!c)return-1;return solveRandom(e,u,l,c,s,t)}],["rem",function rem(e,n,t){return twoCommaSeparatedNodesSolver(e,n,t,solveRem)}],["round",function round(t,r,u){const i=resolveGlobalsAndConstants([...t.value.filter((e=>!a(e)))],r);let o="",l=!1;const c=[],s=[];{let e=c;for(let t=0;t!a(e)))],t);if(1===o.length&&n(o[0]))return{inputs:[o[0]],operation:unary};let l=0;for(;l!a(e)))],n)),n,t));return-1===r?-1:r}function twoCommaSeparatedNodesSolver(e,n,t,r){const a=twoCommaSeparatedArguments(e.value,n,t);if(-1===a)return-1;const[u,i]=a;return r(e,u,i,t)}function twoCommaSeparatedArguments(e,t,r){const u=resolveGlobalsAndConstants([...e.filter((e=>!a(e)))],t),i=[],o=[];{let e=i;for(let t=0;t!a(e)))],t),i=[];{const e=[];let a=[];for(let t=0;t1)return-1;a.fixed=Math.max(0,Math.min(i.value[4].value,1-1e-9))}else{if(-1!==a.fixed)return-1;a.elementShared=!0}}return-1}function calcWrapper(e){return new o([f.Function,"calc(",-1,-1,{value:"calc"}],[f.CloseParen,")",-1,-1,void 0],e)}function maxWrapper(n,t){return new o([f.Function,"max(",-1,-1,{value:"max"}],[f.CloseParen,")",-1,-1,void 0],[n,new e([f.Comma,",",-1,-1,void 0]),t])}function patchNaN(n){if(-1===n)return-1;if(i(n))return n;const t=n.value;return D(t)&&Number.isNaN(t[4].value)?C(t)?new o([f.Function,"calc(",t[2],t[3],{value:"calc"}],[f.CloseParen,")",t[2],t[3],void 0],[new e([f.Ident,"NaN",t[2],t[3],{value:"NaN"}])]):v(t)?new o([f.Function,"calc(",t[2],t[3],{value:"calc"}],[f.CloseParen,")",t[2],t[3],void 0],[new e([f.Ident,"NaN",t[2],t[3],{value:"NaN"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Delim,"*",t[2],t[3],{value:"*"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Dimension,"1"+t[4].unit,t[2],t[3],{value:1,type:m.Integer,unit:t[4].unit}])]):g(t)?new o([f.Function,"calc(",t[2],t[3],{value:"calc"}],[f.CloseParen,")",t[2],t[3],void 0],[new e([f.Ident,"NaN",t[2],t[3],{value:"NaN"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Delim,"*",t[2],t[3],{value:"*"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Percentage,"1%",t[2],t[3],{value:1}])]):-1:n}function patchInfinity(n){if(-1===n)return-1;if(i(n))return n;const t=n.value;if(!D(t))return n;if(Number.isFinite(t[4].value)||Number.isNaN(t[4].value))return n;let r="";return Number.NEGATIVE_INFINITY===t[4].value&&(r="-"),C(t)?new o([f.Function,"calc(",t[2],t[3],{value:"calc"}],[f.CloseParen,")",t[2],t[3],void 0],[new e([f.Ident,r+"infinity",t[2],t[3],{value:r+"infinity"}])]):v(t)?new o([f.Function,"calc(",t[2],t[3],{value:"calc"}],[f.CloseParen,")",t[2],t[3],void 0],[new e([f.Ident,r+"infinity",t[2],t[3],{value:r+"infinity"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Delim,"*",t[2],t[3],{value:"*"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Dimension,"1"+t[4].unit,t[2],t[3],{value:1,type:m.Integer,unit:t[4].unit}])]):new o([f.Function,"calc(",t[2],t[3],{value:"calc"}],[f.CloseParen,")",t[2],t[3],void 0],[new e([f.Ident,r+"infinity",t[2],t[3],{value:r+"infinity"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Delim,"*",t[2],t[3],{value:"*"}]),new l([[f.Whitespace," ",t[2],t[3],void 0]]),new e([f.Percentage,"1%",t[2],t[3],{value:1}])])}function patchMinusZero(e){if(-1===e)return-1;if(i(e))return e;const n=e.value;return D(n)&&Object.is(-0,n[4].value)?("-0"===n[1]||(g(n)?n[1]="-0%":v(n)?n[1]="-0"+n[4].unit:n[1]="-0"),e):e}function patchPrecision(e,n=13){if(-1===e)return-1;if(n<=0)return e;if(i(e))return e;const t=e.value;if(!D(t))return e;if(Number.isInteger(t[4].value))return e;const r=Number(t[4].value.toFixed(n)).toString();return C(t)?t[1]=r:g(t)?t[1]=r+"%":v(t)&&(t[1]=r+t[4].unit),e}function patchCanonicalUnit(e){return-1===e?-1:i(e)?e:v(e.value)?(e.value=toCanonicalUnit(e.value),e):e}function patchCalcResult(e,n){let t=e;return n?.toCanonicalUnits&&(t=patchCanonicalUnit(t)),t=patchPrecision(t,n?.precision),t=patchMinusZero(t),n?.censorIntoStandardRepresentableValues||(t=patchNaN(t),t=patchInfinity(t)),t}function tokenizeGlobals(e){const n=new Map;if(!e)return n;for(const[t,r]of e)if(h(r))n.set(t,r);else if("string"!=typeof r);else{const e=F({css:r}),a=e.nextToken();if(e.nextToken(),!e.endOfFile())continue;if(!D(a))continue;n.set(t,a)}return n}function calc(e,n){return calcFromComponentValues(c(b({css:e}),{}),n).map((e=>e.map((e=>w(...e.tokens()))).join(""))).join(",")}function calcFromComponentValues(e,n){const t=tokenizeGlobals(n?.globals);return s(e,(e=>{if(!i(e))return;const r=j.get(e.getName().toLowerCase());if(!r)return;const a=patchCalcResult(solve(r(e,t,n??{})),n);return-1!==a?a:void 0}))}const _=new Set(j.keys());export{calc,calcFromComponentValues,_ as mathFunctionNames}; diff --git a/packages/css-calc/docs/css-calc.api.json b/packages/css-calc/docs/css-calc.api.json index b9a8e2d273..96550b6718 100644 --- a/packages/css-calc/docs/css-calc.api.json +++ b/packages/css-calc/docs/css-calc.api.json @@ -361,7 +361,7 @@ }, { "kind": "Content", - "text": ";\n precision?: number;\n toCanonicalUnits?: boolean;\n censorIntoStandardRepresentableValues?: boolean;\n rawPercentages?: boolean;\n randomSeed?: number;\n}" + "text": ";\n precision?: number;\n toCanonicalUnits?: boolean;\n censorIntoStandardRepresentableValues?: boolean;\n rawPercentages?: boolean;\n randomCaching?: {\n propertyName: string;\n propertyN: number;\n elementID: string;\n documentID: string;\n };\n}" }, { "kind": "Content", diff --git a/packages/css-calc/docs/css-calc.conversionoptions.md b/packages/css-calc/docs/css-calc.conversionoptions.md index 7af5c1610c..28681ccf22 100644 --- a/packages/css-calc/docs/css-calc.conversionoptions.md +++ b/packages/css-calc/docs/css-calc.conversionoptions.md @@ -13,7 +13,12 @@ export type conversionOptions = { toCanonicalUnits?: boolean; censorIntoStandardRepresentableValues?: boolean; rawPercentages?: boolean; - randomSeed?: number; + randomCaching?: { + propertyName: string; + propertyN: number; + elementID: string; + documentID: string; + }; }; ``` **References:** [GlobalsWithStrings](./css-calc.globalswithstrings.md) diff --git a/packages/css-calc/src/functions/calc.ts b/packages/css-calc/src/functions/calc.ts index 7c69b27890..3386ba8cd9 100644 --- a/packages/css-calc/src/functions/calc.ts +++ b/packages/css-calc/src/functions/calc.ts @@ -1,7 +1,7 @@ import type { Calculation } from '../calculation'; import type { ComponentValue, SimpleBlockNode } from '@csstools/css-parser-algorithms'; import type { Globals } from '../util/globals'; -import { TokenType, NumberType, isTokenOpenParen, isTokenDelim, isTokenComma, isTokenIdent } from '@csstools/css-tokenizer'; +import { TokenType, NumberType, isTokenOpenParen, isTokenDelim, isTokenComma, isTokenIdent, isTokenNumber } from '@csstools/css-tokenizer'; import { addition } from '../operation/addition'; import { division } from '../operation/division'; import { isCalculation, solve } from '../calculation'; @@ -32,6 +32,7 @@ import { unary } from '../operation/unary'; import { solveLog } from './log'; import { isNone } from '../util/is-none'; import type { conversionOptions } from '../options'; +import type { RandomValueSharing} from './random'; import { solveRandom } from './random'; type mathFunction = (node: FunctionNode, globals: Globals, options: conversionOptions) => Calculation | -1 @@ -576,65 +577,127 @@ function log(logNode: FunctionNode, globals: Globals, options: conversionOptions } function random(randomNode: FunctionNode, globals: Globals, options: conversionOptions): Calculation | -1 { - const nodes: Array = randomNode.value.filter(x => !isWhiteSpaceOrCommentNode(x)); + const randomValueSharingAndNodes = parseRandomValueSharing( + randomNode.value.filter(x => !isWhiteSpaceOrCommentNode(x)), + globals, + options, + ); + if (randomValueSharingAndNodes === -1) { + return -1; + } - let randomCachingOptions = ''; - const stepValues: Array = [] - const values: Array = [] + const [randomValueSharing, nodes] = randomValueSharingAndNodes; - { - for (let i = 0; i < nodes.length; i++) { - const node = nodes[i]; - if (!randomCachingOptions && values.length === 0 && isTokenNode(node) && isTokenIdent(node.value)) { - const token = node.value; - const tokenStr = token[4].value.toLowerCase(); - if (tokenStr === 'per-element' || tokenStr.startsWith('--')) { - randomCachingOptions = tokenStr; + const randomArguments = variadicArguments(nodes, globals, options); + if (randomArguments === -1) { + return -1; + } - const nextNode = nodes[i + 1]; - if (!isTokenNode(nextNode) || !isTokenComma(nextNode.value)) { - return -1; - } + const [a, b, c] = randomArguments; - i++; - continue; - } + if (!a || !b) { + return -1 + } + + return solveRandom( + randomNode, + randomValueSharing, + a, + b, + c, + options + ); +} + +function parseRandomValueSharing(nodes: Array, globals: Globals, options: conversionOptions): [RandomValueSharing, Array] | -1 { + const x: RandomValueSharing = { + isAuto: false, + dashedIdent: "", + fixed: -1, + elementShared: false, + }; + + const firstNode = nodes[0]; + if (!isTokenNode(firstNode) || !isTokenIdent(firstNode.value)) { + return [x, nodes]; + } + + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (!isTokenNode(node)) { + return -1; + } + + if (isTokenComma(node.value)) { + return [x, nodes.slice(i+1)]; + } + + if (!isTokenIdent(node.value)) { + return -1; + } + + const token = node.value; + const tokenStr = token[4].value.toLowerCase(); + + if (tokenStr === 'element-shared') { + if (x.fixed !== -1) { + return -1; } - if (isTokenNode(node) && isTokenComma(node.value)) { - const nextNode = nodes[i + 1]; + x.elementShared = true; + continue; + } - if (values.length > 0 && isTokenNode(nextNode) && isTokenIdent(nextNode.value)) { - const token = nextNode.value; - const tokenStr = token[4].value.toLowerCase(); - if (tokenStr === 'by' || tokenStr.startsWith('--')) { - stepValues.push(...nodes.slice(i + 2)); + // fixed + if (tokenStr === 'fixed') { + if (x.elementShared || x.dashedIdent || x.isAuto) { + return -1; + } - break; - } - } + i++; + const nextNode = nodes[i]; + if (!nextNode) { + return -1; + } + + const fixedNumber = solve(calc(calcWrapper([nextNode]), globals, options)); + if (fixedNumber === -1) { + return -1; + } + + if (!isTokenNumber(fixedNumber.value)) { + return -1; + } + + if (fixedNumber.value[4].value < 0 || fixedNumber.value[4].value > 1) { + return -1; } - values.push(node); + x.fixed = Math.max(0, Math.min(fixedNumber.value[4].value, 1 - 0.000_000_001)); + + continue; } - } - const solvedValues = twoCommaSeparatedArguments(values, globals, options); - if (solvedValues === -1) { - return -1; - } + if (tokenStr === 'auto') { + if (x.fixed !== -1 || x.dashedIdent) { + return -1; + } - const [a, b] = solvedValues; + x.isAuto = true; + continue; + } - let solvedStepValue: TokenNode | -1 | null = null; - if (stepValues.length) { - solvedStepValue = singleArgument(stepValues, globals, options); - if (solvedStepValue === -1) { - return -1; + if (tokenStr.startsWith('--')) { + if (x.fixed !== -1 || x.isAuto) { + return -1; + } + + x.dashedIdent = tokenStr; + continue; } } - return solveRandom(randomNode, randomCachingOptions, a, b, solvedStepValue, options); + return -1; } function calcWrapper(v: Array): FunctionNode { diff --git a/packages/css-calc/src/functions/random.ts b/packages/css-calc/src/functions/random.ts index 25855192e2..4f1cbc717f 100644 --- a/packages/css-calc/src/functions/random.ts +++ b/packages/css-calc/src/functions/random.ts @@ -4,10 +4,36 @@ import { convertUnit } from '../unit-conversions'; import { resultToCalculation } from './result-to-calculation'; import { twoOfSameNumeric } from '../util/kind-of-number'; import type { CSSToken} from '@csstools/css-tokenizer'; -import { isTokenNumeric, stringify } from '@csstools/css-tokenizer'; +import { isTokenNumeric } from '@csstools/css-tokenizer'; import type { conversionOptions } from '../options'; -export function solveRandom(randomNode: FunctionNode, randomCachingOptions: string, a: TokenNode, b: TokenNode, stepValue: TokenNode|null, options: conversionOptions): Calculation | -1 { +const NULL_CHAR = String.fromCodePoint(0x000); + +export type RandomValueSharing = { + isAuto: boolean, + dashedIdent: string, + elementShared: boolean, + fixed: number, +} + +export function solveRandom(randomNode: FunctionNode, randomValueSharing: RandomValueSharing, a: TokenNode, b: TokenNode, stepValue: TokenNode|null, options: conversionOptions): Calculation | -1 { + if (randomValueSharing.fixed === -1 && !options.randomCaching) { + return -1; + } + + if (!options.randomCaching) { + options.randomCaching = { + propertyName: '', + propertyN: 0, + elementID: '', + documentID: '', + } + } + + if (options.randomCaching && !options.randomCaching.propertyN) { + options.randomCaching.propertyN = 0; + } + const aToken = a.value; if (!isTokenNumeric(aToken)) { return -1; @@ -26,56 +52,82 @@ export function solveRandom(randomNode: FunctionNode, randomCachingOptions: stri } } - let result; if (!Number.isFinite(aToken[4].value)) { - result = Number.NaN; - } else if (!Number.isFinite(bToken[4].value)) { - result = Number.NaN; - } else if (!Number.isFinite(bToken[4].value - aToken[4].value)) { - result = Number.NaN; - } else if (stepValueToken && !Number.isFinite(stepValueToken[4].value)) { - result = aToken[4].value - } else { - const rnd = sfc32( - crc32( - [ - randomCachingOptions, - stringify(aToken), - stringify(bToken), - (stepValue ? `by ${stepValue.toString()}` : ''), - ].join(','), - ), - options.randomSeed, - ); + return resultToCalculation(randomNode, aToken, Number.NaN); + } - let min = aToken[4].value; - let max = bToken[4].value; - if (min > max) { - [min, max] = [max, min]; - } + if (!Number.isFinite(bToken[4].value)) { + return resultToCalculation(randomNode, aToken, Number.NaN); + } - if ( - stepValueToken && ( - (stepValueToken[4].value <= 0) || - ((Math.abs(min - max) / stepValueToken[4].value) > 10_000_000_000) - ) - ) { - stepValueToken = null - } + if (!Number.isFinite(bToken[4].value - aToken[4].value)) { + return resultToCalculation(randomNode, aToken, Number.NaN); + } + + if (stepValueToken && !Number.isFinite(stepValueToken[4].value)) { + return resultToCalculation(randomNode, aToken, aToken[4].value); + } + + const rnd = randomValueSharing.fixed === -1 ? sfc32( + crc32( + [ + randomValueSharing.dashedIdent ? randomValueSharing.dashedIdent : (`${options.randomCaching?.propertyName} ${options.randomCaching.propertyN++}`), + randomValueSharing.elementShared ? "" : options.randomCaching.elementID, + options.randomCaching.documentID, + ].join(NULL_CHAR), + ), + ) : () : number => { return randomValueSharing.fixed }; + + let min = aToken[4].value; + let max = bToken[4].value; + if (min > max) { + [min, max] = [max, min]; + } + + if ( + stepValueToken && ( + (stepValueToken[4].value <= 0) || + ((Math.abs(min - max) / stepValueToken[4].value) > 10_000_000_000) + ) + ) { + stepValueToken = null + } + + if (stepValueToken) { + const err = Math.max(stepValueToken[4].value / 1000, 0.000_000_001); - if (stepValueToken) { - const delta = Math.abs(min - max); - const randomValue = rnd(); - const steps = Math.floor((delta / stepValueToken[4].value) * randomValue); + const steps = [min]; + let lastStep = 0; + while (true) { + lastStep += stepValueToken[4].value; - result = min + (steps * stepValueToken[4].value); - } else { - const randomValue = rnd(); - result = Number(((randomValue * (max - min)) + min).toFixed(5)); + const stepResult = min + lastStep; + if ((stepResult + err) < max) { + steps.push(stepResult); + } else { + steps.push(max); + break; + } + + if ((stepResult + stepValueToken[4].value - err) > max) { + break; + } } + + const randomValue = rnd(); + return resultToCalculation( + randomNode, + aToken, + Number(steps[Math.floor(steps.length * randomValue)].toFixed(5)) + ); } - return resultToCalculation(randomNode, aToken, result); + const randomValue = rnd(); + return resultToCalculation( + randomNode, + aToken, + Number(((randomValue * (max - min)) + min).toFixed(5)) + ); } function sfc32(a: number = 0.34944106645296036, b: number = 0.19228640875738723, c: number = 0.8784393832007205, d: number = 0.04850964319275053): () => number { diff --git a/packages/css-calc/src/options.ts b/packages/css-calc/src/options.ts index 919e3aa2af..df124a3d7a 100644 --- a/packages/css-calc/src/options.ts +++ b/packages/css-calc/src/options.ts @@ -39,7 +39,29 @@ export type conversionOptions = { rawPercentages?: boolean /** - * Seed the pseudo random number generator used in `random()` + * The values used to generate random value cache keys. */ - randomSeed?: number + randomCaching?: { + /** + * The name of the property the random function is used in. + */ + propertyName: string + + /** + * N is the index of the random function among other random functions in the same property value. + */ + propertyN: number + + /** + * An element ID identifying the element the style is being applied to. + * When omitted any `random()` call will not be computed. + */ + elementID: string + + /** + * A document ID identifying the Document the styles are from. + * When omitted any `random()` call will not be computed. + */ + documentID: string + } }; diff --git a/packages/css-calc/test/additional/random.mjs b/packages/css-calc/test/additional/random.mjs index 27d62d0243..4d65d98854 100644 --- a/packages/css-calc/test/additional/random.mjs +++ b/packages/css-calc/test/additional/random.mjs @@ -2,166 +2,303 @@ import { calc } from '@csstools/css-calc'; import assert from 'node:assert'; assert.strictEqual( - calc('random(100px, 500px)'), - '466.96922px', + calc('random(100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.54613px', ); assert.strictEqual( - calc('random(calc(80px + 20px), 500px)'), - '466.96922px', + calc('random(fixed, 100px, 500px)'), + 'random(fixed, 100px, 500px)', ); assert.strictEqual( - calc('random(80px + 20px, 500px)'), - '466.96922px', + calc('random(fixed element-shared, 100px, 500px)'), + 'random(fixed element-shared, 100px, 500px)', ); assert.strictEqual( - calc('random(calc(50px * 2), 500px)'), - '466.96922px', + calc('random(fixed -0.5, 100px, 500px)'), + 'random(fixed -0.5, 100px, 500px)', ); assert.strictEqual( - calc('random(--foo, 100px, 500px)'), - '385.03443px', + calc('random(fixed 1.5, 100px, 500px)'), + 'random(fixed 1.5, 100px, 500px)', ); assert.strictEqual( - calc('random(--foo, 80px + 20px, 500px)'), - '385.03443px', + calc('random(fixed 0.5, 100px, 500px)'), + '300px', ); assert.strictEqual( - calc('random(--bar, 100px, 500px)'), - '247.498px', + calc('random(fixed calc(1 / 2), 100px, 500px)'), + '300px', ); assert.strictEqual( - calc('random(99px, 500px)'), - '353.2884px', + calc('random(fixed 0.5 element-shared, 100px, 500px)'), + 'random(fixed 0.5 element-shared, 100px, 500px)', ); assert.strictEqual( - calc('random(99, 500px)'), + calc('random(fixed 0, 100px, 500px)'), + '100px', +); + +assert.strictEqual( + calc('random(fixed 1, 100px, 500px)'), + '500px', +); + +assert.strictEqual( + calc('random(auto, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.54613px', +); + +assert.strictEqual( + calc('random(auto, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'bb', propertyName: 'c', propertyN: 0 } }), + '125.44077px', +); + +assert.strictEqual( + calc('random(auto element-shared, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '182.79634px', +); + +assert.strictEqual( + calc('random(auto element-shared, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'bb', propertyName: 'c', propertyN: 0 } }), + '182.79634px', +); + +assert.strictEqual( + calc('random(--foo, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '319.55825px', +); + +assert.strictEqual( + calc('random(--foo element-shared, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '182.8387px', +); + +assert.strictEqual( + calc('random(element-shared --foo, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '182.8387px', +); + +assert.strictEqual( + calc('random(element-shared auto, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '182.79634px', +); + +assert.strictEqual( + calc('random(100px, 500px) random(100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.54613px 420.66239px', +); + +assert.strictEqual( + calc('random(--foo, 100px, 500px) random(--foo, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '319.55825px 319.55825px', +); + +assert.strictEqual( + calc('random(calc(80px + 20px), 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.54613px', +); + +assert.strictEqual( + calc('random(80px + 20px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.54613px', +); + +assert.strictEqual( + calc('random(calc(50px * 2), 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.54613px', +); + +assert.strictEqual( + calc('random(--foo, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '319.55825px', +); + +assert.strictEqual( + calc('random(--foo, 80px + 20px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '319.55825px', +); + +assert.strictEqual( + calc('random(--bar, 100px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '441.70825px', +); + +assert.strictEqual( + calc('random(99px, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '475.48499px', +); + +assert.strictEqual( + calc('random(99, 500px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), 'random(99, 500px)', ); assert.strictEqual( - calc('random(100px, 500px, by 10px)'), - '200px', + calc('random(100px, 500px, 10px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '480px', ); assert.strictEqual( - calc('random(100px, 500px, by calc(5px * 2))'), - '200px', + calc('random(100px, 500px, calc(5px * 2))', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '480px', ); assert.strictEqual( - calc('random(--foo, 100px, 500px, by 5px * 2)'), - '490px', + calc('random(--foo, 100px, 500px, 5px * 2)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '320px', ); assert.strictEqual( - calc('random(-10px, 20px, by 50px)'), - '-10px', + calc('random(-10px, 20px, 50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '20px', ); assert.strictEqual( - calc('random(--foo, -10px, 20px, by 50px)'), - '-10px', + calc('random(--foo, -10px, 20px, 50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '20px', ); assert.strictEqual( - calc('random(--bar, -10px, 20px, by 50px)'), + calc('random(--aaaa, -10px, 20px, 50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), '-10px', ); assert.strictEqual( - calc('random(-10px, 60px, by 50px)'), - '-10px', + calc('random(-10px, 60px, 50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '40px', ); assert.strictEqual( - calc('random(--foo, -10px, 60px, by 50px)'), + calc('random(--foo, -10px, 60px, 50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), '40px', ); assert.strictEqual( - calc('random(--bar, -10px, 60px, by 50px)'), + calc('random(--aaaa, -10px, 60px, 50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), '-10px', ); assert.strictEqual( - calc('random(-10px, 20px, by -50px)'), - '13.45151px', + calc('random(-10px, 20px, -50px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '18.16596px', ); assert.strictEqual( - calc('random(-10px, 20px, by 0px)'), - '-1.86008px', + calc('random(-10px, 20px, 0px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '18.16596px', ); assert.strictEqual( - calc('random(-10px, 20px, by calc(10px * infinity))'), + calc('random(-10px, 20px, calc(10px * infinity))', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), '-10px', ); assert.strictEqual( - calc('random(-10px, 20px, by (1px / 0))'), + calc('random(-10px, 20px, (1px / 0))', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), '-10px', ); assert.strictEqual( - calc('random(calc(10px * infinity), 20px)'), + calc('random(calc(10px * infinity), 20px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), 'calc(NaN * 1px)', ); assert.strictEqual( - calc('random(-10px, calc(10px * infinity))'), + calc('random(-10px, calc(10px * infinity))', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), 'calc(NaN * 1px)', ); assert.strictEqual( - calc('random(10ms, 1s)'), - '934.64243ms', + calc('random(10ms, 1s)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '939.47666ms', ); assert.strictEqual( - calc('random(10deg, 10px)'), + calc('random(10deg, 10px)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), 'random(10deg, 10px)', ); assert.strictEqual( - calc('random(0%, 100%)'), - '47.16924%', + calc('random(0%, 100%)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '93.88653%', +); + +assert.strictEqual( + calc('random(0deg, 360deg)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '337.99151deg', +); + +assert.strictEqual( + calc('random(--foo, 10, 20, -2)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '15.48896', ); assert.strictEqual( - calc('random(0deg, 360deg)'), - '173.25527deg', + calc('random(10, 20, 0.00005)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), // Number of steps is small enough + '19.3887', ); assert.strictEqual( - calc('random(--foo, 10, 20, by -2)'), - '17.30236', + calc('random(10, 20, 0.000005)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), // Number of steps is small enough + '19.38865', ); assert.strictEqual( - calc('random(10, 20, by 0.00005)'), // Number of steps is small enough - '18.7764', + calc('random(0, 1, 0.00000000005)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), // Number of steps is too large + '0.93887', ); assert.strictEqual( - calc('random(10, 20, by 0.000005)'), // Number of steps is small enough - '15.882265', + calc('random(0, 10000000, 0.00000000005)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), // Number of steps is too large + '9388653.16566', ); assert.strictEqual( - calc('random(0, 1, by 0.00000000005)'), // Number of steps is too large - '0.70517', + calc('random(--aaa, 0.2, 0.3, 0.1)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), // Number of steps is too large + '0.3', ); +for (let i = 0; i < 100; i++) { + const result = Number(calc(`random(--a${i}, 0, 0.3, 0.1)`, { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } })); + + assert.ok(result >= 0); + assert.ok(result <= 0.3); + assert.ok(result === 0 || result === 0.1 || result === 0.2 || result === 0.3); +} + +for (let i = 0; i < 100; i++) { + const result = Number(calc(`random(--a${i}, 0.2, 0.4, 0.1)`, { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } })); + + assert.ok(result >= 0.2); + assert.ok(result <= 0.4); + assert.ok(result === 0.2 || result === 0.3 || result === 0.4); +} + assert.strictEqual( - calc('random(0, 10000000, by 0.00000000005)'), // Number of steps is too large - '8282240.00987', + calc('random(--aaa, 0, 1.8, 0.6)', { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } }), + '1.8', ); + +for (let i = 0; i < 100; i++) { + const result = Number(calc(`random(--a${i}, 0, 1.8, 0.6)`, { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } })); + + assert.ok(result >= 0); + assert.ok(result <= 1.8); + assert.ok(result === 0 || result === 0.6 || result === 1.2 || result === 1.8); +} + +for (let i = 0; i < 100; i++) { + const result = Number(calc(`random(--a${i}, 100, 200, 30)`, { randomCaching: { documentID: 'a', elementID: 'b', propertyName: 'c', propertyN: 0 } })); + + assert.ok(result >= 100); + assert.ok(result <= 190); + assert.ok(result === 100 || result === 130 || result === 160 || result === 190); +} diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css index c3a4d16adb..7552199c9d 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css @@ -737,14 +737,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css index de50d6629f..a433616d5f 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css @@ -742,14 +742,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css index f4e5264ecd..ad326b4dc0 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css @@ -761,14 +761,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css index 4499baa1f6..4032410276 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css @@ -649,14 +649,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.css b/plugin-packs/postcss-preset-env/test/basic.css index 497e2edc38..a68403fe3f 100644 --- a/plugin-packs/postcss-preset-env/test/basic.css +++ b/plugin-packs/postcss-preset-env/test/basic.css @@ -532,14 +532,14 @@ .random { color: rgb( - random(--r, 0, 255, by 5), - random(--g, 0, 255, by 5), - random(--b, 0, 255, by 5) + random(--r, 0, 255, 5), + random(--g, 0, 255, 5), + random(--b, 0, 255, 5) ); border-color: oklch( - random(--l, 0%, 100%, by 5%), - random(--c, 30%, 70%, by 5%), - random(--h, 0deg, 360deg, by 12deg) + random(--l, 0%, 100%, 5%) + random(--c, 30%, 70%, 5%) + random(--h, 0deg, 360deg, 12deg) ); } diff --git a/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css b/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css index db641b61e2..d1cd6c0f7a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css @@ -731,14 +731,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css index d24a083c8e..c88fd6f292 100644 --- a/plugin-packs/postcss-preset-env/test/basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.expect.css @@ -756,14 +756,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css index 99e5a99ff7..704230db9a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css @@ -648,14 +648,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css index 77f13d94a3..ccb21cdd02 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css @@ -643,14 +643,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css b/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css index 6362b6d344..8ed7618ea3 100644 --- a/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css @@ -605,14 +605,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css index e26c84d362..68b725eadb 100644 --- a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css @@ -752,14 +752,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css index e3b644ca6d..d0c7f55507 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css @@ -775,14 +775,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css index 0d722c31cb..c52f7e7c7c 100644 --- a/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css @@ -746,14 +746,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css b/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css index 31f1cdaf94..922a4fa651 100644 --- a/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.nesting.true.expect.css @@ -538,14 +538,14 @@ .random { color: rgb( - random(--r, 0, 255, by 5), - random(--g, 0, 255, by 5), - random(--b, 0, 255, by 5) + random(--r, 0, 255, 5), + random(--g, 0, 255, 5), + random(--b, 0, 255, 5) ); border-color: oklch( - random(--l, 0%, 100%, by 5%), - random(--c, 30%, 70%, by 5%), - random(--h, 0deg, 360deg, by 12deg) + random(--l, 0%, 100%, 5%) + random(--c, 30%, 70%, 5%) + random(--h, 0deg, 360deg, 12deg) ); } diff --git a/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css b/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css index e7a4ecd8d9..63478ac220 100644 --- a/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css @@ -734,14 +734,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css index 11b6344cdf..731998433f 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css @@ -864,14 +864,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css index ccbab4fa84..6e042da2a5 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css @@ -1226,25 +1226,27 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); color: rgb( - random(--r, 0, 255, by 5), - random(--g, 0, 255, by 5), - random(--b, 0, 255, by 5) + random(--r, 0, 255, 5), + random(--g, 0, 255, 5), + random(--b, 0, 255, 5) ); + border-color: rgb(228, 112, 176); + border-color: oklch( - 85%, - 40%, - 96deg + 70% + 40% + 348deg ); border-color: oklch( - random(--l, 0%, 100%, by 5%), - random(--c, 30%, 70%, by 5%), - random(--h, 0deg, 360deg, by 12deg) + random(--l, 0%, 100%, 5%) + random(--c, 30%, 70%, 5%) + random(--h, 0deg, 360deg, 12deg) ); } diff --git a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css index 76f05acb2b..4f8d269e20 100644 --- a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css @@ -630,14 +630,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css index 87404f45ba..c1ad1b54fe 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css @@ -644,14 +644,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css index dcca0a8627..3b9b1618dd 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css @@ -639,14 +639,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css index e7d58034dd..a4d7a9c058 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css @@ -752,14 +752,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css b/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css index d70d617786..04f1316a82 100644 --- a/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css @@ -641,14 +641,10 @@ .random { color: rgb( - 115, - 230, - 125 + 140, + 0, + 85 ); - border-color: oklch( - 85%, - 40%, - 96deg - ); + border-color: rgb(228, 112, 176); } diff --git a/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css b/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css index 4033dcb5ae..85cbe7d103 100644 --- a/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.vendors-1.expect.css @@ -729,14 +729,14 @@ .random { color: rgb( - random(--r, 0, 255, by 5), - random(--g, 0, 255, by 5), - random(--b, 0, 255, by 5) + random(--r, 0, 255, 5), + random(--g, 0, 255, 5), + random(--b, 0, 255, 5) ); border-color: oklch( - random(--l, 0%, 100%, by 5%), - random(--c, 30%, 70%, by 5%), - random(--h, 0deg, 360deg, by 12deg) + random(--l, 0%, 100%, 5%) + random(--c, 30%, 70%, 5%) + random(--h, 0deg, 360deg, 12deg) ); } diff --git a/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css b/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css index 4033dcb5ae..85cbe7d103 100644 --- a/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.vendors-2.expect.css @@ -729,14 +729,14 @@ .random { color: rgb( - random(--r, 0, 255, by 5), - random(--g, 0, 255, by 5), - random(--b, 0, 255, by 5) + random(--r, 0, 255, 5), + random(--g, 0, 255, 5), + random(--b, 0, 255, 5) ); border-color: oklch( - random(--l, 0%, 100%, by 5%), - random(--c, 30%, 70%, by 5%), - random(--h, 0deg, 360deg, by 12deg) + random(--l, 0%, 100%, 5%) + random(--c, 30%, 70%, 5%) + random(--h, 0deg, 360deg, 12deg) ); } diff --git a/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css b/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css index a543d60d55..6b5463364e 100644 --- a/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.vendors-3.expect.css @@ -723,14 +723,14 @@ .random { color: rgb( - random(--r, 0, 255, by 5), - random(--g, 0, 255, by 5), - random(--b, 0, 255, by 5) + random(--r, 0, 255, 5), + random(--g, 0, 255, 5), + random(--b, 0, 255, 5) ); border-color: oklch( - random(--l, 0%, 100%, by 5%), - random(--c, 30%, 70%, by 5%), - random(--h, 0deg, 360deg, by 12deg) + random(--l, 0%, 100%, 5%) + random(--c, 30%, 70%, 5%) + random(--h, 0deg, 360deg, 12deg) ); } diff --git a/plugins/postcss-random-function/CHANGELOG.md b/plugins/postcss-random-function/CHANGELOG.md index a70ded93e9..2f1497ec73 100644 --- a/plugins/postcss-random-function/CHANGELOG.md +++ b/plugins/postcss-random-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Random Function +### Unreleased (major) + +- Match the latest [specification](https://drafts.csswg.org/css-values-5/#randomness) + ### 1.0.3 _February 23, 2025_ diff --git a/plugins/postcss-random-function/README.md b/plugins/postcss-random-function/README.md index 87b84cfc16..e05e91c42e 100644 --- a/plugins/postcss-random-function/README.md +++ b/plugins/postcss-random-function/README.md @@ -10,31 +10,31 @@ npm install @csstools/postcss-random-function --save-dev ```css div { - color: oklch(0.7, 0.2, random(120deg, 240deg)); + color: oklch(0.7 0.2 random(120deg, 240deg)); } div { - color: oklch(0.7, 0.2, random(120deg, 240deg, by 7deg)); + color: oklch(0.7 0.2 random(120deg, 240deg, 7deg)); } div { - color: oklch(0.7, 0.2, random(--text, 120deg, 240deg)); - border-color: oklch(0.7, 0.2, random(--border, 120deg, 240deg)); + margin: random(10px, 100px) random(10px, 100px); + padding: random(--padding, 10px, 100px) random(--padding, 10px, 100px); } /* becomes */ div { - color: oklch(0.7, 0.2, 238.66036deg); + color: oklch(0.7 0.2 177.17235deg); } div { - color: oklch(0.7, 0.2, 134deg); + color: oklch(0.7 0.2 176deg); } div { - color: oklch(0.7, 0.2, 226.47057deg); - border-color: oklch(0.7, 0.2, 157.76966deg); + margin: 41.7525px 70.01679px; + padding: 44.03856px 44.03856px; } ``` @@ -92,35 +92,35 @@ postcssRandomFunction({ preserve: true }) ```css div { - color: oklch(0.7, 0.2, random(120deg, 240deg)); + color: oklch(0.7 0.2 random(120deg, 240deg)); } div { - color: oklch(0.7, 0.2, random(120deg, 240deg, by 7deg)); + color: oklch(0.7 0.2 random(120deg, 240deg, 7deg)); } div { - color: oklch(0.7, 0.2, random(--text, 120deg, 240deg)); - border-color: oklch(0.7, 0.2, random(--border, 120deg, 240deg)); + margin: random(10px, 100px) random(10px, 100px); + padding: random(--padding, 10px, 100px) random(--padding, 10px, 100px); } /* becomes */ div { - color: oklch(0.7, 0.2, 238.66036deg); - color: oklch(0.7, 0.2, random(120deg, 240deg)); + color: oklch(0.7 0.2 177.17235deg); + color: oklch(0.7 0.2 random(120deg, 240deg)); } div { - color: oklch(0.7, 0.2, 134deg); - color: oklch(0.7, 0.2, random(120deg, 240deg, by 7deg)); + color: oklch(0.7 0.2 176deg); + color: oklch(0.7 0.2 random(120deg, 240deg, 7deg)); } div { - color: oklch(0.7, 0.2, 226.47057deg); - color: oklch(0.7, 0.2, random(--text, 120deg, 240deg)); - border-color: oklch(0.7, 0.2, 157.76966deg); - border-color: oklch(0.7, 0.2, random(--border, 120deg, 240deg)); + margin: 41.7525px 70.01679px; + margin: random(10px, 100px) random(10px, 100px); + padding: 44.03856px 44.03856px; + padding: random(--padding, 10px, 100px) random(--padding, 10px, 100px); } ``` diff --git a/plugins/postcss-random-function/dist/index.cjs b/plugins/postcss-random-function/dist/index.cjs index 6852a3e2ab..a0d2f50ed2 100644 --- a/plugins/postcss-random-function/dist/index.cjs +++ b/plugins/postcss-random-function/dist/index.cjs @@ -1 +1 @@ -"use strict";var e=require("@csstools/css-calc");const s=/(?{const c=Object.assign({preserve:!1},o);return{postcssPlugin:"postcss-random-function",Declaration(o){if(!s.test(o.value))return;const r=e.calc(o.value,{precision:5,toCanonicalUnits:!0,randomSeed:o.source?.input.css.length});r!==o.value&&(o.cloneBefore({value:r}),c.preserve||o.remove())}}};creator.postcss=!0,module.exports=creator; +"use strict";var e=require("@csstools/css-calc");const r=String.fromCodePoint(0);function randomCacheKeyFromPostcssDeclaration(e){let o="",s=e.parent;for(;s;){switch(s.type){case"rule":o+=r+"selector"+r+s.selector+r;break;case"atrule":"scope"===s.name&&(o+=r+"prelude"+r+s.params+r)}s=s.parent}return{propertyName:e.prop,propertyN:0,elementID:o,documentID:e.source?.input.css??e.root().toString()}}const o=/(?{const s=Object.assign({preserve:!1},r);return{postcssPlugin:"postcss-random-function",Declaration(r){if(!o.test(r.value))return;const t=e.calc(r.value,{precision:5,toCanonicalUnits:!0,randomCaching:randomCacheKeyFromPostcssDeclaration(r)});t!==r.value&&(r.cloneBefore({value:t}),s.preserve||r.remove())}}};creator.postcss=!0,module.exports=creator; diff --git a/plugins/postcss-random-function/dist/index.mjs b/plugins/postcss-random-function/dist/index.mjs index cd8a11038e..b99ecce646 100644 --- a/plugins/postcss-random-function/dist/index.mjs +++ b/plugins/postcss-random-function/dist/index.mjs @@ -1 +1 @@ -import{calc as s}from"@csstools/css-calc";const e=/(?{const t=Object.assign({preserve:!1},o);return{postcssPlugin:"postcss-random-function",Declaration(o){if(!e.test(o.value))return;const n=s(o.value,{precision:5,toCanonicalUnits:!0,randomSeed:o.source?.input.css.length});n!==o.value&&(o.cloneBefore({value:n}),t.preserve||o.remove())}}};creator.postcss=!0;export{creator as default}; +import{calc as e}from"@csstools/css-calc";const o=String.fromCodePoint(0);function randomCacheKeyFromPostcssDeclaration(e){let r="",t=e.parent;for(;t;){switch(t.type){case"rule":r+=o+"selector"+o+t.selector+o;break;case"atrule":"scope"===t.name&&(r+=o+"prelude"+o+t.params+o)}t=t.parent}return{propertyName:e.prop,propertyN:0,elementID:r,documentID:e.source?.input.css??e.root().toString()}}const r=/(?{const t=Object.assign({preserve:!1},o);return{postcssPlugin:"postcss-random-function",Declaration(o){if(!r.test(o.value))return;const s=e(o.value,{precision:5,toCanonicalUnits:!0,randomCaching:randomCacheKeyFromPostcssDeclaration(o)});s!==o.value&&(o.cloneBefore({value:s}),t.preserve||o.remove())}}};creator.postcss=!0;export{creator as default}; diff --git a/plugins/postcss-random-function/src/cache-key.ts b/plugins/postcss-random-function/src/cache-key.ts new file mode 100644 index 0000000000..5bd718ff91 --- /dev/null +++ b/plugins/postcss-random-function/src/cache-key.ts @@ -0,0 +1,54 @@ +import type { AtRule, Container, Declaration, Document, Rule } from 'postcss'; +import type { ContainerWithChildren } from 'postcss/lib/container'; + +const NULL_CHAR = String.fromCodePoint(0x000); + +export function randomCacheKeyFromPostcssDeclaration(decl: Declaration): { + /** + * The name of the property the random function is used in. + */ + propertyName: string + + /** + * N is the index of the random function among other random functions in the same property value. + */ + propertyN: number + + /** + * An element ID identifying the element the style is being applied to. + */ + elementID: string + + /** + * A document ID identifying the Document the styles are from. + */ + documentID: string +} { + let elementID = ''; + + let ancestor: Document | ContainerWithChildren | Container | undefined = decl.parent; + while (ancestor) { + switch (ancestor.type) { + case "rule": + elementID += NULL_CHAR + 'selector' + NULL_CHAR + (ancestor as Rule).selector + NULL_CHAR; + break; + case "atrule": + if ((ancestor as AtRule).name === 'scope') { + elementID += NULL_CHAR + 'prelude' + NULL_CHAR + (ancestor as AtRule).params + NULL_CHAR; + } + break; + + default: + break; + } + + ancestor = ancestor.parent + } + + return { + propertyName: decl.prop, + propertyN: 0, + elementID: elementID, + documentID: decl.source?.input.css ?? decl.root().toString(), + } +} diff --git a/plugins/postcss-random-function/src/index.ts b/plugins/postcss-random-function/src/index.ts index acb71bff18..48f04b69c1 100644 --- a/plugins/postcss-random-function/src/index.ts +++ b/plugins/postcss-random-function/src/index.ts @@ -1,5 +1,6 @@ import type { PluginCreator } from 'postcss'; import { calc } from '@csstools/css-calc'; +import { randomCacheKeyFromPostcssDeclaration } from './cache-key'; /** postcss-random-function plugin options */ export type pluginOptions = { @@ -29,7 +30,7 @@ const creator: PluginCreator = (opts?: pluginOptions) => { const modifiedValue = calc(decl.value, { precision: 5, toCanonicalUnits: true, - randomSeed: decl.source?.input.css.length + randomCaching: randomCacheKeyFromPostcssDeclaration(decl), }); if (modifiedValue === decl.value) { return; diff --git a/plugins/postcss-random-function/test/basic.css b/plugins/postcss-random-function/test/basic.css index 740d6c6cd1..e23dc8c9d1 100644 --- a/plugins/postcss-random-function/test/basic.css +++ b/plugins/postcss-random-function/test/basic.css @@ -3,7 +3,7 @@ } .random-2 { - z-index: random(0, 10, by 1); + z-index: random(0, 10 1); } .random-3 { @@ -19,7 +19,7 @@ } .random-12 { - width: random(0px, 10px, by 1px); + width: random(0px, 10px 1px); } .random-13 { @@ -30,6 +30,63 @@ width: random(--bar, 0px, 10px); } +.random-15 { + padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); + margin: random(0px, 10px) random(0px, 10px); + inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); + border-top-right-radius: random(0px, 10px); + border-top-left-radius: random(0px, 10px); + border-bottom-right-radius: random(--foo, 0px, 10px); + border-bottom-left-radius: random(--foo, 0px, 10px); +} + +.random-15 { + padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); + margin: random(0px, 10px) random(0px, 10px); + inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); + border-top-right-radius: random(0px, 10px); + border-top-left-radius: random(0px, 10px); + border-bottom-right-radius: random(--foo, 0px, 10px); + border-bottom-left-radius: random(--foo, 0px, 10px); +} + +.random-15-b { + padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); + margin: random(0px, 10px) random(0px, 10px); + inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); + border-top-right-radius: random(0px, 10px); + border-top-left-radius: random(0px, 10px); + border-bottom-right-radius: random(--foo, 0px, 10px); + border-bottom-left-radius: random(--foo, 0px, 10px); +} + +.random-16 { + margin: random(element-shared, 0px, 10px) random(element-shared, 0px, 10px); + inset: random(--foo element-shared, 0px, 10px) random(--foo element-shared, 0px, 10px); + border-top-right-radius: random(element-shared, 0px, 10px); + border-top-left-radius: random(element-shared, 0px, 10px); + border-bottom-right-radius: random(--foo element-shared, 0px, 10px); + border-bottom-left-radius: random(--foo element-shared, 0px, 10px); +} + +.random-16 { + margin: random(element-shared, 0px, 10px) random(element-shared, 0px, 10px); + inset: random(--foo element-shared, 0px, 10px) random(--foo element-shared, 0px, 10px); + border-top-right-radius: random(element-shared, 0px, 10px); + border-top-left-radius: random(element-shared, 0px, 10px); + border-bottom-right-radius: random(--foo element-shared, 0px, 10px); + border-bottom-left-radius: random(--foo element-shared, 0px, 10px); +} + +.random-16-b { + margin: random(element-shared, 0px, 10px) random(element-shared, 0px, 10px); + inset: random(--foo element-shared, 0px, 10px) random(--foo element-shared, 0px, 10px); + border-top-right-radius: random(element-shared, 0px, 10px); + border-top-left-radius: random(element-shared, 0px, 10px); + border-bottom-right-radius: random(--foo element-shared, 0px, 10px); + border-bottom-left-radius: random(--foo element-shared, 0px, 10px); +} + .ignore-1 { --foo: 10px; width: random(0px, var(--foo)); diff --git a/plugins/postcss-random-function/test/basic.expect.css b/plugins/postcss-random-function/test/basic.expect.css index 593a15545e..6ec2307b56 100644 --- a/plugins/postcss-random-function/test/basic.expect.css +++ b/plugins/postcss-random-function/test/basic.expect.css @@ -1,33 +1,90 @@ .random-1 { - z-index: 2.59248; + z-index: 5.21287; } .random-2 { - z-index: 2; + z-index: random(0, 10 1); } .random-3 { - z-index: 2.06974; + z-index: 9.78963; } .random-4 { - z-index: 4.78814; + z-index: 1.76681; } .random-11 { - width: 4.63961px; + width: 3.73222px; } .random-12 { - width: 7px; + width: random(0px, 10px 1px); } .random-13 { - width: 4.81303px; + width: 5.98171px; } .random-14 { - width: 2.1821px; + width: 6.22777px; +} + +.random-15 { + padding: 5px 5px; + margin: 1.63012px 5.06483px; + inset: 7.06555px 7.06555px; + border-top-right-radius: 5.28165px; + border-top-left-radius: 5.16324px; + border-bottom-right-radius: 7.06555px; + border-bottom-left-radius: 7.06555px; +} + +.random-15 { + padding: 5px 5px; + margin: 1.63012px 5.06483px; + inset: 7.06555px 7.06555px; + border-top-right-radius: 5.28165px; + border-top-left-radius: 5.16324px; + border-bottom-right-radius: 7.06555px; + border-bottom-left-radius: 7.06555px; +} + +.random-15-b { + padding: 5px 5px; + margin: 7.47638px 7.02446px; + inset: 8.49751px 8.49751px; + border-top-right-radius: 8.99482px; + border-top-left-radius: 7.27335px; + border-bottom-right-radius: 8.49751px; + border-bottom-left-radius: 8.49751px; +} + +.random-16 { + margin: 8.81978px 3.54399px; + inset: 7.51683px 7.51683px; + border-top-right-radius: 5.60447px; + border-top-left-radius: 9.87151px; + border-bottom-right-radius: 7.51683px; + border-bottom-left-radius: 7.51683px; +} + +.random-16 { + margin: 8.81978px 3.54399px; + inset: 7.51683px 7.51683px; + border-top-right-radius: 5.60447px; + border-top-left-radius: 9.87151px; + border-bottom-right-radius: 7.51683px; + border-bottom-left-radius: 7.51683px; +} + +.random-16-b { + margin: 8.81978px 3.54399px; + inset: 7.51683px 7.51683px; + border-top-right-radius: 5.60447px; + border-top-left-radius: 9.87151px; + border-bottom-right-radius: 7.51683px; + border-bottom-left-radius: 7.51683px; } .ignore-1 { diff --git a/plugins/postcss-random-function/test/basic.preserve-true.expect.css b/plugins/postcss-random-function/test/basic.preserve-true.expect.css index dfd6bbb253..967db5f2c8 100644 --- a/plugins/postcss-random-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-random-function/test/basic.preserve-true.expect.css @@ -1,43 +1,137 @@ .random-1 { - z-index: 2.59248; + z-index: 5.21287; z-index: random(0, 10); } .random-2 { - z-index: 2; - z-index: random(0, 10, by 1); + z-index: random(0, 10 1); } .random-3 { - z-index: 2.06974; + z-index: 9.78963; z-index: random(--foo, 0, 10); } .random-4 { - z-index: 4.78814; + z-index: 1.76681; z-index: random(--bar, 0, 10); } .random-11 { - width: 4.63961px; + width: 3.73222px; width: random(0px, 10px); } .random-12 { - width: 7px; - width: random(0px, 10px, by 1px); + width: random(0px, 10px 1px); } .random-13 { - width: 4.81303px; + width: 5.98171px; width: random(--foo, 0px, 10px); } .random-14 { - width: 2.1821px; + width: 6.22777px; width: random(--bar, 0px, 10px); } +.random-15 { + padding: 5px 5px; + padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); + margin: 1.63012px 5.06483px; + margin: random(0px, 10px) random(0px, 10px); + inset: 7.06555px 7.06555px; + inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); + border-top-right-radius: 5.28165px; + border-top-right-radius: random(0px, 10px); + border-top-left-radius: 5.16324px; + border-top-left-radius: random(0px, 10px); + border-bottom-right-radius: 7.06555px; + border-bottom-right-radius: random(--foo, 0px, 10px); + border-bottom-left-radius: 7.06555px; + border-bottom-left-radius: random(--foo, 0px, 10px); +} + +.random-15 { + padding: 5px 5px; + padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); + margin: 1.63012px 5.06483px; + margin: random(0px, 10px) random(0px, 10px); + inset: 7.06555px 7.06555px; + inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); + border-top-right-radius: 5.28165px; + border-top-right-radius: random(0px, 10px); + border-top-left-radius: 5.16324px; + border-top-left-radius: random(0px, 10px); + border-bottom-right-radius: 7.06555px; + border-bottom-right-radius: random(--foo, 0px, 10px); + border-bottom-left-radius: 7.06555px; + border-bottom-left-radius: random(--foo, 0px, 10px); +} + +.random-15-b { + padding: 5px 5px; + padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); + margin: 7.47638px 7.02446px; + margin: random(0px, 10px) random(0px, 10px); + inset: 8.49751px 8.49751px; + inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); + border-top-right-radius: 8.99482px; + border-top-right-radius: random(0px, 10px); + border-top-left-radius: 7.27335px; + border-top-left-radius: random(0px, 10px); + border-bottom-right-radius: 8.49751px; + border-bottom-right-radius: random(--foo, 0px, 10px); + border-bottom-left-radius: 8.49751px; + border-bottom-left-radius: random(--foo, 0px, 10px); +} + +.random-16 { + margin: 8.81978px 3.54399px; + margin: random(element-shared, 0px, 10px) random(element-shared, 0px, 10px); + inset: 7.51683px 7.51683px; + inset: random(--foo element-shared, 0px, 10px) random(--foo element-shared, 0px, 10px); + border-top-right-radius: 5.60447px; + border-top-right-radius: random(element-shared, 0px, 10px); + border-top-left-radius: 9.87151px; + border-top-left-radius: random(element-shared, 0px, 10px); + border-bottom-right-radius: 7.51683px; + border-bottom-right-radius: random(--foo element-shared, 0px, 10px); + border-bottom-left-radius: 7.51683px; + border-bottom-left-radius: random(--foo element-shared, 0px, 10px); +} + +.random-16 { + margin: 8.81978px 3.54399px; + margin: random(element-shared, 0px, 10px) random(element-shared, 0px, 10px); + inset: 7.51683px 7.51683px; + inset: random(--foo element-shared, 0px, 10px) random(--foo element-shared, 0px, 10px); + border-top-right-radius: 5.60447px; + border-top-right-radius: random(element-shared, 0px, 10px); + border-top-left-radius: 9.87151px; + border-top-left-radius: random(element-shared, 0px, 10px); + border-bottom-right-radius: 7.51683px; + border-bottom-right-radius: random(--foo element-shared, 0px, 10px); + border-bottom-left-radius: 7.51683px; + border-bottom-left-radius: random(--foo element-shared, 0px, 10px); +} + +.random-16-b { + margin: 8.81978px 3.54399px; + margin: random(element-shared, 0px, 10px) random(element-shared, 0px, 10px); + inset: 7.51683px 7.51683px; + inset: random(--foo element-shared, 0px, 10px) random(--foo element-shared, 0px, 10px); + border-top-right-radius: 5.60447px; + border-top-right-radius: random(element-shared, 0px, 10px); + border-top-left-radius: 9.87151px; + border-top-left-radius: random(element-shared, 0px, 10px); + border-bottom-right-radius: 7.51683px; + border-bottom-right-radius: random(--foo element-shared, 0px, 10px); + border-bottom-left-radius: 7.51683px; + border-bottom-left-radius: random(--foo element-shared, 0px, 10px); +} + .ignore-1 { --foo: 10px; width: random(0px, var(--foo)); diff --git a/plugins/postcss-random-function/test/examples/example.css b/plugins/postcss-random-function/test/examples/example.css index fd1e2d7d8d..360e7f66ac 100644 --- a/plugins/postcss-random-function/test/examples/example.css +++ b/plugins/postcss-random-function/test/examples/example.css @@ -1,12 +1,12 @@ div { - color: oklch(0.7, 0.2, random(120deg, 240deg)); + color: oklch(0.7 0.2 random(120deg, 240deg)); } div { - color: oklch(0.7, 0.2, random(120deg, 240deg, by 7deg)); + color: oklch(0.7 0.2 random(120deg, 240deg, 7deg)); } div { - color: oklch(0.7, 0.2, random(--text, 120deg, 240deg)); - border-color: oklch(0.7, 0.2, random(--border, 120deg, 240deg)); + margin: random(10px, 100px) random(10px, 100px); + padding: random(--padding, 10px, 100px) random(--padding, 10px, 100px); } diff --git a/plugins/postcss-random-function/test/examples/example.expect.css b/plugins/postcss-random-function/test/examples/example.expect.css index ec244174a9..993cac467d 100644 --- a/plugins/postcss-random-function/test/examples/example.expect.css +++ b/plugins/postcss-random-function/test/examples/example.expect.css @@ -1,12 +1,12 @@ div { - color: oklch(0.7, 0.2, 238.66036deg); + color: oklch(0.7 0.2 177.17235deg); } div { - color: oklch(0.7, 0.2, 134deg); + color: oklch(0.7 0.2 176deg); } div { - color: oklch(0.7, 0.2, 226.47057deg); - border-color: oklch(0.7, 0.2, 157.76966deg); + margin: 41.7525px 70.01679px; + padding: 44.03856px 44.03856px; } diff --git a/plugins/postcss-random-function/test/examples/example.preserve-true.expect.css b/plugins/postcss-random-function/test/examples/example.preserve-true.expect.css index 6a368cff01..19b390a308 100644 --- a/plugins/postcss-random-function/test/examples/example.preserve-true.expect.css +++ b/plugins/postcss-random-function/test/examples/example.preserve-true.expect.css @@ -1,16 +1,16 @@ div { - color: oklch(0.7, 0.2, 238.66036deg); - color: oklch(0.7, 0.2, random(120deg, 240deg)); + color: oklch(0.7 0.2 177.17235deg); + color: oklch(0.7 0.2 random(120deg, 240deg)); } div { - color: oklch(0.7, 0.2, 134deg); - color: oklch(0.7, 0.2, random(120deg, 240deg, by 7deg)); + color: oklch(0.7 0.2 176deg); + color: oklch(0.7 0.2 random(120deg, 240deg, 7deg)); } div { - color: oklch(0.7, 0.2, 226.47057deg); - color: oklch(0.7, 0.2, random(--text, 120deg, 240deg)); - border-color: oklch(0.7, 0.2, 157.76966deg); - border-color: oklch(0.7, 0.2, random(--border, 120deg, 240deg)); + margin: 41.7525px 70.01679px; + margin: random(10px, 100px) random(10px, 100px); + padding: 44.03856px 44.03856px; + padding: random(--padding, 10px, 100px) random(--padding, 10px, 100px); }