@@ -138,6 +138,19 @@ impl Rule for PreferQuerySelector {
138138 } ) ;
139139 }
140140
141+ // For non-literal arguments, we can still auto-fix `getElementById(id)` -> `querySelector(`#${id}`)
142+ // Only apply this fix for simple identifiers so we avoid nested template literals
143+ // and complex expressions like member/call expressions or template literals
144+ if property_name == "getElementById"
145+ && matches ! ( argument_expr, Expression :: Identifier ( _) )
146+ {
147+ return ctx. diagnostic_with_fix ( diagnostic, |fixer| {
148+ let source_text = fixer. source_range ( argument_expr. span ( ) ) ;
149+ let span = property_span. merge ( argument_expr. span ( ) ) ;
150+ fixer. replace ( span, format ! ( "{preferred_selector}(`#${{{source_text}}}`" ) )
151+ } ) ;
152+ }
153+
141154 ctx. diagnostic ( diagnostic) ;
142155 }
143156 }
@@ -201,7 +214,16 @@ fn test() {
201214 ) ,
202215 ( "document.getElementsByClassName(null);" , "document.querySelectorAll(null);" , None ) ,
203216 ( "document.getElementsByTagName(` `);" , "document.querySelectorAll(` `);" , None ) ,
217+ ( "document.getElementById(123);" , "document.getElementById(123);" , None ) ,
204218 ( "document.getElementById(`id`);" , "document.querySelector(`#id`);" , None ) ,
219+ ( "document.getElementById(obj.id);" , "document.getElementById(obj.id);" , None ) ,
220+ ( "document.getElementById(getId());" , "document.getElementById(getId());" , None ) ,
221+ ( "document.getElementById(`${foo}`);" , "document.getElementById(`${foo}`);" , None ) ,
222+ (
223+ "document.getElementById(searchInputId);" ,
224+ "document.querySelector(`#${searchInputId}`);" ,
225+ None ,
226+ ) ,
205227 (
206228 "document.getElementsByClassName(foo + \" bar\" );" ,
207229 "document.getElementsByClassName(foo + \" bar\" );" ,
0 commit comments