1
1
import type { RuleContext , RuleFeature } from "@eslint-react/kit" ;
2
- import type { TSESTree } from "@typescript-eslint/types" ;
3
2
import type { RuleListener } from "@typescript-eslint/utils/ts-eslint" ;
4
3
import type { CamelCase } from "string-ts" ;
5
- import * as AST from "@eslint-react/ast" ;
6
4
import * as ER from "@eslint-react/core" ;
7
5
6
+ import { AST_NODE_TYPES , type TSESTree } from "@typescript-eslint/types" ;
8
7
import { createRule } from "../utils" ;
9
8
10
9
export const RULE_NAME = "no-dangerously-set-innerhtml-with-children" ;
@@ -40,7 +39,8 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
40
39
JSXElement ( node ) {
41
40
const attributes = node . openingElement . attributes ;
42
41
const initialScope = context . sourceCode . getScope ( node ) ;
43
- const hasChildren = hasChildrenWithin ( node ) || ER . hasAttribute ( context , "children" , attributes , initialScope ) ;
42
+ const hasChildren = node . children . some ( isSignificantChildren )
43
+ || ER . hasAttribute ( context , "children" , attributes , initialScope ) ;
44
44
if ( hasChildren && ER . hasAttribute ( context , dangerouslySetInnerHTML , attributes , initialScope ) ) {
45
45
context . report ( {
46
46
messageId : "noDangerouslySetInnerhtmlWithChildren" ,
@@ -51,8 +51,26 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
51
51
} ;
52
52
}
53
53
54
- function hasChildrenWithin ( node : TSESTree . JSXElement ) : boolean {
55
- return node . children . length > 0
56
- && node . children [ 0 ] != null
57
- && ! AST . isLineBreak ( node . children [ 0 ] ) ;
54
+ /**
55
+ * Check if a Literal or JSXText node is whitespace
56
+ * @param node The AST node to check
57
+ * @returns boolean `true` if the node is whitespace
58
+ */
59
+ function isWhiteSpace ( node : TSESTree . JSXText | TSESTree . Literal ) {
60
+ return typeof node . value === "string" && node . raw . trim ( ) === "" ;
61
+ }
62
+
63
+ /**
64
+ * Check if a Literal or JSXText node is padding spaces
65
+ * @param node The AST node to check
66
+ * @returns boolean
67
+ */
68
+ function isPaddingSpaces ( node : TSESTree . Node ) {
69
+ return ER . isJsxText ( node )
70
+ && isWhiteSpace ( node )
71
+ && node . raw . includes ( "\n" ) ;
72
+ }
73
+
74
+ function isSignificantChildren ( node : TSESTree . JSXElement [ "children" ] [ number ] ) {
75
+ return node . type !== AST_NODE_TYPES . JSXText || ! isPaddingSpaces ( node ) ;
58
76
}
0 commit comments