From 7bcb5315dbe8dfa0a87cb85ca7e49cac111c219f Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Fri, 20 Sep 2019 18:27:30 -0700 Subject: [PATCH 01/13] Bump version for release --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0b699d35..dcd86a0c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.4.0.9000 +Version: 1.5 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")), From 4944b75e0eb903e59be2423182bc712899d6ed8c Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Fri, 4 Oct 2019 12:34:12 -0700 Subject: [PATCH 02/13] Bump version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index dcd86a0c..d40a2387 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.5 +Version: 1.5.0.9000 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")), From 56bf3e58376931dde131a6e44820f5dbc58e90f4 Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 7 Oct 2019 09:54:03 -0500 Subject: [PATCH 03/13] Use to schedule staticRender() iff jQuery 3 or higher is present in shinyMode --- inst/www/htmlwidgets.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/inst/www/htmlwidgets.js b/inst/www/htmlwidgets.js index 64c7e8d7..789394a7 100644 --- a/inst/www/htmlwidgets.js +++ b/inst/www/htmlwidgets.js @@ -659,8 +659,17 @@ invokePostRenderHandlers(); } + function has_jQuery3() { + if (!window.jQuery) { + return false; + } + var $version = window.jQuery.fn.jquery; + var $major_version = parseInt($version.split(".")[0]); + return $major_version >= 3; + } + // Wait until after the document has loaded to render the widgets. - if (shinyMode && window.jQuery) { + if (shinyMode && window.jQuery && has_jQuery3()) { /* / Shiny 1.4.0 bumps jQuery from 1.x to 3.x, which means jQuery's / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now From 6d0c24b68d7e98f762dfdb0bffa3dc6e93c64c61 Mon Sep 17 00:00:00 2001 From: Carson Date: Mon, 7 Oct 2019 12:04:49 -0500 Subject: [PATCH 04/13] Bump version; update NEWS --- DESCRIPTION | 2 +- inst/NEWS | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d40a2387..cd1383d3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.5.0.9000 +Version: 1.5.1 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")), diff --git a/inst/NEWS b/inst/NEWS index 07374296..5d8b2f7d 100644 --- a/inst/NEWS +++ b/inst/NEWS @@ -1,3 +1,8 @@ +htmlwidgets 1.5.1 +------------------------------------------------------- + +* Fixed an issue with dynamically rendered widgets (i.e., using `shiny::uiOutput()` to render a widget) with any version of shiny prior to 1.4. This issue was introduced by htmlwidgets 1.5. (#351) + htmlwidgets 1.5 ----------------------------------------------------------------------- From ebda03ae23936b5be8f5d1576b5521e839265d1d Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Mon, 7 Oct 2019 11:52:52 -0700 Subject: [PATCH 05/13] Prevent staticRender from being called unconditionally when htmlwidgets.js is loaded after page load --- inst/www/htmlwidgets.js | 42 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/inst/www/htmlwidgets.js b/inst/www/htmlwidgets.js index 789394a7..648d4fcd 100644 --- a/inst/www/htmlwidgets.js +++ b/inst/www/htmlwidgets.js @@ -668,44 +668,24 @@ return $major_version >= 3; } - // Wait until after the document has loaded to render the widgets. - if (shinyMode && window.jQuery && has_jQuery3()) { - /* - / Shiny 1.4.0 bumps jQuery from 1.x to 3.x, which means jQuery's - / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now - / really means $(setTimeout(fn)). https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous - / - / In order to ensure the order of execution of on-ready handlers - / remains consistent with how it's been in the past, a static render - / in Shiny is now scheduled via $(). - / - / This is not a long term solution: it just preserves the current order - / of execution. Part of that ordering is to ensure initShiny executes - / _after_ staticRender, which is both right and wrong: - / * It's wrong because, when initShiny executes, it registers methods - / like Shiny.onInputChange that widget authors would expect to be available - / during a staticRender. - / * It's also 'right' because initShiny currently (as of v1.4.0) wants - / to execute after user code so that it can bind to any dynamically - / created elements. - / - / A longer term solution might be to make changes to Shiny so that - / these methods are available before the binding takes place, and then - / the ordering would be: register methods -> static render -> bind. - */ - window.jQuery(function() { - window.HTMLWidgets.staticRender(); - }); - } else if (document.addEventListener) { + if (document.addEventListener) { document.addEventListener("DOMContentLoaded", function() { document.removeEventListener("DOMContentLoaded", arguments.callee, false); - window.HTMLWidgets.staticRender(); + if (shinyMode && window.jQuery && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { + window.HTMLWidgets.staticRender(); + } }, false); } else if (document.attachEvent) { document.attachEvent("onreadystatechange", function() { if (document.readyState === "complete") { document.detachEvent("onreadystatechange", arguments.callee); - window.HTMLWidgets.staticRender(); + if (shinyMode && window.jQuery && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { + window.HTMLWidgets.staticRender(); + } } }); } From cb7e3d1ad8c55560109edf91ccc179b4cb6a497e Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Mon, 7 Oct 2019 16:22:14 -0500 Subject: [PATCH 06/13] Add a comment; abstract out duplication in logic (#354) --- inst/www/htmlwidgets.js | 43 +++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/inst/www/htmlwidgets.js b/inst/www/htmlwidgets.js index 648d4fcd..6f3d672d 100644 --- a/inst/www/htmlwidgets.js +++ b/inst/www/htmlwidgets.js @@ -659,6 +659,7 @@ invokePostRenderHandlers(); } + function has_jQuery3() { if (!window.jQuery) { return false; @@ -668,24 +669,46 @@ return $major_version >= 3; } + /* + / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's + / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now + / really means $(setTimeout(fn)). + / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous + / + / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny + / one tick later than it did before, which means staticRender() is + / called renderValue() earlier than (advanced) widget authors might be expecting. + / https://github.com/rstudio/shiny/issues/2630 + / + / For a concrete example, leaflet has some methods (e.g., updateBounds) + / which reference Shiny methods registered in initShiny (e.g., setInputValue). + / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to + / delay execution of those methods (until Shiny methods are ready) + / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268 + / + / Ideally widget authors wouldn't need to use this setTimeout() hack that + / leaflet uses to call Shiny methods on a staticRender(). In the long run, + / the logic initShiny should be broken up so that method registration happens + / right away, but binding happens later. + */ + function maybeStaticRenderLater() { + if (shinyMode && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { + window.HTMLWidgets.staticRender(); + } + } + if (document.addEventListener) { document.addEventListener("DOMContentLoaded", function() { document.removeEventListener("DOMContentLoaded", arguments.callee, false); - if (shinyMode && window.jQuery && has_jQuery3()) { - window.jQuery(window.HTMLWidgets.staticRender); - } else { - window.HTMLWidgets.staticRender(); - } + maybeStaticRenderLater(); }, false); } else if (document.attachEvent) { document.attachEvent("onreadystatechange", function() { if (document.readyState === "complete") { document.detachEvent("onreadystatechange", arguments.callee); - if (shinyMode && window.jQuery && has_jQuery3()) { - window.jQuery(window.HTMLWidgets.staticRender); - } else { - window.HTMLWidgets.staticRender(); - } + maybeStaticRenderLater(); } }); } From 91cfa1cee38c2a35f32f53ee34afc6b076e71c8b Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Mon, 7 Oct 2019 14:30:20 -0700 Subject: [PATCH 07/13] v1.5.1 release candidate (#353) * Use to schedule staticRender() iff jQuery 3 or higher is present in shinyMode * Bump version; update NEWS * Prevent staticRender from being called unconditionally when htmlwidgets.js is loaded after page load * Add a comment; abstract out duplication in logic (#354) --- DESCRIPTION | 2 +- inst/NEWS | 5 +++ inst/www/htmlwidgets.js | 72 ++++++++++++++++++++++++----------------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d40a2387..cd1383d3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.5.0.9000 +Version: 1.5.1 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")), diff --git a/inst/NEWS b/inst/NEWS index 07374296..5d8b2f7d 100644 --- a/inst/NEWS +++ b/inst/NEWS @@ -1,3 +1,8 @@ +htmlwidgets 1.5.1 +------------------------------------------------------- + +* Fixed an issue with dynamically rendered widgets (i.e., using `shiny::uiOutput()` to render a widget) with any version of shiny prior to 1.4. This issue was introduced by htmlwidgets 1.5. (#351) + htmlwidgets 1.5 ----------------------------------------------------------------------- diff --git a/inst/www/htmlwidgets.js b/inst/www/htmlwidgets.js index 64c7e8d7..6f3d672d 100644 --- a/inst/www/htmlwidgets.js +++ b/inst/www/htmlwidgets.js @@ -659,44 +659,56 @@ invokePostRenderHandlers(); } - // Wait until after the document has loaded to render the widgets. - if (shinyMode && window.jQuery) { - /* - / Shiny 1.4.0 bumps jQuery from 1.x to 3.x, which means jQuery's - / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now - / really means $(setTimeout(fn)). https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous - / - / In order to ensure the order of execution of on-ready handlers - / remains consistent with how it's been in the past, a static render - / in Shiny is now scheduled via $(). - / - / This is not a long term solution: it just preserves the current order - / of execution. Part of that ordering is to ensure initShiny executes - / _after_ staticRender, which is both right and wrong: - / * It's wrong because, when initShiny executes, it registers methods - / like Shiny.onInputChange that widget authors would expect to be available - / during a staticRender. - / * It's also 'right' because initShiny currently (as of v1.4.0) wants - / to execute after user code so that it can bind to any dynamically - / created elements. - / - / A longer term solution might be to make changes to Shiny so that - / these methods are available before the binding takes place, and then - / the ordering would be: register methods -> static render -> bind. - */ - window.jQuery(function() { + + function has_jQuery3() { + if (!window.jQuery) { + return false; + } + var $version = window.jQuery.fn.jquery; + var $major_version = parseInt($version.split(".")[0]); + return $major_version >= 3; + } + + /* + / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's + / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now + / really means $(setTimeout(fn)). + / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous + / + / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny + / one tick later than it did before, which means staticRender() is + / called renderValue() earlier than (advanced) widget authors might be expecting. + / https://github.com/rstudio/shiny/issues/2630 + / + / For a concrete example, leaflet has some methods (e.g., updateBounds) + / which reference Shiny methods registered in initShiny (e.g., setInputValue). + / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to + / delay execution of those methods (until Shiny methods are ready) + / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268 + / + / Ideally widget authors wouldn't need to use this setTimeout() hack that + / leaflet uses to call Shiny methods on a staticRender(). In the long run, + / the logic initShiny should be broken up so that method registration happens + / right away, but binding happens later. + */ + function maybeStaticRenderLater() { + if (shinyMode && has_jQuery3()) { + window.jQuery(window.HTMLWidgets.staticRender); + } else { window.HTMLWidgets.staticRender(); - }); - } else if (document.addEventListener) { + } + } + + if (document.addEventListener) { document.addEventListener("DOMContentLoaded", function() { document.removeEventListener("DOMContentLoaded", arguments.callee, false); - window.HTMLWidgets.staticRender(); + maybeStaticRenderLater(); }, false); } else if (document.attachEvent) { document.attachEvent("onreadystatechange", function() { if (document.readyState === "complete") { document.detachEvent("onreadystatechange", arguments.callee); - window.HTMLWidgets.staticRender(); + maybeStaticRenderLater(); } }); } From 5b44e2a7e4b5b43b457ea254f59e219da29ba0b3 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Wed, 9 Oct 2019 12:55:48 -0700 Subject: [PATCH 08/13] Bump version for development --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index cd1383d3..6c93378c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.5.1 +Version: 1.5.1.9000 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")), From b3573236c4553019b30e595adcb4fbe693f4a834 Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Fri, 8 Nov 2019 11:36:50 -0600 Subject: [PATCH 09/13] Try evaluating code with parentheses before without parentheses, closes #356. (#357) The problem with evaluating without parentheses first is that named function declarations are valid expressions that return undefined (whereas evaluating with parentheses returns the function, as expected). It's true there may be weird corner-cases where switching this order leads to something else that's undesirable, but we've been operating with the 'with parentheses' model for so long that switching the ordering now will minimize backward-compatibility issues --- inst/NEWS | 5 +++++ inst/www/htmlwidgets.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/inst/NEWS b/inst/NEWS index 5d8b2f7d..139109aa 100644 --- a/inst/NEWS +++ b/inst/NEWS @@ -1,3 +1,8 @@ +htmlwidgets 1.5.1.9000 +------------------------------------------------------- + +* Fixed an issue with passing named function declarations to `JS()` and `onRender()` (introduced by v1.4). (#356) + htmlwidgets 1.5.1 ------------------------------------------------------- diff --git a/inst/www/htmlwidgets.js b/inst/www/htmlwidgets.js index 6f3d672d..3d227624 100644 --- a/inst/www/htmlwidgets.js +++ b/inst/www/htmlwidgets.js @@ -249,13 +249,13 @@ function tryEval(code) { var result = null; try { - result = eval(code); + result = eval("(" + code + ")"); } catch(error) { if (!error instanceof SyntaxError) { throw error; } try { - result = eval("(" + code + ")"); + result = eval(code); } catch(e) { if (e instanceof SyntaxError) { throw error; From bb2874ca847a552a390f7ad65efe20af806720df Mon Sep 17 00:00:00 2001 From: Carson Sievert Date: Wed, 6 May 2020 17:12:03 -0500 Subject: [PATCH 10/13] Add reportTheme arg to shinyWidgetOutput() (#361) * Add reportTheme arg to shinyWidgetOutput(), in anticipation of https://github.com/rstudio/shiny/pull/2740 * Throw message if reportTheme is TRUE and there is an outdated shiny version * news typo --- DESCRIPTION | 4 ++-- R/htmlwidgets.R | 22 +++++++++++++++++++--- inst/NEWS | 2 ++ man/createWidget.Rd | 14 +++++++++++--- man/htmlwidgets-shiny.Rd | 16 ++++++++++++---- man/saveWidget.Rd | 12 +++++++++--- man/sizingPolicy.Rd | 28 +++++++++++++++++++--------- 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 6c93378c..b3d61d67 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.5.1.9000 +Version: 1.5.1.9001 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")), @@ -25,4 +25,4 @@ Suggests: Enhances: shiny (>= 1.1) URL: https://github.com/ramnathv/htmlwidgets BugReports: https://github.com/ramnathv/htmlwidgets/issues -RoxygenNote: 6.1.1 +RoxygenNote: 7.0.2 diff --git a/R/htmlwidgets.R b/R/htmlwidgets.R index aff81807..1eab89b5 100644 --- a/R/htmlwidgets.R +++ b/R/htmlwidgets.R @@ -358,6 +358,8 @@ createWidget <- function(name, #' function. #' @param reportSize Should the widget's container size be reported in the #' shiny session's client data? +#' @param reportTheme Should the widget's container styles (e.g., colors and fonts) +#' be reported in the shiny session's client data? #' @param expr An expression that generates an HTML widget (or a #' \href{https://rstudio.github.io/promises/}{promise} of an HTML widget). #' @param env The environment in which to evaluate \code{expr}. @@ -386,13 +388,27 @@ createWidget <- function(name, #' #' @export shinyWidgetOutput <- function(outputId, name, width, height, package = name, - inline = FALSE, reportSize = FALSE) { + inline = FALSE, reportSize = FALSE, reportTheme = FALSE) { checkShinyVersion() + + # Theme reporting requires this shiny feature + # https://github.com/rstudio/shiny/pull/2740/files + if (reportTheme && + nzchar(system.file(package = "shiny")) && + packageVersion("shiny") < "1.4.0.9003") { + message("`reportTheme = TRUE` requires shiny v.1.4.0.9003 or higher. Consider upgrading shiny.") + } + # generate html html <- htmltools::tagList( - widget_html(name, package, id = outputId, - class = paste0(name, " html-widget html-widget-output", if (reportSize) " shiny-report-size"), + widget_html( + name, package, id = outputId, + class = paste0( + name, " html-widget html-widget-output", + if (reportSize) " shiny-report-size", + if (reportTheme) " shiny-report-theme" + ), style = sprintf("width:%s; height:%s; %s", htmltools::validateCssUnit(width), htmltools::validateCssUnit(height), diff --git a/inst/NEWS b/inst/NEWS index 139109aa..c2164906 100644 --- a/inst/NEWS +++ b/inst/NEWS @@ -3,6 +3,8 @@ htmlwidgets 1.5.1.9000 * Fixed an issue with passing named function declarations to `JS()` and `onRender()` (introduced by v1.4). (#356) +* Added a `reportTheme` argument to `shinyWidgetOutput()`. If `TRUE`, CSS styles of the widget's output container are made available to `shiny::getCurrentOutputInfo()`, making it possible to provide 'smart' styling defaults in a `renderWidget()` context. (#361) + htmlwidgets 1.5.1 ------------------------------------------------------- diff --git a/man/createWidget.Rd b/man/createWidget.Rd index ee77f9d2..413f318c 100644 --- a/man/createWidget.Rd +++ b/man/createWidget.Rd @@ -4,9 +4,17 @@ \alias{createWidget} \title{Create an HTML Widget} \usage{ -createWidget(name, x, width = NULL, height = NULL, - sizingPolicy = htmlwidgets::sizingPolicy(), package = name, - dependencies = NULL, elementId = NULL, preRenderHook = NULL) +createWidget( + name, + x, + width = NULL, + height = NULL, + sizingPolicy = htmlwidgets::sizingPolicy(), + package = name, + dependencies = NULL, + elementId = NULL, + preRenderHook = NULL +) } \arguments{ \item{name}{Widget name (should match the base name of the YAML and diff --git a/man/htmlwidgets-shiny.Rd b/man/htmlwidgets-shiny.Rd index a779ab73..659678bf 100644 --- a/man/htmlwidgets-shiny.Rd +++ b/man/htmlwidgets-shiny.Rd @@ -6,8 +6,16 @@ \alias{shinyRenderWidget} \title{Shiny bindings for HTML widgets} \usage{ -shinyWidgetOutput(outputId, name, width, height, package = name, - inline = FALSE, reportSize = FALSE) +shinyWidgetOutput( + outputId, + name, + width, + height, + package = name, + inline = FALSE, + reportSize = FALSE, + reportTheme = FALSE +) shinyRenderWidget(expr, outputFunction, env, quoted) } @@ -25,8 +33,8 @@ string and have \code{"px"} appended.} \item{inline}{use an inline (\code{span()}) or block container (\code{div()}) for the output} -\item{reportSize}{Should the widget's container size be reported in the -shiny session's client data?} +\item{reportSize}{Should the widget's container styles (e.g., background +/foreground color) be reported in the shiny session's client data?} \item{expr}{An expression that generates an HTML widget (or a \href{https://rstudio.github.io/promises/}{promise} of an HTML widget).} diff --git a/man/saveWidget.Rd b/man/saveWidget.Rd index d5555625..62d6032d 100644 --- a/man/saveWidget.Rd +++ b/man/saveWidget.Rd @@ -4,9 +4,15 @@ \alias{saveWidget} \title{Save a widget to an HTML file} \usage{ -saveWidget(widget, file, selfcontained = TRUE, libdir = NULL, - background = "white", title = class(widget)[[1]], - knitrOptions = list()) +saveWidget( + widget, + file, + selfcontained = TRUE, + libdir = NULL, + background = "white", + title = class(widget)[[1]], + knitrOptions = list() +) } \arguments{ \item{widget}{Widget to save} diff --git a/man/sizingPolicy.Rd b/man/sizingPolicy.Rd index 39ff985e..fcaef019 100644 --- a/man/sizingPolicy.Rd +++ b/man/sizingPolicy.Rd @@ -4,15 +4,25 @@ \alias{sizingPolicy} \title{Create a widget sizing policy} \usage{ -sizingPolicy(defaultWidth = NULL, defaultHeight = NULL, - padding = NULL, viewer.defaultWidth = NULL, - viewer.defaultHeight = NULL, viewer.padding = NULL, - viewer.fill = TRUE, viewer.suppress = FALSE, - viewer.paneHeight = NULL, browser.defaultWidth = NULL, - browser.defaultHeight = NULL, browser.padding = NULL, - browser.fill = FALSE, browser.external = FALSE, - knitr.defaultWidth = NULL, knitr.defaultHeight = NULL, - knitr.figure = TRUE) +sizingPolicy( + defaultWidth = NULL, + defaultHeight = NULL, + padding = NULL, + viewer.defaultWidth = NULL, + viewer.defaultHeight = NULL, + viewer.padding = NULL, + viewer.fill = TRUE, + viewer.suppress = FALSE, + viewer.paneHeight = NULL, + browser.defaultWidth = NULL, + browser.defaultHeight = NULL, + browser.padding = NULL, + browser.fill = FALSE, + browser.external = FALSE, + knitr.defaultWidth = NULL, + knitr.defaultHeight = NULL, + knitr.figure = TRUE +) } \arguments{ \item{defaultWidth}{The default width used to display the widget. This From 6fcc4b03ed3fc42be76d4e43d863db3d85c8babb Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Sat, 23 May 2020 11:46:25 -0700 Subject: [PATCH 11/13] Add missing roxygenize step (#370) * Add missing roxygenize step * Remove setwd, it's done automatically now --- vignettes/develop_intro.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/develop_intro.Rmd b/vignettes/develop_intro.Rmd index bd37a7e6..fdaa5a25 100644 --- a/vignettes/develop_intro.Rmd +++ b/vignettes/develop_intro.Rmd @@ -278,8 +278,8 @@ This method is highly recommended as it ensures that you get started with the ri ```r devtools::create("mywidget") # create package using devtools -setwd("mywidget") # navigate to package dir htmlwidgets::scaffoldWidget("mywidget") # create widget scaffolding +devtools::document() # roxygenize, so NAMESPACE is updated devtools::install() # install the package so we can try it ``` From 52bf8751d9efe974d4e4a4be193a32a3493c0ce0 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Tue, 25 Aug 2020 14:08:47 -0700 Subject: [PATCH 12/13] Export JSEvals (#381) --- DESCRIPTION | 2 +- NAMESPACE | 1 + R/utils.R | 36 +++++++++++++++++++++++------------- inst/NEWS | 2 ++ man/JSEvals.Rd | 34 ++++++++++++++++++++++++++++++++++ man/htmlwidgets-shiny.Rd | 7 +++++-- 6 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 man/JSEvals.Rd diff --git a/DESCRIPTION b/DESCRIPTION index b3d61d67..73857fd9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -25,4 +25,4 @@ Suggests: Enhances: shiny (>= 1.1) URL: https://github.com/ramnathv/htmlwidgets BugReports: https://github.com/ramnathv/htmlwidgets/issues -RoxygenNote: 7.0.2 +RoxygenNote: 7.1.1 diff --git a/NAMESPACE b/NAMESPACE index c37ce80f..160e645b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,7 @@ S3method(as.tags,htmlwidget) S3method(print,htmlwidget) S3method(print,suppress_viewer) export(JS) +export(JSEvals) export(appendContent) export(createWidget) export(getDependency) diff --git a/R/utils.R b/R/utils.R index 3a7de263..6d5a107c 100644 --- a/R/utils.R +++ b/R/utils.R @@ -128,19 +128,29 @@ JS <- function(...) { structure(x, class = unique(c("JS_EVAL", oldClass(x)))) } -# Creates a list of keys whose values need to be evaluated on the client-side. -# -# It works by transforming \code{list(foo = list(1, list(bar = -# I('function(){}')), 2))} to \code{list("foo.2.bar")}. Later on the JS side, we -# will split foo.2.bar to ['foo', '2', 'bar'] and evaluate the JSON object -# member. Note '2' (character) should have been 2 (integer) but it does not seem -# to matter in JS: x[2] is the same as x['2'] when all child members of x are -# unnamed, and ('2' in x) will be true even if x is an array without names. This -# is a little hackish. -# -# @param list a list in which the elements that should be evaluated as -# JavaScript are to be identified -# @author Yihui Xie +#' Creates a list of keys whose values need to be evaluated on the client-side +#' +#' It works by transforming \code{list(foo = list(1, list(bar = +#' I('function(){}')), 2))} to \code{list("foo.2.bar")}. Later on the JS side, +#' the \code{window.HTMLWidgets.evaluateStringMember} function is called with +#' the JSON object and the "foo.2.bar" string, which is split to \code{['foo', +#' '2', 'bar']}, and the string at that location is replaced \emph{in-situ} with +#' the results of evaluating it. Note '2' (character) should have been 2 +#' (integer) but it does not seem to matter in JS: x[2] is the same as x['2'] +#' when all child members of x are unnamed, and ('2' in x) will be true even if +#' x is an array without names. This is a little hackish. +#' +#' This function is intended mostly for internal use. There's generally no need +#' for widget authors or users to call it, as it's called automatically on the +#' widget instance data during rendering. It's exported in case other packages +#' want to add support for \code{\link{JS}} in contexts outside of widget +#' payloads. +#' +#' @param list a list in which the elements that should be evaluated as +#' JavaScript are to be identified +#' @author Yihui Xie +#' @keywords internal +#' @export JSEvals <- function(list) { # the `%||% list()` part is necessary as of R 3.4.0 (April 2017) -- if `evals` # is NULL then `I(evals)` results in a warning in R 3.4.0. This is circumvented diff --git a/inst/NEWS b/inst/NEWS index c2164906..8c90f28d 100644 --- a/inst/NEWS +++ b/inst/NEWS @@ -5,6 +5,8 @@ htmlwidgets 1.5.1.9000 * Added a `reportTheme` argument to `shinyWidgetOutput()`. If `TRUE`, CSS styles of the widget's output container are made available to `shiny::getCurrentOutputInfo()`, making it possible to provide 'smart' styling defaults in a `renderWidget()` context. (#361) +* Export the `JSEvals` function, allowing other packages to support `JS()` in non-widget contexts. + htmlwidgets 1.5.1 ------------------------------------------------------- diff --git a/man/JSEvals.Rd b/man/JSEvals.Rd new file mode 100644 index 00000000..210d76e7 --- /dev/null +++ b/man/JSEvals.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{JSEvals} +\alias{JSEvals} +\title{Creates a list of keys whose values need to be evaluated on the client-side} +\usage{ +JSEvals(list) +} +\arguments{ +\item{list}{a list in which the elements that should be evaluated as +JavaScript are to be identified} +} +\description{ +It works by transforming \code{list(foo = list(1, list(bar = +I('function(){}')), 2))} to \code{list("foo.2.bar")}. Later on the JS side, +the \code{window.HTMLWidgets.evaluateStringMember} function is called with +the JSON object and the "foo.2.bar" string, which is split to \code{['foo', +'2', 'bar']}, and the string at that location is replaced \emph{in-situ} with +the results of evaluating it. Note '2' (character) should have been 2 +(integer) but it does not seem to matter in JS: x[2] is the same as x['2'] +when all child members of x are unnamed, and ('2' in x) will be true even if +x is an array without names. This is a little hackish. +} +\details{ +This function is intended mostly for internal use. There's generally no need +for widget authors or users to call it, as it's called automatically on the +widget instance data during rendering. It's exported in case other packages +want to add support for \code{\link{JS}} in contexts outside of widget +payloads. +} +\author{ +Yihui Xie +} +\keyword{internal} diff --git a/man/htmlwidgets-shiny.Rd b/man/htmlwidgets-shiny.Rd index 659678bf..e641cfb3 100644 --- a/man/htmlwidgets-shiny.Rd +++ b/man/htmlwidgets-shiny.Rd @@ -33,8 +33,11 @@ string and have \code{"px"} appended.} \item{inline}{use an inline (\code{span()}) or block container (\code{div()}) for the output} -\item{reportSize}{Should the widget's container styles (e.g., background -/foreground color) be reported in the shiny session's client data?} +\item{reportSize}{Should the widget's container size be reported in the +shiny session's client data?} + +\item{reportTheme}{Should the widget's container styles (e.g., colors and fonts) +be reported in the shiny session's client data?} \item{expr}{An expression that generates an HTML widget (or a \href{https://rstudio.github.io/promises/}{promise} of an HTML widget).} From 62a1695f94a0a588cdd9f9d0bfe2fd86ff8af664 Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Tue, 25 Aug 2020 15:07:41 -0700 Subject: [PATCH 13/13] Bump dev version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 73857fd9..54e473ec 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: htmlwidgets Type: Package Title: HTML Widgets for R -Version: 1.5.1.9001 +Version: 1.5.1.9002 Authors@R: c( person("Ramnath", "Vaidyanathan", role = c("aut", "cph")), person("Yihui", "Xie", role = c("aut")),