From 040ae293fbd183e976a782e401e0c27d4a9e5010 Mon Sep 17 00:00:00 2001 From: Winston Chang Date: Fri, 6 Feb 2015 10:47:42 -0600 Subject: [PATCH] Revert switch to jsonlite This reverts commits deffc90, ab4dc64, and 0755579, returning to RJSONIO. The purpose of this is to prepare for a maintenance release for 0.11 without the switch to jsonlite, to reduce the risk of new bugs. --- DESCRIPTION | 2 +- NAMESPACE | 1 + R/graph.R | 2 +- R/server.R | 8 ++++---- R/shiny.R | 9 ++++----- R/update-input.R | 2 +- R/utils.R | 5 +++++ inst/tests/test-input-handler.R | 10 +++++----- man/registerInputHandler.Rd | 4 ++-- man/removeInputHandler.Rd | 2 +- man/session.Rd | 2 +- 11 files changed, 26 insertions(+), 21 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 705ebd5d0..4852e6a36 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -65,7 +65,7 @@ Imports: utils, httpuv (>= 1.3.2), mime (>= 0.1.3), - jsonlite (>= 0.9.14), + RJSONIO, xtable, digest, htmltools (>= 0.2.6), diff --git a/NAMESPACE b/NAMESPACE index e717dcec2..2fc403fb1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -196,3 +196,4 @@ import(htmltools) import(httpuv) import(mime) import(xtable) +importFrom(RJSONIO,fromJSON) diff --git a/R/graph.R b/R/graph.R index 643c51960..35634facb 100644 --- a/R/graph.R +++ b/R/graph.R @@ -1,5 +1,5 @@ writeReactLog <- function(file=stdout()) { - cat(toJSON(.graphStack$as_list(), pretty=TRUE), file=file) + cat(RJSONIO::toJSON(.graphStack$as_list(), pretty=TRUE), file=file) } #' Reactive Log Visualizer diff --git a/R/server.R b/R/server.R index 11a28e0c9..5ef066015 100644 --- a/R/server.R +++ b/R/server.R @@ -9,7 +9,7 @@ inputHandlers <- Map$new() #' #' Adds an input handler for data of this type. When called, Shiny will use the #' function provided to refine the data passed back from the client (after being -#' deserialized by jsonlite) before making it available in the \code{input} +#' deserialized by RJSONIO) before making it available in the \code{input} #' variable of the \code{server.R} file. #' #' This function will register the handler for the duration of the R process @@ -31,7 +31,7 @@ inputHandlers <- Map$new() #' parameters: #' \enumerate{ #' \item{The value of this input as provided by the client, deserialized -#' using jsonlite.} +#' using RJSONIO.} #' \item{The \code{shinysession} in which the input exists.} #' \item{The name of the input.} #' } @@ -64,7 +64,7 @@ registerInputHandler <- function(type, fun, force=FALSE){ #' Deregister an Input Handler #' #' Removes an Input Handler. Rather than using the previously specified handler -#' for data of this type, the default jsonlite serialization will be used. +#' for data of this type, the default RJSONIO serialization will be used. #' #' @param type The type for which handlers should be removed. #' @return The handler previously associated with this \code{type}, if one @@ -245,7 +245,7 @@ decodeMessage <- function(data) { if (readInt(1) != 0x01020202L) { # use native encoding for the message nativeData <- iconv(rawToChar(data), 'UTF-8') - return(jsonlite::fromJSON(nativeData, simplifyVector=FALSE)) + return(fromJSON(nativeData, asText=TRUE, simplify=FALSE)) } i <- 5 diff --git a/R/shiny.R b/R/shiny.R index 99d0c63a0..90952c14f 100644 --- a/R/shiny.R +++ b/R/shiny.R @@ -18,6 +18,7 @@ NULL #' @aliases shiny #' @docType package #' @import htmltools httpuv xtable digest R6 mime +#' @importFrom RJSONIO fromJSON NULL @@ -79,9 +80,7 @@ createUniqueId <- function(bytes, prefix = "", suffix = "") { } toJSON <- function(x, ..., digits = getOption("shiny.json.digits", 16)) { - jsonlite::toJSON(x, dataframe = "columns", null = "null", na = "null", - auto_unbox = TRUE, digits = digits, use_signif = TRUE, - force = TRUE, ...) + RJSONIO::toJSON(x, digits = digits, ...) } # Call the workerId func with no args to get the worker id, and with an arg to @@ -200,7 +199,7 @@ workerId <- local({ #' \item{sendCustomMessage(type, message)}{ #' Sends a custom message to the web page. \code{type} must be a #' single-element character vector giving the type of message, while -#' \code{message} can be any jsonlite-encodable value. Custom messages +#' \code{message} can be any RJSONIO-encodable value. Custom messages #' have no meaning to Shiny itself; they are used soley to convey information #' to custom JavaScript logic in the browser. You can do this by adding #' JavaScript code to the browser that calls @@ -302,7 +301,7 @@ ShinySession <- R6Class( if (!is.null(websocket$request$HTTP_SHINY_SERVER_CREDENTIALS)) { try({ - creds <- jsonlite::fromJSON(websocket$request$HTTP_SHINY_SERVER_CREDENTIALS) + creds <- fromJSON(websocket$request$HTTP_SHINY_SERVER_CREDENTIALS) session$user <<- creds$user session$groups <<- creds$groups }, silent=FALSE) diff --git a/R/update-input.R b/R/update-input.R index be0bd580a..184c28433 100644 --- a/R/update-input.R +++ b/R/update-input.R @@ -453,7 +453,7 @@ updateSelectizeInput <- function(session, inputId, label = NULL, choices = NULL, selectizeJSON <- function(data, req) { query <- parseQueryString(req$QUERY_STRING) # extract the query variables, conjunction (and/or), search string, maximum options - var <- unlist(jsonlite::fromJSON(query$field)) + var <- unlist(fromJSON(query$field, asText = TRUE)) cjn <- if (query$conju == 'and') all else any # all keywords in lower-case, for case-insensitive matching key <- unique(strsplit(tolower(query$query), '\\s+')[[1]]) diff --git a/R/utils.R b/R/utils.R index 53c070e72..ec66b1263 100644 --- a/R/utils.R +++ b/R/utils.R @@ -705,6 +705,11 @@ dataTablesJSON <- function(data, req) { for (j in seq_len(ncol(fdata))[k]) fdata[, j] <- htmlEscape(fdata[, j]) } } + # WAT: toJSON(list(x = matrix(nrow = 0, ncol = 1))) => {"x": } (#299) + if (nrow(fdata) == 0) fdata <- list() + # WAT: toJSON(list(x = matrix(1:2))) => {x: [ [1], [2] ]}, however, + # toJSON(list(x = matrix(1))) => {x: [ 1 ]} (loss of dimension, #429) + if (length(fdata) && all(dim(fdata) == 1)) fdata <- list(list(fdata[1, 1])) res <- toJSON(list( draw = as.integer(q$draw), diff --git a/inst/tests/test-input-handler.R b/inst/tests/test-input-handler.R index f6d905711..1ac39c825 100644 --- a/inst/tests/test-input-handler.R +++ b/inst/tests/test-input-handler.R @@ -15,7 +15,7 @@ test_that("Date converts to date", { x <- "2013/01/01" class(x) <- "shiny.date" handler <- inputHandlers$get('shiny.date') - expect_identical( + expect_identical( handler(x), as.Date(unclass(x)) ) }) @@ -24,7 +24,7 @@ test_that("List of dates converts to vector", { x <- list("2013/01/01", "2014/01/01") class(x) <- "shiny.date" handler <- inputHandlers$get('shiny.date') - expect_identical( + expect_identical( handler(x), as.Date(unlist(x)) ) }) @@ -41,7 +41,7 @@ test_that("Matrix converts list of lists to matrix", { test_that("Nulls are not converted to NAs in parsing", { msg <- charToRaw("{\"method\":\"init\",\"data\":{\"obs\":500,\"nullObs\":null}}") expect_identical( - decodeMessage(msg), - list(method="init", data=list(obs=500L, nullObs=NULL)) + decodeMessage(msg), + list(method="init", data=list(obs=500, nullObs=NULL)) ) -}) +}) \ No newline at end of file diff --git a/man/registerInputHandler.Rd b/man/registerInputHandler.Rd index 7a12fb9e3..0820a56d6 100644 --- a/man/registerInputHandler.Rd +++ b/man/registerInputHandler.Rd @@ -16,7 +16,7 @@ parse the data delivered from the client before it is available in the parameters: \enumerate{ \item{The value of this input as provided by the client, deserialized - using jsonlite.} + using RJSONIO.} \item{The \code{shinysession} in which the input exists.} \item{The name of the input.} }} @@ -28,7 +28,7 @@ a handler defined.} \description{ Adds an input handler for data of this type. When called, Shiny will use the function provided to refine the data passed back from the client (after being -deserialized by jsonlite) before making it available in the \code{input} +deserialized by RJSONIO) before making it available in the \code{input} variable of the \code{server.R} file. } \details{ diff --git a/man/removeInputHandler.Rd b/man/removeInputHandler.Rd index 986edee43..d4218607d 100644 --- a/man/removeInputHandler.Rd +++ b/man/removeInputHandler.Rd @@ -15,7 +15,7 @@ The handler previously associated with this \code{type}, if one } \description{ Removes an Input Handler. Rather than using the previously specified handler -for data of this type, the default jsonlite serialization will be used. +for data of this type, the default RJSONIO serialization will be used. } \seealso{ \code{\link{registerInputHandler}} diff --git a/man/session.Rd b/man/session.Rd index f5c56bb7a..994348e00 100644 --- a/man/session.Rd +++ b/man/session.Rd @@ -84,7 +84,7 @@ \item{sendCustomMessage(type, message)}{ Sends a custom message to the web page. \code{type} must be a single-element character vector giving the type of message, while - \code{message} can be any jsonlite-encodable value. Custom messages + \code{message} can be any RJSONIO-encodable value. Custom messages have no meaning to Shiny itself; they are used soley to convey information to custom JavaScript logic in the browser. You can do this by adding JavaScript code to the browser that calls