Compare commits

..

3 Commits

Author SHA1 Message Date
Carson
5d563a00eb Port most everything to bslib 2025-04-25 10:19:04 -05:00
Carson
d4bf6aaab9 Restrict type='submit' behavior specifically to submitButton() 2025-04-25 10:06:12 -05:00
Carson
49c5d29003 First pass at adding textSubmitInput() 2025-04-25 10:06:12 -05:00
98 changed files with 3568 additions and 3322 deletions

View File

@@ -1,132 +1,121 @@
Type: Package
Package: shiny
Type: Package
Title: Web Application Framework for R
Version: 1.11.1.9000
Version: 1.10.0.9001
Authors@R: c(
person("Winston", "Chang", , "winston@posit.co", role = "aut",
comment = c(ORCID = "0000-0002-1576-2126")),
person("Joe", "Cheng", , "joe@posit.co", role = "aut"),
person("JJ", "Allaire", , "jj@posit.co", role = "aut"),
person("Carson", "Sievert", , "carson@posit.co", role = c("aut", "cre"),
comment = c(ORCID = "0000-0002-4958-2844")),
person("Barret", "Schloerke", , "barret@posit.co", role = "aut",
comment = c(ORCID = "0000-0001-9986-114X")),
person("Garrick", "Aden-Buie", , "garrick@adenbuie.com", role = "aut",
comment = c(ORCID = "0000-0002-7111-0077")),
person("Yihui", "Xie", , "yihui@posit.co", role = "aut"),
person("Winston", "Chang", role = c("aut", "cre"), email = "winston@posit.co", comment = c(ORCID = "0000-0002-1576-2126")),
person("Joe", "Cheng", role = "aut", email = "joe@posit.co"),
person("JJ", "Allaire", role = "aut", email = "jj@posit.co"),
person("Carson", "Sievert", role = "aut", email = "carson@posit.co", comment = c(ORCID = "0000-0002-4958-2844")),
person("Barret", "Schloerke", role = "aut", email = "barret@posit.co", comment = c(ORCID = "0000-0001-9986-114X")),
person("Yihui", "Xie", role = "aut", email = "yihui@posit.co"),
person("Jeff", "Allen", role = "aut"),
person("Jonathan", "McPherson", , "jonathan@posit.co", role = "aut"),
person("Jonathan", "McPherson", role = "aut", email = "jonathan@posit.co"),
person("Alan", "Dipert", role = "aut"),
person("Barbara", "Borges", role = "aut"),
person("Posit Software, PBC", role = c("cph", "fnd"),
comment = c(ROR = "03wc8by49")),
person(, "jQuery Foundation", role = "cph",
comment = "jQuery library and jQuery UI library"),
person(, "jQuery contributors", role = c("ctb", "cph"),
comment = "jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt"),
person(, "jQuery UI contributors", role = c("ctb", "cph"),
comment = "jQuery UI library; authors listed in inst/www/shared/jqueryui/AUTHORS.txt"),
person("Posit Software, PBC", role = c("cph", "fnd")),
person(family = "jQuery Foundation", role = "cph",
comment = "jQuery library and jQuery UI library"),
person(family = "jQuery contributors", role = c("ctb", "cph"),
comment = "jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt"),
person(family = "jQuery UI contributors", role = c("ctb", "cph"),
comment = "jQuery UI library; authors listed in inst/www/shared/jqueryui/AUTHORS.txt"),
person("Mark", "Otto", role = "ctb",
comment = "Bootstrap library"),
comment = "Bootstrap library"),
person("Jacob", "Thornton", role = "ctb",
comment = "Bootstrap library"),
person(, "Bootstrap contributors", role = "ctb",
comment = "Bootstrap library"),
person(, "Twitter, Inc", role = "cph",
comment = "Bootstrap library"),
comment = "Bootstrap library"),
person(family = "Bootstrap contributors", role = "ctb",
comment = "Bootstrap library"),
person(family = "Twitter, Inc", role = "cph",
comment = "Bootstrap library"),
person("Prem Nawaz", "Khan", role = "ctb",
comment = "Bootstrap accessibility plugin"),
comment = "Bootstrap accessibility plugin"),
person("Victor", "Tsaran", role = "ctb",
comment = "Bootstrap accessibility plugin"),
comment = "Bootstrap accessibility plugin"),
person("Dennis", "Lembree", role = "ctb",
comment = "Bootstrap accessibility plugin"),
comment = "Bootstrap accessibility plugin"),
person("Srinivasu", "Chakravarthula", role = "ctb",
comment = "Bootstrap accessibility plugin"),
comment = "Bootstrap accessibility plugin"),
person("Cathy", "O'Connor", role = "ctb",
comment = "Bootstrap accessibility plugin"),
person(, "PayPal, Inc", role = "cph",
comment = "Bootstrap accessibility plugin"),
comment = "Bootstrap accessibility plugin"),
person(family = "PayPal, Inc", role = "cph",
comment = "Bootstrap accessibility plugin"),
person("Stefan", "Petre", role = c("ctb", "cph"),
comment = "Bootstrap-datepicker library"),
comment = "Bootstrap-datepicker library"),
person("Andrew", "Rowls", role = c("ctb", "cph"),
comment = "Bootstrap-datepicker library"),
comment = "Bootstrap-datepicker library"),
person("Brian", "Reavis", role = c("ctb", "cph"),
comment = "selectize.js library"),
comment = "selectize.js library"),
person("Salmen", "Bejaoui", role = c("ctb", "cph"),
comment = "selectize-plugin-a11y library"),
comment = "selectize-plugin-a11y library"),
person("Denis", "Ineshin", role = c("ctb", "cph"),
comment = "ion.rangeSlider library"),
comment = "ion.rangeSlider library"),
person("Sami", "Samhuri", role = c("ctb", "cph"),
comment = "Javascript strftime library"),
person(, "SpryMedia Limited", role = c("ctb", "cph"),
comment = "DataTables library"),
comment = "Javascript strftime library"),
person(family = "SpryMedia Limited", role = c("ctb", "cph"),
comment = "DataTables library"),
person("John", "Fraser", role = c("ctb", "cph"),
comment = "showdown.js library"),
comment = "showdown.js library"),
person("John", "Gruber", role = c("ctb", "cph"),
comment = "showdown.js library"),
comment = "showdown.js library"),
person("Ivan", "Sagalaev", role = c("ctb", "cph"),
comment = "highlight.js library"),
person("R Core Team", role = c("ctb", "cph"),
comment = "tar implementation from R")
)
comment = "highlight.js library"),
person(family = "R Core Team", role = c("ctb", "cph"),
comment = "tar implementation from R")
)
Description: Makes it incredibly easy to build interactive web
applications with R. Automatic "reactive" binding between inputs and
outputs and extensive prebuilt widgets make it possible to build
beautiful, responsive, and powerful applications with minimal effort.
License: GPL-3 | file LICENSE
URL: https://shiny.posit.co/, https://github.com/rstudio/shiny
BugReports: https://github.com/rstudio/shiny/issues
Depends:
methods,
R (>= 3.0.2)
R (>= 3.0.2),
methods
Imports:
utils,
grDevices,
httpuv (>= 1.5.2),
mime (>= 0.3),
jsonlite (>= 0.9.16),
xtable,
fontawesome (>= 0.4.0),
htmltools (>= 0.5.4),
R6 (>= 2.0),
sourcetools,
later (>= 1.0.0),
promises (>= 1.3.2),
tools,
cli,
rlang (>= 0.4.10),
fastmap (>= 1.1.1),
withr,
commonmark (>= 1.7),
glue (>= 1.3.2),
bslib (>= 0.6.0),
cachem (>= 1.1.0),
cli,
commonmark (>= 1.7),
fastmap (>= 1.1.1),
fontawesome (>= 0.4.0),
glue (>= 1.3.2),
grDevices,
htmltools (>= 0.5.4),
httpuv (>= 1.5.2),
jsonlite (>= 0.9.16),
later (>= 1.0.0),
lifecycle (>= 0.2.0),
mime (>= 0.3),
promises (>= 1.3.2),
R6 (>= 2.0),
rlang (>= 0.4.10),
sourcetools,
tools,
utils,
withr,
xtable
lifecycle (>= 0.2.0)
Suggests:
Cairo (>= 1.5-5),
coro (>= 1.1.0),
datasets,
DT,
dygraphs,
future,
ggplot2,
knitr (>= 1.6),
magrittr,
markdown,
mirai,
ragg,
reactlog (>= 1.0.0),
rmarkdown,
sass,
showtext,
Cairo (>= 1.5-5),
testthat (>= 3.2.1),
watcher,
yaml
Config/Needs/check: shinytest2
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
knitr (>= 1.6),
markdown,
rmarkdown,
ggplot2,
reactlog (>= 1.0.0),
magrittr,
yaml,
future,
dygraphs,
ragg,
showtext,
sass,
watcher
URL: https://shiny.posit.co/,
https://github.com/rstudio/shiny
BugReports: https://github.com/rstudio/shiny/issues
Collate:
'globals.R'
'app-state.R'
@@ -212,7 +201,6 @@ Collate:
'test.R'
'update-input.R'
'utils-lang.R'
'utils-tags.R'
'version_bs_date_picker.R'
'version_ion_range_slider.R'
'version_jquery.R'
@@ -220,3 +208,9 @@ Collate:
'version_selectize.R'
'version_strftime.R'
'viewer.R'
RoxygenNote: 7.3.2
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
Config/testthat/edition: 3
Config/Needs/check:
shinytest2

61
NEWS.md
View File

