mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-13 08:57:57 -05:00
Compare commits
2 Commits
randomPort
...
wch-bump-l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cc63109a7 | ||
|
|
bf79ef1cdb |
@@ -65,7 +65,7 @@ Depends:
|
||||
Imports:
|
||||
utils,
|
||||
grDevices,
|
||||
httpuv (>= 1.5.1.9002),
|
||||
httpuv (>= 1.5.2),
|
||||
mime (>= 0.3),
|
||||
jsonlite (>= 0.9.16),
|
||||
xtable,
|
||||
@@ -73,7 +73,7 @@ Imports:
|
||||
htmltools (>= 0.3.6.9004),
|
||||
R6 (>= 2.0),
|
||||
sourcetools,
|
||||
later (>= 0.7.2),
|
||||
later (>= 0.8.0.9004),
|
||||
promises (>= 1.0.1),
|
||||
tools,
|
||||
crayon,
|
||||
@@ -91,7 +91,7 @@ Suggests:
|
||||
magrittr
|
||||
Remotes:
|
||||
rstudio/htmltools,
|
||||
rstudio/httpuv
|
||||
r-lib/later
|
||||
URL: http://shiny.rstudio.com
|
||||
BugReports: https://github.com/rstudio/shiny/issues
|
||||
Collate:
|
||||
|
||||
@@ -84,7 +84,6 @@ export(fileInput)
|
||||
export(fillCol)
|
||||
export(fillPage)
|
||||
export(fillRow)
|
||||
export(findPort)
|
||||
export(fixedPage)
|
||||
export(fixedPanel)
|
||||
export(fixedRow)
|
||||
|
||||
6
NEWS.md
6
NEWS.md
@@ -46,14 +46,10 @@ shiny 1.3.2.9001
|
||||
|
||||
* Fixed [#2233](https://github.com/rstudio/shiny/issues/2233): `verbatimTextOutput()` produced wrapped text on Safari, but the text should not be wrapped. ([#2353](https://github.com/rstudio/shiny/pull/2353))
|
||||
|
||||
* Fixed [#2335](https://github.com/rstudio/shiny/issues/2335): When `dateInput()`'s `value` was unspecified, and `max` and/or `min` was set to `Sys.Date()`, the value was not being set properly. ([#2526](https://github.com/rstudio/shiny/pull/2526))
|
||||
|
||||
* Fixed [#2591](https://github.com/rstudio/shiny/issues/2591): Providing malformed date-strings to `min` or `max` no longer results in JS errors for `dateInput()` and `dateRangeInput()`. ([#2592](https://github.com/rstudio/shiny/pull/2592))
|
||||
* Fixed [#2335](https://github.com/rstudio/shiny/issues/2335): When `dateInput()`'s `value` was unspecified, and `max` and/or `min` was set to `Sys.Date()`, the value was not being set properly. ([#2526](https://github.com/rstudio/shiny/pull/2526))
|
||||
|
||||
* Fixed [rstudio/reactlog#36](https://github.com/rstudio/reactlog/issues/36): Changes to reactive values not displaying accurately in reactlog. ([#2424](https://github.com/rstudio/shiny/pull/2424))
|
||||
|
||||
* Fixed [#2598](https://github.com/rstudio/shiny/issues/2598): Showcase files don't appear with a wide window. ([#2582](https://github.com/rstudio/shiny/pull/2582))
|
||||
|
||||
* Fixed [#2329](https://github.com/rstudio/shiny/issues/2329), [#1817](https://github.com/rstudio/shiny/issues/1817): These bugs were reported as fixed in Shiny 1.3.0 but were not actually fixed because some JavaScript changes were accidentally not included in the release. The fix resolves issues that occur when `withProgressBar()` or bookmarking are combined with the [networkD3](https://christophergandrud.github.io/networkD3/) package's Sankey plot.
|
||||
|
||||
### Library updates
|
||||
|
||||
124
R/server.R
124
R/server.R
@@ -85,25 +85,24 @@ addResourcePath <- function(prefix, directoryPath) {
|
||||
}
|
||||
)
|
||||
|
||||
# # Often times overwriting a resource path is "what you want",
|
||||
# # but sometimes it can lead to difficult to diagnose issues
|
||||
# # (e.g. an implict dependency might set a resource path that
|
||||
# # conflicts with what you, the app author, are trying to register)
|
||||
# # Note that previous versions of shiny used to warn about this case,
|
||||
# # but it was eventually removed since it caused confusion (#567).
|
||||
# # It seems a good compromise is to throw a more information message.
|
||||
# if (getOption("shiny.resourcePathChanges", FALSE) &&
|
||||
# prefix %in% names(.globals$resourcePaths)) {
|
||||
# existingPath <- .globals$resourcePaths[[prefix]]$path
|
||||
# if (normalizedPath != existingPath) {
|
||||
# message(
|
||||
# "The resource path '", prefix, "' used to point to ",
|
||||
# existingPath, ", but it now points to ", normalizedPath, ". ",
|
||||
# "If your app doesn't work as expected, you may want to ",
|
||||
# "choose a different prefix name."
|
||||
# )
|
||||
# }
|
||||
# }
|
||||
# Often times overwriting a resource path is "what you want",
|
||||
# but sometimes it can lead to difficult to diagnose issues
|
||||
# (e.g. an implict dependency might set a resource path that
|
||||
# conflicts with what you, the app author, are trying to register)
|
||||
# Note that previous versions of shiny used to warn about this case,
|
||||
# but it was eventually removed since it caused confusion (#567).
|
||||
# It seems a good comprimise is to throw a more information message.
|
||||
if (prefix %in% names(.globals$resourcePaths)) {
|
||||
existingPath <- .globals$resourcePaths[[prefix]]$path
|
||||
if (normalizedPath != existingPath) {
|
||||
message(
|
||||
"The resource path '", prefix, "' used to point to ",
|
||||
existingPath, ", but it now points to ", normalizedPath, ". ",
|
||||
"If your app doesn't work as expected, you may want to ",
|
||||
"choose a different prefix name."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# If a shiny app is currently running, dynamically register this path with
|
||||
# the corresponding httpuv server object.
|
||||
@@ -724,7 +723,7 @@ isRunning <- function() {
|
||||
#' }
|
||||
#' @export
|
||||
runApp <- function(appDir=getwd(),
|
||||
port=getOption('shiny.port', findPort(host = host)),
|
||||
port=getOption('shiny.port'),
|
||||
launch.browser=getOption('shiny.launch.browser',
|
||||
interactive()),
|
||||
host=getOption('shiny.host', '127.0.0.1'),
|
||||
@@ -794,12 +793,12 @@ runApp <- function(appDir=getwd(),
|
||||
if (arg %in% names(appOps)) appOps[[arg]] else default
|
||||
}
|
||||
|
||||
if (missing(host))
|
||||
host <- findVal("host", host %OR% '0.0.0.0')
|
||||
if (missing(port))
|
||||
port <- findVal("port", port %OR% findPort(host = host))
|
||||
port <- findVal("port", port)
|
||||
if (missing(launch.browser))
|
||||
launch.browser <- findVal("launch.browser", launch.browser)
|
||||
if (missing(host))
|
||||
host <- findVal("host", host)
|
||||
if (missing(quiet))
|
||||
quiet <- findVal("quiet", quiet)
|
||||
if (missing(display.mode))
|
||||
@@ -807,6 +806,8 @@ runApp <- function(appDir=getwd(),
|
||||
if (missing(test.mode))
|
||||
test.mode <- findVal("test.mode", test.mode)
|
||||
|
||||
if (is.null(host) || is.na(host)) host <- '0.0.0.0'
|
||||
|
||||
workerId(workerId)
|
||||
|
||||
if (inShinyServer()) {
|
||||
@@ -881,6 +882,44 @@ runApp <- function(appDir=getwd(),
|
||||
|
||||
require(shiny)
|
||||
|
||||
# determine port if we need to
|
||||
if (is.null(port)) {
|
||||
|
||||
# Try up to 20 random ports. If we don't succeed just plow ahead
|
||||
# with the final value we tried, and let the "real" startServer
|
||||
# somewhere down the line fail and throw the error to the user.
|
||||
#
|
||||
# If we (think we) succeed, save the value as .globals$lastPort,
|
||||
# and try that first next time the user wants a random port.
|
||||
|
||||
for (i in 1:20) {
|
||||
if (!is.null(.globals$lastPort)) {
|
||||
port <- .globals$lastPort
|
||||
.globals$lastPort <- NULL
|
||||
}
|
||||
else {
|
||||
# Try up to 20 random ports
|
||||
while (TRUE) {
|
||||
port <- p_randomInt(3000, 8000)
|
||||
# Reject ports in this range that are considered unsafe by Chrome
|
||||
# http://superuser.com/questions/188058/which-ports-are-considered-unsafe-on-chrome
|
||||
# https://github.com/rstudio/shiny/issues/1784
|
||||
if (!port %in% c(3659, 4045, 6000, 6665:6669, 6697)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Test port to see if we can use it
|
||||
tmp <- try(startServer(host, port, list()), silent=TRUE)
|
||||
if (!inherits(tmp, 'try-error')) {
|
||||
stopServer(tmp)
|
||||
.globals$lastPort <- port
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Invoke user-defined onStop callbacks, before the application's internal
|
||||
# onStop callbacks.
|
||||
on.exit({
|
||||
@@ -1022,7 +1061,7 @@ stopApp <- function(returnValue = invisible()) {
|
||||
#' }
|
||||
#' @export
|
||||
runExample <- function(example=NA,
|
||||
port=getOption('shiny.port', findPort(host = host)),
|
||||
port=NULL,
|
||||
launch.browser=getOption('shiny.launch.browser',
|
||||
interactive()),
|
||||
host=getOption('shiny.host', '127.0.0.1'),
|
||||
@@ -1086,7 +1125,7 @@ runExample <- function(example=NA,
|
||||
#' runGadget(shinyApp(ui, server))
|
||||
#' }
|
||||
#' @export
|
||||
runGadget <- function(app, server = NULL, port = getOption("shiny.port", findPort()),
|
||||
runGadget <- function(app, server = NULL, port = getOption("shiny.port"),
|
||||
viewer = paneViewer(), stopOnCancel = TRUE) {
|
||||
|
||||
if (!is.shiny.appobj(app)) {
|
||||
@@ -1181,41 +1220,6 @@ browserViewer <- function(browser = getOption("browser")) {
|
||||
}
|
||||
}
|
||||
|
||||
#' Find an open TCP port
|
||||
#'
|
||||
#' Finds a random available TCP port for listening on.
|
||||
#'
|
||||
#' @param min Minimum port number.
|
||||
#' @param max Maximum port number.
|
||||
#' @param host see [httpuv::randomPort()].
|
||||
#' @param n Number of ports to try before giving up.
|
||||
#' @param cache if `TRUE`, use the last random port if it's available.
|
||||
#'
|
||||
#' @details This function automatically excludes some ports
|
||||
#' which are considered unsafe by web browsers.
|
||||
#'
|
||||
#' @seealso [httpuv::randomPort()]
|
||||
#' @export
|
||||
#' @examples
|
||||
#'
|
||||
#' findPort()
|
||||
#' findPort()
|
||||
#' findPort(cache = FALSE)
|
||||
findPort <- function(min = 3000L, max = 8000L,
|
||||
host = getOption("shiny.host", "127.0.0.1"),
|
||||
n = 20, cache = TRUE) {
|
||||
if (cache && !is.null(.globals$lastPort)) {
|
||||
tmp <- try(startServer(host, .globals$lastPort, list()), silent = TRUE)
|
||||
if (!inherits(tmp, 'try-error')) {
|
||||
stopServer(tmp)
|
||||
return(.globals$lastPort)
|
||||
}
|
||||
}
|
||||
.globals$lastPort <- withPrivateSeed(httpuv::randomPort(min, max, host, n))
|
||||
.globals$lastPort
|
||||
}
|
||||
|
||||
|
||||
# Returns TRUE if we're running in Shiny Server or other hosting environment,
|
||||
# otherwise returns FALSE.
|
||||
inShinyServer <- function() {
|
||||
|
||||
@@ -204,8 +204,7 @@ sd_section("Utility functions",
|
||||
"onStop",
|
||||
"diskCache",
|
||||
"memoryCache",
|
||||
"reexports",
|
||||
"findPort"
|
||||
"reexports"
|
||||
)
|
||||
)
|
||||
sd_section("Plot interaction",
|
||||
|
||||
@@ -83,8 +83,6 @@
|
||||
el.id = "srcref_" + srcref;
|
||||
var ref = srcref;
|
||||
var code = document.getElementById(srcfile.replace(/\./g, "_") + "_code");
|
||||
// if there is no code file (might be a shiny file), quit early
|
||||
if (!code) return;
|
||||
var start = findTextPoint(code, ref[0], ref[4]);
|
||||
var end = findTextPoint(code, ref[2], ref[5]);
|
||||
|
||||
@@ -150,8 +148,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
// hide the new element before doing anything to it
|
||||
$(newHostElement).hide();
|
||||
$(currentHostElement).fadeOut(animateCodeMs, function() {
|
||||
var tabs = document.getElementById("showcase-code-tabs");
|
||||
currentHostElement.removeChild(tabs);
|
||||
@@ -164,7 +160,7 @@
|
||||
document.getElementById("showcase-code-content").removeAttribute("style");
|
||||
}
|
||||
|
||||
$(newHostElement).fadeIn(animateCodeMs);
|
||||
$(newHostElement).fadeIn();
|
||||
if (!above) {
|
||||
// remove the applied width and zoom on the app container, and
|
||||
// scroll smoothly down to the code's new home
|
||||
@@ -193,6 +189,7 @@
|
||||
if (above) {
|
||||
$(document.body).animate({ scrollTop: 0 }, animateCodeMs);
|
||||
}
|
||||
$(newHostElement).hide();
|
||||
isCodeAbove = above;
|
||||
setAppCodeSxsWidths(above && animate);
|
||||
$(window).trigger("resize");
|
||||
|
||||
@@ -4924,9 +4924,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
||||
}
|
||||
|
||||
date = this._newDate(date);
|
||||
// If date parsing fails, do nothing
|
||||
if (date === null) return;
|
||||
|
||||
date = this._UTCDateAsLocal(date);
|
||||
if (isNaN(date)) return;
|
||||
// Workaround for https://github.com/eternicode/bootstrap-datepicker/issues/2010
|
||||
@@ -4959,9 +4956,6 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
||||
}
|
||||
|
||||
date = this._newDate(date);
|
||||
// If date parsing fails, do nothing
|
||||
if (date === null) return;
|
||||
|
||||
date = this._UTCDateAsLocal(date);
|
||||
if (isNaN(date)) return;
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
inst/www/shared/shiny.min.js
vendored
2
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
@@ -1,36 +0,0 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/server.R
|
||||
\name{findPort}
|
||||
\alias{findPort}
|
||||
\title{Find an open TCP port}
|
||||
\usage{
|
||||
findPort(min = 3000L, max = 8000L, host = getOption("shiny.host",
|
||||
"127.0.0.1"), n = 20, cache = TRUE)
|
||||
}
|
||||
\arguments{
|
||||
\item{min}{Minimum port number.}
|
||||
|
||||
\item{max}{Maximum port number.}
|
||||
|
||||
\item{host}{see \code{\link[httpuv:randomPort]{httpuv::randomPort()}}.}
|
||||
|
||||
\item{n}{Number of ports to try before giving up.}
|
||||
|
||||
\item{cache}{if \code{TRUE}, use the last random port if it's available.}
|
||||
}
|
||||
\description{
|
||||
Finds a random available TCP port for listening on.
|
||||
}
|
||||
\details{
|
||||
This function automatically excludes some ports
|
||||
which are considered unsafe by web browsers.
|
||||
}
|
||||
\examples{
|
||||
|
||||
findPort()
|
||||
findPort()
|
||||
findPort(cache = FALSE)
|
||||
}
|
||||
\seealso{
|
||||
\code{\link[httpuv:randomPort]{httpuv::randomPort()}}
|
||||
}
|
||||
@@ -4,11 +4,11 @@
|
||||
\alias{runApp}
|
||||
\title{Run Shiny Application}
|
||||
\usage{
|
||||
runApp(appDir = getwd(), port = getOption("shiny.port", findPort(host =
|
||||
host)), launch.browser = getOption("shiny.launch.browser",
|
||||
interactive()), host = getOption("shiny.host", "127.0.0.1"),
|
||||
workerId = "", quiet = FALSE, display.mode = c("auto", "normal",
|
||||
"showcase"), test.mode = getOption("shiny.testmode", FALSE))
|
||||
runApp(appDir = getwd(), port = getOption("shiny.port"),
|
||||
launch.browser = getOption("shiny.launch.browser", interactive()),
|
||||
host = getOption("shiny.host", "127.0.0.1"), workerId = "",
|
||||
quiet = FALSE, display.mode = c("auto", "normal", "showcase"),
|
||||
test.mode = getOption("shiny.testmode", FALSE))
|
||||
}
|
||||
\arguments{
|
||||
\item{appDir}{The application to run. Should be one of the following:
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
\alias{runExample}
|
||||
\title{Run Shiny Example Applications}
|
||||
\usage{
|
||||
runExample(example = NA, port = getOption("shiny.port", findPort(host =
|
||||
host)), launch.browser = getOption("shiny.launch.browser",
|
||||
interactive()), host = getOption("shiny.host", "127.0.0.1"),
|
||||
display.mode = c("auto", "normal", "showcase"))
|
||||
runExample(example = NA, port = NULL,
|
||||
launch.browser = getOption("shiny.launch.browser", interactive()),
|
||||
host = getOption("shiny.host", "127.0.0.1"), display.mode = c("auto",
|
||||
"normal", "showcase"))
|
||||
}
|
||||
\arguments{
|
||||
\item{example}{The name of the example to run, or \code{NA} (the default) to
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
\alias{runGadget}
|
||||
\title{Run a gadget}
|
||||
\usage{
|
||||
runGadget(app, server = NULL, port = getOption("shiny.port",
|
||||
findPort()), viewer = paneViewer(), stopOnCancel = TRUE)
|
||||
runGadget(app, server = NULL, port = getOption("shiny.port"),
|
||||
viewer = paneViewer(), stopOnCancel = TRUE)
|
||||
}
|
||||
\arguments{
|
||||
\item{app}{Either a Shiny app object as created by
|
||||
|
||||
@@ -143,10 +143,6 @@ $.extend(dateInputBinding, {
|
||||
}
|
||||
|
||||
date = this._newDate(date);
|
||||
// If date parsing fails, do nothing
|
||||
if (date === null)
|
||||
return;
|
||||
|
||||
date = this._UTCDateAsLocal(date);
|
||||
if (isNaN(date))
|
||||
return;
|
||||
@@ -181,10 +177,6 @@ $.extend(dateInputBinding, {
|
||||
}
|
||||
|
||||
date = this._newDate(date);
|
||||
// If date parsing fails, do nothing
|
||||
if (date === null)
|
||||
return;
|
||||
|
||||
date = this._UTCDateAsLocal(date);
|
||||
if (isNaN(date))
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user