Skip to content

Commit

Permalink
fix(plugins/web-api): add 'for of' support to 'no-leaked-event-listen… (
Browse files Browse the repository at this point in the history
  • Loading branch information
Rel1cx authored Dec 2, 2024
1 parent 87ca237 commit a3eec07
Show file tree
Hide file tree
Showing 18 changed files with 836 additions and 316 deletions.
4 changes: 2 additions & 2 deletions examples/vite-react-dom-legacy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.16.0",
"eslint-plugin-react-hooks": "rc",
"eslint-plugin-react-refresh": "^0.4.14",
"eslint-plugin-react-refresh": "^0.4.16",
"globals": "^15.13.0",
"vite": "^6.0.1"
"vite": "^6.0.2"
}
}
4 changes: 2 additions & 2 deletions examples/vite-react-dom-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.16.0",
"eslint-plugin-react-hooks": "rc",
"eslint-plugin-react-refresh": "^0.4.14",
"eslint-plugin-react-refresh": "^0.4.16",
"typescript": "^5.7.2",
"typescript-eslint": "^8.16.0",
"vite": "^6.0.1"
"vite": "^6.0.2"
}
}
4 changes: 2 additions & 2 deletions examples/vite-react-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.16.0",
"eslint-plugin-react-hooks": "rc",
"eslint-plugin-react-refresh": "^0.4.14",
"eslint-plugin-react-refresh": "^0.4.16",
"globals": "^15.13.0",
"vite": "^6.0.1"
"vite": "^6.0.2"
}
}
2 changes: 1 addition & 1 deletion examples/webpack-react-dom-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"esbuild-register": "3.6.0",
"eslint": "^9.16.0",
"eslint-plugin-react-hooks": "rc",
"eslint-plugin-react-refresh": "^0.4.14",
"eslint-plugin-react-refresh": "^0.4.16",
"eslint-webpack-plugin": "4.2.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.6.3",
Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@
"devDependencies": {
"@changesets/cli": "^2.27.10",
"@effect/language-service": "^0.2.0",
"@effect/platform": "^0.69.31",
"@effect/platform-bun": "^0.49.33",
"@effect/platform-node": "^0.64.33",
"@effect/platform": "^0.70.1",
"@effect/platform-bun": "^0.50.1",
"@effect/platform-node": "^0.65.1",
"@effect/schema": "^0.75.5",
"@eslint/config-inspector": "^0.5.6",
"@eslint/js": "^9.16.0",
Expand All @@ -67,11 +67,11 @@
"@typescript-eslint/parser": "^8.16.0",
"@typescript-eslint/rule-tester": "^8.16.0",
"@typescript-eslint/types": "^8.16.0",
"@vitest/ui": "^2.1.6",
"@vitest/ui": "^2.1.8",
"concurrently": "^9.1.0",
"cspell": "^8.16.1",
"dprint": "^0.47.5",
"effect": "^3.10.19",
"dprint": "^0.47.6",
"effect": "^3.11.1",
"esbuild": "^0.24.0",
"eslint": "^9.16.0",
"eslint-config-flat-gitignore": "^0.3.0",
Expand All @@ -87,7 +87,7 @@
"eslint-plugin-unicorn": "^56.0.1",
"eslint-plugin-vitest": "^0.5.4",
"importx": "^0.5.0",
"lefthook": "^1.8.4",
"lefthook": "^1.8.5",
"markdownlint": "^0.36.1",
"publint": "^0.2.12",
"react": "^18.3.1",
Expand All @@ -100,13 +100,13 @@
"tsup": "^8.3.5",
"tsx": "^4.19.2",
"turbo": "^2.3.3",
"type-fest": "^4.29.0",
"type-fest": "^4.29.1",
"typedoc": "^0.27.2",
"typedoc-plugin-markdown": "^4.3.0",
"typedoc-plugin-markdown": "^4.3.1",
"typedoc-plugin-rename-defaults": "^0.7.2",
"typescript": "^5.7.2",
"typescript-eslint": "^8.16.0",
"vitest": "^2.1.6"
"vitest": "^2.1.8"
},
"packageManager": "pnpm@9.14.4",
"engines": {
Expand Down
52 changes: 26 additions & 26 deletions packages/core/docs/functions/isInitializedFromReact.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Initial scope to search for the identifier

ESLint React settings

#### settings.additionalComponents
#### additionalComponents

`object`[]

Expand All @@ -44,9 +44,9 @@ This is used to inform the ESLint React plugins how to treat these components du
`[{ name: "Link", as: "a", attributes: [{ name: "to", as: "href" }, { name: "rel", defaultValue: "noopener noreferrer" }] }]`
```

#### settings.additionalHooks
#### additionalHooks

`object`
\{`use`: `string`[];`useActionState`: `string`[];`useCallback`: `string`[];`useContext`: `string`[];`useDebugValue`: `string`[];`useDeferredValue`: `string`[];`useEffect`: `string`[];`useId`: `string`[];`useImperativeHandle`: `string`[];`useInsertionEffect`: `string`[];`useLayoutEffect`: `string`[];`useMemo`: `string`[];`useOptimistic`: `string`[];`useReducer`: `string`[];`useRef`: `string`[];`useState`: `string`[];`useSyncExternalStore`: `string`[];`useTransition`: `string`[]; \}

A object of aliases for React built-in hooks.

Expand All @@ -60,79 +60,79 @@ ESLint React will recognize these aliases as equivalent to the built-in hooks in
`{ useLayoutEffect: ["useIsomorphicLayoutEffect"] }`
```

#### settings.additionalHooks.use
#### additionalHooks.use

`string`[]

#### settings.additionalHooks.useActionState
#### additionalHooks.useActionState

`string`[]

#### settings.additionalHooks.useCallback
#### additionalHooks.useCallback

`string`[]

#### settings.additionalHooks.useContext
#### additionalHooks.useContext

`string`[]

#### settings.additionalHooks.useDebugValue
#### additionalHooks.useDebugValue

`string`[]

#### settings.additionalHooks.useDeferredValue
#### additionalHooks.useDeferredValue

`string`[]

#### settings.additionalHooks.useEffect
#### additionalHooks.useEffect

`string`[]

#### settings.additionalHooks.useId
#### additionalHooks.useId

`string`[]

#### settings.additionalHooks.useImperativeHandle
#### additionalHooks.useImperativeHandle

`string`[]

#### settings.additionalHooks.useInsertionEffect
#### additionalHooks.useInsertionEffect

`string`[]

#### settings.additionalHooks.useLayoutEffect
#### additionalHooks.useLayoutEffect

`string`[]

#### settings.additionalHooks.useMemo
#### additionalHooks.useMemo

`string`[]

#### settings.additionalHooks.useOptimistic
#### additionalHooks.useOptimistic

`string`[]

#### settings.additionalHooks.useReducer
#### additionalHooks.useReducer

`string`[]

#### settings.additionalHooks.useRef
#### additionalHooks.useRef

`string`[]

#### settings.additionalHooks.useState
#### additionalHooks.useState

`string`[]

#### settings.additionalHooks.useSyncExternalStore
#### additionalHooks.useSyncExternalStore

`string`[]

#### settings.additionalHooks.useTransition
#### additionalHooks.useTransition

`string`[]

#### settings.importSource
#### importSource

`string`

Expand All @@ -152,7 +152,7 @@ This allows to specify a custom import location for React when not using the off
`"@pika/react"`
```

#### settings.jsxPragma
#### jsxPragma

`string`

Expand All @@ -162,7 +162,7 @@ The identifier that’s used for JSX Element creation.

`"createElement"`

#### settings.jsxPragmaFrag
#### jsxPragmaFrag

`string`

Expand All @@ -176,7 +176,7 @@ This should not be a member expression (i.e. use "Fragment" instead of "React.Fr

`"Fragment"`

#### settings.polymorphicPropName
#### polymorphicPropName

`string`

Expand All @@ -192,7 +192,7 @@ This is used to determine the type of the component.
`"as"`
```

#### settings.version
#### version

`string`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,67 @@ ruleTester.run(RULE_NAME, rule, {
},
],
},
{
code: /* tsx */ `
import { useEffect } from "react";
export const Component = () => {
const events = ["mousemove", "mousedown", "keydown", "scroll", "touchstart"];
const handleActivity = () => {};
useEffect(() => {
for (const evt of events) {
window.addEventListener(event, handleActivity);
}
return () => {
for (const event of events) {
window.removeEventListener(evt, handleActivity);
}
};
}, []);
return null;
};
`,
errors: [
{
messageId: "noLeakedEventListenerInEffect",
},
],
},
{
code: /* tsx */ `
import { useEffect } from "react";
export const Component = () => {
const events = ["mousemove", "mousedown", "keydown", "scroll", "touchstart"];
const handleActivity1 = () => {};
const handleActivity2 = () => {};
useEffect(() => {
for (const event of events) {
window.addEventListener(event, handleActivity1);
}
return () => {
for (const evt of events) {
window.removeEventListener(evt, handleActivity2);
}
};
}, []);
return null;
};
`,
errors: [
{
messageId: "noLeakedEventListenerInEffect",
},
],
},
],
valid: [
...allValid,
Expand Down Expand Up @@ -931,6 +992,75 @@ ruleTester.run(RULE_NAME, rule, {
};
}, []);
return null;
};
`,
/* tsx */ `
import { useEffect } from "react";
export const Component = () => {
const events = ["mousemove", "mousedown", "keydown", "scroll", "touchstart"];
const handleActivity = () => {};
useEffect(() => {
for (const event of events) {
window.addEventListener(event, handleActivity);
}
return () => {
for (const event of events) {
window.removeEventListener(event, handleActivity);
}
};
}, []);
return null;
};
`,
/* tsx */ `
import { useEffect } from "react";
export const Component = () => {
const events = ["mousemove", "mousedown", "keydown", "scroll", "touchstart"];
const handleActivity = () => {};
useEffect(() => {
for (const event of events) {
window.addEventListener(event, handleActivity);
}
return () => {
for (const evt of events) {
window.removeEventListener(evt, handleActivity);
}
};
}, []);
return null;
};
`,
/* tsx */ `
import { useEffect } from "react";
export const Component = () => {
const events = ["mousemove", "mousedown", "keydown", "scroll", "touchstart"];
const handleActivity = () => {};
useEffect(() => {
for (let event of events) {
window.addEventListener(event, handleActivity);
}
return () => {
for (let evt of events) {
window.removeEventListener(evt, handleActivity);
}
};
}, []);
return null;
};
`,
Expand Down
Loading

0 comments on commit a3eec07

Please sign in to comment.