@@ -2,27 +2,15 @@
## New features
* The `icon` argument of `updateActionButton()`/`updateActionLink()` nows allows values other than `shiny::icon()` (e.g., `fontawesome::fa()`, `bsicons::bs_icon()`, etc). (#4249)
* `textInput()`, `textAreaInput()`, `numericInput()` and `passwordInput()` all gain an `updateOn` option. `updateOn = "change"` is the default and previous behavior, where the input value updates immediately whenever the value changes. With `updateOn = "blur"`, the input value will update only when the text input loses focus or when the user presses Enter (or Cmd/Ctrl + Enter for `textAreaInput()`). (#4183)
## Bug fixes
* `textAreaInput()` gains a `autoresize` option, which automatically resizes the text area to fit its content.
* `updateActionButton()`/`updateActionLink()` now correctly renders HTML content passed to the `label` argument. (#4249)
* The `callback` argument of Shiny.js' `InputBinding.subscribe()` method gains support for a value of `"event"`. This makes it possible for an input binding to use event priority when updating the value (i.e., send immediately and always resend, even if the value hasn't changed).
## Changes
* The return value of `actionButton()`/`actionLink()` changed slightly: `label` and `icon` are wrapped in an additional HTML container element. This allows for: 1. `updateActionButton()`/`updateActionLink()` to distinguish between the `label` and `icon` when making updates and 2. spacing between `label` and `icon` to be more easily customized via CSS.
# shiny 1.11.1
This is a patch release primarily for addressing the bugs introduced in v1.11.0.
## Bug fixes
* Fixed an issue where `InputBinding` implementations that don't pass a value to their `subscribe` callback were no longer notifying Shiny of input changes. (#4243)
* `updateActionButton()` and `updateActionLink()` once again handle `label` updates correctly. (#4245)
# shiny 1.11.0
* Shiny no longer suspends input changes when _any_ `<input type="submit">` or `<button type="submit">` is on the page. Instead, it now only suspends when a `submitButton()` is present. If you have reason for creating a submit button from custom HTML, add a CSS class of `shiny-submit-button` to the button.
## Improvements
@@ -33,45 +21,17 @@ This is a patch release primarily for addressing the bugs introduced in v1.11.0.
* Shows a spinner on `tableOutput()`. (#4172)
* Places a minimum height on recalculating outputs so that the spinner is always visible. (#4172)
* Shiny now uses `{cli}` instead of `{crayon}` for rich log messages. (thanks @olivroy, #4170)
* Shiny now uses `{cli}` instead of `{crayon}` for rich log messages. (@olivroy #4170)
* `renderPlot()` was updated to accommodate changes in ggplot2 v4.0.0. (#4226)
* When adding the new tab via `insertTab()` or `bslib::nav_insert()`, the underlying JavaScript no longer renders content twice. (#4179)
## New features
* `textInput()`, `textAreaInput()`, `numericInput()` and `passwordInput()` all gain an `updateOn` option. `updateOn = "change"` is the default and previous behavior, where the input value updates immediately whenever the value changes. With `updateOn = "blur"`, the input value will update only when the text input loses focus or when the user presses Enter (or Cmd/Ctrl + Enter for `textAreaInput()`). (#4183)
* `textAreaInput()` gains a `autoresize` option, which automatically resizes the text area to fit its content. (#4210)
* The family of `update*Input()` functions can now render HTML content passed to the `label` argument (e.g., `updateInputText(label = tags$b("New label"))`). (#3996)
* `ExtendedTask` now catches synchronous values and errors and returns them via `$result()`. Previously, the extended task function was required to always return a promise. This change makes it easier to use `ExtendedTask` with a function that may return early or do some synchronous work before returning a promise. (#4225)
* The `callback` argument of Shiny.js' `InputBinding.subscribe()` method gains support for a value of `"event"`. This makes it possible for an input binding to use event priority when updating the value (i.e., send immediately and always resend, even if the value hasn't changed). (#4211)
## Changes
* Shiny no longer suspends input changes when _any_ `<input type="submit">` or `<button type="submit">` is on the page. Instead, it now only suspends when a `submitButton()` is present. If you have reason for creating a submit button from custom HTML, add a CSS class of `shiny-submit-button` to the button. (#4209)
* Shiny's JavaScript assets are now compiled to ES2021 instead of ES5. (#4066)
* Upgraded jQuery from 3.6.0 to 3.7.1. (#3969)
* Updated jQuery UI from 1.13.2 to 1.14.1. (#4175)
* Shiny's Typescript assets are now compiled to ES2021 instead of ES5. (#4066)
## Bug fixes
* Fixed a bug with modals where calling `removeModal()` too quickly after `showModal()` would fail to remove the modal if the remove modal message was received while the modal was in the process of being revealed. (#4173)
* The Shiny Client Console (enabled with `shiny::devmode()`) no longer displays duplicate warning or error message. (#4177)
* Synchronous errors that occur inside a `ExtendedTask` no longer stop the session. (#4225)
* Calling `removeModal()` immediately after `showModal()` no longer fails to remove the modal (this would sometimes happen if the remove message was received while the modal was in the process of being revealed). (#4173)
* `runExample("08_html")` now (correctly) requests to 'shiny.min.css', eliminating a network request failure. (#4220)
* `shiny::shinyAppTemplate()` no longer errors without a call to `library(shiny)`. (#3870)
* Updated the JavaScript used when inserting a tab to avoid rendering dynamic UI elements twice when adding the new tab via `insertTab()` or `bslib::nav_insert()`. (#4179)
# shiny 1.10.0
@@ -232,6 +192,7 @@ In addition, various properties of the spinners and pulse can be customized with
* Fixed #3833: When `width` is provided to `textAreaInput()`, we now correctly set the width of the `<textarea>` element. (#3838)
# shiny 1.7.4.1
## Full changelog
@@ -420,7 +381,7 @@ This release focuses on improvements in three main areas:
* Fixed #2951: screen readers correctly announce labels and date formats for `dateInput()` and `dateRangeInput()` widgets. (#2978)
* Closed #2847: `selectInput()` is reasonably accessible for screen readers even when `selectize` option is set to TRUE. To improve `selectize.js` accessibility, we have added [selectize-plugin-a11y](https://github.com/SalmenBejaoui/selectize-plugin-a11y) by default. (#2993)
* Closed #2847: `selectInput()` is reasonably accessible for screen readers even when `selectize` option is set to TRUE. To improve `selectize.js` accessibility, we have added [selectize-plugin-a11y](https://github.com/SLMNBJ/selectize-plugin-a11y) by default. (#2993)
* Closed #612: Added `alt` argument to `renderPlot()` and `renderCachedPlot()` to specify descriptive texts for `plotOutput()` objects, which is essential for screen readers. By default, alt text is set to the static text, "Plot object," but even dynamic text can be made with reactive function. (#3006, thanks @trafficonese and @leonawicz for the original PR and discussion via #2494)

View File

@@ -231,8 +231,8 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#' promises, but rather objects provided by the
#' \href{https://rstudio.github.io/promises/}{\pkg{promises}} package, which
#' are similar to promises in JavaScript. (See [promises::promise()] for more
#' information.) You can also use [mirai::mirai()] or [future::future()]
#' objects to run code in a separate process or even on a remote machine.
#' information.) You can also use [future::future()] objects to run code in a
#' separate process or even on a remote machine.
#'
#' If the value returns a promise, then anything that consumes the cached
#' reactive must expect it to return a promise.

View File

@@ -75,18 +75,6 @@ getCallNames <- function(calls) {
})
}
# A stripped down version of getCallNames() that intentionally avoids deparsing expressions.
# Instead, it leaves expressions to be directly `rlang::hash()` (for de-duplication), which
# is much faster than deparsing then hashing.
getCallNamesForHash <- function(calls) {
lapply(calls, function(call) {
name <- call[[1L]]
if (is.function(name)) return("<Anonymous>")
if (typeof(name) == "promise") return("<Promise>")
name
})
}
getLocs <- function(calls) {
vapply(calls, function(call) {
srcref <- attr(call, "srcref", exact = TRUE)
@@ -156,7 +144,7 @@ getCallStackDigest <- function(callStack, warn = FALSE) {
)
}
rlang::hash(getCallNamesForHash(callStack))
rlang::hash(getCallNames(callStack))
}
saveCallStackDigest <- function(callStack) {

View File

@@ -41,15 +41,12 @@
#' is, a function that quickly returns a promise) and allows even that very
#' session to immediately unblock and carry on with other user interactions.
#'
#' @examplesIf rlang::is_interactive() && rlang::is_installed("mirai")
#' @examplesIf rlang::is_interactive() && rlang::is_installed("future")
#'
#' library(shiny)
#' library(bslib)
#' library(mirai)
#'
#' # Set background processes for running tasks
#' daemons(1)
#' # Reset when the app is stopped
#' onStop(function() daemons(0))
#' library(future)
#' plan(multisession)
#'
#' ui <- page_fluid(
#' titlePanel("Extended Task Demo"),
@@ -63,12 +60,13 @@
#'
#' server <- function(input, output) {
#' rand_task <- ExtendedTask$new(function() {
#' mirai(
#' future(
#' {
#' # Slow operation goes here
#' Sys.sleep(2)
#' sample(1:100, 1)
#' }
#' },
#' seed = TRUE
#' )
#' })
#'
@@ -102,12 +100,11 @@ ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
#' @param func The long-running operation to execute. This should be an
#' asynchronous function, meaning, it should use the
#' [\{promises\}](https://rstudio.github.io/promises/) package, most
#' likely in conjunction with the
#' [\{mirai\}](https://mirai.r-lib.org) or
#' likely in conjuction with the
#' [\{future\}](https://rstudio.github.io/promises/articles/promises_04_futures.html)
#' package. (In short, the return value of `func` should be a
#' [`mirai`][mirai::mirai()], [`Future`][future::future()], `promise`,
#' or something else that [promises::as.promise()] understands.)
#' [`Future`][future::future()] object, or a `promise`, or something else
#' that [promises::as.promise()] understands.)
#'
#' It's also important that this logic does not read from any
#' reactive inputs/sources, as inputs may change after the function is
@@ -133,15 +130,14 @@ ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
#' arguments.
invoke = function(...) {
args <- rlang::dots_list(..., .ignore_empty = "none")
call <- rlang::caller_call(n = 0)
if (
isolate(private$rv_status()) == "running" ||
private$invocation_queue$size() > 0
) {
private$invocation_queue$add(list(args = args, call = call))
private$invocation_queue$add(args)
} else {
private$do_invoke(args, call = call)
private$do_invoke(args)
}
invisible(NULL)
},
@@ -208,41 +204,44 @@ ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
rv_error = NULL,
invocation_queue = NULL,
do_invoke = function(args, call = NULL) {
do_invoke = function(args) {
private$rv_status("running")
private$rv_value(NULL)
private$rv_error(NULL)
p <- promises::promise_resolve(
maskReactiveContext(do.call(private$func, args))
)
p <- promises::then(
p,
onFulfilled = function(value, .visible) {
private$on_success(list(value = value, visible = .visible))
},
onRejected = function(error) {
private$on_error(error, call = call)
}
)
promises::finally(p, onFinally = function() {
if (private$invocation_queue$size() > 0) {
next_call <- private$invocation_queue$remove()
private$do_invoke(next_call$args, next_call$call)
}
p <- NULL
tryCatch({
maskReactiveContext({
# TODO: Bounce the do.call off of a promise_resolve(), so that the
# call to invoke() always returns immediately?
result <- do.call(private$func, args)
p <- promises::as.promise(result)
})
}, error = function(e) {
private$on_error(e)
})
promises::finally(
promises::then(p,
onFulfilled = function(value, .visible) {
private$on_success(list(value=value, visible=.visible))
},
onRejected = function(error) {
private$on_error(error)
}
),
onFinally = function() {
if (private$invocation_queue$size() > 0) {
private$do_invoke(private$invocation_queue$remove())
}
}
)
invisible(NULL)
},
on_error = function(err, call = NULL) {
cli::cli_warn(
"ERROR: An error occurred when invoking the ExtendedTask.",
parent = err,
call = call
)
on_error = function(err) {
private$rv_status("error")
private$rv_error(err)
},

View File

@@ -56,24 +56,13 @@ actionButton <- function(inputId, label, icon = NULL, width = NULL,
value <- restoreInput(id = inputId, default = NULL)
icon <- validateIcon(icon)
if (!is.null(icon)) {
icon <- span(icon, class = "action-icon")
}
if (!is.null(label)) {
label <- span(label, class = "action-label")
}
tags$button(
id = inputId,
tags$button(id=inputId,
style = css(width = validateCssUnit(width)),
type = "button",
class = "btn btn-default action-button",
type="button",
class="btn btn-default action-button",
`data-val` = value,
disabled = if (isTRUE(disabled)) NA else NULL,
icon, label,
list(validateIcon(icon), label),
...
)
}
@@ -83,40 +72,30 @@ actionButton <- function(inputId, label, icon = NULL, width = NULL,
actionLink <- function(inputId, label, icon = NULL, ...) {
value <- restoreInput(id = inputId, default = NULL)
icon <- validateIcon(icon)
if (!is.null(icon)) {
icon <- span(icon, class = "action-icon")
}
if (!is.null(label)) {
label <- span(label, class = "action-label")
}
tags$a(
id = inputId,
href = "#",
class = "action-button action-link",
tags$a(id=inputId,
href="#",
class="action-button",
`data-val` = value,
icon, label,
list(validateIcon(icon), label),
...
)
}
# Throw an informative warning if icon isn't html-ish
# Check that the icon parameter is valid:
# 1) Check if the user wants to actually add an icon:
# -- if icon=NULL, it means leave the icon unchanged
# -- if icon=character(0), it means don't add an icon or, more usefully,
# remove the previous icon
# 2) If so, check that the icon has the right format (this does not check whether
# it is a *real* icon - currently that would require a massive cross reference
# with the "font-awesome" and the "glyphicon" libraries)
validateIcon <- function(icon) {
if (length(icon) == 0) {
if (is.null(icon) || identical(icon, character(0))) {
return(icon)
} else if (inherits(icon, "shiny.tag") && icon$name == "i") {
return(icon)
} else {
stop("Invalid icon. Use Shiny's 'icon()' function to generate a valid icon")
}
if (!isTagLike(icon)) {
rlang::warn(
c(
"It appears that a non-HTML value was provided to `icon`.",
i = "Try using a `shiny::icon()` (or an equivalent) to get an icon."
),
class = "shiny-validate-icon"
)
}
icon
}

View File

@@ -57,7 +57,7 @@ submitButton <- function(text = "Apply Changes", icon = NULL, width = NULL) {
div(
tags$button(
type="submit",
class="btn btn-primary shiny-submit-button",
class="btn btn-primary submit-button",
style = css(width = validateCssUnit(width)),
list(icon, text)
)

View File

@@ -66,7 +66,7 @@ textAreaInput <- function(
resize <- match.arg(resize, c("both", "none", "vertical", "horizontal"))
}
classes <- "form-control"
classes <- c("shiny-input-textarea", "form-control")
if (autoresize) {
classes <- c(classes, "textarea-autoresize")
if (is.null(rows)) {
@@ -75,7 +75,7 @@ textAreaInput <- function(
}
div(
class = "shiny-input-textarea form-group shiny-input-container",
class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
tags$textarea(

View File

@@ -266,8 +266,6 @@ drawPlot <- function(name, session, func, width, height, alt, pixelratio, res, .
# addition to ggplot, and there's a print method for that class, that we
# won't override that method. https://github.com/rstudio/shiny/issues/841
print.ggplot <- custom_print.ggplot
# For compatibility with ggplot2 >v4.0.0
`print.ggplot2::ggplot` <- custom_print.ggplot
# Use capture.output to squelch printing to the actual console; we
# are only interested in plot output

View File

@@ -37,11 +37,7 @@
updateTextInput <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, value = NULL, placeholder = NULL) {
validate_session_object(session)
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
value = value,
placeholder = placeholder
))
message <- dropNulls(list(label=label, value=value, placeholder=placeholder))
session$sendInputMessage(inputId, message)
}
@@ -115,10 +111,7 @@ updateTextAreaInput <- updateTextInput
updateCheckboxInput <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, value = NULL) {
validate_session_object(session)
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
value = value
))
message <- dropNulls(list(label=label, value=value))
session$sendInputMessage(inputId, message)
}
@@ -181,11 +174,8 @@ updateCheckboxInput <- function(session = getDefaultReactiveDomain(), inputId, l
updateActionButton <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, icon = NULL, disabled = NULL) {
validate_session_object(session)
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
icon = if (!is.null(icon)) processDeps(validateIcon(icon), session),
disabled = disabled
))
if (!is.null(icon)) icon <- as.character(validateIcon(icon))
message <- dropNulls(list(label=label, icon=icon, disabled=disabled))
session$sendInputMessage(inputId, message)
}
#' @rdname updateActionButton
@@ -235,12 +225,7 @@ updateDateInput <- function(session = getDefaultReactiveDomain(), inputId, label
min <- dateYMD(min, "min")
max <- dateYMD(max, "max")
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
value = value,
min = min,
max = max
))
message <- dropNulls(list(label=label, value=value, min=min, max=max))
session$sendInputMessage(inputId, message)
}
@@ -290,7 +275,7 @@ updateDateRangeInput <- function(session = getDefaultReactiveDomain(), inputId,
max <- dateYMD(max, "max")
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
label = label,
value = dropNulls(list(start = start, end = end)),
min = min,
max = max
@@ -389,16 +374,13 @@ updateNavlistPanel <- updateTabsetPanel
#' }
#' @export
updateNumericInput <- function(session = getDefaultReactiveDomain(), inputId, label = NULL, value = NULL,
min = NULL, max = NULL, step = NULL) {
min = NULL, max = NULL, step = NULL) {
validate_session_object(session)
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
value = formatNoSci(value),
min = formatNoSci(min),
max = formatNoSci(max),
step = formatNoSci(step)
label = label, value = formatNoSci(value),
min = formatNoSci(min), max = formatNoSci(max), step = formatNoSci(step)
))
session$sendInputMessage(inputId, message)
}
@@ -478,7 +460,7 @@ updateSliderInput <- function(session = getDefaultReactiveDomain(), inputId, lab
}
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
label = label,
value = formatNoSci(value),
min = formatNoSci(min),
max = formatNoSci(max),
@@ -509,11 +491,7 @@ updateInputOptions <- function(session, inputId, label = NULL, choices = NULL,
))
}
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
options = options,
value = selected
))
message <- dropNulls(list(label = label, options = options, value = selected))
session$sendInputMessage(inputId, message)
}
@@ -666,11 +644,7 @@ updateSelectInput <- function(session = getDefaultReactiveDomain(), inputId, lab
choices <- if (!is.null(choices)) choicesWithNames(choices)
if (!is.null(selected)) selected <- as.character(selected)
options <- if (!is.null(choices)) selectOptions(choices, selected, inputId, FALSE)
message <- dropNulls(list(
label = if (!is.null(label)) processDeps(label, session),
options = options,
value = selected
))
message <- dropNulls(list(label = label, options = options, value = selected))
session$sendInputMessage(inputId, message)
}

View File

@@ -1,21 +0,0 @@
# Check if `x` is a tag(), tagList(), or HTML()
# @param strict If `FALSE`, also consider a normal list() of 'tags' to be a tag list.
isTagLike <- function(x, strict = FALSE) {
isTag(x) || isTagList(x, strict = strict) || isTRUE(attr(x, "html"))
}
isTag <- function(x) {
inherits(x, "shiny.tag")
}
isTagList <- function(x, strict = TRUE) {
if (strict) {
return(inherits(x, "shiny.tag.list"))
}
if (!is.list(x)) {
return(FALSE)
}
all(vapply(x, isTagLike, logical(1)))
}

View File

@@ -1,2 +1,2 @@
# Generated by tools/updatejQuery.R; do not edit by hand
version_jquery <- "3.7.1"
version_jquery <- "3.6.0"

View File

@@ -1,2 +1,2 @@
# Generated by tools/updatejQueryUI.R; do not edit by hand
version_jqueryui <- "1.14.1"
version_jqueryui <- "1.13.2"

View File

@@ -5,7 +5,7 @@ test_that("Initial snapshot values are consistent", {
app$expect_values()
}){{
if (isTRUE(module)) {
shiny::HTML('
HTML('
test_that("Module values are consistent", {

View File

@@ -1,9 +1,9 @@
<html>
<head>
<script src="shared/jquery.min.js" type="text/javascript"></script>
<script src="shared/shiny.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="shared/shiny.min.css"/>
<script src="shared/jquery.js" type="text/javascript"></script>
<script src="shared/shiny.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="shared/shiny.css"/>
</head>
<body>

View File

@@ -1,2 +1,2 @@
/*! shiny 1.11.1.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
/*! shiny 1.10.0.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
:where([data-shiny-busy-spinners] .recalculating){position:relative}[data-shiny-busy-spinners] .recalculating{min-height:var(--shiny-spinner-size, 32px)}[data-shiny-busy-spinners] .recalculating:after{position:absolute;content:"";--_shiny-spinner-url: var(--shiny-spinner-url, url(spinners/ring.svg));--_shiny-spinner-color: var(--shiny-spinner-color, var(--bs-primary, #007bc2));--_shiny-spinner-size: var(--shiny-spinner-size, 32px);--_shiny-spinner-delay: var(--shiny-spinner-delay, 1s);background:var(--_shiny-spinner-color);width:var(--_shiny-spinner-size);height:var(--_shiny-spinner-size);inset:calc(50% - var(--_shiny-spinner-size) / 2);mask-image:var(--_shiny-spinner-url);-webkit-mask-image:var(--_shiny-spinner-url);opacity:0;animation-delay:var(--_shiny-spinner-delay);animation-name:fade-in;animation-duration:.25s;animation-fill-mode:forwards}[data-shiny-busy-spinners] .recalculating:has(>*),[data-shiny-busy-spinners] .recalculating:empty{opacity:1}[data-shiny-busy-spinners] .recalculating>*:not(.recalculating){opacity:var(--_shiny-fade-opacity);transition:opacity .25s ease var(--shiny-spinner-delay, 1s)}[data-shiny-busy-spinners] .recalculating.html-widget-output{visibility:inherit!important}[data-shiny-busy-spinners] .recalculating.html-widget-output>*{visibility:hidden}[data-shiny-busy-spinners] .recalculating.html-widget-output :after{visibility:visible}[data-shiny-busy-spinners] .recalculating.shiny-html-output:not(.shiny-table-output):after{display:none}[data-shiny-busy-spinners][data-shiny-busy-pulse].shiny-busy:after{--_shiny-pulse-background: var( --shiny-pulse-background, linear-gradient( 120deg, transparent, var(--bs-indigo, #4b00c1), var(--bs-purple, #74149c), var(--bs-pink, #bf007f), transparent ) );--_shiny-pulse-height: var(--shiny-pulse-height, 3px);--_shiny-pulse-speed: var(--shiny-pulse-speed, 1.2s);position:fixed;top:0;left:0;height:var(--_shiny-pulse-height);background:var(--_shiny-pulse-background);z-index:9999;animation-name:busy-page-pulse;animation-duration:var(--_shiny-pulse-speed);animation-direction:alternate;animation-iteration-count:infinite;animation-timing-function:ease-in-out;content:""}[data-shiny-busy-spinners][data-shiny-busy-pulse].shiny-busy:has(.recalculating:not(.shiny-html-output)):after{display:none}[data-shiny-busy-spinners][data-shiny-busy-pulse].shiny-busy:has(.recalculating.shiny-table-output):after{display:none}[data-shiny-busy-spinners][data-shiny-busy-pulse].shiny-busy:has(#shiny-disconnected-overlay):after{display:none}[data-shiny-busy-pulse]:not([data-shiny-busy-spinners]).shiny-busy:after{--_shiny-pulse-background: var( --shiny-pulse-background, linear-gradient( 120deg, transparent, var(--bs-indigo, #4b00c1), var(--bs-purple, #74149c), var(--bs-pink, #bf007f), transparent ) );--_shiny-pulse-height: var(--shiny-pulse-height, 3px);--_shiny-pulse-speed: var(--shiny-pulse-speed, 1.2s);position:fixed;top:0;left:0;height:var(--_shiny-pulse-height);background:var(--_shiny-pulse-background);z-index:9999;animation-name:busy-page-pulse;animation-duration:var(--_shiny-pulse-speed);animation-direction:alternate;animation-iteration-count:infinite;animation-timing-function:ease-in-out;content:""}[data-shiny-busy-pulse]:not([data-shiny-busy-spinners]).shiny-busy:has(#shiny-disconnected-overlay):after{display:none}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes busy-page-pulse{0%{left:-14%;right:97%}45%{left:0%;right:14%}55%{left:14%;right:0%}to{left:97%;right:-14%}}.shiny-spinner-output-container{--shiny-spinner-size: 0px}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
Authors ordered by first contribution
A list of current team members is available at https://jqueryui.com/about
A list of current team members is available at http://jqueryui.com/about
Paul Bakaus <paul.bakaus@gmail.com>
Richard Worth <rdworth@gmail.com>
@@ -42,7 +42,7 @@ Adam Sontag <ajpiano@ajpiano.com>
Carl Fürstenberg <carl@excito.com>
Kevin Dalman <development@allpro.net>
Alberto Fernández Capel <afcapel@gmail.com>
Jacek Jędrzejewski (https://jacek.jedrzejewski.name)
Jacek Jędrzejewski (http://jacek.jedrzejewski.name)
Ting Kuei <ting@kuei.com>
Samuel Cormier-Iijima <sam@chide.it>
Jon Palmer <jonspalmer@gmail.com>
@@ -370,15 +370,3 @@ dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Adam Lidén Hällgren <adamlh92@gmail.com>
James Hinderks <hinderks@gmail.com>
Denny Septian Panggabean <97607754+ddevsr@users.noreply.github.com>
Matías Cánepa <matias.canepa@gmail.com>
Ashish Kurmi <100655670+boahc077@users.noreply.github.com>
DeerBear <andrea.raimondi@gmail.com>
Дилян Палаузов <dpa-github@aegee.org>
Kenneth DeBacker <kcdebacker@gmail.com>
Timo Tijhof <krinkle@fastmail.com>
Timmy Willison <timmywil@users.noreply.github.com>
divdeploy <166095818+divdeploy@users.noreply.github.com>
mark van tilburg <markvantilburg@gmail.com>
Ralf Koller <1665422+rpkoller@users.noreply.github.com>
Porter Clevidence <116387727+porterclev@users.noreply.github.com>
Daniel García <93217193+Daniel-Garmig@users.noreply.github.com>

View File

@@ -1,4 +1,4 @@
Copyright OpenJS Foundation and other contributors, https://openjsf.org/
Copyright jQuery Foundation and other contributors, https://jquery.org/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -437,7 +437,7 @@ $( "#button-icon" ).button({
showLabel: false
});
$( "#radioset" ).controlgroup();
$( "#radioset" ).buttonset();
$( "#controlgroup" ).controlgroup();

View File

@@ -1,8 +1,8 @@
/*! jQuery UI - v1.14.1 - 2024-10-30
* https://jqueryui.com
/*! jQuery UI - v1.13.2 - 2022-07-14
* http://jqueryui.com
* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
* To view and modify this theme, visit https://jqueryui.com/themeroller/?bgColorDefault=%23f6f6f6&borderColorDefault=%23c5c5c5&fcDefault=%23454545&bgColorHover=%23ededed&borderColorHover=%23cccccc&fcHover=%232b2b2b&bgColorActive=%23007fff&borderColorActive=%23003eff&fcActive=%23ffffff&bgColorHeader=%23e9e9e9&borderColorHeader=%23dddddd&fcHeader=%23333333&bgColorContent=%23ffffff&borderColorContent=%23dddddd&fcContent=%23333333&bgColorHighlight=%23fffa90&borderColorHighlight=%23dad55e&fcHighlight=%23777620&bgColorError=%23fddfdf&borderColorError=%23f1a899&fcError=%235f3f3f&bgColorOverlay=%23aaaaaa&opacityOverlay=.3&bgColorShadow=%23666666&opacityShadow=.3&offsetTopShadow=0px&offsetLeftShadow=0px&thicknessShadow=5px&cornerRadiusShadow=8px&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif&fwDefault=normal&cornerRadius=3px&bgTextureDefault=flat&bgTextureHover=flat&bgTextureActive=flat&bgTextureHeader=flat&bgTextureContent=flat&bgTextureHighlight=flat&bgTextureError=flat&bgTextureOverlay=flat&bgTextureShadow=flat&bgImgOpacityDefault=75&bgImgOpacityHover=75&bgImgOpacityActive=65&bgImgOpacityHeader=75&bgImgOpacityContent=75&bgImgOpacityHighlight=55&bgImgOpacityError=95&bgImgOpacityOverlay=0&bgImgOpacityShadow=0&iconColorActive=%23ffffff&iconColorContent=%23444444&iconColorDefault=%23777777&iconColorError=%23cc0000&iconColorHeader=%23444444&iconColorHighlight=%23777620&iconColorHover=%23555555&opacityOverlayPerc=30&opacityShadowPerc=30&bgImgUrlActive=&bgImgUrlContent=&bgImgUrlDefault=&bgImgUrlError=&bgImgUrlHeader=&bgImgUrlHighlight=&bgImgUrlHover=&bgImgUrlOverlay=&bgImgUrlShadow=&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&bgDefaultRepeat=&bgHoverRepeat=&bgActiveRepeat=&bgHeaderRepeat=&bgContentRepeat=&bgHighlightRepeat=&bgErrorRepeat=&bgOverlayRepeat=&bgShadowRepeat=&bgDefaultYPos=&bgHoverYPos=&bgActiveYPos=&bgHeaderYPos=&bgContentYPos=&bgHighlightYPos=&bgErrorYPos=&bgOverlayYPos=&bgShadowYPos=&bgDefaultXPos=&bgHoverXPos=&bgActiveXPos=&bgHeaderXPos=&bgContentXPos=&bgHighlightXPos=&bgErrorXPos=&bgOverlayXPos=&bgShadowXPos=
* Copyright OpenJS Foundation and other contributors; Licensed MIT */
* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6
* Copyright jQuery Foundation and other contributors; Licensed MIT */
/* Layout helpers
----------------------------------*/
@@ -45,6 +45,7 @@
left: 0;
position: absolute;
opacity: 0;
-ms-filter: "alpha(opacity=0)"; /* support: IE8 */
}
.ui-front {
@@ -121,6 +122,8 @@
.ui-menu .ui-menu-item {
margin: 0;
cursor: pointer;
/* support: IE10, see #8844 */
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
}
.ui-menu .ui-menu-item-wrapper {
position: relative;
@@ -170,7 +173,12 @@
vertical-align: middle;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* Support: IE <= 11 */
overflow: visible;
}
.ui-button,
@@ -221,7 +229,7 @@ input.ui-button.ui-icon-notext .ui-icon {
}
/* workarounds */
/* Support: Firefox 5 - 125+ */
/* Support: Firefox 5 - 40 */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
@@ -272,6 +280,9 @@ button.ui-button::-moz-focus-inner {
/* Spinner specific style fixes */
.ui-controlgroup-vertical .ui-spinner-input {
/* Support: IE8 only, Android < 4.4 only */
width: 75%;
width: calc( 100% - 2.4em );
}
.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
@@ -568,6 +579,7 @@ button.ui-button::-moz-focus-inner {
cursor: move;
}
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable {
@@ -577,6 +589,7 @@ button.ui-button::-moz-focus-inner {
position: absolute;
font-size: 0.1px;
display: block;
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable-disabled .ui-resizable-handle,
@@ -651,12 +664,14 @@ button.ui-button::-moz-focus-inner {
.ui-progressbar .ui-progressbar-overlay {
background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
height: 100%;
-ms-filter: "alpha(opacity=25)"; /* support: IE8 */
opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
background-image: none;
}
.ui-selectable {
-ms-touch-action: none;
touch-action: none;
}
.ui-selectable-helper {
@@ -714,6 +729,7 @@ button.ui-button::-moz-focus-inner {
width: 1.2em;
height: 1.2em;
cursor: pointer;
-ms-touch-action: none;
touch-action: none;
}
.ui-slider .ui-slider-range {
@@ -725,6 +741,12 @@ button.ui-button::-moz-focus-inner {
background-position: 0 0;
}
/* support: IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
filter: inherit;
}
.ui-slider-horizontal {
height: .8em;
}
@@ -763,6 +785,7 @@ button.ui-button::-moz-focus-inner {
top: 0;
}
.ui-sortable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-spinner {
@@ -1018,14 +1041,19 @@ a.ui-button:active,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
opacity: .7;
-ms-filter: "alpha(opacity=70)"; /* support: IE8 */
font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
opacity: .35;
-ms-filter: "alpha(opacity=35)"; /* support: IE8 */
background-image: none;
}
.ui-state-disabled .ui-icon {
-ms-filter: "alpha(opacity=35)"; /* support: IE8 - See #6059 */
}
/* Icons
----------------------------------*/
@@ -1278,8 +1306,10 @@ a.ui-button:active,
/* Overlays */
.ui-widget-overlay {
background: #aaaaaa;
opacity: .3;
opacity: .003;
-ms-filter: Alpha(Opacity=.3); /* support: IE8 */
}
.ui-widget-shadow {
-webkit-box-shadow: 0px 0px 5px #666666;
box-shadow: 0px 0px 5px #666666;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,12 @@
/*!
* jQuery UI CSS Framework 1.14.1
* https://jqueryui.com
* jQuery UI CSS Framework 1.13.2
* http://jqueryui.com
*
* Copyright OpenJS Foundation and other contributors
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* https://jquery.org/license
* http://jquery.org/license
*
* https://api.jqueryui.com/category/theming/
* http://api.jqueryui.com/category/theming/
*/
/* Layout helpers
----------------------------------*/
@@ -49,6 +49,7 @@
left: 0;
position: absolute;
opacity: 0;
-ms-filter: "alpha(opacity=0)"; /* support: IE8 */
}
.ui-front {
@@ -125,6 +126,8 @@
.ui-menu .ui-menu-item {
margin: 0;
cursor: pointer;
/* support: IE10, see #8844 */
list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
}
.ui-menu .ui-menu-item-wrapper {
position: relative;
@@ -174,7 +177,12 @@
vertical-align: middle;
text-align: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* Support: IE <= 11 */
overflow: visible;
}
.ui-button,
@@ -225,7 +233,7 @@ input.ui-button.ui-icon-notext .ui-icon {
}
/* workarounds */
/* Support: Firefox 5 - 125+ */
/* Support: Firefox 5 - 40 */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
@@ -276,6 +284,9 @@ button.ui-button::-moz-focus-inner {
/* Spinner specific style fixes */
.ui-controlgroup-vertical .ui-spinner-input {
/* Support: IE8 only, Android < 4.4 only */
width: 75%;
width: calc( 100% - 2.4em );
}
.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
@@ -572,6 +583,7 @@ button.ui-button::-moz-focus-inner {
cursor: move;
}
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable {
@@ -581,6 +593,7 @@ button.ui-button::-moz-focus-inner {
position: absolute;
font-size: 0.1px;
display: block;
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable-disabled .ui-resizable-handle,
@@ -655,12 +668,14 @@ button.ui-button::-moz-focus-inner {
.ui-progressbar .ui-progressbar-overlay {
background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
height: 100%;
-ms-filter: "alpha(opacity=25)"; /* support: IE8 */
opacity: 0.25;
}
.ui-progressbar-indeterminate .ui-progressbar-value {
background-image: none;
}
.ui-selectable {
-ms-touch-action: none;
touch-action: none;
}
.ui-selectable-helper {
@@ -718,6 +733,7 @@ button.ui-button::-moz-focus-inner {
width: 1.2em;
height: 1.2em;
cursor: pointer;
-ms-touch-action: none;
touch-action: none;
}
.ui-slider .ui-slider-range {
@@ -729,6 +745,12 @@ button.ui-button::-moz-focus-inner {
background-position: 0 0;
}
/* support: IE8 - See #6727 */
.ui-slider.ui-state-disabled .ui-slider-handle,
.ui-slider.ui-state-disabled .ui-slider-range {
filter: inherit;
}
.ui-slider-horizontal {
height: .8em;
}
@@ -767,6 +789,7 @@ button.ui-button::-moz-focus-inner {
top: 0;
}
.ui-sortable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-spinner {

File diff suppressed because one or more lines are too long

View File

@@ -1,14 +1,14 @@
/*!
* jQuery UI CSS Framework 1.14.1
* https://jqueryui.com
* jQuery UI CSS Framework 1.13.2
* http://jqueryui.com
*
* Copyright OpenJS Foundation and other contributors
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* https://jquery.org/license
* http://jquery.org/license
*
* https://api.jqueryui.com/category/theming/
* http://api.jqueryui.com/category/theming/
*
* To view and modify this theme, visit https://jqueryui.com/themeroller/?bgColorDefault=%23f6f6f6&borderColorDefault=%23c5c5c5&fcDefault=%23454545&bgColorHover=%23ededed&borderColorHover=%23cccccc&fcHover=%232b2b2b&bgColorActive=%23007fff&borderColorActive=%23003eff&fcActive=%23ffffff&bgColorHeader=%23e9e9e9&borderColorHeader=%23dddddd&fcHeader=%23333333&bgColorContent=%23ffffff&borderColorContent=%23dddddd&fcContent=%23333333&bgColorHighlight=%23fffa90&borderColorHighlight=%23dad55e&fcHighlight=%23777620&bgColorError=%23fddfdf&borderColorError=%23f1a899&fcError=%235f3f3f&bgColorOverlay=%23aaaaaa&opacityOverlay=.3&bgColorShadow=%23666666&opacityShadow=.3&offsetTopShadow=0px&offsetLeftShadow=0px&thicknessShadow=5px&cornerRadiusShadow=8px&fsDefault=1em&ffDefault=Arial%2CHelvetica%2Csans-serif&fwDefault=normal&cornerRadius=3px&bgTextureDefault=flat&bgTextureHover=flat&bgTextureActive=flat&bgTextureHeader=flat&bgTextureContent=flat&bgTextureHighlight=flat&bgTextureError=flat&bgTextureOverlay=flat&bgTextureShadow=flat&bgImgOpacityDefault=75&bgImgOpacityHover=75&bgImgOpacityActive=65&bgImgOpacityHeader=75&bgImgOpacityContent=75&bgImgOpacityHighlight=55&bgImgOpacityError=95&bgImgOpacityOverlay=0&bgImgOpacityShadow=0&iconColorActive=%23ffffff&iconColorContent=%23444444&iconColorDefault=%23777777&iconColorError=%23cc0000&iconColorHeader=%23444444&iconColorHighlight=%23777620&iconColorHover=%23555555&opacityOverlayPerc=30&opacityShadowPerc=30&bgImgUrlActive=&bgImgUrlContent=&bgImgUrlDefault=&bgImgUrlError=&bgImgUrlHeader=&bgImgUrlHighlight=&bgImgUrlHover=&bgImgUrlOverlay=&bgImgUrlShadow=&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&bgDefaultRepeat=&bgHoverRepeat=&bgActiveRepeat=&bgHeaderRepeat=&bgContentRepeat=&bgHighlightRepeat=&bgErrorRepeat=&bgOverlayRepeat=&bgShadowRepeat=&bgDefaultYPos=&bgHoverYPos=&bgActiveYPos=&bgHeaderYPos=&bgContentYPos=&bgHighlightYPos=&bgErrorYPos=&bgOverlayYPos=&bgShadowYPos=&bgDefaultXPos=&bgHoverXPos=&bgActiveXPos=&bgHeaderXPos=&bgContentXPos=&bgHighlightXPos=&bgErrorXPos=&bgOverlayXPos=&bgShadowXPos=
* To view and modify this theme, visit http://jqueryui.com/themeroller/?bgShadowXPos=&bgOverlayXPos=&bgErrorXPos=&bgHighlightXPos=&bgContentXPos=&bgHeaderXPos=&bgActiveXPos=&bgHoverXPos=&bgDefaultXPos=&bgShadowYPos=&bgOverlayYPos=&bgErrorYPos=&bgHighlightYPos=&bgContentYPos=&bgHeaderYPos=&bgActiveYPos=&bgHoverYPos=&bgDefaultYPos=&bgShadowRepeat=&bgOverlayRepeat=&bgErrorRepeat=&bgHighlightRepeat=&bgContentRepeat=&bgHeaderRepeat=&bgActiveRepeat=&bgHoverRepeat=&bgDefaultRepeat=&iconsHover=url(%22images%2Fui-icons_555555_256x240.png%22)&iconsHighlight=url(%22images%2Fui-icons_777620_256x240.png%22)&iconsHeader=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsError=url(%22images%2Fui-icons_cc0000_256x240.png%22)&iconsDefault=url(%22images%2Fui-icons_777777_256x240.png%22)&iconsContent=url(%22images%2Fui-icons_444444_256x240.png%22)&iconsActive=url(%22images%2Fui-icons_ffffff_256x240.png%22)&bgImgUrlShadow=&bgImgUrlOverlay=&bgImgUrlHover=&bgImgUrlHighlight=&bgImgUrlHeader=&bgImgUrlError=&bgImgUrlDefault=&bgImgUrlContent=&bgImgUrlActive=&opacityFilterShadow=Alpha(Opacity%3D30)&opacityFilterOverlay=Alpha(Opacity%3D30)&opacityShadowPerc=30&opacityOverlayPerc=30&iconColorHover=%23555555&iconColorHighlight=%23777620&iconColorHeader=%23444444&iconColorError=%23cc0000&iconColorDefault=%23777777&iconColorContent=%23444444&iconColorActive=%23ffffff&bgImgOpacityShadow=0&bgImgOpacityOverlay=0&bgImgOpacityError=95&bgImgOpacityHighlight=55&bgImgOpacityContent=75&bgImgOpacityHeader=75&bgImgOpacityActive=65&bgImgOpacityHover=75&bgImgOpacityDefault=75&bgTextureShadow=flat&bgTextureOverlay=flat&bgTextureError=flat&bgTextureHighlight=flat&bgTextureContent=flat&bgTextureHeader=flat&bgTextureActive=flat&bgTextureHover=flat&bgTextureDefault=flat&cornerRadius=3px&fwDefault=normal&ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&cornerRadiusShadow=8px&thicknessShadow=5px&offsetLeftShadow=0px&offsetTopShadow=0px&opacityShadow=.3&bgColorShadow=%23666666&opacityOverlay=.3&bgColorOverlay=%23aaaaaa&fcError=%235f3f3f&borderColorError=%23f1a899&bgColorError=%23fddfdf&fcHighlight=%23777620&borderColorHighlight=%23dad55e&bgColorHighlight=%23fffa90&fcContent=%23333333&borderColorContent=%23dddddd&bgColorContent=%23ffffff&fcHeader=%23333333&borderColorHeader=%23dddddd&bgColorHeader=%23e9e9e9&fcActive=%23ffffff&borderColorActive=%23003eff&bgColorActive=%23007fff&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgColorHover=%23ededed&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgColorDefault=%23f6f6f6
*/
@@ -172,14 +172,19 @@ a.ui-button:active,
.ui-widget-content .ui-priority-secondary,
.ui-widget-header .ui-priority-secondary {
opacity: .7;
-ms-filter: "alpha(opacity=70)"; /* support: IE8 */
font-weight: normal;
}
.ui-state-disabled,
.ui-widget-content .ui-state-disabled,
.ui-widget-header .ui-state-disabled {
opacity: .35;
-ms-filter: "alpha(opacity=35)"; /* support: IE8 */
background-image: none;
}
.ui-state-disabled .ui-icon {
-ms-filter: "alpha(opacity=35)"; /* support: IE8 - See #6059 */
}
/* Icons
----------------------------------*/
@@ -432,8 +437,10 @@ a.ui-button:active,
/* Overlays */
.ui-widget-overlay {
background: #aaaaaa;
opacity: .3;
opacity: .003;
-ms-filter: Alpha(Opacity=.3); /* support: IE8 */
}
.ui-widget-shadow {
-webkit-box-shadow: 0px 0px 5px #666666;
box-shadow: 0px 0px 5px #666666;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
/*! shiny 1.11.1.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
/*! shiny 1.10.0.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
"use strict";(()=>{document.documentElement.classList.add("autoreload-enabled");var c=window.location.protocol==="https:"?"wss:":"ws:",s=window.location.pathname.replace(/\/?$/,"/")+"autoreload/",i=`${c}//${window.location.host}${s}`,l=document.currentScript?.dataset?.wsUrl||i;async function u(o){let e=new WebSocket(o),n=!1;return new Promise((a,r)=>{e.onopen=()=>{n=!0},e.onerror=t=>{r(t)},e.onclose=()=>{n?a(!1):r(new Error("WebSocket connection failed"))},e.onmessage=function(t){t.data==="autoreload"&&a(!0)}})}async function d(o){return new Promise(e=>setTimeout(e,o))}async function w(){for(;;){try{if(await u(l)){window.location.reload();return}}catch{console.debug("Giving up on autoreload");return}await d(1e3)}}w().catch(o=>{console.error(o)});})();
//# sourceMappingURL=shiny-autoreload.js.map

View File

@@ -1,2 +1,2 @@
/*! shiny 1.11.1.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
/*! shiny 1.10.0.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
#showcase-well{border-radius:0}.shiny-code{background-color:#fff;margin-bottom:0}.shiny-code code{font-family:Menlo,Consolas,Courier New,monospace}.shiny-code-container{margin-top:20px;clear:both}.shiny-code-container h3{display:inline;margin-right:15px}.showcase-header{font-size:16px;font-weight:400}.showcase-code-link{text-align:right;padding:15px}#showcase-app-container{vertical-align:top}#showcase-code-tabs{margin-right:15px}#showcase-code-tabs pre{border:none;line-height:1em}#showcase-code-tabs .nav,#showcase-code-tabs ul{margin-bottom:0}#showcase-code-tabs .tab-content{border-style:solid;border-color:#e5e5e5;border-width:0px 1px 1px 1px;overflow:auto;border-bottom-right-radius:4px;border-bottom-left-radius:4px}#showcase-app-code{width:100%}#showcase-code-position-toggle{float:right}#showcase-sxs-code{padding-top:20px;vertical-align:top}.showcase-code-license{display:block;text-align:right}#showcase-code-content pre{background-color:#fff}

View File

@@ -1,3 +1,3 @@
/*! shiny 1.11.1.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
/*! shiny 1.10.0.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
"use strict";(()=>{var f=400;function c(e,i){let t=0;if(e.nodeType===3){let n=e.nodeValue.replace(/\n/g,"").length;if(n>=i)return{element:e,offset:i};t+=n}else if(e.nodeType===1&&e.firstChild){let n=c(e.firstChild,i);if(n.element!==null)return n;t+=n.offset}return e.nextSibling?c(e.nextSibling,i-t):{element:null,offset:t}}function r(e,i,t){let n=0;for(let s=0;s<e.childNodes.length;s++){let l=e.childNodes[s];if(l.nodeType===3){let o=/\n/g,d;for(;(d=o.exec(l.nodeValue))!==null;)if(n++,n===i)return c(l,d.index+t+1)}else if(l.nodeType===1){let o=r(l,i-n,t);if(o.element!==null)return o;n+=o.offset}}return{element:null,offset:n}}function w(e,i){if(!document.createRange)return;let t=document.getElementById("srcref_"+e);if(!t){t=document.createElement("span"),t.id="srcref_"+e;let n=e,s=document.getElementById(i.replace(/\./g,"_")+"_code");if(!s)return;let l=r(s,n[0],n[4]),o=r(s,n[2],n[5]);if(l.element===null||o.element===null)return;let d=document.createRange();l.element.parentNode.nodeName==="SPAN"&&l.element!==o.element?d.setStartBefore(l.element.parentNode):d.setStart(l.element,l.offset),o.element.parentNode.nodeName==="SPAN"&&l.element!==o.element?d.setEndAfter(o.element.parentNode):d.setEnd(o.element,o.offset),d.surroundContents(t)}$(t).stop(!0,!0).effect("highlight",null,1600)}Shiny&&Shiny.addCustomMessageHandler("showcase-src",function(e){e.srcref&&e.srcfile&&w(e.srcref,e.srcfile)});var a=!1,m=function(e,i){let t=i?f:1,n=e?document.getElementById("showcase-sxs-code"):document.getElementById("showcase-code-inline"),s=e?document.getElementById("showcase-code-inline"):document.getElementById("showcase-sxs-code");if(document.getElementById("showcase-app-metadata")===null){let o=$("#showcase-well");e?o.fadeOut(t):o.fadeIn(t)}$(n).hide(),$(s).fadeOut(t,function(){let o=document.getElementById("showcase-code-tabs");s.removeChild(o),n.appendChild(o),e?h():document.getElementById("showcase-code-content").removeAttribute("style"),$(n).fadeIn(t),e||(document.getElementById("showcase-app-container").removeAttribute("style"),i&&$(document.body).animate({scrollTop:$(n).offset().top}));let d=document.getElementById("readme-md");d!==null&&(d.parentElement.removeChild(d),e?(s.appendChild(d),$(s).fadeIn(t)):document.getElementById("showcase-app-metadata").appendChild(d)),document.getElementById("showcase-code-position-toggle").innerHTML=e?'<i class="fa fa-level-down"></i> show below':'<i class="fa fa-level-up"></i> show with app'}),e&&$(document.body).animate({scrollTop:0},t),a=e,u(e&&i),$(window).trigger("resize")};function u(e){let t=960,n=1,s=document.getElementById("showcase-app-code").offsetWidth;s/2>960?t=s/2:s*.66>960?t=960:(t=s*.66,n=t/960);let l=document.getElementById("showcase-app-container");$(l).animate({width:t+"px",zoom:n*100+"%"},e?f:0)}var g=function(){m(!a,!0)},p=function(){document.body.offsetWidth>1350&&m(!0,!1)};function h(){document.getElementById("showcase-code-content").style.height=$(window).height()+"px"}function y(){let e=document.getElementById("showcase-markdown-content");if(e!==null){let i=e.innerText||e.innerHTML,t=window.Showdown.converter;document.getElementById("readme-md").innerHTML=new t().makeHtml(i)}}$(window).resize(function(){a&&(u(!1),h())});window.toggleCodePosition=g;$(window).on("load",p);$(window).on("load",y);window.hljs&&window.hljs.initHighlightingOnLoad();})();
//# sourceMappingURL=shiny-showcase.js.map

View File

@@ -1,3 +1,3 @@
/*! shiny 1.11.1.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
/*! shiny 1.10.0.9000 | (c) 2012-2025 Posit Software, PBC. | License: GPL-3 | file LICENSE */
"use strict";(()=>{var t=eval;window.addEventListener("message",function(a){let e=a.data;e.code&&t(e.code)});})();
//# sourceMappingURL=shiny-testmode.js.map

File diff suppressed because it is too large Load Diff

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

File diff suppressed because one or more lines are too long

View File

@@ -384,8 +384,8 @@ html.autoreload-enabled #shiny-disconnected-overlay.reloading {
width: 100%;
}
/* Styling for textAreaInput(autoresize=TRUE) */
textarea.textarea-autoresize.form-control {
/* Styling for inputTextArea(autoresize=TRUE) */
.textarea-autoresize textarea.form-control {
padding: 5px 8px;
resize: none;
overflow-y: hidden;
@@ -463,13 +463,6 @@ textarea.textarea-autoresize.form-control {
}
}
// Add spacing between icon and label for actionButton()
.action-button:not(.action-link) {
.action-icon + .action-label {
padding-left: 0.5ch;
}
}
/* Overrides bootstrap-datepicker3.css styling for invalid date ranges.
See https://github.com/rstudio/shiny/issues/2042 for details. */
.datepicker table tbody tr td.disabled,

View File

@@ -46,15 +46,12 @@ session to immediately unblock and carry on with other user interactions.
}
\examples{
\dontshow{if (rlang::is_interactive() && rlang::is_installed("mirai")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
\dontshow{if (rlang::is_interactive() && rlang::is_installed("future")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
library(shiny)
library(bslib)
library(mirai)
# Set background processes for running tasks
daemons(1)
# Reset when the app is stopped
onStop(function() daemons(0))
library(future)
plan(multisession)
ui <- page_fluid(
titlePanel("Extended Task Demo"),
@@ -68,12 +65,13 @@ ui <- page_fluid(
server <- function(input, output) {
rand_task <- ExtendedTask$new(function() {
mirai(
future(
{
# Slow operation goes here
Sys.sleep(2)
sample(1:100, 1)
}
},
seed = TRUE
)
})
@@ -123,12 +121,11 @@ server function.
\item{\code{func}}{The long-running operation to execute. This should be an
asynchronous function, meaning, it should use the
\href{https://rstudio.github.io/promises/}{\{promises\}} package, most
likely in conjunction with the
\href{https://mirai.r-lib.org}{\{mirai\}} or
likely in conjuction with the
\href{https://rstudio.github.io/promises/articles/promises_04_futures.html}{\{future\}}
package. (In short, the return value of \code{func} should be a
\code{\link[mirai:mirai]{mirai}}, \code{\link[future:future]{Future}}, \code{promise},
or something else that \code{\link[promises:is.promise]{promises::as.promise()}} understands.)
\code{\link[future:future]{Future}} object, or a \code{promise}, or something else
that \code{\link[promises:is.promise]{promises::as.promise()}} understands.)
It's also important that this logic does not read from any
reactive inputs/sources, as inputs may change after the function is

View File

@@ -234,8 +234,8 @@ With a cached reactive expression, the key and/or value expression can be
promises, but rather objects provided by the
\href{https://rstudio.github.io/promises/}{\pkg{promises}} package, which
are similar to promises in JavaScript. (See \code{\link[promises:promise]{promises::promise()}} for more
information.) You can also use \code{\link[mirai:mirai]{mirai::mirai()}} or \code{\link[future:future]{future::future()}}
objects to run code in a separate process or even on a remote machine.
information.) You can also use \code{\link[future:future]{future::future()}} objects to run code in a
separate process or even on a remote machine.
If the value returns a promise, then anything that consumes the cached
reactive must expect it to return a promise.

View File

@@ -20,15 +20,14 @@ includes extensive annotated examples.
\link{shiny-options} for documentation about global options.
}
\author{
\strong{Maintainer}: Carson Sievert \email{carson@posit.co} (\href{https://orcid.org/0000-0002-4958-2844}{ORCID})
\strong{Maintainer}: Winston Chang \email{winston@posit.co} (\href{https://orcid.org/0000-0002-1576-2126}{ORCID})
Authors:
\itemize{
\item Winston Chang \email{winston@posit.co} (\href{https://orcid.org/0000-0002-1576-2126}{ORCID})
\item Joe Cheng \email{joe@posit.co}
\item JJ Allaire \email{jj@posit.co}
\item Carson Sievert \email{carson@posit.co} (\href{https://orcid.org/0000-0002-4958-2844}{ORCID})
\item Barret Schloerke \email{barret@posit.co} (\href{https://orcid.org/0000-0001-9986-114X}{ORCID})
\item Garrick Aden-Buie \email{garrick@adenbuie.com} (\href{https://orcid.org/0000-0002-7111-0077}{ORCID})
\item Yihui Xie \email{yihui@posit.co}
\item Jeff Allen
\item Jonathan McPherson \email{jonathan@posit.co}
@@ -38,7 +37,7 @@ Authors:
Other contributors:
\itemize{
\item Posit Software, PBC (03wc8by49) [copyright holder, funder]
\item Posit Software, PBC [copyright holder, funder]
\item jQuery Foundation (jQuery library and jQuery UI library) [copyright holder]
\item jQuery contributors (jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt) [contributor, copyright holder]
\item jQuery UI contributors (jQuery UI library; authors listed in inst/www/shared/jqueryui/AUTHORS.txt) [contributor, copyright holder]
@@ -62,7 +61,7 @@ Other contributors:
\item John Fraser (showdown.js library) [contributor, copyright holder]
\item John Gruber (showdown.js library) [contributor, copyright holder]
\item Ivan Sagalaev (highlight.js library) [contributor, copyright holder]
\item R Core Team (tar implementation from R) [contributor, copyright holder]
\item R Core Team (tar implementation from R) [contributor, copyright holder]
}
}

View File

@@ -72,7 +72,7 @@ be done 100\% correctly.}
\code{\link[=runApp]{runApp()}} for more information.}
\item{shiny.jquery.version (defaults to \code{3})}{The major version of jQuery to use.
Currently only values of \code{3} or \code{1} are supported. If \code{1}, then jQuery 1.12.4 is used. If \code{3},
then jQuery 3.7.1 is used.}
then jQuery 3.6.0 is used.}
\item{shiny.json.digits (defaults to \code{I(16)})}{Max number of digits to use when converting
numbers to JSON format to send to the client web browser. Use \code{\link[=I]{I()}} to specify significant digits.
Use \code{NA} for max precision.}

View File

@@ -3,7 +3,7 @@
"homepage": "https://shiny.rstudio.com",
"repository": "github:rstudio/shiny",
"name": "@types/rstudio-shiny",
"version": "1.11.1-alpha.9000",
"version": "1.10.0-alpha.9000",
"license": "GPL-3.0-only",
"main": "",
"browser": "",
@@ -23,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.32",
"@types/jquery": "3.5.14",
"@types/selectize": "0.12.34",
"lit": "^3.0.0"
},
@@ -35,7 +35,7 @@
"@testing-library/user-event": "^13.1.9",
"@types/highlightjs": "^9.12.1",
"@types/jest": "^26.0.23",
"@types/jqueryui": "1.12.24",
"@types/jqueryui": "1.12.16",
"@types/lodash": "^4.14.170",
"@types/node": "^18.14.2",
"@types/showdown": "^1.9.3",
@@ -56,7 +56,7 @@
"eslint-plugin-unicorn": "^43.0.2",
"fs-readdir-recursive": "^1.1.0",
"jest": "^26.6.3",
"jquery": "3.7.1",
"jquery": "^3.6.0",
"lodash": "^4.17.21",
"madge": "^4.0.2",
"node-gyp": "^8.1.0",

View File

@@ -1,28 +1,34 @@
# Revdeps
## Failed to check (22)
## Failed to check (20)
|package |version |error |warning |note |
|:------------------|:-------|:-----|:-------|:----|
|animalEKF |1.2 |1 | | |
|AovBay |0.1.0 |1 | | |
|Certara.VPCResults |3.0.2 |1 | | |
|chipPCR |1.0-2 |1 | | |
|ctsem |3.10.1 |1 | | |
|dartR.sim |? | | | |
|diveR |? | | | |
|gap |? | | | |
|jsmodule |? | | | |
|loon.shiny |? | | | |
|robmedExtra |0.1.1 |1 | | |
|rstanarm |2.32.1 |1 | | |
|SensMap |0.7 |1 | | |
|Seurat |5.1.0 |1 | |1 |
|shinyTempSignal |0.0.8 |1 | | |
|Signac |1.14.0 |1 | | |
|statsr |0.3.0 |1 | | |
|TestAnaAPP |1.1.2 |1 | | |
|tidyvpc |1.5.2 |1 | | |
|visR |? | | | |
## New problems (2)
|package |version |error |warning |note |
|:-------|:-------|:-----|:-------|:------|
|[HH](problems.md#hh)|3.1-52 | | |__+1__ |
|[PopED](problems.md#poped)|0.7.0 | | |__+1__ |
|package |version |error |warning |note |
|:--------------------|:-------|:-----|:-------|:----|
|bigPint |? | | | |
|bioCancer |? | | | |
|EBImage |? | | | |
|FAfA |0.3 |1 | | |
|fio |0.1.6 |1 | | |
|GeneNetworkBuilder |? | | | |
|gradientPickerD3 |? | | | |
|InterCellar |? | | | |
|LACE |? | | | |
|lavaan.shiny |1.2 |1 | | |
|LDABiplots |? | | | |
|LDAShiny |? | | | |
|loon.shiny |? | | | |
|MatrixQCvis |? | | | |
|metricsgraphics |? | | | |
|modchart |? | | | |
|omicsViewer |? | | | |
|RSP |0.4 |1 | | |
|rstanarm |2.32.1 |1 | | |
|sphereML |0.1.1 |1 | | |
|StatTeacherAssistant |? | | | |
|TestAnaAPP |1.1.2 |1 | | |

View File

@@ -1,19 +1,39 @@
## revdepcheck results
We checked 1344 reverse dependencies (1330 from CRAN + 14 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.
We checked 1278 reverse dependencies (1277 from CRAN + 1 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.
* We saw 0 new problems
* We failed to check 8 packages
* We saw 2 new problems
* We failed to check 19 packages
Issues with CRAN packages are summarised below.
### New problems
(This reports the first line of each new failure)
* HH
checking installed package size ... NOTE
* PopED
checking installed package size ... NOTE
### Failed to check
* FAfA (NA)
* fio (NA)
* lavaan.shiny (NA)
* loon.shiny (NA)
* RSP (NA)
* rstanarm (NA)
* sphereML (NA)
* TestAnaAPP (NA)
* animalEKF (NA)
* AovBay (NA)
* Certara.VPCResults (NA)
* chipPCR (NA)
* ctsem (NA)
* dartR.sim (NA)
* diveR (NA)
* gap (NA)
* jsmodule (NA)
* loon.shiny (NA)
* robmedExtra (NA)
* rstanarm (NA)
* SensMap (NA)
* Seurat (NA)
* shinyTempSignal (NA)
* Signac (NA)
* statsr (NA)
* TestAnaAPP (NA)
* tidyvpc (NA)

View File

@@ -1 +1,49 @@
*Wow, no problems at all. :)*
# HH
<details>
* Version: 3.1-52
* GitHub: NA
* Source code: https://github.com/cran/HH
* Date/Publication: 2024-02-11 00:00:02 UTC
* Number of recursive dependencies: 165
Run `revdepcheck::cloud_details(, "HH")` for more info
</details>
## Newly broken
* checking installed package size ... NOTE
```
installed size is 5.1Mb
sub-directories of 1Mb or more:
R 1.5Mb
help 1.5Mb
```
# PopED
<details>
* Version: 0.7.0
* GitHub: https://github.com/andrewhooker/PopED
* Source code: https://github.com/cran/PopED
* Date/Publication: 2024-10-07 19:30:02 UTC
* Number of recursive dependencies: 140
Run `revdepcheck::cloud_details(, "PopED")` for more info
</details>
## Newly broken
* checking installed package size ... NOTE
```
installed size is 5.5Mb
sub-directories of 1Mb or more:
R 1.5Mb
doc 1.4Mb
test 1.1Mb
```

View File

@@ -1,22 +1,14 @@
# Using Shiny TypeScript Definitions
When developing TypeScript projects that use `window.Shiny`, we recommend installing the Shiny TypeScript definitions to your package. To install the latest stable definitions, run one of the following (depending on if you're using `npm` or `yarn`):
When developing TypeScript projects that use `window.Shiny`, we recommend installing the Shiny TypeScript definitions to your package. To install the latest stable definitions, call
```bash
npm install https://github.com/rstudio/shiny\#v1.10.0 --save-dev
# or
yarn add https://github.com/rstudio/shiny\#v1.10.0 --dev
yarn add https://github.com/rstudio/shiny\#v1.7.0
```
, matching the GitHub tag to your current the Shiny CRAN release (ex: `v1.10.0`). If you are asked to select a version of `@types/jquery`, please select the closest matching version.
, 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 matching version.
This will provide a global type definition of `window.Shiny`. In your code, you can access the Shiny object via `window.Shiny` or just `Shiny`. However, note that if you are using TypeScript, it will be OK with `window.Shiny` but it will flag uses of `Shiny` (without the `window.` prefix), because TypeScript won't know that it's a global variable. We consider it better practice to use `window.Shiny` instead of `Shiny`, but if you want TypeScript to know that `Shiny` is available as a global variable, you can add the following to a TypeScript file in your code base.
```ts
declare global {
const Shiny: ShinyClass;
}
```
This will provide a global type definition 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.js` 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.
@@ -194,7 +186,7 @@ Both JavaScript files will produce a sourcemap (`**.js.map`) that the browser wi
### Exported types
`./extras/globalShiny.ts` contains global declarations to define `window.Shiny`, a globally available `Shiny` variable, and a globally available `ShinyClass` 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 definition when the Type definitions are installed by external developers.
`./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 definition when the Type definitions are installed by external developers.
### GitHub Actions

View File

@@ -0,0 +1,6 @@
.textarea-autoresize textarea.form-control {
padding: 5px 8px;
resize: none;
overflow-y: hidden;
height: auto;
}

View File

@@ -1,12 +1,10 @@
import $ from "jquery";
import type { HtmlDep } from "../../shiny/render";
import { renderContent } from "../../shiny/render";
import { hasDefinedProperty } from "../../utils";
import { InputBinding } from "./inputBinding";
type ActionButtonReceiveMessageData = {
label?: { html: string; deps: HtmlDep[] };
icon?: { html: string; deps: HtmlDep[] };
label?: string;
icon?: string | [];
disabled?: boolean;
};
@@ -41,40 +39,45 @@ class ActionButtonInputBinding extends InputBinding {
getState(el: HTMLElement): { value: number } {
return { value: this.getValue(el) };
}
async receiveMessage(
el: HTMLElement,
data: ActionButtonReceiveMessageData
): Promise<void> {
if (hasDefinedProperty(data, "icon")) {
let iconContainer = el.querySelector<HTMLElement>(
":scope > .action-icon"
);
// If no container exists yet, create one
if (!iconContainer) {
iconContainer = document.createElement("span");
iconContainer.className = "action-icon";
el.prepend(iconContainer);
}
await renderContent(iconContainer, data.icon);
}
receiveMessage(el: HTMLElement, data: ActionButtonReceiveMessageData): void {
const $el = $(el);
if (hasDefinedProperty(data, "label")) {
let labelContainer = el.querySelector<HTMLElement>(
":scope > .action-label"
);
if (!labelContainer) {
labelContainer = document.createElement("span");
labelContainer.className = "action-label";
el.appendChild(labelContainer);
if (hasDefinedProperty(data, "label") || hasDefinedProperty(data, "icon")) {
// retrieve current label and icon
let label: string = $el.text();
let icon = "";
// to check (and store) the previous icon, we look for a $el child
// object that has an i tag, and some (any) class (this prevents
// italicized text - which has an i tag but, usually, no class -
// from being mistakenly selected)
if ($el.find("i[class]").length > 0) {
const iconHtml = $el.find("i[class]")[0];
if (iconHtml === $el.children()[0]) {
// another check for robustness
icon = $(iconHtml).prop("outerHTML");
}
}
await renderContent(labelContainer, data.label);
// update the requested properties
if (hasDefinedProperty(data, "label")) {
label = data.label;
}
if (hasDefinedProperty(data, "icon")) {
// `data.icon` can be an [] if user gave `character(0)`.
icon = Array.isArray(data.icon) ? "" : data.icon ?? "";
}
// produce new html
$el.html(icon + " " + label);
}
if (hasDefinedProperty(data, "disabled")) {
if (data.disabled) {
el.setAttribute("disabled", "");
$el.attr("disabled", "");
} else {
el.removeAttribute("disabled");
$el.attr("disabled", null);
}
}
}

View File

@@ -1,16 +1,11 @@
import $ from "jquery";
import type { HtmlDep } from "../../shiny/render";
import { renderContent } from "../../shiny/render";
import { hasDefinedProperty } from "../../utils";
import { InputBinding } from "./inputBinding";
type CheckedHTMLElement = HTMLInputElement;
type CheckboxChecked = CheckedHTMLElement["checked"];
type CheckboxReceiveMessageData = {
value?: CheckboxChecked;
label?: { html: string; deps: HtmlDep[] };
};
type CheckboxReceiveMessageData = { value?: CheckboxChecked; label?: string };
class CheckboxInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
@@ -37,10 +32,10 @@ class CheckboxInputBinding extends InputBinding {
value: el.checked,
};
}
async receiveMessage(
receiveMessage(
el: CheckedHTMLElement,
data: CheckboxReceiveMessageData
): Promise<void> {
): void {
if (hasDefinedProperty(data, "value")) {
el.checked = data.value;
}
@@ -48,8 +43,7 @@ class CheckboxInputBinding extends InputBinding {
// checkboxInput()'s label works different from other
// input labels...the label container should always exist
if (hasDefinedProperty(data, "label")) {
const labelSpan = $(el).parent().find("span");
await renderContent(labelSpan, data.label);
$(el).parent().find("span").text(data.label);
}
$(el).trigger("change");

View File

@@ -113,10 +113,10 @@ class CheckboxGroupInputBinding extends InputBinding {
options: options,
};
}
async receiveMessage(
receiveMessage(
el: CheckboxGroupHTMLElement,
data: CheckboxGroupReceiveMessageData
): Promise<void> {
): void {
const $el = $(el);
// This will replace all the options
@@ -132,7 +132,7 @@ class CheckboxGroupInputBinding extends InputBinding {
this.setValue(el, data.value);
}
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
$(el).trigger("change");
}

View File

@@ -292,13 +292,10 @@ class DateInputBinding extends DateInputBindingBase {
startview: startview,
};
}
async receiveMessage(
el: HTMLElement,
data: DateReceiveMessageData
): Promise<void> {
receiveMessage(el: HTMLElement, data: DateReceiveMessageData): void {
const $input = $(el).find("input");
await updateLabel(data.label, this._getLabelNode(el));
updateLabel(data.label, this._getLabelNode(el));
if (hasDefinedProperty(data, "min")) this._setMin($input[0], data.min);

View File

@@ -106,16 +106,13 @@ class DateRangeInputBinding extends DateInputBindingBase {
startview: startview,
};
}
async receiveMessage(
el: HTMLElement,
data: DateRangeReceiveMessageData
): Promise<void> {
receiveMessage(el: HTMLElement, data: DateRangeReceiveMessageData): void {
const $el = $(el);
const $inputs = $el.find("input");
const $startinput = $inputs.eq(0);
const $endinput = $inputs.eq(1);
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
if (hasDefinedProperty(data, "min")) {
this._setMin($startinput[0], data.min);

View File

@@ -2,21 +2,6 @@ import type { EventPriority } from "../../inputPolicies/inputPolicy";
import type { RatePolicyModes } from "../../inputPolicies/inputRateDecorator";
import type { BindScope } from "../../shiny/bind";
type SubscribeEventPriority =
| EventPriority
| boolean
| { priority: EventPriority };
// Historically, the .subscribe()'s callback value only took a boolean. In this
// case:
// * false: send value immediately (i.e., priority = "immediate")
// * true: send value later (i.e., priority = "deferred")
// * The input rate policy is also consulted on whether to debounce or
// throttle
// In recent versions, the value can also be "event", meaning that the
// value should be sent immediately regardless of whether it has changed.
type InputSubscribeCallback = (value: SubscribeEventPriority) => void;
class InputBinding {
name!: string;
@@ -42,7 +27,16 @@ class InputBinding {
el; // unused var
}
subscribe(el: HTMLElement, callback: InputSubscribeCallback): void {
// Historically, the callback value could only be boolean. In this case:
// * false: send value immediately (i.e., priority = "immediate")
// * true: send value later (i.e., priority = "deferred")
// * The input rate policy is also consulted on whether to debounce or throttle
// In recent versions, the value can also be "event", meaning that the
// value should be sent regardless of whether it has changed.
subscribe(
el: HTMLElement,
callback: (value: EventPriority | boolean) => void
): void {
// empty
el; // unused var
callback; // unused var
@@ -115,4 +109,3 @@ class InputBinding {
//// END NOTES FOR FUTURE DEV
export { InputBinding };
export type { InputSubscribeCallback, SubscribeEventPriority };

View File

@@ -51,10 +51,7 @@ class NumberInputBinding extends TextInputBindingBase {
return "shiny.number";
el;
}
async receiveMessage(
el: NumberHTMLElement,
data: NumberReceiveMessageData
): Promise<void> {
receiveMessage(el: NumberHTMLElement, data: NumberReceiveMessageData): void {
// Setting values to `""` will remove the attribute value from the DOM element.
// The attr key will still remain, but there is not value... ex: `<input id="foo" type="number" min max/>`
if (hasDefinedProperty(data, "value")) el.value = data.value ?? "";
@@ -62,7 +59,7 @@ class NumberInputBinding extends TextInputBindingBase {
if (hasDefinedProperty(data, "max")) el.max = data.max ?? "";
if (hasDefinedProperty(data, "step")) el.step = data.step ?? "";
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
$(el).trigger("change");
}

View File

@@ -103,10 +103,7 @@ class RadioInputBinding extends InputBinding {
options: options,
};
}
async receiveMessage(
el: RadioHTMLElement,
data: RadioReceiveMessageData
): Promise<void> {
receiveMessage(el: RadioHTMLElement, data: RadioReceiveMessageData): void {
const $el = $(el);
// This will replace all the options
@@ -125,7 +122,7 @@ class RadioInputBinding extends InputBinding {
this.setValue(el, data.value);
}
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
$(el).trigger("change");
}

View File

@@ -102,10 +102,10 @@ class SelectInputBinding extends InputBinding {
options: options,
};
}
async receiveMessage(
receiveMessage(
el: SelectHTMLElement,
data: SelectInputReceiveMessageData
): Promise<void> {
): void {
const $el = $(el);
// This will replace all the options
@@ -205,7 +205,7 @@ class SelectInputBinding extends InputBinding {
this.setValue(el, data.value);
}
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
$(el).trigger("change");
}

View File

@@ -179,10 +179,7 @@ class SliderInputBinding extends TextInputBindingBase {
unsubscribe(el: HTMLElement): void {
$(el).off(".sliderInputBinding");
}
async receiveMessage(
el: HTMLElement,
data: SliderReceiveMessageData
): Promise<void> {
receiveMessage(el: HTMLElement, data: SliderReceiveMessageData): void {
const $el = $(el);
const slider = $el.data("ionRangeSlider");
const msg: {
@@ -229,7 +226,7 @@ class SliderInputBinding extends TextInputBindingBase {
}
}
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
// (maybe) update data elements
const domElements: Array<"data-type" | "time-format" | "timezone"> = [

View File

@@ -1,6 +1,7 @@
import $ from "jquery";
import { $escape, hasDefinedProperty, updateLabel } from "../../utils";
import type { EventPriority } from "../../inputPolicies/inputPolicy";
import { InputBinding } from "./inputBinding";
// interface TextHTMLElement extends NameValueHTMLElement {
@@ -49,7 +50,10 @@ class TextInputBindingBase extends InputBinding {
value;
}
subscribe(el: TextHTMLElement, callback: (x: boolean) => void): void {
subscribe(
el: TextHTMLElement,
callback: (x: EventPriority | boolean) => void
): void {
const $el = $(el);
const updateOn = $el.data("update-on") || "change";
@@ -126,13 +130,10 @@ class TextInputBinding extends TextInputBindingBase {
placeholder: el.placeholder,
};
}
async receiveMessage(
el: TextHTMLElement,
data: TextReceiveMessageData
): Promise<void> {
receiveMessage(el: TextHTMLElement, data: TextReceiveMessageData): void {
if (hasDefinedProperty(data, "value")) this.setValue(el, data.value);
await updateLabel(data.label, getLabelNode(el));
updateLabel(data.label, getLabelNode(el));
if (hasDefinedProperty(data, "placeholder"))
el.placeholder = data.placeholder;

View File

@@ -2,53 +2,96 @@ import $ from "jquery";
import { TextInputBinding } from "./text";
// When a textarea becomes visible, update the height
const intersectObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
updateHeight(entry.target as HTMLInputElement);
}
});
});
class TextareaInputBinding extends TextInputBinding {
#inputHandler: EventListener | null = null;
export class TextareaInputBinding extends TextInputBinding {
find(scope: HTMLElement): JQuery<HTMLElement> {
// Inputs now also have the .shiny-input-textarea class
return $(scope).find("textarea");
}
}
initialize(el: HTMLInputElement): void {
super.initialize(el);
updateHeight(el);
/*************************************************************
* Code below this point is for textAreaInput(autoresize=TRUE)
************************************************************/
interface DOMEvent<T extends EventTarget> extends Event {
readonly target: T;
}
function onDelegatedEvent(
eventName: string,
selector: string,
callback: (target: HTMLTextAreaElement) => void
) {
document.addEventListener(eventName, (e) => {
const e2 = e as DOMEvent<HTMLTextAreaElement>;
if (e2.target.matches(selector)) {
callback(e2.target);
}
});
}
// Use a single intersectionObserver as they are slow to create / use.
let textAreaIntersectionObserver: IntersectionObserver | null = null;
function callUpdateHeightWhenTargetIsVisible(target: HTMLTextAreaElement) {
if (textAreaIntersectionObserver === null) {
// Create a single observer to watch for the textarea becoming visible
textAreaIntersectionObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
// Quit if the entry is not visible
if (!entry.isIntersecting) {
return;
}
// If the entry is visible (even if it's just a single pixel)
// Stop observing the target
textAreaIntersectionObserver?.unobserve(entry.target);
// Update the height of the textarea
updateHeight(entry.target as HTMLTextAreaElement);
});
});
}
subscribe(el: HTMLInputElement, callback: (x: boolean) => void): void {
super.subscribe(el, callback);
textAreaIntersectionObserver.observe(target);
}
this.#inputHandler = (e) => updateHeight(e.target as HTMLInputElement);
el.addEventListener("input", this.#inputHandler);
intersectObserver.observe(el);
}
function updateHeight(target: HTMLTextAreaElement) {
if (target.scrollHeight > 0) {
// Automatically resize the textarea to fit its content.
target.style.height = "auto";
target.style.height = target.scrollHeight + "px";
} else {
// The textarea is not visible on the page, therefore it has a 0 scroll height.
unsubscribe(el: HTMLInputElement): void {
super.unsubscribe(el);
if (this.#inputHandler) el.removeEventListener("input", this.#inputHandler);
intersectObserver.unobserve(el);
// If we should autoresize the text area height, then we can wait for the textarea to
// become visible and call `updateHeight` again. Hopefully the scroll height is no
// longer 0
callUpdateHeightWhenTargetIsVisible(target);
}
}
function updateHeight(el: HTMLInputElement) {
if (!el.classList.contains("textarea-autoresize")) {
// Update on change
onDelegatedEvent(
"input",
"textarea.textarea-autoresize",
(target: HTMLTextAreaElement) => {
updateHeight(target);
}
);
// Update on load
function updateOnLoad() {
if (document.readyState === "loading") {
// Document still loading, wait 10ms to check again.
setTimeout(updateOnLoad, 10);
return;
}
if (el.scrollHeight == 0) {
return;
}
el.style.height = "auto";
el.style.height = el.scrollHeight + "px";
// document.readyState in ["interactive", "complete"];\
const textAreas = document.querySelectorAll(
"textarea.textarea-autoresize"
) as NodeListOf<HTMLTextAreaElement>;
textAreas.forEach(updateHeight);
}
export { TextareaInputBinding };
updateOnLoad();

View File

@@ -1,7 +1,6 @@
import $ from "jquery";
import { Shiny } from "..";
import type { InputBinding, OutputBinding } from "../bindings";
import type { SubscribeEventPriority } from "../bindings/input/inputBinding";
import { OutputBindingAdapter } from "../bindings/outputAdapter";
import type { BindingRegistry } from "../bindings/registry";
import { ShinyClientMessageEvent } from "../components/errorConsole";
@@ -9,7 +8,7 @@ import type {
InputRateDecorator,
InputValidateDecorator,
} from "../inputPolicies";
import type { EventPriority } from "../inputPolicies/inputPolicy";
import type { InputPolicyOpts } from "../inputPolicies/inputPolicy";
import { shinyAppBindOutput, shinyAppUnbindOutput } from "./initedMethods";
import { sendImageSizeFns } from "./sendImageSize";
@@ -29,7 +28,7 @@ function valueChangeCallback(
inputs: InputValidateDecorator,
binding: InputBinding,
el: HTMLElement,
priority?: SubscribeEventPriority
priority: InputPolicyOpts["priority"]
) {
let id = binding.getId(el);
@@ -39,32 +38,10 @@ function valueChangeCallback(
if (type) id = id + ":" + type;
// Normalize the priority to a valid EventPriority
const normalizedPriority = normalizeEventPriority(priority);
inputs.setInput(id, value, { priority: normalizedPriority, binding, el });
inputs.setInput(id, value, { priority, binding, el });
}
}
// Narrow the type of the subscribe callback value to EventPriority
function normalizeEventPriority(
priority?: SubscribeEventPriority
): EventPriority {
if (priority === false || priority === undefined) {
return "immediate";
}
if (priority === true) {
return "deferred";
}
if (typeof priority === "object" && "priority" in priority) {
return priority.priority;
}
return priority;
}
/**
* Registry for input and output binding IDs. Used to check for duplicate IDs
* and to keep track of which IDs have already been added to the app. Use an
@@ -286,8 +263,17 @@ function bindInputs(
const thisBinding = binding;
const thisEl = el;
return function (priority?: SubscribeEventPriority) {
valueChangeCallback(inputs, thisBinding, thisEl, priority);
// Historically speaking, this callback has only accepted a boolean value,
// but in recent versions it can also accept a input priority.
return function (priority: InputPolicyOpts["priority"] | boolean) {
const normalizedPriority =
typeof priority !== "boolean"
? priority
: priority
? "deferred"
: "immediate";
valueChangeCallback(inputs, thisBinding, thisEl, normalizedPriority);
};
})();

View File

@@ -82,7 +82,7 @@ class ShinyClass {
addCustomMessageHandler: typeof addCustomMessageHandler;
// The following are added in the initialization, by initShiny()
createSocket?: () => Promise<WebSocket>;
createSocket?: () => WebSocket;
user?: string;
progressHandlers?: ShinyApp["progressHandlers"];
shinyapp?: ShinyApp;
@@ -177,11 +177,11 @@ class ShinyClass {
let target: InputPolicy;
if (document.querySelector(".shiny-submit-button")) {
if (document.querySelector(".submit-button")) {
// If there is a submit button on the page, use defer decorator
target = inputsDefer;
document.querySelectorAll(".shiny-submit-button").forEach(function (x) {
document.querySelectorAll(".submit-button").forEach(function (x) {
x.addEventListener("click", function (event) {
event.preventDefault();
inputsDefer.submit();
@@ -669,7 +669,7 @@ class ShinyClass {
// We've collected all the initial values--start the server process!
inputsNoResend.reset(initialValues);
await shinyapp.connect(initialValues);
shinyapp.connect(initialValues);
$(document).one("shiny:connected", () => {
initDeferredIframes();
});

View File

@@ -92,7 +92,7 @@ function setFileInputBinding(fileInputBinding_: FileInputBinding): void {
fileInputBinding = fileInputBinding_;
}
function getShinyCreateWebsocket(): (() => Promise<WebSocket>) | void {
function getShinyCreateWebsocket(): (() => WebSocket) | void {
return validateShinyHasBeenSet().createSocket;
}

View File

@@ -159,11 +159,11 @@ class ShinyApp {
this._init();
}
async connect(initialInput: InputValues): Promise<void> {
connect(initialInput: InputValues): void {
if (this.$socket)
throw "Connect was already called on this application object";
this.$socket = await this.createSocket();
this.$socket = this.createSocket();
this.$initialInput = initialInput;
$.extend(this.$inputValues, initialInput);
@@ -176,7 +176,7 @@ class ShinyApp {
private scheduledReconnect: number | undefined = undefined;
async reconnect(): Promise<void> {
reconnect(): void {
// This function can be invoked directly even if there's a scheduled
// reconnect, so be sure to clear any such scheduled reconnects.
clearTimeout(this.scheduledReconnect);
@@ -184,15 +184,15 @@ class ShinyApp {
if (this.isConnected())
throw "Attempted to reconnect, but already connected.";
this.$socket = await this.createSocket();
this.$socket = this.createSocket();
this.$initialInput = $.extend({}, this.$inputValues);
this.$updateConditionals();
}
async createSocket(): Promise<ShinyWebSocket> {
const createSocketFunc: () => Promise<ShinyWebSocket> =
createSocket(): ShinyWebSocket {
const createSocketFunc: () => ShinyWebSocket =
getShinyCreateWebsocket() ||
(async () => {
(() => {
let protocol = "ws:";
if (window.location.protocol === "https:") protocol = "wss:";
@@ -211,12 +211,6 @@ class ShinyApp {
if (!/\/$/.test(defaultPath)) defaultPath += "/";
defaultPath += "websocket/";
const sessionId = await this.$getSessionId();
if (sessionId) {
defaultPath += "?session_id=" + sessionId;
}
// Fail gracefully if the server does not support this endpoint
const ws: ShinyWebSocket = new WebSocket(
protocol + "//" + window.location.host + defaultPath
);
@@ -226,7 +220,7 @@ class ShinyApp {
return ws;
});
const socket = await createSocketFunc();
const socket = createSocketFunc();
let hasOpened = false;
socket.onopen = () => {
@@ -283,39 +277,6 @@ class ShinyApp {
return socket;
}
async $getSessionId(): Promise<string | null> {
// If the session ID has been received through a websocket message,
// no need to create a new one.
if (this.config) {
return this.config.sessionId;
}
// Fetch this client's session ID from the server. When successful, the
// server will require a (valid) session ID when establishing a websocket
// connection.
try {
const response = await fetch("/new_shiny_session/");
if (response.ok) {
const data = await response.json();
return data.session_id;
}
// If the endpoint doesn't exist, then a session ID isn't required
// to establish a websocket connection.
if (response.status === 404) {
return null;
}
// If other problems happen, we probably want to know about it.
console.error("Error fetching session ID:", response);
return null;
} catch (error) {
console.error("Error fetching session ID:", error);
return null;
}
}
async startActionQueueLoop(): Promise<void> {
// eslint-disable-next-line no-constant-condition
while (true) {
@@ -353,8 +314,8 @@ class ShinyApp {
}
$scheduleReconnect(delay: Parameters<typeof setTimeout>[1]): void {
this.scheduledReconnect = window.setTimeout(async () => {
await this.reconnect();
this.scheduledReconnect = window.setTimeout(() => {
this.reconnect();
}, delay);
}

View File

@@ -1,6 +1,4 @@
import $ from "jquery";
import type { HtmlDep } from "../shiny/render";
import { renderContent } from "../shiny/render";
import { windowDevicePixelRatio } from "../window/pixelRatio";
import type { MapValuesUnion, MapWithResult } from "./extraTypes";
import { hasDefinedProperty, hasOwnProperty } from "./object";
@@ -353,27 +351,23 @@ const compareVersion = function (
else throw `Unknown operator: ${op}`;
};
async function updateLabel(
labelContent: string | { html: string; deps: HtmlDep[] } | undefined,
function updateLabel(
labelTxt: string | undefined,
labelNode: JQuery<HTMLElement>
): Promise<void> {
): void {
// Only update if label was specified in the update method
if (typeof labelContent === "undefined") return;
if (typeof labelTxt === "undefined") return;
if (labelNode.length !== 1) {
throw new Error("labelNode must be of length 1");
}
if (typeof labelContent === "string") {
labelContent = {
html: labelContent,
deps: [],
};
}
// Should the label be empty?
const emptyLabel = Array.isArray(labelTxt) && labelTxt.length === 0;
if (labelContent.html === "") {
if (emptyLabel) {
labelNode.addClass("shiny-label-null");
} else {
await renderContent(labelNode, labelContent);
labelNode.text(labelTxt);
labelNode.removeClass("shiny-label-null");
}
}

View File

@@ -1,14 +1,7 @@
import type { HtmlDep } from "../../shiny/render";
import { InputBinding } from "./inputBinding";
type ActionButtonReceiveMessageData = {
label?: {
html: string;
deps: HtmlDep[];
};
icon?: {
html: string;
deps: HtmlDep[];
};
label?: string;
icon?: string | [];
disabled?: boolean;
};
declare class ActionButtonInputBinding extends InputBinding {
@@ -20,7 +13,7 @@ declare class ActionButtonInputBinding extends InputBinding {
getState(el: HTMLElement): {
value: number;
};
receiveMessage(el: HTMLElement, data: ActionButtonReceiveMessageData): Promise<void>;
receiveMessage(el: HTMLElement, data: ActionButtonReceiveMessageData): void;
unsubscribe(el: HTMLElement): void;
}
export { ActionButtonInputBinding };

View File

@@ -1,13 +1,9 @@
import type { HtmlDep } from "../../shiny/render";
import { InputBinding } from "./inputBinding";
type CheckedHTMLElement = HTMLInputElement;
type CheckboxChecked = CheckedHTMLElement["checked"];
type CheckboxReceiveMessageData = {
value?: CheckboxChecked;
label?: {
html: string;
deps: HtmlDep[];
};
label?: string;
};
declare class CheckboxInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement>;
@@ -19,7 +15,7 @@ declare class CheckboxInputBinding extends InputBinding {
label: string;
value: CheckboxChecked;
};
receiveMessage(el: CheckedHTMLElement, data: CheckboxReceiveMessageData): Promise<void>;
receiveMessage(el: CheckedHTMLElement, data: CheckboxReceiveMessageData): void;
}
export { CheckboxInputBinding };
export type { CheckedHTMLElement, CheckboxReceiveMessageData };

View File

@@ -20,7 +20,7 @@ declare class CheckboxGroupInputBinding extends InputBinding {
value: ReturnType<CheckboxGroupInputBinding["getValue"]>;
options: ValueLabelObject[];
};
receiveMessage(el: CheckboxGroupHTMLElement, data: CheckboxGroupReceiveMessageData): Promise<void>;
receiveMessage(el: CheckboxGroupHTMLElement, data: CheckboxGroupReceiveMessageData): void;
subscribe(el: CheckboxGroupHTMLElement, callback: (x: boolean) => void): void;
unsubscribe(el: CheckboxGroupHTMLElement): void;
}

View File

@@ -52,7 +52,7 @@ declare class DateInputBinding extends DateInputBindingBase {
format: string;
startview: DatepickerViewModes;
};
receiveMessage(el: HTMLElement, data: DateReceiveMessageData): Promise<void>;
receiveMessage(el: HTMLElement, data: DateReceiveMessageData): void;
}
export { DateInputBinding, DateInputBindingBase };
export type { DateReceiveMessageData };

View File

@@ -27,7 +27,7 @@ declare class DateRangeInputBinding extends DateInputBindingBase {
language: string;
startview: string;
};
receiveMessage(el: HTMLElement, data: DateRangeReceiveMessageData): Promise<void>;
receiveMessage(el: HTMLElement, data: DateRangeReceiveMessageData): void;
initialize(el: HTMLElement): void;
subscribe(el: HTMLElement, callback: (x: boolean) => void): void;
unsubscribe(el: HTMLElement): void;

View File

@@ -1,17 +1,13 @@
import type { EventPriority } from "../../inputPolicies/inputPolicy";
import type { RatePolicyModes } from "../../inputPolicies/inputRateDecorator";
import type { BindScope } from "../../shiny/bind";
type SubscribeEventPriority = EventPriority | boolean | {
priority: EventPriority;
};
type InputSubscribeCallback = (value: SubscribeEventPriority) => void;
declare class InputBinding {
name: string;
find(scope: BindScope): JQuery<HTMLElement>;
getId(el: HTMLElement): string;
getType(el: HTMLElement): string | null;
getValue(el: HTMLElement): any;
subscribe(el: HTMLElement, callback: InputSubscribeCallback): void;
subscribe(el: HTMLElement, callback: (value: EventPriority | boolean) => void): void;
unsubscribe(el: HTMLElement): void;
receiveMessage(el: HTMLElement, data: unknown): Promise<void> | void;
getState(el: HTMLElement): unknown;
@@ -23,4 +19,3 @@ declare class InputBinding {
dispose(el: HTMLElement): void;
}
export { InputBinding };
export type { InputSubscribeCallback, SubscribeEventPriority };

View File

@@ -12,7 +12,7 @@ declare class NumberInputBinding extends TextInputBindingBase {
getValue(el: NumberHTMLElement): string[] | number | string | null | undefined;
setValue(el: NumberHTMLElement, value: number): void;
getType(el: NumberHTMLElement): string;
receiveMessage(el: NumberHTMLElement, data: NumberReceiveMessageData): Promise<void>;
receiveMessage(el: NumberHTMLElement, data: NumberReceiveMessageData): void;
getState(el: NumberHTMLElement): {
label: string;
value: ReturnType<NumberInputBinding["getValue"]>;

View File

@@ -18,7 +18,7 @@ declare class RadioInputBinding extends InputBinding {
value: ReturnType<RadioInputBinding["getValue"]>;
options: ValueLabelObject[];
};
receiveMessage(el: RadioHTMLElement, data: RadioReceiveMessageData): Promise<void>;
receiveMessage(el: RadioHTMLElement, data: RadioReceiveMessageData): void;
subscribe(el: RadioHTMLElement, callback: (x: boolean) => void): void;
unsubscribe(el: RadioHTMLElement): void;
}

View File

@@ -28,7 +28,7 @@ declare class SelectInputBinding extends InputBinding {
label: string;
}>;
};
receiveMessage(el: SelectHTMLElement, data: SelectInputReceiveMessageData): Promise<void>;
receiveMessage(el: SelectHTMLElement, data: SelectInputReceiveMessageData): void;
subscribe(el: SelectHTMLElement, callback: (x: boolean) => void): void;
unsubscribe(el: HTMLElement): void;
initialize(el: SelectHTMLElement): void;

View File

@@ -26,7 +26,7 @@ declare class SliderInputBinding extends TextInputBindingBase {
setValue(el: HTMLElement, value: number | string | [number | string, number | string]): void;
subscribe(el: HTMLElement, callback: (x: boolean) => void): void;
unsubscribe(el: HTMLElement): void;
receiveMessage(el: HTMLElement, data: SliderReceiveMessageData): Promise<void>;
receiveMessage(el: HTMLElement, data: SliderReceiveMessageData): void;
getRatePolicy(el: HTMLElement): {
policy: "debounce";
delay: 250;

View File

@@ -1,3 +1,4 @@
import type { EventPriority } from "../../inputPolicies/inputPolicy";
import { InputBinding } from "./inputBinding";
type TextHTMLElement = HTMLInputElement;
type TextReceiveMessageData = {
@@ -10,7 +11,7 @@ declare class TextInputBindingBase extends InputBinding {
getId(el: TextHTMLElement): string;
getValue(el: TextHTMLElement): unknown;
setValue(el: TextHTMLElement, value: unknown): void;
subscribe(el: TextHTMLElement, callback: (x: boolean) => void): void;
subscribe(el: TextHTMLElement, callback: (x: EventPriority | boolean) => void): void;
unsubscribe(el: TextHTMLElement): void;
receiveMessage(el: TextHTMLElement, data: unknown): void;
getState(el: TextHTMLElement): unknown;
@@ -27,7 +28,7 @@ declare class TextInputBinding extends TextInputBindingBase {
value: string;
placeholder: string;
};
receiveMessage(el: TextHTMLElement, data: TextReceiveMessageData): Promise<void>;
receiveMessage(el: TextHTMLElement, data: TextReceiveMessageData): void;
}
export { TextInputBinding, TextInputBindingBase };
export type { TextHTMLElement, TextReceiveMessageData };

View File

@@ -1,9 +1,4 @@
import { TextInputBinding } from "./text";
declare class TextareaInputBinding extends TextInputBinding {
#private;
export declare class TextareaInputBinding extends TextInputBinding {
find(scope: HTMLElement): JQuery<HTMLElement>;
initialize(el: HTMLInputElement): void;
subscribe(el: HTMLInputElement, callback: (x: boolean) => void): void;
unsubscribe(el: HTMLInputElement): void;
}
export { TextareaInputBinding };

View File

@@ -0,0 +1,18 @@
import type { EventPriority } from "../../inputPolicies/inputPolicy";
import { InputBinding } from "./inputBinding";
type TextHTMLElement = HTMLInputElement;
type TextSubmitReceiveMessageData = {
value?: string;
placeholder?: string;
submit?: boolean;
focus?: boolean;
};
declare class TextSubmitInputBinding extends InputBinding {
find(scope: HTMLElement): JQuery<HTMLElement>;
getValue(el: TextHTMLElement): string;
setValue(el: TextHTMLElement, value: string): void;
subscribe(el: TextHTMLElement, callback: (x: EventPriority | boolean) => void): void;
unsubscribe(el: HTMLElement): void;
receiveMessage(el: TextHTMLElement, data: TextSubmitReceiveMessageData): void;
}
export { TextSubmitInputBinding };

View File

@@ -35,7 +35,7 @@ declare class ShinyClass {
renderHtmlAsync: typeof renderHtmlAsync;
renderHtml: typeof renderHtml;
addCustomMessageHandler: typeof addCustomMessageHandler;
createSocket?: () => Promise<WebSocket>;
createSocket?: () => WebSocket;
user?: string;
progressHandlers?: ShinyApp["progressHandlers"];
shinyapp?: ShinyApp;

View File

@@ -19,5 +19,5 @@ declare function shinyAppUnbindOutput(id: string, binding: OutputBindingAdapter)
declare function getShinyOnCustomMessage(): Handler | null;
declare function getFileInputBinding(): FileInputBinding;
declare function setFileInputBinding(fileInputBinding_: FileInputBinding): void;
declare function getShinyCreateWebsocket(): (() => Promise<WebSocket>) | void;
declare function getShinyCreateWebsocket(): (() => WebSocket) | void;
export { setShinyObj, shinySetInputValue, shinyShinyApp, setShinyUser, shinyForgetLastInputValue, shinyBindAll, shinyUnbindAll, shinyInitializeInputs, shinyAppBindOutput, shinyAppUnbindOutput, getShinyOnCustomMessage, getFileInputBinding, setFileInputBinding, getShinyCreateWebsocket, };

View File

@@ -52,12 +52,11 @@ declare class ShinyApp {
$nextRequestId: number;
$allowReconnect: boolean | "force";
constructor();
connect(initialInput: InputValues): Promise<void>;
connect(initialInput: InputValues): void;
isConnected(): boolean;
private scheduledReconnect;
reconnect(): Promise<void>;
createSocket(): Promise<ShinyWebSocket>;
$getSessionId(): Promise<string | null>;
reconnect(): void;
createSocket(): ShinyWebSocket;
startActionQueueLoop(): Promise<void>;
sendInput(values: InputValues): void;
$notifyDisconnected(): void;

View File

@@ -1,4 +1,3 @@
import type { HtmlDep } from "../shiny/render";
import type { MapValuesUnion, MapWithResult } from "./extraTypes";
import { hasDefinedProperty, hasOwnProperty } from "./object";
declare function escapeHTML(str: string): string;
@@ -27,10 +26,7 @@ declare function isnan(x: unknown): boolean;
declare function _equal(x: unknown, y: unknown): boolean;
declare function equal(...args: unknown[]): boolean;
declare const compareVersion: (a: string, op: "<" | "<=" | "==" | ">" | ">=", b: string) => boolean;
declare function updateLabel(labelContent: string | {
html: string;
deps: HtmlDep[];
} | undefined, labelNode: JQuery<HTMLElement>): Promise<void>;
declare function updateLabel(labelTxt: string | undefined, labelNode: JQuery<HTMLElement>): void;
declare function getComputedLinkColor(el: HTMLElement): string;
declare function isBS3(): boolean;
declare function toLowerCase<T extends string>(str: T): Lowercase<T>;

View File

@@ -1,21 +0,0 @@
# Action button allows icon customization
Code
actionButton("foo", "Click me")
Output
<button id="foo" type="button" class="btn btn-default action-button">
<span class="action-label">Click me</span>
</button>
---
Code
actionButton("foo", "Click me", icon = icon("star"))
Output
<button id="foo" type="button" class="btn btn-default action-button">
<span class="action-icon">
<i class="far fa-star" role="presentation" aria-label="star icon"></i>
</span>
<span class="action-label">Click me</span>
</button>

View File

@@ -55,42 +55,3 @@ test_that("Action link accepts class arguments", {
get_class(make_link("extra extra2")), sub("\"$", " extra extra2\"", act_class)
)
})
test_that("Action button allows icon customization", {
# No separator between icon and label
expect_snapshot(actionButton("foo", "Click me"))
# Should include separator between icon and label
expect_snapshot(
actionButton("foo", "Click me", icon = icon("star"))
)
# Warn on a non-HTML icon
expect_warning(
actionButton("foo", "Click me", icon = "not an icon"),
"non-HTML value was provided"
)
# Allows for arbitrary HTML as icon
btn <- expect_no_warning(
actionButton("foo", "Click me", icon = tags$svg())
)
btn2 <- expect_no_warning(
actionButton("foo", "Click me", icon = tagList(tags$svg()))
)
btn3 <- expect_no_warning(
actionButton("foo", "Click me", icon = list(tags$svg()))
)
btn4 <- expect_no_warning(
actionButton("foo", "Click me", icon = HTML("<svg></svg>"))
)
# Ignore newlines+indentation for comparison
as_character <- function(x) {
gsub("\\n\\s*", "", as.character(x))
}
expect_equal(as_character(btn), as_character(btn2))
expect_equal(as_character(btn2), as_character(btn3))
expect_equal(as_character(btn3), as_character(btn4))
})

View File

@@ -6,9 +6,7 @@ sortList <- function(x) {
}
# This will create print.ggplot in the current environment
# print.ggplot is for ggplot2 < 4.0.0
# print.ggplot2::ggplot is for ggplot2 >= 4.0.0
print.ggplot <- `print.ggplot2::ggplot` <- custom_print.ggplot
print.ggplot <- custom_print.ggplot
test_that("ggplot coordmap", {

View File

@@ -1307,7 +1307,7 @@ for (do_priming in c(TRUE, FALSE)) {
# dr should've fired, and we should have converged on the right answer.
expect_identical(dr_fired, 2)
isolate(expect_identical(rv$a, dr()))
# be sure tr() converged on the right answer; (We've already confirmed throttle-like behavior above)
expect_identical(tr_fired, 4)
isolate(expect_identical(rv$a, tr()))
})
}

View File

@@ -16,19 +16,18 @@ test_that("Radio buttons and checkboxes work with modules", {
resultA <- sessA$lastInputMessage
expect_equal(resultA$id, "test1")
expect_equal(as.character(resultA$message$label$html), "Label")
expect_equal(resultA$message$label, "Label")
expect_equal(resultA$message$value, "a")
expect_match(resultA$message$options, '"modA-test1"')
expect_no_match(resultA$message$options, '"test1"')
sessB <- createModuleSession("modB")
updateCheckboxGroupInput(sessB, "test2", label = icon("eye"), choices = LETTERS[1:5])
updateCheckboxGroupInput(sessB, "test2", label = "Label", choices = LETTERS[1:5])
resultB <- sessB$lastInputMessage
expect_equal(resultB$id, "test2")
expect_length(resultB$message$label, 2)
expect_s3_class(resultB$message$label$html, "html")
expect_equal(resultB$message$label, "Label")
expect_null(resultB$message$value)
expect_match(resultB$message$options, '"modB-test2"')
expect_no_match(resultB$message$options, '"test2"')

View File

@@ -1,7 +1,7 @@
library(magrittr)
version <- "3.7.1"
version_types <- "3.5.29"
version <- "3.6.0"
version_types <- "3.5.14"
jq_cdn_download <- function(version) {
Map(

View File

@@ -1,4 +1,4 @@
version <- "1.14.1"
version <- "1.13.2"
version_types <- "1.12.16"
jqui_folder <- rprojroot::find_package_root_file("inst", "www", "shared", "jqueryui")

View File

@@ -1211,21 +1211,21 @@ __metadata:
languageName: node
linkType: hard
"@types/jquery@npm:3.5.32":
version: 3.5.32
resolution: "@types/jquery@npm:3.5.32"
"@types/jquery@npm:3.5.14":
version: 3.5.14
resolution: "@types/jquery@npm:3.5.14"
dependencies:
"@types/sizzle": "*"
checksum: 7fe7251bda3fc9d80417ef7c88ad963ccb591706bca2fb84ea5d9600498a8f9911c32302f28fd1910bb212c34193f38f63818757a9833b70e1f46c3a98a17625
checksum: 159d6f804ed1a204b3f79f2d591a271d82e866bd45bd49fb6ef40561a25dbe0f47ec7815681b44cc2db5598425f72811e7e80ab0e983d980470998ac56feb375
languageName: node
linkType: hard
"@types/jqueryui@npm:1.12.24":
version: 1.12.24
resolution: "@types/jqueryui@npm:1.12.24"
"@types/jqueryui@npm:1.12.16":
version: 1.12.16
resolution: "@types/jqueryui@npm:1.12.16"
dependencies:
"@types/jquery": "*"
checksum: 4bb147b591753f873f011cc591ef371d7ba8792fc2742f87cd96a7896ad817903a0e62863b5c6fd72a4036318877d3eb51573ee96ff70819fe3ad7f73fb805ec
checksum: a39a2b5c26a2b1341f50af49957b17a36423bdd6300c2a9188b1adc0d263f3e31255e8f2f77ffd59f750ede6cc713c84c9c88cdc6d43fa7d88949a40679f8a5e
languageName: node
linkType: hard
@@ -1286,8 +1286,8 @@ __metadata:
"@types/highlightjs": ^9.12.1
"@types/ion-rangeslider": 2.3.0
"@types/jest": ^26.0.23
"@types/jquery": 3.5.32
"@types/jqueryui": 1.12.24
"@types/jquery": 3.5.14
"@types/jqueryui": 1.12.16
"@types/lodash": ^4.14.170
"@types/node": ^18.14.2
"@types/selectize": 0.12.34
@@ -1309,7 +1309,7 @@ __metadata:
eslint-plugin-unicorn: ^43.0.2
fs-readdir-recursive: ^1.1.0
jest: ^26.6.3
jquery: 3.7.1
jquery: ^3.6.0
lit: ^3.0.0
lodash: ^4.17.21
madge: ^4.0.2
@@ -5773,10 +5773,10 @@ __metadata:
languageName: node
linkType: hard
"jquery@npm:3.7.1":
version: 3.7.1
resolution: "jquery@npm:3.7.1"
checksum: 4370b8139d6ae82867eb6f7f21d1edccf1d1bdf41c0840920ea80d366c2cd5dbe1ceebb110ee9772aa839b04400faa1572c5c560b507c688ed7b61cea26c0e27
"jquery@npm:^3.6.0":
version: 3.6.3
resolution: "jquery@npm:3.6.3"
checksum: 0fd366bdcaa0c84a7a8751ce20f8192290141913978b5059574426d9b01f4365daa675f95aab3eec94fd794d27b08d32078a2236bef404b8ba78073009988ce6
languageName: node
linkType: hard