mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-11 16:08:19 -05:00
Compare commits
10 Commits
feature/gr
...
htmltools-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9fc873c8d | ||
|
|
0153349979 | ||
|
|
d227842414 | ||
|
|
b6a2122a41 | ||
|
|
78f87d9003 | ||
|
|
0824726dbb | ||
|
|
f55155404a | ||
|
|
b711bb553f | ||
|
|
2a36179bdc | ||
|
|
e57221861f |
@@ -10,3 +10,4 @@
|
||||
^man-roxygen$
|
||||
^\.travis\.yml$
|
||||
^staticdocs$
|
||||
^tools$
|
||||
|
||||
10
DESCRIPTION
10
DESCRIPTION
@@ -20,13 +20,14 @@ Imports:
|
||||
caTools,
|
||||
RJSONIO,
|
||||
xtable,
|
||||
digest
|
||||
digest,
|
||||
htmltools (>= 0.2.4)
|
||||
Suggests:
|
||||
datasets,
|
||||
markdown,
|
||||
Cairo (>= 1.5-5),
|
||||
testthat,
|
||||
knitr
|
||||
knitr (>= 1.6),
|
||||
markdown
|
||||
URL: http://www.rstudio.com/shiny/
|
||||
BugReports: https://github.com/rstudio/shiny/issues
|
||||
Roxygen: list(wrap = FALSE)
|
||||
@@ -36,13 +37,13 @@ Collate:
|
||||
'map.R'
|
||||
'globals.R'
|
||||
'utils.R'
|
||||
'htmltools.R'
|
||||
'bootstrap.R'
|
||||
'cache.R'
|
||||
'fileupload.R'
|
||||
'graph.R'
|
||||
'hooks.R'
|
||||
'html-deps.R'
|
||||
'htmltools.R'
|
||||
'imageutils.R'
|
||||
'jqueryui.R'
|
||||
'middleware-shiny.R'
|
||||
@@ -58,7 +59,6 @@ Collate:
|
||||
'shinywrappers.R'
|
||||
'showcase.R'
|
||||
'slider.R'
|
||||
'tags.R'
|
||||
'tar.R'
|
||||
'timer.R'
|
||||
'update-input.R'
|
||||
|
||||
16
NAMESPACE
16
NAMESPACE
@@ -1,4 +1,4 @@
|
||||
# Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
# Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
|
||||
S3method("$",reactivevalues)
|
||||
S3method("$",shinyoutput)
|
||||
@@ -13,21 +13,14 @@ S3method("[[",shinyoutput)
|
||||
S3method("[[<-",reactivevalues)
|
||||
S3method("[[<-",shinyoutput)
|
||||
S3method("names<-",reactivevalues)
|
||||
S3method(as.character,shiny.tag)
|
||||
S3method(as.character,shiny.tag.list)
|
||||
S3method(as.list,reactivevalues)
|
||||
S3method(as.shiny.appobj,character)
|
||||
S3method(as.shiny.appobj,list)
|
||||
S3method(as.shiny.appobj,shiny.appobj)
|
||||
S3method(format,html)
|
||||
S3method(format,shiny.tag)
|
||||
S3method(format,shiny.tag.list)
|
||||
S3method(as.tags,shiny.render.function)
|
||||
S3method(names,reactivevalues)
|
||||
S3method(print,html)
|
||||
S3method(print,reactive)
|
||||
S3method(print,shiny.appobj)
|
||||
S3method(print,shiny.tag)
|
||||
S3method(print,shiny.tag.list)
|
||||
S3method(str,reactivevalues)
|
||||
export(HTML)
|
||||
export(a)
|
||||
@@ -62,7 +55,6 @@ export(flowLayout)
|
||||
export(fluidPage)
|
||||
export(fluidRow)
|
||||
export(getDefaultReactiveDomain)
|
||||
export(getProvidedHtmlDependencies)
|
||||
export(h1)
|
||||
export(h2)
|
||||
export(h3)
|
||||
@@ -86,11 +78,10 @@ export(installExprFunction)
|
||||
export(invalidateLater)
|
||||
export(is.reactive)
|
||||
export(is.reactivevalues)
|
||||
export(is.singleton)
|
||||
export(isolate)
|
||||
export(knit_print.shiny.appobj)
|
||||
export(knit_print.shiny.render.function)
|
||||
export(knit_print.shiny.tag)
|
||||
export(knit_print.shiny.tag.list)
|
||||
export(mainPanel)
|
||||
export(makeReactiveBinding)
|
||||
export(markRenderFunction)
|
||||
@@ -188,6 +179,7 @@ export(withTags)
|
||||
import(RJSONIO)
|
||||
import(caTools)
|
||||
import(digest)
|
||||
import(htmltools)
|
||||
import(httpuv)
|
||||
import(methods)
|
||||
import(xtable)
|
||||
|
||||
37
R/app.R
37
R/app.R
@@ -273,37 +273,10 @@ knit_print.shiny.appobj <- function(x, ...) {
|
||||
# need to grab those and put them in meta, like in knit_print.shiny.tag. But
|
||||
# for now it's not an issue, so just return the HTML and warning.
|
||||
|
||||
knitr::asis_output(html_preserve(format(output, indent=FALSE)),
|
||||
knitr::asis_output(htmlPreserve(format(output, indent=FALSE)),
|
||||
meta = shiny_warning, cacheable = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname knitr_methods
|
||||
#' @export
|
||||
knit_print.shiny.tag <- function(x, ...) {
|
||||
output <- surroundSingletons(x)
|
||||
deps <- getNewestDeps(findDependencies(x))
|
||||
content <- takeHeads(output)
|
||||
head_content <- doRenderTags(tagList(content$head))
|
||||
|
||||
meta <- if (length(head_content) > 1 || head_content != "") {
|
||||
list(structure(head_content, class = "shiny_head"))
|
||||
}
|
||||
meta <- c(meta, deps)
|
||||
|
||||
knitr::asis_output(html_preserve(format(content$ui, indent=FALSE)), meta = meta)
|
||||
}
|
||||
|
||||
knit_print.html <- function(x, ...) {
|
||||
deps <- getNewestDeps(findDependencies(x))
|
||||
knitr::asis_output(html_preserve(as.character(x)),
|
||||
meta = if (length(deps)) list(deps))
|
||||
}
|
||||
|
||||
#' @rdname knitr_methods
|
||||
#' @export
|
||||
knit_print.shiny.tag.list <- knit_print.shiny.tag
|
||||
|
||||
|
||||
# Lets us use a nicer syntax in knitr chunks than literally
|
||||
# calling output$value <- renderFoo(...) and fooOutput().
|
||||
#' @rdname knitr_methods
|
||||
@@ -313,11 +286,3 @@ knit_print.shiny.render.function <- function(x, ...) {
|
||||
attr(output, "knit_cacheable") <- FALSE
|
||||
output
|
||||
}
|
||||
|
||||
html_preserve <- function(x) {
|
||||
x <- paste(x, collapse = "\r\n")
|
||||
if (nzchar(x))
|
||||
sprintf("<!--html_preserve-->%s<!--/html_preserve-->", x)
|
||||
else
|
||||
x
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#' @include utils.R
|
||||
#' @include htmltools.R
|
||||
NULL
|
||||
|
||||
#' Create a Bootstrap page
|
||||
@@ -38,16 +37,19 @@ bootstrapPage <- function(..., title = NULL, responsive = TRUE, theme = NULL) {
|
||||
}
|
||||
cssExt <- ext(".css")
|
||||
jsExt = ext(".js")
|
||||
bs <- "shared/bootstrap"
|
||||
bs <- c(
|
||||
href = "shared/bootstrap",
|
||||
file = system.file("www/shared/bootstrap", package = "shiny")
|
||||
)
|
||||
|
||||
list(
|
||||
html_dependency("bootstrap", "2.3.2", path = bs,
|
||||
htmlDependency("bootstrap", "2.3.2", bs,
|
||||
script = sprintf("js/bootstrap%s", jsExt),
|
||||
stylesheet = if (is.null(theme))
|
||||
sprintf("css/bootstrap%s", cssExt)
|
||||
),
|
||||
if (responsive) {
|
||||
html_dependency("bootstrap-responsive", "2.3.2", path = bs,
|
||||
htmlDependency("bootstrap-responsive", "2.3.2", bs,
|
||||
stylesheet = sprintf("css/bootstrap-responsive%s", cssExt),
|
||||
meta = list(viewport = "width=device-width, initial-scale=1.0")
|
||||
)
|
||||
@@ -55,7 +57,7 @@ bootstrapPage <- function(..., title = NULL, responsive = TRUE, theme = NULL) {
|
||||
)
|
||||
}
|
||||
|
||||
attach_dependency(
|
||||
attachDependencies(
|
||||
tagList(
|
||||
if (!is.null(title)) tags$head(tags$title(title)),
|
||||
if (!is.null(theme)) {
|
||||
@@ -753,7 +755,8 @@ selectizeInput <- function(inputId, ..., options = NULL, width = NULL) {
|
||||
selectizeIt <- function(inputId, select, options, width = NULL, nonempty = FALSE) {
|
||||
res <- checkAsIs(options)
|
||||
|
||||
selectizeDep <- html_dependency("selectize", "0.8.5", "shared/selectize",
|
||||
selectizeDep <- htmlDependency(
|
||||
"selectize", "0.8.5", c(href = "shared/selectize"),
|
||||
stylesheet = "css/selectize.bootstrap2.css",
|
||||
head = format(tagList(
|
||||
HTML('<!--[if lt IE 9]>'),
|
||||
@@ -762,7 +765,7 @@ selectizeIt <- function(inputId, select, options, width = NULL, nonempty = FALSE
|
||||
tags$script(src = 'shared/selectize/js/selectize.min.js')
|
||||
))
|
||||
)
|
||||
attach_dependency(
|
||||
attachDependencies(
|
||||
tagList(
|
||||
select,
|
||||
tags$script(
|
||||
@@ -979,8 +982,9 @@ sliderInput <- function(inputId, label, min, max, value, step = NULL,
|
||||
}
|
||||
}
|
||||
|
||||
datePickerDependency <- html_dependency("bootstrap-datepicker", "1.0.2",
|
||||
"shared/datepicker", script = "js/bootstrap-datepicker.min.js",
|
||||
datePickerDependency <- htmlDependency(
|
||||
"bootstrap-datepicker", "1.0.2", c(href = "shared/datepicker"),
|
||||
script = "js/bootstrap-datepicker.min.js",
|
||||
stylesheet = "css/datepicker.css")
|
||||
|
||||
#' Create date input
|
||||
@@ -1059,7 +1063,7 @@ dateInput <- function(inputId, label, value = NULL, min = NULL, max = NULL,
|
||||
if (inherits(min, "Date")) min <- format(min, "%Y-%m-%d")
|
||||
if (inherits(max, "Date")) max <- format(max, "%Y-%m-%d")
|
||||
|
||||
attach_dependency(
|
||||
attachDependencies(
|
||||
tags$div(id = inputId,
|
||||
class = "shiny-date-input",
|
||||
|
||||
@@ -1158,7 +1162,7 @@ dateRangeInput <- function(inputId, label, start = NULL, end = NULL,
|
||||
if (inherits(min, "Date")) min <- format(min, "%Y-%m-%d")
|
||||
if (inherits(max, "Date")) max <- format(max, "%Y-%m-%d")
|
||||
|
||||
attach_dependency(
|
||||
attachDependencies(
|
||||
tags$div(id = inputId,
|
||||
# input-daterange class is needed for dropdown behavior
|
||||
class = "shiny-date-range-input input-daterange",
|
||||
@@ -1604,12 +1608,12 @@ tableOutput <- function(outputId) {
|
||||
}
|
||||
|
||||
dataTableDependency <- list(
|
||||
html_dependency(
|
||||
"datatables", "1.9.4", "shared/datatables",
|
||||
htmlDependency(
|
||||
"datatables", "1.9.4", c(href = "shared/datatables"),
|
||||
script = "js/jquery.dataTables.min.js"
|
||||
),
|
||||
html_dependency(
|
||||
"datatables-bootstrap", "1.9.4", "shared/datatables",
|
||||
htmlDependency(
|
||||
"datatables-bootstrap", "1.9.4", c(href = "shared/datatables"),
|
||||
stylesheet = "css/DT_bootstrap.css",
|
||||
script = "js/DT_bootstrap.js"
|
||||
)
|
||||
@@ -1618,7 +1622,7 @@ dataTableDependency <- list(
|
||||
#' @rdname tableOutput
|
||||
#' @export
|
||||
dataTableOutput <- function(outputId) {
|
||||
attach_dependency(
|
||||
attachDependencies(
|
||||
div(id = outputId, class="shiny-datatable-output"),
|
||||
dataTableDependency
|
||||
)
|
||||
@@ -1762,49 +1766,3 @@ icon <- function(name, class = NULL, lib = "font-awesome") {
|
||||
iconClass <- function(icon) {
|
||||
if (!is.null(icon)) icon[[2]]$attribs$class
|
||||
}
|
||||
|
||||
#' Validate proper CSS formatting of a unit
|
||||
#'
|
||||
#' Checks that the argument is valid for use as a CSS unit of length.
|
||||
#'
|
||||
#' \code{NULL} and \code{NA} are returned unchanged.
|
||||
#'
|
||||
#' Single element numeric vectors are returned as a character vector with the
|
||||
#' number plus a suffix of \code{"px"}.
|
||||
#'
|
||||
#' Single element character vectors must be \code{"auto"} or \code{"inherit"},
|
||||
#' or a number. If the number has a suffix, it must be valid: \code{px},
|
||||
#' \code{\%}, \code{em}, \code{pt}, \code{in}, \code{cm}, \code{mm}, \code{ex},
|
||||
#' or \code{pc}. If the number has no suffix, the suffix \code{"px"} is
|
||||
#' appended.
|
||||
#'
|
||||
#' Any other value will cause an error to be thrown.
|
||||
#'
|
||||
#' @param x The unit to validate. Will be treated as a number of pixels if a
|
||||
#' unit is not specified.
|
||||
#' @return A properly formatted CSS unit of length, if possible. Otherwise, will
|
||||
#' throw an error.
|
||||
#' @examples
|
||||
#' validateCssUnit("10%")
|
||||
#' validateCssUnit(400) #treated as '400px'
|
||||
#' @export
|
||||
validateCssUnit <- function(x) {
|
||||
if (is.null(x) || is.na(x))
|
||||
return(x)
|
||||
|
||||
if (length(x) > 1 || (!is.character(x) && !is.numeric(x)))
|
||||
stop('CSS units must be a numeric or character vector with a single element')
|
||||
|
||||
# if the input is a character vector consisting only of digits (e.g. "960"), coerce it to a
|
||||
# numeric value
|
||||
if (is.character(x) && nchar(x) > 0 && gsub("\\d*", "", x) == "")
|
||||
x <- as.numeric(x)
|
||||
|
||||
if (is.character(x) &&
|
||||
!grepl("^(auto|inherit|((\\.\\d+)|(\\d+(\\.\\d+)?))(%|in|cm|mm|em|ex|pt|pc|px))$", x)) {
|
||||
stop('"', x, '" is not a valid CSS unit (e.g., "100%", "400px", "auto")')
|
||||
} else if (is.numeric(x)) {
|
||||
x <- paste(x, "px", sep = "")
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
pathPattern <- "^(~|/|[a-zA-Z]:[/\\\\]|\\\\\\\\)"
|
||||
|
||||
createWebDependency <- function(dependency) {
|
||||
if (is.null(dependency))
|
||||
return(NULL)
|
||||
@@ -7,53 +5,11 @@ createWebDependency <- function(dependency) {
|
||||
if (!inherits(dependency, "html_dependency"))
|
||||
stop("Unexpected non-html_dependency type")
|
||||
|
||||
# Does it look like a path on disk? Register it as a resource and replace the
|
||||
# disk-based path with a relative URL
|
||||
if (grepl(pathPattern, dependency$path, perl = TRUE)) {
|
||||
if (is.null(dependency$src$href)) {
|
||||
prefix <- paste(dependency$name, "-", dependency$version, sep = "")
|
||||
addResourcePath(prefix, dependency$path)
|
||||
dependency$path <- prefix
|
||||
addResourcePath(prefix, dependency$src$file)
|
||||
dependency$src$href <- prefix
|
||||
}
|
||||
|
||||
return(dependency)
|
||||
}
|
||||
|
||||
# Given a list of dependencies, choose the latest versions and return them as a
|
||||
# named list in the correct order.
|
||||
getNewestDeps <- function(dependencies) {
|
||||
result <- list()
|
||||
for (dep in dependencies) {
|
||||
if (!is.null(dep)) {
|
||||
other <- result[[dep$name]]
|
||||
if (is.null(other) || compareVersion(dep$version, other$version) > 0) {
|
||||
# Note that if the dep was already in the result list, then this
|
||||
# assignment preserves its position in the list
|
||||
result[[dep$name]] <- dep
|
||||
}
|
||||
}
|
||||
}
|
||||
return(result)
|
||||
}
|
||||
|
||||
# Remove `remove` from `dependencies` if the name matches.
|
||||
# dependencies is a named list of dependencies.
|
||||
# remove is a named list of dependencies that take priority.
|
||||
# If warnOnConflict, then warn when a dependency is being removed because of an
|
||||
# older version already being loaded.
|
||||
removeDeps <- function(dependencies, remove, warnOnConflict = TRUE) {
|
||||
matches <- names(dependencies) %in% names(remove)
|
||||
if (warnOnConflict) {
|
||||
for (depname in names(dependencies)[matches]) {
|
||||
loser <- dependencies[[depname]]
|
||||
winner <- remove[[depname]]
|
||||
if (compareVersion(loser$version, winner$version) > 0) {
|
||||
warning(sprintf(paste("The dependency %s %s conflicts with",
|
||||
"version %s"), loser$name, loser$version, winner$version
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Return only deps that weren't in remove
|
||||
return(dependencies[!matches])
|
||||
}
|
||||
|
||||
166
R/htmltools.R
166
R/htmltools.R
@@ -1,97 +1,101 @@
|
||||
#' @export
|
||||
a <- htmltools::a
|
||||
|
||||
#' @export
|
||||
br <- htmltools::br
|
||||
|
||||
# Define an HTML dependency
|
||||
#
|
||||
# Define an HTML dependency (e.g. CSS or Javascript and related library). HTML
|
||||
# dependency definitions are required for \code{\link{html_output}} that
|
||||
# require CSS or JavaScript within the document head to render correctly.
|
||||
#
|
||||
# @param name Library name
|
||||
# @param version Library version
|
||||
# @param path Full path to library
|
||||
# @param meta Named list of meta tags to insert into document head
|
||||
# @param script Script(s) to include within the document head (should be
|
||||
# specified relative to the \code{path} parameter).
|
||||
# @param stylesheet Stylesheet(s) to include within the document (should be
|
||||
# specified relative to the \code{path} parameter).
|
||||
# @param head Arbitrary lines of HTML to insert into the document head
|
||||
#
|
||||
# @return An object that can be included in the list of dependencies passed to
|
||||
# \code{\link{html_print}} or \code{\link{html_knit_print}}.
|
||||
#
|
||||
# @details See the documentation on
|
||||
# \href{http://rmarkdown.rstudio.com/developer_html_widgets.html}{R
|
||||
# Markdown HTML Widgets} for examples and additional details.
|
||||
#
|
||||
html_dependency <- function(name,
|
||||
version,
|
||||
path,
|
||||
meta = NULL,
|
||||
script = NULL,
|
||||
stylesheet = NULL,
|
||||
head = NULL) {
|
||||
structure(class = "html_dependency", list(
|
||||
name = name,
|
||||
version = version,
|
||||
path = path,
|
||||
meta = meta,
|
||||
script = script,
|
||||
stylesheet = stylesheet,
|
||||
head = head
|
||||
))
|
||||
}
|
||||
#' @export
|
||||
code <- htmltools::code
|
||||
|
||||
#' @export
|
||||
div <- htmltools::div
|
||||
|
||||
# Given a list of HTML dependencies produce a character representation
|
||||
# suitable for inclusion within the head of an HTML document
|
||||
html_dependencies_as_character <- function(dependencies, lib_dir = NULL) {
|
||||
#' @export
|
||||
em <- htmltools::em
|
||||
|
||||
html <- c()
|
||||
#' @export
|
||||
h1 <- htmltools::h1
|
||||
|
||||
for (dep in dependencies) {
|
||||
#' @export
|
||||
h2 <- htmltools::h2
|
||||
|
||||
# copy library files if necessary
|
||||
if (!is.null(lib_dir)) {
|
||||
#' @export
|
||||
h3 <- htmltools::h3
|
||||
|
||||
if (!file.exists(lib_dir))
|
||||
dir.create(lib_dir)
|
||||
#' @export
|
||||
h4 <- htmltools::h4
|
||||
|
||||
target_dir <- file.path(lib_dir, basename(dep$path))
|
||||
if (!file.exists(target_dir))
|
||||
file.copy(from = dep$path, to = lib_dir, recursive = TRUE)
|
||||
#' @export
|
||||
h5 <- htmltools::h5
|
||||
|
||||
dep$path <- file.path(basename(lib_dir), basename(target_dir))
|
||||
}
|
||||
#' @export
|
||||
h6 <- htmltools::h6
|
||||
|
||||
# add meta content
|
||||
for (name in names(dep$meta)) {
|
||||
html <- c(html, paste("<meta name=\"", name,
|
||||
"\" content=\"", dep$meta[[name]], "\" />",
|
||||
sep = ""))
|
||||
}
|
||||
#' @export
|
||||
hr <- htmltools::hr
|
||||
|
||||
# add stylesheets
|
||||
for (stylesheet in dep$stylesheet) {
|
||||
stylesheet <- file.path(dep$path, stylesheet)
|
||||
html <- c(html, paste("<link href=\"", stylesheet, "\" ",
|
||||
"rel=\"stylesheet\" />",
|
||||
sep = ""))
|
||||
}
|
||||
#' @export
|
||||
HTML <- htmltools::HTML
|
||||
|
||||
# add scripts
|
||||
for (script in dep$script) {
|
||||
script <- file.path(dep$path, script)
|
||||
html <- c(html,
|
||||
paste("<script src=\"", script, "\"></script>", sep = ""))
|
||||
}
|
||||
#' @export
|
||||
img <- htmltools::img
|
||||
|
||||
# add raw head content
|
||||
html <- c(html, dep$head)
|
||||
}
|
||||
#' @export
|
||||
includeCSS <- htmltools::includeCSS
|
||||
|
||||
html
|
||||
}
|
||||
#' @export
|
||||
includeHTML <- htmltools::includeHTML
|
||||
|
||||
attach_dependency <- function(x, dependency) {
|
||||
structure(x, html_dependency = dependency)
|
||||
}
|
||||
#' @export
|
||||
includeMarkdown <- htmltools::includeMarkdown
|
||||
|
||||
#' @export
|
||||
includeScript <- htmltools::includeScript
|
||||
|
||||
#' @export
|
||||
includeText <- htmltools::includeText
|
||||
|
||||
#' @export
|
||||
is.singleton <- htmltools::is.singleton
|
||||
|
||||
#' @export
|
||||
p <- htmltools::p
|
||||
|
||||
#' @export
|
||||
pre <- htmltools::pre
|
||||
|
||||
#' @export
|
||||
singleton <- htmltools::singleton
|
||||
|
||||
#' @export
|
||||
span <- htmltools::span
|
||||
|
||||
#' @export
|
||||
strong <- htmltools::strong
|
||||
|
||||
#' @export
|
||||
tag <- htmltools::tag
|
||||
|
||||
#' @export
|
||||
tagAppendAttributes <- htmltools::tagAppendAttributes
|
||||
|
||||
#' @export
|
||||
tagAppendChild <- htmltools::tagAppendChild
|
||||
|
||||
#' @export
|
||||
tagAppendChildren <- htmltools::tagAppendChildren
|
||||
|
||||
#' @export
|
||||
tagList <- htmltools::tagList
|
||||
|
||||
#' @export
|
||||
tags <- htmltools::tags
|
||||
|
||||
#' @export
|
||||
tagSetChildren <- htmltools::tagSetChildren
|
||||
|
||||
#' @export
|
||||
validateCssUnit <- htmltools::validateCssUnit
|
||||
|
||||
#' @export
|
||||
withTags <- htmltools::withTags
|
||||
|
||||
@@ -463,7 +463,7 @@ identicalFunctionBodies <- function(a, b) {
|
||||
handlerManager <- HandlerManager$new()
|
||||
|
||||
addSubApp <- function(appObj, autoRemove = TRUE) {
|
||||
path <- sprintf("/%s", createUniqueId(16))
|
||||
path <- createUniqueId(16, "/app")
|
||||
appHandlers <- createAppHandlers(appObj$httpHandler, appObj$serverFuncSource)
|
||||
|
||||
# remove the leading / from the path so a relative path is returned
|
||||
|
||||
13
R/shiny.R
13
R/shiny.R
@@ -15,14 +15,19 @@ NULL
|
||||
#' @name shiny-package
|
||||
#' @aliases shiny
|
||||
#' @docType package
|
||||
#' @import httpuv caTools RJSONIO xtable digest methods
|
||||
#' @import htmltools httpuv caTools RJSONIO xtable digest methods
|
||||
NULL
|
||||
|
||||
createUniqueId <- function(bytes) {
|
||||
createUniqueId <- function(bytes, prefix = "", suffix = "") {
|
||||
withPrivateSeed({
|
||||
paste(
|
||||
format(as.hexmode(sample(256, bytes, replace = TRUE)-1), width=2),
|
||||
collapse = "")
|
||||
prefix,
|
||||
paste(
|
||||
format(as.hexmode(sample(256, bytes, replace = TRUE)-1), width=2),
|
||||
collapse = ""),
|
||||
suffix,
|
||||
sep = ""
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
180
R/shinyui.R
180
R/shinyui.R
@@ -1,143 +1,5 @@
|
||||
#' @include globals.R
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
p <- function(...) tags$p(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
h1 <- function(...) tags$h1(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
h2 <- function(...) tags$h2(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
h3 <- function(...) tags$h3(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
h4 <- function(...) tags$h4(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
h5 <- function(...) tags$h5(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
h6 <- function(...) tags$h6(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
a <- function(...) tags$a(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
br <- function(...) tags$br(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
div <- function(...) tags$div(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
span <- function(...) tags$span(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
pre <- function(...) tags$pre(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
code <- function(...) tags$code(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
img <- function(...) tags$img(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
strong <- function(...) tags$strong(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
em <- function(...) tags$em(...)
|
||||
|
||||
#' @rdname builder
|
||||
#' @export
|
||||
hr <- function(...) tags$hr(...)
|
||||
|
||||
#' Include Content From a File
|
||||
#'
|
||||
#' Include HTML, text, or rendered Markdown into a \link[=shinyUI]{Shiny UI}.
|
||||
#'
|
||||
#' These functions provide a convenient way to include an extensive amount of
|
||||
#' HTML, textual, Markdown, CSS, or JavaScript content, rather than using a
|
||||
#' large literal R string.
|
||||
#'
|
||||
#' @note \code{includeText} escapes its contents, but does no other processing.
|
||||
#' This means that hard breaks and multiple spaces will be rendered as they
|
||||
#' usually are in HTML: as a single space character. If you are looking for
|
||||
#' preformatted text, wrap the call with \code{\link{pre}}, or consider using
|
||||
#' \code{includeMarkdown} instead.
|
||||
#'
|
||||
#' @note The \code{includeMarkdown} function requires the \code{markdown}
|
||||
#' package.
|
||||
#'
|
||||
#' @param path The path of the file to be included. It is highly recommended to
|
||||
#' use a relative path (the base path being the Shiny application directory),
|
||||
#' not an absolute path.
|
||||
#'
|
||||
#' @rdname include
|
||||
#' @name include
|
||||
#' @aliases includeHTML
|
||||
#' @export
|
||||
includeHTML <- function(path) {
|
||||
dependsOnFile(path)
|
||||
lines <- readLines(path, warn=FALSE, encoding='UTF-8')
|
||||
return(HTML(paste(lines, collapse='\r\n')))
|
||||
}
|
||||
|
||||
#' @rdname include
|
||||
#' @export
|
||||
includeText <- function(path) {
|
||||
dependsOnFile(path)
|
||||
lines <- readLines(path, warn=FALSE, encoding='UTF-8')
|
||||
return(paste(lines, collapse='\r\n'))
|
||||
}
|
||||
|
||||
#' @rdname include
|
||||
#' @export
|
||||
includeMarkdown <- function(path) {
|
||||
library(markdown)
|
||||
|
||||
dependsOnFile(path)
|
||||
html <- markdown::markdownToHTML(path, fragment.only=TRUE)
|
||||
Encoding(html) <- 'UTF-8'
|
||||
return(HTML(html))
|
||||
}
|
||||
|
||||
#' @param ... Any additional attributes to be applied to the generated tag.
|
||||
#' @rdname include
|
||||
#' @export
|
||||
includeCSS <- function(path, ...) {
|
||||
dependsOnFile(path)
|
||||
lines <- readLines(path, warn=FALSE, encoding='UTF-8')
|
||||
args <- list(...)
|
||||
if (is.null(args$type))
|
||||
args$type <- 'text/css'
|
||||
return(do.call(tags$style,
|
||||
c(list(HTML(paste(lines, collapse='\r\n'))), args)))
|
||||
}
|
||||
|
||||
#' @rdname include
|
||||
#' @export
|
||||
includeScript <- function(path, ...) {
|
||||
dependsOnFile(path)
|
||||
lines <- readLines(path, warn=FALSE, encoding='UTF-8')
|
||||
return(tags$script(HTML(paste(lines, collapse='\r\n')), ...))
|
||||
}
|
||||
NULL
|
||||
|
||||
#' Load the MathJax library and typeset math expressions
|
||||
#'
|
||||
@@ -162,22 +24,6 @@ withMathJax <- function(...) {
|
||||
)
|
||||
}
|
||||
|
||||
#' Include Content Only Once
|
||||
#'
|
||||
#' Use \code{singleton} to wrap contents (tag, text, HTML, or lists) that should
|
||||
#' be included in the generated document only once, yet may appear in the
|
||||
#' document-generating code more than once. Only the first appearance of the
|
||||
#' content (in document order) will be used. Useful for custom components that
|
||||
#' have JavaScript files or stylesheets.
|
||||
#'
|
||||
#' @param x A \code{\link{tag}}, text, \code{\link{HTML}}, or list.
|
||||
#'
|
||||
#' @export
|
||||
singleton <- function(x) {
|
||||
class(x) <- c(class(x), 'shiny.singleton')
|
||||
return(x)
|
||||
}
|
||||
|
||||
renderPage <- function(ui, connection, showcase=0) {
|
||||
|
||||
if (showcase > 0)
|
||||
@@ -187,17 +33,18 @@ renderPage <- function(ui, connection, showcase=0) {
|
||||
|
||||
deps <- c(
|
||||
list(
|
||||
html_dependency("jquery", "1.11.0", "shared", script = "jquery.js"),
|
||||
html_dependency("shiny", packageVersion("shiny"), "shared",
|
||||
htmlDependency("jquery", "1.11.0", c(href="shared"), script = "jquery.js"),
|
||||
htmlDependency("shiny", packageVersion("shiny"), c(href="shared"),
|
||||
script = "shiny.js", stylesheet = "shiny.css")
|
||||
),
|
||||
result$dependencies
|
||||
)
|
||||
deps <- resolveDependencies(deps)
|
||||
deps <- lapply(deps, createWebDependency)
|
||||
depStr <- paste(sapply(deps, function(dep) {
|
||||
sprintf("%s[%s]", dep$name, dep$version)
|
||||
}), collapse = ";")
|
||||
depHtml <- html_dependencies_as_character(deps)
|
||||
depHtml <- renderDependencies(deps, "href")
|
||||
|
||||
# write preamble
|
||||
writeLines(c('<!DOCTYPE html>',
|
||||
@@ -284,20 +131,3 @@ uiHttpHandler <- function(ui, path = "/") {
|
||||
return(httpResponse(200, content=html))
|
||||
}
|
||||
}
|
||||
|
||||
#' Return HTML dependencies provided by Shiny
|
||||
#'
|
||||
#' By default, Shiny supplies some framework scripts when it renders a page.
|
||||
#' \code{getProvidedHtmlDependencies} returns a list of those provided objects.
|
||||
#'
|
||||
#' @return A list of objects of type \code{html_dependency}, one per dependency
|
||||
#'
|
||||
#' @export
|
||||
getProvidedHtmlDependencies <- function() {
|
||||
list(structure(
|
||||
list(name = "jquery",
|
||||
version = "1.11.0",
|
||||
path = system.file("www/shared/jquery.js", package="shiny"),
|
||||
script = "jquery.js"),
|
||||
class = "html_dependency"))
|
||||
}
|
||||
|
||||
@@ -23,13 +23,18 @@ markRenderFunction <- function(uiFunc, renderFunc) {
|
||||
|
||||
useRenderFunction <- function(renderFunc) {
|
||||
outputFunction <- attr(renderFunc, "outputFunc")
|
||||
id <- createUniqueId(8)
|
||||
id <- createUniqueId(8, "out")
|
||||
o <- getDefaultReactiveDomain()$output
|
||||
if (!is.null(o))
|
||||
o[[id]] <- renderFunc
|
||||
return(outputFunction(id))
|
||||
}
|
||||
|
||||
#' @S3method as.tags shiny.render.function
|
||||
as.tags.shiny.render.function <- function(x, ...) {
|
||||
useRenderFunction(x)
|
||||
}
|
||||
|
||||
#' Plot Output
|
||||
#'
|
||||
#' Renders a reactive plot that is suitable for assigning to an \code{output}
|
||||
@@ -459,7 +464,8 @@ renderUI <- function(expr, env=parent.frame(), quoted=FALSE, func=NULL) {
|
||||
|
||||
result <- takeSingletons(result, shinysession$singletons, desingleton=FALSE)$ui
|
||||
result <- surroundSingletons(result)
|
||||
dependencies <- lapply(getNewestDeps(findDependencies(result)), createWebDependency)
|
||||
dependencies <- lapply(resolveDependencies(findDependencies(result)),
|
||||
createWebDependency)
|
||||
names(dependencies) <- NULL
|
||||
|
||||
# renderTags returns a list with head, singletons, and html
|
||||
|
||||
10
R/showcase.R
10
R/showcase.R
@@ -31,13 +31,13 @@ licenseLink <- function(licenseName) {
|
||||
showcaseHead <- function() {
|
||||
|
||||
deps <- list(
|
||||
html_dependency("jqueryui", "1.10.4", "shared/jqueryui/1.10.4",
|
||||
htmlDependency("jqueryui", "1.10.4", c(href="shared/jqueryui/1.10.4"),
|
||||
script = "jquery-ui.min.js"),
|
||||
html_dependency("showdown", "0.3.1", "shared/showdown/compressed",
|
||||
htmlDependency("showdown", "0.3.1", c(href="shared/showdown/compressed"),
|
||||
script = "showdown.js"),
|
||||
html_dependency("font-awesome", "4.0.3", "shared/font-awesome",
|
||||
htmlDependency("font-awesome", "4.0.3", c(href="shared/font-awesome"),
|
||||
stylesheet = "css/font-awesome.min.css"),
|
||||
html_dependency("highlight.js", "6.2", "shared/highlight",
|
||||
htmlDependency("highlight.js", "6.2", c(href="shared/highlight"),
|
||||
script = "highlight.pack.js")
|
||||
)
|
||||
|
||||
@@ -54,7 +54,7 @@ showcaseHead <- function() {
|
||||
else ""
|
||||
))
|
||||
|
||||
return(attach_dependency(html, deps))
|
||||
return(attachDependencies(html, deps))
|
||||
}
|
||||
|
||||
# Returns tags containing the application metadata (title and author) in
|
||||
|
||||
@@ -99,13 +99,12 @@ slider <- function(inputId, min, max, value, step = NULL, ...,
|
||||
}
|
||||
|
||||
# build slider
|
||||
dep <- html_dependency(name = "jslider", version = "1",
|
||||
path = "shared/slider",
|
||||
dep <- htmlDependency("jslider", "1", c(href="shared/slider"),
|
||||
script = "js/jquery.slider.min.js",
|
||||
stylesheet = "css/jquery.slider.min.css"
|
||||
)
|
||||
sliderFragment <- list(
|
||||
attach_dependency(
|
||||
attachDependencies(
|
||||
tags$input(
|
||||
id=inputId, type="slider",
|
||||
name=inputId, value=paste(value, collapse=';'), class="jslider",
|
||||
|
||||
637
R/tags.R
637
R/tags.R
@@ -1,637 +0,0 @@
|
||||
|
||||
|
||||
htmlEscape <- local({
|
||||
.htmlSpecials <- list(
|
||||
`&` = '&',
|
||||
`<` = '<',
|
||||
`>` = '>'
|
||||
)
|
||||
.htmlSpecialsPattern <- paste(names(.htmlSpecials), collapse='|')
|
||||
.htmlSpecialsAttrib <- c(
|
||||
.htmlSpecials,
|
||||
`'` = ''',
|
||||
`"` = '"',
|
||||
`\r` = ' ',
|
||||
`\n` = ' '
|
||||
)
|
||||
.htmlSpecialsPatternAttrib <- paste(names(.htmlSpecialsAttrib), collapse='|')
|
||||
|
||||
function(text, attribute=TRUE) {
|
||||
pattern <- if(attribute)
|
||||
.htmlSpecialsPatternAttrib
|
||||
else
|
||||
.htmlSpecialsPattern
|
||||
|
||||
# Short circuit in the common case that there's nothing to escape
|
||||
if (!any(grepl(pattern, text)))
|
||||
return(text)
|
||||
|
||||
specials <- if(attribute)
|
||||
.htmlSpecialsAttrib
|
||||
else
|
||||
.htmlSpecials
|
||||
|
||||
for (chr in names(specials)) {
|
||||
text <- gsub(chr, specials[[chr]], text, fixed=TRUE)
|
||||
}
|
||||
|
||||
return(text)
|
||||
}
|
||||
})
|
||||
|
||||
isTag <- function(x) {
|
||||
inherits(x, "shiny.tag")
|
||||
}
|
||||
|
||||
#' @export
|
||||
print.shiny.tag <- function(x, ...) {
|
||||
print(as.character(x), ...)
|
||||
invisible(x)
|
||||
}
|
||||
|
||||
# indent can be numeric to indicate an initial indent level,
|
||||
# or FALSE to suppress
|
||||
#' @export
|
||||
format.shiny.tag <- function(x, ..., singletons = character(0), indent = 0) {
|
||||
as.character(renderTags(x, singletons = singletons, indent = indent)$html)
|
||||
}
|
||||
|
||||
#' @export
|
||||
as.character.shiny.tag <- function(x, ...) {
|
||||
renderTags(x)$html
|
||||
}
|
||||
|
||||
#' @export
|
||||
print.shiny.tag.list <- print.shiny.tag
|
||||
|
||||
#' @export
|
||||
format.shiny.tag.list <- format.shiny.tag
|
||||
|
||||
#' @export
|
||||
as.character.shiny.tag.list <- as.character.shiny.tag
|
||||
|
||||
#' @export
|
||||
print.html <- function(x, ...) {
|
||||
cat(x, "\n")
|
||||
invisible(x)
|
||||
}
|
||||
|
||||
#' @export
|
||||
format.html <- function(x, ...) {
|
||||
as.character(x)
|
||||
}
|
||||
|
||||
normalizeText <- function(text) {
|
||||
if (!is.null(attr(text, "html")))
|
||||
text
|
||||
else
|
||||
htmlEscape(text, attribute=FALSE)
|
||||
|
||||
}
|
||||
|
||||
#' @rdname tag
|
||||
#' @export
|
||||
tagList <- function(...) {
|
||||
lst <- list(...)
|
||||
class(lst) <- c("shiny.tag.list", "list")
|
||||
return(lst)
|
||||
}
|
||||
|
||||
#' @rdname tag
|
||||
#' @export
|
||||
tagAppendAttributes <- function(tag, ...) {
|
||||
tag$attribs <- c(tag$attribs, list(...))
|
||||
tag
|
||||
}
|
||||
|
||||
#' @rdname tag
|
||||
#' @export
|
||||
tagAppendChild <- function(tag, child) {
|
||||
tag$children[[length(tag$children)+1]] <- child
|
||||
tag
|
||||
}
|
||||
|
||||
#' @rdname tag
|
||||
#' @export
|
||||
tagAppendChildren <- function(tag, ..., list = NULL) {
|
||||
tag$children <- c(tag$children, c(list(...), list))
|
||||
tag
|
||||
}
|
||||
|
||||
#' @rdname tag
|
||||
#' @export
|
||||
tagSetChildren <- function(tag, ..., list = NULL) {
|
||||
tag$children <- c(list(...), list)
|
||||
tag
|
||||
}
|
||||
|
||||
#' HTML Tag Object
|
||||
#'
|
||||
#' \code{tag()} creates an HTML tag definition. Note that all of the valid HTML5
|
||||
#' tags are already defined in the \code{\link{tags}} environment so these
|
||||
#' functions should only be used to generate additional tags.
|
||||
#' \code{tagAppendChild()} and \code{tagList()} are for supporting package
|
||||
#' authors who wish to create their own sets of tags; see the contents of
|
||||
#' bootstrap.R for examples.
|
||||
#' @param _tag_name HTML tag name
|
||||
#' @param varArgs List of attributes and children of the element. Named list
|
||||
#' items become attributes, and unnamed list items become children. Valid
|
||||
#' children are tags, single-character character vectors (which become text
|
||||
#' nodes), and raw HTML (see \code{\link{HTML}}). You can also pass lists that
|
||||
#' contain tags, text nodes, and HTML.
|
||||
#' @param tag A tag to append child elements to.
|
||||
#' @param child A child element to append to a parent tag.
|
||||
#' @param ... Unnamed items that comprise this list of tags.
|
||||
#' @param list An optional list of elements. Can be used with or instead of the
|
||||
#' \code{...} items.
|
||||
#' @return An HTML tag object that can be rendered as HTML using
|
||||
#' \code{\link{as.character}()}.
|
||||
#' @export
|
||||
#' @examples
|
||||
#' tagList(tags$h1("Title"),
|
||||
#' tags$h2("Header text"),
|
||||
#' tags$p("Text here"))
|
||||
#'
|
||||
#' # Can also convert a regular list to a tagList (internal data structure isn't
|
||||
#' # exactly the same, but when rendered to HTML, the output is the same).
|
||||
#' x <- list(tags$h1("Title"),
|
||||
#' tags$h2("Header text"),
|
||||
#' tags$p("Text here"))
|
||||
#' tagList(x)
|
||||
tag <- function(`_tag_name`, varArgs) {
|
||||
# Get arg names; if not a named list, use vector of empty strings
|
||||
varArgsNames <- names(varArgs)
|
||||
if (is.null(varArgsNames))
|
||||
varArgsNames <- character(length=length(varArgs))
|
||||
|
||||
# Named arguments become attribs, dropping NULL values
|
||||
named_idx <- nzchar(varArgsNames)
|
||||
attribs <- dropNulls(varArgs[named_idx])
|
||||
|
||||
# Unnamed arguments are flattened and added as children.
|
||||
# Use unname() to remove the names attribute from the list, which would
|
||||
# consist of empty strings anyway.
|
||||
children <- unname(varArgs[!named_idx])
|
||||
|
||||
# Return tag data structure
|
||||
structure(
|
||||
list(name = `_tag_name`,
|
||||
attribs = attribs,
|
||||
children = children),
|
||||
class = "shiny.tag"
|
||||
)
|
||||
}
|
||||
|
||||
tagWrite <- function(tag, textWriter, indent=0, eol = "\n") {
|
||||
|
||||
if (length(tag) == 0)
|
||||
return (NULL)
|
||||
|
||||
# optionally process a list of tags
|
||||
if (!isTag(tag) && is.list(tag)) {
|
||||
tag <- dropNullsOrEmpty(flattenTags(tag))
|
||||
lapply(tag, tagWrite, textWriter, indent)
|
||||
return (NULL)
|
||||
}
|
||||
|
||||
nextIndent <- if (is.numeric(indent)) indent + 1 else indent
|
||||
indent <- if (is.numeric(indent)) indent else 0
|
||||
|
||||
# compute indent text
|
||||
indentText <- paste(rep(" ", indent*2), collapse="")
|
||||
|
||||
# Check if it's just text (may either be plain-text or HTML)
|
||||
if (is.character(tag)) {
|
||||
textWriter(paste(indentText, normalizeText(tag), eol, sep=""))
|
||||
return (NULL)
|
||||
}
|
||||
|
||||
# write tag name
|
||||
textWriter(paste(indentText, "<", tag$name, sep=""))
|
||||
|
||||
# Convert all attribs to chars explicitly; prevents us from messing up factors
|
||||
attribs <- lapply(tag$attribs, as.character)
|
||||
# concatenate attributes
|
||||
# split() is very slow, so avoid it if possible
|
||||
if (anyDuplicated(names(attribs)))
|
||||
attribs <- lapply(split(attribs, names(attribs)), paste, collapse = " ")
|
||||
|
||||
# write attributes
|
||||
for (attrib in names(attribs)) {
|
||||
attribValue <- attribs[[attrib]]
|
||||
if (!is.na(attribValue)) {
|
||||
if (is.logical(attribValue))
|
||||
attribValue <- tolower(attribValue)
|
||||
text <- htmlEscape(attribValue, attribute=TRUE)
|
||||
textWriter(paste(" ", attrib,"=\"", text, "\"", sep=""))
|
||||
}
|
||||
else {
|
||||
textWriter(paste(" ", attrib, sep=""))
|
||||
}
|
||||
}
|
||||
|
||||
# write any children
|
||||
children <- dropNullsOrEmpty(flattenTags(tag$children))
|
||||
if (length(children) > 0) {
|
||||
textWriter(">")
|
||||
|
||||
# special case for a single child text node (skip newlines and indentation)
|
||||
if ((length(children) == 1) && is.character(children[[1]]) ) {
|
||||
textWriter(paste(normalizeText(children[[1]]), "</", tag$name, ">", eol,
|
||||
sep=""))
|
||||
}
|
||||
else {
|
||||
textWriter("\n")
|
||||
for (child in children)
|
||||
tagWrite(child, textWriter, nextIndent)
|
||||
textWriter(paste(indentText, "</", tag$name, ">", eol, sep=""))
|
||||
}
|
||||
}
|
||||
else {
|
||||
# only self-close void elements
|
||||
# (see: http://dev.w3.org/html5/spec/single-page.html#void-elements)
|
||||
if (tag$name %in% c("area", "base", "br", "col", "command", "embed", "hr",
|
||||
"img", "input", "keygen", "link", "meta", "param",
|
||||
"source", "track", "wbr")) {
|
||||
textWriter(paste("/>", eol, sep=""))
|
||||
}
|
||||
else {
|
||||
textWriter(paste("></", tag$name, ">", eol, sep=""))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doRenderTags <- function(ui, indent = 0) {
|
||||
# Render the body--the bodyHtml variable will be created
|
||||
conn <- file(open="w+")
|
||||
connWriter <- function(text) writeChar(text, conn, eos = NULL)
|
||||
htmlResult <- tryCatch({
|
||||
tagWrite(ui, connWriter, indent)
|
||||
flush(conn)
|
||||
readLines(conn)
|
||||
},
|
||||
finally = close(conn)
|
||||
)
|
||||
return(HTML(paste(htmlResult, collapse = "\n")))
|
||||
}
|
||||
|
||||
renderTags <- function(ui, singletons = character(0), indent = 0) {
|
||||
# Do singleton and head processing before rendering
|
||||
singletonInfo <- takeSingletons(ui, singletons)
|
||||
headInfo <- takeHeads(singletonInfo$ui)
|
||||
deps <- getNewestDeps(findDependencies(singletonInfo$ui))
|
||||
|
||||
headIndent <- if (is.numeric(indent)) indent + 1 else indent
|
||||
headHtml <- doRenderTags(headInfo$head, indent = headIndent)
|
||||
bodyHtml <- doRenderTags(headInfo$ui, indent = indent)
|
||||
|
||||
return(list(head = headHtml,
|
||||
singletons = singletonInfo$singletons,
|
||||
dependencies = deps,
|
||||
html = bodyHtml))
|
||||
}
|
||||
|
||||
# Walk a tree of tag objects, rewriting objects according to func.
|
||||
# preorder=TRUE means preorder tree traversal, that is, an object
|
||||
# should be rewritten before its children.
|
||||
rewriteTags <- function(ui, func, preorder) {
|
||||
if (preorder)
|
||||
ui <- func(ui)
|
||||
|
||||
if (isTag(ui)) {
|
||||
ui$children[] <- lapply(ui$children, rewriteTags, func, preorder)
|
||||
} else if (is.list(ui)) {
|
||||
ui[] <- lapply(ui, rewriteTags, func, preorder)
|
||||
}
|
||||
|
||||
if (!preorder)
|
||||
ui <- func(ui)
|
||||
|
||||
return(ui)
|
||||
}
|
||||
|
||||
# Preprocess a tag object by changing any singleton X into
|
||||
# <!--SHINY.SINGLETON[sig]-->X'<!--/SHINY.SINGLETON[sig]-->
|
||||
# where sig is the sha1 of X, and X' is X minus the singleton
|
||||
# attribute.
|
||||
#
|
||||
# In the case of nested singletons, outer singletons are processed
|
||||
# before inner singletons (otherwise the processing of inner
|
||||
# singletons would cause the sha1 of the outer singletons to be
|
||||
# different).
|
||||
surroundSingletons <- local({
|
||||
surroundSingleton <- function(uiObj) {
|
||||
if (inherits(uiObj, "shiny.singleton")) {
|
||||
sig <- digest(uiObj, "sha1")
|
||||
class(uiObj) <- class(uiObj)[class(uiObj) != "shiny.singleton"]
|
||||
return(tagList(
|
||||
HTML(sprintf("<!--SHINY.SINGLETON[%s]-->", sig)),
|
||||
uiObj,
|
||||
HTML(sprintf("<!--/SHINY.SINGLETON[%s]-->", sig))
|
||||
))
|
||||
} else {
|
||||
uiObj
|
||||
}
|
||||
}
|
||||
|
||||
function(ui) {
|
||||
rewriteTags(ui, surroundSingleton, TRUE)
|
||||
}
|
||||
})
|
||||
|
||||
# Given a tag object, apply singleton logic (allow singleton objects
|
||||
# to appear no more than once per signature) and return the processed
|
||||
# HTML objects and also the list of known singletons.
|
||||
takeSingletons <- function(ui, singletons=character(0), desingleton=TRUE) {
|
||||
result <- rewriteTags(ui, function(uiObj) {
|
||||
if (inherits(uiObj, "shiny.singleton")) {
|
||||
sig <- digest(uiObj, "sha1")
|
||||
if (sig %in% singletons)
|
||||
return(NULL)
|
||||
singletons <<- append(singletons, sig)
|
||||
if (desingleton)
|
||||
class(uiObj) <- class(uiObj)[class(uiObj) != "shiny.singleton"]
|
||||
return(uiObj)
|
||||
} else {
|
||||
return(uiObj)
|
||||
}
|
||||
}, TRUE)
|
||||
|
||||
return(list(ui=result, singletons=singletons))
|
||||
}
|
||||
|
||||
# Given a tag object, extract out any children of tags$head
|
||||
# and return them separate from the body.
|
||||
takeHeads <- function(ui) {
|
||||
headItems <- list()
|
||||
result <- rewriteTags(ui, function(uiObj) {
|
||||
if (isTag(uiObj) && tolower(uiObj$name) == "head") {
|
||||
headItems <<- append(headItems, uiObj$children)
|
||||
return(NULL)
|
||||
}
|
||||
return(uiObj)
|
||||
}, FALSE)
|
||||
|
||||
return(list(ui=result, head=headItems))
|
||||
}
|
||||
|
||||
findDependencies <- function(ui) {
|
||||
dep <- attr(ui, "html_dependency")
|
||||
if (!is.null(dep) && inherits(dep, "html_dependency"))
|
||||
dep <- list(dep)
|
||||
children <- if (is.list(ui)) {
|
||||
if (isTag(ui)) {
|
||||
ui$children
|
||||
} else {
|
||||
ui
|
||||
}
|
||||
}
|
||||
childDeps <- unlist(lapply(children, findDependencies), recursive = FALSE)
|
||||
c(childDeps, if (!is.null(dep)) dep)
|
||||
}
|
||||
|
||||
#' HTML Builder Functions
|
||||
#'
|
||||
#' Simple functions for constructing HTML documents.
|
||||
#'
|
||||
#' The \code{tags} environment contains convenience functions for all valid
|
||||
#' HTML5 tags. To generate tags that are not part of the HTML5 specification,
|
||||
#' you can use the \code{\link{tag}()} function.
|
||||
#'
|
||||
#' Dedicated functions are available for the most common HTML tags that do not
|
||||
#' conflict with common R functions.
|
||||
#'
|
||||
#' The result from these functions is a tag object, which can be converted using
|
||||
#' \code{\link{as.character}()}.
|
||||
#'
|
||||
#' @name builder
|
||||
#' @param ... Attributes and children of the element. Named arguments become
|
||||
#' attributes, and positional arguments become children. Valid children are
|
||||
#' tags, single-character character vectors (which become text nodes), and raw
|
||||
#' HTML (see \code{\link{HTML}}). You can also pass lists that contain tags,
|
||||
#' text nodes, and HTML.
|
||||
#' @export tags
|
||||
#' @examples
|
||||
#' doc <- tags$html(
|
||||
#' tags$head(
|
||||
#' tags$title('My first page')
|
||||
#' ),
|
||||
#' tags$body(
|
||||
#' h1('My first heading'),
|
||||
#' p('My first paragraph, with some ',
|
||||
#' strong('bold'),
|
||||
#' ' text.'),
|
||||
#' div(id='myDiv', class='simpleDiv',
|
||||
#' 'Here is a div with some attributes.')
|
||||
#' )
|
||||
#' )
|
||||
#' cat(as.character(doc))
|
||||
NULL
|
||||
|
||||
#' @rdname builder
|
||||
#' @format NULL
|
||||
#' @docType NULL
|
||||
#' @keywords NULL
|
||||
tags <- list(
|
||||
a = function(...) tag("a", list(...)),
|
||||
abbr = function(...) tag("abbr", list(...)),
|
||||
address = function(...) tag("address", list(...)),
|
||||
area = function(...) tag("area", list(...)),
|
||||
article = function(...) tag("article", list(...)),
|
||||
aside = function(...) tag("aside", list(...)),
|
||||
audio = function(...) tag("audio", list(...)),
|
||||
b = function(...) tag("b", list(...)),
|
||||
base = function(...) tag("base", list(...)),
|
||||
bdi = function(...) tag("bdi", list(...)),
|
||||
bdo = function(...) tag("bdo", list(...)),
|
||||
blockquote = function(...) tag("blockquote", list(...)),
|
||||
body = function(...) tag("body", list(...)),
|
||||
br = function(...) tag("br", list(...)),
|
||||
button = function(...) tag("button", list(...)),
|
||||
canvas = function(...) tag("canvas", list(...)),
|
||||
caption = function(...) tag("caption", list(...)),
|
||||
cite = function(...) tag("cite", list(...)),
|
||||
code = function(...) tag("code", list(...)),
|
||||
col = function(...) tag("col", list(...)),
|
||||
colgroup = function(...) tag("colgroup", list(...)),
|
||||
command = function(...) tag("command", list(...)),
|
||||
data = function(...) tag("data", list(...)),
|
||||
datalist = function(...) tag("datalist", list(...)),
|
||||
dd = function(...) tag("dd", list(...)),
|
||||
del = function(...) tag("del", list(...)),
|
||||
details = function(...) tag("details", list(...)),
|
||||
dfn = function(...) tag("dfn", list(...)),
|
||||
div = function(...) tag("div", list(...)),
|
||||
dl = function(...) tag("dl", list(...)),
|
||||
dt = function(...) tag("dt", list(...)),
|
||||
em = function(...) tag("em", list(...)),
|
||||
embed = function(...) tag("embed", list(...)),
|
||||
eventsource = function(...) tag("eventsource", list(...)),
|
||||
fieldset = function(...) tag("fieldset", list(...)),
|
||||
figcaption = function(...) tag("figcaption", list(...)),
|
||||
figure = function(...) tag("figure", list(...)),
|
||||
footer = function(...) tag("footer", list(...)),
|
||||
form = function(...) tag("form", list(...)),
|
||||
h1 = function(...) tag("h1", list(...)),
|
||||
h2 = function(...) tag("h2", list(...)),
|
||||
h3 = function(...) tag("h3", list(...)),
|
||||
h4 = function(...) tag("h4", list(...)),
|
||||
h5 = function(...) tag("h5", list(...)),
|
||||
h6 = function(...) tag("h6", list(...)),
|
||||
head = function(...) tag("head", list(...)),
|
||||
header = function(...) tag("header", list(...)),
|
||||
hgroup = function(...) tag("hgroup", list(...)),
|
||||
hr = function(...) tag("hr", list(...)),
|
||||
html = function(...) tag("html", list(...)),
|
||||
i = function(...) tag("i", list(...)),
|
||||
iframe = function(...) tag("iframe", list(...)),
|
||||
img = function(...) tag("img", list(...)),
|
||||
input = function(...) tag("input", list(...)),
|
||||
ins = function(...) tag("ins", list(...)),
|
||||
kbd = function(...) tag("kbd", list(...)),
|
||||
keygen = function(...) tag("keygen", list(...)),
|
||||
label = function(...) tag("label", list(...)),
|
||||
legend = function(...) tag("legend", list(...)),
|
||||
li = function(...) tag("li", list(...)),
|
||||
link = function(...) tag("link", list(...)),
|
||||
mark = function(...) tag("mark", list(...)),
|
||||
map = function(...) tag("map", list(...)),
|
||||
menu = function(...) tag("menu", list(...)),
|
||||
meta = function(...) tag("meta", list(...)),
|
||||
meter = function(...) tag("meter", list(...)),
|
||||
nav = function(...) tag("nav", list(...)),
|
||||
noscript = function(...) tag("noscript", list(...)),
|
||||
object = function(...) tag("object", list(...)),
|
||||
ol = function(...) tag("ol", list(...)),
|
||||
optgroup = function(...) tag("optgroup", list(...)),
|
||||
option = function(...) tag("option", list(...)),
|
||||
output = function(...) tag("output", list(...)),
|
||||
p = function(...) tag("p", list(...)),
|
||||
param = function(...) tag("param", list(...)),
|
||||
pre = function(...) tag("pre", list(...)),
|
||||
progress = function(...) tag("progress", list(...)),
|
||||
q = function(...) tag("q", list(...)),
|
||||
ruby = function(...) tag("ruby", list(...)),
|
||||
rp = function(...) tag("rp", list(...)),
|
||||
rt = function(...) tag("rt", list(...)),
|
||||
s = function(...) tag("s", list(...)),
|
||||
samp = function(...) tag("samp", list(...)),
|
||||
script = function(...) tag("script", list(...)),
|
||||
section = function(...) tag("section", list(...)),
|
||||
select = function(...) tag("select", list(...)),
|
||||
small = function(...) tag("small", list(...)),
|
||||
source = function(...) tag("source", list(...)),
|
||||
span = function(...) tag("span", list(...)),
|
||||
strong = function(...) tag("strong", list(...)),
|
||||
style = function(...) tag("style", list(...)),
|
||||
sub = function(...) tag("sub", list(...)),
|
||||
summary = function(...) tag("summary", list(...)),
|
||||
sup = function(...) tag("sup", list(...)),
|
||||
table = function(...) tag("table", list(...)),
|
||||
tbody = function(...) tag("tbody", list(...)),
|
||||
td = function(...) tag("td", list(...)),
|
||||
textarea = function(...) tag("textarea", list(...)),
|
||||
tfoot = function(...) tag("tfoot", list(...)),
|
||||
th = function(...) tag("th", list(...)),
|
||||
thead = function(...) tag("thead", list(...)),
|
||||
time = function(...) tag("time", list(...)),
|
||||
title = function(...) tag("title", list(...)),
|
||||
tr = function(...) tag("tr", list(...)),
|
||||
track = function(...) tag("track", list(...)),
|
||||
u = function(...) tag("u", list(...)),
|
||||
ul = function(...) tag("ul", list(...)),
|
||||
var = function(...) tag("var", list(...)),
|
||||
video = function(...) tag("video", list(...)),
|
||||
wbr = function(...) tag("wbr", list(...))
|
||||
)
|
||||
|
||||
#' Mark Characters as HTML
|
||||
#'
|
||||
#' Marks the given text as HTML, which means the \link{tag} functions will know
|
||||
#' not to perform HTML escaping on it.
|
||||
#'
|
||||
#' @param text The text value to mark with HTML
|
||||
#' @param ... Any additional values to be converted to character and
|
||||
#' concatenated together
|
||||
#' @return The same value, but marked as HTML.
|
||||
#'
|
||||
#' @examples
|
||||
#' el <- div(HTML("I like <u>turtles</u>"))
|
||||
#' cat(as.character(el))
|
||||
#'
|
||||
#' @export
|
||||
HTML <- function(text, ...) {
|
||||
htmlText <- c(text, as.character(list(...)))
|
||||
htmlText <- paste(htmlText, collapse=" ")
|
||||
attr(htmlText, "html") <- TRUE
|
||||
class(htmlText) <- c("html", "character")
|
||||
htmlText
|
||||
}
|
||||
|
||||
#' Evaluate an expression using the \code{tags}
|
||||
#'
|
||||
#' This function makes it simpler to write HTML-generating code. Instead of
|
||||
#' needing to specify \code{tags} each time a tag function is used, as in
|
||||
#' \code{tags$div()} and \code{tags$p()}, code inside \code{withTags} is
|
||||
#' evaluated with \code{tags} searched first, so you can simply use
|
||||
#' \code{div()} and \code{p()}.
|
||||
#'
|
||||
#' If your code uses an object which happens to have the same name as an
|
||||
#' HTML tag function, such as \code{source()} or \code{summary()}, it will call
|
||||
#' the tag function. To call the intended (non-tags function), specify the
|
||||
#' namespace, as in \code{base::source()} or \code{base::summary()}.
|
||||
#'
|
||||
#' @param code A set of tags.
|
||||
#'
|
||||
#' @examples
|
||||
#' # Using tags$ each time
|
||||
#' tags$div(class = "myclass",
|
||||
#' tags$h3("header"),
|
||||
#' tags$p("text")
|
||||
#' )
|
||||
#'
|
||||
#' # Equivalent to above, but using withTags
|
||||
#' withTags(
|
||||
#' div(class = "myclass",
|
||||
#' h3("header"),
|
||||
#' p("text")
|
||||
#' )
|
||||
#' )
|
||||
#'
|
||||
#'
|
||||
#' @export
|
||||
withTags <- function(code) {
|
||||
eval(substitute(code), envir = as.list(tags), enclos = parent.frame())
|
||||
}
|
||||
|
||||
|
||||
# Given a list of tags, lists, and other items, return a flat list, where the
|
||||
# items from the inner, nested lists are pulled to the top level, recursively.
|
||||
flattenTags <- function(x) {
|
||||
if (isTag(x)) {
|
||||
# For tags, wrap them into a list (which will be unwrapped by caller)
|
||||
list(x)
|
||||
} else if (is.list(x)) {
|
||||
if (length(x) == 0) {
|
||||
# Empty lists are simply returned
|
||||
x
|
||||
} else {
|
||||
# For items that are lists (but not tags), recurse
|
||||
unlist(lapply(x, flattenTags), recursive = FALSE)
|
||||
}
|
||||
|
||||
} else if (is.character(x)){
|
||||
# This will preserve attributes if x is a character with attribute,
|
||||
# like what HTML() produces
|
||||
list(x)
|
||||
|
||||
} else if (is.function(x) && inherits(x, "shiny.render.function")) {
|
||||
|
||||
list(useRenderFunction(x))
|
||||
|
||||
} else {
|
||||
# For other items, coerce to character and wrap them into a list (which
|
||||
# will be unwrapped by caller). Note that this will strip attributes.
|
||||
list(as.character(x))
|
||||
}
|
||||
}
|
||||
@@ -159,8 +159,6 @@ sd_section("Embedding",
|
||||
"Functions that are intended for third-party packages that embed Shiny applications.",
|
||||
c(
|
||||
"shinyApp",
|
||||
"maskReactiveContext",
|
||||
"knitr_methods",
|
||||
"getProvidedHtmlDependencies"
|
||||
"maskReactiveContext"
|
||||
)
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ test_that("All man pages have an entry in staticdocs/index.r", {
|
||||
return()
|
||||
}
|
||||
# Known not to be indexed
|
||||
known_unindexed <- c("shiny-package")
|
||||
known_unindexed <- c("shiny-package", "knitr_methods")
|
||||
|
||||
indexed_topics <- local({
|
||||
result <- character(0)
|
||||
|
||||
@@ -1,432 +0,0 @@
|
||||
context("tags")
|
||||
|
||||
test_that("Basic tag writing works", {
|
||||
expect_equal(as.character(tagList("hi")), HTML("hi"))
|
||||
expect_equal(
|
||||
as.character(tagList("one", "two", tagList("three"))),
|
||||
HTML("one\ntwo\nthree"))
|
||||
expect_equal(
|
||||
as.character(tags$b("one")),
|
||||
HTML("<b>one</b>"))
|
||||
expect_equal(
|
||||
as.character(tags$b("one", "two")),
|
||||
HTML("<b>\n one\n two\n</b>"))
|
||||
expect_equal(
|
||||
as.character(tagList(list("one"))),
|
||||
HTML("one"))
|
||||
expect_equal(
|
||||
as.character(tagList(list(tagList("one")))),
|
||||
HTML("one"))
|
||||
expect_equal(
|
||||
as.character(tagList(tags$br(), "one")),
|
||||
HTML("<br/>\none"))
|
||||
})
|
||||
|
||||
|
||||
test_that("withTags works", {
|
||||
output_tags <- tags$div(class = "myclass",
|
||||
tags$h3("header"),
|
||||
tags$p("text here")
|
||||
)
|
||||
output_withhtml <- withTags(
|
||||
div(class = "myclass",
|
||||
h3("header"),
|
||||
p("text here")
|
||||
)
|
||||
)
|
||||
expect_identical(output_tags, output_withhtml)
|
||||
|
||||
|
||||
# Check that current environment is searched
|
||||
x <- 100
|
||||
expect_identical(tags$p(x), withTags(p(x)))
|
||||
|
||||
# Just to make sure, run it in a function, which has its own environment
|
||||
foo <- function() {
|
||||
y <- 100
|
||||
withTags(p(y))
|
||||
}
|
||||
expect_identical(tags$p(100), foo())
|
||||
})
|
||||
|
||||
|
||||
test_that("HTML escaping in tags", {
|
||||
# Regular text is escaped
|
||||
expect_equivalent(format(div("<a&b>")), "<div><a&b></div>")
|
||||
|
||||
# Text in HTML() isn't escaped
|
||||
expect_equivalent(format(div(HTML("<a&b>"))), "<div><a&b></div>")
|
||||
|
||||
# Text in a property is escaped
|
||||
expect_equivalent(format(div(class = "<a&b>", "text")),
|
||||
'<div class="<a&b>">text</div>')
|
||||
|
||||
# HTML() has no effect in a property like 'class'
|
||||
expect_equivalent(format(div(class = HTML("<a&b>"), "text")),
|
||||
'<div class="<a&b>">text</div>')
|
||||
})
|
||||
|
||||
|
||||
test_that("Adding child tags", {
|
||||
tag_list <- list(tags$p("tag1"), tags$b("tag2"), tags$i("tag3"))
|
||||
|
||||
# Creating nested tags by calling the tag$div function and passing a list
|
||||
t1 <- tags$div(class="foo", tag_list)
|
||||
expect_equal(length(t1$children), 1)
|
||||
expect_equal(length(t1$children[[1]]), 3)
|
||||
expect_equal(t1$children[[1]][[1]]$name, "p")
|
||||
expect_equal(t1$children[[1]][[1]]$children[[1]], "tag1")
|
||||
expect_equal(t1$children[[1]][[2]]$name, "b")
|
||||
expect_equal(t1$children[[1]][[2]]$children[[1]], "tag2")
|
||||
expect_equal(t1$children[[1]][[3]]$name, "i")
|
||||
expect_equal(t1$children[[1]][[3]]$children[[1]], "tag3")
|
||||
|
||||
|
||||
# div tag used as starting point for tests below
|
||||
div_tag <- tags$div(class="foo")
|
||||
|
||||
# Appending each child
|
||||
t2 <- tagAppendChild(div_tag, tag_list[[1]])
|
||||
t2 <- tagAppendChild(t2, tag_list[[2]])
|
||||
t2 <- tagAppendChild(t2, tag_list[[3]])
|
||||
t2a <- do.call(tags$div, c(tag_list, class="foo"))
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
|
||||
# tagSetChildren, using list argument
|
||||
t2 <- tagSetChildren(div_tag, list = tag_list)
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
# tagSetChildren, using ... arguments
|
||||
t2 <- tagSetChildren(div_tag, tag_list[[1]], tag_list[[2]], tag_list[[3]])
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
# tagSetChildren, using ... and list arguments
|
||||
t2 <- tagSetChildren(div_tag, tag_list[[1]], list = tag_list[2:3])
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
# tagSetChildren overwrites existing children
|
||||
t2 <- tagAppendChild(div_tag, p("should replace this tag"))
|
||||
t2 <- tagSetChildren(div_tag, list = tag_list)
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
|
||||
# tagAppendChildren, using list argument
|
||||
t2 <- tagAppendChild(div_tag, tag_list[[1]])
|
||||
t2 <- tagAppendChildren(t2, list = tag_list[2:3])
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
# tagAppendChildren, using ... arguments
|
||||
t2 <- tagAppendChild(div_tag, tag_list[[1]])
|
||||
t2 <- tagAppendChildren(t2, tag_list[[2]], tag_list[[3]])
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
# tagAppendChildren, using ... and list arguments
|
||||
t2 <- tagAppendChild(div_tag, tag_list[[1]])
|
||||
t2 <- tagAppendChildren(t2, tag_list[[2]], list = list(tag_list[[3]]))
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
# tagAppendChildren can start with no children
|
||||
t2 <- tagAppendChildren(div_tag, list = tag_list)
|
||||
expect_identical(t2a, t2)
|
||||
|
||||
|
||||
# tagSetChildren preserves attributes
|
||||
x <- tagSetChildren(div(), HTML("text"))
|
||||
expect_identical(attr(x$children[[1]], "html"), TRUE)
|
||||
|
||||
# tagAppendChildren preserves attributes
|
||||
x <- tagAppendChildren(div(), HTML("text"))
|
||||
expect_identical(attr(x$children[[1]], "html"), TRUE)
|
||||
})
|
||||
|
||||
|
||||
test_that("Creating simple tags", {
|
||||
# Empty tag
|
||||
expect_identical(
|
||||
div(),
|
||||
structure(
|
||||
list(name = "div", attribs = list(), children = list()),
|
||||
.Names = c("name", "attribs", "children"),
|
||||
class = "shiny.tag"
|
||||
)
|
||||
)
|
||||
|
||||
# Tag with text
|
||||
expect_identical(
|
||||
div("text"),
|
||||
structure(
|
||||
list(name = "div", attribs = list(), children = list("text")),
|
||||
.Names = c("name", "attribs", "children"),
|
||||
class = "shiny.tag"
|
||||
)
|
||||
)
|
||||
|
||||
# NULL attributes are dropped
|
||||
expect_identical(
|
||||
div(a = NULL, b = "value"),
|
||||
div(b = "value")
|
||||
)
|
||||
|
||||
# NULL children are dropped
|
||||
expect_identical(
|
||||
renderTags(div("foo", NULL, list(NULL, list(NULL, "bar"))))$html,
|
||||
renderTags(div("foo", "bar"))$html
|
||||
)
|
||||
|
||||
# Numbers are coerced to strings
|
||||
expect_identical(
|
||||
renderTags(div(1234))$html,
|
||||
renderTags(div("1234"))$html
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
test_that("Creating nested tags", {
|
||||
# Simple version
|
||||
# Note that the $children list should not have a names attribute
|
||||
expect_identical(
|
||||
div(class="foo", list("a", "b")),
|
||||
structure(
|
||||
list(name = "div",
|
||||
attribs = structure(list(class = "foo"), .Names = "class"),
|
||||
children = list(list("a", "b"))),
|
||||
.Names = c("name", "attribs", "children"),
|
||||
class = "shiny.tag"
|
||||
)
|
||||
)
|
||||
|
||||
# More complex version
|
||||
t1 <- withTags(
|
||||
div(class = "foo",
|
||||
p("child tag"),
|
||||
list(
|
||||
p("in-list child tag 1"),
|
||||
"in-list character string",
|
||||
p(),
|
||||
p("in-list child tag 2")
|
||||
),
|
||||
"character string",
|
||||
1234
|
||||
)
|
||||
)
|
||||
|
||||
# t1 should be identical to this data structure.
|
||||
# The nested list should be flattened, and non-tag, non-strings should be
|
||||
# converted to strings
|
||||
t1_full <- structure(
|
||||
list(
|
||||
name = "div",
|
||||
attribs = list(class = "foo"),
|
||||
children = list(
|
||||
structure(list(name = "p",
|
||||
attribs = list(),
|
||||
children = list("child tag")),
|
||||
class = "shiny.tag"
|
||||
),
|
||||
structure(list(name = "p",
|
||||
attribs = list(),
|
||||
children = list("in-list child tag 1")),
|
||||
class = "shiny.tag"
|
||||
),
|
||||
"in-list character string",
|
||||
structure(list(name = "p",
|
||||
attribs = list(),
|
||||
children = list()),
|
||||
class = "shiny.tag"
|
||||
),
|
||||
structure(list(name = "p",
|
||||
attribs = list(),
|
||||
children = list("in-list child tag 2")),
|
||||
class = "shiny.tag"
|
||||
),
|
||||
"character string",
|
||||
"1234"
|
||||
)
|
||||
),
|
||||
class = "shiny.tag"
|
||||
)
|
||||
|
||||
expect_identical(renderTags(t1)$html, renderTags(t1_full)$html)
|
||||
})
|
||||
|
||||
test_that("Attributes are preserved", {
|
||||
# HTML() adds an attribute to the data structure (note that this is
|
||||
# different from the 'attribs' field in the list)
|
||||
x <- HTML("<tag>&&</tag>")
|
||||
expect_identical(attr(x, "html"), TRUE)
|
||||
expect_equivalent(format(x), "<tag>&&</tag>")
|
||||
|
||||
# Make sure attributes are preserved when wrapped in other tags
|
||||
x <- div(HTML("<tag>&&</tag>"))
|
||||
expect_equivalent(x$children[[1]], HTML("<tag>&&</tag>"))
|
||||
expect_identical(attr(x$children[[1]], "html"), TRUE)
|
||||
expect_equivalent(format(x), "<div><tag>&&</tag></div>")
|
||||
|
||||
# Deeper nesting
|
||||
x <- div(p(HTML("<tag>&&</tag>")))
|
||||
expect_equivalent(x$children[[1]]$children[[1]], HTML("<tag>&&</tag>"))
|
||||
expect_identical(attr(x$children[[1]]$children[[1]], "html"), TRUE)
|
||||
expect_equivalent(format(x), "<div>\n <p><tag>&&</tag></p>\n</div>")
|
||||
})
|
||||
|
||||
|
||||
test_that("Flattening a list of tags", {
|
||||
# Flatten a nested list
|
||||
nested <- list(
|
||||
"a1",
|
||||
list(
|
||||
"b1",
|
||||
list("c1", "c2"),
|
||||
list(),
|
||||
"b2",
|
||||
list("d1", "d2")
|
||||
),
|
||||
"a2"
|
||||
)
|
||||
flat <- list("a1", "b1", "c1", "c2", "b2", "d1", "d2", "a2")
|
||||
expect_identical(flattenTags(nested), flat)
|
||||
|
||||
# no-op for flat lists
|
||||
expect_identical(flattenTags(list(a="1", "b")), list(a="1", "b"))
|
||||
|
||||
# numbers are coerced to character
|
||||
expect_identical(flattenTags(list(a=1, "b")), list(a="1", "b"))
|
||||
|
||||
# empty list results in empty list
|
||||
expect_identical(flattenTags(list()), list())
|
||||
|
||||
# preserve attributes
|
||||
nested <- list("txt1", list(structure("txt2", prop="prop2")))
|
||||
flat <- list("txt1",
|
||||
structure("txt2", prop="prop2"))
|
||||
expect_identical(flattenTags(nested), flat)
|
||||
})
|
||||
|
||||
test_that("Head and singleton behavior", {
|
||||
result <- renderTags(tagList(
|
||||
tags$head(singleton("hello"))
|
||||
))
|
||||
|
||||
expect_identical(result$html, HTML(""))
|
||||
expect_identical(result$head, HTML(" hello"))
|
||||
expect_identical(result$singletons, "60eed8231e688bcba7c275c58dd2e3b4dacb61f0")
|
||||
|
||||
# Ensure that "hello" actually behaves like a singleton
|
||||
result2 <- renderTags(tagList(
|
||||
tags$head(singleton("hello"))
|
||||
), singletons = result$singletons)
|
||||
|
||||
expect_identical(result$singletons, result2$singletons)
|
||||
expect_identical(result2$head, HTML(""))
|
||||
expect_identical(result2$html, HTML(""))
|
||||
|
||||
result3 <- renderTags(tagList(
|
||||
tags$head(singleton("hello"), singleton("hello"))
|
||||
))
|
||||
expect_identical(result$singletons, result3$singletons)
|
||||
expect_identical(result3$head, HTML(" hello"))
|
||||
|
||||
# Ensure that singleton can be applied to lists, not just tags
|
||||
result4 <- renderTags(list(singleton(list("hello")), singleton(list("hello"))))
|
||||
expect_identical(result4$singletons, "d7319e3f14167c4c056dd7aa0b274c83fe2291f6")
|
||||
expect_identical(result4$html, renderTags(HTML("hello"))$html)
|
||||
})
|
||||
|
||||
test_that("Factors are treated as characters, not numbers", {
|
||||
myfactors <- factor(LETTERS[1:3])
|
||||
expect_identical(
|
||||
as.character(tags$option(value=myfactors[[1]], myfactors[[1]])),
|
||||
HTML('<option value="A">A</option>')
|
||||
)
|
||||
|
||||
expect_identical(
|
||||
as.character(tags$option(value=myfactors[[1]], value='B', value=3, myfactors[[1]])),
|
||||
HTML('<option value="A B 3">A</option>')
|
||||
)
|
||||
})
|
||||
|
||||
test_that("Unusual list contents are rendered correctly", {
|
||||
expect_identical(renderTags(list(NULL)), renderTags(HTML("")))
|
||||
expect_identical(renderTags(list(100)), renderTags(HTML("100")))
|
||||
expect_identical(renderTags(list(list(100))), renderTags(HTML("100")))
|
||||
expect_identical(renderTags(list(list())), renderTags(HTML("")))
|
||||
expect_identical(renderTags(NULL), renderTags(HTML("")))
|
||||
})
|
||||
|
||||
test_that("Low-level singleton manipulation methods", {
|
||||
# Default arguments drop singleton duplicates and strips the
|
||||
# singletons it keeps of the singleton bit
|
||||
result1 <- takeSingletons(tags$div(
|
||||
singleton(tags$head(tags$script("foo"))),
|
||||
singleton(tags$head(tags$script("foo")))
|
||||
))
|
||||
|
||||
expect_identical(result1$ui$children[[2]], NULL)
|
||||
expect_false(is(result1$ui$children[[1]], "shiny.singleton"))
|
||||
|
||||
# desingleton=FALSE means drop duplicates but don't strip the
|
||||
# singleton bit
|
||||
result2 <- takeSingletons(tags$div(
|
||||
singleton(tags$head(tags$script("foo"))),
|
||||
singleton(tags$head(tags$script("foo")))
|
||||
), desingleton=FALSE)
|
||||
|
||||
expect_identical(result2$ui$children[[2]], NULL)
|
||||
expect_is(result2$ui$children[[1]], "shiny.singleton")
|
||||
|
||||
result3 <- surroundSingletons(tags$div(
|
||||
singleton(tags$script("foo")),
|
||||
singleton(tags$script("foo"))
|
||||
))
|
||||
|
||||
expect_identical(
|
||||
renderTags(result3)$html,
|
||||
HTML("<div>
|
||||
<!--SHINY.SINGLETON[58b302d493b50acb75e4a5606687cadccdf902d8]-->
|
||||
<script>foo</script>
|
||||
<!--/SHINY.SINGLETON[58b302d493b50acb75e4a5606687cadccdf902d8]-->
|
||||
<!--SHINY.SINGLETON[58b302d493b50acb75e4a5606687cadccdf902d8]-->
|
||||
<script>foo</script>
|
||||
<!--/SHINY.SINGLETON[58b302d493b50acb75e4a5606687cadccdf902d8]-->
|
||||
</div>")
|
||||
)
|
||||
})
|
||||
|
||||
test_that("Indenting can be controlled/suppressed", {
|
||||
expect_identical(
|
||||
renderTags(tags$div("a", "b"))$html,
|
||||
HTML("<div>\n a\n b\n</div>")
|
||||
)
|
||||
expect_identical(
|
||||
format(tags$div("a", "b")),
|
||||
"<div>\n a\n b\n</div>"
|
||||
)
|
||||
|
||||
expect_identical(
|
||||
renderTags(tags$div("a", "b"), indent = 2)$html,
|
||||
HTML(" <div>\n a\n b\n </div>")
|
||||
)
|
||||
expect_identical(
|
||||
format(tags$div("a", "b"), indent = 2),
|
||||
" <div>\n a\n b\n </div>"
|
||||
)
|
||||
|
||||
expect_identical(
|
||||
renderTags(tags$div("a", "b"), indent = FALSE)$html,
|
||||
HTML("<div>\na\nb\n</div>")
|
||||
)
|
||||
expect_identical(
|
||||
format(tags$div("a", "b"), indent = FALSE),
|
||||
"<div>\na\nb\n</div>"
|
||||
)
|
||||
|
||||
expect_identical(
|
||||
renderTags(tagList(tags$div("a", "b")), indent = FALSE)$html,
|
||||
HTML("<div>\na\nb\n</div>")
|
||||
)
|
||||
expect_identical(
|
||||
format(tagList(tags$div("a", "b")), indent = FALSE),
|
||||
"<div>\na\nb\n</div>"
|
||||
)
|
||||
})
|
||||
@@ -1285,7 +1285,7 @@
|
||||
|
||||
registerDependency(dep.name, dep.version);
|
||||
|
||||
var path = dep.path;
|
||||
var href = dep.src.href;
|
||||
|
||||
var $head = $("head").first();
|
||||
|
||||
@@ -1299,14 +1299,14 @@
|
||||
if (dep.stylesheet) {
|
||||
var stylesheets = $.map(asArray(dep.stylesheet), function(stylesheet) {
|
||||
return $("<link rel='stylesheet' type='text/css'>")
|
||||
.attr("href", path + "/" + stylesheet);
|
||||
.attr("href", href + "/" + stylesheet);
|
||||
});
|
||||
$head.append(stylesheets);
|
||||
}
|
||||
|
||||
if (dep.script) {
|
||||
var scripts = $.map(asArray(dep.script), function(scriptName) {
|
||||
return $("<script>").attr("src", path + "/" + scriptName);
|
||||
return $("<script>").attr("src", href + "/" + scriptName);
|
||||
});
|
||||
$head.append(scripts);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
\name{HTML}
|
||||
\alias{HTML}
|
||||
\title{Mark Characters as HTML}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{absolutePanel}
|
||||
\alias{absolutePanel}
|
||||
\alias{fixedPanel}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{actionButton}
|
||||
\alias{actionButton}
|
||||
\alias{actionLink}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{addResourcePath}
|
||||
\alias{addResourcePath}
|
||||
\title{Resource Publishing}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{bootstrapPage}
|
||||
\alias{basicPage}
|
||||
\alias{bootstrapPage}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
\name{p}
|
||||
\name{builder}
|
||||
\alias{a}
|
||||
\alias{br}
|
||||
\alias{builder}
|
||||
@@ -21,6 +20,8 @@
|
||||
\alias{tags}
|
||||
\title{HTML Builder Functions}
|
||||
\usage{
|
||||
tags
|
||||
|
||||
p(...)
|
||||
|
||||
h1(...)
|
||||
@@ -54,8 +55,6 @@ strong(...)
|
||||
em(...)
|
||||
|
||||
hr(...)
|
||||
|
||||
tags
|
||||
}
|
||||
\arguments{
|
||||
\item{...}{Attributes and children of the element. Named arguments become
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{checkboxGroupInput}
|
||||
\alias{checkboxGroupInput}
|
||||
\title{Checkbox Group Input Control}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{checkboxInput}
|
||||
\alias{checkboxInput}
|
||||
\title{Checkbox Input Control}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{column}
|
||||
\alias{column}
|
||||
\title{Create a column within a UI definition}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{conditionalPanel}
|
||||
\alias{conditionalPanel}
|
||||
\title{Conditional Panel}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{dateInput}
|
||||
\alias{dateInput}
|
||||
\title{Create date input}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{dateRangeInput}
|
||||
\alias{dateRangeInput}
|
||||
\title{Create date range input}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{getDefaultReactiveDomain}
|
||||
\alias{domains}
|
||||
\alias{getDefaultReactiveDomain}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{downloadButton}
|
||||
\alias{downloadButton}
|
||||
\alias{downloadLink}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{downloadHandler}
|
||||
\alias{downloadHandler}
|
||||
\title{File Downloads}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{exprToFunction}
|
||||
\alias{exprToFunction}
|
||||
\title{Convert an expression to a function}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{fileInput}
|
||||
\alias{fileInput}
|
||||
\title{File Upload Control}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{fixedPage}
|
||||
\alias{fixedPage}
|
||||
\alias{fixedRow}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{flowLayout}
|
||||
\alias{flowLayout}
|
||||
\title{Flow layout}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{fluidPage}
|
||||
\alias{fluidPage}
|
||||
\alias{fluidRow}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
\name{getProvidedHtmlDependencies}
|
||||
\alias{getProvidedHtmlDependencies}
|
||||
\title{Return HTML dependencies provided by Shiny}
|
||||
\usage{
|
||||
getProvidedHtmlDependencies()
|
||||
}
|
||||
\value{
|
||||
A list of objects of type \code{html_dependency}, one per dependency
|
||||
}
|
||||
\description{
|
||||
By default, Shiny supplies some framework scripts when it renders a page.
|
||||
\code{getProvidedHtmlDependencies} returns a list of those provided objects.
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{headerPanel}
|
||||
\alias{headerPanel}
|
||||
\title{Create a header panel}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{helpText}
|
||||
\alias{helpText}
|
||||
\title{Create a help text element}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{htmlOutput}
|
||||
\alias{htmlOutput}
|
||||
\alias{uiOutput}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{icon}
|
||||
\alias{icon}
|
||||
\title{Create an icon}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{imageOutput}
|
||||
\alias{imageOutput}
|
||||
\title{Create a image output element}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
\name{include}
|
||||
\alias{include}
|
||||
\alias{includeCSS}
|
||||
@@ -26,7 +25,7 @@ includeScript(path, ...)
|
||||
\item{...}{Any additional attributes to be applied to the generated tag.}
|
||||
}
|
||||
\description{
|
||||
Include HTML, text, or rendered Markdown into a \link[=shinyUI]{Shiny UI}.
|
||||
Load HTML, text, or rendered Markdown from a file and turn into HTML.
|
||||
}
|
||||
\details{
|
||||
These functions provide a convenient way to include an extensive amount of
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{inputPanel}
|
||||
\alias{inputPanel}
|
||||
\title{Input panel}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{installExprFunction}
|
||||
\alias{installExprFunction}
|
||||
\title{Install an expression as a function}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{invalidateLater}
|
||||
\alias{invalidateLater}
|
||||
\title{Scheduled Invalidation}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{is.reactivevalues}
|
||||
\alias{is.reactivevalues}
|
||||
\title{Checks whether an object is a reactivevalues object}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{isolate}
|
||||
\alias{isolate}
|
||||
\title{Create a non-reactive scope for an expression}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{knitr_methods}
|
||||
\alias{knit_print.shiny.appobj}
|
||||
\alias{knit_print.shiny.render.function}
|
||||
\alias{knit_print.shiny.tag}
|
||||
\alias{knit_print.shiny.tag.list}
|
||||
\alias{knitr_methods}
|
||||
\title{Knitr S3 methods}
|
||||
\usage{
|
||||
knit_print.shiny.appobj(x, ...)
|
||||
|
||||
knit_print.shiny.tag(x, ...)
|
||||
|
||||
knit_print.shiny.tag.list(x, ...)
|
||||
|
||||
knit_print.shiny.render.function(x, ...)
|
||||
}
|
||||
\arguments{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{mainPanel}
|
||||
\alias{mainPanel}
|
||||
\title{Create a main panel}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{makeReactiveBinding}
|
||||
\alias{makeReactiveBinding}
|
||||
\title{Make a reactive variable}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{markRenderFunction}
|
||||
\alias{markRenderFunction}
|
||||
\title{Mark a function as a render function}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{maskReactiveContext}
|
||||
\alias{maskReactiveContext}
|
||||
\title{Evaluate an expression without a reactive context}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{navbarPage}
|
||||
\alias{navbarMenu}
|
||||
\alias{navbarPage}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{navlistPanel}
|
||||
\alias{navlistPanel}
|
||||
\title{Create a navigation list panel}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{numericInput}
|
||||
\alias{numericInput}
|
||||
\title{Create a numeric input control}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{observe}
|
||||
\alias{observe}
|
||||
\title{Create a reactive observer}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{outputOptions}
|
||||
\alias{outputOptions}
|
||||
\title{Set options for an output object.}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{pageWithSidebar}
|
||||
\alias{pageWithSidebar}
|
||||
\title{Create a page with a sidebar}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{parseQueryString}
|
||||
\alias{parseQueryString}
|
||||
\title{Parse a GET query string from a URL}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{plotOutput}
|
||||
\alias{plotOutput}
|
||||
\title{Create an plot output element}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{plotPNG}
|
||||
\alias{plotPNG}
|
||||
\title{Run a plotting function and save the output as a PNG}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{radioButtons}
|
||||
\alias{radioButtons}
|
||||
\title{Create radio buttons}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactive}
|
||||
\alias{is.reactive}
|
||||
\alias{reactive}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveFileReader}
|
||||
\alias{reactiveFileReader}
|
||||
\title{Reactive file reader}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactivePlot}
|
||||
\alias{reactivePlot}
|
||||
\title{Plot output (deprecated)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactivePoll}
|
||||
\alias{reactivePoll}
|
||||
\title{Reactive polling}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactivePrint}
|
||||
\alias{reactivePrint}
|
||||
\title{Print output (deprecated)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveTable}
|
||||
\alias{reactiveTable}
|
||||
\title{Table output (deprecated)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveText}
|
||||
\alias{reactiveText}
|
||||
\title{Text output (deprecated)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveTimer}
|
||||
\alias{reactiveTimer}
|
||||
\title{Timer}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveUI}
|
||||
\alias{reactiveUI}
|
||||
\title{UI output (deprecated)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveValues}
|
||||
\alias{reactiveValues}
|
||||
\title{Create an object for storing reactive values}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{reactiveValuesToList}
|
||||
\alias{reactiveValuesToList}
|
||||
\title{Convert a reactivevalues object to a list}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{registerInputHandler}
|
||||
\alias{registerInputHandler}
|
||||
\title{Register an Input Handler}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{removeInputHandler}
|
||||
\alias{removeInputHandler}
|
||||
\title{Deregister an Input Handler}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderDataTable}
|
||||
\alias{renderDataTable}
|
||||
\title{Table output with the JavaScript library DataTables}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderImage}
|
||||
\alias{renderImage}
|
||||
\title{Image file output}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderPlot}
|
||||
\alias{renderPlot}
|
||||
\title{Plot Output}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderPrint}
|
||||
\alias{renderPrint}
|
||||
\title{Printable Output}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderTable}
|
||||
\alias{renderTable}
|
||||
\title{Table Output}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderText}
|
||||
\alias{renderText}
|
||||
\title{Text Output}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{renderUI}
|
||||
\alias{renderUI}
|
||||
\title{UI Output}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{repeatable}
|
||||
\alias{repeatable}
|
||||
\title{Make a random number generator repeatable}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{runApp}
|
||||
\alias{runApp}
|
||||
\title{Run Shiny Application}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{runExample}
|
||||
\alias{runExample}
|
||||
\title{Run Shiny Example Applications}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{runGist}
|
||||
\alias{runGist}
|
||||
\title{Run a Shiny application from https://gist.github.com}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{runGitHub}
|
||||
\alias{runGitHub}
|
||||
\title{Run a Shiny application from a GitHub repository}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{runUrl}
|
||||
\alias{runUrl}
|
||||
\title{Run a Shiny application from a URL}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{selectInput}
|
||||
\alias{selectInput}
|
||||
\alias{selectizeInput}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{session}
|
||||
\alias{session}
|
||||
\title{Session object}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\docType{package}
|
||||
\name{shiny-package}
|
||||
\alias{shiny}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{shinyApp}
|
||||
\alias{as.shiny.appobj}
|
||||
\alias{as.shiny.appobj.character}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{shinyDeprecated}
|
||||
\alias{shinyDeprecated}
|
||||
\title{Print message for deprecated functions in Shiny}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{shinyServer}
|
||||
\alias{shinyServer}
|
||||
\title{Define Server Functionality}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{shinyUI}
|
||||
\alias{shinyUI}
|
||||
\title{Create a Shiny UI handler}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{showReactLog}
|
||||
\alias{showReactLog}
|
||||
\title{Reactive Log Visualizer}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
% Generated by roxygen2 (4.0.0): do not edit by hand
|
||||
% Generated by roxygen2 (4.0.1): do not edit by hand
|
||||
\name{sidebarLayout}
|
||||
\alias{sidebarLayout}
|
||||
\title{Layout a sidebar and main area}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user