diff --git a/.changeset/thick-boxes-warn.md b/.changeset/thick-boxes-warn.md new file mode 100644 index 000000000..acb45f2ee --- /dev/null +++ b/.changeset/thick-boxes-warn.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-svelte": minor +--- + +feat: add `svelte/no-dom-manipulating` rule diff --git a/.stylelintignore b/.stylelintignore index 9a04d6db8..4ddb7e08d 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -14,3 +14,4 @@ LICENSE *.md /docs-svelte-kit/ /coverage +/build diff --git a/README.md b/README.md index 1415dfc3c..bc6695189 100644 --- a/README.md +++ b/README.md @@ -298,6 +298,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | Rule ID | Description | | |:--------|:------------|:---| +| [svelte/no-dom-manipulating](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dom-manipulating/) | disallow DOM manipulating | | | [svelte/no-dupe-else-if-blocks](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dupe-else-if-blocks/) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-style-properties](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dupe-style-properties/) | disallow duplicate style properties | :star: | | [svelte/no-dynamic-slot-name](https://ota-meshi.github.io/eslint-plugin-svelte/rules/no-dynamic-slot-name/) | disallow dynamic slot name | :star::wrench: | diff --git a/docs/rules.md b/docs/rules.md index 075eb2911..953e7c266 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -16,6 +16,7 @@ These rules relate to possible syntax or logic errors in Svelte code: | Rule ID | Description | | |:--------|:------------|:---| +| [svelte/no-dom-manipulating](./rules/no-dom-manipulating.md) | disallow DOM manipulating | | | [svelte/no-dupe-else-if-blocks](./rules/no-dupe-else-if-blocks.md) | disallow duplicate conditions in `{#if}` / `{:else if}` chains | :star: | | [svelte/no-dupe-style-properties](./rules/no-dupe-style-properties.md) | disallow duplicate style properties | :star: | | [svelte/no-dynamic-slot-name](./rules/no-dynamic-slot-name.md) | disallow dynamic slot name | :star::wrench: | diff --git a/docs/rules/no-dom-manipulating.md b/docs/rules/no-dom-manipulating.md new file mode 100644 index 000000000..21f3aa6dd --- /dev/null +++ b/docs/rules/no-dom-manipulating.md @@ -0,0 +1,109 @@ +--- +pageClass: "rule-details" +sidebarDepth: 0 +title: "svelte/no-dom-manipulating" +description: "disallow DOM manipulating" +--- + +# svelte/no-dom-manipulating + +> disallow DOM manipulating + +- :exclamation: **_This rule has not been released yet._** + +## :book: Rule Details + +In general, DOM manipulating should delegate to Svelte runtime. If you manipulate the DOM directly, the Svelte runtime may confuse because there is a difference between the actual DOM and the Svelte runtime's expected DOM. +Therefore this rule reports where you use DOM manipulating function. +We don't recommend but If you intentionally manipulate the DOM, simply you can ignore this ESLint report. + + + + + +```svelte + + +{#if show} +
Foo
+{/if} +
+ {#if show} + Bar + {/if} +
+ + + + +``` + +
+ +This rule only tracks and checks variables given with `bind:this={}`. In other words, it doesn't track things like function arguments given to `transition:` directives. These functions have been well tested and are often used more carefully. + + + + + +```svelte + + + + +{#if visible} +

The quick brown fox jumps over the lazy dog

+{/if} +``` + +
+ +See also . + +## :wrench: Options + +Nothing. + +## :mag: Implementation + +- [Rule source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/src/rules/no-dom-manipulating.ts) +- [Test source](https://github.com/ota-meshi/eslint-plugin-svelte/blob/main/tests/src/rules/no-dom-manipulating.ts) diff --git a/src/rules/no-dom-manipulating.ts b/src/rules/no-dom-manipulating.ts new file mode 100644 index 000000000..5dd5122dd --- /dev/null +++ b/src/rules/no-dom-manipulating.ts @@ -0,0 +1,131 @@ +import type { AST } from "svelte-eslint-parser" +import type { TSESTree } from "@typescript-eslint/types" +import { createRule } from "../utils" +import { findVariable, getNodeName } from "../utils/ast-utils" +import type { Variable } from "@typescript-eslint/scope-manager" +import { getPropertyName } from "eslint-utils" + +const DOM_MANIPULATING_METHODS = new Set([ + "appendChild", // https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild + "insertBefore", // https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore + "normalize", // https://developer.mozilla.org/en-US/docs/Web/API/Node/normalize + "removeChild", // https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild + "replaceChild", // https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild + "after", // https://developer.mozilla.org/en-US/docs/Web/API/Element/after + "append", // https://developer.mozilla.org/en-US/docs/Web/API/Element/append + "before", // https://developer.mozilla.org/en-US/docs/Web/API/Element/before + "insertAdjacentElement", // https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentElement + "insertAdjacentHTML", // https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML + "insertAdjacentText", // https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText + "prepend", // https://developer.mozilla.org/en-US/docs/Web/API/Element/prepend + "remove", // https://developer.mozilla.org/en-US/docs/Web/API/Element/remove + "replaceChildren", // https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren + "replaceWith", // https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceWith +]) +const DOM_MANIPULATING_PROPERTIES = new Set([ + "textContent", // https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent + "innerHTML", // https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML + "outerHTML", // https://developer.mozilla.org/en-US/docs/Web/API/Element/outerHTML + "innerText", // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText + "outerText", // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/outerText +]) + +export default createRule("no-dom-manipulating", { + meta: { + docs: { + description: "disallow DOM manipulating", + category: "Possible Errors", + recommended: false, + }, + schema: [], + messages: { + disallowManipulateDOM: + "Don't manipulate the DOM directly. The Svelte runtime can get confused if there is a difference between the actual DOM and the DOM expected by the Svelte runtime.", + }, + type: "problem", + }, + create(context) { + const domVariables = new Set() + + /** + * Verify DOM variable identifier node + */ + function verifyIdentifier( + node: TSESTree.Identifier | TSESTree.JSXIdentifier, + ) { + const member = node.parent + if (member?.type !== "MemberExpression" || member.object !== node) { + return + } + const name = getPropertyName(member) + if (!name) { + return + } + let target: TSESTree.Expression = member + let parent = target.parent + while (parent?.type === "ChainExpression") { + target = parent + parent = parent.parent + } + if (!parent) { + return + } + if (parent.type === "CallExpression") { + if (parent.callee !== target || !DOM_MANIPULATING_METHODS.has(name)) { + return + } + } else if (parent.type === "AssignmentExpression") { + if (parent.left !== target || !DOM_MANIPULATING_PROPERTIES.has(name)) { + return + } + } + context.report({ + node: member, + messageId: "disallowManipulateDOM", + }) + } + + return { + "SvelteDirective[kind='Binding']"(node: AST.SvelteBindingDirective) { + if ( + node.key.name.name !== "this" || + !node.expression || + node.expression.type !== "Identifier" + ) { + // not bind:this={id} + return + } + const element = node.parent.parent + if (element.type !== "SvelteElement" || !isHTMLElement(element)) { + // not HTML element + return + } + const variable = findVariable(context, node.expression) + if ( + !variable || + (variable.scope.type !== "module" && variable.scope.type !== "global") + ) { + return + } + domVariables.add(variable) + }, + "Program:exit"() { + for (const variable of domVariables) { + for (const reference of variable.references) { + verifyIdentifier(reference.identifier) + } + } + }, + } + + /** + * Checks whether the given node is a HTML element or not. + */ + function isHTMLElement(node: AST.SvelteElement) { + return ( + node.kind === "html" || + (node.kind === "special" && getNodeName(node) === "svelte:element") + ) + } + }, +}) diff --git a/src/utils/ast-utils.ts b/src/utils/ast-utils.ts index 8cfb4e196..0d89cc004 100644 --- a/src/utils/ast-utils.ts +++ b/src/utils/ast-utils.ts @@ -518,19 +518,17 @@ function getAttributeValueRangeTokens( * Returns name of SvelteElement */ export function getNodeName(node: SvAST.SvelteElement): string { - if ("name" in node.name) { + if (node.name.type === "Identifier" || node.name.type === "SvelteName") { return node.name.name } - let object = "" + const memberPath = [node.name.property.name] let currentObject = node.name.object - while ("object" in currentObject) { - object = `${currentObject.property.name}.${object}` + while (currentObject.type === "SvelteMemberExpressionName") { + memberPath.unshift(currentObject.property.name) currentObject = currentObject.object } - if ("name" in currentObject) { - object = `${currentObject.name}.${object}` - } - return object + node.name.property.name + memberPath.unshift(currentObject.name) + return memberPath.join(".") } /** diff --git a/src/utils/rules.ts b/src/utils/rules.ts index 7e62e8ed6..ac31ae0c8 100644 --- a/src/utils/rules.ts +++ b/src/utils/rules.ts @@ -12,6 +12,7 @@ import maxAttributesPerLine from "../rules/max-attributes-per-line" import mustacheSpacing from "../rules/mustache-spacing" import noAtDebugTags from "../rules/no-at-debug-tags" import noAtHtmlTags from "../rules/no-at-html-tags" +import noDomManipulating from "../rules/no-dom-manipulating" import noDupeElseIfBlocks from "../rules/no-dupe-else-if-blocks" import noDupeStyleProperties from "../rules/no-dupe-style-properties" import noDynamicSlotName from "../rules/no-dynamic-slot-name" @@ -59,6 +60,7 @@ export const rules = [ mustacheSpacing, noAtDebugTags, noAtHtmlTags, + noDomManipulating, noDupeElseIfBlocks, noDupeStyleProperties, noDynamicSlotName, diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/chain01-errors.yaml b/tests/fixtures/rules/no-dom-manipulating/invalid/chain01-errors.yaml new file mode 100644 index 000000000..6714e92f7 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/chain01-errors.yaml @@ -0,0 +1,14 @@ +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 5 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 9 + column: 7 + suggestions: null diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/chain01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/invalid/chain01-input.svelte new file mode 100644 index 000000000..5dcc1596f --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/chain01-input.svelte @@ -0,0 +1,16 @@ + + +

div

+ + + diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/remove-text01-errors.yaml b/tests/fixtures/rules/no-dom-manipulating/invalid/remove-text01-errors.yaml new file mode 100644 index 000000000..605377446 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/remove-text01-errors.yaml @@ -0,0 +1,7 @@ +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 9 + column: 25 + suggestions: null diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/remove-text01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/invalid/remove-text01-input.svelte new file mode 100644 index 000000000..9fade1be9 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/remove-text01-input.svelte @@ -0,0 +1,19 @@ + + +
+ {#if show} + div + {/if} +
+ + + diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/remove01-errors.yaml b/tests/fixtures/rules/no-dom-manipulating/invalid/remove01-errors.yaml new file mode 100644 index 000000000..e5ec19389 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/remove01-errors.yaml @@ -0,0 +1,7 @@ +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 9 + column: 24 + suggestions: null diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/remove01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/invalid/remove01-input.svelte new file mode 100644 index 000000000..c667f30e7 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/remove01-input.svelte @@ -0,0 +1,17 @@ + + +{#if show} +
div
+{/if} + + + diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/svelte-element01-errors.yaml b/tests/fixtures/rules/no-dom-manipulating/invalid/svelte-element01-errors.yaml new file mode 100644 index 000000000..cfef8c2f5 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/svelte-element01-errors.yaml @@ -0,0 +1,14 @@ +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 7 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 8 + column: 5 + suggestions: null diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/svelte-element01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/invalid/svelte-element01-input.svelte new file mode 100644 index 000000000..2b6f8ff1c --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/svelte-element01-input.svelte @@ -0,0 +1,15 @@ + + +

div

+div + + diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-method01-errors.yaml b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-method01-errors.yaml new file mode 100644 index 000000000..36620243f --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-method01-errors.yaml @@ -0,0 +1,105 @@ +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 6 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 7 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 8 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 9 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 10 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 11 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 12 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 13 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 14 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 15 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 16 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 17 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 18 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 19 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 20 + column: 5 + suggestions: null diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-method01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-method01-input.svelte new file mode 100644 index 000000000..fa82c940e --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-method01-input.svelte @@ -0,0 +1,29 @@ + + +
+
+ div +
+ + diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-prop01-errors.yaml b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-prop01-errors.yaml new file mode 100644 index 000000000..493178b51 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-prop01-errors.yaml @@ -0,0 +1,35 @@ +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 4 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 5 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 6 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 7 + column: 5 + suggestions: null +- message: + Don't manipulate the DOM directly. The Svelte runtime can get confused + if there is a difference between the actual DOM and the DOM expected by the + Svelte runtime. + line: 8 + column: 5 + suggestions: null diff --git a/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-prop01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-prop01-input.svelte new file mode 100644 index 000000000..676de2ff2 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/invalid/well-known-prop01-input.svelte @@ -0,0 +1,14 @@ + + +
div
+ + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/computed-member01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/computed-member01-input.svelte new file mode 100644 index 000000000..97d68234e --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/computed-member01-input.svelte @@ -0,0 +1,8 @@ + + +
div
+ + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/loop01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/loop01-input.svelte new file mode 100644 index 000000000..367d3d5e2 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/loop01-input.svelte @@ -0,0 +1,15 @@ + + +{#each list as item} + +{/each} + + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/non-bind-this01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/non-bind-this01-input.svelte new file mode 100644 index 000000000..62c3df057 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/non-bind-this01-input.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/non-element01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/non-element01-input.svelte new file mode 100644 index 000000000..075aac9a6 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/non-element01-input.svelte @@ -0,0 +1,15 @@ + + +div +div + + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/remove-text01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/remove-text01-input.svelte new file mode 100644 index 000000000..95326d290 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/remove-text01-input.svelte @@ -0,0 +1,15 @@ + + +
+ {#if show} + div + {/if} +
+ + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/remove01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/remove01-input.svelte new file mode 100644 index 000000000..cad26e34c --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/remove01-input.svelte @@ -0,0 +1,13 @@ + + +{#if show} +
div
+{/if} + + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/unknown-method01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/unknown-method01-input.svelte new file mode 100644 index 000000000..9cf3823fa --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/unknown-method01-input.svelte @@ -0,0 +1,8 @@ + + +
div
+ + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/unknown-prop01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/unknown-prop01-input.svelte new file mode 100644 index 000000000..e18ff9462 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/unknown-prop01-input.svelte @@ -0,0 +1,8 @@ + + +
div
+ + diff --git a/tests/fixtures/rules/no-dom-manipulating/valid/unknown-var01-input.svelte b/tests/fixtures/rules/no-dom-manipulating/valid/unknown-var01-input.svelte new file mode 100644 index 000000000..00b0aef82 --- /dev/null +++ b/tests/fixtures/rules/no-dom-manipulating/valid/unknown-var01-input.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/tests/src/rules/no-dom-manipulating.ts b/tests/src/rules/no-dom-manipulating.ts new file mode 100644 index 000000000..1e70ab7b0 --- /dev/null +++ b/tests/src/rules/no-dom-manipulating.ts @@ -0,0 +1,16 @@ +import { RuleTester } from "eslint" +import rule from "../../../src/rules/no-dom-manipulating" +import { loadTestCases } from "../../utils/utils" + +const tester = new RuleTester({ + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + }, +}) + +tester.run( + "no-dom-manipulating", + rule as any, + loadTestCases("no-dom-manipulating"), +) diff --git a/typings/eslint-utils/index.d.ts b/typings/eslint-utils/index.d.ts index d5d5d28ec..206b80918 100644 --- a/typings/eslint-utils/index.d.ts +++ b/typings/eslint-utils/index.d.ts @@ -1,12 +1,16 @@ import type { AST } from "svelte-eslint-parser" import type { TSESTree } from "@typescript-eslint/types" import type { Scope } from "@typescript-eslint/scope-manager" -import type { CALL, CONSTRUCT, ESM, READ } from "eslint-utils/referenceTracker" +import type { + CALL, + CONSTRUCT, + ESM, + READ, + TraceMap, +} from "eslint-utils/referenceTracker" export { ReferenceTracker, TrackedReferences, - getPropertyName, - getInnermostScope, } from "../../node_modules/@types/eslint-utils" type Token = { type: string; value: string } export function isArrowToken(token: Token): boolean