@@ -4,6 +4,7 @@ import { createRule } from '../utils/index.js';
4
4
import globals from 'globals' ;
5
5
import type { TSESTree } from '@typescript-eslint/types' ;
6
6
import { findVariable , getScope } from '../utils/ast-utils.js' ;
7
+ import type { AST } from 'svelte-eslint-parser' ;
7
8
8
9
export default createRule ( 'no-top-level-browser-globals' , {
9
10
meta : {
@@ -36,10 +37,10 @@ export default createRule('no-top-level-browser-globals', {
36
37
} ;
37
38
const maybeGuards : MaybeGuard [ ] = [ ] ;
38
39
39
- const functions : TSESTree . FunctionLike [ ] = [ ] ;
40
+ const functions : ( TSESTree . FunctionLike | AST . SvelteSnippetBlock ) [ ] = [ ] ;
40
41
const typeAnnotations : ( TSESTree . TypeNode | TSESTree . TSTypeAnnotation ) [ ] = [ ] ;
41
42
42
- function enterFunction ( node : TSESTree . FunctionLike ) {
43
+ function enterFunction ( node : TSESTree . FunctionLike | AST . SvelteSnippetBlock ) {
43
44
if ( isTopLevelLocation ( node ) ) {
44
45
functions . push ( node ) ;
45
46
}
@@ -120,6 +121,7 @@ export default createRule('no-top-level-browser-globals', {
120
121
121
122
return {
122
123
':function' : enterFunction ,
124
+ SvelteSnippetBlock : enterFunction ,
123
125
'*.typeAnnotation' : enterTypeAnnotation ,
124
126
MetaProperty : enterMetaProperty ,
125
127
'Program:exit' : verifyGlobalReferences
@@ -144,7 +146,7 @@ export default createRule('no-top-level-browser-globals', {
144
146
* Checks whether the node is in a top-level location.
145
147
* @returns `true` if the node is in a top-level location.
146
148
*/
147
- function isTopLevelLocation ( node : TSESTree . Node ) {
149
+ function isTopLevelLocation ( node : TSESTree . Node | AST . SvelteSnippetBlock ) {
148
150
for ( const func of functions ) {
149
151
if ( func . range [ 0 ] <= node . range [ 0 ] && node . range [ 1 ] <= func . range [ 1 ] ) {
150
152
return false ;
@@ -321,7 +323,7 @@ export default createRule('no-top-level-browser-globals', {
321
323
node : TSESTree . Expression ;
322
324
not ?: boolean ;
323
325
} ) : ( ( node : TSESTree . Node ) => boolean ) | null {
324
- const parent = guardInfo . node . parent ;
326
+ const parent = guardInfo . node . parent as TSESTree . Node | AST . SvelteNode ;
325
327
if ( ! parent ) return null ;
326
328
327
329
if ( parent . type === 'ConditionalExpression' ) {
@@ -331,6 +333,22 @@ export default createRule('no-top-level-browser-globals', {
331
333
if ( parent . type === 'UnaryExpression' && parent . operator === '!' ) {
332
334
return getGuardChecker ( { not : ! guardInfo . not , node : parent } ) ;
333
335
}
336
+ if ( parent . type === 'SvelteIfBlock' && parent . expression === guardInfo . node ) {
337
+ if ( ! guardInfo . not ) {
338
+ if ( parent . children . length === 0 ) {
339
+ return null ; // No block to check
340
+ }
341
+ const first = parent . children [ 0 ] ;
342
+ const last = parent . children . at ( - 1 ) ! ;
343
+ return ( n ) => first . range [ 0 ] <= n . range [ 0 ] && n . range [ 1 ] <= last . range [ 1 ] ;
344
+ }
345
+ // not
346
+ if ( parent . else ) {
347
+ const block = parent . else ;
348
+ return ( n ) => block . range [ 0 ] <= n . range [ 0 ] && n . range [ 1 ] <= block . range [ 1 ] ;
349
+ }
350
+ return null ;
351
+ }
334
352
if ( parent . type === 'IfStatement' && parent . test === guardInfo . node ) {
335
353
if ( ! guardInfo . not ) {
336
354
const block = parent . consequent ;
0 commit comments