@eslint/css-tree 3.6.6 → 3.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -185,10 +185,27 @@ One of CDN services like `unpkg` or `jsDelivr` can be used. By default (for shor
185
185
 
186
186
  MIT
187
187
 
188
-
189
188
  ## Branch Setup and Development
190
189
 
191
190
  * `main` - the default branch for new development in the fork repo
192
191
  * `upstream` - kept in sync with `csstree/csstree`
193
192
 
194
193
  When merging in changes from `csstree/csstree`, sync `upstream` in the GitHub UI (if possible). Then send a pull request to `main` to work through any merge conflicts.
194
+
195
+ <!-- NOTE: This section is autogenerated. Do not manually edit.-->
196
+ <!--sponsorsstart-->
197
+
198
+ ## Sponsors
199
+
200
+ The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate)
201
+ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
202
+
203
+ <h3>Platinum Sponsors</h3>
204
+ <p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
205
+ <p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3>
206
+ <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
207
+ <p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
208
+ <h3>Technology Sponsors</h3>
209
+ Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
210
+ <p><a href="https://netlify.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/netlify-icon.svg" alt="Netlify" height="32"></a> <a href="https://algolia.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/algolia-icon.svg" alt="Algolia" height="32"></a> <a href="https://1password.com"><img src="https://raw.githubusercontent.com/eslint/eslint.org/main/src/assets/images/techsponsors/1password-icon.svg" alt="1Password" height="32"></a></p>
211
+ <!--sponsorsend-->
@@ -56,8 +56,31 @@ function isElementSelectorStart() {
56
56
  }
57
57
 
58
58
  function isSelectorStart() {
59
- return this.tokenType === types.Delim && selectorStarts.has(this.source.charCodeAt(this.tokenStart)) ||
60
- this.tokenType === types.Hash || this.tokenType === types.LeftSquareBracket ||
59
+ // Check for Delim tokens that might be selector starts
60
+ if (this.tokenType === types.Delim && selectorStarts.has(this.source.charCodeAt(this.tokenStart))) {
61
+ const code = this.source.charCodeAt(this.tokenStart);
62
+
63
+ // Special case: browser hack prefixes (*, +, &) followed immediately by an ident
64
+ // (no whitespace) are declarations, not selectors. Examples: *zoom: 1; +width: 100px; &prop: value;
65
+ if (code === STAR || code === PLUSSIGN || code === AMPERSAND) {
66
+ const nextToken = this.lookupType(1);
67
+ const nextTokenNonSC = this.lookupTypeNonSC(1);
68
+
69
+ // If next token is Ident and there's no whitespace between, it's a declaration
70
+ if (nextToken === types.Ident && nextTokenNonSC === types.Ident) {
71
+ return false;
72
+ }
73
+ }
74
+ return true;
75
+ }
76
+
77
+ // Hash can be either a Hash token (#id selector) or Delim(#) + Ident (browser hack)
78
+ // When it's a Hash token, it's a selector. When it's Delim, check if followed by Ident without whitespace
79
+ if (this.tokenType === types.Hash) {
80
+ return true;
81
+ }
82
+
83
+ return this.tokenType === types.LeftSquareBracket ||
61
84
  this.tokenType === types.Colon || isElementSelectorStart.call(this);
62
85
  }
63
86
 
@@ -3,11 +3,61 @@
3
3
  const types = require('../../tokenizer/types.cjs');
4
4
 
5
5
  const AMPERSAND = 0x0026; // U+0026 AMPERSAND (&)
6
+ const DOT = 0x002E; // U+002E FULL STOP (.)
7
+ const STAR = 0x002A; // U+002A ASTERISK (*);
8
+ const PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
9
+ const GREATERTHANSIGN = 0x003E; // U+003E GREATER-THAN SIGN (>)
10
+ const TILDE = 0x007E; // U+007E TILDE (~)
11
+
12
+ const selectorStarts = new Set([
13
+ AMPERSAND,
14
+ DOT,
15
+ STAR,
16
+ PLUSSIGN,
17
+ GREATERTHANSIGN,
18
+ TILDE
19
+ ]);
6
20
 
7
21
  function consumeRaw() {
8
22
  return this.Raw(this.consumeUntilSemicolonIncluded, true);
9
23
  }
10
24
 
25
+ function isElementSelectorStart() {
26
+ if (this.tokenType !== types.Ident) {
27
+ return false;
28
+ }
29
+
30
+ const nextTokenType = this.lookupTypeNonSC(1);
31
+
32
+ // Simple case: if next token is not colon, semicolon, or closing brace, it's likely a selector
33
+ if (nextTokenType !== types.Colon && nextTokenType !== types.Semicolon && nextTokenType !== types.RightCurlyBracket) {
34
+ return true;
35
+ }
36
+
37
+ // Special handling for colon case - could be pseudo-class/pseudo-element
38
+ if (nextTokenType === types.Colon) {
39
+ // Look ahead further to see what follows the colon
40
+ const afterColonType = this.lookupTypeNonSC(2);
41
+
42
+ // If after colon there's an identifier (pseudo-class/pseudo-element name),
43
+ // check what comes after that
44
+ if (afterColonType === types.Ident) {
45
+ const afterPseudoType = this.lookupTypeNonSC(3);
46
+ // If it's followed by { or other selector tokens, it's a selector
47
+ // If it's followed by ; or } or EOF, it's not a selector (property)
48
+ return afterPseudoType !== types.Semicolon && afterPseudoType !== types.RightCurlyBracket && afterPseudoType !== 0; // 0 is EOF
49
+ }
50
+ }
51
+
52
+ return false;
53
+ }
54
+
55
+ function isSelectorStart() {
56
+ return this.tokenType === types.Delim && selectorStarts.has(this.source.charCodeAt(this.tokenStart)) ||
57
+ this.tokenType === types.Hash || this.tokenType === types.LeftSquareBracket ||
58
+ this.tokenType === types.Colon || isElementSelectorStart.call(this);
59
+ }
60
+
11
61
  const name = 'DeclarationList';
12
62
  const structure = {
13
63
  children: [[
@@ -33,7 +83,7 @@ function parse() {
33
83
  break;
34
84
 
35
85
  default:
36
- if (this.isDelim(AMPERSAND)) {
86
+ if (isSelectorStart.call(this)) {
37
87
  children.push(this.parseWithFallback(this.Rule, consumeRaw));
38
88
  } else {
39
89
  children.push(this.parseWithFallback(this.Declaration, consumeRaw));
@@ -11,6 +11,20 @@ function eatIdentifierOrAsterisk() {
11
11
  this.error('Identifier or asterisk is expected');
12
12
  }
13
13
 
14
+ // Check if asterisk is followed immediately by an ident (no whitespace)
15
+ // This is invalid in selectors (e.g., "*foo" should error, "* foo" or "*:hover" is ok)
16
+ if (this.isDelim(ASTERISK)) {
17
+ const currentTokenEnd = this.tokenStart + 1; // asterisk is 1 char
18
+ this.next();
19
+
20
+ // If next token is an ident and starts immediately after asterisk, it's an error
21
+ if (this.tokenType === types.Ident && this.tokenStart === currentTokenEnd) {
22
+ this.error('Whitespace is required between universal selector and type selector');
23
+ }
24
+
25
+ return;
26
+ }
27
+
14
28
  this.next();
15
29
  }
16
30