@@ -15,6 +15,7 @@ Default Highlight: css
1515
1616<pre class=link-defaults>
1717spec:infra; type:dfn; text:list
18+ spec:infra; type:dfn; for:list; text:append
1819spec:css-properties-values-api; type:dfn; text:supported syntax component name
1920spec:css-properties-values-api; type:dfn; text:syntax component
2021spec:css-syntax-3; type:dfn; text:declaration
@@ -83,20 +84,13 @@ Defining Custom Functions {#defining-custom-functions}
8384
8485 A <dfn>custom function</dfn> consists of a name (<<function-name>> ),
8586 a list of [=function parameter|parameters=] ,
86- a list of [=function dependency|dependencies=] ,
8787 a function body,
8888 and optionally a <dfn>return type</dfn> described by a [=syntax definition=] .
8989
9090 A <dfn>function parameter</dfn> consists of a name (<<custom-property-name>> );
9191 optionally a <dfn>parameter type</dfn> , described by a [=syntax definition=] ;
9292 and optionally a <dfn>default value</dfn> .
9393
94- A <dfn>function dependency</dfn> ,
95- is a special [=function parameter=] ,
96- that represents
97- a [=local variable=] , [=function parameter=] , or [=custom property=]
98- being implicitly passed as an argument from the calling context.
99-
10094The <dfn>@function</dfn> Rule {#function-rule}
10195----------------------------------------------
10296
@@ -105,14 +99,12 @@ and its syntax is:
10599
106100<pre class="prod def" nohighlight>
107101<@function> = @function <<function-name>> <<function-parameter-list>> ? )
108- [ using ( <<function-dependency-list>> ) ]?
109102 [ returns <<css-type>> ]?
110103{
111104 <<declaration-rule-list>>
112105}
113106
114107<dfn><<function-parameter-list>></dfn> = <<function-parameter>> #
115- <dfn><<function-dependency-list>></dfn> = <<function-parameter>> #
116108<dfn><<function-parameter>></dfn> = <<custom-property-name>> <<css-type>> ? [ : <<declaration-value>> ]?
117109<dfn><<css-type>></dfn> = <<syntax-component>> | <<type()>>
118110<dfn function lt="type()" for="@function"><type()></dfn> = type( <<syntax>> )
@@ -125,12 +117,10 @@ with the additional restriction that it must start with two dashes
125117
126118The name of the resulting [=custom function=] is given by the <<function-name>> ,
127119the [=function parameters=] are optionally given by <<function-parameter-list>> ,
128- the [=function dependencies=] are optionally given by <<function-dependency-list>> ,
129120and the [=return type=] is optionally given by the <<css-type>> following the "returns" keyword.
130121
131122<div class='example'>
132- If the <<css-type>> of a [=function parameter=] ,
133- [=function dependency=] ,
123+ If the <<css-type>> of a [=function parameter=]
134124 or [=custom function=] return value
135125 can be described by a single <<syntax-component>> ,
136126 then the ''type()'' function may be omitted:
@@ -150,8 +140,6 @@ and the [=return type=] is optionally given by the <<css-type>> following the "r
150140 </pre>
151141</div>
152142
153- Issue: Should duplicates be disallowed <em> across</em> parameters/dependencies
154- as well?
155143
156144If more than one ''@function'' exists for a given name,
157145then the rule in the stronger cascade layer wins,
@@ -161,8 +149,6 @@ The <<function-name>> of a ''@function'' rule is a [=tree-scoped name=].
161149
162150If the <<function-parameter-list>>
163151contains the same <<custom-property-name>> more than once,
164- or if the <<function-dependency-list>>
165- contains the same <<custom-property-name>> more than once,
166152then the ''@function'' rule is invalid.
167153
168154The body of a ''@function'' rule accepts [=conditional group rules=] ,
@@ -191,7 +177,7 @@ The '@function/result' descriptor
191177determines the result of [=evaluate a custom function|evaluating=]
192178the [=custom function=] that is defined by a ''@function'' rule.
193179Using [=locally substitute a var()|locally substituted=] ''var()'' functions,
194- it can reference [=function parameters=] , [=function dependencies=] , [= local variables=] ,
180+ it can reference [=function parameters=] , [=local variables=] ,
195181as well as other [=custom functions=] via <<dashed-function>> s.
196182
197183The '@function/result' descriptor itself does not have a type,
@@ -246,23 +232,24 @@ described in [[!css-variables]].
246232 1. Let |function| be the result of dereferencing
247233 the |dashed function|'s name as a [=tree-scoped reference=] .
248234 If no such name exists, return failure.
249- 2. Let |dependency values| be an initially empty [=list=] .
250- 3. For each |dependency| in |function|'s [=function dependency|dependencies=] :
251- * Let |dependency value| be the value that would be substituted
252- if a ''var()'' function had been specified explicitly
253- at the end of |dashed function|'s argument list,
254- with |dependency| as its only argument.
255- * If that substitution would have made a containing declaration
256- [=invalid at computed-value time=] ,
257- set |dependency value| to the [=guaranteed-invalid value=] .
258- * Append the result of [=resolving an argument=] to |dependency values|,
259- using |dependency value| as value,
260- and |dependency| as parameter.
235+ 2. Let |dependencies| be an initially empty [=list=] .
236+ 3. For every possible argument to ''var()'' (with no fallback)
237+ that would lead to a valid [=locally substitute a var()|local substitution=]
238+ in place of |dashed function|:
239+ [=append=] a [=declaration=] to |dependencies|
240+ with that argument as the name,
241+ and the substitution value as the value.
242+
243+ Note: This exposes any [=custom properties=] , [=local variables=] ,
244+ and [=function parameters=] that are visible
245+ in any given context
246+ to [=custom functions=] invoked by that context.
247+
261248 4. [=substitute arbitrary substitution functions|Substitute=]
262249 any [=arbitrary substitution functions=]
263250 within |dashed function|'s arguments.
264251 5. [=Evaluate a custom function=] ,
265- using |function|, |dashed function| and |dependency values |.
252+ using |function|, |dashed function| and |dependencies |.
266253 6. If failure was returned, return failure.
267254 7. Otherwise,
268255 replace the <<dashed-function>> with the [=equivalent token sequence=]
@@ -281,7 +268,7 @@ Evaluating Custom Functions {#evaluating-custom-functions}
281268 To <dfn>evaluate a custom function</dfn> ,
282269 with |function| being a [=custom function=] ,
283270 |dashed function| being the <<dashed-function>> invoking that |function|,
284- and |dependency values | being a [=list=] of values .
271+ and |dependencies | being a [=list=] of [=declarations=] .
285272
286273 1. If the number of values in |dashed function|'s argument list
287274 is greater than the number of values in |function|'s [=function parameter|parameters=] ,
@@ -297,7 +284,7 @@ Evaluating Custom Functions {#evaluating-custom-functions}
297284 and |parameter| as parameter.
298285 3. Let |result| be the [=resolved local value=]
299286 of the '@function/result' descriptor,
300- using |function|, |dashed function|, and |dependency values |.
287+ using |function|, |dashed function|, and |dependencies |.
301288 4. If |function| has a [=return type=] ,
302289 set |result| to the result of [=resolve a typed value|resolving a typed value=] ,
303290 using |result| as the value,
@@ -367,25 +354,26 @@ Evaluating Custom Functions {#evaluating-custom-functions}
367354Parameters and Locals {#parameters}
368355-----------------------------------
369356
370- The [=function parameters=] and [=function dependencies=] of a [=custom function=]
357+ The [=function parameters=] of a [=custom function=]
371358 are available for [=locally substitute a var()|local substitution=]
372359 as if they were declared as [=local variables=]
373360 at the start of the ''@function'' rule body.
374361
375362 Note: A [=local variable=] with the same name
376- as a [=function parameter=] / [=function dependency=] is allowed,
377- but will make the parameter/dependency unreachable
363+ as a [=function parameter=] is allowed,
364+ but will make the parameter unreachable
378365 for [=locally substitute a var()|substitution=]
379366
380367 A <dfn>local variable</dfn>
381368 is a custom property defined with the body of a [=custom function=] .
382- It is only visible within the function where it is defined.
369+ It is visible within the function where it is defined,
370+ and within other [=custom functions=] invoked by that function.
383371
384372<div algorithm>
385373 To <dfn>locally substitute a var()</dfn> within a value,
386374 with |function| being a [=custom function=] ,
387375 |dashed function| being the <<dashed-function>> invoking that |function|,
388- and |dependency values | being a [=list=] of values :
376+ and |dependencies | being a [=list=] of [=declarations=] :
389377
390378 1. Let |substitution value| be one of the following options,
391379 depending on the [=custom property=] named in the first argument of the ''var()'' function:
@@ -397,9 +385,9 @@ Parameters and Locals {#parameters}
397385 : Otherwise, if the [=custom property=] name matches a [=function parameter|parameter=] within |function|
398386 :: The corresponding argument value within the |dashed function|.
399387
400- : Otherwise, if the [=custom property=] name matches a [=function dependency|dependency=] within |function|
401- :: The corresponding value of that [=function dependency|dependency=]
402- within |dependency values| .
388+ : Otherwise, if the [=custom property=] name matches the name
389+ of a [=declaration=] within |dependencies|
390+ :: The corresponding value of that [=declaration=] .
403391
404392 : Otherwise
405393 :: The [=guaranteed-invalid value=] .
@@ -426,6 +414,39 @@ If any substitution algorithm returns failure,
426414then the [=resolved local value=] of a [=local variable=]
427415is the [=guaranteed-invalid value=] .
428416
417+ <div class='example'>
418+ A [=custom function=] can access [=local variables=]
419+ and [=function parameters=]
420+ from functions higher up in the call stack:
421+
422+ <pre class='lang-css'>
423+ @function --foo(--x) {
424+ --y: 2;
425+ result: --bar();
426+ }
427+ @function --bar() returns <number> {
428+ result: calc(var(--x) + var(--y));
429+ }
430+ div {
431+ z-index: --foo(1); /* 3 */
432+ }
433+ </pre>
434+
435+ Similarly, [=custom properties=] are implicitly available:
436+
437+ <pre class='lang-css'>
438+ @function --double-z() returns <number> {
439+ result: calc(var(--z) * 2);
440+ }
441+ div {
442+ --z: 3;
443+ z-index: --double-z(); /* 6 */
444+ }
445+ </pre>
446+
447+ </div>
448+
449+
429450Cycles {#cycles}
430451----------------
431452
0 commit comments