mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-13 08:57:57 -05:00
Compare commits
33 Commits
v1.9.0
...
add-client
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f9176ac3b | ||
|
|
8f6ccd6bc4 | ||
|
|
380dfe0904 | ||
|
|
774def26de | ||
|
|
b24cbcb7b8 | ||
|
|
4d3ec8e7bd | ||
|
|
1018f7cc62 | ||
|
|
d87bcc5184 | ||
|
|
ca590f3854 | ||
|
|
a56cd962f0 | ||
|
|
078aeb23a8 | ||
|
|
79af1d6c92 | ||
|
|
f0bbc1db56 | ||
|
|
930040b66c | ||
|
|
a145add5d4 | ||
|
|
abf71389be | ||
|
|
2e2114f99d | ||
|
|
09d415502f | ||
|
|
c489fef4ff | ||
|
|
9d12b0fca7 | ||
|
|
cc9b9d4e6a | ||
|
|
34f9e4484d | ||
|
|
03a3f8f886 | ||
|
|
b900db0c74 | ||
|
|
5fb3ebc2d9 | ||
|
|
fbc6b2df57 | ||
|
|
6208225354 | ||
|
|
e22b693418 | ||
|
|
c7ca49c634 | ||
|
|
d84aa94762 | ||
|
|
89e2c18531 | ||
|
|
43d36c08dc | ||
|
|
4bc330e5dd |
@@ -1,7 +1,7 @@
|
||||
Package: shiny
|
||||
Type: Package
|
||||
Title: Web Application Framework for R
|
||||
Version: 1.9.0
|
||||
Version: 1.9.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"),
|
||||
|
||||
27
NEWS.md
27
NEWS.md
@@ -1,3 +1,29 @@
|
||||
# shiny (development version)
|
||||
|
||||
## 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 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)
|
||||
|
||||
* Capture and send client window size and scroll dimensions to the server which can be accessed via `session$clientData`. (#4147)
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Fixed a bug in `conditionalPanel()` that would cause the panel to repeatedly show/hide itself when the provided condition was not boolean. (@kamilzyla, #4127)
|
||||
|
||||
* 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)
|
||||
|
||||
* Fixed a bug in `onBookmark` hook that caused elements to not be excluded from URL bookmarking. (#3762)
|
||||
|
||||
# shiny 1.9.1
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Fixed a bug introduced in v1.9.0 where the boundaries of hover/click/brush regions on plots were being incorrectly scaled when browser zoom was used. (#4111)
|
||||
|
||||
# shiny 1.9.0
|
||||
|
||||
## New busy indication feature
|
||||
@@ -29,6 +55,7 @@ In addition, various properties of the spinners and pulse can be customized with
|
||||
* Output bindings that are removed, invalidated, then inserted again (while invalidated) now correctly include the `.recalculating` CSS class. (#4039)
|
||||
|
||||
* Fixed a recent issue with `uiOutput()` and `conditionalPanel()` not properly lower opacity when recalculation (in a Bootstrap 5 context). (#4027)
|
||||
|
||||
* Image outputs that were scaled by CSS had certain regions that were unresponsive to hover/click/brush handlers. (#3234)
|
||||
|
||||
# shiny 1.8.1.1
|
||||
|
||||
@@ -99,13 +99,13 @@ saveShinySaveState <- function(state) {
|
||||
|
||||
# Encode the state to a URL. This does not save to disk.
|
||||
encodeShinySaveState <- function(state) {
|
||||
exclude <- c(state$exclude, "._bookmark_")
|
||||
inputVals <- serializeReactiveValues(state$input, exclude, stateDir = NULL)
|
||||
|
||||
# Allow user-supplied onSave function to do things like add state$values.
|
||||
if (!is.null(state$onSave))
|
||||
isolate(state$onSave(state))
|
||||
|
||||
exclude <- c(state$exclude, "._bookmark_")
|
||||
inputVals <- serializeReactiveValues(state$input, exclude, stateDir = NULL)
|
||||
|
||||
inputVals <- vapply(inputVals,
|
||||
function(x) toJSON(x, strict_atomic = FALSE),
|
||||
character(1),
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
/*! shiny 1.9.0 | (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, var(--bs-body-bg, #fff), var(--bs-indigo, #4b00c1), var(--bs-purple, #74149c), var(--bs-pink, #bf007f), var(--bs-body-bg, #fff) ) );--_shiny-pulse-height: var(--shiny-pulse-height, 5px);--_shiny-pulse-speed: var(--shiny-pulse-speed, 1.85s);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-iteration-count:infinite;animation-timing-function:ease-in-out;content:""}[data-shiny-busy-spinners][data-shiny-busy-pulse].shiny-busy:has(.recalculating):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, var(--bs-body-bg, #fff), var(--bs-indigo, #4b00c1), var(--bs-purple, #74149c), var(--bs-pink, #bf007f), var(--bs-body-bg, #fff) ) );--_shiny-pulse-height: var(--shiny-pulse-height, 5px);--_shiny-pulse-speed: var(--shiny-pulse-speed, 1.85s);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-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:-75%;width:75%}50%{left:100%;width:75%}to{left:-75%;width:75%}}.shiny-spinner-output-container{--shiny-spinner-size: 0px}
|
||||
/*! 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}
|
||||
|
||||
@@ -235,6 +235,10 @@
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.irs--shiny .irs-handle.type_last {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.irs--shiny .irs-handle.state_hover, .irs--shiny .irs-handle:hover {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
@@ -143,6 +143,11 @@ $font-family: $font-family-base !default;
|
||||
border-radius: $handle_width;
|
||||
z-index: 2;
|
||||
|
||||
&.type_last {
|
||||
// Ensure last-used handle is on top if it overlaps with another handle
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
&.state_hover,
|
||||
&:hover {
|
||||
background: $handle_color_hover;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
||||
/*! shiny 1.9.0 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
|
||||
/*! shiny 1.9.1.9000 | (c) 2012-2024 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
@@ -1,3 +1,3 @@
|
||||
/*! shiny 1.9.0 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
|
||||
/*! 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)});})();
|
||||
//# sourceMappingURL=shiny-testmode.js.map
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*! shiny 1.9.0 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
|
||||
/*! shiny 1.9.1.9000 | (c) 2012-2024 RStudio, PBC. | License: GPL-3 | file LICENSE */
|
||||
"use strict";
|
||||
(function() {
|
||||
var __create = Object.create;
|
||||
@@ -8061,12 +8061,6 @@
|
||||
}, {
|
||||
key: "subscribe",
|
||||
value: function subscribe(el, callback) {
|
||||
(0, import_jquery8.default)(el).on(
|
||||
"keyup.dateInputBinding input.dateInputBinding",
|
||||
function() {
|
||||
callback(true);
|
||||
}
|
||||
);
|
||||
(0, import_jquery8.default)(el).on(
|
||||
"changeDate.dateInputBinding change.dateInputBinding",
|
||||
function() {
|
||||
@@ -8510,12 +8504,6 @@
|
||||
}, {
|
||||
key: "subscribe",
|
||||
value: function subscribe(el, callback) {
|
||||
(0, import_jquery9.default)(el).on(
|
||||
"keyup.dateRangeInputBinding input.dateRangeInputBinding",
|
||||
function() {
|
||||
callback(true);
|
||||
}
|
||||
);
|
||||
(0, import_jquery9.default)(el).on(
|
||||
"changeDate.dateRangeInputBinding change.dateRangeInputBinding",
|
||||
function() {
|
||||
@@ -14583,13 +14571,7 @@
|
||||
var dists = [];
|
||||
var i5;
|
||||
for (i5 = 0; i5 < coordmap.panels.length; i5++) {
|
||||
var panelRange = coordmap.panels[i5].range;
|
||||
var b3 = {
|
||||
top: panelRange.top * cssToImgRatio.y,
|
||||
bottom: panelRange.bottom * cssToImgRatio.y,
|
||||
left: panelRange.left * cssToImgRatio.x,
|
||||
right: panelRange.right * cssToImgRatio.x
|
||||
};
|
||||
var b3 = coordmap.panels[i5].range;
|
||||
if (x2 <= b3.right + expandImg.x && x2 >= b3.left - expandImg.x && y4 <= b3.bottom + expandImg.y && y4 >= b3.top - expandImg.y) {
|
||||
matches.push(coordmap.panels[i5]);
|
||||
var xdist = 0;
|
||||
@@ -23923,7 +23905,7 @@
|
||||
}
|
||||
var nsPrefix = el.attr("data-ns-prefix");
|
||||
var nsScope = this._narrowScope(scope, nsPrefix);
|
||||
var show3 = condFunc(nsScope);
|
||||
var show3 = Boolean(condFunc(nsScope));
|
||||
var showing = el.css("display") !== "none";
|
||||
if (show3 !== showing) {
|
||||
if (show3) {
|
||||
@@ -25084,7 +25066,7 @@
|
||||
_defineProperty23(this, "initializeInputs", void 0);
|
||||
_defineProperty23(this, "initializedPromise", void 0);
|
||||
_defineProperty23(this, "oncustommessage", void 0);
|
||||
this.version = "1.9.0";
|
||||
this.version = "1.9.1.9000";
|
||||
var _initInputBindings = initInputBindings(), inputBindings = _initInputBindings.inputBindings, fileInputBinding2 = _initInputBindings.fileInputBinding;
|
||||
var _initOutputBindings = initOutputBindings(), outputBindings = _initOutputBindings.outputBindings;
|
||||
setFileInputBinding(fileInputBinding2);
|
||||
@@ -25150,11 +25132,17 @@
|
||||
value: function() {
|
||||
var _initialize = _asyncToGenerator14(/* @__PURE__ */ _regeneratorRuntime14().mark(function _callee3() {
|
||||
var _this2 = this;
|
||||
var shinyapp, inputBatchSender, inputsNoResend, inputsEvent, inputsRate, inputsDefer, target, inputs, inputBindings, outputBindings, shinyBindCtx, initializeInputs, getIdFromEl, initialValues, getComputedBgColor, getComputedFont, maybeAddThemeObserver, doSendTheme, doSendImageSize, isHidden, lastKnownVisibleOutputs, doSendOutputHiddenState, sendOutputHiddenStateDebouncer, sendOutputHiddenState, filterEventsByNamespace, bs3classes, singletonText, dependencyText;
|
||||
var shinyapp, inputBatchSender, inputsNoResend, inputsEvent, inputsRate, inputsDefer, target, inputs, inputBindings, outputBindings, shinyBindCtx, initializeInputs, getIdFromEl, initialValues, getComputedBgColor, getComputedFont, maybeAddThemeObserver, doSendTheme, doSendImageSize, isHidden, lastKnownVisibleOutputs, doSendOutputHiddenState, sendOutputHiddenStateDebouncer, sendOutputHiddenState, filterEventsByNamespace, bs3classes, doSendWindowSize, singletonText, dependencyText;
|
||||
return _regeneratorRuntime14().wrap(function _callee3$(_context3) {
|
||||
while (1)
|
||||
switch (_context3.prev = _context3.next) {
|
||||
case 0:
|
||||
doSendWindowSize = function _doSendWindowSize() {
|
||||
inputs.setInput(".clientdata_window_width", window.innerWidth);
|
||||
inputs.setInput(".clientdata_window_height", window.innerHeight);
|
||||
inputs.setInput(".clientdata_scroll_width", document.documentElement.scrollWidth);
|
||||
inputs.setInput(".clientdata_scroll_height", document.documentElement.scrollHeight);
|
||||
};
|
||||
filterEventsByNamespace = function _filterEventsByNamesp(namespace, handler) {
|
||||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
||||
args[_key - 2] = arguments[_key];
|
||||
@@ -25382,9 +25370,9 @@
|
||||
this.initializeInputs = initializeInputs;
|
||||
initializeInputs(document.documentElement);
|
||||
_context3.t0 = mapValues;
|
||||
_context3.next = 34;
|
||||
_context3.next = 35;
|
||||
return _bindAll(shinyBindCtx(), document.documentElement);
|
||||
case 34:
|
||||
case 35:
|
||||
_context3.t1 = _context3.sent;
|
||||
_context3.t2 = function(x2) {
|
||||
return x2.value;
|
||||
@@ -25456,6 +25444,11 @@
|
||||
return;
|
||||
e4;
|
||||
});
|
||||
initialValues[".clientdata_window_width"] = window.innerWidth;
|
||||
initialValues[".clientdata_window_height"] = window.innerHeight;
|
||||
initialValues[".clientdata_scroll_width"] = document.documentElement.scrollWidth;
|
||||
initialValues[".clientdata_scroll_height"] = document.documentElement.scrollHeight;
|
||||
(0, import_jquery39.default)(window).resize(debounce(500, doSendWindowSize));
|
||||
singletonText = initialValues[".clientdata_singletons"] = (0, import_jquery39.default)('script[type="application/shiny-singletons"]').text();
|
||||
registerNames(singletonText.split(/,/));
|
||||
dependencyText = (0, import_jquery39.default)('script[type="application/html-dependencies"]').text();
|
||||
@@ -25473,7 +25466,7 @@
|
||||
(0, import_jquery39.default)(document).one("shiny:sessioninitialized", function() {
|
||||
_this2.initializedPromise.resolve();
|
||||
});
|
||||
case 69:
|
||||
case 75:
|
||||
case "end":
|
||||
return _context3.stop();
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
inst/www/shared/shiny.min.css
vendored
2
inst/www/shared/shiny.min.css
vendored
File diff suppressed because one or more lines are too long
4
inst/www/shared/shiny.min.js
vendored
4
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
@@ -3,7 +3,7 @@
|
||||
"homepage": "https://shiny.rstudio.com",
|
||||
"repository": "github:rstudio/shiny",
|
||||
"name": "@types/rstudio-shiny",
|
||||
"version": "1.9.0",
|
||||
"version": "1.9.1-alpha.9000",
|
||||
"license": "GPL-3.0-only",
|
||||
"main": "",
|
||||
"browser": "",
|
||||
|
||||
@@ -64,15 +64,15 @@
|
||||
--shiny-pulse-background,
|
||||
linear-gradient(
|
||||
120deg,
|
||||
var(--bs-body-bg, #fff),
|
||||
transparent,
|
||||
var(--bs-indigo, #4b00c1),
|
||||
var(--bs-purple, #74149c),
|
||||
var(--bs-pink, #bf007f),
|
||||
var(--bs-body-bg, #fff)
|
||||
transparent
|
||||
)
|
||||
);
|
||||
--_shiny-pulse-height: var(--shiny-pulse-height, 5px);
|
||||
--_shiny-pulse-speed: var(--shiny-pulse-speed, 1.85s);
|
||||
--_shiny-pulse-height: var(--shiny-pulse-height, 3px);
|
||||
--_shiny-pulse-speed: var(--shiny-pulse-speed, 1.2s);
|
||||
|
||||
/* Color, sizing, & positioning */
|
||||
position: fixed;
|
||||
@@ -85,6 +85,7 @@
|
||||
/* Animation */
|
||||
animation-name: busy-page-pulse;
|
||||
animation-duration: var(--_shiny-pulse-speed);
|
||||
animation-direction: alternate;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: ease-in-out;
|
||||
|
||||
@@ -99,7 +100,9 @@
|
||||
&.shiny-busy::after {
|
||||
@include shiny-page-busy;
|
||||
}
|
||||
&.shiny-busy:has(.recalculating)::after {
|
||||
// Hide the pulse if there are spinners on the page
|
||||
// (Note: UI outputs don't get spinners)
|
||||
&.shiny-busy:has(.recalculating:not(.shiny-html-output))::after {
|
||||
display: none;
|
||||
}
|
||||
&.shiny-busy:has(#shiny-disconnected-overlay)::after {
|
||||
@@ -130,17 +133,23 @@
|
||||
/* Keyframes for the pulsing banner */
|
||||
@keyframes busy-page-pulse {
|
||||
0% {
|
||||
left: -75%;
|
||||
width: 75%;
|
||||
left: -14%;
|
||||
right: 97%;
|
||||
}
|
||||
50% {
|
||||
left: 100%;
|
||||
width: 75%;
|
||||
|
||||
45% {
|
||||
left: 0%;
|
||||
right: 14%;
|
||||
}
|
||||
/* Go back */
|
||||
100% {
|
||||
left: -75%;
|
||||
width: 75%;
|
||||
|
||||
55% {
|
||||
left: 14%;
|
||||
right: 0%;
|
||||
}
|
||||
|
||||
to {
|
||||
left: 97%;
|
||||
right: -14%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,19 +40,15 @@ class DateInputBindingBase extends InputBinding {
|
||||
el;
|
||||
}
|
||||
subscribe(el: HTMLElement, callback: (x: boolean) => void): void {
|
||||
$(el).on(
|
||||
"keyup.dateInputBinding input.dateInputBinding",
|
||||
// event: Event
|
||||
function () {
|
||||
// Use normal debouncing policy when typing
|
||||
callback(true);
|
||||
}
|
||||
);
|
||||
// Don't update when in the middle of typing; listening on keyup or input
|
||||
// tends to send spurious values to the server, based on unpredictable
|
||||
// browser-dependant interpretation of partially-typed date strings.
|
||||
$(el).on(
|
||||
"changeDate.dateInputBinding change.dateInputBinding",
|
||||
// event: Event
|
||||
function () {
|
||||
// Send immediately when clicked
|
||||
// Or if typing, when enter pressed or focus lost
|
||||
callback(false);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -161,19 +161,15 @@ class DateRangeInputBinding extends DateInputBindingBase {
|
||||
this._setMax($endinput[0], $endinput.data("max-date"));
|
||||
}
|
||||
subscribe(el: HTMLElement, callback: (x: boolean) => void): void {
|
||||
$(el).on(
|
||||
"keyup.dateRangeInputBinding input.dateRangeInputBinding",
|
||||
// event: Event
|
||||
function () {
|
||||
// Use normal debouncing policy when typing
|
||||
callback(true);
|
||||
}
|
||||
);
|
||||
// Don't update when in the middle of typing; listening on keyup or input
|
||||
// tends to send spurious values to the server, based on unpredictable
|
||||
// browser-dependant interpretation of partially-typed date strings.
|
||||
$(el).on(
|
||||
"changeDate.dateRangeInputBinding change.dateRangeInputBinding",
|
||||
// event: Event
|
||||
function () {
|
||||
// Send immediately when clicked
|
||||
// Or if typing, when enter pressed or focus lost
|
||||
callback(false);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -293,13 +293,7 @@ function initCoordmap(
|
||||
let i;
|
||||
|
||||
for (i = 0; i < coordmap.panels.length; i++) {
|
||||
const panelRange = coordmap.panels[i].range;
|
||||
const b = {
|
||||
top: panelRange.top * cssToImgRatio.y,
|
||||
bottom: panelRange.bottom * cssToImgRatio.y,
|
||||
left: panelRange.left * cssToImgRatio.x,
|
||||
right: panelRange.right * cssToImgRatio.x,
|
||||
};
|
||||
const b = coordmap.panels[i].range;
|
||||
|
||||
if (
|
||||
x <= b.right + expandImg.x &&
|
||||
|
||||
@@ -646,6 +646,27 @@ class ShinyClass {
|
||||
e;
|
||||
});
|
||||
|
||||
initialValues[".clientdata_window_width"] = window.innerWidth;
|
||||
initialValues[".clientdata_window_height"] = window.innerHeight;
|
||||
initialValues[".clientdata_scroll_width"] =
|
||||
document.documentElement.scrollWidth;
|
||||
initialValues[".clientdata_scroll_height"] =
|
||||
document.documentElement.scrollHeight;
|
||||
|
||||
function doSendWindowSize() {
|
||||
inputs.setInput(".clientdata_window_width", window.innerWidth);
|
||||
inputs.setInput(".clientdata_window_height", window.innerHeight);
|
||||
inputs.setInput(
|
||||
".clientdata_scroll_width",
|
||||
document.documentElement.scrollWidth
|
||||
);
|
||||
inputs.setInput(
|
||||
".clientdata_scroll_height",
|
||||
document.documentElement.scrollHeight
|
||||
);
|
||||
}
|
||||
|
||||
$(window).resize(debounce(500, doSendWindowSize));
|
||||
// The server needs to know what singletons were rendered as part of
|
||||
// the page loading
|
||||
const singletonText = (initialValues[".clientdata_singletons"] = $(
|
||||
|
||||
@@ -614,7 +614,7 @@ class ShinyApp {
|
||||
|
||||
const nsPrefix = el.attr("data-ns-prefix") as string;
|
||||
const nsScope = this._narrowScope(scope, nsPrefix);
|
||||
const show = condFunc(nsScope);
|
||||
const show = Boolean(condFunc(nsScope));
|
||||
const showing = el.css("display") !== "none";
|
||||
|
||||
if (show !== showing) {
|
||||
|
||||
@@ -148,7 +148,7 @@ function pixelRatio(): number {
|
||||
//
|
||||
// When the function is executed, it will evaluate that expression using
|
||||
// "with" on the argument value, and return the result.
|
||||
function scopeExprToFunc(expr: string): (scope: unknown) => boolean {
|
||||
function scopeExprToFunc(expr: string): (scope: unknown) => unknown {
|
||||
/*jshint evil: true */
|
||||
const exprEscaped = expr
|
||||
.replace(/[\\"']/g, "\\$&")
|
||||
@@ -159,7 +159,7 @@ function scopeExprToFunc(expr: string): (scope: unknown) => boolean {
|
||||
// \b has a special meaning; need [\b] to match backspace char.
|
||||
.replace(/[\b]/g, "\\b");
|
||||
|
||||
let func: () => boolean;
|
||||
let func: () => unknown;
|
||||
|
||||
try {
|
||||
// @ts-expect-error; Do not know how to type this _dangerous_ situation
|
||||
@@ -178,7 +178,7 @@ function scopeExprToFunc(expr: string): (scope: unknown) => boolean {
|
||||
throw e;
|
||||
}
|
||||
|
||||
return function (scope: unknown): boolean {
|
||||
return function (scope: unknown): unknown {
|
||||
return func.call(scope);
|
||||
};
|
||||
}
|
||||
|
||||
2
srcts/types/src/utils/index.d.ts
vendored
2
srcts/types/src/utils/index.d.ts
vendored
@@ -10,7 +10,7 @@ declare function parseDate(dateString: string): Date;
|
||||
declare function formatDateUTC(x: Date): string;
|
||||
declare function makeResizeFilter(el: HTMLElement, func: (width: HTMLElement["offsetWidth"], height: HTMLElement["offsetHeight"]) => void): () => void;
|
||||
declare function pixelRatio(): number;
|
||||
declare function scopeExprToFunc(expr: string): (scope: unknown) => boolean;
|
||||
declare function scopeExprToFunc(expr: string): (scope: unknown) => unknown;
|
||||
declare function asArray<T>(value: T | T[] | null | undefined): T[];
|
||||
declare function mergeSort<Item>(list: Item[], sortfunc: (a: Item, b: Item) => boolean | number): Item[];
|
||||
declare function $escape(val: undefined): undefined;
|
||||
|
||||
@@ -11,18 +11,18 @@ test_that("HTML has correct attributes", {
|
||||
})
|
||||
|
||||
test_that("Github extensions are on by default", {
|
||||
html <- markdown("a ~paragraph~ with a link: https://example.com")
|
||||
html <- markdown("a ~~paragraph~~ with a link: https://example.com")
|
||||
expect_equal(html, HTML("<p>a <del>paragraph</del> with a link: <a href=\"https://example.com\">https://example.com</a></p>\n"))
|
||||
})
|
||||
|
||||
test_that("Github extensions can be disabled", {
|
||||
html <- markdown("a ~paragraph~", extensions = FALSE)
|
||||
expect_equal(html, HTML("<p>a ~paragraph~</p>\n"))
|
||||
html <- markdown("a ~~paragraph~~", extensions = FALSE)
|
||||
expect_equal(html, HTML("<p>a ~~paragraph~~</p>\n"))
|
||||
})
|
||||
|
||||
test_that("Additional options are respected", {
|
||||
html <- markdown("a ~paragraph~", extensions = FALSE, sourcepos = TRUE)
|
||||
expect_equal(html, HTML("<p data-sourcepos=\"1:1-1:13\">a ~paragraph~</p>\n"))
|
||||
html <- markdown("a ~~paragraph~~", extensions = FALSE, sourcepos = TRUE)
|
||||
expect_equal(html, HTML("<p data-sourcepos=\"1:1-1:15\">a ~~paragraph~~</p>\n"))
|
||||
})
|
||||
|
||||
test_that("Multiline markdown works properly", {
|
||||
|
||||
@@ -1232,162 +1232,85 @@ test_that("event handling helpers take correct dependencies", {
|
||||
})
|
||||
|
||||
|
||||
test_that("debounce/throttle work properly (with priming)", {
|
||||
do_priming <- TRUE
|
||||
# Some of the CRAN test machines are heavily loaded and so the timing for
|
||||
# these tests isn't reliable. https://github.com/rstudio/shiny/pull/2789
|
||||
skip_on_cran()
|
||||
for (do_priming in c(TRUE, FALSE)) {
|
||||
label <- if (do_priming) "with priming" else "without priming"
|
||||
test_that(sprintf("debounce/throttle work properly (%s)", label), {
|
||||
# Some of the CRAN test machines are heavily loaded and so the timing for
|
||||
# these tests isn't reliable. https://github.com/rstudio/shiny/pull/2789
|
||||
skip_on_cran()
|
||||
|
||||
# The changing of rv$a will be the (chatty) source of reactivity.
|
||||
rv <- reactiveValues(a = 0)
|
||||
# The changing of rv$a will be the (chatty) source of reactivity.
|
||||
rv <- reactiveValues(a = 0)
|
||||
|
||||
# This observer will be what changes rv$a.
|
||||
src <- observe({
|
||||
invalidateLater(100)
|
||||
rv$a <- isolate(rv$a) + 1
|
||||
})
|
||||
on.exit(src$destroy(), add = TRUE)
|
||||
# This observer will be what changes rv$a.
|
||||
src <- observe({
|
||||
invalidateLater(300)
|
||||
rv$a <- isolate(rv$a) + 1
|
||||
})
|
||||
on.exit(src$destroy(), add = TRUE)
|
||||
|
||||
# Make a debounced reactive to test.
|
||||
dr <- debounce(reactive(rv$a), 500)
|
||||
# Make a debounced reactive to test.
|
||||
dr <- debounce(reactive(rv$a), 500)
|
||||
|
||||
# Make a throttled reactive to test.
|
||||
tr <- throttle(reactive(rv$a), 500)
|
||||
# Make a throttled reactive to test.
|
||||
tr <- throttle(reactive(rv$a), 500)
|
||||
|
||||
# Keep track of how often dr/tr are fired
|
||||
dr_fired <- 0
|
||||
dr_monitor <- observeEvent(dr(), {
|
||||
dr_fired <<- dr_fired + 1
|
||||
})
|
||||
on.exit(dr_monitor$destroy(), add = TRUE)
|
||||
# Keep track of how often dr/tr are fired
|
||||
dr_fired <- 0
|
||||
dr_monitor <- observeEvent(dr(), {
|
||||
dr_fired <<- dr_fired + 1
|
||||
})
|
||||
on.exit(dr_monitor$destroy(), add = TRUE)
|
||||
|
||||
tr_fired <- 0
|
||||
tr_monitor <- observeEvent(tr(), {
|
||||
tr_fired <<- tr_fired + 1
|
||||
})
|
||||
on.exit(tr_monitor$destroy(), add = TRUE)
|
||||
tr_fired <- 0
|
||||
tr_monitor <- observeEvent(tr(), {
|
||||
tr_fired <<- tr_fired + 1
|
||||
})
|
||||
on.exit(tr_monitor$destroy(), add = TRUE)
|
||||
|
||||
# Starting values are both 0. Earlier I found that the tests behaved
|
||||
# differently if I accessed the values of dr/tr before the first call to
|
||||
# flushReact(). That bug was fixed, but to ensure that similar bugs don't
|
||||
# appear undetected, we run this test with and without do_priming.
|
||||
if (do_priming) {
|
||||
# Starting values are both 0. Earlier I found that the tests behaved
|
||||
# differently if I accessed the values of dr/tr before the first call to
|
||||
# flushReact(). That bug was fixed, but to ensure that similar bugs don't
|
||||
# appear undetected, we run this test with and without do_priming.
|
||||
if (do_priming) {
|
||||
expect_identical(isolate(dr()), 0)
|
||||
expect_identical(isolate(tr()), 0)
|
||||
}
|
||||
|
||||
# Pump timer and reactives for about 1.3 seconds
|
||||
stopAt <- Sys.time() + 1.3
|
||||
while (Sys.time() < stopAt) {
|
||||
timerCallbacks$executeElapsed()
|
||||
flushReact()
|
||||
Sys.sleep(0.001)
|
||||
}
|
||||
|
||||
# dr() should not have had time to fire, other than the initial run, since
|
||||
# there haven't been long enough gaps between invalidations.
|
||||
expect_identical(dr_fired, 1)
|
||||
# The value of dr() should not have updated either.
|
||||
expect_identical(isolate(dr()), 0)
|
||||
expect_identical(isolate(tr()), 0)
|
||||
}
|
||||
|
||||
# Pump timer and reactives for about 1.3 seconds
|
||||
stopAt <- Sys.time() + 1.3
|
||||
while (Sys.time() < stopAt) {
|
||||
timerCallbacks$executeElapsed()
|
||||
flushReact()
|
||||
Sys.sleep(0.001)
|
||||
}
|
||||
# tr() however, has had time to fire multiple times and update its value.
|
||||
expect_identical(tr_fired, 3)
|
||||
expect_identical(isolate(tr()), 4)
|
||||
|
||||
# dr() should not have had time to fire, other than the initial run, since
|
||||
# there haven't been long enough gaps between invalidations.
|
||||
expect_identical(dr_fired, 1)
|
||||
# The value of dr() should not have updated either.
|
||||
expect_identical(isolate(dr()), 0)
|
||||
# Now let some time pass without any more updates.
|
||||
src$destroy() # No more updates
|
||||
stopAt <- Sys.time() + 1
|
||||
while (Sys.time() < stopAt) {
|
||||
timerCallbacks$executeElapsed()
|
||||
flushReact()
|
||||
Sys.sleep(0.001)
|
||||
}
|
||||
|
||||
# tr() however, has had time to fire multiple times and update its value.
|
||||
expect_identical(tr_fired, 3)
|
||||
expect_identical(isolate(tr()), 10)
|
||||
|
||||
# Now let some time pass without any more updates.
|
||||
src$destroy() # No more updates
|
||||
stopAt <- Sys.time() + 1
|
||||
while (Sys.time() < stopAt) {
|
||||
timerCallbacks$executeElapsed()
|
||||
flushReact()
|
||||
Sys.sleep(0.001)
|
||||
}
|
||||
|
||||
# dr should've fired, and we should have converged on the right answer.
|
||||
expect_identical(dr_fired, 2)
|
||||
isolate(expect_identical(rv$a, dr()))
|
||||
expect_identical(tr_fired, 4)
|
||||
isolate(expect_identical(rv$a, tr()))
|
||||
})
|
||||
|
||||
# Identical to test block above, but with do_priming set to FALSE.
|
||||
test_that("debounce/throttle work properly (without priming)", {
|
||||
do_priming <- FALSE
|
||||
# Some of the CRAN test machines are heavily loaded and so the timing for
|
||||
# these tests isn't reliable. https://github.com/rstudio/shiny/pull/2789
|
||||
skip_on_cran()
|
||||
|
||||
# The changing of rv$a will be the (chatty) source of reactivity.
|
||||
rv <- reactiveValues(a = 0)
|
||||
|
||||
# This observer will be what changes rv$a.
|
||||
src <- observe({
|
||||
invalidateLater(100)
|
||||
rv$a <- isolate(rv$a) + 1
|
||||
# dr should've fired, and we should have converged on the right answer.
|
||||
expect_identical(dr_fired, 2)
|
||||
isolate(expect_identical(rv$a, dr()))
|
||||
expect_identical(tr_fired, 4)
|
||||
isolate(expect_identical(rv$a, tr()))
|
||||
})
|
||||
on.exit(src$destroy(), add = TRUE)
|
||||
|
||||
# Make a debounced reactive to test.
|
||||
dr <- debounce(reactive(rv$a), 500)
|
||||
|
||||
# Make a throttled reactive to test.
|
||||
tr <- throttle(reactive(rv$a), 500)
|
||||
|
||||
# Keep track of how often dr/tr are fired
|
||||
dr_fired <- 0
|
||||
dr_monitor <- observeEvent(dr(), {
|
||||
dr_fired <<- dr_fired + 1
|
||||
})
|
||||
on.exit(dr_monitor$destroy(), add = TRUE)
|
||||
|
||||
tr_fired <- 0
|
||||
tr_monitor <- observeEvent(tr(), {
|
||||
tr_fired <<- tr_fired + 1
|
||||
})
|
||||
on.exit(tr_monitor$destroy(), add = TRUE)
|
||||
|
||||
# Starting values are both 0. Earlier I found that the tests behaved
|
||||
# differently if I accessed the values of dr/tr before the first call to
|
||||
# flushReact(). That bug was fixed, but to ensure that similar bugs don't
|
||||
# appear undetected, we run this test with and without do_priming.
|
||||
if (do_priming) {
|
||||
expect_identical(isolate(dr()), 0)
|
||||
expect_identical(isolate(tr()), 0)
|
||||
}
|
||||
|
||||
# Pump timer and reactives for about 1.3 seconds
|
||||
stopAt <- Sys.time() + 1.3
|
||||
while (Sys.time() < stopAt) {
|
||||
timerCallbacks$executeElapsed()
|
||||
flushReact()
|
||||
Sys.sleep(0.001)
|
||||
}
|
||||
|
||||
# dr() should not have had time to fire, other than the initial run, since
|
||||
# there haven't been long enough gaps between invalidations.
|
||||
expect_identical(dr_fired, 1)
|
||||
# The value of dr() should not have updated either.
|
||||
expect_identical(isolate(dr()), 0)
|
||||
|
||||
# tr() however, has had time to fire multiple times and update its value.
|
||||
expect_identical(tr_fired, 3)
|
||||
expect_identical(isolate(tr()), 10)
|
||||
|
||||
# Now let some time pass without any more updates.
|
||||
src$destroy() # No more updates
|
||||
stopAt <- Sys.time() + 1
|
||||
while (Sys.time() < stopAt) {
|
||||
timerCallbacks$executeElapsed()
|
||||
flushReact()
|
||||
Sys.sleep(0.001)
|
||||
}
|
||||
|
||||
# dr should've fired, and we should have converged on the right answer.
|
||||
expect_identical(dr_fired, 2)
|
||||
isolate(expect_identical(rv$a, dr()))
|
||||
expect_identical(tr_fired, 4)
|
||||
isolate(expect_identical(rv$a, tr()))
|
||||
})
|
||||
}
|
||||
|
||||
test_that("reactive domain works across async handlers", {
|
||||
obj <- new.env()
|
||||
|
||||
@@ -3,7 +3,7 @@ new file mode 100644
|
||||
index 00000000..ba052f8b
|
||||
--- /dev/null
|
||||
+++ b/inst/www/shared/ionrangeslider/scss/shiny.scss
|
||||
@@ -0,0 +1,201 @@
|
||||
@@ -0,0 +1,206 @@
|
||||
+/* 'shiny' skin for Ion.RangeSlider, largely based on the 'big' skin, but with smaller dimensions, grayscale grid text, and without gradients
|
||||
+© Posit, PBC, 2023
|
||||
+© RStudio, Inc, 2014
|
||||
@@ -149,6 +149,11 @@ index 00000000..ba052f8b
|
||||
+ border-radius: $handle_width;
|
||||
+ z-index: 2;
|
||||
+
|
||||
+ &.type_last {
|
||||
+ // Ensure last-used handle is on top if it overlaps with another handle
|
||||
+ z-index: 3;
|
||||
+ }
|
||||
+
|
||||
+ &.state_hover,
|
||||
+ &:hover {
|
||||
+ background: $handle_color_hover;
|
||||
|
||||
Reference in New Issue
Block a user