Skip to content

Commit b2025e6

Browse files
authored
[Attr Type] Flush to spec (#4045)
1 parent a5b1736 commit b2025e6

File tree

8 files changed

+98
-10
lines changed

8 files changed

+98
-10
lines changed

accepted/attr-type.changes.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## Draft 2.0
2+
3+
* Match the name `type` case-insensitively when checking for invalid functions.
4+
5+
* Don't allow indent tokens after `%` even if it would complete a statement.
6+
7+
* Consider `attr()` calls to be special numbers now that they can be return
8+
numbers in CSS and not just strings.
9+
110
## Draft 1.1
211

312
* Add `type` to the list of forbidden function names.

accepted/attr-type.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Attr Type: Draft 1.1
1+
# Attr Type: Draft 2.0
22

33
*([Issue](https://github.com/sass/sass/issues/4030),
44
[Changelog](attr-type.changes.md))*
@@ -7,6 +7,8 @@
77

88
* [Background](#background)
99
* [Summary](#summary)
10+
* [Definitions](#definitions)
11+
* [Special Number](#special-number)
1012
* [Syntax](#syntax)
1113
* [`SpecialFunctionExpression`](#specialfunctionexpression)
1214
* [`SingleExpression`](#singleexpression)
@@ -62,6 +64,15 @@ anticipate that a single `%` will be widely used in other contexts, so we don't
6264
plan to deprecate the modulo operator, although that path is open in the future
6365
if CSS starts using this value more widely.
6466

67+
## Definitions
68+
69+
### Special Number
70+
71+
Add `attr(` to the list of unquoted string prefixes that qualify as [special
72+
numbers].
73+
74+
[special numbers]: ../spec/functions.md#special-number
75+
6576
## Syntax
6677

6778
### `SpecialFunctionExpression`
@@ -82,15 +93,28 @@ Change [the `SpecialFunctionName` production] to be:
8293
8394
### `SingleExpression`
8495

85-
Add `Percent` as a production to [`SingleExpression`] with the annotation "If
86-
this is ambiguous with part of `ProductExpression`, parse `ProductExpression`
87-
preferentially".
96+
Add `Percent` as a production to [`SingleExpression`] with the following
97+
annotation:
8898

8999
[`SingleExpression`]: ../spec/syntax.md#singleexpression
90100

101+
If this is ambiguous with part of `ProductExpression`, parse `ProductExpression`
102+
preferentially. If this is followed by a [`Whitespace`] that contains a
103+
[`LineBreak`], do not parse that `Whitespace` as part of an [`IndentSame`] or
104+
[`IndentMore`] production.
105+
106+
[`Whitespace`]: ../spec/statement.md#whitespace
107+
[`LineBreak`]: ../spec/statement.md#whitespace
108+
[`IndentSame`]: ../spec/statement.md#indentation
109+
[`IndentMore`]: ../spec/statement.md#indentation
110+
91111
> This effectively means that the unquoted string `%` is allowed everywhere
92112
> *except* in a middle element of a space-separated list, since that would be
93-
> ambiguous with a modulo operation.
113+
> ambiguous with a modulo operation. The whitespace clause ensures that a `%` at
114+
> the end of a line in the indented syntax always looks at the next token, for
115+
> backwards-compatibility with parsing it as an operator and so that whether the
116+
> statement ends on that line or not doesn't depend on the first token of the
117+
> next line.
94118
95119
### `Percent`
96120

@@ -110,7 +134,7 @@ In the [semantics for `@function`], add a bullet point below the second:
110134

111135
[semantics for `@function`]: ../spec/at-rules/function.md#semantics
112136

113-
* If `name` is `type`, throw an error.
137+
* If `name` is case-insensitively equal to `type`, throw an error.
114138

115139
> Unlike other forbidden function names, this doesn't cover vendor prefixes.
116140
> This is for two reasons: first, we don't expect to add special parsing for

js-api-doc/deprecations.d.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
export interface Deprecations {
88
// START AUTOGENERATED LIST
9-
// Checksum: 47c97f7824eb25d7f1e64e3230938b88330d40b4
9+
// Checksum: 3639e60773866019c018ae16267c8f23e4df86cf
1010

1111
/**
1212
* Deprecation for passing a string directly to meta.call().
@@ -162,6 +162,13 @@ export interface Deprecations {
162162
*/
163163
'global-builtin': Deprecation<'global-builtin'>;
164164

165+
/**
166+
* Deprecation for functions named "type".
167+
*
168+
* This deprecation became active in Dart Sass 1.86.0.
169+
*/
170+
'type-function': Deprecation<'type-function'>;
171+
165172
// END AUTOGENERATED LIST
166173

167174
/**

spec/at-rules/function.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ To execute a `@function` rule `rule`:
2323

2424
* Let `name` be the value of `rule`'s `Identifier`.
2525

26+
* If `name` is case-insensitively equal to `type`, throw an error.
27+
28+
> Unlike other forbidden function names, this doesn't cover vendor prefixes.
29+
> This is for two reasons: first, we don't expect to add special parsing for
30+
> `type()` with vendor prefixes. Second, "type" is a relatively common word,
31+
> so it's likely for private function names to end with `-type` in a way that
32+
> could be indistinguishable from a vendor prefix.
33+
2634
* If `name` begins with `--`, throw an error.
2735

2836
* If `name` is `calc`, `element`, `expression`, `url`, `and`, `or`, or `not`, or

spec/deprecations.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,9 @@ global-builtin:
147147
dart-sass:
148148
status: active
149149
deprecated: 1.80.0
150+
151+
type-function:
152+
description: 'Functions named "type".'
153+
dart-sass:
154+
status: active
155+
deprecated: 1.86.0

spec/functions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ A *special number* is either:
3131
* a [calculation], or
3232
* an unquoted string that CSS will recognize as a function that may return a
3333
number. For the purposes of Sass, this is any unquoted string that begins with
34-
`calc(`, `var(`, `env(`, `clamp(`, `min(`, or `max(`. This matching is
35-
case-insensitive.
34+
`calc(`, `var(`, `env(`, `attr(`, `clamp(`, `min(`, or `max(`. This matching
35+
is case-insensitive.
3636

3737
[calculation]: types/calculation.md
3838

spec/js-api/deprecations.d.ts.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
### `Deprecations`
3030

3131
<!-- START AUTOGENERATED LIST -->
32-
<!-- Checksum: 47c97f7824eb25d7f1e64e3230938b88330d40b4 -->
32+
<!-- Checksum: 3639e60773866019c018ae16267c8f23e4df86cf -->
3333
```ts
3434
export interface Deprecations {
3535
'call-string': Deprecation<'call-string'>;
@@ -54,6 +54,7 @@ export interface Deprecations {
5454
'legacy-js-api': Deprecation<'legacy-js-api'>;
5555
import: Deprecation<'import'>;
5656
'global-builtin': Deprecation<'global-builtin'>;
57+
'type-function': Deprecation<'type-function'>;
5758
'user-authored': Deprecation<'user-authored', 'user'>;
5859
}
5960
```

spec/syntax.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* [Consuming a Name](#consuming-a-name)
2424
* [Consuming an Escaped Code Point](#consuming-an-escaped-code-point)
2525
* [Consuming a special function](#consuming-a-special-function)
26+
* [Semantics](#semantics)
27+
* [`Percent`](#percent)
2628

2729
## Definitions
2830

@@ -173,6 +175,8 @@ parentheses.
173175
&#32; | UnaryExpression
174176
&#32; | UnicodeRange
175177
&#32; | [Variable]
178+
&#32; | Percent³
179+
**Percent** ::= '%'
176180
</pre></x>
177181

178182
[BracketedListExpression]: types/list.md#syntax
@@ -185,6 +189,24 @@ parentheses.
185189
2: If this is ambiguous with any other production, parse the other production
186190
preferentially.
187191

192+
3: If this is ambiguous with part of `ProductExpression`, parse
193+
`ProductExpression` preferentially. If this is followed by a [`Whitespace`]
194+
that contains a [`LineBreak`], do not parse that `Whitespace` as part of an
195+
[`IndentSame`] or [`IndentMore`] production.
196+
197+
> This effectively means that the unquoted string `%` is allowed everywhere
198+
> *except* in a middle element of a space-separated list, since that would be
199+
> ambiguous with a modulo operation. The whitespace clause ensures that a `%`
200+
> at the end of a line in the indented syntax always looks at the next token,
201+
> for backwards-compatibility with parsing it as an operator and so that
202+
> whether the statement ends on that line or not doesn't depend on the first
203+
> token of the next line.
204+
205+
[`Whitespace`]: statement.md#whitespace
206+
[`LineBreak`]: statement.md#whitespace
207+
[`IndentSame`]: statement.md#indentation
208+
[`IndentMore`]: statement.md#indentation
209+
188210
### `SpecialFunctionExpression`
189211

190212
> These functions are "special" in the sense that their arguments don't use the
@@ -195,9 +217,14 @@ parentheses.
195217
**SpecialFunctionExpression** ::= SpecialFunctionName InterpolatedDeclarationValue ')'
196218
**SpecialFunctionName**¹ ::= VendorPrefix? ('element(' | 'expression(')
197219
&#32; | VendorPrefix 'calc('
220+
&#32; | 'type('
198221
**VendorPrefix**¹ ::= '-' ([identifier-start code point] | [digit]) '-'
199222
</pre></x>
200223

224+
> No browser has yet supported `type()` with a vendor prefix, nor are they
225+
> likely to do so in the future given that vendor prefixes are largely unpopular
226+
> now.
227+
201228
[digit]: https://drafts.csswg.org/css-syntax-3/#digit
202229

203230
1: Both `SpecialFunctionName` and `VendorPrefix` are matched case-insensitively,
@@ -477,3 +504,9 @@ SassScript expression.
477504
* Return an unquoted interpolated string expression that would be identical to
478505
the source text according to CSS semantics for all possible interpolated
479506
strings.
507+
508+
## Semantics
509+
510+
### `Percent`
511+
512+
To evaluate a `Percent`, return an unquoted string with the value `%`.

0 commit comments

Comments
 (0)