Skip to content

Commit 0d08ff5

Browse files
authored
save_html() now works correctly with components and pages with non-default theme values (#823)
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
1 parent 11a8281 commit 0d08ff5

File tree

9 files changed

+121
-8
lines changed

9 files changed

+121
-8
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Imports:
3232
base64enc,
3333
cachem,
3434
grDevices,
35-
htmltools (>= 0.5.4.9000),
35+
htmltools (>= 0.5.6.9001),
3636
jquerylib (>= 0.1.3),
3737
jsonlite,
3838
lifecycle,

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ S3method(print,bslib_fragment)
99
S3method(print,bslib_page)
1010
S3method(print,bslib_showcase_layout)
1111
S3method(print,bslib_value_box_theme)
12+
S3method(save_html,bslib_fragment)
13+
S3method(save_html,bslib_page)
1214
export(accordion)
1315
export(accordion_panel)
1416
export(accordion_panel_close)

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636

3737
* Improved the style and appearance of the button to enter full screen in `card()`s and `value_box()`es to better adapt to Bootstrap's dark mode. (#780)
3838

39+
* `htmltools::save_html()` now works as expected when applied directly to components (e.g., `card()`, etc) and pages with a non-default theme. (#823, #815)
40+
3941
* `layout_sidebar()` received a new design. The button to collapse and expand the sidebar now appears at the top edge of the sidebar, and we now use the [arrow-bar-left](https://icons.getbootstrap.com/icons/arrow-bar-left/) icon instead of [chevron-left](https://icons.getbootstrap.com/icons/chevron-left/). On mobile devices, the sidebar now fills the `layout_sidebar()` area as an overlay, rather than expanding from above the main content area. **Note** the `max_mobile_height` argument of `sidebar()` determines the maximum height of the sidebar area on mobile, but it now only applies when `open = "always"`. (#798)
4042

4143
* `layout_sidebar()` now uses an `<aside>` element for the sidebar's container and a `<header>` element for the sidebar title. The classes of each element remain the same, but the semantic meaning of the elements is now better reflected in the HTML markup. (#580)

R/print.R

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ as_page <- function(x, theme = bs_theme()) {
1111
x
1212
}
1313

14-
#' Make HTML browsable by default
14+
#' Print a bslib page/fragment
1515
#'
16-
#' @param x a [tag()] object.
17-
#' @param ... passed along to an underlying print method
16+
#' @param x a bslib page/fragment.
17+
#' @param ... passed along to an underlying print method.
1818
#' @export
1919
#' @keywords internal
2020
#' @rdname html-browse
@@ -23,6 +23,18 @@ print.bslib_fragment <- function(x, ...) {
2323
invisible(print(x, ...))
2424
}
2525

26+
#' Save a bslib page/fragment as HTML
27+
#'
28+
#' @param x a bslib page/fragment.
29+
#' @param ... passed along to an underlying [save_html()] method.
30+
#' @export
31+
#' @keywords internal
32+
#' @rdname save-html
33+
save_html.bslib_fragment <- function(html, file, ...) {
34+
html <- attr(html, "bslib_page")(html)
35+
save_html(html, file, ...)
36+
}
37+
2638
#' @rdname html-browse
2739
#' @export
2840
print.bslib_page <- function(x, ...) {
@@ -36,3 +48,13 @@ print.bslib_page <- function(x, ...) {
3648

3749
invisible(NextMethod())
3850
}
51+
52+
#' @rdname save-html
53+
#' @export
54+
save_html.bslib_page <- function(html, file, ...) {
55+
old_theme <- bs_global_get()
56+
bs_global_set(attr(html, "bs_theme", exact = TRUE))
57+
on.exit(bs_global_set(old_theme), add = TRUE)
58+
59+
NextMethod()
60+
}

man/html-browse.Rd

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/save-html.Rd

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8"/>
5+
<style>body{background-color:white;}</style>
6+
<script src="lib/jquery/jquery-3.6.0.min.js"></script>
7+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
8+
<link href="lib/bootstrap/bootstrap.min.css" rel="stylesheet" />
9+
<script src="lib/bootstrap/bootstrap.bundle.min.js"></script>
10+
<script src="lib/bslib-component-js/components.min.js"></script>
11+
<script src="lib/bslib-component-js/web-components.min.js" type="module"></script>
12+
<link href="lib/bslib-component-css/components.css" rel="stylesheet" />
13+
<script src="lib/bs3compat/transition.js"></script>
14+
<script src="lib/bs3compat/tabs.js"></script>
15+
<script src="lib/bs3compat/bs3compat.js"></script>
16+
<link href="lib/htmltools-fill/fill.css" rel="stylesheet" />
17+
<script src="lib/bslib-tag-require/tag-require.js"></script>
18+
19+
</head>
20+
<body>
21+
<div class="container-fluid">
22+
<div class="card bslib-card bslib-mb-spacing html-fill-item html-fill-container" data-bslib-card-init data-require-bs-caller="card()" data-require-bs-version="5">
23+
<div class="card-body bslib-gap-spacing html-fill-item html-fill-container" style="margin-top:auto;margin-bottom:auto;flex:1 1 auto;">A simple card</div>
24+
<script data-bslib-card-init>bslib.Card.initializeAllCards();</script>
25+
</div>
26+
</div>
27+
</body>
28+
</html>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8"/>
5+
<style>body{background-color:white;}</style>
6+
<script src="lib/jquery/jquery-3.6.0.min.js"></script>
7+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
8+
<link href="lib/bootstrap/bootstrap.min.css" rel="stylesheet" />
9+
<script src="lib/bootstrap/bootstrap.bundle.min.js"></script>
10+
<script src="lib/bslib-component-js/components.min.js"></script>
11+
<script src="lib/bslib-component-js/web-components.min.js" type="module"></script>
12+
<link href="lib/bslib-component-css/bslib-component-css.min.css" rel="stylesheet" />
13+
14+
</head>
15+
<body>A simple page without bs3compat dependencies</body>
16+
</html>

tests/testthat/test-page.R

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,26 @@ test_that("page_sidebar()", {
7878
)
7979

8080
})
81+
82+
test_that("save_html() works on components and pages with a custom theme", {
83+
withr::local_options(list(htmltools.dir.version = FALSE))
84+
85+
withr::with_tempdir({
86+
save_html(
87+
card("A simple card"),
88+
"card.html"
89+
)
90+
expect_snapshot_file("card.html")
91+
})
92+
93+
withr::with_tempdir({
94+
save_html(
95+
page(
96+
theme = bs_remove(bs_theme(), "bs3compat"),
97+
"A simple page without bs3compat dependencies"
98+
),
99+
"modern-page.html"
100+
)
101+
expect_snapshot_file("modern-page.html")
102+
})
103+
})

0 commit comments

Comments
 (0)