mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-11 16:08:19 -05:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
283c71e772 | ||
|
|
b1297395a9 | ||
|
|
b850cd2509 | ||
|
|
56878ebbaa | ||
|
|
6a09fda08e | ||
|
|
77bc4e9ec7 | ||
|
|
a1b9fda809 | ||
|
|
97a12ec601 | ||
|
|
81bdde64c4 | ||
|
|
c4ef42337b | ||
|
|
ce78d0dcf1 | ||
|
|
7069064dd6 | ||
|
|
a0a83d5fe3 | ||
|
|
8fbc4ad4c1 | ||
|
|
5346a00373 | ||
|
|
2dc69aea37 | ||
|
|
be6f6716bf | ||
|
|
7f59f93692 | ||
|
|
798b336df6 | ||
|
|
bef6b4bfd9 | ||
|
|
80ab088e2d | ||
|
|
481a692b07 | ||
|
|
8ae936ba01 | ||
|
|
6dc377842f | ||
|
|
837307fe8c | ||
|
|
dfe359c1b6 | ||
|
|
b8923e9497 | ||
|
|
9ebcbf8a2d |
@@ -26,6 +26,7 @@
|
||||
^\.vscode$
|
||||
^\.madgerc$
|
||||
^\.prettierrc\.yml$
|
||||
^babel\.config\.json$
|
||||
^jest\.config\.js$
|
||||
^package\.json$
|
||||
^tsconfig\.json$
|
||||
|
||||
@@ -15,6 +15,11 @@ 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
|
||||
@@ -70,6 +75,10 @@ rules:
|
||||
|
||||
"@typescript-eslint/consistent-type-imports":
|
||||
- error
|
||||
|
||||
"@typescript-eslint/no-floating-promises":
|
||||
- error
|
||||
|
||||
"@typescript-eslint/naming-convention":
|
||||
- error
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Package: shiny
|
||||
Type: Package
|
||||
Title: Web Application Framework for R
|
||||
Version: 1.7.5.9000
|
||||
Version: 1.8.0
|
||||
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"),
|
||||
|
||||
23
NEWS.md
23
NEWS.md
@@ -1,15 +1,34 @@
|
||||
# shiny (development version)
|
||||
# shiny 1.8.0
|
||||
|
||||
## Breaking changes
|
||||
|
||||
* Closed #3899: The JS function `Shiny.bindAll()` is now asynchronous. This change is driven by the recent push toward making dynamic UI rendering asynchronous, which is necessary for [shinylive](https://shinylive.io/r) (and should've happened when it was first introduced in Shiny v1.7.5). The vast majority of existing `Shiny.bindAll()` uses should continue to work as before, but some cases may break if downstream code relies on it being synchronous (i.e., blocking the main thread). In this case, consider placing any downstream code in a `.then()` callback (or `await` the result in a `async` function). (#3929)
|
||||
* Since `renderContent()` calls `bindAll()` (after it inserts content), it now returns a `Promise<void>` instead of `void`, which can be useful if downstream code needs to wait for the binding to complete.
|
||||
|
||||
## New features and improvements
|
||||
|
||||
* Updated `selectizeInput()`'s selectize.js dependency from v0.12.4 to v0.15.2. In addition to many bug fixes and improvements, this update also adds several new [plugin options](https://selectize.dev/docs/demos/plugins). (#3875)
|
||||
|
||||
* Shiny's CSS styling for things like `showNotification()`, `withProgress()`, `inputPanel()`, etc., now looks better with `{bslib}`'s upcoming CSS-only dark mode. (#3882)
|
||||
* Shiny's CSS styling (for things like `showNotification()`, `withProgress()`, `inputPanel()`, etc.), has been updated with `{bslib}`'s upcoming CSS-only dark mode feature in mind. (#3882, #3914)
|
||||
|
||||
* Default styles for `showNotification()` were tweaked slightly to improve accessibility, sizing, and padding. (#3913)
|
||||
|
||||
* Shiny inputs and `{htmlwidgets}` are no longer treated as draggable inside of `absolutePanel()`/`fixedPanel()` with `draggable = TRUE`. As a result, interactions like zooming and panning now work as expected with widgets like `{plotly}` and `{leaflet}` when they appear in a draggable panel. (#3752, #3933)
|
||||
|
||||
* For `InputBinding`s, the `.receiveMessage()` method can now be asynchronous or synchronous (previously it could only be synchronous). (#3930)
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* `fileInput()` no longer has unwanted round corners applied to the `buttonLabel`. (#3879)
|
||||
|
||||
* Fixed #3898: `wrapFunctionLabel()` no longer throws an error if the `name` is longer than 10000 bytes. (#3903)
|
||||
|
||||
# shiny 1.7.5.1
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* On r-devel (R > 4.3.1), `isTruthy(NULL)` now returns `FALSE` (as it does with older versions of R). (#3906)
|
||||
|
||||
# shiny 1.7.5
|
||||
|
||||
## Possibly breaking changes
|
||||
|
||||
@@ -253,9 +253,8 @@ selectizeDependencyFunc <- function(theme) {
|
||||
# name, the JS/CSS would be loaded/included twice, which leads to
|
||||
# strange issues, especially since we now include a 3rd party
|
||||
# accessibility plugin https://github.com/rstudio/shiny/pull/3153
|
||||
script <- file.path(
|
||||
selectizeDir, c("js/selectize.min.js", "accessibility/js/selectize-plugin-a11y.min.js")
|
||||
)
|
||||
script <- file.path(selectizeDir, selectizeScripts())
|
||||
|
||||
bslib::bs_dependency(
|
||||
input = sass::sass_file(stylesheet),
|
||||
theme = theme,
|
||||
@@ -273,10 +272,18 @@ selectizeStaticDependency <- function(version) {
|
||||
src = "www/shared/selectize",
|
||||
package = "shiny",
|
||||
stylesheet = "css/selectize.bootstrap3.css",
|
||||
script = c(
|
||||
"js/selectize.min.js",
|
||||
"accessibility/js/selectize-plugin-a11y.min.js"
|
||||
)
|
||||
script = selectizeScripts()
|
||||
)
|
||||
}
|
||||
|
||||
selectizeScripts <- function() {
|
||||
isMinified <- isTRUE(get_devmode_option("shiny.minified", TRUE))
|
||||
paste0(
|
||||
c(
|
||||
"js/selectize",
|
||||
"accessibility/js/selectize-plugin-a11y"
|
||||
),
|
||||
if (isMinified) ".min.js" else ".js"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
20
R/jqueryui.R
20
R/jqueryui.R
@@ -76,16 +76,20 @@ absolutePanel <- function(...,
|
||||
|
||||
style <- paste(paste(names(cssProps), cssProps, sep = ':', collapse = ';'), ';', sep='')
|
||||
divTag <- tags$div(style=style, ...)
|
||||
if (isTRUE(draggable)) {
|
||||
divTag <- tagAppendAttributes(divTag, class='draggable')
|
||||
return(tagList(
|
||||
divTag,
|
||||
jqueryuiDependency(),
|
||||
tags$script('$(".draggable").draggable();')
|
||||
))
|
||||
} else {
|
||||
|
||||
if (identical(draggable, FALSE)) {
|
||||
return(divTag)
|
||||
}
|
||||
|
||||
# Add Shiny inputs and htmlwidgets to 'non-draggable' elements
|
||||
# Cf. https://api.jqueryui.com/draggable/#option-cancel
|
||||
dragOpts <- '{cancel: ".shiny-input-container,.html-widget,input,textarea,button,select,option"}'
|
||||
dragJS <- sprintf('$(".draggable").draggable(%s);', dragOpts)
|
||||
tagList(
|
||||
tagAppendAttributes(divTag, class='draggable'),
|
||||
jqueryuiDependency(),
|
||||
tags$script(HTML(dragJS))
|
||||
)
|
||||
}
|
||||
|
||||
#' @rdname absolutePanel
|
||||
|
||||
@@ -133,8 +133,11 @@ shinyDependencyCSS <- function(theme) {
|
||||
))
|
||||
}
|
||||
|
||||
bs_version <- bslib::theme_version(theme)
|
||||
bootstrap_scss <- paste0("shiny.bootstrap", bs_version, ".scss")
|
||||
|
||||
scss_home <- system_file("www/shared/shiny_scss", package = "shiny")
|
||||
scss_files <- file.path(scss_home, c("bootstrap.scss", "shiny.scss"))
|
||||
scss_files <- file.path(scss_home, c(bootstrap_scss, "shiny.scss"))
|
||||
scss_files <- lapply(scss_files, sass::sass_file)
|
||||
|
||||
bslib::bs_dependency(
|
||||
|
||||
16
R/utils.R
16
R/utils.R
@@ -1240,14 +1240,12 @@ dotloop <- function(fun_, ...) {
|
||||
#' @param x An expression whose truthiness value we want to determine
|
||||
#' @export
|
||||
isTruthy <- function(x) {
|
||||
if (inherits(x, 'try-error'))
|
||||
return(FALSE)
|
||||
|
||||
if (!is.atomic(x))
|
||||
return(TRUE)
|
||||
|
||||
if (is.null(x))
|
||||
return(FALSE)
|
||||
if (inherits(x, 'try-error'))
|
||||
return(FALSE)
|
||||
if (!is.atomic(x))
|
||||
return(TRUE)
|
||||
if (length(x) == 0)
|
||||
return(FALSE)
|
||||
if (all(is.na(x)))
|
||||
@@ -1431,6 +1429,12 @@ wrapFunctionLabel <- function(func, name, ..stacktraceon = FALSE, dots = TRUE) {
|
||||
if (name == "name" || name == "func" || name == "relabelWrapper") {
|
||||
stop("Invalid name for wrapFunctionLabel: ", name)
|
||||
}
|
||||
if (nchar(name, "bytes") > 10000) {
|
||||
# Max variable length in R is 10000 bytes. Truncate to a shorter number of
|
||||
# chars because some characters could be multi-byte.
|
||||
name <- substr(name, 1, 5000)
|
||||
}
|
||||
|
||||
assign(name, func, environment())
|
||||
registerDebugHook(name, environment(), name)
|
||||
|
||||
|
||||
15
babel.config.json
Normal file
15
babel.config.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"presets": [
|
||||
"@babel/preset-typescript",
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": "3.12"
|
||||
}
|
||||
]
|
||||
],
|
||||
"ignore":[
|
||||
"node_modules/core-js"
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
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)}}()});
|
||||
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)}}()});
|
||||
|
||||
3486
inst/www/shared/selectize/js/selectize.js
Normal file
3486
inst/www/shared/selectize/js/selectize.js
Normal file
File diff suppressed because it is too large
Load Diff
33
inst/www/shared/selectize/js/selectize.min.js
vendored
33
inst/www/shared/selectize/js/selectize.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
/*! shiny 1.7.5.9000 | (c) 2012-2023 RStudio, PBC. | License: GPL-3 | file LICENSE */
|
||||
/*! shiny 1.8.0 | (c) 2012-2023 RStudio, 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
@@ -1,3 +1,3 @@
|
||||
/*! shiny 1.7.5.9000 | (c) 2012-2023 RStudio, 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)});})();
|
||||
/*! shiny 1.8.0 | (c) 2012-2023 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)});})();
|
||||
//# sourceMappingURL=shiny-testmode.js.map
|
||||
|
||||
@@ -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\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",
|
||||
"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",
|
||||
"names": ["indirectEval", "e", "message", "indirectEval"]
|
||||
}
|
||||
|
||||
22162
inst/www/shared/shiny.js
22162
inst/www/shared/shiny.js
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
4
inst/www/shared/shiny.min.css
vendored
4
inst/www/shared/shiny.min.css
vendored
File diff suppressed because one or more lines are too long
13
inst/www/shared/shiny.min.js
vendored
13
inst/www/shared/shiny.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
52
inst/www/shared/shiny_scss/bootstrap.scss
vendored
52
inst/www/shared/shiny_scss/bootstrap.scss
vendored
@@ -1,52 +0,0 @@
|
||||
$prefix: bs- !default; // BS5 CSS variable prefix
|
||||
|
||||
// For BS3, which doesn't have these Sass variables (but has other, similar ones)
|
||||
$border-width: 1px !default;
|
||||
$border-radius: $border-radius-base !default;
|
||||
$border-color: mix($body-bg, $text-color, 70%) !default;
|
||||
$primary: $brand-primary !default;
|
||||
$info: $brand-info !default;
|
||||
$warning: $brand-warning !default;
|
||||
$danger: $brand-danger !default;
|
||||
|
||||
// No rgb CSS vars available in BS3-4
|
||||
$primary-rgb: var(--#{$prefix}primary-rgb, red($primary),green($primary),blue($primary)) !default;
|
||||
$info-rgb: var(--#{$prefix}info-rgb, red($info), green($info), blue($info)) !default;
|
||||
$warning-rgb: var(--#{$prefix}warning-rgb, red($warning), green($warning), blue($warning)) !default;
|
||||
$danger-rgb: var(--#{$prefix}danger-rgb, red($danger), green($danger), blue($danger)) !default;
|
||||
|
||||
|
||||
$shiny-emphasis-color-rgb: var(--#{$prefix}emphasis-color-rgb, 0,0,0) !default;
|
||||
$shiny-disconnected-bg: RGBA($shiny-emphasis-color-rgb, 0.42) !default;
|
||||
$shiny-table-na: RGBA($shiny-emphasis-color-rgb, 0.46) !default;
|
||||
$shiny-error-validated-color: RGBA($shiny-emphasis-color-rgb, 0.5) !default;
|
||||
$shiny-progress-text-bg-color: RGBA($primary-rgb, 0.05) !default;
|
||||
$shiny-input-panel-bg: RGBA($shiny-emphasis-color-rgb, 0.04) !default;
|
||||
$shiny-input-panel-border: $border-width solid var(--#{$prefix}border-color, $border-color) !default;
|
||||
$shiny-input-panel-border-radius: $border-radius !default;
|
||||
$shiny-text-output-border-radius: $border-radius !default;
|
||||
$notification-bg-color: RGBA($shiny-emphasis-color-rgb, 0.05) !default;
|
||||
$notification-color: $shiny-emphasis-color-rgb !default;
|
||||
$notification-border: $border-width solid var(--#{$prefix}border-color, $border-color) !default;
|
||||
$notification-border-radius: $border-radius !default;
|
||||
$notification-message-bg: RGBA($info-rgb, 0.05) !default;
|
||||
$notification-message-color: RGBA($info-rgb, 1) !default;
|
||||
$notification-message-border: $border-width solid RGBA($info-rgb, 0.5) !default;
|
||||
$notification-warning-bg: RGBA($warning-rgb, 0.05) !default;
|
||||
$notification-warning-color: RGBA($warning-rgb, 0.9) !default;
|
||||
$notification-warning-border: $border-width solid RGBA($warning-rgb, 0.3) !default;
|
||||
$notification-error-bg: RGBA($danger-rgb, 0.05) !default;
|
||||
$notification-error-color: RGBA($danger-rgb, 0.9) !default;
|
||||
$notification-error-border: $border-width solid RGBA($warning-rgb, 0.2) !default;
|
||||
$notification-close-color: RGBA($shiny-emphasis-color-rgb, 0.8) !default;
|
||||
$notification-close-hover-color: RGB($shiny-emphasis-color-rgb) !default;
|
||||
$notification-content-action-color: RGB($primary-rgb) !default;
|
||||
$datepicker-disabled-color: $dropdown-link-disabled-color !default;
|
||||
|
||||
// I don't think BS3 has a file input box shadow setting
|
||||
@if variable-exists('custom-file-focus-box-shadow') {
|
||||
$shiny-file-active-shadow: $custom-file-focus-box-shadow !default;
|
||||
}
|
||||
|
||||
// TODO: should this be changed to danger?
|
||||
//$shiny-error-color: red !default;
|
||||
34
inst/www/shared/shiny_scss/shiny.bootstrap3.scss
Normal file
34
inst/www/shared/shiny_scss/shiny.bootstrap3.scss
Normal file
@@ -0,0 +1,34 @@
|
||||
$bg: $body-bg !default;
|
||||
$fg: $text-color !default; // BS3
|
||||
$theme-colors: ("primary": $brand-primary, "info": $brand-info, "warning": $brand-warning, "danger": $brand-danger) !default;
|
||||
|
||||
// No $border-width, $border-color, or $border-radius in BS3
|
||||
$border-width: 1px !default;
|
||||
$border-color: mix($bg, $fg, 70%) !default;
|
||||
$border-radius: $border-radius-base !default;
|
||||
|
||||
$shiny-disconnected-bg: mix($bg, $fg, 58%) !default;
|
||||
$shiny-table-na: mix($bg, $fg, 54%) !default;
|
||||
$shiny-error-validated-color: mix($bg, $fg, 50%) !default;
|
||||
$shiny-progress-text-bg-color: #eef8ff !default;
|
||||
$shiny-input-panel-bg: mix($bg, $fg, 96%) !default;
|
||||
$shiny-input-panel-border: $border-width solid $border-color !default;
|
||||
$shiny-input-panel-border-radius: $border-radius !default;
|
||||
$shiny-text-output-border-radius: $border-radius !default;
|
||||
$notification-bg-color: mix($bg, $fg, 90%) !default;
|
||||
$notification-color: $fg !default;
|
||||
$notification-border: $border-width solid $border-color !default;
|
||||
$notification-border-radius: $border-radius !default;
|
||||
$notification-message-bg: mix($bg, map-get($theme-colors, "info"), 90%) !default;
|
||||
$notification-message-color: mix($fg, map-get($theme-colors, "info"), 10%) !default;
|
||||
$notification-message-border: $border-width solid mix($bg, map-get($theme-colors, "info"), 53%) !default;
|
||||
$notification-warning-bg: mix($bg, map-get($theme-colors, "warning"), 90%) !default;
|
||||
$notification-warning-color: mix($fg, map-get($theme-colors, "warning"), 10%) !default;
|
||||
$notification-warning-border: $border-width solid mix($bg, map-get($theme-colors, "warning"), 71%) !default;
|
||||
$notification-error-bg: mix($bg, map-get($theme-colors, "danger"), 90%) !default;
|
||||
$notification-error-color: mix($fg, map-get($theme-colors, "danger"), 10%) !default;
|
||||
$notification-error-border: $border-width solid mix($bg, map-get($theme-colors, "danger"), 79%) !default;
|
||||
$notification-close-color: mix($bg, $fg, 20%) !default;
|
||||
$notification-close-hover-color: $fg !default;
|
||||
$notification-content-action-color: map-get($theme-colors, "primary") !default;
|
||||
$datepicker-disabled-color: $dropdown-link-disabled-color !default;
|
||||
30
inst/www/shared/shiny_scss/shiny.bootstrap4.scss
Normal file
30
inst/www/shared/shiny_scss/shiny.bootstrap4.scss
Normal file
@@ -0,0 +1,30 @@
|
||||
$bg: $body-bg !default;
|
||||
$fg: $body-color !default;
|
||||
|
||||
$shiny-disconnected-bg: mix($bg, $fg, 58%) !default;
|
||||
$shiny-table-na: mix($bg, $fg, 54%) !default;
|
||||
$shiny-error-validated-color: mix($bg, $fg, 50%) !default;
|
||||
$shiny-progress-text-bg-color: #eef8ff !default;
|
||||
$shiny-input-panel-bg: mix($bg, $fg, 96%) !default;
|
||||
$shiny-input-panel-border: $border-width solid $border-color !default;
|
||||
$shiny-input-panel-border-radius: $border-radius !default;
|
||||
$shiny-text-output-border-radius: $border-radius !default;
|
||||
$notification-bg-color: mix($bg, $fg, 90%) !default;
|
||||
$notification-color: $fg !default;
|
||||
$notification-border: $border-width solid $border-color !default;
|
||||
$notification-border-radius: $border-radius !default;
|
||||
$notification-message-bg: mix($bg, map-get($theme-colors, "info"), 90%) !default;
|
||||
$notification-message-color: mix($fg, map-get($theme-colors, "info"), 10%) !default;
|
||||
$notification-message-border: $border-width solid mix($bg, map-get($theme-colors, "info"), 53%) !default;
|
||||
$notification-warning-bg: mix($bg, map-get($theme-colors, "warning"), 90%) !default;
|
||||
$notification-warning-color: mix($fg, map-get($theme-colors, "warning"), 10%) !default;
|
||||
$notification-warning-border: $border-width solid mix($bg, map-get($theme-colors, "warning"), 71%) !default;
|
||||
$notification-error-bg: mix($bg, map-get($theme-colors, "danger"), 90%) !default;
|
||||
$notification-error-color: mix($fg, map-get($theme-colors, "danger"), 10%) !default;
|
||||
$notification-error-border: $border-width solid mix($bg, map-get($theme-colors, "danger"), 79%) !default;
|
||||
$notification-close-color: mix($bg, $fg, 20%) !default;
|
||||
$notification-close-hover-color: $fg !default;
|
||||
$notification-content-action-color: map-get($theme-colors, "primary") !default;
|
||||
$datepicker-disabled-color: $dropdown-link-disabled-color !default;
|
||||
|
||||
$shiny-file-active-shadow: $custom-file-focus-box-shadow !default;
|
||||
39
inst/www/shared/shiny_scss/shiny.bootstrap5.scss
Normal file
39
inst/www/shared/shiny_scss/shiny.bootstrap5.scss
Normal file
@@ -0,0 +1,39 @@
|
||||
$body-emphasis-color: $body-color !default; // introduced in BS 5.3
|
||||
|
||||
$shiny-emphasis-color-rgb: var(--#{$prefix}emphasis-color-rgb, 0,0,0) !default;
|
||||
|
||||
$shiny-disconnected-bg: RGBA($shiny-emphasis-color-rgb, 0.42) !default;
|
||||
$shiny-table-na: RGBA($shiny-emphasis-color-rgb, 0.46) !default;
|
||||
$shiny-error-color: var(--#{$prefix}danger-text-emphasis) !default;
|
||||
$shiny-error-validated-color: RGBA($shiny-emphasis-color-rgb, 0.5) !default;
|
||||
$shiny-progress-text-bg-color: RGBA(var(--#{$prefix}primary-rgb, #{to-rgb($primary)}), 0.05) !default;
|
||||
|
||||
$shiny-input-panel-bg: RGBA($shiny-emphasis-color-rgb, 0.04) !default;
|
||||
$shiny-input-panel-border: $border-width solid var(--#{$prefix}border-color, #{$border-color}) !default;
|
||||
$shiny-input-panel-border-radius: $border-radius !default;
|
||||
$shiny-text-output-border-radius: $border-radius !default;
|
||||
|
||||
$notification-color: var(--#{$prefix}emphasis-color, #{$body-emphasis-color}) !default;
|
||||
$notification-bg-color: var(--#{$prefix}body-bg, #{$body-bg}) !default;
|
||||
$notification-border: $border-width solid var(--#{$prefix}border-color, #{$border-color}) !default;
|
||||
$notification-border-radius: $border-radius !default;
|
||||
|
||||
$notification-message-color: var(--#{$prefix}info-text-emphasis) !default;
|
||||
$notification-message-bg: var(--#{$prefix}info-bg-subtle) !default;
|
||||
$notification-message-border: $border-width solid var(--#{$prefix}info-border-subtle) !default;
|
||||
|
||||
$notification-warning-color: var(--#{$prefix}warning-text-emphasis) !default;
|
||||
$notification-warning-bg: var(--#{$prefix}warning-bg-subtle) !default;
|
||||
$notification-warning-border: $border-width solid var(--#{$prefix}warning-border-subtle) !default;
|
||||
|
||||
$notification-error-color: var(--#{$prefix}danger-text-emphasis) !default;
|
||||
$notification-error-bg: var(--#{$prefix}danger-bg-subtle) !default;
|
||||
$notification-error-border: $border-width solid var(--#{$prefix}danger-border-subtle) !default;
|
||||
|
||||
$notification-close-color: RGBA($shiny-emphasis-color-rgb, 0.8) !default;
|
||||
$notification-close-hover-color: RGB($shiny-emphasis-color-rgb) !default;
|
||||
$notification-content-action-color: RGB(var(--#{$prefix}primary-rgb, #{to-rgb($primary)})) !default;
|
||||
|
||||
$datepicker-disabled-color: $dropdown-link-disabled-color !default;
|
||||
|
||||
$shiny-file-active-shadow: $input-focus-box-shadow !default;
|
||||
@@ -13,7 +13,7 @@ $notification-bg-color: #e8e8e8 !default;
|
||||
$notification-color: #333 !default;
|
||||
$notification-border: 1px solid #ccc !default;
|
||||
$notification-border-radius: 3px !default;
|
||||
$notification-padding: 10px 8px 10px 10px !default;
|
||||
$notification-padding: 10px 2rem 10px 10px !default;
|
||||
$notification-message-bg: #d9edf7 !default;
|
||||
$notification-message-color: #31708f !default;
|
||||
$notification-message-border: 1px solid #bce8f1 !default;
|
||||
@@ -88,10 +88,7 @@ pre.shiny-text-output {
|
||||
|
||||
#shiny-disconnected-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
inset: 0;
|
||||
background-color: $shiny-disconnected-bg;
|
||||
opacity: 0.5;
|
||||
overflow: hidden;
|
||||
@@ -99,6 +96,17 @@ pre.shiny-text-output {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
html.autoreload-enabled #shiny-disconnected-overlay.reloading {
|
||||
opacity: 0;
|
||||
animation: fadeIn 250ms forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
@keyframes fadeIn {
|
||||
to {
|
||||
opacity: 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
.table.shiny-table {
|
||||
@include table-padding($left: 12px, $right: 12px);
|
||||
}
|
||||
@@ -382,18 +390,19 @@ pre.shiny-text-output {
|
||||
right: 0;
|
||||
background-color: rgba(0,0,0,0);
|
||||
padding: 2px;
|
||||
width: 250px;
|
||||
width: 300px;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.shiny-notification {
|
||||
position: relative;
|
||||
background-color: $notification-bg-color;
|
||||
color: $notification-color;
|
||||
border: $notification-border;
|
||||
@include border-radius-shim($notification-border-radius);
|
||||
opacity: 0.85;
|
||||
padding: $notification-padding;
|
||||
margin: 2px;
|
||||
margin: 5px;
|
||||
&-message {
|
||||
color: $notification-message-color;
|
||||
background-color: $notification-message-bg;
|
||||
@@ -410,17 +419,23 @@ pre.shiny-text-output {
|
||||
border: $notification-error-border;
|
||||
}
|
||||
&-close {
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
bottom: 9px;
|
||||
position: relative;
|
||||
padding-left: 4px;
|
||||
position: absolute;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: normal;
|
||||
font-size: 1.125em;
|
||||
padding: 0.25rem;
|
||||
color: $notification-close-color;
|
||||
cursor: default;
|
||||
cursor: pointer;
|
||||
}
|
||||
&-close:hover {
|
||||
color: $notification-close-hover-color;
|
||||
font-weight: bold;
|
||||
}
|
||||
&-content-action a {
|
||||
color: $notification-content-action-color;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"homepage": "https://shiny.rstudio.com",
|
||||
"repository": "github:rstudio/shiny",
|
||||
"name": "@types/rstudio-shiny",
|
||||
"version": "1.7.5-alpha.9000",
|
||||
"version": "1.8.0",
|
||||
"license": "GPL-3.0-only",
|
||||
"main": "",
|
||||
"browser": "",
|
||||
@@ -50,6 +50,7 @@
|
||||
"caniuse-lite": "^1.0.30001312",
|
||||
"core-js": "^3.13.0",
|
||||
"esbuild": "^0.15.10",
|
||||
"esbuild-plugin-babel": "https://github.com/schloerke/esbuild-plugin-babel#patch-2",
|
||||
"esbuild-plugin-globals": "^0.1.1",
|
||||
"esbuild-plugin-sass": "^1.0.1",
|
||||
"eslint": "^8.24.0",
|
||||
|
||||
@@ -1,28 +1,22 @@
|
||||
# Revdeps
|
||||
|
||||
## Failed to check (21)
|
||||
## Failed to check (15)
|
||||
|
||||
|package |version |error |warning |note |
|
||||
|:----------|:-------|:-----|:-------|:----|
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|ctsem |3.7.6 |1 | | |
|
||||
|disk.frame |0.8.2 |1 | | |
|
||||
|diveR |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|grandR |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|loon.shiny |? | | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|RQuantLib |0.4.18 |1 | | |
|
||||
|rstanarm |2.21.4 |1 | | |
|
||||
|NA |? | | | |
|
||||
|NA |? | | | |
|
||||
|package |version |error |warning |note |
|
||||
|:------------------|:-------|:-----|:-------|:----|
|
||||
|bigPint |? | | | |
|
||||
|bioCancer |? | | | |
|
||||
|ctsem |3.9.1 |1 | | |
|
||||
|diveR |? | | | |
|
||||
|EBImage |? | | | |
|
||||
|GeneNetworkBuilder |? | | | |
|
||||
|InterCellar |? | | | |
|
||||
|LACE |? | | | |
|
||||
|loon.shiny |? | | | |
|
||||
|MatrixQCvis |? | | | |
|
||||
|modchart |? | | | |
|
||||
|omicsViewer |? | | | |
|
||||
|parcats |? | | | |
|
||||
|RQuantLib |0.4.19 |1 | | |
|
||||
|rstanarm |2.26.1 |1 | | |
|
||||
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
## revdepcheck results
|
||||
|
||||
We checked 1145 reverse dependencies (1131 from CRAN + 14 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.
|
||||
We checked 1172 reverse dependencies (1162 from CRAN + 10 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package.
|
||||
|
||||
* We saw 0 new problems
|
||||
* We failed to check 7 packages
|
||||
* We failed to check 5 packages
|
||||
|
||||
Issues with CRAN packages are summarised below.
|
||||
|
||||
### Failed to check
|
||||
|
||||
* ctsem (NA)
|
||||
* disk.frame (NA)
|
||||
* diveR (NA)
|
||||
* grandR (NA)
|
||||
* loon.shiny (NA)
|
||||
* RQuantLib (NA)
|
||||
* rstanarm (NA)
|
||||
|
||||
@@ -150,6 +150,12 @@ All config files are located in the root folder to avoid opening two separate VS
|
||||
* Used by `prettier` to know how to adjust code when a file is saved in VSCode or within `eslint`'s linting process.
|
||||
* `yarnrc.yml`
|
||||
* Notifies `yarn` to use `yarn` v2, install `./node_modules` folder for `esbuild`, and any CLI plugins.
|
||||
* `babel.config.json`
|
||||
* Used within `babel` transpilation of TypeScript -> JavaScript -> polyfilled JavaScript.
|
||||
* Noteable options set:
|
||||
* `"useBuiltIns": "usage"` - `core-js` polyfills are only added as they are _used_.
|
||||
* `"corejs": "3.9"` - This number should match the installed `core-js` number.
|
||||
* `"ignore":["node_modules/core-js"]` - The `core-js` library is directly ignored to [avoid being processed by `babel`](https://github.com/zloirock/core-js/issues/743#issuecomment-571983318).
|
||||
* `jest.config.js`
|
||||
* Used to configure [`jest` testing](https://jestjs.io/)
|
||||
* `package.json`
|
||||
@@ -162,6 +168,7 @@ All config files are located in the root folder to avoid opening two separate VS
|
||||
* `tsconfig.json` -
|
||||
* TypeScript config file
|
||||
* Notable options set:
|
||||
* `target: ES5` - Compile to es5, so babel has an easier job.
|
||||
* `preserveConstEnums: false` - Do no preserve enum values into the final code. (If true, produces bloat / unused code)
|
||||
* `isolatedModules: true` & `esModuleInterop: true` - Requested by `esbuild`. This [allows for `esbuild`](https://esbuild.github.io/content-types/#typescript) to safely compile the files in parallel
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@ import { basename } from "path";
|
||||
// @ts-ignore; Type definitions are not found. This occurs when `strict: true` in tsconfig.json
|
||||
import readcontrol from "readcontrol";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore; Type definitions are not found. This occurs when `strict: true` in tsconfig.json
|
||||
import babelPlugin from "esbuild-plugin-babel";
|
||||
|
||||
const outDir = "./inst/www/shared/";
|
||||
|
||||
type ShinyDesc = { version: string; package: string; license: string };
|
||||
@@ -75,7 +79,7 @@ async function build(
|
||||
return esbuildBuild({
|
||||
incremental: incremental,
|
||||
watch: watch,
|
||||
target: "es2020",
|
||||
target: "es5",
|
||||
preserveSymlinks: true,
|
||||
...opts,
|
||||
}).then((x) => {
|
||||
@@ -84,4 +88,4 @@ async function build(
|
||||
});
|
||||
}
|
||||
|
||||
export { outDir, build, shinyDesc, banner };
|
||||
export { outDir, build, shinyDesc, banner, babelPlugin };
|
||||
|
||||
@@ -55,6 +55,14 @@ build({
|
||||
minify: true,
|
||||
});
|
||||
|
||||
build({
|
||||
...opts,
|
||||
entryPoints: [outDir + "selectize/js/selectize.js"],
|
||||
outfile: outDir + "selectize/js/selectize.min.js",
|
||||
minify: true,
|
||||
target: "es6",
|
||||
});
|
||||
|
||||
build({
|
||||
...opts,
|
||||
entryPoints: [outDir + "selectize/accessibility/js/selectize-plugin-a11y.js"],
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
|
||||
// - TypeScript -----------------------------------------------------------
|
||||
|
||||
import { banner, build, outDir } from "./_build";
|
||||
import { banner, build, outDir, babelPlugin } from "./_build";
|
||||
|
||||
build({
|
||||
bundle: true,
|
||||
sourcemap: true,
|
||||
minify: true,
|
||||
plugins: [babelPlugin()],
|
||||
banner: banner,
|
||||
entryPoints: [
|
||||
"srcts/extras/shiny-autoreload.ts",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// yarn build
|
||||
// ```
|
||||
|
||||
import { banner, build, outDir, shinyDesc } from "./_build";
|
||||
import { banner, build, outDir, shinyDesc, babelPlugin } from "./_build";
|
||||
import globalsPlugin from "esbuild-plugin-globals";
|
||||
import type { BuildOptions } from "esbuild";
|
||||
import { verifyJqueryImport } from "./_jquery";
|
||||
@@ -18,6 +18,7 @@ const opts: BuildOptions = {
|
||||
//// Loaded dynamically. MUST use `window.strftime` within code
|
||||
// strftime: "window.strftime",
|
||||
}),
|
||||
babelPlugin(),
|
||||
],
|
||||
define: {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
|
||||
@@ -1,18 +1,86 @@
|
||||
/* eslint-disable unicorn/filename-case */
|
||||
const protocol = (window.location.protocol === "https:") ? "wss:" : "ws:";
|
||||
|
||||
document.documentElement.classList.add("autoreload-enabled");
|
||||
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
||||
// Add trailing slash to path, if necessary, before appending "autoreload"
|
||||
const defaultPath = window.location.pathname.replace(/\/?$/, "/") + "autoreload/";
|
||||
const defaultPath =
|
||||
window.location.pathname.replace(/\/?$/, "/") + "autoreload/";
|
||||
const defaultUrl = `${protocol}//${window.location.host}${defaultPath}`;
|
||||
|
||||
// By default, use the defaultUrl. But if there's a data-ws-url attribute on our
|
||||
// <script> tag, use that instead.
|
||||
const wsUrl = document.currentScript.dataset.wsUrl || defaultUrl;
|
||||
const ws = new WebSocket(wsUrl);
|
||||
const wsUrl = document.currentScript?.dataset?.wsUrl || defaultUrl;
|
||||
|
||||
ws.onmessage = function (event) {
|
||||
if (event.data === "autoreload") {
|
||||
window.location.reload();
|
||||
/**
|
||||
* Connects to an autoreload URL and waits for the server to tell us what to do.
|
||||
*
|
||||
* @param url The ws:// or wss:// URL to connect to.
|
||||
* @returns true if the server requests a reload, or false if the connection was
|
||||
* successfully established but then closed without the server requesting a
|
||||
* reload
|
||||
* @throws A nondescript error if the connection fails to be established.
|
||||
*/
|
||||
async function autoreload(url: string): Promise<boolean> {
|
||||
const ws = new WebSocket(url);
|
||||
|
||||
let success = false;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
ws.onopen = () => {
|
||||
success = true;
|
||||
};
|
||||
|
||||
ws.onerror = (err) => {
|
||||
reject(err);
|
||||
};
|
||||
|
||||
ws.onclose = () => {
|
||||
if (!success) {
|
||||
reject(new Error("WebSocket connection failed"));
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
};
|
||||
|
||||
ws.onmessage = function (event) {
|
||||
if (event.data === "autoreload") {
|
||||
resolve(true);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
while (true) {
|
||||
try {
|
||||
if (await autoreload(wsUrl)) {
|
||||
window.location.reload();
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
// It's possible for the autoreload() call to throw. If it does, that
|
||||
// means we tried but failed to connect to the autoreload socket. This
|
||||
// probably means that the entire `shiny run --reload` process was
|
||||
// restarted. As of today, the autoreload websocket port number is
|
||||
// randomly chosen for each `shiny run --reload` process, so it's
|
||||
// impossible for us to recover.
|
||||
console.debug("Giving up on autoreload");
|
||||
return;
|
||||
}
|
||||
// If we get here, the connection to the autoreload server was
|
||||
// successful but then got broken. Wait for a second, and then
|
||||
// try to re-establish the connection.
|
||||
await sleep(1000);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
initialize().catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
export {};
|
||||
|
||||
@@ -44,7 +44,7 @@ class InputBinding {
|
||||
// 'data' should be an object with elements corresponding to value, min,
|
||||
// max, etc., as appropriate for the type of input object. It also should
|
||||
// trigger a change event.
|
||||
receiveMessage(el: HTMLElement, data: unknown): void {
|
||||
receiveMessage(el: HTMLElement, data: unknown): Promise<void> | void {
|
||||
throw "Not implemented";
|
||||
el; // unused var
|
||||
data; // unused var
|
||||
|
||||
@@ -2,8 +2,6 @@ import $ from "jquery";
|
||||
import { InputBinding } from "./inputBinding";
|
||||
import { $escape, hasDefinedProperty, updateLabel } from "../../utils";
|
||||
import { indirectEval } from "../../utils/eval";
|
||||
import { shinyBindAll, shinyUnbindAll } from "../../shiny/initedMethods";
|
||||
import type { NotUndefined } from "../../utils/extraTypes";
|
||||
|
||||
type SelectHTMLElement = HTMLSelectElement & { nonempty: boolean };
|
||||
|
||||
@@ -62,10 +60,14 @@ class SelectInputBinding extends InputBinding {
|
||||
getId(el: SelectHTMLElement): string {
|
||||
return InputBinding.prototype.getId.call(this, el) || el.name;
|
||||
}
|
||||
getValue(
|
||||
el: HTMLElement
|
||||
): NotUndefined<ReturnType<JQuery<HTMLElement>["val"]>> {
|
||||
return $(el).val() as NotUndefined<ReturnType<JQuery<HTMLElement>["val"]>>;
|
||||
getValue(el: SelectHTMLElement): any {
|
||||
if (!isSelectize(el)) {
|
||||
return $(el).val();
|
||||
} else {
|
||||
const selectize = this._selectize(el);
|
||||
|
||||
return selectize?.getValue();
|
||||
}
|
||||
}
|
||||
setValue(el: SelectHTMLElement, value: string): void {
|
||||
if (!isSelectize(el)) {
|
||||
@@ -146,6 +148,7 @@ class SelectInputBinding extends InputBinding {
|
||||
selectize.settings.load = function (query: string, callback: CallbackFn) {
|
||||
const settings = selectize.settings;
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
$.ajax({
|
||||
url: data.url,
|
||||
data: {
|
||||
@@ -284,34 +287,18 @@ class SelectInputBinding extends InputBinding {
|
||||
// @ts-expect-error; Need to type `options` keys to know exactly which values are accessed.
|
||||
options[x] = indirectEval("(" + options[x] + ")");
|
||||
});
|
||||
|
||||
let control = this._newSelectize($el, options);
|
||||
|
||||
let control = $el.selectize(options)[0].selectize as SelectizeInfo;
|
||||
// .selectize() does not really update settings; must destroy and rebuild
|
||||
|
||||
if (update) {
|
||||
const settings = $.extend(control.settings, options);
|
||||
|
||||
control.destroy();
|
||||
control = this._newSelectize($el, settings);
|
||||
control = $el.selectize(settings)[0].selectize as SelectizeInfo;
|
||||
}
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
protected _newSelectize(
|
||||
$el: JQuery<HTMLSelectElement>,
|
||||
options: SelectizeOptions
|
||||
): SelectizeInfo {
|
||||
// Starting with selectize v0.15.2, $el.selectize() can prune the <select>
|
||||
// element from the DOM, meaning that if we're already bound to it, we'll
|
||||
// lose the binding. So if we are bound, unbind first, then rebind after.
|
||||
// (Note this is quite similar to how Shiny.renderContent() works.)
|
||||
const binding = $el.data("shiny-input-binding");
|
||||
if (binding) shinyUnbindAll($el.parent());
|
||||
const control = $el.selectize(options)[0].selectize as SelectizeInfo;
|
||||
if (binding) shinyBindAll($el.parent());
|
||||
return control;
|
||||
}
|
||||
}
|
||||
|
||||
export { SelectInputBinding };
|
||||
|
||||
@@ -180,6 +180,7 @@ class FileUploader extends FileProcessor {
|
||||
onFile(file: File, cont: () => void): void {
|
||||
this.onProgress(file, 0);
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
$.ajax(this.uploadUrl, {
|
||||
type: "POST",
|
||||
cache: false,
|
||||
|
||||
@@ -140,14 +140,14 @@ function bindInputs(
|
||||
return inputItems;
|
||||
}
|
||||
|
||||
function bindOutputs(
|
||||
async function bindOutputs(
|
||||
{
|
||||
sendOutputHiddenState,
|
||||
maybeAddThemeObserver,
|
||||
outputBindings,
|
||||
}: BindInputsCtx,
|
||||
scope: BindScope = document.documentElement
|
||||
): void {
|
||||
): Promise<void> {
|
||||
const $scope = $(scope);
|
||||
|
||||
const bindings = outputBindings.getBindings();
|
||||
@@ -184,7 +184,7 @@ function bindOutputs(
|
||||
|
||||
const bindingAdapter = new OutputBindingAdapter(el, binding);
|
||||
|
||||
shinyAppBindOutput(id, bindingAdapter);
|
||||
await shinyAppBindOutput(id, bindingAdapter);
|
||||
$el.data("shiny-output-binding", bindingAdapter);
|
||||
$el.addClass("shiny-bound-output");
|
||||
if (!$el.attr("aria-live")) $el.attr("aria-live", "polite");
|
||||
@@ -270,11 +270,11 @@ function unbindOutputs(
|
||||
|
||||
// (Named used before TS conversion)
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
function _bindAll(
|
||||
async function _bindAll(
|
||||
shinyCtx: BindInputsCtx,
|
||||
scope: BindScope
|
||||
): ReturnType<typeof bindInputs> {
|
||||
bindOutputs(shinyCtx, scope);
|
||||
): Promise<ReturnType<typeof bindInputs>> {
|
||||
await bindOutputs(shinyCtx, scope);
|
||||
return bindInputs(shinyCtx, scope);
|
||||
}
|
||||
function unbindAll(
|
||||
@@ -285,10 +285,13 @@ function unbindAll(
|
||||
unbindInputs(scope, includeSelf);
|
||||
unbindOutputs(shinyCtx, scope, includeSelf);
|
||||
}
|
||||
function bindAll(shinyCtx: BindInputsCtx, scope: BindScope): void {
|
||||
async function bindAll(
|
||||
shinyCtx: BindInputsCtx,
|
||||
scope: BindScope
|
||||
): Promise<void> {
|
||||
// _bindAll returns input values; it doesn't send them to the server.
|
||||
// Shiny.bindAll needs to send the values to the server.
|
||||
const currentInputItems = _bindAll(shinyCtx, scope);
|
||||
const currentInputItems = await _bindAll(shinyCtx, scope);
|
||||
|
||||
const inputs = shinyCtx.inputs;
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ function setShiny(windowShiny_: Shiny): void {
|
||||
// Init Shiny a little later than document ready, so user code can
|
||||
// run first (i.e. to register bindings)
|
||||
setTimeout(function () {
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
initShiny(windowShiny);
|
||||
}, 1);
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ import { registerNames as singletonsRegisterNames } from "./singletons";
|
||||
import type { InputPolicyOpts } from "../inputPolicies/inputPolicy";
|
||||
|
||||
// "init_shiny.js"
|
||||
function initShiny(windowShiny: Shiny): void {
|
||||
async function initShiny(windowShiny: Shiny): Promise<void> {
|
||||
setShinyObj(windowShiny);
|
||||
const shinyapp = (windowShiny.shinyapp = new ShinyApp());
|
||||
|
||||
@@ -95,8 +95,8 @@ function initShiny(windowShiny: Shiny): void {
|
||||
};
|
||||
}
|
||||
|
||||
windowShiny.bindAll = function (scope: BindScope) {
|
||||
bindAll(shinyBindCtx(), scope);
|
||||
windowShiny.bindAll = async function (scope: BindScope) {
|
||||
await bindAll(shinyBindCtx(), scope);
|
||||
};
|
||||
windowShiny.unbindAll = function (scope: BindScope, includeSelf = false) {
|
||||
unbindAll(shinyBindCtx(), scope, includeSelf);
|
||||
@@ -146,7 +146,7 @@ function initShiny(windowShiny: Shiny): void {
|
||||
// have a reference to the DOM element, which would prevent it from being
|
||||
// GC'd.
|
||||
const initialValues = mapValues(
|
||||
_bindAll(shinyBindCtx(), document.documentElement),
|
||||
await _bindAll(shinyBindCtx(), document.documentElement),
|
||||
(x) => x.value
|
||||
);
|
||||
|
||||
|
||||
@@ -55,8 +55,8 @@ function setShinyUser(user: string): void {
|
||||
function shinyForgetLastInputValue(name: string): void {
|
||||
validateShinyHasBeenSet().forgetLastInputValue(name);
|
||||
}
|
||||
function shinyBindAll(scope: BindScope): void {
|
||||
validateShinyHasBeenSet().bindAll(scope);
|
||||
async function shinyBindAll(scope: BindScope): Promise<void> {
|
||||
await validateShinyHasBeenSet().bindAll(scope);
|
||||
}
|
||||
function shinyUnbindAll(scope: BindScope, includeSelf = false): void {
|
||||
validateShinyHasBeenSet().unbindAll(scope, includeSelf);
|
||||
@@ -65,8 +65,11 @@ function shinyInitializeInputs(scope: BindScope): void {
|
||||
validateShinyHasBeenSet().initializeInputs(scope);
|
||||
}
|
||||
|
||||
function shinyAppBindOutput(id: string, binding: OutputBindingAdapter): void {
|
||||
shinyShinyApp().bindOutput(id, binding);
|
||||
async function shinyAppBindOutput(
|
||||
id: string,
|
||||
binding: OutputBindingAdapter
|
||||
): Promise<void> {
|
||||
await shinyShinyApp().bindOutput(id, binding);
|
||||
}
|
||||
|
||||
function shinyAppUnbindOutput(
|
||||
|
||||
@@ -50,6 +50,7 @@ function initReactlog(): void {
|
||||
window.escape(shinyAppConfig().sessionId);
|
||||
|
||||
// send notification
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
$.get(url, function (result: "marked" | void) {
|
||||
if (result !== "marked") return;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ function updateTime(reconnectTime: number): void {
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function showReconnectDialog(delay: number): void {
|
||||
async function showReconnectDialog(delay: number): Promise<void> {
|
||||
const reconnectTime = new Date().getTime() + delay;
|
||||
|
||||
// If there's already a reconnect dialog, don't add another
|
||||
@@ -34,7 +34,7 @@ function showReconnectDialog(delay: number): void {
|
||||
const action =
|
||||
'<a id="shiny-reconnect-now" href="#" onclick="Shiny.shinyapp.reconnect();">Try now</a>';
|
||||
|
||||
showNotification({
|
||||
await showNotification({
|
||||
id: "reconnect",
|
||||
html: html,
|
||||
action: action,
|
||||
|
||||
@@ -62,7 +62,7 @@ async function renderContentAsync(
|
||||
|
||||
if (where === "replace") {
|
||||
shinyInitializeInputs(el);
|
||||
shinyBindAll(el);
|
||||
await shinyBindAll(el);
|
||||
} else {
|
||||
const $parent = $(el).parent();
|
||||
|
||||
@@ -75,7 +75,7 @@ async function renderContentAsync(
|
||||
}
|
||||
}
|
||||
shinyInitializeInputs(scope);
|
||||
shinyBindAll(scope);
|
||||
await shinyBindAll(scope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ function renderContent(
|
||||
el: BindScope,
|
||||
content: string | { html: string; deps?: HtmlDep[] } | null,
|
||||
where: WherePosition = "replace"
|
||||
): void {
|
||||
): Promise<void> {
|
||||
if (where === "replace") {
|
||||
shinyUnbindAll(el);
|
||||
}
|
||||
@@ -106,7 +106,7 @@ function renderContent(
|
||||
|
||||
if (where === "replace") {
|
||||
shinyInitializeInputs(el);
|
||||
shinyBindAll(el);
|
||||
return shinyBindAll(el);
|
||||
} else {
|
||||
const $parent = $(el).parent();
|
||||
|
||||
@@ -119,7 +119,7 @@ function renderContent(
|
||||
}
|
||||
}
|
||||
shinyInitializeInputs(scope);
|
||||
shinyBindAll(scope);
|
||||
return shinyBindAll(scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,9 @@ class ShinyApp {
|
||||
socket.send(msg as string);
|
||||
}
|
||||
|
||||
// This launches the action queue loop, which just runs in the background,
|
||||
// so we don't need to await it.
|
||||
/* eslint-disable @typescript-eslint/no-floating-promises */
|
||||
this.startActionQueueLoop();
|
||||
};
|
||||
socket.onmessage = (e) => {
|
||||
@@ -244,7 +247,8 @@ class ShinyApp {
|
||||
};
|
||||
// Called when a successfully-opened websocket is closed, or when an
|
||||
// attempt to open a connection fails.
|
||||
socket.onclose = () => {
|
||||
socket.onclose = (e) => {
|
||||
const restarting = e.code === 1012; // Uvicorn sets this code when autoreloading
|
||||
// These things are needed only if we've successfully opened the
|
||||
// websocket.
|
||||
if (hasOpened) {
|
||||
@@ -257,7 +261,7 @@ class ShinyApp {
|
||||
this.$notifyDisconnected();
|
||||
}
|
||||
|
||||
this.onDisconnected(); // Must be run before this.$removeSocket()
|
||||
this.onDisconnected(restarting); // Must be run before this.$removeSocket()
|
||||
this.$removeSocket();
|
||||
};
|
||||
return socket;
|
||||
@@ -333,13 +337,12 @@ class ShinyApp {
|
||||
};
|
||||
})();
|
||||
|
||||
onDisconnected(): void {
|
||||
onDisconnected(reloading = false): void {
|
||||
// Add gray-out overlay, if not already present
|
||||
const $overlay = $("#shiny-disconnected-overlay");
|
||||
|
||||
if ($overlay.length === 0) {
|
||||
if ($("#shiny-disconnected-overlay").length === 0) {
|
||||
$(document.body).append('<div id="shiny-disconnected-overlay"></div>');
|
||||
}
|
||||
$("#shiny-disconnected-overlay").toggleClass("reloading", reloading);
|
||||
|
||||
// To try a reconnect, both the app (this.$allowReconnect) and the
|
||||
// server (this.$socket.allowReconnect) must allow reconnections, or
|
||||
@@ -507,12 +510,16 @@ class ShinyApp {
|
||||
return value;
|
||||
}
|
||||
|
||||
bindOutput(id: string, binding: OutputBindingAdapter): OutputBindingAdapter {
|
||||
async bindOutput(
|
||||
id: string,
|
||||
binding: OutputBindingAdapter
|
||||
): Promise<OutputBindingAdapter> {
|
||||
if (!id) throw "Can't bind an element with no ID";
|
||||
if (this.$bindings[id]) throw "Duplicate binding for ID " + id;
|
||||
this.$bindings[id] = binding;
|
||||
|
||||
if (this.$values[id] !== undefined) binding.onValueChange(this.$values[id]);
|
||||
if (this.$values[id] !== undefined)
|
||||
await binding.onValueChange(this.$values[id]);
|
||||
else if (this.$errors[id] !== undefined)
|
||||
binding.onValueError(this.$errors[id]);
|
||||
|
||||
@@ -710,7 +717,7 @@ class ShinyApp {
|
||||
|
||||
addMessageHandler(
|
||||
"inputMessages",
|
||||
(message: Array<{ id: string; message: unknown }>) => {
|
||||
async (message: Array<{ id: string; message: unknown }>) => {
|
||||
// inputMessages should be an array
|
||||
for (let i = 0; i < message.length; i++) {
|
||||
const $obj = $(".shiny-bound-input#" + $escape(message[i].id));
|
||||
@@ -727,7 +734,7 @@ class ShinyApp {
|
||||
$(el).trigger(evt);
|
||||
if (!evt.isDefaultPrevented()) {
|
||||
try {
|
||||
inputBinding.receiveMessage(el, evt.message);
|
||||
await inputBinding.receiveMessage(el, evt.message);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
"[shiny] Error in inputBinding.receiveMessage()",
|
||||
@@ -819,15 +826,15 @@ class ShinyApp {
|
||||
}
|
||||
});
|
||||
|
||||
addMessageHandler("custom", (message: { [key: string]: unknown }) => {
|
||||
addMessageHandler("custom", async (message: { [key: string]: unknown }) => {
|
||||
// For old-style custom messages - should deprecate and migrate to new
|
||||
// method
|
||||
const shinyOnCustomMessage = getShinyOnCustomMessage();
|
||||
|
||||
if (shinyOnCustomMessage) shinyOnCustomMessage(message);
|
||||
if (shinyOnCustomMessage) await shinyOnCustomMessage(message);
|
||||
|
||||
// Send messages.foo and messages.bar to appropriate handlers
|
||||
this._sendMessagesToHandlers(
|
||||
await this._sendMessagesToHandlers(
|
||||
message,
|
||||
customMessageHandlers,
|
||||
customMessageHandlerOrder
|
||||
|
||||
@@ -8,7 +8,7 @@ declare class InputBinding {
|
||||
getValue(el: HTMLElement): any;
|
||||
subscribe(el: HTMLElement, callback: (value: boolean) => void): void;
|
||||
unsubscribe(el: HTMLElement): void;
|
||||
receiveMessage(el: HTMLElement, data: unknown): void;
|
||||
receiveMessage(el: HTMLElement, data: unknown): Promise<void> | void;
|
||||
getState(el: HTMLElement): unknown;
|
||||
getRatePolicy(el: HTMLElement): {
|
||||
policy: RatePolicyModes;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference types="selectize" />
|
||||
import { InputBinding } from "./inputBinding";
|
||||
import type { NotUndefined } from "../../utils/extraTypes";
|
||||
type SelectHTMLElement = HTMLSelectElement & {
|
||||
nonempty: boolean;
|
||||
};
|
||||
@@ -19,7 +18,7 @@ declare class SelectInputBinding extends InputBinding {
|
||||
find(scope: HTMLElement): JQuery<HTMLElement>;
|
||||
getType(el: HTMLElement): string | null;
|
||||
getId(el: SelectHTMLElement): string;
|
||||
getValue(el: HTMLElement): NotUndefined<ReturnType<JQuery<HTMLElement>["val"]>>;
|
||||
getValue(el: SelectHTMLElement): any;
|
||||
setValue(el: SelectHTMLElement, value: string): void;
|
||||
getState(el: SelectHTMLElement): {
|
||||
label: JQuery<HTMLElement>;
|
||||
@@ -34,7 +33,6 @@ declare class SelectInputBinding extends InputBinding {
|
||||
unsubscribe(el: HTMLElement): void;
|
||||
initialize(el: SelectHTMLElement): void;
|
||||
protected _selectize(el: SelectHTMLElement, update?: boolean): SelectizeInfo | undefined;
|
||||
protected _newSelectize($el: JQuery<HTMLSelectElement>, options: SelectizeOptions): SelectizeInfo;
|
||||
}
|
||||
export { SelectInputBinding };
|
||||
export type { SelectInputReceiveMessageData };
|
||||
|
||||
4
srcts/types/src/shiny/bind.d.ts
vendored
4
srcts/types/src/shiny/bind.d.ts
vendored
@@ -21,8 +21,8 @@ declare function bindInputs(shinyCtx: BindInputsCtx, scope?: BindScope): {
|
||||
};
|
||||
};
|
||||
};
|
||||
declare function _bindAll(shinyCtx: BindInputsCtx, scope: BindScope): ReturnType<typeof bindInputs>;
|
||||
declare function _bindAll(shinyCtx: BindInputsCtx, scope: BindScope): Promise<ReturnType<typeof bindInputs>>;
|
||||
declare function unbindAll(shinyCtx: BindInputsCtx, scope: BindScope, includeSelf?: boolean): void;
|
||||
declare function bindAll(shinyCtx: BindInputsCtx, scope: BindScope): void;
|
||||
declare function bindAll(shinyCtx: BindInputsCtx, scope: BindScope): Promise<void>;
|
||||
export { unbindAll, bindAll, _bindAll };
|
||||
export type { BindScope, BindInputsCtx };
|
||||
|
||||
2
srcts/types/src/shiny/init.d.ts
vendored
2
srcts/types/src/shiny/init.d.ts
vendored
@@ -1,3 +1,3 @@
|
||||
import type { Shiny } from ".";
|
||||
declare function initShiny(windowShiny: Shiny): void;
|
||||
declare function initShiny(windowShiny: Shiny): Promise<void>;
|
||||
export { initShiny };
|
||||
|
||||
4
srcts/types/src/shiny/initedMethods.d.ts
vendored
4
srcts/types/src/shiny/initedMethods.d.ts
vendored
@@ -11,10 +11,10 @@ declare function shinySetInputValue(name: string, value: unknown, opts?: {
|
||||
declare function shinyShinyApp(): ShinyApp;
|
||||
declare function setShinyUser(user: string): void;
|
||||
declare function shinyForgetLastInputValue(name: string): void;
|
||||
declare function shinyBindAll(scope: BindScope): void;
|
||||
declare function shinyBindAll(scope: BindScope): Promise<void>;
|
||||
declare function shinyUnbindAll(scope: BindScope, includeSelf?: boolean): void;
|
||||
declare function shinyInitializeInputs(scope: BindScope): void;
|
||||
declare function shinyAppBindOutput(id: string, binding: OutputBindingAdapter): void;
|
||||
declare function shinyAppBindOutput(id: string, binding: OutputBindingAdapter): Promise<void>;
|
||||
declare function shinyAppUnbindOutput(id: string, binding: OutputBindingAdapter): boolean;
|
||||
declare function getShinyOnCustomMessage(): Handler | null;
|
||||
declare function getFileInputBinding(): FileInputBinding;
|
||||
|
||||
2
srcts/types/src/shiny/reconnectDialog.d.ts
vendored
2
srcts/types/src/shiny/reconnectDialog.d.ts
vendored
@@ -1,3 +1,3 @@
|
||||
declare function showReconnectDialog(delay: number): void;
|
||||
declare function showReconnectDialog(delay: number): Promise<void>;
|
||||
declare function hideReconnectDialog(): void;
|
||||
export { showReconnectDialog, hideReconnectDialog };
|
||||
|
||||
2
srcts/types/src/shiny/render.d.ts
vendored
2
srcts/types/src/shiny/render.d.ts
vendored
@@ -8,7 +8,7 @@ declare function renderContentAsync(el: BindScope, content: string | {
|
||||
declare function renderContent(el: BindScope, content: string | {
|
||||
html: string;
|
||||
deps?: HtmlDep[];
|
||||
} | null, where?: WherePosition): void;
|
||||
} | null, where?: WherePosition): Promise<void>;
|
||||
declare function renderHtmlAsync(html: string, el: BindScope, dependencies: HtmlDep[], where?: WherePosition): Promise<ReturnType<typeof singletonsRenderHtml>>;
|
||||
declare function renderHtml(html: string, el: BindScope, dependencies: HtmlDep[], where?: WherePosition): ReturnType<typeof singletonsRenderHtml>;
|
||||
declare function renderDependenciesAsync(dependencies: HtmlDep[] | null): Promise<void>;
|
||||
|
||||
4
srcts/types/src/shiny/shinyapp.d.ts
vendored
4
srcts/types/src/shiny/shinyapp.d.ts
vendored
@@ -61,13 +61,13 @@ declare class ShinyApp {
|
||||
next: () => number;
|
||||
reset: () => void;
|
||||
};
|
||||
onDisconnected(): void;
|
||||
onDisconnected(reloading?: boolean): void;
|
||||
onConnected(): void;
|
||||
makeRequest(method: string, args: unknown[], onSuccess: OnSuccessRequest, onError: OnErrorRequest, blobs: Array<ArrayBuffer | Blob | string> | undefined): void;
|
||||
$sendMsg(msg: MessageValue): void;
|
||||
receiveError(name: string, error: ErrorsMessageValue): void;
|
||||
receiveOutput<T>(name: string, value: T): Promise<T | undefined>;
|
||||
bindOutput(id: string, binding: OutputBindingAdapter): OutputBindingAdapter;
|
||||
bindOutput(id: string, binding: OutputBindingAdapter): Promise<OutputBindingAdapter>;
|
||||
unbindOutput(id: string, binding: OutputBindingAdapter): boolean;
|
||||
private _narrowScopeComponent;
|
||||
private _narrowScope;
|
||||
|
||||
@@ -18,6 +18,9 @@ expect_snapshot2 <- function(...) {
|
||||
if (getRversion() < "3.6.0") {
|
||||
skip("Skipping snapshots on R < 3.6 because of different RNG method")
|
||||
}
|
||||
if (packageVersion("htmltools") <= "0.5.6" && getRversion() > "4.3.1") {
|
||||
skip("Skipping snapshots since htmltools is 'outdated'")
|
||||
}
|
||||
expect_snapshot(...)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
diff --git a/inst/www/shared/selectize/js/selectize.js b/inst/www/shared/selectize/js/selectize.js
|
||||
index 0b447a7b3..cbfe9178e 100644
|
||||
--- a/inst/www/shared/selectize/js/selectize.js
|
||||
+++ b/inst/www/shared/selectize/js/selectize.js
|
||||
@@ -834,6 +834,9 @@ var Selectize = function($input, settings) {
|
||||
|
||||
self.settings = {};
|
||||
|
||||
+ // increase the count of 'active' (i.e., non-destroyed) selectize instances
|
||||
+ ++Selectize.count;
|
||||
+
|
||||
$.extend(self, {
|
||||
order : 0,
|
||||
settings : settings,
|
||||
@@ -841,8 +844,8 @@ var Selectize = function($input, settings) {
|
||||
tabIndex : $input.attr('tabindex') || '',
|
||||
tagType : input.tagName.toLowerCase() === 'select' ? TAG_SELECT : TAG_INPUT,
|
||||
rtl : /rtl/i.test(dir),
|
||||
-
|
||||
- eventNS : '.selectize' + (++Selectize.count),
|
||||
+ // generate a unique ID for the event namespace
|
||||
+ eventNS : '.selectize-' + (new Date().getTime()) + '-' + (Math.random().toString(36).substr(2, 5)),
|
||||
highlightedValue : null,
|
||||
isBlurring : false,
|
||||
isOpen : false,
|
||||
32
tools/selectize-patches/008-selectize-revert-d2564a0a.patch
Normal file
32
tools/selectize-patches/008-selectize-revert-d2564a0a.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
diff --git a/inst/www/shared/selectize/js/selectize.js b/inst/www/shared/selectize/js/selectize.js
|
||||
index 767f45e1c..a902fae5b 100644
|
||||
--- a/inst/www/shared/selectize/js/selectize.js
|
||||
+++ b/inst/www/shared/selectize/js/selectize.js
|
||||
@@ -1064,14 +1064,8 @@ $.extend(Selectize.prototype, {
|
||||
self.ignoreHover = self.settings.ignoreHover;
|
||||
});
|
||||
|
||||
- var inputPlaceholder = $('<div></div>');
|
||||
- var inputChildren = $input.children().detach();
|
||||
-
|
||||
- $input.replaceWith(inputPlaceholder);
|
||||
- inputPlaceholder.replaceWith($input);
|
||||
-
|
||||
this.revertSettings = {
|
||||
- $children : inputChildren,
|
||||
+ $children : $input.children().detach(),
|
||||
tabindex : $input.attr('tabindex')
|
||||
};
|
||||
|
||||
diff --git a/inst/www/shared/shiny.js b/inst/www/shared/shiny.js
|
||||
index aeff68aa3..db9880f26 100644
|
||||
Binary files a/inst/www/shared/shiny.js and b/inst/www/shared/shiny.js differ
|
||||
diff --git a/inst/www/shared/shiny.js.map b/inst/www/shared/shiny.js.map
|
||||
index 34350b024..1abf54644 100644
|
||||
Binary files a/inst/www/shared/shiny.js.map and b/inst/www/shared/shiny.js.map differ
|
||||
diff --git a/inst/www/shared/shiny.min.js b/inst/www/shared/shiny.min.js
|
||||
index 8b8027fd3..eb1994aac 100644
|
||||
Binary files a/inst/www/shared/shiny.min.js and b/inst/www/shared/shiny.min.js differ
|
||||
diff --git a/inst/www/shared/shiny.min.js.map b/inst/www/shared/shiny.min.js.map
|
||||
index 560e1492e..0de12987b 100644
|
||||
Binary files a/inst/www/shared/shiny.min.js.map and b/inst/www/shared/shiny.min.js.map differ
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/inst/www/shared/selectize/js/selectize.js b/inst/www/shared/selectize/js/selectize.js
|
||||
index a902fae5b..5fa6dccaf 100644
|
||||
--- a/inst/www/shared/selectize/js/selectize.js
|
||||
+++ b/inst/www/shared/selectize/js/selectize.js
|
||||
@@ -2757,7 +2757,7 @@ Selectize.defaults = {
|
||||
maxItems: null,
|
||||
hideSelected: null,
|
||||
addPrecedence: false,
|
||||
- selectOnTab: true,
|
||||
+ selectOnTab: false,
|
||||
preload: false,
|
||||
allowEmptyOption: false,
|
||||
showEmptyOptionInDropdown: false,
|
||||
@@ -20,7 +20,7 @@ unlink(inst_dir, recursive = TRUE)
|
||||
|
||||
dir.create(file.path(inst_dir, "js"), recursive = TRUE)
|
||||
file.copy(
|
||||
file.path(node_dir, "js", "selectize.min.js"),
|
||||
file.path(node_dir, "js", c("selectize.js", "selectize.min.js")),
|
||||
file.path(inst_dir, "js"),
|
||||
overwrite = TRUE
|
||||
)
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@@ -2220,6 +2220,7 @@ __metadata:
|
||||
caniuse-lite: ^1.0.30001312
|
||||
core-js: ^3.13.0
|
||||
esbuild: ^0.15.10
|
||||
esbuild-plugin-babel: "https://github.com/schloerke/esbuild-plugin-babel#patch-2"
|
||||
esbuild-plugin-globals: ^0.1.1
|
||||
esbuild-plugin-sass: ^1.0.1
|
||||
eslint: ^8.24.0
|
||||
@@ -4223,6 +4224,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild-plugin-babel@https://github.com/schloerke/esbuild-plugin-babel#patch-2":
|
||||
version: 0.2.3
|
||||
resolution: "esbuild-plugin-babel@https://github.com/schloerke/esbuild-plugin-babel.git#commit=40106e72776cf4e2e4da8e52926632ceed378da0"
|
||||
peerDependencies:
|
||||
"@babel/core": ^7.0.0
|
||||
checksum: c89e123bc1944efcee5628ea6d8cb878384a4de5c19b4b598b660c03dd6429dd11e9120b5cbf54722331c69cb3bc25183b63ef1c28174ed44787228a44a58684
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild-plugin-globals@npm:^0.1.1":
|
||||
version: 0.1.1
|
||||
resolution: "esbuild-plugin-globals@npm:0.1.1"
|
||||
|
||||
Reference in New Issue
Block a user