Skip to content

HTMLWidget with save_selfcontained editing entire file #229

@MikeLydeamore

Description

@MikeLydeamore

I was very excited to see support for HTMLWidgets added. I've tried to follow the process described in PR 223 but when I do this, I get a whole bunch of replaced text at the top of my file.

Here is my Quarto file:

---
title: "HTMLWidget with WebR"
format: html
engine: knitr
filters:
    - webr
execute:
    echo: false
    warning: false
    message: false
---

```{webr-r}
#| context: setup

save_selfcontained <- function(widget)  {
  
  temp_dir <- tempfile()
  dir.create(temp_dir)
  temp_file <- file.path(temp_dir,"widget.html")
  
  htmlwidgets::saveWidget(widget, file = temp_file, selfcontained = FALSE)

  # read not self-contained html
  html_text <- readLines(temp_file)
  
  js_lines <- which(grepl(
    x = html_text,
    pattern = '(src=.*js)'
  ))
  
  # convert link[rel=stylesheet] to <style>css file contents</style>
  css_lines <- which(grepl(
    x = html_text,
    pattern = '(href=.*css)'
  ))
  
  # perform self-contained conversion/replacement of JS
  if(length(js_lines) > 0) {
    html_text[js_lines] <- lapply(js_lines, function(js_line) {
      js_file <- sub(x=html_text[js_line], pattern='.*src=[":\'](.*\\.js).*', replacement="\\1")
      js_content <- paste0(
        "<script>",
        paste0(readLines(file.path(temp_dir,js_file)), collapse="\n"),
        "</script>",
        collapse="\n"
      )
    })
  }
  
  # perform self-contained conversion/replacement of JS
  if(length(css_lines) > 0) {
    html_text[css_lines] <- lapply(css_lines, function(css_line) {
      css_file <- sub(x=html_text[css_line], pattern='.*href=[":\'](.*\\.css).*', replacement="\\1")
      css_content <- paste0(
        "<style>",
        paste0(readLines(file.path(temp_dir,css_file)), collapse="\n"),
        "</style>",
        collapse="\n"
      )
    })
  }
  
  # save self-contained html
  write(paste0(html_text,collapse="\n"), file=file.path(temp_dir,"index.html"))
  
  return(file.path(temp_dir,"index.html"))
}
```

```{webr-r}
library(dygraphs)
view <- function(widget) {
	webr::viewer_install()
	path <- save_selfcontained(v)
	getOption("viewer")(path)
}

v <- dygraph(nhtemp, main = "New Haven Temperatures") %>% 
  dyRangeSelector(dateWindow = c("1920-01-01", "1960-01-01"))
view(v)
```

and here is the result:

Image

I took save_selfcontained from the linked blog here: https://www.jsinr.me/2024/01/10/selfcontained-htmlwidgets/

I've narrowed this down to the self-contained conversion/replacement of JS section, but I don't know why it seems to be replacing everything rather than just the saved widget.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions