Compare commits

..

12 Commits

Author SHA1 Message Date
hadley
71d20d3561 Document (GitHub Actions) 2021-07-04 19:45:24 +00:00
Hadley Wickham
32ac62f2a3 Get imputed URL for current app/session 2021-07-04 14:41:30 -05:00
Winston Chang
d1e7e6c63a Add note about R version support 2021-07-02 14:04:35 -05:00
Winston Chang
29b574bf94 Merge pull request #3456 from heds1/update-rejected-ports 2021-07-01 16:34:25 -05:00
Barret Schloerke
7e4248bbca TypeScript: Globally declare Shiny variable, window.Shiny variable, and Shiny type (#3457) 2021-07-01 14:51:16 -04:00
heds1
fee267dc2e docs: update runapp port parameter docs, and add three more tcp ports to be blocked 2021-07-01 21:40:59 +12:00
Carson Sievert
9864130435 Use random inline styles to ensure transitionend fires everytime (#3452)
* Follow up to #3333: use random inline styles to ensure transitionend fires everytime

* yarn lint (GitHub Actions)

* Add missing '#'

* yarn lint (GitHub Actions)

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2021-06-30 15:26:49 -05:00
Carson Sievert
c9770cbd03 Close #3443: Fix sliderInput()'s grid tick positioning without Bootstrap (#3444) 2021-06-29 15:56:47 -05:00
Carson Sievert
ed6a40ba41 Close #3446: get removeModel() working with Bootstrap 4 (#3447) 2021-06-29 15:54:48 -05:00
Carson
3c22cdf90c roxygenize 2021-06-29 15:11:39 -05:00
Marcus Spittler
e55749b897 Update utils.R example to validate() (#2809)
Added an empty option to `choices` in `selectizeInput` in order to make the second `need` statement in `validate` meaningful. Otherwise the second `need` ("Please choose a state") is never displayed.
2021-06-29 15:10:42 -05:00
Carson Sievert
88cd87a5f7 Revert "Set selectize dropdownParent to "body" to prevent clipping" (#3450)
This reverts commit ce90d5cd0a.
2021-06-29 12:22:33 -05:00
117 changed files with 234 additions and 134 deletions

View File

@@ -1,3 +1,7 @@
Addresses #2521: Updated the list of TCP ports that will [be rejected](https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/net/base/port_util.cc)
by default in runapp.R, adding 5060, 5061 and 6566. Added documentation describing the port range (3000:8000)
and which ports are rejected.
shiny 1.6.0.9000
================

View File

@@ -208,15 +208,6 @@ selectizeIt <- function(inputId, select, options, nonempty = FALSE) {
options$plugins <- c(options$plugins, list('selectize-plugin-a11y'))
}
# to prevent clipping of the selectize drop-down we set the dropdownParent
# to "body". This might be necessary if e.g. overflow-x: scroll is set
# on it's container, which forces overflow-y to 'auto' (as per
# https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-y). Discussion
# of usage here: https://github.com/selectize/selectize.js/issues/192
if (is.null(options$dropdownParent)) {
options$dropdownParent <- "body"
}
res <- checkAsIs(options)
deps <- list(selectizeDependency())

View File

@@ -178,14 +178,15 @@ modalDialog <- function(..., title = NULL, footer = modalButton("Dismiss"),
if (!is.null(footer)) div(class = "modal-footer", footer)
)
),
tags$script(
"if (window.bootstrap) {
# jQuery plugin doesn't work in Bootstrap 5, but vanilla JS doesn't work in Bootstrap 4 :sob:
tags$script(HTML(
"if (window.bootstrap && !window.bootstrap.Modal.VERSION.match(/^4\\./)) {
var modal = new bootstrap.Modal(document.getElementById('shiny-modal'));
modal.show();
} else {
$('#shiny-modal').modal().focus();
}"
)
))
)
}

View File

@@ -22,7 +22,10 @@
#' @param port The TCP port that the application should listen on. If the
#' `port` is not specified, and the `shiny.port` option is set (with
#' `options(shiny.port = XX)`), then that port will be used. Otherwise,
#' use a random port.
#' use a random port between 3000:8000, excluding ports that are blocked
#' by Google Chrome for being considered unsafe: 3659, 4045, 5060,
#' 5061, 6000, 6566, 6665:6669 and 6697. Up to twenty random
#' ports will be tried.
#' @param launch.browser If true, the system's default web browser will be
#' launched automatically after the app is started. Defaults to true in
#' interactive sessions only. This value of this parameter can also be a
@@ -301,7 +304,8 @@ runApp <- function(appDir=getwd(),
# 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)) {
# https://chromium.googlesource.com/chromium/src.git/+/refs/heads/main/net/base/port_util.cc
if (!port %in% c(3659, 4045, 5060, 5061, 6000, 6566, 6665:6669, 6697)) {
break
}
}

View File

@@ -2126,6 +2126,51 @@ ShinySession <- R6Class(
}
})
}
},
getUrl = function() {
req <- self$request
url <-
# Connect
req[["HTTP_X_RSC_REQUEST"]] %||%
req[["HTTP_RSTUDIO_CONNECT_APP_BASE_URL"]] %||%
# ShinyApps.io
if (!is.null(req[["HTTP_X_REDX_FRONTEND_NAME"]])) {
paste0("https://", req[["HTTP_X_REDX_FRONTEND_NAME"]])
}
if (is.null(url)) {
forwarded_host <- req[["HTTP_X_FORWARDED_HOST"]]
forwarded_port <- req[["HTTP_X_FORWARDED_PORT"]]
host <- if (!is.null(forwarded_host) && !is.null(forwarded_port)) {
paste0(forwarded_host, ":", forwarded_port)
} else {
req[["HTTP_HOST"]] %||% paste0(req[["SERVER_NAME"]], ":", req[["SERVER_PORT"]])
}
proto <- req[["HTTP_X_FORWARDED_PROTO"]] %||% req[["rook.url_scheme"]]
if (tolower(proto) == "http") {
host <- sub(":80$", "", host)
} else if (tolower(proto) == "https") {
host <- sub(":443$", "", host)
}
url <- paste0(
proto,
"://",
host,
req[["SCRIPT_NAME"]],
req[["PATH_INFO"]]
)
}
# Strip existing querystring, if any
url <- sub("\\?.*", "", url)
url
}
)
)

View File

