mirror of
https://github.com/rstudio/shiny.git
synced 2026-04-07 03:00:20 -04:00
Disable seralizing of passwords and actionButtons
This commit is contained in:
@@ -151,9 +151,6 @@ ReactiveValues <- R6Class(
|
||||
|
||||
# Set a metadata value. Does not trigger reactivity.
|
||||
setMeta = function(key, metaKey, value) {
|
||||
if (!exists(key, envir = .values, inherits = FALSE)) {
|
||||
stop("Attempted to set metadata on non-existent value.")
|
||||
}
|
||||
# Make sure to use named (not numeric) indexing into list.
|
||||
metaKey <- as.character(metaKey)
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ decodeBookmarkDataURL <- function(url) {
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#' @param input The session's input object.
|
||||
#' @param exclude A character vector of input names that should not be
|
||||
#' bookmarked.
|
||||
@@ -22,6 +21,13 @@ encodeBookmarkDataURL <- function(input, exclude = NULL) {
|
||||
vals <- reactiveValuesToList(input)
|
||||
vals <- vals[setdiff(names(vals), exclude)]
|
||||
|
||||
# Remove items that are marked as unserializable
|
||||
impl <- .subset2(input, "impl")
|
||||
unserializable_idx <- vapply(names(vals), function(x) {
|
||||
identical(impl$getMeta(x, "shiny.serializable"), FALSE)
|
||||
}, FUN.VALUE = logical(1))
|
||||
vals <- vals[!unserializable_idx]
|
||||
|
||||
vals <- vapply(vals, function(x) {
|
||||
toJSON(x, strict_atomic = FALSE)
|
||||
}, character(1), USE.NAMES = TRUE)
|
||||
|
||||
@@ -89,6 +89,12 @@ registerInputHandler("shiny.number", function(val, ...){
|
||||
ifelse(is.null(val), NA, val)
|
||||
})
|
||||
|
||||
registerInputHandler("shiny.password", function(val, shinysession, name) {
|
||||
# Mark passwords as not serializable
|
||||
.subset2(shinysession$input, "impl")$setMeta(name, "shiny.serializable", FALSE)
|
||||
val
|
||||
})
|
||||
|
||||
registerInputHandler("shiny.date", function(val, ...){
|
||||
# First replace NULLs with NA, then convert to Date vector
|
||||
datelist <- ifelse(lapply(val, is.null), NA, val)
|
||||
@@ -104,7 +110,10 @@ registerInputHandler("shiny.datetime", function(val, ...){
|
||||
as.POSIXct(unlist(times), origin = "1970-01-01", tz = "UTC")
|
||||
})
|
||||
|
||||
registerInputHandler("shiny.action", function(val, ...) {
|
||||
registerInputHandler("shiny.action", function(val, shinysession, name) {
|
||||
# Mark as not serializable
|
||||
.subset2(shinysession$input, "impl")$setMeta(name, "shiny.serializable", FALSE)
|
||||
|
||||
# mark up the action button value with a special class so we can recognize it later
|
||||
class(val) <- c(class(val), "shinyActionButtonValue")
|
||||
val
|
||||
|
||||
13
R/server.R
13
R/server.R
@@ -247,11 +247,14 @@ createAppHandlers <- function(httpHandlers, serverFuncSource) {
|
||||
stop("No handler registered for for type ", name)
|
||||
}
|
||||
|
||||
msg$data[[ splitName[[1]] ]] <-
|
||||
inputHandlers$get(splitName[[2]])(
|
||||
val,
|
||||
shinysession,
|
||||
splitName[[1]] )
|
||||
inputName <- splitName[[1]]
|
||||
|
||||
# Get the function for processing this type of input
|
||||
inputHandler <- inputHandlers$get(splitName[[2]])
|
||||
|
||||
msg$data[[inputName]] <- inputHandler(val, shinysession,
|
||||
inputName)
|
||||
|
||||
}
|
||||
else if (is.list(val) && is.null(names(val))) {
|
||||
val_flat <- unlist(val, recursive = TRUE)
|
||||
|
||||
10
srcjs/input_binding_password.js
Normal file
10
srcjs/input_binding_password.js
Normal file
@@ -0,0 +1,10 @@
|
||||
var passwordInputBinding = {};
|
||||
$.extend(passwordInputBinding, textInputBinding, {
|
||||
find: function(scope) {
|
||||
return $(scope).find('input[type="password"]');
|
||||
},
|
||||
getType: function(el) {
|
||||
return "shiny.password";
|
||||
}
|
||||
});
|
||||
inputBindings.register(passwordInputBinding, 'shiny.passwordInput');
|
||||
@@ -1,7 +1,7 @@
|
||||
var textInputBinding = new InputBinding();
|
||||
$.extend(textInputBinding, {
|
||||
find: function(scope) {
|
||||
return $(scope).find('input[type="text"], input[type="password"], input[type="search"], input[type="url"], input[type="email"]');
|
||||
return $(scope).find('input[type="text"], input[type="search"], input[type="url"], input[type="email"]');
|
||||
},
|
||||
getId: function(el) {
|
||||
return InputBinding.prototype.getId.call(this, el) || el.name;
|
||||
|
||||
@@ -48,6 +48,7 @@ module.exports = function(grunt) {
|
||||
js_srcdir + 'input_binding.js',
|
||||
js_srcdir + 'input_binding_text.js',
|
||||
js_srcdir + 'input_binding_textarea.js',
|
||||
js_srcdir + 'input_binding_password.js',
|
||||
js_srcdir + 'input_binding_number.js',
|
||||
js_srcdir + 'input_binding_checkbox.js',
|
||||
js_srcdir + 'input_binding_slider.js',
|
||||
|
||||
Reference in New Issue
Block a user