11import type { RuleContext , RuleFeature } from "@eslint-react/kit" ;
2- import type { TSESTree } from "@typescript-eslint/types" ;
32import type { RuleListener } from "@typescript-eslint/utils/ts-eslint" ;
43import type { CamelCase } from "string-ts" ;
5- import * as AST from "@eslint-react/ast" ;
64import * as ER from "@eslint-react/core" ;
75
6+ import { AST_NODE_TYPES , type TSESTree } from "@typescript-eslint/types" ;
87import { createRule } from "../utils" ;
98
109export const RULE_NAME = "no-dangerously-set-innerhtml-with-children" ;
@@ -40,7 +39,8 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
4039 JSXElement ( node ) {
4140 const attributes = node . openingElement . attributes ;
4241 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 ) ;
4444 if ( hasChildren && ER . hasAttribute ( context , dangerouslySetInnerHTML , attributes , initialScope ) ) {
4545 context . report ( {
4646 messageId : "noDangerouslySetInnerhtmlWithChildren" ,
@@ -51,8 +51,26 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
5151 } ;
5252}
5353
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 ) ;
5876}
0 commit comments