mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-13 17:08:05 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69c32d4d90 | ||
|
|
36ffebd975 | ||
|
|
deb56539fb | ||
|
|
af8d099b9f | ||
|
|
eed869d321 | ||
|
|
f8f2acf6c3 | ||
|
|
7be9f74827 | ||
|
|
ed77982330 | ||
|
|
e1b47eca90 | ||
|
|
bfa0b2d2bc | ||
|
|
d67783edbd | ||
|
|
77712b6664 | ||
|
|
1633e7faa6 | ||
|
|
2dc5ee5862 | ||
|
|
bbaea23eea | ||
|
|
d112ac7eef | ||
|
|
cf21e987f2 | ||
|
|
dae11765bc | ||
|
|
df30a3c7f4 | ||
|
|
aaa4600597 | ||
|
|
ba1730d26b |
@@ -1,7 +1,7 @@
|
||||
Package: shiny
|
||||
Type: Package
|
||||
Title: Web Application Framework for R
|
||||
Version: 1.0.1
|
||||
Version: 1.0.3
|
||||
Authors@R: c(
|
||||
person("Winston", "Chang", role = c("aut", "cre"), email = "winston@rstudio.com"),
|
||||
person("Joe", "Cheng", role = "aut", email = "joe@rstudio.com"),
|
||||
@@ -56,7 +56,7 @@ Authors@R: c(
|
||||
)
|
||||
Description: Makes it incredibly easy to build interactive web
|
||||
applications with R. Automatic "reactive" binding between inputs and
|
||||
outputs and extensive pre-built widgets make it possible to build
|
||||
outputs and extensive prebuilt widgets make it possible to build
|
||||
beautiful, responsive, and powerful applications with minimal effort.
|
||||
License: GPL-3 | file LICENSE
|
||||
Depends:
|
||||
|
||||
36
NEWS.md
36
NEWS.md
@@ -1,3 +1,37 @@
|
||||
shiny 1.0.3
|
||||
================
|
||||
|
||||
This is a hotfix release of Shiny. With previous versions of Shiny, when running an application on the newly-released version of R, 3.4.0, it would print a message: `Warning in body(fun) : argument is not a function`. This has no effect on the application, but because the message could be alarming to users, we are releasing a new version of Shiny that fixes this issue.
|
||||
|
||||
## Full changelog
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Fixed [#1672](https://github.com/rstudio/shiny/issues/1672): When an error occurred while uploading a file, the progress bar did not change colors. ([#1673](https://github.com/rstudio/shiny/pull/1673))
|
||||
|
||||
* Fixed [#1676](https://github.com/rstudio/shiny/issues/1676): On R 3.4.0, running a Shiny application gave a warning: `Warning in body(fun) : argument is not a function`. ([#1677](https://github.com/rstudio/shiny/pull/1677))
|
||||
|
||||
|
||||
shiny 1.0.2
|
||||
================
|
||||
|
||||
This is a hotfix release of Shiny. The primary reason for this release is because the web host for MathJax JavaScript library is scheduled to be shut down in the next few weeks. After it is shut down, Shiny applications that use MathJax will no longer be able to load the MathJax library if they are run with Shiny 1.0.1 and below. (If you don't know whether your application uses MathJax, it probably does not.) For more information about why the MathJax CDN is shutting down, see https://www.mathjax.org/cdn-shutting-down/.
|
||||
|
||||
## Full changelog
|
||||
|
||||
### Minor new features and improvements
|
||||
|
||||
* Added a `shiny:sessioninitialized` Javascript event, which is fired at the end of the initialize method of the Session object. This allows us to listen for this event when we want to get the value of things like `Shiny.user`. ([#1568](https://github.com/rstudio/shiny/pull/1568))
|
||||
|
||||
* Fixed [#1649](https://github.com/rstudio/shiny/issues/1649): allow the `choices` argument in `checkboxGroupInput()` to be `NULL` (or `c()`) to keep backward compatibility with Shiny < 1.0.1. This will result in the same thing as providing `choices = character(0)`. ([#1652](https://github.com/rstudio/shiny/pull/1652))
|
||||
|
||||
* The official URL for accessing MathJax libraries over CDN has been deprecated and will be removed soon. We have switched to a new rstudio.com URL that we will support going forward. ([#1664](https://github.com/rstudio/shiny/pull/1664))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Fixed [#1653](https://github.com/rstudio/shiny/issues/1653): wrong code example in documentation. ([#1658](https://github.com/rstudio/shiny/pull/1658))
|
||||
|
||||
|
||||
shiny 1.0.1
|
||||
================
|
||||
|
||||
@@ -19,7 +53,7 @@ This is a maintenance release of Shiny, mostly aimed at fixing bugs and introduc
|
||||
|
||||
* Addressed [#1348](https://github.com/rstudio/shiny/issues/1348) and [#1437](https://github.com/rstudio/shiny/issues/1437) by adding two new arguments to `radioButtons()` and `checkboxGroupInput()`: `choiceNames` (list or vector) and `choiceValues` (list or vector). These can be passed in as an alternative to `choices`, with the added benefit that the elements in `choiceNames` can be arbitrary UI (i.e. anything created by `HTML()` and the `tags()` functions, like icons and images). While the underlying values for each choice (passed in through `choiceValues`) must still be simple text, their visual representation on the app (what the user actually clicks to select a different option) can be any valid HTML element. See `?radioButtons` for a small example. ([#1521](https://github.com/rstudio/shiny/pull/1521))
|
||||
|
||||
* Updated `tools/README.md` with more detailed instructions. ([##1616](https://github.com/rstudio/shiny/pull/1616))
|
||||
* Updated `tools/README.md` with more detailed instructions. ([#1616](https://github.com/rstudio/shiny/pull/1616))
|
||||
|
||||
* Fixed [#1565](https://github.com/rstudio/shiny/issues/1565), which meant that resources with spaces in their names return HTTP 404. ([#1566](https://github.com/rstudio/shiny/pull/1566))
|
||||
|
||||
|
||||
@@ -70,6 +70,11 @@
|
||||
checkboxGroupInput <- function(inputId, label, choices = NULL, selected = NULL,
|
||||
inline = FALSE, width = NULL, choiceNames = NULL, choiceValues = NULL) {
|
||||
|
||||
# keep backward compatibility with Shiny < 1.0.1 (see #1649)
|
||||
if (is.null(choices) && is.null(choiceNames) && is.null(choiceValues)) {
|
||||
choices <- character(0)
|
||||
}
|
||||
|
||||
args <- normalizeChoicesArgs(choices, choiceNames, choiceValues)
|
||||
|
||||
selected <- restoreInput(id = inputId, default = selected)
|
||||
|
||||
@@ -1541,9 +1541,22 @@ coerceToFunc <- function(x) {
|
||||
#' @seealso \code{\link{reactiveFileReader}}
|
||||
#'
|
||||
#' @examples
|
||||
#' # Assume the existence of readTimestamp and readValue functions
|
||||
#' function(input, output, session) {
|
||||
#' data <- reactivePoll(1000, session, readTimestamp, readValue)
|
||||
#'
|
||||
#' data <- reactivePoll(1000, session,
|
||||
#' # This function returns the time that log_file was last modified
|
||||
#' checkFunc = function() {
|
||||
#' if (file.exists(log_file))
|
||||
#' file.info(log_file)$mtime[1]
|
||||
#' else
|
||||
#' ""
|
||||
#' },
|
||||
#' # This function returns the content of log_file
|
||||
#' valueFunc = function() {
|
||||
#' read.csv(log_file)
|
||||
#' }
|
||||
#' )
|
||||
#'
|
||||
#' output$dataTable <- renderTable({
|
||||
#' data()
|
||||
#' })
|
||||
@@ -1618,7 +1631,7 @@ reactivePoll <- function(intervalMillis, session, checkFunc, valueFunc) {
|
||||
#' # Cross-session reactive file reader. In this example, all sessions share
|
||||
#' # the same reader, so read.csv only gets executed once no matter how many
|
||||
#' # user sessions are connected.
|
||||
#' fileData <- reactiveFileReader(1000, session, 'data.csv', read.csv)
|
||||
#' fileData <- reactiveFileReader(1000, NULL, 'data.csv', read.csv)
|
||||
#' function(input, output, session) {
|
||||
#' output$data <- renderTable({
|
||||
#' fileData()
|
||||
|
||||
@@ -470,11 +470,13 @@ find_panel_info <- function(b) {
|
||||
# This is for ggplot2>2.2.1, after an API was introduced for extracting
|
||||
# information about the plot object.
|
||||
find_panel_info_api <- function(b) {
|
||||
# Workaround for check NOTE, until ggplot2 >2.2.1 is released
|
||||
colon_colon <- `::`
|
||||
# Given a built ggplot object, return x and y domains (data space coords) for
|
||||
# each panel.
|
||||
layout <- ggplot2::summarise_layout(b)
|
||||
coord <- ggplot2::summarise_coord(b)
|
||||
layers <- ggplot2::summarise_layers(b)
|
||||
layout <- colon_colon("ggplot2", "summarise_layout")(b)
|
||||
coord <- colon_colon("ggplot2", "summarise_coord")(b)
|
||||
layers <- colon_colon("ggplot2", "summarise_layers")(b)
|
||||
|
||||
# Given x and y scale objects and a coord object, return a list that has
|
||||
# the bases of log transformations for x and y, or NULL if it's not a
|
||||
|
||||
@@ -370,9 +370,9 @@ argsForServerFunc <- function(serverFunc, session) {
|
||||
}
|
||||
|
||||
getEffectiveBody <- function(func) {
|
||||
# Note: NULL values are OK. isS4(NULL) returns FALSE, body(NULL)
|
||||
# returns NULL.
|
||||
if (isS4(func) && class(func) == "functionWithTrace")
|
||||
if (is.null(func))
|
||||
NULL
|
||||
else if (isS4(func) && class(func) == "functionWithTrace")
|
||||
body(func@original)
|
||||
else
|
||||
body(func)
|
||||
|
||||
@@ -5,7 +5,7 @@ NULL
|
||||
#'
|
||||
#' Shiny makes it incredibly easy to build interactive web applications with R.
|
||||
#' Automatic "reactive" binding between inputs and outputs and extensive
|
||||
#' pre-built widgets make it possible to build beautiful, responsive, and
|
||||
#' prebuilt widgets make it possible to build beautiful, responsive, and
|
||||
#' powerful applications with minimal effort.
|
||||
#'
|
||||
#' The Shiny tutorial at \url{http://shiny.rstudio.com/tutorial/} explains
|
||||
|
||||
@@ -14,7 +14,7 @@ NULL
|
||||
#' # now we can just write "static" content without withMathJax()
|
||||
#' div("more math here $$\\sqrt{2}$$")
|
||||
withMathJax <- function(...) {
|
||||
path <- 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
|
||||
path <- 'https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
|
||||
tagList(
|
||||
tags$head(
|
||||
singleton(tags$script(src = path, type = 'text/javascript'))
|
||||
|
||||
@@ -18,7 +18,8 @@ licenseLink <- function(licenseName) {
|
||||
"Artistic-2.0" = "http://www.r-project.org/Licenses/Artistic-2.0",
|
||||
"BSD_2_clause" = "http://www.r-project.org/Licenses/BSD_2_clause",
|
||||
"BSD_3_clause" = "http://www.r-project.org/Licenses/BSD_3_clause",
|
||||
"MIT" = "http://www.r-project.org/Licenses/MIT")
|
||||
"MIT" = "http://www.r-project.org/Licenses/MIT",
|
||||
"CC-BY-SA-4.0" = "https://www.r-project.org/Licenses/CC-BY-SA-4.0")
|
||||
if (exists(licenseName, where = licenses)) {
|
||||
tags$a(href=licenses[[licenseName]], licenseName)
|
||||
} else {
|
||||
|
||||
@@ -14,9 +14,9 @@ For an introduction and examples, visit the [Shiny Dev Center](http://shiny.rstu
|
||||
* Shiny applications are automatically "live" in the same way that spreadsheets are live. Outputs change instantly as users modify inputs, without requiring a reload of the browser.
|
||||
* Shiny user interfaces can be built entirely using R, or can be written directly in HTML, CSS, and JavaScript for more flexibility.
|
||||
* Works in any R environment (Console R, Rgui for Windows or Mac, ESS, StatET, RStudio, etc.).
|
||||
* Attractive default UI theme based on [Bootstrap](http://getbootstrap.com/2.3.2/).
|
||||
* Attractive default UI theme based on [Bootstrap](http://getbootstrap.com/).
|
||||
* A highly customizable slider widget with built-in support for animation.
|
||||
* Pre-built output widgets for displaying plots, tables, and printed output of R objects.
|
||||
* Prebuilt output widgets for displaying plots, tables, and printed output of R objects.
|
||||
* Fast bidirectional communication between the web browser and R using the [httpuv](https://github.com/rstudio/httpuv) package.
|
||||
* Uses a [reactive](http://en.wikipedia.org/wiki/Reactive_programming) programming model that eliminates messy event handling code, so you can focus on the code that really matters.
|
||||
* Develop and redistribute your own Shiny widgets that other developers can easily drop into their own applications (coming soon!).
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
.shiny-code {
|
||||
background-color: white;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.shiny-code code {
|
||||
|
||||
@@ -1241,6 +1241,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
||||
addMessageHandler('config', function (message) {
|
||||
this.config = { workerId: message.workerId, sessionId: message.sessionId };
|
||||
if (message.user) exports.user = message.user;
|
||||
$(document).trigger('shiny:sessioninitialized');
|
||||
});
|
||||
|
||||
addMessageHandler('busy', function (message) {
|
||||
@@ -4978,7 +4979,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
||||
this.$container().css('visibility', visible ? 'visible' : 'hidden');
|
||||
};
|
||||
this.$setError = function (error) {
|
||||
this.$bar().toggleClass('bar-danger', error !== null);
|
||||
this.$bar().toggleClass('progress-bar-danger', error !== null);
|
||||
if (error !== null) {
|
||||
this.onProgress(null, 1);
|
||||
this.$bar().text(error);
|
||||
|
||||
File diff suppressed because one or more lines are too long
6
inst/www/shared/shiny.min.js
vendored
6
inst/www/shared/shiny.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -58,7 +58,7 @@ function(input, output, session) {
|
||||
# Cross-session reactive file reader. In this example, all sessions share
|
||||
# the same reader, so read.csv only gets executed once no matter how many
|
||||
# user sessions are connected.
|
||||
fileData <- reactiveFileReader(1000, session, 'data.csv', read.csv)
|
||||
fileData <- reactiveFileReader(1000, NULL, 'data.csv', read.csv)
|
||||
function(input, output, session) {
|
||||
output$data <- renderTable({
|
||||
fileData()
|
||||
|
||||
@@ -57,9 +57,22 @@ will be executed in a reactive context; therefore, they may read reactive
|
||||
values and reactive expressions.
|
||||
}
|
||||
\examples{
|
||||
# Assume the existence of readTimestamp and readValue functions
|
||||
function(input, output, session) {
|
||||
data <- reactivePoll(1000, session, readTimestamp, readValue)
|
||||
|
||||
data <- reactivePoll(1000, session,
|
||||
# This function returns the time that log_file was last modified
|
||||
checkFunc = function() {
|
||||
if (file.exists(log_file))
|
||||
file.info(log_file)$mtime[1]
|
||||
else
|
||||
""
|
||||
},
|
||||
# This function returns the content of log_file
|
||||
valueFunc = function() {
|
||||
read.csv(log_file)
|
||||
}
|
||||
)
|
||||
|
||||
output$dataTable <- renderTable({
|
||||
data()
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
\description{
|
||||
Shiny makes it incredibly easy to build interactive web applications with R.
|
||||
Automatic "reactive" binding between inputs and outputs and extensive
|
||||
pre-built widgets make it possible to build beautiful, responsive, and
|
||||
prebuilt widgets make it possible to build beautiful, responsive, and
|
||||
powerful applications with minimal effort.
|
||||
}
|
||||
\details{
|
||||
|
||||
@@ -169,7 +169,7 @@ $.extend(FileUploader.prototype, FileProcessor.prototype);
|
||||
this.$container().css('visibility', visible ? 'visible' : 'hidden');
|
||||
};
|
||||
this.$setError = function(error) {
|
||||
this.$bar().toggleClass('bar-danger', (error !== null));
|
||||
this.$bar().toggleClass('progress-bar-danger', (error !== null));
|
||||
if (error !== null) {
|
||||
this.onProgress(null, 1);
|
||||
this.$bar().text(error);
|
||||
|
||||
@@ -631,6 +631,7 @@ var ShinyApp = function() {
|
||||
addMessageHandler('config', function(message) {
|
||||
this.config = {workerId: message.workerId, sessionId: message.sessionId};
|
||||
if (message.user) exports.user = message.user;
|
||||
$(document).trigger('shiny:sessioninitialized');
|
||||
});
|
||||
|
||||
addMessageHandler('busy', function(message) {
|
||||
|
||||
@@ -247,3 +247,21 @@ test_that("normalizeChoicesArgs does its job", {
|
||||
expected <- list(choiceNames = NULL, choiceValues = NULL)
|
||||
expect_equal(normalizeChoicesArgs(NULL, NULL, NULL, FALSE), expected)
|
||||
})
|
||||
|
||||
test_that("Choices need not be provided, can be NULL or c()", {
|
||||
|
||||
expected <- "<div id=\"cb\" class=\"form-group shiny-input-checkboxgroup shiny-input-container\">\n <label class=\"control-label\" for=\"cb\">Choose:</label>\n <div class=\"shiny-options-group\"></div>\n</div>"
|
||||
noChoices <- checkboxGroupInput("cb", "Choose:")
|
||||
choicesNull <- checkboxGroupInput("cb", "Choose:", choices = NULL)
|
||||
choicesCharacter <- checkboxGroupInput("cb", "Choose:", choices = c())
|
||||
choicesCharacter0 <- checkboxGroupInput("cb", "Choose:", choices = character(0))
|
||||
allChoicesNull <- checkboxGroupInput("cb", "Choose:", choices = NULL,
|
||||
choiceNames = NULL, choiceValues = NULL)
|
||||
|
||||
expect_identical(noChoices, choicesNull)
|
||||
expect_identical(noChoices, choicesCharacter)
|
||||
expect_identical(noChoices, choicesCharacter0)
|
||||
expect_identical(noChoices, allChoicesNull)
|
||||
|
||||
expect_true(grepl(fixed = TRUE, expected, format(noChoices)))
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user