Skip to content

htmlwidgets::saveWidget selfContained adds <pre> tags around custom HTML #358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rfaelens opened this issue Dec 3, 2019 · 7 comments · Fixed by #401
Closed

htmlwidgets::saveWidget selfContained adds <pre> tags around custom HTML #358

rfaelens opened this issue Dec 3, 2019 · 7 comments · Fixed by #401

Comments

@rfaelens
Copy link

rfaelens commented Dec 3, 2019

The timevis package uses the function timevis_html to add a custom zoom menu:
https://github.com/daattali/timevis/blob/be9756629bf12f5225d578d10c093d8f968f8551/R/timevis.R#L505

This works fine in combination with htmlwidgets::saveWidget selfContained=FALSE.
When using the selfContained=TRUE option however, the custom HTML is wrapped in <pre> tags, and is therefore not present in the output.

As a workaround, the generated HTML code can be adapted afterwards, but this is less than ideal.

Minimal reprex: https://gist.github.com/rfaelens/9dc31900c8e6601f2b978be4f5c4ec43
Referencing original issue: daattali/timevis#87

@strazto
Copy link

strazto commented Aug 31, 2020

I have a marginally related issue w/ selfContained = TRUE causing stylesheets to be mangled -

When selfContained = TRUE, the following:

attach_dependencies <- function(graph) {
  jquery <- htmltools::htmlDependency(
    "jquery", version = "3.4.1",
    src = list(href = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/"),
    script = "jquery.min.js"
    )

  bootstrap <- htmltools::htmlDependency(
    "bootstrap",
    version = "3.4.1",
    src = list(href = "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/"),
    stylesheet = "bootstrap.min.css"
  )

  graph$dependencies %<>% c(list(jquery, bootstrap))
  graph
}

graph %<>% attach_dependencies()

graph %>% htmlwidgets::saveWidget("my_widget.html", selfcontained = T)

Renders out as:

<head>
<meta charset="utf-8">
<title>visNetwork</title>
<style>body{background-color:white;}</style>
<!--  minfied htmlwidgets src --><script></script>
<!-- minified vis-420.1/vis.css --><style type="text/css"></style>
<!-- minified vis.js --><script></script>
<!-- minified visnetwork bindings --><script></script>
<!-- minified jquery src --><script></script>
<!-- HERE IS THE PROBLEM -->
<!-- minified bootstrap css -->
<style type="text/css; charset=utf-8">
</style>
<!-- Above "type" is appended with "charset=utf-8" -->
<style type="text/css">div.vis-tooltip {display : none}</style>
</head>

selfcontained = false

<head>
<meta charset="utf-8">
<style>body{background-color:white;}</style>
<script src="workflow_graph_zoomed_files/htmlwidgets-1.3/htmlwidgets.js"></script>
<link href="workflow_graph_zoomed_files/vis-4.20.1/vis.css" rel="stylesheet">
<script src="workflow_graph_zoomed_files/vis-4.20.1/vis.min.js"></script>
<script src="workflow_graph_zoomed_files/visNetwork-binding-2.0.9/visNetwork.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
  <title>visNetwork</title>
<style type="text/css">div.vis-tooltip {display : none}</style>
</head>

For whatever reason, in the case of the bootstrap stylesheet, when trying to embed it, htmlwidgets adds an extra qualifier to its type attribute, extending it from type="text/css" to type="text/css; charset=utf-8".

As a result of this, the bootstrap stylesheet doesn't appear to be applied to my document. The only thing that seems to fix this client-side (via devtools / browser inspect) is to modify the type attribute of this <style> tag, changing it from:

<style type="text/css; charset=utf-8">...</style>

back to:

<style type="text/css">...</style>

In order to fix this mangling, I can probably run some clientside jquery that just finds instances of this value for type and restores them, but this fix isn't exactly cute.

@strazto
Copy link

strazto commented Aug 31, 2020

The following serves as an effective workaround:

// inst/lib/fix_utf.js
$(function() {
  $('style[type="text/css; charset=utf-8"]').attr("type", "text/css");
})
attach_dependencies <- function(graph) {
  jquery <- htmltools::htmlDependency(
    "jquery", version = "3.4.1",
    src = list(href = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/"),
    script = "jquery.min.js"
    )

  bootstrap <- htmltools::htmlDependency(
    "bootstrap",
    version = "3.4.1",
    src = list(href = "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/"),
    stylesheet = "bootstrap.min.css"
    )

    fix_utf <- htmltools::htmlDependency(
      "fix_utf",
      "0.0.0.9001",
      package = "mandrake",
      src = "lib",
      script = "fix_utf.js"
   )
  graph$dependencies %<>% c(list(jquery, bootstrap,  fix_utf))
  graph
}

graph %<>% attach_dependencies()

graph %>% htmlwidgets::saveWidget("my_widget.html", selfcontained = T)

@ismirsehregal
Copy link

I'm having the same issue.

@jcheng5
Copy link
Collaborator

jcheng5 commented Nov 11, 2020

I'm not seeing it, it might be down to your Pandoc version. What does rmarkdown::pandoc_version() report? And what version of RStudio?

@ismirsehregal
Copy link

@jcheng5 thanks for the response!

I'm using RStudio version 1.4.869 and pandoc version 2.10.1

@rfaelens reprex renders:

for selfcontained = TRUE
image

for selfcontained = FALSE (you can see the buttons in the upper right corner)
image

@ismirsehregal
Copy link

@jcheng5 were you able to reproduce this with the above mentioned versions?

@ismirsehregal
Copy link

@andrewdenner I just rendered @rfaelens reprex using your PR. Unfortunately the result remains the same on my machine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants