rstudio / htmltools

Tools for HTML generation and output
https://rstudio.github.io/htmltools/
214 stars 67 forks source link

`tagAppendChildren` and other functions using `tagQuery` cannot select elements at top level. #363

Closed jtlandis closed 1 year ago

jtlandis commented 1 year ago

I do not know if this is intended but it seems that TagQuery does not bother checking the root element of the tag whenever using a .cssSelector. From my own snooping tagQueryFindAll walks over each element, but doesn’t check the element itself, only its children/descendants. Consider the following reprex

library(htmltools)

ele <- div(id = "content",
           div(id = "something-else"))

tq <- tagQuery(ele)
tq$find("#content")
#> `$allTags()`:
#> <div id="content">
#>   <div id="something-else"></div>
#> </div>
#> 
#> `$selectedTags()`: (Empty selection)
tq$find("#something-else")
#> `$allTags()`:
#> <div id="content">
#>   <div id="something-else"></div>
#> </div>
#> 
#> `$selectedTags()`:
#> [[1]]
#> <div id="something-else"></div>

not checkin the root level makes the following unviable.

page <- shiny::bootstrapPage()
page <- tagAppendChildren(page, ele, div(id = "foo"))
page <- tagAppendChildren(page, a("link1"), .cssSelector = "#content")
page <- tagAppendChildren(page, a("link2"), .cssSelector = "#something-else")
page <- tagAppendChildren(page, a("link3"), .cssSelector = "#foo")
shiny:::renderPage(page) |> cat()
#> <!DOCTYPE html>
#> <html>
#> <head>
#>   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
#>   <script type="application/shiny-singletons"></script>
#>   <script type="application/html-dependencies">jquery[3.6.0];shiny-css[1.7.2];shiny-javascript[1.7.2];bootstrap[3.4.1]</script>
#> <script src="jquery-3.6.0/jquery.min.js"></script>
#> <link href="shiny-css-1.7.2/shiny.min.css" rel="stylesheet" />
#> <script src="shiny-javascript-1.7.2/shiny.min.js"></script>
#> <meta name="viewport" content="width=device-width, initial-scale=1" />
#> <link href="bootstrap-3.4.1/css/bootstrap.min.css" rel="stylesheet" />
#> <link href="bootstrap-3.4.1/accessibility/css/bootstrap-accessibility.min.css" rel="stylesheet" />
#> <script src="bootstrap-3.4.1/js/bootstrap.min.js"></script>
#> <script src="bootstrap-3.4.1/accessibility/js/bootstrap-accessibility.min.js"></script>
#> </head>
#> <body>
#>   <div id="content">
#>     <div id="something-else">
#>       <a>link2</a>
#>     </div>
#>   </div>
#>   <div id="foo"></div>
#> </body>
#> </html>

Created on 2023-01-27 with reprex v2.0.2

cpsievert commented 1 year ago

Thanks. We're aware of the confusion, and will likely fix this behavior. Closing here since this is duplicate of #334