@@ -1159,7 +1159,7 @@ reactiveStop <- function(message = "", class = NULL) {
#'
#' ui <- fluidPage(
#' checkboxGroupInput('in1', 'Check some letters', choices = head(LETTERS)),
#' selectizeInput('in2', 'Select a state', choices = state.name),
#' selectizeInput('in2', 'Select a state', choices = c("", state.name)),
#' plotOutput('plot')
#' )
#'

View File

@@ -58,3 +58,7 @@ We welcome contributions to the **shiny** package. Please see our [CONTRIBUTING.
## License
The shiny package as a whole is licensed under the GPLv3. See the [LICENSE](LICENSE) file for more details.
## R version support
Shiny is supported on the latest release version of R, as well as the previous four minor release versions of R. For example, if the latest release R version is 4.1, then that version is supported, as well as 4.0, 3.6, 3.5, and 3.4.

View File

@@ -13,6 +13,13 @@
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* https://github.com/rstudio/shiny/issues/3443 */
/* https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */
box-sizing: border-box;
}
.irs *, .irs *:before, .irs *:after {
box-sizing: inherit;
}
.irs-line {

View File

@@ -4,6 +4,12 @@
@include pos-r();
-webkit-touch-callout: none;
@include no-click();
/* https://github.com/rstudio/shiny/issues/3443 */
/* https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */
box-sizing: border-box;
*, *:before, *:after {
box-sizing: inherit;
}
&-line {
@include pos-r();

View File

@@ -1,3 +1,3 @@
/*! shiny 1.6.0.9021 | (c) 2012-2021 RStudio, PBC. | License: GPL-3 | file LICENSE */
(function(){var t="ws:";window.location.protocol==="https:"&&(t="wss:");var o=window.location.pathname;/\/$/.test(o)||(o+="/");o+="autoreload/";var n=new WebSocket(t+"//"+window.location.host+o);n.onmessage=function(a){a.data==="autoreload"&&window.location.reload()};})();
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjdHMvZXh0cmFzL3NoaW55LWF1dG9yZWxvYWQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbInZhciBwcm90b2NvbCA9IFwid3M6XCI7XG5pZiAod2luZG93LmxvY2F0aW9uLnByb3RvY29sID09PSBcImh0dHBzOlwiKSBwcm90b2NvbCA9IFwid3NzOlwiO1xudmFyIGRlZmF1bHRQYXRoID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lO1xuaWYgKCEvXFwvJC8udGVzdChkZWZhdWx0UGF0aCkpIGRlZmF1bHRQYXRoICs9IFwiL1wiO1xuZGVmYXVsdFBhdGggKz0gXCJhdXRvcmVsb2FkL1wiO1xudmFyIHdzID0gbmV3IFdlYlNvY2tldChwcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0ICsgZGVmYXVsdFBhdGgpO1xuXG53cy5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgaWYgKGV2ZW50LmRhdGEgPT09IFwiYXV0b3JlbG9hZFwiKSB7XG4gICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xuICB9XG59O1xuXG5leHBvcnQge307Il0sCiAgIm1hcHBpbmdzIjogIjtZQUFBLEdBQUksR0FBVyxNQUNmLEFBQUksT0FBTyxTQUFTLFdBQWEsVUFBVSxHQUFXLFFBQ3RELEdBQUksR0FBYyxPQUFPLFNBQVMsU0FDbEMsQUFBSyxNQUFNLEtBQUssSUFBYyxJQUFlLEtBQzdDLEdBQWUsY0FDZixHQUFJLEdBQUssR0FBSSxXQUFVLEVBQVcsS0FBTyxPQUFPLFNBQVMsS0FBTyxHQUVoRSxFQUFHLFVBQVksU0FBVSxFQUFPLENBQzlCLEFBQUksRUFBTSxPQUFTLGNBQ2pCLE9BQU8sU0FBUyIsCiAgIm5hbWVzIjogW10KfQo=
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjdHMvZXh0cmFzL3NoaW55LWF1dG9yZWxvYWQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qIGVzbGludC1kaXNhYmxlIHVuaWNvcm4vZmlsZW5hbWUtY2FzZSAqL1xudmFyIHByb3RvY29sID0gXCJ3czpcIjtcbmlmICh3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgPT09IFwiaHR0cHM6XCIpIHByb3RvY29sID0gXCJ3c3M6XCI7XG52YXIgZGVmYXVsdFBhdGggPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWU7XG5pZiAoIS9cXC8kLy50ZXN0KGRlZmF1bHRQYXRoKSkgZGVmYXVsdFBhdGggKz0gXCIvXCI7XG5kZWZhdWx0UGF0aCArPSBcImF1dG9yZWxvYWQvXCI7XG52YXIgd3MgPSBuZXcgV2ViU29ja2V0KHByb3RvY29sICsgXCIvL1wiICsgd2luZG93LmxvY2F0aW9uLmhvc3QgKyBkZWZhdWx0UGF0aCk7XG5cbndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldmVudCkge1xuICBpZiAoZXZlbnQuZGF0YSA9PT0gXCJhdXRvcmVsb2FkXCIpIHtcbiAgICB3aW5kb3cubG9jYXRpb24ucmVsb2FkKCk7XG4gIH1cbn07XG5cbmV4cG9ydCB7fTsiXSwKICAibWFwcGluZ3MiOiAiO1lBQ0EsR0FBSSxHQUFXLE1BQ2YsQUFBSSxPQUFPLFNBQVMsV0FBYSxVQUFVLEdBQVcsUUFDdEQsR0FBSSxHQUFjLE9BQU8sU0FBUyxTQUNsQyxBQUFLLE1BQU0sS0FBSyxJQUFjLElBQWUsS0FDN0MsR0FBZSxjQUNmLEdBQUksR0FBSyxHQUFJLFdBQVUsRUFBVyxLQUFPLE9BQU8sU0FBUyxLQUFPLEdBRWhFLEVBQUcsVUFBWSxTQUFVLEVBQU8sQ0FDOUIsQUFBSSxFQUFNLE9BQVMsY0FDakIsT0FBTyxTQUFTIiwKICAibmFtZXMiOiBbXQp9Cg==

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
/*! shiny 1.6.0.9021 | (c) 2012-2021 RStudio, PBC. | License: GPL-3 | file LICENSE */
(function(){var a=eval;window.addEventListener("message",function(i){var e=i.data;e.code&&a(e.code)});})();
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjdHMvc3JjL3V0aWxzL2V2YWwudHMiLCAiLi4vLi4vLi4vc3JjdHMvZXh0cmFzL3NoaW55LXRlc3Rtb2RlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvL2VzYnVpbGQuZ2l0aHViLmlvL2NvbnRlbnQtdHlwZXMvI2RpcmVjdC1ldmFsXG4vL3RsL2RyO1xuLy8gKiBEaXJlY3QgdXNhZ2Ugb2YgYGV2YWwoXCJ4XCIpYCBpcyBiYWQgd2l0aCBidW5kbGVkIGNvZGUuXG4vLyAqIEluc3RlYWQsIHVzZSBpbmRpcmVjdCBjYWxscyB0byBgZXZhbGAgc3VjaCBhcyBgaW5kaXJlY3RFdmFsKFwieFwiKWBcbi8vICAgKiBFdmVuIGp1c3QgcmVuYW1pbmcgdGhlIGZ1bmN0aW9uIHdvcmtzIHdlbGwgZW5vdWdoLlxuLy8gPiBUaGlzIGlzIGtub3duIGFzIFwiaW5kaXJlY3QgZXZhbFwiIGJlY2F1c2UgZXZhbCBpcyBub3QgYmVpbmcgY2FsbGVkIGRpcmVjdGx5LCBhbmQgc28gZG9lcyBub3QgdHJpZ2dlciB0aGUgZ3JhbW1hdGljYWwgc3BlY2lhbCBjYXNlIGZvciBkaXJlY3QgZXZhbCBpbiB0aGUgSmF2YVNjcmlwdCBWTS4gWW91IGNhbiBjYWxsIGluZGlyZWN0IGV2YWwgdXNpbmcgYW55IHN5bnRheCBhdCBhbGwgZXhjZXB0IGZvciBhbiBleHByZXNzaW9uIG9mIHRoZSBleGFjdCBmb3JtIGV2YWwoJ3gnKS4gRm9yIGV4YW1wbGUsIHZhciBldmFsMiA9IGV2YWw7IGV2YWwyKCd4JykgYW5kIFtldmFsXVswXSgneCcpIGFuZCB3aW5kb3cuZXZhbCgneCcpIGFyZSBhbGwgaW5kaXJlY3QgZXZhbCBjYWxscy5cbi8vID4gV2hlbiB5b3UgdXNlIGluZGlyZWN0IGV2YWwsIHRoZSBjb2RlIGlzIGV2YWx1YXRlZCBpbiB0aGUgZ2xvYmFsIHNjb3BlIGluc3RlYWQgb2YgaW4gdGhlIGlubGluZSBzY29wZSBvZiB0aGUgY2FsbGVyLlxuXG4vKipcbiAqIEV2YWx1YXRlcyBKYXZhU2NyaXB0IGNvZGUgYW5kIGV4ZWN1dGVzIGl0IHZpYSBfSW5kaXJlY3QgRXZhbHVhdGlvbl9cbiAqIEBwYXJhbSB5IEEgU3RyaW5nIHZhbHVlIHRoYXQgY29udGFpbnMgdmFsaWQgSmF2YVNjcmlwdCBjb2RlLlxuICpcbiAqIEZyb20gW2VzYnVpbGRdKGVzYnVpbGQuZ2l0aHViLmlvL2NvbnRlbnQtdHlwZXMvI2RpcmVjdC1ldmFsKTogRGlyZWN0IHVzYWdlIG9mIGBldmFsKFwieFwiKWAgaXMgYmFkIHdpdGggYnVuZGxlZCBjb2RlLiBJbnN0ZWFkLCB1c2UgaW5kaXJlY3QgY2FsbHMgdG8gYGV2YWxgIHN1Y2ggYXMgYGluZGlyZWN0RXZhbChcInhcIilgLiBFdmVuIGp1c3QgcmVuYW1pbmcgdGhlIGZ1bmN0aW9uIHdvcmtzIHdlbGwgZW5vdWdoLlxuICpcbiAqID4gVGhpcyBpcyBrbm93biBhcyBcImluZGlyZWN0IGV2YWxcIiBiZWNhdXNlIGV2YWwgaXMgbm90IGJlaW5nIGNhbGxlZCBkaXJlY3RseSwgYW5kIHNvIGRvZXMgbm90IHRyaWdnZXIgdGhlIGdyYW1tYXRpY2FsIHNwZWNpYWwgY2FzZSBmb3IgZGlyZWN0IGV2YWwgaW4gdGhlIEphdmFTY3JpcHQgVk0uIFlvdSBjYW4gY2FsbCBpbmRpcmVjdCBldmFsIHVzaW5nIGFueSBzeW50YXggYXQgYWxsIGV4Y2VwdCBmb3IgYW4gZXhwcmVzc2lvbiBvZiB0aGUgZXhhY3QgZm9ybSBgZXZhbCgneCcpYC4gRm9yIGV4YW1wbGUsIGB2YXIgZXZhbDIgPSBldmFsOyBldmFsMigneCcpYCBhbmQgYFtldmFsXVswXSgneCcpYCBhbmQgd2luZG93LmBldmFsKCd4JylgIGFyZSBhbGwgaW5kaXJlY3QgZXZhbCBjYWxscy5cbiAqID4gV2hlbiB5b3UgdXNlIGluZGlyZWN0IGV2YWwsIHRoZSBjb2RlIGlzIGV2YWx1YXRlZCBpbiB0aGUgZ2xvYmFsIHNjb3BlIGluc3RlYWQgb2YgaW4gdGhlIGlubGluZSBzY29wZSBvZiB0aGUgY2FsbGVyLlxuICpcbiAqL1xudmFyIGluZGlyZWN0RXZhbCA9IGV2YWw7XG5leHBvcnQgeyBpbmRpcmVjdEV2YWwgfTsiLCAiaW1wb3J0IHsgaW5kaXJlY3RFdmFsIH0gZnJvbSBcIi4uL3NyYy91dGlscy9ldmFsXCI7IC8vIExpc3RlbiBmb3IgbWVzc2FnZXMgZnJvbSBwYXJlbnQgZnJhbWUuIFRoaXMgZmlsZSBpcyBvbmx5IGFkZGVkIHdoZW4gdGhlXG4vLyBzaGlueS50ZXN0bW9kZSBvcHRpb24gaXMgVFJVRS5cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIGZ1bmN0aW9uIChlKSB7XG4gIHZhciBtZXNzYWdlID0gZS5kYXRhO1xuICBpZiAobWVzc2FnZS5jb2RlKSBpbmRpcmVjdEV2YWwobWVzc2FnZS5jb2RlKTtcbn0pOyJdLAogICJtYXBwaW5ncyI6ICI7WUFrQkEsR0FBSSxHQUFlLEtDZm5CLE9BQU8saUJBQWlCLFVBQVcsU0FBVSxFQUFHLENBQzlDLEdBQUksR0FBVSxFQUFFLEtBQ2hCLEFBQUksRUFBUSxNQUFNLEVBQWEsRUFBUSIsCiAgIm5hbWVzIjogW10KfQo=
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjdHMvc3JjL3V0aWxzL2V2YWwudHMiLCAiLi4vLi4vLi4vc3JjdHMvZXh0cmFzL3NoaW55LXRlc3Rtb2RlLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvL2VzYnVpbGQuZ2l0aHViLmlvL2NvbnRlbnQtdHlwZXMvI2RpcmVjdC1ldmFsXG4vL3RsL2RyO1xuLy8gKiBEaXJlY3QgdXNhZ2Ugb2YgYGV2YWwoXCJ4XCIpYCBpcyBiYWQgd2l0aCBidW5kbGVkIGNvZGUuXG4vLyAqIEluc3RlYWQsIHVzZSBpbmRpcmVjdCBjYWxscyB0byBgZXZhbGAgc3VjaCBhcyBgaW5kaXJlY3RFdmFsKFwieFwiKWBcbi8vICAgKiBFdmVuIGp1c3QgcmVuYW1pbmcgdGhlIGZ1bmN0aW9uIHdvcmtzIHdlbGwgZW5vdWdoLlxuLy8gPiBUaGlzIGlzIGtub3duIGFzIFwiaW5kaXJlY3QgZXZhbFwiIGJlY2F1c2UgZXZhbCBpcyBub3QgYmVpbmcgY2FsbGVkIGRpcmVjdGx5LCBhbmQgc28gZG9lcyBub3QgdHJpZ2dlciB0aGUgZ3JhbW1hdGljYWwgc3BlY2lhbCBjYXNlIGZvciBkaXJlY3QgZXZhbCBpbiB0aGUgSmF2YVNjcmlwdCBWTS4gWW91IGNhbiBjYWxsIGluZGlyZWN0IGV2YWwgdXNpbmcgYW55IHN5bnRheCBhdCBhbGwgZXhjZXB0IGZvciBhbiBleHByZXNzaW9uIG9mIHRoZSBleGFjdCBmb3JtIGV2YWwoJ3gnKS4gRm9yIGV4YW1wbGUsIHZhciBldmFsMiA9IGV2YWw7IGV2YWwyKCd4JykgYW5kIFtldmFsXVswXSgneCcpIGFuZCB3aW5kb3cuZXZhbCgneCcpIGFyZSBhbGwgaW5kaXJlY3QgZXZhbCBjYWxscy5cbi8vID4gV2hlbiB5b3UgdXNlIGluZGlyZWN0IGV2YWwsIHRoZSBjb2RlIGlzIGV2YWx1YXRlZCBpbiB0aGUgZ2xvYmFsIHNjb3BlIGluc3RlYWQgb2YgaW4gdGhlIGlubGluZSBzY29wZSBvZiB0aGUgY2FsbGVyLlxudmFyIGluZGlyZWN0RXZhbCA9IGV2YWw7XG5leHBvcnQgeyBpbmRpcmVjdEV2YWwgfTsiLCAiLyogZXNsaW50LWRpc2FibGUgdW5pY29ybi9maWxlbmFtZS1jYXNlICovXG5pbXBvcnQgeyBpbmRpcmVjdEV2YWwgfSBmcm9tIFwiLi4vc3JjL3V0aWxzL2V2YWxcIjsgLy8gTGlzdGVuIGZvciBtZXNzYWdlcyBmcm9tIHBhcmVudCBmcmFtZS4gVGhpcyBmaWxlIGlzIG9ubHkgYWRkZWQgd2hlbiB0aGVcbi8vIHNoaW55LnRlc3Rtb2RlIG9wdGlvbiBpcyBUUlVFLlxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgZnVuY3Rpb24gKGUpIHtcbiAgdmFyIG1lc3NhZ2UgPSBlLmRhdGE7XG4gIGlmIChtZXNzYWdlLmNvZGUpIGluZGlyZWN0RXZhbChtZXNzYWdlLmNvZGUpO1xufSk7Il0sCiAgIm1hcHBpbmdzIjogIjtZQU9BLEdBQUksR0FBZSxLQ0huQixPQUFPLGlCQUFpQixVQUFXLFNBQVUsRUFBRyxDQUM5QyxHQUFJLEdBQVUsRUFBRSxLQUNoQixBQUFJLEVBQVEsTUFBTSxFQUFhLEVBQVEiLAogICJuYW1lcyI6IFtdCn0K

View File

@@ -9181,22 +9181,17 @@
} else {
link.attr("href", href2);
link.attr("onload", function() {
var dummyId = "dummy-" + Math.floor(Math.random() * 999999999);
var cssString = "#" + dummyId + " { color: #a7c920 !important; transition: 0.1s all !important; visibility: hidden !important; position: absolute !important; top: -1000px !important; left: 0 !important; }";
var base64CssString = "data:text/css;base64," + btoa(cssString);
var $dummyLink = (0, import_jquery27.default)("<link rel='stylesheet' type='text/css' />");
$dummyLink.attr("href", base64CssString);
var $dummyEl = (0, import_jquery27.default)("<div id='" + dummyId + "'></div>");
var $dummyEl = (0, import_jquery27.default)("<div>").css("transition", "0.1s all").css("position", "absolute").css("top", "-1000px").css("left", "0");
$dummyEl.one("transitionend", function() {
$dummyEl.remove();
removeSheet(findSheet($dummyLink.attr("href")));
removeSheet(oldSheet);
sendImageSizeFns.transitioned();
});
(0, import_jquery27.default)(document.body).append($dummyEl);
var color = "#" + Math.floor(Math.random() * 16777215).toString(16);
setTimeout(function() {
return $head.append($dummyLink);
}, 0);
return $dummyEl.css("color", color);
}, 10);
});
$head.append(link);
}
@@ -12286,8 +12281,8 @@
data: _this.$initialInput
}));
while (_this.$pendingMessages.length) {
var _msg = _this.$pendingMessages.shift();
socket.send(_msg);
var msg = _this.$pendingMessages.shift();
socket.send(msg);
}
};
socket.onmessage = function(e) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -30,7 +30,10 @@ expression that produces a Shiny app object.
\item{port}{The TCP port that the application should listen on. If the
\code{port} is not specified, and the \code{shiny.port} option is set (with
\code{options(shiny.port = XX)}), then that port will be used. Otherwise,
use a random port.}
use a random port between 3000:8000, excluding ports that are blocked
by Google Chrome for being considered unsafe: 3659, 4045, 5060,
5061, 6000, 6566, 6665:6669 and 6697. Up to twenty random
ports will be tried.}
\item{launch.browser}{If true, the system's default web browser will be
launched automatically after the app is started. Defaults to true in

View File

@@ -19,7 +19,10 @@ list the available examples.}
\item{port}{The TCP port that the application should listen on. If the
\code{port} is not specified, and the \code{shiny.port} option is set (with
\code{options(shiny.port = XX)}), then that port will be used. Otherwise,
use a random port.}
use a random port between 3000:8000, excluding ports that are blocked
by Google Chrome for being considered unsafe: 3659, 4045, 5060,
5061, 6000, 6566, 6665:6669 and 6697. Up to twenty random
ports will be tried.}
\item{launch.browser}{If true, the system's default web browser will be
launched automatically after the app is started. Defaults to true in

View File

@@ -68,7 +68,7 @@ options(device.ask.default = FALSE)
ui <- fluidPage(
checkboxGroupInput('in1', 'Check some letters', choices = head(LETTERS)),
selectizeInput('in2', 'Select a state', choices = state.name),
selectizeInput('in2', 'Select a state', choices = c("", state.name)),
plotOutput('plot')
)

View File

@@ -2,13 +2,16 @@
"private": true,
"homepage": "https://shiny.rstudio.com",
"repository": "github:rstudio/shiny",
"name": "@types/shiny",
"name": "@types/rstudio-shiny",
"version": "1.6.0-alpha.9021",
"license": "GPL-3.0-only",
"main": "",
"browser": "",
"types": "srcts/types/shiny/index.d.ts",
"types": "srcts/types/extras/globalShiny.d.ts",
"files": [
"DESCRIPTION",
"LICENSE",
"NEWS.md",
"srcts/types/**/*.d.ts"
],
"engines": {
@@ -20,7 +23,7 @@
"@types/bootstrap-datepicker": "0.0.14",
"@types/datatables.net": "^1.10.19",
"@types/ion-rangeslider": "2.3.0",
"@types/jquery": "^3.5.5",
"@types/jquery": "patch:@types/jquery@3.5.5#./srcts/patch/types-jquery.patch",
"@types/selectize": "0.12.34"
},
"devDependencies": {
@@ -75,6 +78,7 @@
"util-inspect": "https://github.com/deecewan/browser-util-inspect#c0b4350df4378ffd743e8c36dd3898ce3992823e"
},
"scripts": {
"prepare": "node --eval \"1+1; // help yarn users not install the whole repo; https://github.com/yarnpkg/yarn/issues/2822#issuecomment-847360267\"",
"watch": "yarn run build_shiny --watch",
"build": "yarn run build_shiny && yarn run bundle_extras && yarn run bundle_external_libs",
"build_shiny": "yarn run checks && yarn run bundle_shiny",

View File

@@ -173,6 +173,25 @@ yarn watch
Both JavaScript files will produce a sourcemap (`**.js.map`) that the browser will understand. This will help you debug Shiny's JavaScript code within the browser and point back to the original TypeScript files.
### Exported types
`./extras/globalShiny.ts` contains global declarations to define `window.Shiny`, a globally available `Shiny` variable, and a globally available `Shiny` type. This file is in a parallel folder to `./src` to avoid `Shiny` from being globally accessable within the source code. However, this file is the default type defintion when the Type definitions are installed by external developers.
#### External development
When developing TypeScript projects that leverage Shiny, we recommend installing the Shiny TypeScript definitions to your package. To install the definitions, call
```bash
yarn add https://github.com/rstudio/shiny\#v1.7.0
```
, matching the GitHub tag to your current the Shiny CRAN release (ex: `v1.7.0`). If you are asked to select a version of `@types/jquery`, please select the closest version.
This will provide a global type defintion of `Shiny`, let your IDE know that `window.Shiny` is of type `Shiny`, and declare a globally available variable `Shiny` within your project. You **should not** need to import anything. Similar to `jQuery`, it should _Just Work_<sup>TM</sup>.
When loading your compiled file, it should be loaded after Shiny is loaded. If you are using an `htmlDependency()` to add your code to the page, your script will automatically be loaded after has been loaded.
### GitHub Actions
On push to the `master` branch or push to a Pull Request to the `master` branch, a GitHub Action will be run to make sure the bundled JavaScript code is up to date. If the source code does not compile to the exact same file, it will be committed an pushed back to the outdated branch. (This makes it so the full build tools are not necessary for small tweaks and comments. 🎉)

View File

@@ -92,16 +92,11 @@
* √ Completely remove `parcel` from `./package.json` and only use `esbuild`
* √ Delete 'shiny-es5' files
* Delete 'old' folder
* Maybe not. Might be good to keep for a cycle.
* _Uglify_ js files (like in previous Gruntfile.js)
* datepicker
* ionrangeslider
* selectize
* Documentation
* Check out
* https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#this
* https://github.com/gajus/eslint-plugin-jsdoc
* Looks like it can handle markdown
# Eventual TODO

View File

@@ -0,0 +1,20 @@
// Type definitions for @types-rstudio/shiny
// Project: Shiny <https://shiny.rstudio.com/>
// Definitions by: RStudio <https://www.rstudio.com/>
import type { Shiny as RStudioShiny } from "../src/shiny/index";
declare global {
// Tell Shiny variable globally exists
// eslint-disable-next-line @typescript-eslint/naming-convention
const Shiny: RStudioShiny;
// Tell window.Shiny exists
interface Window {
// eslint-disable-next-line @typescript-eslint/naming-convention
Shiny: RStudioShiny;
}
// Make `Shiny` a globally available type definition. (No need to import the type)
type Shiny = RStudioShiny;
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable unicorn/filename-case */
let protocol = "ws:";
if (window.location.protocol === "https:") protocol = "wss:";

View File

@@ -1,7 +1,8 @@
import type { Shiny } from "../src/shiny";
/* eslint-disable unicorn/filename-case */
import "./globalShiny";
type ShowcaseSrcMessage = {
srcref: Array<number>;
srcref: number[];
srcfile: string;
};
@@ -135,8 +136,8 @@ function highlightSrcref(
// If this is the main Shiny window, wire up our custom message handler.
// TODO-barret, this should work
if ((window as any).Shiny) {
((window as any).Shiny as Shiny).addCustomMessageHandler(
if (Shiny) {
Shiny.addCustomMessageHandler(
"showcase-src",
function (message: ShowcaseSrcMessage) {
if (message.srcref && message.srcfile) {

View File

@@ -1,3 +1,4 @@
/* eslint-disable unicorn/filename-case */
import { indirectEval } from "../src/utils/eval";
// Listen for messages from parent frame. This file is only added when the

View File

@@ -525,11 +525,17 @@ function initDeferredIframes(): void {
// TODO-barret; This method uses `window.Shiny`. Could be replaced with `fullShinyObj_.shinyapp?.isConnected()`,
// but that would not use `window.Shiny`. Is it a problem???
if (
// @ts-expect-error; Do not want to define `window.Shiny` as a type to discourage usage of `window.Shiny`
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore; Do not want to define `window.Shiny` as a type to discourage usage of `window.Shiny`;
// Can not expect error when combining with window available Shiny definition
!window.Shiny ||
// @ts-expect-error; Do not want to define `window.Shiny` as a type to discourage usage of `window.Shiny`
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore; Do not want to define `window.Shiny` as a type to discourage usage of `window.Shiny`;
// Can not expect error when combining with window available Shiny definition
!window.Shiny.shinyapp ||
// @ts-expect-error; Do not want to define `window.Shiny` as a type to discourage usage of `window.Shiny`
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore; Do not want to define `window.Shiny` as a type to discourage usage of `window.Shiny`;
// Can not expect error when combining with window available Shiny definition
!window.Shiny.shinyapp.isConnected()
) {
// If somehow we accidentally call this before the server connection is

View File

@@ -233,37 +233,26 @@ function renderDependency(dep: HtmlDep) {
// the same plot being redrawn multiple times with different
// styling.
link.attr("onload", () => {
const dummyId = "dummy-" + Math.floor(Math.random() * 999999999);
const cssString =
"#" +
dummyId +
" { " +
"color: #a7c920 !important; " + // An arbitrary color for the transition
"transition: 0.1s all !important; " +
"visibility: hidden !important; " +
"position: absolute !important; " +
"top: -1000px !important; " +
"left: 0 !important; }";
const base64CssString = "data:text/css;base64," + btoa(cssString);
const $dummyLink = $("<link rel='stylesheet' type='text/css' />");
$dummyLink.attr("href", base64CssString);
const $dummyEl = $("<div id='" + dummyId + "'></div>");
const $dummyEl = $("<div>")
.css("transition", "0.1s all")
.css("position", "absolute")
.css("top", "-1000px")
.css("left", "0");
$dummyEl.one("transitionend", () => {
$dummyEl.remove();
removeSheet(findSheet($dummyLink.attr("href")));
removeSheet(oldSheet);
sendImageSizeFns.transitioned();
});
$(document.body).append($dummyEl);
// Need to add the CSS with a setTimeout 0, to ensure that it
// takes effect _after_ the DOM element has been added. This is
// necessary to ensure that the transition actually occurs.
setTimeout(() => $head.append($dummyLink), 0);
// To ensure a transition actually happens, change the inline style _after_
// the DOM element has been added, and also use a new random color each time
// to prevent any potential caching done by the browser
const color =
"#" + Math.floor(Math.random() * 16777215).toString(16);
setTimeout(() => $dummyEl.css("color", color), 10);
});
$head.append(link);

View File

@@ -33,9 +33,7 @@ import type { WherePosition } from "./singletons";
import type { UploadInitValue, UploadEndValue } from "../file/fileProcessor";
type ResponseValue = UploadEndValue | UploadInitValue;
type Handler = (
msg: unknown[] | boolean | string | { [key: string]: unknown }
) => void;
type Handler = (message: any) => void;
type ShinyWebSocket = WebSocket & {
allowReconnect?: boolean;

View File

@@ -6,16 +6,6 @@
// > This is known as "indirect eval" because eval is not being called directly, and so does not trigger the grammatical special case for direct eval in the JavaScript VM. You can call indirect eval using any syntax at all except for an expression of the exact form eval('x'). For example, var eval2 = eval; eval2('x') and [eval][0]('x') and window.eval('x') are all indirect eval calls.
// > When you use indirect eval, the code is evaluated in the global scope instead of in the inline scope of the caller.
/**
* Evaluates JavaScript code and executes it via _Indirect Evaluation_
* @param y A String value that contains valid JavaScript code.
*
* From [esbuild](esbuild.github.io/content-types/#direct-eval): Direct usage of `eval("x")` is bad with bundled code. Instead, use indirect calls to `eval` such as `indirectEval("x")`. Even just renaming the function works well enough.
*
* > This is known as "indirect eval" because eval is not being called directly, and so does not trigger the grammatical special case for direct eval in the JavaScript VM. You can call indirect eval using any syntax at all except for an expression of the exact form `eval('x')`. For example, `var eval2 = eval; eval2('x')` and `[eval][0]('x')` and window.`eval('x')` are all indirect eval calls.
* > When you use indirect eval, the code is evaluated in the global scope instead of in the inline scope of the caller.
*
*/
const indirectEval = eval;
export { indirectEval };

View File

@@ -1,9 +1,3 @@
/**
* Wrapper around `Object.prototype.hasOwnProperty.call(x,y)`
* @param x Object to inspect
* @param y Key to inspect in `x`
* @returns Whether object `x` actually has property `y`.
* */
function hasOwnProperty(x: { [key: string]: unknown }, y: string): boolean {
return Object.prototype.hasOwnProperty.call(x, y);
}

8
srcts/types/extras/globalShiny.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
import type { Shiny as RStudioShiny } from "../src/shiny/index";
declare global {
const Shiny: RStudioShiny;
interface Window {
Shiny: RStudioShiny;
}
type Shiny = RStudioShiny;
}

View File

@@ -1,9 +1,7 @@
import type { OutputBindingAdapter } from "../bindings/outputAdapter";
import type { UploadInitValue, UploadEndValue } from "../file/fileProcessor";
declare type ResponseValue = UploadEndValue | UploadInitValue;
declare type Handler = (msg: unknown[] | boolean | string | {
[key: string]: unknown;
}) => void;
declare type Handler = (message: any) => void;
declare type ShinyWebSocket = WebSocket & {
allowReconnect?: boolean;
};

Some files were not shown because too many files have changed in this diff Show More