Compare commits

...

68 Commits

Author SHA1 Message Date
Carson
ef5e727473 Follow up to #4276: preserve shinyRemoveButton from previous config (if no new one is specified) 2025-08-29 16:19:29 -05:00
Carson Sievert
f981ed6363 feat: add shinyRemoveButton selectize.js option (for py-shiny) (#4276)
* fix: supply and retain default selectize.js plugins (for py-shiny)

* `npm run build` (GitHub Actions)

* Move more in a 'remove_button' attribute direction

* `npm run build` (GitHub Actions)

* Move to a JSON-only approach

* `npm run build` (GitHub Actions)

* Drop sticky update logic by always sending 'missing' value and resolving client-side

* Cleanup

* Don't mutate options; better typing pattern

* `npm run build` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-08-28 15:49:25 -05:00
Carson Sievert
6d6b0ea6f9 fix: add CSS workaround to hide all but the first selectize remove button (#4275)
* fix: add CSS workaround to hide all but the first selectize remove button

* Update news

* Apply suggestions from code review
2025-08-21 16:48:34 -05:00
Barret Schloerke
0e355ed25c preemptively run revdepcheck. 5 failures. 2025-08-18 09:10:19 -04:00
Barret Schloerke
80a9ff470c fix(scss): Remove updated scss files and restore R sass compilation (#4272)
* Revert changes in 8861645d99 from #4252

We compile from R sass. So we should be partial to R's compiler, no the latest in npm

* Restore original compile script (with message) that built using R-sass, not npm

* Add step in build command to update the sass output

* run new command
2025-08-14 16:03:48 -04:00
Barret Schloerke
ead0abcd62 bug(check): Update .Rbuildignore with new and removed files (#4270) 2025-08-04 23:17:45 -04:00
Barret Schloerke
7dcb54bc7e build(js): Migrate from yarn to npm (#4252) 2025-08-04 16:07:39 -04:00
Colin Gillespie
ae82850e1f docs: Update R supported versions (#4256) 2025-08-04 10:37:48 -04:00
Daniel Chen
0610d756a8 docs: update srcts/readme.md to shiny 1.11.1 (#4259) 2025-08-04 09:50:06 -04:00
Carson Sievert
6325067130 Update DESCRIPTION (#4255)
* Change maintainer to Carson

* Add Garrick

* Add Posit ROR link

* `usethis::use_tidy_description()` (GitHub Actions)

* `devtools::document()` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-07-22 13:19:24 -05:00
Carson Sievert
1a4e52dc73 Run routine (#4257)
* Touch news

* `usethis::use_tidy_description()` (GitHub Actions)

* Revert "Touch news"

This reverts commit 854e7e10ae.

* `usethis::use_tidy_description()` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-07-22 12:38:23 -05:00
Winston Chang
08383ad8b9 Update srcts/README with info about window.Shiny (#4198) 2025-07-18 17:22:52 -05:00
Carson Sievert
ecf6bfe9a7 Put actionButton()s icon and label into containers (#4249)
* Put action icon and label into containers

* Update snaps

* More robust test

* Don't include container if icon/label isn't specified

* `yarn build` (GitHub Actions)

* Send HTML string/deps on update; update news

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-07-14 16:22:03 -05:00
Carson Sievert
f7528568e5 Increment version number to 1.11.1.9000 (#4253)
* Increment version number to 1.11.1.9000

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-07-07 22:02:14 -07:00
Carson Sievert
51f653b66f v1.11.1 release candidate (#4245)
* v1.11.1 release candidate

* `yarn build` (GitHub Actions)

* Revert actionButton()/actionLink() implementation to v1.11.0's behavior (re-introducing #4239)

* Minimal fix to address the regression in #4239

Ideally we'd fix this issue, and also get updateActionButton() working with HTML labels, but thanks to today's release of kinesis (which snapshots all of actionButton()s markup), and CRAN dragging their feet to accept our original submission (which was fine, by the way), we can't have nice things

* `yarn build` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-07-07 21:53:08 -07:00
Carson Sievert
460a93a5fd Revert the addition of spacing between icon and label in actionButton() (#4248)
* Revert the addition of spacing between icon and label in actionButton()

* `yarn build` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-06-27 10:58:17 -05:00
Carson Sievert
3ea4c8eb1d Restrict icon/label separator spacing to actionButton() (#4247)
* Follow up to #4242: Restrict icon/label separator spacing to actionButton()

* `yarn build` (GitHub Actions)

* Add spacing only when both icon and label are truthy

* Update snapshot

* `yarn build` (GitHub Actions)

* Slightly more readable JS

* `yarn build` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-06-26 19:12:13 -05:00
Carson Sievert
f237de559d Fix front-end action button label updating logic (#4242)
* Close #4239: fix front-end action button label updating logic (follow up to #3996)

* Update news

* Use a separator instead of putting markup in attributes

* `yarn build` (GitHub Actions)

* Address feedback

* Cleanup

* Refactor into a single method to split icon/label

* `yarn build` (GitHub Actions)

* Better naming

* Add some padding to the separator

* Add some unit tests for R logic

* Update NEWS.md

* Update NEWS.md

* Update NEWS.md

* Update NEWS.md

* Increase backcompat (keep same R structure when no icon is provided)

* Refine comment

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-06-26 16:32:17 -05:00
Carson
8c7abbac44 Update news 2025-06-26 13:56:35 -05:00
Carson Sievert
1710316142 Properly handle undefined value for input subscribe callback (#4243)
* Close #4240: properly handle undefined value for input subscribe callback

* Refactor normalization into a function
2025-06-26 09:36:09 -05:00
Carson Sievert
2d856f4f09 Start new version (#4241)
* Start new version

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-06-25 17:05:03 -05:00
Carson Sievert
ab219e3408 v1.11.0 release candidate (#4232) 2025-06-25 16:28:51 -05:00
Carson Sievert
673be3dd77 Follow up to #3996: fix front-end checkbox label updating logic (#4238)
* Follow up to #3996: fix front-end checkbox label updating logic

* More descriptive name
2025-06-20 15:15:30 -05:00
Carson Sievert
b25e6feabb feat(InputBinding): subscribe callback now supports event priority (#4211)
* feat(InputBinding): subscribe callback now supports event priority

* Update NEWS.md

* Update srcts/src/shiny/bind.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* `yarn build` (GitHub Actions)

* Simpler and more consistent typing

* Support a suitable object as input

* Provide a type for the callback itself, not just the valueit's given

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-06-19 10:27:45 -05:00
Carson Sievert
e6b22d86b6 Follow up to #3996 when label is unspecified (i.e., NULL), don't include it in the message (#4237) 2025-06-19 09:48:44 -05:00
Carson Sievert
9c5196ee63 Run routine (#4234)
* Run routine

* `devtools::document()` (GitHub Actions)

* `yarn build` (GitHub Actions)

* Update NEWS.md

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-06-16 12:52:48 -05:00
Hedley
9b53251b09 chore: #4175 update jquery-ui to 1.14.1 (#4205)
* chore: #4175 update jquery-ui to 1.14.1

* Update to latest types

---------

Co-authored-by: Carson <cpsievert1@gmail.com>
2025-06-16 12:42:07 -05:00
David Macro
942bdd8c40 Update jQuery to 3.7.1 (#3969)
* Update jquery

* Upgrade to latest types

* Update news

---------

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2025-06-16 11:46:17 -05:00
edemain03
d762865753 Fix 404 in example 08_html (shiny.min.css) (#4221)
* fix(examples-shiny): use shiny.min.css in 08_html to avoid 404 (#4220)

* Update NEWS.md

* Minimize all the files

---------

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2025-06-16 11:20:00 -05:00
Carson Sievert
992b967095 Follow up to #3870: fix location of news item (#4233) 2025-06-16 11:12:58 -05:00
Stuart Russell
9a39cea0cc Bugfix for error found in tests (#3870)
* Bugfix for error found when calling shiny::shinyAppTemplate without library(shiny)

* Update news

* Update NEWS.md

---------

Co-authored-by: Carson <cpsievert1@gmail.com>
2025-06-16 11:05:43 -05:00
John Coene
db9f210257 Allow update input labels with HTML (#3996)
* fix: allow update input labels with HTML fixes #3995

* refactor: use processDeps and renderContent

* fix: formatting on lists

* fix: put spaces between infix

* chore: generated files

* fix: update input tests

* revert: generated javascript and sourcemaps

* fix: empty label check

* Remove package-lock

* Undo unintended change when merging

* Update news

* Simplify

---------

Co-authored-by: Carson <cpsievert1@gmail.com>
2025-06-16 11:01:44 -05:00
Charlie Gao
e8b7c08a19 Adds mirai to documentation (#4230)
* Update docs to mention mirai

* Update example to use mirai

* Fix other roxygen2 render
2025-06-16 09:42:21 -05:00
Michael Chirico
b596245571 family->given for R Core authorship (#4222) 2025-06-12 16:23:57 -05:00
Carson Sievert
57bb3a12d3 fix(renderPlot): get interactive plotting working with ggplot2 v4.0 (#4228)
* fix(renderPlot): get interactive plotting working with ggplot2 v4.0

* Update NEWS.md
2025-06-12 16:23:38 -05:00
Winston Chang
219fbc6819 Update NEWS 2025-06-09 17:22:20 -05:00
Teun van den Brand
a660093fa5 Compatibility with ggplot2 4.0.0 (#4226)
* add S7 class method

* Update tests/testthat/test-plot-coordmap.R

---------

Co-authored-by: Winston Chang <winston@stdout.org>
2025-06-09 17:20:43 -05:00
Garrick Aden-Buie
eac0eea886 fix: Wrap extended task invocation in promise_resolve() (#4225)
* fix: Wrap extended task invocation in `promise_resolve()`

* refactor: cleanup error handling and promise chain

* chore: add news entry
2025-05-30 08:44:31 -04:00
Charlie Gao
6df0bb9423 Fix performance regression related to limiting deep call stack growth (#4214)
* Use less expensive version of getCallNames() just for hashing

* Update R/conditions.R

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

---------

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
Co-authored-by: Barret Schloerke <barret@rstudio.com>
2025-05-23 18:56:00 +01:00
Barret Schloerke
159e771ac7 Relax test as we've already confirmed throttle is updating. Only required final value expectation (#4218) 2025-05-23 13:43:03 -04:00
Carson Sievert
ca41c0831b feat!(submitButton): don't treat any HTML type='submit' button/input like a submitButton() (#4209)
* feat!(submitButton): don't treat any HTML type='submit' button/input like a submitButton()

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

* Update NEWS.md

* `yarn build` (GitHub Actions)

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
Co-authored-by: Barret Schloerke <barret@rstudio.com>
Co-authored-by: schloerke <schloerke@users.noreply.github.com>
2025-05-01 12:37:21 -05:00
Carson Sievert
316c3c8409 feat(textAreaInput): Add an autoresize option (#4210)
* feat(textAreaInput): Add an autoresize option

* `devtools::document()` (GitHub Actions)

* `yarn build` (GitHub Actions)

* Update NEWS.md

* Fix broken CSS selector.

Rules aren't being applied correctly in PyShiny either...

* Put shiny input class on container (to mirror what PyShiny does)

* Refactor autoresize logic

* Reduce diff size

---------

Co-authored-by: cpsievert <cpsievert@users.noreply.github.com>
2025-04-30 18:34:04 -05:00
Garrick Aden-Buie
f79a22b987 feat: Fully reload ui/server when autoreload occurs (#4184)
* feat: Fully reload ui/server when autoreload occurs

* chore: remove stray empty line

* chore: clean up function names and add comments

* docs: Add news item

* feat: Use {watcher} for autoreload file watching (#4185)

* feat: Use {watcher}

* chore: shikokuchuo/watcher@dev

* chore: watcher is on CRAN now

* chore: Undo air format changes

* feat: Use `shiny.autoreload.interval` for watcher latency

* chore: Simply track last time auto-reload changed

* docs: rewrite options docs for clarity

* chore: code style

* docs: global.R changes are not applied

* feat(ui/server): Autoreload also reloads global and R support files

* chore: remove outdated comment

* chore: safer comparisons

* chore: Restore legacy autoreload watcher if {watcher} not installed

* rename: autoload_r_support_if_needed()

* chore: use `rlang::is_false()`

* chore: use_build_ignore("_dev")
2025-04-24 13:53:40 -04:00
Garrick Aden-Buie
83219e3551 fix: Improve jquery node detection (#4203) 2025-03-25 21:26:27 -04:00
Garrick Aden-Buie
f55c26af4a docs: Link to outputOptions() from render functions (#4196)
* docs(downloadHandler): Link to `outputOptions()`

* docs: include `outputOptions()` in other render functions
2025-03-03 11:11:11 -05:00
Garrick Aden-Buie
9fbb2c5829 docs: Rewrite news for #4183 (#4195) 2025-02-28 08:06:54 -05:00
Winston Chang
531f31b66f textInput(), textAreaInput(), numericInput(), passwordInput(): allow updating value on blur (#4183)
* textInput: Add updateOn parameter and allow setting debounce delay

* `devtools::document()` (GitHub Actions)

* `yarn build` (GitHub Actions)

* Update news

* Remove debounce parameter

* `devtools::document()` (GitHub Actions)

* `yarn build` (GitHub Actions)

* Add updateOn parameter to numericInput, passwordInput

* Add updateOn to textAreaInput()

* `devtools::document()` (GitHub Actions)

* feat: Ignore change events unless from server messages when `updateOn="blur"`

* refactor: `updateOn="change"` instead of `"input"`

* feat: Update inputs on Enter or Cmd/Ctrl+Enter (textarea)

* chore: Document `...` and ensure they are empty

* chore: Use `rlang::arg_match()`

* chore: code style (air format)

* fix: textAreaInput, not inputTextArea

* docs(NEWS): Minor edit

* chore: If element has focus, ignore change event

---------

Co-authored-by: wch <wch@users.noreply.github.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
2025-02-26 12:45:26 -05:00
Winston Chang
58e152154a Stop using Babel; compile JS to ES2020 (#4066)
Co-authored-by: wch <wch@users.noreply.github.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
Co-authored-by: gadenbuie <gadenbuie@users.noreply.github.com>
Co-authored-by: Barret Schloerke <barret@posit.co>
2025-02-03 12:37:19 -05:00
Garrick Aden-Buie
55b37fdeb3 fix(insertTab): Render inserted nav html only once (#4179)
* fix: Fix checking if `scope` is a jquery element

Fixes rstudio/bslib#1159

* refactor: Don't check binding validity if `scope` isn't an element

* fix(insertTab): Render inserted nav html only once

* chore: Don't need to delay binding

* fix: Bind all after inserting nav controls

Output bindings require outputs to be attached to the DOM.

* chore: align comment

* chore: Add news item
2025-01-27 17:15:27 -05:00
Garrick Aden-Buie
b8a5aef53a feat: De-duplicate client console messages (#4177)
* feat: De-duplicate client console messages

* refactor(ShinyErrorConsole): Add `appendConsoleMessage()` static method

* fix: Make `appendConsoleMessage()` an instance method

* rename: `createClientMessageElement()`

* docs: add news item
2025-01-27 16:57:10 -05:00
Carson Sievert
d764ea9b4e Busy indicator improvements (#4172)
* Make sure spinner is visible when htmlwidget errors are visible

* Give recalculating outputs a min-height large enough to show the spinner

* tableOutput() now gets the spinner treatment

* yarn run bundle_extras

* Forward visibility hidden for all recalculating widgets, not just those with a error message (otherwise spinner won't be visible after a req())

* Update news
2025-01-22 14:14:20 -06:00
olivroy
8ad779f949 Various test lints (#4171)
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
2025-01-21 15:08:00 -05:00
olivroy
7642fc84b7 Replace crayon by cli + address some TODOs to add some color (#4170)
* Replace crayon by cli + address some TODOs to add some color

* docs: add news

---------

Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
2025-01-21 11:00:51 -05:00
Garrick Aden-Buie
0952f3e0a7 ci: update for 2025 (#4178)
* ci: update for 2025

* chore: RStudio --> Posit
---------

Co-authored-by: gadenbuie <gadenbuie@users.noreply.github.com>
2025-01-14 13:26:41 -05:00
Garrick Aden-Buie
13ca8dfc57 fix: Schedule .modal("hide") for transitioning modals (#4173)
* fix: Schedule modal removal for transitioning modals

* refactor: Simplify and both call and schedule modal hiding at same time

* Increment version number to 1.10.0.9000

* docs: Add NEWS entry
2024-12-31 16:27:25 -05:00
Garrick Aden-Buie
79f42f5846 v1.10.0 (#4166)
* Increment version number to 1.10.0

* `yarn build` (GitHub Actions)

* Sync package version (GitHub Actions)

* chore: urlchecker::url_update()

✔ Updated: <https://shiny.rstudio.com/reference/shiny/latest/insertUI.html> to <https://shiny.posit.co/r/reference/shiny/latest/insertui.html> in NEWS.md
✔ Updated: <https://shiny.rstudio.com/reference/shiny/latest/modalDialog.html> to <https://shiny.posit.co/r/reference/shiny/latest/modaldialog.html> in NEWS.md
✔ Updated: <https://shiny.rstudio.com/reference/shiny/latest/Progress.html> to <https://shiny.posit.co/r/reference/shiny/latest/progress.html> in NEWS.md
✔ Updated: <https://shiny.rstudio.com/reference/shiny/latest/renderTable.html> to <https://shiny.posit.co/r/reference/shiny/latest/rendertable.html> in NEWS.md
✔ Updated: <https://shiny.rstudio.com/reference/shiny/latest/showNotification.html> to <https://shiny.posit.co/r/reference/shiny/latest/shownotification.html> in NEWS.md
✔ Updated: <https://shiny.rstudio.com/reference/shiny/latest/withProgress.html> to <https://shiny.posit.co/r/reference/shiny/latest/withprogress.html> in NEWS.md

* chore: revdepcheck

* chore: polish NEWS

* chore: update CRAN comments

* Polish NEWS

---------

Co-authored-by: gadenbuie <gadenbuie@users.noreply.github.com>
Co-authored-by: Carson <cpsievert1@gmail.com>
2024-12-16 09:30:53 -06:00
Joe Cheng
9a35b01e23 Fix observeEvent stack trace stripping (#4163)
* Fix observeEvent stack trace stripping

* Add unit test

* Add deep stack version of unit test
2024-12-09 20:50:53 -08:00
Joe Cheng
5bf0701939 Plot outputs incorrectly sized inside scaled outputs (#4139)
* Fix #4135: Plot outputs incorrectly sized inside scaled outputs

CSS zoom property affects el.getBoundingClientRect() but not
el.offsetWidth/Height. When reporting sizes of outputs from
client to server, we need to back out the CSS zoom because
those sizes are used as CSS width/height, which will be
affected by zoom.

(Note that something similar happens with CSS transforms but
we don't have a good way to deal with them)

* Squelch TS error

* `yarn build` (GitHub Actions)

* Add TODO

Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>

* Rebuild JS

---------

Co-authored-by: jcheng5 <jcheng5@users.noreply.github.com>
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
2024-12-08 01:25:32 -08:00
Garrick Aden-Buie
e5083f4938 feat: Avoid throwing errors for shared input/output IDs (#4101)
* refactor: Factor out message display from error handler

* feat: Add custom event for sending a client message

* feat: Report binding validity problem via event instead of throwing error

* feat: Don't need to hide shared input/output message

Now that it's not an error, it's safe to report

* refactor: Move `inDevMode()` logic into error console

* refactor: Rename `.error` --> `.event`

* feat: wrap client error message

It's otherwise hard to tell that the error is scrollable
Plus the scrolling is over the whole message rather than the part that overflows

* feat: always send client console messages to browser console as well

* chore: throw if `shiny:client-message` receives an event that isn't CustomEvent

* feat: Handle status in `showShinyClientMessage()`

* Renamed `showMessageInClientConsole()` to `showShinyClientMessage()` to improve clarity

* Added `status` argument to `showShinyClientMessage()` to allow for different message types

* refactor: Don't throw errors for duplicate IDs

Brings dev mode in line with current "prod" behavior,
where errors aren't thrown for duplciates. In both cases
we still get console or client messages.

* refactor: Clean up `status` inside `checkValidity()`

* refactor: Have `checkValidity()` handle emitting the client console event
2024-12-06 16:00:19 -05:00
Garrick Aden-Buie
ce6a562a3c chore: routine (#4161) 2024-12-06 15:16:29 -05:00
Dan Gealow
b6bcfc8683 Work around a selectize bug (re-fixes #3966) (#4142)
* Work around a selectize bug (re-fixes #3966)

---------

Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
2024-12-06 15:03:59 -05:00
Dean Attali
d37beeece7 ExtendedTask: add example to docs (#4087)
Co-authored-by: Garrick Aden-Buie <garrick@adenbuie.com>
2024-12-06 14:24:01 -05:00
Joe Cheng
79ee25620f Limit deep stack growth (#4156)
* Limit deep stack growth

* Improvements to deep stack trace culling

- Keep around the first deep stack trace; it may have useful
  information. (We may want to change this in the future to
  keep the first two stack traces, or even make it an option)
- Print out an indicator that we've elided stack traces, and
  how many

* Add comments

* Add NEWS item

* Add test for unlimited deep stacks

* Code review feedback

* Code review feedback

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

* Use head() over indexing

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

* Improve unit test robustness

* Remove vector indices from snapshot

* Make stack trace stripping work across deep stacks

* Pass tests

* Try passing tests again

* Rename keep_head to retain_first_n

* Remove misleading variable assignment

* Add more comments, refine dropTrivialTestFrames

* Don't call stripStackTraces if we're not stripping

* Use deep stack deduplication instead of elision

This hopefully will avoid any potential ..stacktraceon../off..
scoring issues, and will be more useful for users. The downside
is that it's still possible to have uselessly large deep stack
traces, but at least that will only happen now if you have
manually written gigantic async/promise chains by hand or maybe
did some clever metaprogramming. The coro case should be fine.

* Add coro-based unit test

* Use rlang::hash, it's much faster

* typo

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

* Remove unnecessary logic

* Simplify/robustify reactlog version checking test

* Warn only once on call stack digest cache miss

* Super conservatively wrap appendCallStackWithDupe in try/catch

* Use more specific attribute name

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>

* Remove excessively cautious try/catch

---------

Co-authored-by: Carson Sievert <cpsievert1@gmail.com>
2024-12-06 10:17:05 -08:00
Joe Cheng
82c678a1eb Update NEWS.md for stack trace domain explosion 2024-12-03 13:37:58 -08:00
Joe Cheng
458924569a Stack trace domain explosion (#4155)
* Avoid way too many promise domains being activated

Using `captureStackTraces` in wrapForContext is a bad idea, it
piles on a new domain every time a handler is bound.

* Use captureStackTraces, it means the same thing

* Update promises version requirement

* Add test for stack trace growth

* Simplify stack trace snapshot tests

The `category` column isn't a good candidate for snapshot
testing, as its contents vary depending on how the package
was loaded/installed. During devtools::test() or similar,
shiny package code shows up as 'user'. But during CI, it
doesn't show up as anything.
2024-12-03 13:23:50 -08:00
Garrick Aden-Buie
501b012b2b chore: Remove zipfs from recommended vscode extensions (#4151) 2024-11-07 10:52:10 -05:00
Garrick Aden-Buie
ee1aac847a docs(runExample): display.mode follows DESCRIPTION (#4152)
Fixes #4077

The argument documentation wasn't updated to reflect that `runExample()` can run more than just Shiny's examples
2024-11-07 10:51:27 -05:00
bart1
7785a76a67 Closing bracket missing (#4150)
* type

* typo
2024-11-01 09:05:20 -05:00
273 changed files with 18585 additions and 39577 deletions

View File

@@ -21,19 +21,14 @@
^TODO-promises.md$
^manualtests$
^\.github$
^\.yarn$
^\.vscode$
^\.madgerc$
^\.prettierrc\.yml$
^babel\.config\.json$
^jest\.config\.js$
^package\.json$
^tsconfig\.json$
^yarn\.lock$
^package-lock\.json$
^node_modules$
^coverage$
^.ignore$
^\.browserslistrc$
^\.eslintrc\.yml$
^\.yarnrc\.yml$
^eslint\.config\.mjs$
^_dev$
^.claude$

View File

@@ -1,8 +0,0 @@
# Browsers that we support
last 2 versions
not dead
> 0.2%
# > 1%
Firefox ESR
phantomjs 2.1
IE 11 # sorry

View File

@@ -1,110 +0,0 @@
root: true
env:
browser: true
es6: true
extends:
- 'eslint:recommended'
- 'plugin:@typescript-eslint/recommended'
- 'plugin:jest/recommended'
- 'plugin:prettier/recommended'
- 'plugin:jest-dom/recommended'
globals:
Atomics: readonly
SharedArrayBuffer: readonly
parser: '@typescript-eslint/parser'
parserOptions:
ecmaVersion: 2018
sourceType: module
project:
- './tsconfig.json'
ignorePatterns: # mirrors tsconfig.json's exclude
- '**/__tests__'
- '**/*.d.ts'
plugins:
- '@typescript-eslint'
- prettier
- jest-dom
- unicorn
rules:
"@typescript-eslint/explicit-function-return-type":
- off
"@typescript-eslint/no-explicit-any":
- off
"@typescript-eslint/explicit-module-boundary-types":
- error
default-case:
- error
linebreak-style:
- error
- unix
quotes:
- error
- double
- avoid-escape
semi:
- error
- always
dot-location:
- error
- property
camelcase:
# - error
- "off"
unicorn/filename-case:
- error
- case: camelCase
"@typescript-eslint/array-type":
- error
- default: array-simple
readonly: array-simple
"@typescript-eslint/consistent-indexed-object-style":
- error
- index-signature
"@typescript-eslint/sort-type-union-intersection-members":
- error
"@typescript-eslint/consistent-type-imports":
- error
"@typescript-eslint/no-floating-promises":
- error
"@typescript-eslint/naming-convention":
- error
- selector: default
format: [camelCase]
- selector: method
modifiers: [private]
format: [camelCase]
leadingUnderscore: require
- selector: method
modifiers: [protected]
format: [camelCase]
leadingUnderscore: require
- selector: variable
format: [camelCase]
trailingUnderscore: forbid
leadingUnderscore: forbid
- selector: parameter
format: [camelCase]
trailingUnderscore: allow
leadingUnderscore: forbid
- selector: [enum, enumMember]
format: [PascalCase]
- selector: typeLike
format: [PascalCase]
custom:
regex: "(t|T)ype$"
match: false

View File

@@ -5,8 +5,8 @@ echo "Updating package.json version to match DESCRIPTION Version"
Rscript ./tools/updatePackageJsonVersion.R
if [ -n "$(git status --porcelain package.json)" ]
then
echo "package.json has changed after running ./tools/updatePackageJsonVersion.R. Re-running 'yarn build'"
yarn build
echo "package.json has changed after running ./tools/updatePackageJsonVersion.R. Re-running 'npm run build'"
npm run build
git add ./inst package.json && git commit -m 'Sync package version (GitHub Actions)' || echo "No package version to commit"
else
echo "No package version difference detected; package.json is current."

View File

@@ -8,7 +8,7 @@ on:
pull_request:
branches: [main]
schedule:
- cron: '0 5 * * 1' # every monday
- cron: "0 5 * * 1" # every monday
name: Package checks
@@ -17,7 +17,5 @@ jobs:
uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1
routine:
uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1
with:
node-version: "14.x"
R-CMD-check:
uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1

12
.gitignore vendored
View File

@@ -9,20 +9,16 @@
shinyapps/
README.html
.*.Rnb.cached
tools/yarn-error.log
/_dev/
.sass_cache_keys
# TypeScript / yarn
# TypeScript
/node_modules/
.cache
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
coverage/
madge.svg
# GHA remotes installation
.github/r-depends.rds
.claude/settings.local.json

View File

@@ -1,6 +1,5 @@
{
"recommendations": [
"arcanis.vscode-zipfs",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]

View File

@@ -1,7 +1,5 @@
{
"search.exclude": {
"**/.yarn": true,
"**/.pnp.*": true
},
"prettier.prettierPath": "./node_modules/prettier",
"typescript.enablePromptUseWorkspaceTsdk": true,

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

@@ -1,10 +0,0 @@
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
spec: "https://github.com/mskelton/yarn-plugin-outdated/raw/main/bundles/@yarnpkg/plugin-outdated.js"
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.2.3.cjs
checksumBehavior: update

View File

@@ -1,119 +1,132 @@
Package: shiny
Type: Package
Package: shiny
Title: Web Application Framework for R
Version: 1.9.1.9000
Version: 1.11.1.9000
Authors@R: c(
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("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("Jeff", "Allen", role = "aut"),
person("Jonathan", "McPherson", role = "aut", email = "jonathan@posit.co"),
person("Jonathan", "McPherson", , "jonathan@posit.co", role = "aut"),
person("Alan", "Dipert", role = "aut"),
person("Barbara", "Borges", role = "aut"),
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("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("Mark", "Otto", role = "ctb",
comment = "Bootstrap library"),
comment = "Bootstrap library"),
person("Jacob", "Thornton", role = "ctb",
comment = "Bootstrap library"),
person(family = "Bootstrap contributors", role = "ctb",
comment = "Bootstrap library"),
person(family = "Twitter, Inc", role = "cph",
comment = "Bootstrap library"),
comment = "Bootstrap library"),
person(, "Bootstrap contributors", role = "ctb",
comment = "Bootstrap library"),
person(, "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(family = "PayPal, Inc", role = "cph",
comment = "Bootstrap accessibility plugin"),
comment = "Bootstrap accessibility plugin"),
person(, "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(family = "SpryMedia Limited", role = c("ctb", "cph"),
comment = "DataTables library"),
comment = "Javascript strftime library"),
person(, "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(family = "R Core Team", role = c("ctb", "cph"),
comment = "tar implementation from R")
)
comment = "highlight.js library"),
person("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:
R (>= 3.0.2),
methods
methods,
R (>= 3.0.2)
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.1.0),
tools,
crayon,
rlang (>= 0.4.10),
fastmap (>= 1.1.1),
withr,
commonmark (>= 1.7),
glue (>= 1.3.2),
bslib (>= 0.6.0),
cachem (>= 1.1.0),
lifecycle (>= 0.2.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
Suggests:
Cairo (>= 1.5-5),
coro (>= 1.1.0),
datasets,
DT,
Cairo (>= 1.5-5),
testthat (>= 3.0.0),
knitr (>= 1.6),
markdown,
rmarkdown,
ggplot2,
reactlog (>= 1.0.0),
magrittr,
yaml,
future,
dygraphs,
future,
ggplot2,
knitr (>= 1.6),
magrittr,
markdown,
mirai,
ragg,
reactlog (>= 1.0.0),
rmarkdown,
sass,
showtext,
sass
URL: https://shiny.posit.co/,
https://github.com/rstudio/shiny
BugReports: https://github.com/rstudio/shiny/issues
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
Collate:
'globals.R'
'app-state.R'
@@ -199,6 +212,7 @@ 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'
@@ -206,10 +220,3 @@ Collate:
'version_selectize.R'
'version_strftime.R'
'viewer.R'
RoxygenNote: 7.3.2
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RdMacros: lifecycle
Config/testthat/edition: 3
Config/Needs/check:
shinytest2

110
NEWS.md
View File

@@ -1,10 +1,91 @@
# shiny (development version)
## New features
* The `icon` argument of `updateActionButton()`/`updateActionLink()` nows allows values other than `shiny::icon()` (e.g., `fontawesome::fa()`, `bsicons::bs_icon()`, etc). (#4249)
## Bug fixes
* `updateActionButton()`/`updateActionLink()` now correctly renders HTML content passed to the `label` argument. (#4249)
* Fixed an issue where `updateSelectizeInput(options = list(plugins="remove_button"))` could lead to multiple remove buttons. (#4275)
## 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
## Improvements
* When auto-reload is enabled, Shiny now reloads the entire app when support files, like Shiny modules, additional script files, or web assets, change. To enable auto-reload, call `devmode(TRUE)` to enable Shiny's developer mode, or set `options(shiny.autoreload = TRUE)` to specifically enable auto-reload. You can choose which files are watched for changes with the `shiny.autoreload.pattern` option. (#4184)
* When busy indicators are enabled (i.e., `useBusyIndicators()`), Shiny now:
* Shows a spinner on recalculating htmlwidgets that have previously rendered an error (including `req()` and `validate()`). (#4172)
* 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)
* `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)
## Bug fixes
* 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)
# shiny 1.10.0
## New features and improvements
* Small improvements to the default pulse busy indicator to better blend with any background. It's also now slightly smaller by default. (#4122)
* When busy indicators are enabled (i.e., `useBusyIndicators()` is in the UI), Shiny now:
* Shows the pulse indicator when dynamic UI elements are recalculating and no other spinners are visible in the app. (#4137)
* Makes the pulse indicator slightly smaller by default and improves its appearance to better blend with any background. (#4122)
* When spinners and the pulse busy indicators are enabled, Shiny now shows the pulse indicator when dynamic UI elements are recalculating if no other spinners are present in the app. (#4137)
* Improve collection of deep stack traces (stack traces that are tracked across steps in an async promise chain) with `{coro}` async generators such as `{elmer}` chat streams. Previously, Shiny treated each iteration of an async generator as a distinct deep stack, leading to pathologically long stack traces; now, Shiny only keeps/prints unique deep stack trace, discarding duplicates. (#4156)
* Added an example to the `ExtendedTask` documentation. (@daattali #4087)
## Bug fixes
@@ -12,9 +93,17 @@
* Fixed a bug with `sliderInput()` when used as a range slider that made it impossible to change the slider value when both handles were at the maximum value. (#4131)
* `dateInput` and `dateRangeInput` no longer send immediate updates to the server when the user is typing a date input. Instead, it waits until the user presses Enter or clicks out of the field to send the update, avoiding spurious and incorrect date values. Note that an update is still sent immediately when the field is cleared. (#3664)
* `dateInput()` and `dateRangeInput()` no longer send immediate updates to the server when the user is typing a date input. Instead, it waits until the user presses Enter or clicks out of the field to send the update, avoiding spurious and incorrect date values. Note that an update is still sent immediately when the field is cleared. (#3664)
* Fixed a bug in `onBookmark` hook that caused elements to not be excluded from URL bookmarking. (#3762)
* Fixed a bug in `onBookmark()` hook that caused elements to not be excluded from URL bookmarking. (#3762)
* Fixed a bug with stack trace capturing that caused reactives with very long async promise chains (hundreds/thousands of steps) to become extremely slow. Chains this long are unlikely to be written by hand, but `{coro}` async generators and `{elmer}` async streaming were easily creating problematically long chains. (#4155)
* Duplicate input and output IDs -- e.g. using `"debug"` for two inputs or two outputs -- or shared IDs -- e.g. using `"debug"` as the `inputId` for an input and an output -- now result in a console warning message, but not an error. When `devmode()` is enabled, an informative message is shown in the Shiny Client Console. We recommend all Shiny devs enable `devmode()` when developing Shiny apps locally. (#4101)
* Updating the choices of a `selectizeInput()` via `updateSelectizeInput()` with `server = TRUE` no longer retains the selected choice as a deselected option if the current value is not part of the new choices. (@dvg-p4 #4142)
* Fixed a bug where stack traces from `observeEvent()` were being stripped of stack frames too aggressively. (#4163)
# shiny 1.9.1
@@ -145,7 +234,6 @@ 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
@@ -334,7 +422,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/SLMNBJ/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/SalmenBejaoui/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)
@@ -1038,7 +1126,7 @@ Shiny can now display notifications on the client browser by using the `showNoti
<img src="http://shiny.rstudio.com/images/notification.png" alt="notification" width="50%"/>
</p>
[Here](https://shiny.rstudio.com/articles/notifications.html)'s our article about it, and the [reference documentation](https://shiny.rstudio.com/reference/shiny/latest/showNotification.html).
[Here](https://shiny.rstudio.com/articles/notifications.html)'s our article about it, and the [reference documentation](https://shiny.posit.co/r/reference/shiny/latest/shownotification.html).
## Progress indicators
@@ -1047,7 +1135,7 @@ If your Shiny app contains computations that take a long time to complete, a pro
**_Important note_:**
> If you were already using progress bars and had customized them with your own CSS, you can add the `style = "old"` argument to your `withProgress()` call (or `Progress$new()`). This will result in the same appearance as before. You can also call `shinyOptions(progress.style = "old")` in your app's server function to make all progress indicators use the old styling.
To see new progress bars in action, see [this app](https://gallery.shinyapps.io/085-progress/) in the gallery. You can also learn more about this in [our article](https://shiny.rstudio.com/articles/progress.html) and in the reference documentation (either for the easier [`withProgress` functional API](https://shiny.rstudio.com/reference/shiny/latest/withProgress.html) or the more complicated, but more powerful, [`Progress` object-oriented API](https://shiny.rstudio.com/reference/shiny/latest/Progress.html).
To see new progress bars in action, see [this app](https://gallery.shinyapps.io/085-progress/) in the gallery. You can also learn more about this in [our article](https://shiny.rstudio.com/articles/progress.html) and in the reference documentation (either for the easier [`withProgress` functional API](https://shiny.posit.co/r/reference/shiny/latest/withprogress.html) or the more complicated, but more powerful, [`Progress` object-oriented API](https://shiny.posit.co/r/reference/shiny/latest/progress.html).
## Reconnection
@@ -1061,7 +1149,7 @@ Shiny has now built-in support for displaying modal dialogs like the one below (
<img src="http://shiny.rstudio.com/images/modal-dialog.png" alt="modal-dialog" width="50%"/>
</p>
To learn more about this, read [our article](https://shiny.rstudio.com/articles/modal-dialogs.html) and the [reference documentation](https://shiny.rstudio.com/reference/shiny/latest/modalDialog.html).
To learn more about this, read [our article](https://shiny.rstudio.com/articles/modal-dialogs.html) and the [reference documentation](https://shiny.posit.co/r/reference/shiny/latest/modaldialog.html).
## `insertUI` and `removeUI`
@@ -1069,7 +1157,7 @@ Sometimes in a Shiny app, arbitrary HTML UI may need to be created on-the-fly in
See [this simple demo app](https://gallery.shinyapps.io/111-insert-ui/) of how one could use `insertUI` and `removeUI` to insert and remove text elements using a queue. Also see [this other app](https://gallery.shinyapps.io/insertUI/) that demonstrates how to insert and remove a few common Shiny input objects. Finally, [this app](https://gallery.shinyapps.io/insertUI-modules/) shows how to dynamically insert modules using `insertUI`.
For more, read [our article](https://shiny.rstudio.com/articles/dynamic-ui.html) about dynamic UI generation and the reference documentation about [`insertUI`](https://shiny.rstudio.com/reference/shiny/latest/insertUI.html) and [`removeUI`](https://shiny.rstudio.com/reference/shiny/latest/insertUI.html).
For more, read [our article](https://shiny.rstudio.com/articles/dynamic-ui.html) about dynamic UI generation and the reference documentation about [`insertUI`](https://shiny.posit.co/r/reference/shiny/latest/insertui.html) and [`removeUI`](https://shiny.posit.co/r/reference/shiny/latest/insertui.html).
## Documentation for connecting to an external database
@@ -1103,7 +1191,7 @@ There are many more minor features, small improvements, and bug fixes than we ca
<img src="http://shiny.rstudio.com/images/render-table.png" alt="render-table" width="75%"/>
</p>
For more, read our [short article](https://shiny.rstudio.com/articles/render-table.html) about this update, experiment with all the new features in this [demo app](https://gallery.shinyapps.io/109-render-table/), or check out the [reference documentation](https://shiny.rstudio.com/reference/shiny/latest/renderTable.html).
For more, read our [short article](https://shiny.rstudio.com/articles/render-table.html) about this update, experiment with all the new features in this [demo app](https://gallery.shinyapps.io/109-render-table/), or check out the [reference documentation](https://shiny.posit.co/r/reference/shiny/latest/rendertable.html).
## Full changelog

View File

@@ -177,7 +177,7 @@ utils::globalVariables(".GenericCallEnv", add = TRUE)
#' cache by putting this at the top of your app.R, server.R, or global.R:
#'
#' ```
#' shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache"))
#' shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache")))
#' ```
#'
#' This will create a subdirectory in your system temp directory named
@@ -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 [future::future()] objects to run code in a
#' separate process or even on a remote machine.
#' information.) You can also use [mirai::mirai()] or [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

@@ -1113,7 +1113,7 @@ plotOutput <- function(outputId, width = "100%", height="400px",
#' @rdname renderTable
#' @export
tableOutput <- function(outputId) {
div(id = outputId, class="shiny-html-output")
div(id = outputId, class="shiny-html-output shiny-table-output")
}
dataTableDependency <- list(

View File

@@ -75,6 +75,18 @@ 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)
@@ -130,6 +142,44 @@ captureStackTraces <- function(expr) {
#' @include globals.R
.globals$deepStack <- NULL
getCallStackDigest <- function(callStack, warn = FALSE) {
dg <- attr(callStack, "shiny.stack.digest", exact = TRUE)
if (!is.null(dg)) {
return(dg)
}
if (isTRUE(warn)) {
rlang::warn(
"Call stack doesn't have a cached digest; expensively computing one now",
.frequency = "once",
.frequency_id = "deepstack-uncached-digest-warning"
)
}
rlang::hash(getCallNamesForHash(callStack))
}
saveCallStackDigest <- function(callStack) {
attr(callStack, "shiny.stack.digest") <- getCallStackDigest(callStack, warn = FALSE)
callStack
}
# Appends a call stack to a list of call stacks, but only if it's not already
# in the list. The list is deduplicated by digest; ideally the digests on the
# list are cached before calling this function (you will get a warning if not).
appendCallStackWithDedupe <- function(lst, x) {
digests <- vapply(lst, getCallStackDigest, character(1), warn = TRUE)
xdigest <- getCallStackDigest(x, warn = TRUE)
stopifnot(all(nzchar(digests)))
stopifnot(length(xdigest) == 1)
stopifnot(nzchar(xdigest))
if (xdigest %in% digests) {
return(lst)
} else {
return(c(lst, list(x)))
}
}
createStackTracePromiseDomain <- function() {
# These are actually stateless, we wouldn't have to create a new one each time
# if we didn't want to. They're pretty cheap though.
@@ -142,13 +192,14 @@ createStackTracePromiseDomain <- function() {
currentStack <- sys.calls()
currentParents <- sys.parents()
attr(currentStack, "parents") <- currentParents
currentStack <- saveCallStackDigest(currentStack)
currentDeepStack <- .globals$deepStack
}
function(...) {
# Fulfill time
if (deepStacksEnabled()) {
origDeepStack <- .globals$deepStack
.globals$deepStack <- c(currentDeepStack, list(currentStack))
.globals$deepStack <- appendCallStackWithDedupe(currentDeepStack, currentStack)
on.exit(.globals$deepStack <- origDeepStack, add = TRUE)
}
@@ -165,13 +216,14 @@ createStackTracePromiseDomain <- function() {
currentStack <- sys.calls()
currentParents <- sys.parents()
attr(currentStack, "parents") <- currentParents
currentStack <- saveCallStackDigest(currentStack)
currentDeepStack <- .globals$deepStack
}
function(...) {
# Fulfill time
if (deepStacksEnabled()) {
origDeepStack <- .globals$deepStack
.globals$deepStack <- c(currentDeepStack, list(currentStack))
.globals$deepStack <- appendCallStackWithDedupe(currentDeepStack, currentStack)
on.exit(.globals$deepStack <- origDeepStack, add = TRUE)
}
@@ -199,6 +251,7 @@ doCaptureStack <- function(e) {
calls <- sys.calls()
parents <- sys.parents()
attr(calls, "parents") <- parents
calls <- saveCallStackDigest(calls)
attr(e, "stack.trace") <- calls
}
if (deepStacksEnabled()) {
@@ -281,88 +334,115 @@ printStackTrace <- function(cond,
full = get_devmode_option("shiny.fullstacktrace", FALSE),
offset = getOption("shiny.stacktraceoffset", TRUE)) {
should_drop <- !full
should_strip <- !full
should_prune <- !full
stackTraceCalls <- c(
stackTraces <- c(
attr(cond, "deep.stack.trace", exact = TRUE),
list(attr(cond, "stack.trace", exact = TRUE))
)
stackTraceParents <- lapply(stackTraceCalls, attr, which = "parents", exact = TRUE)
stackTraceCallNames <- lapply(stackTraceCalls, getCallNames)
stackTraceCalls <- lapply(stackTraceCalls, offsetSrcrefs, offset = offset)
# Use dropTrivialFrames logic to remove trailing bits (.handleSimpleError, h)
if (should_drop) {
# toKeep is a list of logical vectors, of which elements (stack frames) to keep
toKeep <- lapply(stackTraceCallNames, dropTrivialFrames)
# We apply the list of logical vector indices to each data structure
stackTraceCalls <- mapply(stackTraceCalls, FUN = `[`, toKeep, SIMPLIFY = FALSE)
stackTraceCallNames <- mapply(stackTraceCallNames, FUN = `[`, toKeep, SIMPLIFY = FALSE)
stackTraceParents <- mapply(stackTraceParents, FUN = `[`, toKeep, SIMPLIFY = FALSE)
# Stripping of stack traces is the one step where the different stack traces
# interact. So we need to do this in one go, instead of individually within
# printOneStackTrace.
if (!full) {
stripResults <- stripStackTraces(lapply(stackTraces, getCallNames))
} else {
# If full is TRUE, we don't want to strip anything
stripResults <- rep_len(list(TRUE), length(stackTraces))
}
delayedAssign("all_true", {
# List of logical vectors that are all TRUE, the same shape as
# stackTraceCallNames. Delay the evaluation so we don't create it unless
# we need it, but if we need it twice then we don't pay to create it twice.
lapply(stackTraceCallNames, function(st) {
rep_len(TRUE, length(st))
})
})
# stripStackTraces and lapply(stackTraceParents, pruneStackTrace) return lists
# of logical vectors. Use mapply(FUN = `&`) to boolean-and each pair of the
# logical vectors.
toShow <- mapply(
if (should_strip) stripStackTraces(stackTraceCallNames) else all_true,
if (should_prune) lapply(stackTraceParents, pruneStackTrace) else all_true,
FUN = `&`,
mapply(
seq_along(stackTraces),
rev(stackTraces),
rev(stripResults),
FUN = function(i, trace, stripResult) {
if (is.integer(trace)) {
noun <- if (trace > 1L) "traces" else "trace"
message("[ reached getOption(\"shiny.deepstacktrace\") -- omitted ", trace, " more stack ", noun, " ]")
} else {
if (i != 1) {
message("From earlier call:")
}
printOneStackTrace(
stackTrace = trace,
stripResult = stripResult,
full = full,
offset = offset
)
}
# No mapply return value--we're just printing
NULL
},
SIMPLIFY = FALSE
)
dfs <- mapply(seq_along(stackTraceCalls), rev(stackTraceCalls), rev(stackTraceCallNames), rev(toShow), FUN = function(i, calls, nms, index) {
st <- data.frame(
num = rev(which(index)),
call = rev(nms[index]),
loc = rev(getLocs(calls[index])),
category = rev(getCallCategories(calls[index])),
stringsAsFactors = FALSE
)
if (i != 1) {
message("From earlier call:")
}
if (nrow(st) == 0) {
message(" [No stack trace available]")
} else {
width <- floor(log10(max(st$num))) + 1
formatted <- paste0(
" ",
formatC(st$num, width = width),
": ",
mapply(paste0(st$call, st$loc), st$category, FUN = function(name, category) {
if (category == "pkg")
crayon::silver(name)
else if (category == "user")
crayon::blue$bold(name)
else
crayon::white(name)
}),
"\n"
)
cat(file = stderr(), formatted, sep = "")
}
st
}, SIMPLIFY = FALSE)
invisible()
}
printOneStackTrace <- function(stackTrace, stripResult, full, offset) {
calls <- offsetSrcrefs(stackTrace, offset = offset)
callNames <- getCallNames(stackTrace)
parents <- attr(stackTrace, "parents", exact = TRUE)
should_drop <- !full
should_strip <- !full
should_prune <- !full
if (should_drop) {
toKeep <- dropTrivialFrames(callNames)
calls <- calls[toKeep]
callNames <- callNames[toKeep]
parents <- parents[toKeep]
stripResult <- stripResult[toKeep]
}
toShow <- rep(TRUE, length(callNames))
if (should_prune) {
toShow <- toShow & pruneStackTrace(parents)
}
if (should_strip) {
toShow <- toShow & stripResult
}
# If we're running in testthat, hide the parts of the stack trace that can
# vary based on how testthat was launched. It's critical that this is not
# happen at the same time as dropTrivialFrames, which happens before
# pruneStackTrace; because dropTrivialTestFrames removes calls from the top
# (or bottom? whichever is the oldest?) of the stack, it breaks `parents`
# which is based on absolute indices of calls. dropTrivialFrames gets away
# with this because it only removes calls from the opposite side of the stack.
toShow <- toShow & dropTrivialTestFrames(callNames)
st <- data.frame(
num = rev(which(toShow)),
call = rev(callNames[toShow]),
loc = rev(getLocs(calls[toShow])),
category = rev(getCallCategories(calls[toShow])),
stringsAsFactors = FALSE
)
if (nrow(st) == 0) {
message(" [No stack trace available]")
} else {
width <- floor(log10(max(st$num))) + 1
formatted <- paste0(
" ",
formatC(st$num, width = width),
": ",
mapply(paste0(st$call, st$loc), st$category, FUN = function(name, category) {
if (category == "pkg")
cli::col_silver(name)
else if (category == "user")
cli::style_bold(cli::col_blue(name))
else
cli::col_white(name)
}),
"\n"
)
cat(file = stderr(), formatted, sep = "")
}
invisible(st)
}
stripStackTraces <- function(stackTraces, values = FALSE) {
score <- 1L # >=1: show, <=0: hide
lapply(seq_along(stackTraces), function(i) {
@@ -458,6 +538,33 @@ dropTrivialFrames <- function(callnames) {
)
}
dropTrivialTestFrames <- function(callnames) {
if (!identical(Sys.getenv("TESTTHAT_IS_SNAPSHOT"), "true")) {
return(rep_len(TRUE, length(callnames)))
}
hideable <- callnames %in% c(
"test",
"devtools::test",
"test_check",
"testthat::test_check",
"test_dir",
"testthat::test_dir",
"test_file",
"testthat::test_file",
"test_local",
"testthat::test_local"
)
firstGoodCall <- min(which(!hideable))
toRemove <- firstGoodCall - 1L
c(
rep_len(FALSE, toRemove),
rep_len(TRUE, length(callnames) - toRemove)
)
}
offsetSrcrefs <- function(calls, offset = TRUE) {
if (offset) {
srcrefs <- getSrcRefs(calls)

View File

@@ -41,6 +41,56 @@
#' 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")
#' library(shiny)
#' library(bslib)
#' library(mirai)
#'
#' # Set background processes for running tasks
#' daemons(1)
#' # Reset when the app is stopped
#' onStop(function() daemons(0))
#'
#' ui <- page_fluid(
#' titlePanel("Extended Task Demo"),
#' p(
#' 'Click the button below to perform a "calculation"',
#' "that takes a while to perform."
#' ),
#' input_task_button("recalculate", "Recalculate"),
#' p(textOutput("result"))
#' )
#'
#' server <- function(input, output) {
#' rand_task <- ExtendedTask$new(function() {
#' mirai(
#' {
#' # Slow operation goes here
#' Sys.sleep(2)
#' sample(1:100, 1)
#' }
#' )
#' })
#'
#' # Make button state reflect task.
#' # If using R >=4.1, you can do this instead:
#' # rand_task <- ExtendedTask$new(...) |> bind_task_button("recalculate")
#' bind_task_button(rand_task, "recalculate")
#'
#' observeEvent(input$recalculate, {
#' # Invoke the extended in an observer
#' rand_task$invoke()
#' })
#'
#' output$result <- renderText({
#' # React to updated results when the task completes
#' number <- rand_task$result()
#' paste0("Your number is ", number, ".")
#' })
#' }
#'
#' shinyApp(ui, server)
#'
#' @export
ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
public = list(
@@ -52,11 +102,12 @@ 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 conjuction with the
#' likely in conjunction with the
#' [\{mirai\}](https://mirai.r-lib.org) or
#' [\{future\}](https://rstudio.github.io/promises/articles/promises_04_futures.html)
#' package. (In short, the return value of `func` should be a
#' [`Future`][future::future()] object, or a `promise`, or something else
#' that [promises::as.promise()] understands.)
#' [`mirai`][mirai::mirai()], [`Future`][future::future()], `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
@@ -82,14 +133,15 @@ 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(args)
private$invocation_queue$add(list(args = args, call = call))
} else {
private$do_invoke(args)
private$do_invoke(args, call = call)
}
invisible(NULL)
},
@@ -156,44 +208,41 @@ ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE,
rv_error = NULL,
invocation_queue = NULL,
do_invoke = function(args) {
do_invoke = function(args, call = NULL) {
private$rv_status("running")
private$rv_value(NULL)
private$rv_error(NULL)
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)
})
p <- promises::promise_resolve(
maskReactiveContext(do.call(private$func, args))
)
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())
}
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)
}
})
invisible(NULL)
},
on_error = function(err) {
on_error = function(err, call = NULL) {
cli::cli_warn(
"ERROR: An error occurred when invoking the ExtendedTask.",
parent = err,
call = call
)
private$rv_status("error")
private$rv_error(err)
},

View File

@@ -56,13 +56,24 @@ actionButton <- function(inputId, label, icon = NULL, width = NULL,
value <- restoreInput(id = inputId, default = NULL)
tags$button(id=inputId,
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,
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,
list(validateIcon(icon), label),
icon, label,
...
)
}
@@ -72,30 +83,40 @@ actionButton <- function(inputId, label, icon = NULL, width = NULL,
actionLink <- function(inputId, label, icon = NULL, ...) {
value <- restoreInput(id = inputId, default = NULL)
tags$a(id=inputId,
href="#",
class="action-button",
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",
`data-val` = value,
list(validateIcon(icon), label),
icon, label,
...
)
}
# 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)
# Throw an informative warning if icon isn't html-ish
validateIcon <- function(icon) {
if (is.null(icon) || identical(icon, character(0))) {
if (length(icon) == 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

@@ -29,22 +29,36 @@
#' A numeric vector of length 1.
#'
#' @export
numericInput <- function(inputId, label, value, min = NA, max = NA, step = NA,
width = NULL) {
numericInput <- function(
inputId,
label,
value,
min = NA,
max = NA,
step = NA,
width = NULL,
...,
updateOn = c("change", "blur")
) {
rlang::check_dots_empty()
updateOn <- rlang::arg_match(updateOn)
value <- restoreInput(id = inputId, default = value)
# build input tag
inputTag <- tags$input(id = inputId, type = "number", class="shiny-input-number form-control",
value = formatNoSci(value))
if (!is.na(min))
inputTag$attribs$min = min
if (!is.na(max))
inputTag$attribs$max = max
if (!is.na(step))
inputTag$attribs$step = step
inputTag <- tags$input(
id = inputId,
type = "number",
class = "shiny-input-number form-control",
value = formatNoSci(value),
`data-update-on` = updateOn
)
if (!is.na(min)) inputTag$attribs$min = min
if (!is.na(max)) inputTag$attribs$max = max
if (!is.na(step)) inputTag$attribs$step = step
div(class = "form-group shiny-input-container",
div(
class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
inputTag

View File

@@ -30,12 +30,29 @@
#' shinyApp(ui, server)
#' }
#' @export
passwordInput <- function(inputId, label, value = "", width = NULL,
placeholder = NULL) {
div(class = "form-group shiny-input-container",
passwordInput <- function(
inputId,
label,
value = "",
width = NULL,
placeholder = NULL,
...,
updateOn = c("change", "blur")
) {
rlang::check_dots_empty()
updateOn <- rlang::arg_match(updateOn)
div(
class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
tags$input(id = inputId, type="password", class="shiny-input-password form-control", value=value,
placeholder = placeholder)
tags$input(
id = inputId,
type = "password",
class = "shiny-input-password form-control",
value = value,
placeholder = placeholder,
`data-update-on` = updateOn
)
)
}

View File

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

View File

@@ -10,6 +10,14 @@
#' @param placeholder A character string giving the user a hint as to what can
#' be entered into the control. Internet Explorer 8 and 9 do not support this
#' option.
#' @param ... Ignored, included to require named arguments and for future
#' feature expansion.
#' @param updateOn A character vector specifying when the input should be
#' updated. Options are `"change"` (default) and `"blur"`. Use `"change"` to
#' update the input immediately whenever the value changes. Use `"blur"`to
#' delay the input update until the input loses focus (the user moves away
#' from the input), or when Enter is pressed (or Cmd/Ctrl + Enter for
#' [textAreaInput()]).
#' @return A text input control that can be added to a UI definition.
#'
#' @family input elements
@@ -34,15 +42,31 @@
#' unless `value` is provided.
#'
#' @export
textInput <- function(inputId, label, value = "", width = NULL,
placeholder = NULL) {
textInput <- function(
inputId,
label,
value = "",
width = NULL,
placeholder = NULL,
...,
updateOn = c("change", "blur")
) {
rlang::check_dots_empty()
updateOn <- rlang::arg_match(updateOn)
value <- restoreInput(id = inputId, default = value)
div(class = "form-group shiny-input-container",
div(
class = "form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
tags$input(id = inputId, type="text", class="shiny-input-text form-control", value=value,
placeholder = placeholder)
tags$input(
id = inputId,
type = "text",
class = "shiny-input-text form-control",
value = value,
placeholder = placeholder,
`data-update-on` = updateOn
)
)
}

View File

@@ -16,6 +16,8 @@
#' @param resize Which directions the textarea box can be resized. Can be one of
#' `"both"`, `"none"`, `"vertical"`, and `"horizontal"`. The default, `NULL`,
#' will use the client browser's default setting for resizing textareas.
#' @param autoresize If `TRUE`, the textarea will automatically resize to fit
#' the input text.
#' @return A textarea input control that can be added to a UI definition.
#'
#' @family input elements
@@ -41,8 +43,22 @@
#' unless `value` is provided.
#'
#' @export
textAreaInput <- function(inputId, label, value = "", width = NULL, height = NULL,
cols = NULL, rows = NULL, placeholder = NULL, resize = NULL) {
textAreaInput <- function(
inputId,
label,
value = "",
width = NULL,
height = NULL,
cols = NULL,
rows = NULL,
placeholder = NULL,
resize = NULL,
...,
autoresize = FALSE,
updateOn = c("change", "blur")
) {
rlang::check_dots_empty()
updateOn <- rlang::arg_match(updateOn)
value <- restoreInput(id = inputId, default = value)
@@ -50,23 +66,30 @@ textAreaInput <- function(inputId, label, value = "", width = NULL, height = NUL
resize <- match.arg(resize, c("both", "none", "vertical", "horizontal"))
}
style <- css(
# The width is specified on the parent div.
width = if (!is.null(width)) "100%",
height = validateCssUnit(height),
resize = resize
)
classes <- "form-control"
if (autoresize) {
classes <- c(classes, "textarea-autoresize")
if (is.null(rows)) {
rows <- 1
}
}
div(class = "form-group shiny-input-container",
div(
class = "shiny-input-textarea form-group shiny-input-container",
style = css(width = validateCssUnit(width)),
shinyInputLabel(inputId, label),
style = if (!is.null(width)) paste0("width: ", validateCssUnit(width), ";"),
tags$textarea(
id = inputId,
class = "shiny-input-textarea form-control",
class = classes,
placeholder = placeholder,
style = style,
style = css(
width = if (!is.null(width)) "100%",
height = validateCssUnit(height),
resize = resize
),
rows = rows,
cols = cols,
`data-update-on` = updateOn,
value
)
)

View File

@@ -53,10 +53,12 @@ Context <- R6Class(
promises::with_promise_domain(reactivePromiseDomain(), {
withReactiveDomain(.domain, {
env <- .getReactiveEnvironment()
rLog$enter(.reactId, id, .reactType, .domain)
on.exit(rLog$exit(.reactId, id, .reactType, .domain), add = TRUE)
env$runWith(self, func)
captureStackTraces({
env <- .getReactiveEnvironment()
rLog$enter(.reactId, id, .reactType, .domain)
on.exit(rLog$exit(.reactId, id, .reactType, .domain), add = TRUE)
env$runWith(self, func)
})
})
})
},
@@ -223,9 +225,7 @@ wrapForContext <- function(func, ctx) {
function(...) {
.getReactiveEnvironment()$runWith(ctx, function() {
captureStackTraces(
func(...)
)
func(...)
})
}
}

View File

@@ -2304,7 +2304,7 @@ observeEvent <- function(eventExpr, handlerExpr,
priority = priority,
domain = domain,
autoDestroy = TRUE,
..stacktraceon = FALSE # TODO: Does this go in the bindEvent?
..stacktraceon = TRUE
))
o <- inject(bindEvent(

View File

@@ -266,6 +266,8 @@ 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

@@ -445,7 +445,9 @@ stopApp <- function(returnValue = invisible()) {
#' @param host The IPv4 address that the application should listen on. Defaults
#' to the `shiny.host` option, if set, or `"127.0.0.1"` if not.
#' @param display.mode The mode in which to display the example. Defaults to
#' `showcase`, but may be set to `normal` to see the example without
#' `"auto"`, which uses the value of `DisplayMode` in the example's
#' `DESCRIPTION` file. Set to `"showcase"` to show the app code and
#' description with the running app, or `"normal"` to see the example without
#' code or commentary.
#' @param package The package in which to find the example (defaults to
#' `"shiny"`).

View File

@@ -65,16 +65,20 @@ getShinyOption <- function(name, default = NULL) {
#' changes are detected, all connected Shiny sessions are reloaded. This
#' allows for fast feedback loops when tweaking Shiny UI.
#'
#' Since monitoring for changes is expensive (we simply poll for last
#' modified times), this feature is intended only for development.
#' Monitoring for changes is no longer expensive, thanks to the \pkg{watcher}
#' package, but this feature is still intended only for development.
#'
#' You can customize the file patterns Shiny will monitor by setting the
#' shiny.autoreload.pattern option. For example, to monitor only ui.R:
#' `options(shiny.autoreload.pattern = glob2rx("ui.R"))`
#' shiny.autoreload.pattern option. For example, to monitor only `ui.R`:
#' `options(shiny.autoreload.pattern = glob2rx("ui.R"))`.
#'
#' The default polling interval is 500 milliseconds. You can change this
#' by setting e.g. `options(shiny.autoreload.interval = 2000)` (every
#' two seconds).}
#' As mentioned above, Shiny no longer polls watched files for changes.
#' Instead, using \pkg{watcher}, Shiny is notified of file changes as they
#' occur. These changes are batched together within a customizable latency
#' period. You can adjust this period by setting
#' `options(shiny.autoreload.interval = 2000)` (in milliseconds). This value
#' converted to seconds and passed to the `latency` argument of
#' [watcher::watcher()]. The default latency is 250ms.}
#' \item{shiny.deprecation.messages (defaults to `TRUE`)}{This controls whether messages for
#' deprecated functions in Shiny will be printed. See
#' [shinyDeprecated()] for more information.}

View File

@@ -2024,7 +2024,7 @@ ShinySession <- R6Class(
tmpdata <- tempfile(fileext = ext)
return(Context$new(getDefaultReactiveDomain(), '[download]')$run(function() {
promises::with_promise_domain(reactivePromiseDomain(), {
promises::with_promise_domain(createStackTracePromiseDomain(), {
captureStackTraces({
self$incrementBusyCount()
hybrid_chain(
# ..stacktraceon matches with the top-level ..stacktraceoff..

View File

@@ -162,11 +162,29 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
sharedEnv <- globalenv()
}
# To enable hot-reloading of support files, this function is called
# whenever the UI or Server func source is updated. To avoid loading
# support files 2x, we follow the last cache update trigger timestamp.
autoload_r_support_if_needed <- local({
autoload_last_loaded <- -1
function() {
if (!isTRUE(getOption("shiny.autoload.r", TRUE))) return()
last_cache_trigger <- cachedAutoReloadLastChanged$get()
if (identical(autoload_last_loaded, last_cache_trigger)) return()
loadSupport(appDir, renv = sharedEnv, globalrenv = globalenv())
autoload_last_loaded <<- last_cache_trigger
}
})
# uiHandlerSource is a function that returns an HTTP handler for serving up
# ui.R as a webpage. The "cachedFuncWithFile" call makes sure that the closure
# we're creating here only gets executed when ui.R's contents change.
uiHandlerSource <- cachedFuncWithFile(appDir, "ui.R", case.sensitive = FALSE,
function(uiR) {
autoload_r_support_if_needed()
if (file.exists(uiR)) {
# If ui.R contains a call to shinyUI (which sets .globals$ui), use that.
# If not, then take the last expression that's returned from ui.R.
@@ -197,6 +215,7 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
serverSource <- cachedFuncWithFile(appDir, "server.R", case.sensitive = FALSE,
function(serverR) {
autoload_r_support_if_needed()
# If server.R contains a call to shinyServer (which sets .globals$server),
# use that. If not, then take the last expression that's returned from
# server.R.
@@ -232,10 +251,9 @@ shinyAppDir_serverR <- function(appDir, options=list()) {
onStart <- function() {
oldwd <<- getwd()
setwd(appDir)
# TODO: we should support hot reloading on global.R and R/*.R changes.
if (getOption("shiny.autoload.r", TRUE)) {
loadSupport(appDir, renv=sharedEnv, globalrenv=globalenv())
} else {
autoload_r_support_if_needed()
} else {
if (file.exists(file.path.ci(appDir, "global.R")))
sourceUTF8(file.path.ci(appDir, "global.R"))
}
@@ -290,33 +308,77 @@ initAutoReloadMonitor <- function(dir) {
return(function(){})
}
filePattern <- getOption("shiny.autoreload.pattern",
".*\\.(r|html?|js|css|png|jpe?g|gif)$")
filePattern <- getOption(
"shiny.autoreload.pattern",
".*\\.(r|html?|js|css|png|jpe?g|gif)$"
)
lastValue <- NULL
observeLabel <- paste0("File Auto-Reload - '", basename(dir), "'")
obs <- observe(label = observeLabel, {
files <- sort_c(
list.files(dir, pattern = filePattern, recursive = TRUE, ignore.case = TRUE)
)
times <- file.info(files)$mtime
names(times) <- files
if (is.null(lastValue)) {
# First run
lastValue <<- times
} else if (!identical(lastValue, times)) {
# We've changed!
lastValue <<- times
if (is_installed("watcher")) {
check_for_update <- function(paths) {
paths <- grep(
filePattern,
paths,
ignore.case = TRUE,
value = TRUE
)
if (length(paths) == 0) {
return()
}
cachedAutoReloadLastChanged$set()
autoReloadCallbacks$invoke()
}
# [garrick, 2025-02-20] Shiny <= v1.10.0 used `invalidateLater()` with an
# autoreload.interval in ms. {watcher} instead uses a latency parameter in
# seconds, which serves a similar purpose and that I'm keeping for backcompat.
latency <- getOption("shiny.autoreload.interval", 250) / 1000
watcher <- watcher::watcher(dir, check_for_update, latency = latency)
watcher$start()
onStop(watcher$stop)
} else {
# Fall back to legacy observer behavior
if (!is_false(getOption("shiny.autoreload.legacy_warning", TRUE))) {
cli::cli_warn(
c(
"Using legacy autoreload file watching. Please install {.pkg watcher} for a more performant autoreload file watcher.",
"i" = "Set {.run options(shiny.autoreload.legacy_warning = FALSE)} to suppress this warning."
),
.frequency = "regularly",
.frequency_id = "shiny.autoreload.legacy_warning"
)
}
invalidateLater(getOption("shiny.autoreload.interval", 500))
})
lastValue <- NULL
observeLabel <- paste0("File Auto-Reload - '", basename(dir), "'")
watcher <- observe(label = observeLabel, {
files <- sort_c(
list.files(dir, pattern = filePattern, recursive = TRUE, ignore.case = TRUE)
)
times <- file.info(files)$mtime
names(times) <- files
if (is.null(lastValue)) {
# First run
lastValue <<- times
} else if (!identical(lastValue, times)) {
# We've changed!
lastValue <<- times
cachedAutoReloadLastChanged$set()
autoReloadCallbacks$invoke()
}
invalidateLater(getOption("shiny.autoreload.interval", 500))
})
onStop(watcher$destroy)
watcher$destroy
}
onStop(obs$destroy)
obs$destroy
invisible(watcher)
}
#' Load an app's supporting R files
@@ -421,8 +483,6 @@ shinyAppDir_appR <- function(fileName, appDir, options=list())
wasDir <- setwd(appDir)
on.exit(setwd(wasDir))
# TODO: we should support hot reloading on R/*.R changes.
# In an upcoming version of shiny, this option will go away.
if (getOption("shiny.autoload.r", TRUE)) {
# Create a child env which contains all the helpers and will be the shared parent
# of the ui.R and server.R load.

View File

@@ -383,8 +383,10 @@ markOutputAttrs <- function(renderFunc, snapshotExclude = NULL,
#' The corresponding HTML output tag should be `div` or `img` and have
#' the CSS class name `shiny-image-output`.
#'
#' @seealso For more details on how the images are generated, and how to control
#' @seealso
#' * For more details on how the images are generated, and how to control
#' the output, see [plotPNG()].
#' * Use [outputOptions()] to set general output options for an image output.
#'
#' @param expr An expression that returns a list.
#' @inheritParams renderUI
@@ -598,6 +600,7 @@ isTemp <- function(path, tempDir = tempdir(), mustExist) {
#' used in an interactive RMarkdown document.
#'
#' @example res/text-example.R
#' @seealso [outputOptions()]
#' @export
renderPrint <- function(expr, env = parent.frame(), quoted = FALSE,
width = getOption('width'), outputArgs=list())
@@ -719,7 +722,7 @@ renderText <- function(expr, env = parent.frame(), quoted = FALSE,
#' call to [uiOutput()] when `renderUI` is used in an
#' interactive R Markdown document.
#'
#' @seealso [uiOutput()]
#' @seealso [uiOutput()], [outputOptions()]
#' @export
#' @examples
#' ## Only run examples in interactive R sessions
@@ -809,6 +812,13 @@ renderUI <- function(expr, env = parent.frame(), quoted = FALSE,
#'
#' shinyApp(ui, server)
#' }
#'
#' @seealso
#' * The download handler, like other outputs, is suspended (disabled) by
#' default for download buttons and links that are hidden. Use
#' [outputOptions()] to control this behavior, e.g. to set
#' `suspendWhenHidden = FALSE` if the download is initiated by
#' programmatically clicking on the download button using JavaScript.
#' @export
downloadHandler <- function(filename, content, contentType=NULL, outputArgs=list()) {
renderFunc <- function(shinysession, name, ...) {

View File

@@ -158,8 +158,7 @@ print.shiny_runtests <- function(x, ..., reporter = "summary") {
if (any(x$pass)) {
# TODO in future... use clisymbols::symbol$tick and crayon green
cat("* Success\n")
cli::cat_bullet("Success", bullet = "tick", bullet_col = "green")
mapply(
x$file,
x$pass,
@@ -171,9 +170,8 @@ print.shiny_runtests <- function(x, ..., reporter = "summary") {
}
)
}
if (any(!x$pass)) {
# TODO in future... use clisymbols::symbol$cross and crayon red
cat("* Failure\n")
if (!all(x$pass)) {
cli::cat_bullet("Failure", bullet = "cross", bullet_col = "red")
mapply(
x$file,
x$pass,

View File

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

21
R/utils-tags.R Normal file
View File

@@ -0,0 +1,21 @@
# 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

@@ -770,22 +770,45 @@ formatNoSci <- function(x) {
format(x, scientific = FALSE, digits = 15)
}
# A simple getter/setting to track the last time the auto-reload process
# updated. This value is used by `cachedFuncWithFile()` when auto-reload is
# enabled to reload app/ui/server files when watched supporting files change.
cachedAutoReloadLastChanged <- local({
last_update <- 0
list(
set = function() {
last_update <<- as.integer(Sys.time())
invisible(last_update)
},
get = function() {
last_update
}
)
})
# Returns a function that calls the given func and caches the result for
# subsequent calls, unless the given file's mtime changes.
cachedFuncWithFile <- function(dir, file, func, case.sensitive = FALSE) {
dir <- normalizePath(dir, mustWork=TRUE)
mtime <- NA
dir <- normalizePath(dir, mustWork = TRUE)
value <- NULL
last_mtime_file <- NA
last_autoreload <- 0
function(...) {
fname <- if (case.sensitive)
file.path(dir, file)
else
fname <- if (case.sensitive) {
file.path(dir, file)
} else {
file.path.ci(dir, file)
}
now <- file.info(fname)$mtime
if (!identical(mtime, now)) {
autoreload <- last_autoreload < cachedAutoReloadLastChanged$get()
if (autoreload || !identical(last_mtime_file, now)) {
value <<- func(fname, ...)
mtime <<- now
last_mtime_file <<- now
last_autoreload <<- cachedAutoReloadLastChanged$get()
}
value
}

View File

@@ -1,2 +1,2 @@
# Generated by tools/updateBootstrapDatepicker.R; do not edit by hand
version_bs_date_picker <- "1.9.0"
version_bs_date_picker <- "1.10.0"

View File

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

View File

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

View File

@@ -65,4 +65,4 @@ The shiny package as a whole is licensed under the GPLv3. See the [LICENSE](LICE
## R version support
Shiny is supported on the latest release version of R, as well as the previous four minor release versions of R. For example, if the latest release R version is 4.1, then that version is supported, as well as 4.0, 3.6, 3.5, and 3.4.
Shiny is supported on the latest release version of R, as well as the previous four minor release versions of R. For example, if the latest release R version is 4.3, then that version is supported, as well as 4.2, 4.1, 4.0, 3.6.

View File

@@ -1,15 +0,0 @@
{
"presets": [
"@babel/preset-typescript",
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3.12"
}
]
],
"ignore":[
"node_modules/core-js"
]
}

View File

@@ -0,0 +1,40 @@
## revdepcheck results
We checked 1278 reverse dependencies (1277 from CRAN + 1 from Bioconductor), comparing R CMD check results across CRAN and dev versions of shiny.
* We saw 2 new problems (NOTEs only)
* We failed to check 19 packages due to installation issues
Issues with CRAN packages are summarised below.
### New problems
R CMD check displayed NOTEs for two packages, unrelated to changes in shiny.
* HH
checking installed package size ... NOTE
* PopED
checking installed package size ... NOTE
### Failed to check
* animalEKF
* AovBay
* Certara.VPCResults
* chipPCR
* ctsem
* dartR.sim
* diveR
* gap
* jsmodule
* loon.shiny
* robmedExtra
* rstanarm
* SensMap
* Seurat
* shinyTempSignal
* Signac
* statsr
* TestAnaAPP
* tidyvpc

108
eslint.config.mjs Normal file
View File

@@ -0,0 +1,108 @@
import typescriptEslint from "@typescript-eslint/eslint-plugin";
import prettier from "eslint-plugin-prettier";
import unicorn from "eslint-plugin-unicorn";
import globals from "globals";
import tsParser from "@typescript-eslint/parser";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
});
export default [{
ignores: ["**/*.d.ts"],
}, ...compat.extends(
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended",
), {
plugins: {
"@typescript-eslint": typescriptEslint,
prettier,
unicorn,
},
languageOptions: {
globals: {
...globals.browser,
Atomics: "readonly",
SharedArrayBuffer: "readonly",
},
parser: tsParser,
ecmaVersion: 2021,
sourceType: "module",
parserOptions: {
project: ["./tsconfig.json"],
},
},
rules: {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "error",
"default-case": ["error"],
"linebreak-style": ["error", "unix"],
quotes: ["error", "double", "avoid-escape"],
semi: ["error", "always"],
"dot-location": ["error", "property"],
camelcase: ["off"],
"unicorn/filename-case": ["error", {
case: "camelCase",
}],
"@typescript-eslint/array-type": ["error", {
default: "array-simple",
readonly: "array-simple",
}],
"@typescript-eslint/consistent-indexed-object-style": ["error", "index-signature"],
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/naming-convention": ["error", {
selector: "default",
format: ["camelCase"],
}, {
selector: "method",
modifiers: ["private"],
format: ["camelCase"],
leadingUnderscore: "require",
}, {
selector: "method",
modifiers: ["protected"],
format: ["camelCase"],
leadingUnderscore: "require",
}, {
selector: "variable",
format: ["camelCase"],
trailingUnderscore: "forbid",
leadingUnderscore: "forbid",
}, {
selector: "parameter",
format: ["camelCase"],
trailingUnderscore: "allow",
leadingUnderscore: "forbid",
}, {
selector: ["enum", "enumMember"],
format: ["PascalCase"],
}, {
selector: "typeLike",
format: ["PascalCase"],
custom: {
regex: "(t|T)ype$",
match: false,
},
}],
},
}];

View File

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

View File

@@ -1,9 +1,9 @@
<html>
<head>
<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"/>
<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"/>
</head>
<body>

View File

@@ -1,2 +1,2 @@
/*! shiny 1.9.1.9000 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
:where([data-shiny-busy-spinners] .recalculating){position:relative}[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.shiny-html-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(#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}
/*! shiny 1.11.1.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}

View File

@@ -1,5 +1,5 @@
.datepicker {
border-radius: 0.25rem;
border-radius: 3px;
direction: ltr;
}
@@ -30,7 +30,7 @@
display: inline-block;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid rgba(0, 0, 0, 0.15);
border-bottom: 7px solid var(--bs-border-color-translucent);
border-top: 0;
border-bottom-color: rgba(0, 0, 0, 0.2);
position: absolute;
@@ -41,7 +41,7 @@
display: inline-block;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #fff;
border-bottom: 6px solid var(--bs-body-bg);
border-top: 0;
position: absolute;
}
@@ -73,13 +73,13 @@
.datepicker-dropdown.datepicker-orient-top:before {
bottom: -7px;
border-bottom: 0;
border-top: 7px solid rgba(0, 0, 0, 0.15);
border-top: 7px solid var(--bs-border-color-translucent);
}
.datepicker-dropdown.datepicker-orient-top:after {
bottom: -6px;
border-bottom: 0;
border-top: 6px solid #fff;
border-top: 6px solid var(--bs-body-bg);
}
.datepicker table {
@@ -105,64 +105,64 @@
}
.datepicker table tr td.old, .datepicker table tr td.new {
color: #6c757d;
color: #707782;
}
.datepicker table tr td.day:hover, .datepicker table tr td.focused {
color: #000;
background: #e9e9ea;
background: #e8e9e9;
cursor: pointer;
}
.datepicker table tr td.disabled, .datepicker table tr td.disabled:hover {
background: none;
color: #6c757d;
color: #707782;
cursor: default;
}
.datepicker table tr td.highlighted {
color: #000;
background-color: #d1ecf1;
border-color: #83ccd9;
background-color: #cdf4fa;
border-color: #70e0f1;
border-radius: 0;
}
.datepicker table tr td.highlighted:focus, .datepicker table tr td.highlighted.focus {
color: #000;
background-color: #bcd4d9;
border-color: #6299a3;
background-color: #b9dce1;
border-color: #54a8b5;
}
.datepicker table tr td.highlighted:hover {
color: #000;
background-color: #697679;
border-color: #73b3bf;
background-color: #677a7d;
border-color: #63c5d4;
}
.datepicker table tr td.highlighted:active, .datepicker table tr td.highlighted.active {
color: #000;
background-color: #bcd4d9;
border-color: #73b3bf;
background-color: #b9dce1;
border-color: #63c5d4;
}
.datepicker table tr td.highlighted:active:hover, .datepicker table tr td.highlighted:active:focus, .datepicker table tr td.highlighted.focus:active, .datepicker table tr td.highlighted.active:hover, .datepicker table tr td.highlighted.active:focus, .datepicker table tr td.highlighted.active.focus {
.datepicker table tr td.highlighted:active:hover, .datepicker table tr td.highlighted:active:focus, .datepicker table tr td.highlighted:active.focus, .datepicker table tr td.highlighted.active:hover, .datepicker table tr td.highlighted.active:focus, .datepicker table tr td.highlighted.active.focus {
color: #000;
background-color: #adc4c8;
border-color: #6299a3;
background-color: #aacbd0;
border-color: #54a8b5;
}
.datepicker table tr td.highlighted.disabled:hover, .datepicker table tr td.highlighted.disabled:focus, .datepicker table tr td.highlighted.disabled.focus, .datepicker table tr td.highlighted[disabled]:hover, .datepicker table tr td.highlighted[disabled]:focus, .datepicker table tr td.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.highlighted:hover, fieldset[disabled] .datepicker table tr td.highlighted:focus, fieldset[disabled] .datepicker table tr td.highlighted.focus {
background-color: #d1ecf1;
border-color: #83ccd9;
.datepicker table tr td.highlighted.disabled:hover, .datepicker table tr td.highlighted.disabled:focus, .datepicker table tr td.highlighted.disabled.focus, .datepicker table tr td.highlighted[disabled]:hover, .datepicker table tr td.highlighted[disabled]:focus, .datepicker table tr td.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.highlighted:hover, fieldset[disabled] .datepicker table tr td.highlighted:focus, fieldset[disabled] .datepicker table tr td.highlighted.focus {
background-color: #cdf4fa;
border-color: #70e0f1;
}
.datepicker table tr td.highlighted.focused {
background: #aadce5;
background: #9feaf5;
}
.datepicker table tr td.highlighted.disabled, .datepicker table tr td.highlighted.disabled:active {
background: #d1ecf1;
color: #6c757d;
background: #cdf4fa;
color: #707782;
}
.datepicker table tr td.today {
@@ -189,13 +189,13 @@
border-color: #e0a12d;
}
.datepicker table tr td.today:active:hover, .datepicker table tr td.today:active:focus, .datepicker table tr td.today.focus:active, .datepicker table tr td.today.active:hover, .datepicker table tr td.today.active:focus, .datepicker table tr td.today.active.focus {
.datepicker table tr td.today:active:hover, .datepicker table tr td.today:active:focus, .datepicker table tr td.today:active.focus, .datepicker table tr td.today.active:hover, .datepicker table tr td.today.active:focus, .datepicker table tr td.today.active.focus {
color: #000;
background-color: #d4b67f;
border-color: #bf8926;
}
.datepicker table tr td.today.disabled:hover, .datepicker table tr td.today.disabled:focus, .datepicker table tr td.today.disabled.focus, .datepicker table tr td.today[disabled]:hover, .datepicker table tr td.today[disabled]:focus, .datepicker table tr td.today.focus[disabled], fieldset[disabled] .datepicker table tr td.today:hover, fieldset[disabled] .datepicker table tr td.today:focus, fieldset[disabled] .datepicker table tr td.today.focus {
.datepicker table tr td.today.disabled:hover, .datepicker table tr td.today.disabled:focus, .datepicker table tr td.today.disabled.focus, .datepicker table tr td.today[disabled]:hover, .datepicker table tr td.today[disabled]:focus, .datepicker table tr td.today[disabled].focus, fieldset[disabled] .datepicker table tr td.today:hover, fieldset[disabled] .datepicker table tr td.today:focus, fieldset[disabled] .datepicker table tr td.today.focus {
background-color: #ffdb99;
border-color: #ffb733;
}
@@ -206,96 +206,96 @@
.datepicker table tr td.today.disabled, .datepicker table tr td.today.disabled:active {
background: #ffdb99;
color: #6c757d;
color: #707782;
}
.datepicker table tr td.range {
color: #000;
background-color: #e9e9ea;
border-color: #b5b5b8;
background-color: #e8e9e9;
border-color: #b4b7b7;
border-radius: 0;
}
.datepicker table tr td.range:focus, .datepicker table tr td.range.focus {
color: #000;
background-color: #d2d2d3;
border-color: #88888a;
background-color: #d1d2d2;
border-color: #878989;
}
.datepicker table tr td.range:hover {
color: #000;
background-color: #757575;
border-color: #9f9fa2;
background-color: #747575;
border-color: #9ea1a1;
}
.datepicker table tr td.range:active, .datepicker table tr td.range.active {
color: #000;
background-color: #d2d2d3;
border-color: #9f9fa2;
background-color: #d1d2d2;
border-color: #9ea1a1;
}
.datepicker table tr td.range:active:hover, .datepicker table tr td.range:active:focus, .datepicker table tr td.range.focus:active, .datepicker table tr td.range.active:hover, .datepicker table tr td.range.active:focus, .datepicker table tr td.range.active.focus {
.datepicker table tr td.range:active:hover, .datepicker table tr td.range:active:focus, .datepicker table tr td.range:active.focus, .datepicker table tr td.range.active:hover, .datepicker table tr td.range.active:focus, .datepicker table tr td.range.active.focus {
color: #000;
background-color: #c1c1c2;
border-color: #88888a;
background-color: #c1c1c1;
border-color: #878989;
}
.datepicker table tr td.range.disabled:hover, .datepicker table tr td.range.disabled:focus, .datepicker table tr td.range.disabled.focus, .datepicker table tr td.range[disabled]:hover, .datepicker table tr td.range[disabled]:focus, .datepicker table tr td.range.focus[disabled], fieldset[disabled] .datepicker table tr td.range:hover, fieldset[disabled] .datepicker table tr td.range:focus, fieldset[disabled] .datepicker table tr td.range.focus {
background-color: #e9e9ea;
border-color: #b5b5b8;
.datepicker table tr td.range.disabled:hover, .datepicker table tr td.range.disabled:focus, .datepicker table tr td.range.disabled.focus, .datepicker table tr td.range[disabled]:hover, .datepicker table tr td.range[disabled]:focus, .datepicker table tr td.range[disabled].focus, fieldset[disabled] .datepicker table tr td.range:hover, fieldset[disabled] .datepicker table tr td.range:focus, fieldset[disabled] .datepicker table tr td.range.focus {
background-color: #e8e9e9;
border-color: #b4b7b7;
}
.datepicker table tr td.range.focused {
background: #cfcfd1;
background: #ced0d0;
}
.datepicker table tr td.range.disabled, .datepicker table tr td.range.disabled:active {
background: #e9e9ea;
color: #6c757d;
background: #e8e9e9;
color: #707782;
}
.datepicker table tr td.range.highlighted {
color: #000;
background-color: #ddebee;
border-color: #99c3cc;
background-color: #dbeff2;
border-color: #90ced7;
}
.datepicker table tr td.range.highlighted:focus, .datepicker table tr td.range.highlighted.focus {
color: #000;
background-color: #c7d4d6;
border-color: #739299;
background-color: #c5d7da;
border-color: #6c9aa1;
}
.datepicker table tr td.range.highlighted:hover {
color: #000;
background-color: #6f7677;
border-color: #87acb4;
background-color: #6e7879;
border-color: #7fb5bd;
}
.datepicker table tr td.range.highlighted:active, .datepicker table tr td.range.highlighted.active {
color: #000;
background-color: #c7d4d6;
border-color: #87acb4;
background-color: #c5d7da;
border-color: #7fb5bd;
}
.datepicker table tr td.range.highlighted:active:hover, .datepicker table tr td.range.highlighted:active:focus, .datepicker table tr td.range.highlighted.focus:active, .datepicker table tr td.range.highlighted.active:hover, .datepicker table tr td.range.highlighted.active:focus, .datepicker table tr td.range.highlighted.active.focus {
.datepicker table tr td.range.highlighted:active:hover, .datepicker table tr td.range.highlighted:active:focus, .datepicker table tr td.range.highlighted:active.focus, .datepicker table tr td.range.highlighted.active:hover, .datepicker table tr td.range.highlighted.active:focus, .datepicker table tr td.range.highlighted.active.focus {
color: #000;
background-color: #b7c3c6;
border-color: #739299;
background-color: #b6c6c9;
border-color: #6c9aa1;
}
.datepicker table tr td.range.highlighted.disabled:hover, .datepicker table tr td.range.highlighted.disabled:focus, .datepicker table tr td.range.highlighted.disabled.focus, .datepicker table tr td.range.highlighted[disabled]:hover, .datepicker table tr td.range.highlighted[disabled]:focus, .datepicker table tr td.range.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.range.highlighted:hover, fieldset[disabled] .datepicker table tr td.range.highlighted:focus, fieldset[disabled] .datepicker table tr td.range.highlighted.focus {
background-color: #ddebee;
border-color: #99c3cc;
.datepicker table tr td.range.highlighted.disabled:hover, .datepicker table tr td.range.highlighted.disabled:focus, .datepicker table tr td.range.highlighted.disabled.focus, .datepicker table tr td.range.highlighted[disabled]:hover, .datepicker table tr td.range.highlighted[disabled]:focus, .datepicker table tr td.range.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.range.highlighted:hover, fieldset[disabled] .datepicker table tr td.range.highlighted:focus, fieldset[disabled] .datepicker table tr td.range.highlighted.focus {
background-color: #dbeff2;
border-color: #90ced7;
}
.datepicker table tr td.range.highlighted.focused {
background: #bbd7dd;
background: #b6dee4;
}
.datepicker table tr td.range.highlighted.disabled, .datepicker table tr td.range.highlighted.disabled:active {
background: #ddebee;
color: #6c757d;
background: #dbeff2;
color: #707782;
}
.datepicker table tr td.range.today {
@@ -322,92 +322,92 @@
border-color: #d08d14;
}
.datepicker table tr td.range.today:active:hover, .datepicker table tr td.range.today:active:focus, .datepicker table tr td.range.today.focus:active, .datepicker table tr td.range.today.active:hover, .datepicker table tr td.range.today.active:focus, .datepicker table tr td.range.today.active.focus {
.datepicker table tr td.range.today:active:hover, .datepicker table tr td.range.today:active:focus, .datepicker table tr td.range.today:active.focus, .datepicker table tr td.range.today.active:hover, .datepicker table tr td.range.today.active:focus, .datepicker table tr td.range.today.active.focus {
color: #000;
background-color: #cba561;
border-color: #b17811;
}
.datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today.disabled:focus, .datepicker table tr td.range.today.disabled.focus, .datepicker table tr td.range.today[disabled]:hover, .datepicker table tr td.range.today[disabled]:focus, .datepicker table tr td.range.today.focus[disabled], fieldset[disabled] .datepicker table tr td.range.today:hover, fieldset[disabled] .datepicker table tr td.range.today:focus, fieldset[disabled] .datepicker table tr td.range.today.focus {
.datepicker table tr td.range.today.disabled:hover, .datepicker table tr td.range.today.disabled:focus, .datepicker table tr td.range.today.disabled.focus, .datepicker table tr td.range.today[disabled]:hover, .datepicker table tr td.range.today[disabled]:focus, .datepicker table tr td.range.today[disabled].focus, fieldset[disabled] .datepicker table tr td.range.today:hover, fieldset[disabled] .datepicker table tr td.range.today:focus, fieldset[disabled] .datepicker table tr td.range.today.focus {
background-color: #f4c775;
border-color: #eca117;
}
.datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today.disabled:active {
background: #f4c775;
color: #6c757d;
color: #707782;
}
.datepicker table tr td.selected, .datepicker table tr td.selected.highlighted {
color: #fff;
background-color: #898b8d;
border-color: #6b6e71;
color: #000;
background-color: #878889;
border-color: #606060;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.selected:focus, .datepicker table tr td.selected.focus, .datepicker table tr td.selected.highlighted:focus, .datepicker table tr td.selected.highlighted.focus {
color: #fff;
background-color: #959798;
border-color: #909295;
color: #000;
background-color: #7a7a7b;
border-color: #484848;
}
.datepicker table tr td.selected:hover, .datepicker table tr td.selected.highlighted:hover {
color: #fff;
background-color: #c4c5c6;
border-color: #7d7f82;
color: #000;
background-color: #444445;
border-color: #545454;
}
.datepicker table tr td.selected:active, .datepicker table tr td.selected.active, .datepicker table tr td.selected.highlighted:active, .datepicker table tr td.selected.highlighted.active {
color: #fff;
background-color: #959798;
border-color: #7d7f82;
color: #000;
background-color: #7a7a7b;
border-color: #545454;
}
.datepicker table tr td.selected:active:hover, .datepicker table tr td.selected:active:focus, .datepicker table tr td.selected.focus:active, .datepicker table tr td.selected.active:hover, .datepicker table tr td.selected.active:focus, .datepicker table tr td.selected.active.focus, .datepicker table tr td.selected.highlighted:active:hover, .datepicker table tr td.selected.highlighted:active:focus, .datepicker table tr td.selected.highlighted.focus:active, .datepicker table tr td.selected.highlighted.active:hover, .datepicker table tr td.selected.highlighted.active:focus, .datepicker table tr td.selected.highlighted.active.focus {
color: #fff;
background-color: #9d9fa0;
border-color: #909295;
.datepicker table tr td.selected:active:hover, .datepicker table tr td.selected:active:focus, .datepicker table tr td.selected:active.focus, .datepicker table tr td.selected.active:hover, .datepicker table tr td.selected.active:focus, .datepicker table tr td.selected.active.focus, .datepicker table tr td.selected.highlighted:active:hover, .datepicker table tr td.selected.highlighted:active:focus, .datepicker table tr td.selected.highlighted:active.focus, .datepicker table tr td.selected.highlighted.active:hover, .datepicker table tr td.selected.highlighted.active:focus, .datepicker table tr td.selected.highlighted.active.focus {
color: #000;
background-color: #707172;
border-color: #484848;
}
.datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected.disabled:focus, .datepicker table tr td.selected.disabled.focus, .datepicker table tr td.selected[disabled]:hover, .datepicker table tr td.selected[disabled]:focus, .datepicker table tr td.selected.focus[disabled], fieldset[disabled] .datepicker table tr td.selected:hover, fieldset[disabled] .datepicker table tr td.selected:focus, fieldset[disabled] .datepicker table tr td.selected.focus, .datepicker table tr td.selected.highlighted.disabled:hover, .datepicker table tr td.selected.highlighted.disabled:focus, .datepicker table tr td.selected.highlighted.disabled.focus, .datepicker table tr td.selected.highlighted[disabled]:hover, .datepicker table tr td.selected.highlighted[disabled]:focus, .datepicker table tr td.selected.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.selected.highlighted:hover, fieldset[disabled] .datepicker table tr td.selected.highlighted:focus, fieldset[disabled] .datepicker table tr td.selected.highlighted.focus {
background-color: #898b8d;
border-color: #6b6e71;
.datepicker table tr td.selected.disabled:hover, .datepicker table tr td.selected.disabled:focus, .datepicker table tr td.selected.disabled.focus, .datepicker table tr td.selected[disabled]:hover, .datepicker table tr td.selected[disabled]:focus, .datepicker table tr td.selected[disabled].focus, fieldset[disabled] .datepicker table tr td.selected:hover, fieldset[disabled] .datepicker table tr td.selected:focus, fieldset[disabled] .datepicker table tr td.selected.focus, .datepicker table tr td.selected.highlighted.disabled:hover, .datepicker table tr td.selected.highlighted.disabled:focus, .datepicker table tr td.selected.highlighted.disabled.focus, .datepicker table tr td.selected.highlighted[disabled]:hover, .datepicker table tr td.selected.highlighted[disabled]:focus, .datepicker table tr td.selected.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.selected.highlighted:hover, fieldset[disabled] .datepicker table tr td.selected.highlighted:focus, fieldset[disabled] .datepicker table tr td.selected.highlighted.focus {
background-color: #878889;
border-color: #606060;
}
.datepicker table tr td.active, .datepicker table tr td.active.highlighted {
color: #fff;
background-color: #007bff;
border-color: #0277f4;
color: #ffffff;
background-color: #007bc2;
border-color: #0176ba;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td.active:focus, .datepicker table tr td.active.focus, .datepicker table tr td.active.highlighted:focus, .datepicker table tr td.active.highlighted.focus {
color: #fff;
background-color: #1a88ff;
border-color: #4199f7;
color: #ffffff;
background-color: #1a88c8;
border-color: #4198cb;
}
.datepicker table tr td.active:hover, .datepicker table tr td.active.highlighted:hover {
color: #fff;
background-color: #80bdff;
border-color: #2087f5;
color: #ffffff;
background-color: #80bde1;
border-color: #1f86c2;
}
.datepicker table tr td.active:active, .datepicker table tr td.active.active, .datepicker table tr td.active.highlighted:active, .datepicker table tr td.active.highlighted.active {
color: #fff;
background-color: #1a88ff;
border-color: #2087f5;
color: #ffffff;
background-color: #1a88c8;
border-color: #1f86c2;
}
.datepicker table tr td.active:active:hover, .datepicker table tr td.active:active:focus, .datepicker table tr td.active.focus:active, .datepicker table tr td.active.active:hover, .datepicker table tr td.active.active:focus, .datepicker table tr td.active.active.focus, .datepicker table tr td.active.highlighted:active:hover, .datepicker table tr td.active.highlighted:active:focus, .datepicker table tr td.active.highlighted.focus:active, .datepicker table tr td.active.highlighted.active:hover, .datepicker table tr td.active.highlighted.active:focus, .datepicker table tr td.active.highlighted.active.focus {
color: #fff;
background-color: #2b91ff;
border-color: #4199f7;
.datepicker table tr td.active:active:hover, .datepicker table tr td.active:active:focus, .datepicker table tr td.active:active.focus, .datepicker table tr td.active.active:hover, .datepicker table tr td.active.active:focus, .datepicker table tr td.active.active.focus, .datepicker table tr td.active.highlighted:active:hover, .datepicker table tr td.active.highlighted:active:focus, .datepicker table tr td.active.highlighted:active.focus, .datepicker table tr td.active.highlighted.active:hover, .datepicker table tr td.active.highlighted.active:focus, .datepicker table tr td.active.highlighted.active.focus {
color: #ffffff;
background-color: #2b91cc;
border-color: #4198cb;
}
.datepicker table tr td.active.disabled:hover, .datepicker table tr td.active.disabled:focus, .datepicker table tr td.active.disabled.focus, .datepicker table tr td.active[disabled]:hover, .datepicker table tr td.active[disabled]:focus, .datepicker table tr td.active.focus[disabled], fieldset[disabled] .datepicker table tr td.active:hover, fieldset[disabled] .datepicker table tr td.active:focus, fieldset[disabled] .datepicker table tr td.active.focus, .datepicker table tr td.active.highlighted.disabled:hover, .datepicker table tr td.active.highlighted.disabled:focus, .datepicker table tr td.active.highlighted.disabled.focus, .datepicker table tr td.active.highlighted[disabled]:hover, .datepicker table tr td.active.highlighted[disabled]:focus, .datepicker table tr td.active.highlighted.focus[disabled], fieldset[disabled] .datepicker table tr td.active.highlighted:hover, fieldset[disabled] .datepicker table tr td.active.highlighted:focus, fieldset[disabled] .datepicker table tr td.active.highlighted.focus {
background-color: #007bff;
border-color: #0277f4;
.datepicker table tr td.active.disabled:hover, .datepicker table tr td.active.disabled:focus, .datepicker table tr td.active.disabled.focus, .datepicker table tr td.active[disabled]:hover, .datepicker table tr td.active[disabled]:focus, .datepicker table tr td.active[disabled].focus, fieldset[disabled] .datepicker table tr td.active:hover, fieldset[disabled] .datepicker table tr td.active:focus, fieldset[disabled] .datepicker table tr td.active.focus, .datepicker table tr td.active.highlighted.disabled:hover, .datepicker table tr td.active.highlighted.disabled:focus, .datepicker table tr td.active.highlighted.disabled.focus, .datepicker table tr td.active.highlighted[disabled]:hover, .datepicker table tr td.active.highlighted[disabled]:focus, .datepicker table tr td.active.highlighted[disabled].focus, fieldset[disabled] .datepicker table tr td.active.highlighted:hover, fieldset[disabled] .datepicker table tr td.active.highlighted:focus, fieldset[disabled] .datepicker table tr td.active.highlighted.focus {
background-color: #007bc2;
border-color: #0176ba;
}
.datepicker table tr td span {
@@ -423,53 +423,53 @@
.datepicker table tr td span:hover, .datepicker table tr td span.focused {
color: #000;
background: #e9e9ea;
background: #e8e9e9;
}
.datepicker table tr td span.disabled, .datepicker table tr td span.disabled:hover {
background: none;
color: #6c757d;
color: #707782;
cursor: default;
}
.datepicker table tr td span.active, .datepicker table tr td span.active:hover, .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled:hover {
color: #fff;
background-color: #007bff;
border-color: #0277f4;
color: #ffffff;
background-color: #007bc2;
border-color: #0176ba;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.datepicker table tr td span.active:focus, .datepicker table tr td span.active.focus, .datepicker table tr td span.active:hover:focus, .datepicker table tr td span.active.focus:hover, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled:hover:focus, .datepicker table tr td span.active.disabled.focus:hover {
color: #fff;
background-color: #1a88ff;
border-color: #4199f7;
.datepicker table tr td span.active:focus, .datepicker table tr td span.active.focus, .datepicker table tr td span.active:hover:focus, .datepicker table tr td span.active:hover.focus, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled:hover:focus, .datepicker table tr td span.active.disabled:hover.focus {
color: #ffffff;
background-color: #1a88c8;
border-color: #4198cb;
}
.datepicker table tr td span.active:hover, .datepicker table tr td span.active:hover:hover, .datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:hover:hover {
color: #fff;
background-color: #80bdff;
border-color: #2087f5;
color: #ffffff;
background-color: #80bde1;
border-color: #1f86c2;
}
.datepicker table tr td span.active:active, .datepicker table tr td span.active.active, .datepicker table tr td span.active:hover:active, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active.disabled.active:hover {
color: #fff;
background-color: #1a88ff;
border-color: #2087f5;
.datepicker table tr td span.active:active, .datepicker table tr td span.active.active, .datepicker table tr td span.active:hover:active, .datepicker table tr td span.active:hover.active, .datepicker table tr td span.active.disabled:active, .datepicker table tr td span.active.disabled.active, .datepicker table tr td span.active.disabled:hover:active, .datepicker table tr td span.active.disabled:hover.active {
color: #ffffff;
background-color: #1a88c8;
border-color: #1f86c2;
}
.datepicker table tr td span.active:active:hover, .datepicker table tr td span.active:active:focus, .datepicker table tr td span.active.focus:active, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.active:focus, .datepicker table tr td span.active.active.focus, .datepicker table tr td span.active:hover:active:hover, .datepicker table tr td span.active:hover:active:focus, .datepicker table tr td span.active.focus:hover:active, .datepicker table tr td span.active.active:hover:hover, .datepicker table tr td span.active.active:hover:focus, .datepicker table tr td span.active.active.focus:hover, .datepicker table tr td span.active.disabled:active:hover, .datepicker table tr td span.active.disabled:active:focus, .datepicker table tr td span.active.disabled.focus:active, .datepicker table tr td span.active.disabled.active:hover, .datepicker table tr td span.active.disabled.active:focus, .datepicker table tr td span.active.disabled.active.focus, .datepicker table tr td span.active.disabled:hover:active:hover, .datepicker table tr td span.active.disabled:hover:active:focus, .datepicker table tr td span.active.disabled.focus:hover:active, .datepicker table tr td span.active.disabled.active:hover:hover, .datepicker table tr td span.active.disabled.active:hover:focus, .datepicker table tr td span.active.disabled.active.focus:hover {
color: #fff;
background-color: #2b91ff;
border-color: #4199f7;
.datepicker table tr td span.active:active:hover, .datepicker table tr td span.active:active:focus, .datepicker table tr td span.active:active.focus, .datepicker table tr td span.active.active:hover, .datepicker table tr td span.active.active:focus, .datepicker table tr td span.active.active.focus, .datepicker table tr td span.active:hover:active:hover, .datepicker table tr td span.active:hover:active:focus, .datepicker table tr td span.active:hover:active.focus, .datepicker table tr td span.active:hover.active:hover, .datepicker table tr td span.active:hover.active:focus, .datepicker table tr td span.active:hover.active.focus, .datepicker table tr td span.active.disabled:active:hover, .datepicker table tr td span.active.disabled:active:focus, .datepicker table tr td span.active.disabled:active.focus, .datepicker table tr td span.active.disabled.active:hover, .datepicker table tr td span.active.disabled.active:focus, .datepicker table tr td span.active.disabled.active.focus, .datepicker table tr td span.active.disabled:hover:active:hover, .datepicker table tr td span.active.disabled:hover:active:focus, .datepicker table tr td span.active.disabled:hover:active.focus, .datepicker table tr td span.active.disabled:hover.active:hover, .datepicker table tr td span.active.disabled:hover.active:focus, .datepicker table tr td span.active.disabled:hover.active.focus {
color: #ffffff;
background-color: #2b91cc;
border-color: #4198cb;
}
.datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active[disabled]:hover, .datepicker table tr td span.active[disabled]:focus, .datepicker table tr td span.active.focus[disabled], fieldset[disabled] .datepicker table tr td span.active:hover, fieldset[disabled] .datepicker table tr td span.active:focus, fieldset[disabled] .datepicker table tr td span.active.focus, .datepicker table tr td span.active.disabled:hover:hover, .datepicker table tr td span.active.disabled:hover:focus, .datepicker table tr td span.active.disabled.focus:hover, .datepicker table tr td span.active[disabled]:hover:hover, .datepicker table tr td span.active[disabled]:hover:focus, .datepicker table tr td span.active.focus[disabled]:hover, fieldset[disabled] .datepicker table tr td span.active:hover:hover, fieldset[disabled] .datepicker table tr td span.active:hover:focus, fieldset[disabled] .datepicker table tr td span.active.focus:hover, .datepicker table tr td span.active.disabled.disabled:hover, .datepicker table tr td span.active.disabled.disabled:focus, .datepicker table tr td span.active.disabled.disabled.focus, .datepicker table tr td span.active.disabled[disabled]:hover, .datepicker table tr td span.active.disabled[disabled]:focus, .datepicker table tr td span.active.disabled.focus[disabled], fieldset[disabled] .datepicker table tr td span.active.disabled:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:focus, fieldset[disabled] .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled.disabled:hover:hover, .datepicker table tr td span.active.disabled.disabled:hover:focus, .datepicker table tr td span.active.disabled.disabled.focus:hover, .datepicker table tr td span.active.disabled[disabled]:hover:hover, .datepicker table tr td span.active.disabled[disabled]:hover:focus, .datepicker table tr td span.active.disabled.focus[disabled]:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, fieldset[disabled] .datepicker table tr td span.active.disabled.focus:hover {
background-color: #007bff;
border-color: #0277f4;
.datepicker table tr td span.active.disabled:hover, .datepicker table tr td span.active.disabled:focus, .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active[disabled]:hover, .datepicker table tr td span.active[disabled]:focus, .datepicker table tr td span.active[disabled].focus, fieldset[disabled] .datepicker table tr td span.active:hover, fieldset[disabled] .datepicker table tr td span.active:focus, fieldset[disabled] .datepicker table tr td span.active.focus, .datepicker table tr td span.active:hover.disabled:hover, .datepicker table tr td span.active:hover.disabled:focus, .datepicker table tr td span.active:hover.disabled.focus, .datepicker table tr td span.active:hover[disabled]:hover, .datepicker table tr td span.active:hover[disabled]:focus, .datepicker table tr td span.active:hover[disabled].focus, fieldset[disabled] .datepicker table tr td span.active:hover:hover, fieldset[disabled] .datepicker table tr td span.active:hover:focus, fieldset[disabled] .datepicker table tr td span.active:hover.focus, .datepicker table tr td span.active.disabled.disabled:hover, .datepicker table tr td span.active.disabled.disabled:focus, .datepicker table tr td span.active.disabled.disabled.focus, .datepicker table tr td span.active.disabled[disabled]:hover, .datepicker table tr td span.active.disabled[disabled]:focus, .datepicker table tr td span.active.disabled[disabled].focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:focus, fieldset[disabled] .datepicker table tr td span.active.disabled.focus, .datepicker table tr td span.active.disabled:hover.disabled:hover, .datepicker table tr td span.active.disabled:hover.disabled:focus, .datepicker table tr td span.active.disabled:hover.disabled.focus, .datepicker table tr td span.active.disabled:hover[disabled]:hover, .datepicker table tr td span.active.disabled:hover[disabled]:focus, .datepicker table tr td span.active.disabled:hover[disabled].focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, fieldset[disabled] .datepicker table tr td span.active.disabled:hover.focus {
background-color: #007bc2;
border-color: #0176ba;
}
.datepicker table tr td span.old, .datepicker table tr td span.new {
color: #6c757d;
color: #707782;
}
.datepicker .datepicker-switch {
@@ -488,7 +488,7 @@
.datepicker .next:hover,
.datepicker tfoot tr th:hover {
color: #000;
background: #e9e9ea;
background: #e8e9e9;
}
.datepicker .prev.disabled, .datepicker .next.disabled {

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
/*!
* Datepicker for Bootstrap v1.9.0 (https://github.com/uxsolutions/bootstrap-datepicker)
* Datepicker for Bootstrap v1.10.0 (https://github.com/uxsolutions/bootstrap-datepicker)
*
* Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* Licensed under the Apache License v2.0 (https://www.apache.org/licenses/LICENSE-2.0)
*/
(function(factory){
@@ -61,7 +61,7 @@
replace: function(new_array){
if (!new_array)
return;
if (!$.isArray(new_array))
if (!Array.isArray(new_array))
new_array = [new_array];
this.clear();
this.push.apply(this, new_array);
@@ -103,9 +103,15 @@
this.isInput = this.element.is('input');
this.inputField = this.isInput ? this.element : this.element.find('input');
this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .input-group-append, .input-group-prepend, .btn') : false;
if (this.component && this.component.length === 0)
if (this.component && this.component.length === 0){
this.component = false;
this.isInline = !this.component && this.element.is('div');
}
if (this.o.isInline === null){
this.isInline = !this.component && !this.isInput;
} else {
this.isInline = this.o.isInline;
}
this.picker = $(DPGlobal.template);
@@ -176,7 +182,7 @@
},
_resolveDaysOfWeek: function(daysOfWeek){
if (!$.isArray(daysOfWeek))
if (!Array.isArray(daysOfWeek))
daysOfWeek = daysOfWeek.split(/[,\s]*/);
return $.map(daysOfWeek, Number);
},
@@ -263,7 +269,7 @@
o.daysOfWeekHighlighted = this._resolveDaysOfWeek(o.daysOfWeekHighlighted||[]);
o.datesDisabled = o.datesDisabled||[];
if (!$.isArray(o.datesDisabled)) {
if (!Array.isArray(o.datesDisabled)) {
o.datesDisabled = o.datesDisabled.split(',');
}
o.datesDisabled = $.map(o.datesDisabled, function(d){
@@ -570,16 +576,15 @@
clearDates: function(){
this.inputField.val('');
this.update();
this._trigger('changeDate');
this.update();
if (this.o.autoclose) {
this.hide();
}
},
setDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
var args = Array.isArray(arguments[0]) ? arguments[0] : arguments;
this.update.apply(this, args);
this._trigger('changeDate');
this.setValue();
@@ -587,7 +592,7 @@
},
setUTCDates: function(){
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
var args = Array.isArray(arguments[0]) ? arguments[0] : arguments;
this.setDates.apply(this, $.map(args, this._utc_to_local));
return this;
},
@@ -1039,7 +1044,7 @@
//Check if uniqueSort exists (supported by jquery >=1.12 and >=2.2)
//Fallback to unique function for older jquery versions
if ($.isFunction($.uniqueSort)) {
if (typeof $.uniqueSort === "function") {
clsName = $.uniqueSort(clsName);
} else {
clsName = $.unique(clsName);
@@ -1571,12 +1576,12 @@
if (new_date < this.dates[j]){
// Date being moved earlier/left
while (j >= 0 && new_date < this.dates[j]){
while (j >= 0 && new_date < this.dates[j] && (this.pickers[j].element.val() || "").length > 0) {
this.pickers[j--].setUTCDate(new_date);
}
} else if (new_date > this.dates[k]){
// Date being moved later/right
while (k < l && new_date > this.dates[k]){
while (k < l && new_date > this.dates[k] && (this.pickers[k].element.val() || "").length > 0) {
this.pickers[k++].setUTCDate(new_date);
}
}
@@ -1690,6 +1695,7 @@
endDate: Infinity,
forceParse: true,
format: 'mm/dd/yyyy',
isInline: null,
keepEmptyValues: false,
keyboardNavigation: true,
language: 'en',
@@ -2007,7 +2013,7 @@
/* DATEPICKER VERSION
* =================== */
$.fn.datepicker.version = '1.9.0';
$.fn.datepicker.version = '1.10.0';
$.fn.datepicker.deprecated = function(msg){
var console = window.console;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates["ar-DZ"]={days:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت","الأحد"],daysShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت","أحد"],daysMin:["ح","ن","ث","ع","خ","ج","س","ح"],months:["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويليه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthsShort:["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويليه","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],today:"هذا اليوم",rtl:!0,monthsTitle:"أشهر",clear:"إزالة",format:"yyyy/mm/dd",weekStart:0}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.ca={days:["Diumenge","Dilluns","Dimarts","Dimecres","Dijous","Divendres","Dissabte"],daysShort:["Diu","Dil","Dmt","Dmc","Dij","Div","Dis"],daysMin:["dg","dl","dt","dc","dj","dv","ds"],months:["Gener","Febrer","Març","Abril","Maig","Juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],monthsShort:["Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Set","Oct","Nov","Des"],today:"Avui",monthsTitle:"Mesos",clear:"Esborrar",weekStart:1,format:"dd/mm/yyyy"}}(jQuery);
!function(a){a.fn.datepicker.dates.ca={days:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],daysShort:["dg.","dl.","dt.","dc.","dj.","dv.","ds."],daysMin:["dg","dl","dt","dc","dj","dv","ds"],months:["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre"],monthsShort:["gen.","febr.","març","abr.","maig","juny","jul.","ag.","set.","oct.","nov.","des."],today:"Avui",monthsTitle:"Mesos",clear:"Esborra",weekStart:1,format:"dd/mm/yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["Son","Mon","Die","Mit","Don","Fre","Sam"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",monthsTitle:"Monate",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery);
!function(a){a.fn.datepicker.dates.de={days:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],daysShort:["So","Mo","Di","Mi","Do","Fr","Sa"],daysMin:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthsShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],today:"Heute",monthsTitle:"Monate",clear:"Löschen",weekStart:1,format:"dd.mm.yyyy"}}(jQuery);

View File

@@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates["en-US"]={days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",monthsTitle:"Months",clear:"Clear",weekStart:0,format:"m/d/yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.fi={days:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],daysShort:["sun","maa","tii","kes","tor","per","lau"],daysMin:["su","ma","ti","ke","to","pe","la"],months:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tam","hel","maa","huh","tou","kes","hei","elo","syy","lok","mar","jou"],today:"tänään",clear:"Tyhjennä",weekStart:1,format:"d.m.yyyy"}}(jQuery);
!function(a){a.fn.datepicker.dates.fi={days:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"],daysShort:["sun","maa","tii","kes","tor","per","lau"],daysMin:["su","ma","ti","ke","to","pe","la"],months:["tammikuu","helmikuu","maaliskuu","huhtikuu","toukokuu","kesäkuu","heinäkuu","elokuu","syyskuu","lokakuu","marraskuu","joulukuu"],monthsShort:["tammi","helmi","maalis","huhti","touko","kesä","hei","elo","syys","loka","marras","joulu"],today:"tänään",clear:"Tyhjennä",weekStart:1,format:"d.m.yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.id={days:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],daysShort:["Mgu","Sen","Sel","Rab","Kam","Jum","Sab"],daysMin:["Mg","Sn","Sl","Ra","Ka","Ju","Sa"],months:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Ags","Sep","Okt","Nov","Des"],today:"Hari Ini",clear:"Kosongkan"}}(jQuery);
!function(a){a.fn.datepicker.dates.id={days:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],daysShort:["Min","Sen","Sel","Rab","Kam","Jum","Sab"],daysMin:["Mg","Sn","Sl","Rb","Km","Jm","Sb"],months:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],monthsShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agt","Sep","Okt","Nov","Des"],today:"Hari Ini",monthsTitle:"Bulan",clear:"Kosongkan",weekStart:0,format:"dd-mm-yyyy"}}(jQuery);

View File

@@ -0,0 +1 @@
!function(a){a.fn.datepicker.dates.mar={days:["रविवार","सोमवार","मंगळवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],daysShort:["रवि","सोम","मंगळ","बुध","गुरु","शुक्र","शनि"],daysMin:["र","सो","मं","बु","गु","शु","श"],months:["जानेवारी","फेब्रुवारी","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टेंबर","ऑक्टोबर","नोव्हेंबर","डिसेंबर"],monthsShort:["जाने.","फेब्रु.","मार्च","एप्रिल","मे","जून","जुलै","ऑगस्ट","सप्टें.","ऑक्टो.","नोव्हें.","डिसें."],today:"आज",monthsTitle:"महीने",clear:"हटवा",weekStart:1,format:"dd / mm / yyyy"}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates.uk={days:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"],daysShort:["Нед","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Cічень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthsShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],today:"Сьогодні",clear:"Очистити",format:"dd.mm.yyyy",weekStart:1}}(jQuery);
!function(a){a.fn.datepicker.dates.uk={days:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"],daysShort:["Нед","Пнд","Втр","Срд","Чтв","Птн","Суб"],daysMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthsShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],today:"Сьогодні",clear:"Очистити",format:"dd.mm.yyyy",weekStart:1}}(jQuery);

View File

@@ -1 +1 @@
!function(a){a.fn.datepicker.dates["zh-TW"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["週日","週一","週二","週三","週四","週五","週六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",format:"yyyymmdd",weekStart:1,clear:"清除"}}(jQuery);
!function(a){a.fn.datepicker.dates["zh-TW"]={days:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],daysShort:["週日","週一","週二","週三","週四","週五","週六"],daysMin:["日","一","二","三","四","五","六"],months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthsShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],today:"今天",monthsTitle:"月份",format:"yyyy/mm/dd",weekStart:0,titleFormat:"yyyy年mm月",clear:"清除"}}(jQuery);

File diff suppressed because one or more lines are too long

View File

@@ -31,7 +31,6 @@ Michael Bensoussan <mickey@seesmic.com>
Louis-Rémi Babé <lrbabe@gmail.com>
Robert Katić <robert.katic@gmail.com>
Damian Janowski <damian.janowski@gmail.com>
Anton Kovalyov <anton@kovalyov.net>
Dušan B. Jovanovic <dbjdbj@gmail.com>
Earle Castledine <mrspeaker@gmail.com>
Rich Dougherty <rich@rd.gen.nz>
@@ -69,11 +68,11 @@ temp01 <temp01irc@gmail.com>
Colin Snover <github.com@zetafleet.com>
Jared Grippe <jared@deadlyicon.com>
Ryan W Tenney <ryan@10e.us>
Alex Sexton <AlexSexton@gmail.com>
Pinhook <contact@pinhooklabs.com>
Ron Otten <r.j.g.otten@gmail.com>
Jephte Clain <Jephte.Clain@univ-reunion.fr>
Anton Matzneller <obhvsbypqghgc@gmail.com>
Alex Sexton <AlexSexton@gmail.com>
Dan Heberden <danheberden@gmail.com>
Henri Wiechers <hwiechers@gmail.com>
Russell Holbrook <russell.holbrook@patch.com>
@@ -87,9 +86,10 @@ Sylvester Keil <sylvester@keil.or.at>
Brandon Sterne <bsterne@mozilla.com>
Mathias Bynens <mathias@qiwi.be>
Lee Carpenter <elcarpie@gmail.com>
Timmy Willison <4timmywil@gmail.com>
Timmy Willison <timmywil@users.noreply.github.com>
Corey Frang <gnarf37@gmail.com>
Digitalxero <digitalxero>
Anton Kovalyov <anton@kovalyov.net>
David Murdoch <david@davidmurdoch.com>
Josh Varner <josh.varner@gmail.com>
Charles McNulty <cmcnulty@kznf.com>
@@ -111,7 +111,7 @@ Mike Sherov <mike.sherov@gmail.com>
Greg Hazel <ghazel@gmail.com>
Schalk Neethling <schalk@ossreleasefeed.com>
Denis Knauf <Denis.Knauf@gmail.com>
Timo Tijhof <krinklemail@gmail.com>
Timo Tijhof <krinkle@fastmail.com>
Steen Nielsen <swinedk@gmail.com>
Anton Ryzhov <anton@ryzhov.me>
Shi Chuan <shichuanr@gmail.com>
@@ -151,7 +151,6 @@ Chris Faulkner <thefaulkner@gmail.com>
Marcel Greter <marcel.greter@ocbnet.ch>
Elijah Manor <elijah.manor@gmail.com>
Daniel Chatfield <chatfielddaniel@gmail.com>
Daniel Gálvez <dgalvez@editablething.com>
Nikita Govorov <nikita.govorov@gmail.com>
Wesley Walser <waw325@gmail.com>
Mike Pennisi <mike@mikepennisi.com>
@@ -162,9 +161,7 @@ Dave Riddle <david@joyvuu.com>
Callum Macrae <callum@lynxphp.com>
Jonathan Sampson <jjdsampson@gmail.com>
Benjamin Truyman <bentruyman@gmail.com>
Jay Merrifield <fracmak@gmail.com>
James Huston <james@jameshuston.net>
Sai Lung Wong <sai.wong@huffingtonpost.com>
Erick Ruiz de Chávez <erickrdch@gmail.com>
David Bonner <dbonner@cogolabs.com>
Allen J Schmidt Jr <cobrasoft@gmail.com>
@@ -174,8 +171,11 @@ Ismail Khair <ismail.khair@gmail.com>
Carl Danley <carldanley@gmail.com>
Mike Petrovich <michael.c.petrovich@gmail.com>
Greg Lavallee <greglavallee@wapolabs.com>
Daniel Gálvez <dgalvez@editablething.com>
Sai Lung Wong <sai.wong@huffingtonpost.com>
Tom H Fuertes <TomFuertes@gmail.com>
Roland Eckl <eckl.roland@googlemail.com>
Jay Merrifield <fracmak@gmail.com>
Yiming He <yiminghe@gmail.com>
David Fox <dfoxinator@gmail.com>
Bennett Sorbo <bsorbo@gmail.com>
@@ -192,9 +192,9 @@ Diego Tres <diegotres@gmail.com>
Jean Boussier <jean.boussier@gmail.com>
Andrew Plummer <plummer.andrew@gmail.com>
Mark Raddatz <mraddatz@gmail.com>
Pascal Borreli <pascal@borreli.com>
Isaac Z. Schlueter <i@izs.me>
Karl Sieburg <ksieburg@yahoo.com>
Pascal Borreli <pascal@borreli.com>
Nguyen Phuc Lam <ruado1987@gmail.com>
Dmitry Gusev <dmitry.gusev@gmail.com>
Steven Benner <admin@stevenbenner.com>
@@ -202,7 +202,6 @@ Li Xudong <istonelee@gmail.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Renato Oliveira dos Santos <ros3@cin.ufpe.br>
Frederic Junod <frederic.junod@camptocamp.com>
Tom H Fuertes <tomfuertes@gmail.com>
Mitch Foley <mitch@thefoley.net>
ros3cin <ros3@cin.ufpe.br>
Kyle Robinson Young <kyle@dontkry.com>
@@ -250,7 +249,6 @@ Dan Hart <danhart@notonthehighstreet.com>
Nazar Mokrynskyi <nazar@mokrynskyi.com>
Benjamin Tan <demoneaux@gmail.com>
Amit Merchant <bullredeyes@gmail.com>
Jason Bedard <jason+github@jbedard.ca>
Veaceslav Grimalschi <grimalschi@yandex.ru>
Richard McDaniel <rm0026@uah.edu>
Arthur Verschaeve <contact@arthurverschaeve.be>
@@ -273,12 +271,12 @@ Jon Hester <jon.d.hester@gmail.com>
Colin Frick <colin@bash.li>
Winston Howes <winstonhowes@gmail.com>
Alexander O'Mara <me@alexomara.com>
Chris Rebert <github@rebertia.com>
Bastian Buchholz <buchholz.bastian@googlemail.com>
Mu Haibao <mhbseal@163.com>
Calvin Metcalf <calvin.metcalf@gmail.com>
Arthur Stolyar <nekr.fabula@gmail.com>
Gabriel Schulhof <gabriel.schulhof@intel.com>
Chris Rebert <github@rebertia.com>
Gilad Peleg <giladp007@gmail.com>
Julian Alexander Murillo <julian.alexander.murillo@gmail.com>
Kevin Kirsche <Kev.Kirsche+GitHub@gmail.com>
@@ -297,15 +295,14 @@ Christian Grete <webmaster@christiangrete.com>
Tom von Clef <thomas.vonclef@gmail.com>
Liza Ramo <liza.h.ramo@gmail.com>
Joelle Fleurantin <joasqueeniebee@gmail.com>
Steve Mao <maochenyan@gmail.com>
Jon Dufresne <jon.dufresne@gmail.com>
Jae Sung Park <alberto.park@gmail.com>
Josh Soref <apache@soref.com>
Saptak Sengupta <saptak013@gmail.com>
Henry Wong <henryw4k@gmail.com>
Jun Sun <klsforever@gmail.com>
Martijn W. van der Lee <martijn@vanderlee.com>
Devin Wilson <dwilson6.github@gmail.com>
Steve Mao <maochenyan@gmail.com>
Damian Senn <jquery@topaxi.codes>
Zack Hall <zackhall@outlook.com>
Vitaliy Terziev <vitaliyterziev@gmail.com>
@@ -336,6 +333,7 @@ Jordan Beland <jordan.beland@gmail.com>
Henry Zhu <hi@henryzoo.com>
Nilton Cesar <niltoncms@gmail.com>
basil.belokon <basil.belokon@gmail.com>
Saptak Sengupta <saptak013@gmail.com>
Andrey Meshkov <ay.meshkov@gmail.com>
tmybr11 <tomas.perone@gmail.com>
Luis Emilio Velasco Sanchez <emibloque@gmail.com>
@@ -344,14 +342,34 @@ Bert Zhang <enbo@users.noreply.github.com>
Sébastien Règne <regseb@users.noreply.github.com>
wartmanm <3869625+wartmanm@users.noreply.github.com>
Siddharth Dungarwal <sd5869@gmail.com>
abnud1 <ahmad13932013@hotmail.com>
Andrei Fangli <andrei_fangli@outlook.com>
Marja Hölttä <marja.holtta@gmail.com>
abnud1 <ahmad13932013@hotmail.com>
buddh4 <mail@jharrer.de>
Hoang <dangkyokhoang@gmail.com>
Sean Robinson <sean.robinson@scottsdalecc.edu>
Wonseop Kim <wonseop.kim@samsung.com>
Pat O'Callaghan <patocallaghan@gmail.com>
JuanMa Ruiz <ruizjuanma@gmail.com>
Ahmed.S.ElAfifi <ahmed.s.elafifi@gmail.com>
Sean Robinson <sean.robinson@scottsdalecc.edu>
Christian Oliff <christianoliff@pm.me>
Christian Wenz <christian@wenz.org>
Jonathan <vanillajonathan@users.noreply.github.com>
Ed Sanders <ejsanders@gmail.com>
Pierre Grimaud <grimaud.pierre@gmail.com>
Beatriz Rezener <beatrizrezener@users.noreply.github.com>
Necmettin Karakaya <necmettin.karakaya@gmail.com>
Wonhyoung Park <wh05.park@samsung.com>
Dallas Fraser <dallas.fraser.waterloo@gmail.com>
高灰 <www@zeroplace.cn>
fecore1 <89127124+fecore1@users.noreply.github.com>
ygj6 <7699524+ygj6@users.noreply.github.com>
Bruno PIERRE <brunopierre4@yahoo.fr>
Simon Legner <Simon.Legner@gmail.com>
Baoshuo Ren <i@baoshuo.ren>
Anders Kaseorg <andersk@mit.edu>
Alex <aleksandrosansan@gmail.com>
Gabriela Gutierrez <gabigutierrez@google.com>
Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com>
J.Son <x@x-wx.com>
Liam James <liam@minimaximize.com>

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 http://jqueryui.com/about
A list of current team members is available at https://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 (http://jacek.jedrzejewski.name)
Jacek Jędrzejewski (https://jacek.jedrzejewski.name)
Ting Kuei <ting@kuei.com>
Samuel Cormier-Iijima <sam@chide.it>
Jon Palmer <jonspalmer@gmail.com>
@@ -370,3 +370,15 @@ 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 jQuery Foundation and other contributors, https://jquery.org/
Copyright OpenJS Foundation and other contributors, https://openjsf.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: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

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

View File

@@ -1,8 +1,8 @@
/*! jQuery UI - v1.13.2 - 2022-07-14
* http://jqueryui.com
/*! jQuery UI - v1.14.1 - 2024-10-30
* https://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 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 */
* 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 */
/* Layout helpers
----------------------------------*/
@@ -45,7 +45,6 @@
left: 0;
position: absolute;
opacity: 0;
-ms-filter: "alpha(opacity=0)"; /* support: IE8 */
}
.ui-front {
@@ -122,8 +121,6 @@
.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;
@@ -173,12 +170,7 @@
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,
@@ -229,7 +221,7 @@ input.ui-button.ui-icon-notext .ui-icon {
}
/* workarounds */
/* Support: Firefox 5 - 40 */
/* Support: Firefox 5 - 125+ */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
@@ -280,9 +272,6 @@ 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 {
@@ -579,7 +568,6 @@ button.ui-button::-moz-focus-inner {
cursor: move;
}
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable {
@@ -589,7 +577,6 @@ 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,
@@ -664,14 +651,12 @@ 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 {
@@ -729,7 +714,6 @@ 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 {
@@ -741,12 +725,6 @@ 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;
}
@@ -785,7 +763,6 @@ button.ui-button::-moz-focus-inner {
top: 0;
}
.ui-sortable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-spinner {
@@ -1041,19 +1018,14 @@ 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
----------------------------------*/
@@ -1306,10 +1278,8 @@ a.ui-button:active,
/* Overlays */
.ui-widget-overlay {
background: #aaaaaa;
opacity: .003;
-ms-filter: Alpha(Opacity=.3); /* support: IE8 */
opacity: .3;
}
.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.13.2
* http://jqueryui.com
* jQuery UI CSS Framework 1.14.1
* https://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
* https://jquery.org/license
*
* http://api.jqueryui.com/category/theming/
* https://api.jqueryui.com/category/theming/
*/
/* Layout helpers
----------------------------------*/
@@ -49,7 +49,6 @@
left: 0;
position: absolute;
opacity: 0;
-ms-filter: "alpha(opacity=0)"; /* support: IE8 */
}
.ui-front {
@@ -126,8 +125,6 @@
.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;
@@ -177,12 +174,7 @@
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,
@@ -233,7 +225,7 @@ input.ui-button.ui-icon-notext .ui-icon {
}
/* workarounds */
/* Support: Firefox 5 - 40 */
/* Support: Firefox 5 - 125+ */
input.ui-button::-moz-focus-inner,
button.ui-button::-moz-focus-inner {
border: 0;
@@ -284,9 +276,6 @@ 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 {
@@ -583,7 +572,6 @@ button.ui-button::-moz-focus-inner {
cursor: move;
}
.ui-draggable-handle {
-ms-touch-action: none;
touch-action: none;
}
.ui-resizable {
@@ -593,7 +581,6 @@ 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,
@@ -668,14 +655,12 @@ 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 {
@@ -733,7 +718,6 @@ 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 {
@@ -745,12 +729,6 @@ 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;
}
@@ -789,7 +767,6 @@ 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.13.2
* http://jqueryui.com
* jQuery UI CSS Framework 1.14.1
* https://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
* https://jquery.org/license
*
* http://api.jqueryui.com/category/theming/
* https://api.jqueryui.com/category/theming/
*
* 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
* 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=
*/
@@ -172,19 +172,14 @@ 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
----------------------------------*/
@@ -437,10 +432,8 @@ a.ui-button:active,
/* Overlays */
.ui-widget-overlay {
background: #aaaaaa;
opacity: .003;
-ms-filter: Alpha(Opacity=.3); /* support: IE8 */
opacity: .3;
}
.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 +1 @@
Selectize.define("selectize-plugin-a11y",function(c){var t=this,l=13;typeof t.accessibility=="undefined"&&(t.accessibility={}),t.accessibility.helpers={randomId:function(e){for(var r="",s=e||10,i="abcdefghijklmnopqrstuvwxyz0123456789",n=i.length,a=0;a<s;a++)r+=i[Math.floor(n*Math.random())];return r}},t.accessibility.liveRegion={$region:"",speak:function(e){var r=$("<div></div>");r.text(e),this.$region.html(r)},domListener:function(){var e=new MutationObserver(function(r){r.forEach(function(s){var i=$(s.target);if(i.hasClass("items"))if(i.hasClass("dropdown-active")){t.$control_input.attr("aria-expanded","true");for(var n=t.$dropdown_content[0].children,a=0;a<n.length;a++){var o=n[a].attributes;o.role||n[a].setAttribute("role","option"),o.id||n[a].setAttribute("id",t.accessibility.helpers.randomId())}}else t.$control_input.attr("aria-expanded","false"),t.$control_input.removeAttr("aria-activedescendant");else i.hasClass("active")&&i.attr("data-value")&&(t.$control_input.attr("aria-activedescendant",i.attr("id")),t.accessibility.liveRegion.speak(i.text(),500))})});e.observe(t.$dropdown[0],{attributes:!0,attributeFilter:["class"],subtree:!0,attributeOldValue:!0}),e.observe(t.$control[0],{attributes:!0,attributeFilter:["class"]}),e.observe(t.$control_input[0],{attributes:!0,attributeFilter:["value"]})},setAttributes:function(){this.$region.attr({"aria-live":"assertive",role:"log","aria-relevant":"additions","aria-atomic":"true"})},setStyles:function(){this.$region.css({position:"absolute",width:"1px",height:"1px","margin-top":"-1px",clip:"rect(1px, 1px, 1px, 1px)",overflow:"hidden"})},init:function(){this.$region=$("<div>"),this.setAttributes(),this.setStyles(),$("body").append(this.$region),this.domListener()}},this.setup=function(){var e=t.setup;return function(){e.apply(this,arguments);var r=t.accessibility.helpers.randomId(),s=t.accessibility.helpers.randomId();t.$control.on("keydown",function(i){i.keyCode===l&&(t.settings.openOnFocus?(t.settings.openOnFocus=!1,t.focus(),setTimeout(function(){t.settings.openOnFocus=!0},0)):t.focus())}),t.$control_input.attr({role:"combobox","aria-expanded":"false",haspopup:"listbox","aria-owns":s,"aria-label":t.$wrapper.closest("[data-accessibility-selectize-label]").attr("data-accessibility-selectize-label")}),t.$dropdown_content.attr({role:"listbox",id:s}),t.accessibility.liveRegion.init()}}(),this.destroy=function(){var e=t.destroy;return function(){return t.accessibility.liveRegion.$region.remove(),e.apply(this,arguments)}}()});
Selectize.define("selectize-plugin-a11y",function(c){var t=this,l=13;typeof t.accessibility>"u"&&(t.accessibility={}),t.accessibility.helpers={randomId:function(e){for(var r="",s=e||10,i="abcdefghijklmnopqrstuvwxyz0123456789",n=i.length,a=0;a<s;a++)r+=i[Math.floor(n*Math.random())];return r}},t.accessibility.liveRegion={$region:"",speak:function(e){var r=$("<div></div>");r.text(e),this.$region.html(r)},domListener:function(){var e=new MutationObserver(function(r){r.forEach(function(s){var i=$(s.target);if(i.hasClass("items"))if(i.hasClass("dropdown-active")){t.$control_input.attr("aria-expanded","true");for(var n=t.$dropdown_content[0].children,a=0;a<n.length;a++){var o=n[a].attributes;o.role||n[a].setAttribute("role","option"),o.id||n[a].setAttribute("id",t.accessibility.helpers.randomId())}}else t.$control_input.attr("aria-expanded","false"),t.$control_input.removeAttr("aria-activedescendant");else i.hasClass("active")&&i.attr("data-value")&&(t.$control_input.attr("aria-activedescendant",i.attr("id")),t.accessibility.liveRegion.speak(i.text(),500))})});e.observe(t.$dropdown[0],{attributes:!0,attributeFilter:["class"],subtree:!0,attributeOldValue:!0}),e.observe(t.$control[0],{attributes:!0,attributeFilter:["class"]}),e.observe(t.$control_input[0],{attributes:!0,attributeFilter:["value"]})},setAttributes:function(){this.$region.attr({"aria-live":"assertive",role:"log","aria-relevant":"additions","aria-atomic":"true"})},setStyles:function(){this.$region.css({position:"absolute",width:"1px",height:"1px","margin-top":"-1px",clip:"rect(1px, 1px, 1px, 1px)",overflow:"hidden"})},init:function(){this.$region=$("<div>"),this.setAttributes(),this.setStyles(),$("body").append(this.$region),this.domListener()}},this.setup=function(){var e=t.setup;return function(){e.apply(this,arguments);var r=t.accessibility.helpers.randomId(),s=t.accessibility.helpers.randomId();t.$control.on("keydown",function(i){i.keyCode===l&&(t.settings.openOnFocus?(t.settings.openOnFocus=!1,t.focus(),setTimeout(function(){t.settings.openOnFocus=!0},0)):t.focus())}),t.$control_input.attr({role:"combobox","aria-expanded":"false",haspopup:"listbox","aria-owns":s,"aria-label":t.$wrapper.closest("[data-accessibility-selectize-label]").attr("data-accessibility-selectize-label")}),t.$dropdown_content.attr({role:"listbox",id:s}),t.accessibility.liveRegion.init()}}(),this.destroy=function(){var e=t.destroy;return function(){return t.accessibility.liveRegion.$region.remove(),e.apply(this,arguments)}}()});

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

@@ -1,2 +1,2 @@
/*! shiny 1.9.1.9000 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
/*! shiny 1.11.1.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}

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,3 +1,3 @@
/*! shiny 1.9.1.9000 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
"use strict";(function(){var a=eval;window.addEventListener("message",function(i){var e=i.data;e.code&&a(e.code)});})();
/*! shiny 1.11.1.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

View File

@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../../../srcts/src/utils/eval.ts", "../../../srcts/extras/shiny-testmode.ts"],
"sourcesContent": ["//esbuild.github.io/content-types/#direct-eval\n//tl/dr;\n// * Direct usage of `eval(\"x\")` is bad with bundled code.\n// * Instead, use indirect calls to `eval` such as `indirectEval(\"x\")`\n// * Even just renaming the function works well enough.\n// > This is known as \"indirect eval\" because eval is not being called directly, and so does not trigger the grammatical special case for direct eval in the JavaScript VM. You can call indirect eval using any syntax at all except for an expression of the exact form eval('x'). For example, var eval2 = eval; eval2('x') and [eval][0]('x') and window.eval('x') are all indirect eval calls.\n// > When you use indirect eval, the code is evaluated in the global scope instead of in the inline scope of the caller.\n\nvar indirectEval = eval;\nexport { indirectEval };", "/* eslint-disable unicorn/filename-case */\nimport { indirectEval } from \"../src/utils/eval\";\n\n// Listen for messages from parent frame. This file is only added when the\n// shiny.testmode option is TRUE.\nwindow.addEventListener(\"message\", function (e) {\n var message = e.data;\n if (message.code) indirectEval(message.code);\n});"],
"mappings": ";yBAQA,IAAIA,EAAe,KCHnB,OAAO,iBAAiB,UAAW,SAAUC,EAAG,CAC9C,IAAIC,EAAUD,EAAE,KACZC,EAAQ,MAAMC,EAAaD,EAAQ,IAAI,CAC7C,CAAC",
"sourcesContent": ["//esbuild.github.io/content-types/#direct-eval\n//tl/dr;\n// * Direct usage of `eval(\"x\")` is bad with bundled code.\n// * Instead, use indirect calls to `eval` such as `indirectEval(\"x\")`\n// * Even just renaming the function works well enough.\n// > This is known as \"indirect eval\" because eval is not being called directly, and so does not trigger the grammatical special case for direct eval in the JavaScript VM. You can call indirect eval using any syntax at all except for an expression of the exact form eval('x'). For example, var eval2 = eval; eval2('x') and [eval][0]('x') and window.eval('x') are all indirect eval calls.\n// > When you use indirect eval, the code is evaluated in the global scope instead of in the inline scope of the caller.\n\nconst indirectEval = eval;\n\nexport { indirectEval };\n", "/* eslint-disable unicorn/filename-case */\nimport { indirectEval } from \"../src/utils/eval\";\n\n// Listen for messages from parent frame. This file is only added when the\n// shiny.testmode option is TRUE.\nwindow.addEventListener(\"message\", function (e: { data: { code: string } }) {\n const message = e.data;\n\n if (message.code) indirectEval(message.code);\n});\n"],
"mappings": ";mBAQA,IAAMA,EAAe,KCHrB,OAAO,iBAAiB,UAAW,SAAUC,EAA+B,CAC1E,IAAMC,EAAUD,EAAE,KAEdC,EAAQ,MAAMC,EAAaD,EAAQ,IAAI,CAC7C,CAAC",
"names": ["indirectEval", "e", "message", "indirectEval"]
}

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,6 +384,14 @@ html.autoreload-enabled #shiny-disconnected-overlay.reloading {
width: 100%;
}
/* Styling for textAreaInput(autoresize=TRUE) */
textarea.textarea-autoresize.form-control {
padding: 5px 8px;
resize: none;
overflow-y: hidden;
height: auto;
}
#shiny-notification-panel {
position: fixed;
@@ -455,6 +463,13 @@ html.autoreload-enabled #shiny-disconnected-overlay.reloading {
}
}
// 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,
@@ -465,6 +480,13 @@ html.autoreload-enabled #shiny-disconnected-overlay.reloading {
cursor: not-allowed;
}
// Selectize's remove_button plugin has a bug that can lead to multiple remove
// buttons being displayed when options get updated. This prevents that from
// happening (see #4274 for reprex)
.shiny-input-select .selectize-input > .item > .remove:not(:first-child) {
display: none;
}
/* Hidden tabPanels */
.nav-hidden {
/* override anything bootstrap sets for `.nav` */

View File

@@ -1,4 +0,0 @@
module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
};

View File

@@ -45,6 +45,58 @@ is, a function that quickly returns a promise) and allows even that very
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}
library(shiny)
library(bslib)
library(mirai)
# Set background processes for running tasks
daemons(1)
# Reset when the app is stopped
onStop(function() daemons(0))
ui <- page_fluid(
titlePanel("Extended Task Demo"),
p(
'Click the button below to perform a "calculation"',
"that takes a while to perform."
),
input_task_button("recalculate", "Recalculate"),
p(textOutput("result"))
)
server <- function(input, output) {
rand_task <- ExtendedTask$new(function() {
mirai(
{
# Slow operation goes here
Sys.sleep(2)
sample(1:100, 1)
}
)
})
# Make button state reflect task.
# If using R >=4.1, you can do this instead:
# rand_task <- ExtendedTask$new(...) |> bind_task_button("recalculate")
bind_task_button(rand_task, "recalculate")
observeEvent(input$recalculate, {
# Invoke the extended in an observer
rand_task$invoke()
})
output$result <- renderText({
# React to updated results when the task completes
number <- rand_task$result()
paste0("Your number is ", number, ".")
})
}
shinyApp(ui, server)
\dontshow{\}) # examplesIf}
}
\section{Methods}{
\subsection{Public methods}{
\itemize{
@@ -71,11 +123,12 @@ 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 conjuction with the
likely in conjunction with the
\href{https://mirai.r-lib.org}{\{mirai\}} or
\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[future:future]{Future}} object, or a \code{promise}, or something else
that \code{\link[promises:is.promise]{promises::as.promise()}} understands.)
\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.)
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

@@ -182,7 +182,7 @@ If you want to use a cache that is shared across multiple R processes, you
can use a \code{\link[cachem:cache_disk]{cachem::cache_disk()}}. You can create a application-level shared
cache by putting this at the top of your app.R, server.R, or global.R:
\if{html}{\out{<div class="sourceCode">}}\preformatted{shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache"))
\if{html}{\out{<div class="sourceCode">}}\preformatted{shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache")))
}\if{html}{\out{</div>}}
This will create a subdirectory in your system temp directory named
@@ -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[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[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.
If the value returns a promise, then anything that consumes the cached
reactive must expect it to return a promise.

View File

@@ -60,4 +60,14 @@ server <- function(input, output) {
shinyApp(ui, server)
}
}
\seealso{
\itemize{
\item The download handler, like other outputs, is suspended (disabled) by
default for download buttons and links that are hidden. Use
\code{\link[=outputOptions]{outputOptions()}} to control this behavior, e.g. to set
\code{suspendWhenHidden = FALSE} if the download is initiated by
programmatically clicking on the download button using JavaScript.
}
}

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