Skip to content

Commit e7c6189

Browse files
committed
refactor: Organize scripts/htmlDependencies into functions
1 parent 92d9fcb commit e7c6189

File tree

7 files changed

+385
-317
lines changed

7 files changed

+385
-317
lines changed

scripts/_functions_deps.R

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
assert_npm_is_installed <- function() {
2+
if (Sys.which("npm")[["npm"]] == "") {
3+
cli::cli_abort(c(
4+
"{.strong {npm}} is required to install JavaScript dependenceis.",
5+
i = "Please install {.url https://nodejs.org}."
6+
))
7+
}
8+
9+
cli::cli_alert_success("{.strong npm} is installed")
10+
invisible(TRUE)
11+
}
12+
13+
pkg_source_version <- function(pkg) {
14+
desc <- suppressWarnings(utils::packageDescription(pkg))
15+
if (!inherits(desc, "packageDescription")) {
16+
return("[not installed]")
17+
}
18+
version <- desc[["Version"]]
19+
if (is.null(desc[["GithubRepo"]])) {
20+
return(version)
21+
}
22+
23+
sprintf(
24+
"%s (%s/%s@%s)",
25+
version,
26+
desc[["GithubUsername"]],
27+
desc[["GithubRepo"]],
28+
desc[["GithubSHA1"]]
29+
)
30+
}
31+
32+
write_json <- function(
33+
file,
34+
x,
35+
...,
36+
pretty = TRUE,
37+
auto_unbox = TRUE,
38+
generated_by = "scripts/htmlDependencies.R"
39+
) {
40+
jsonlite::write_json(
41+
c(
42+
list(
43+
"note!" = sprintf("Generated by %s: do not edit by hand", generated_by)
44+
),
45+
x
46+
),
47+
file,
48+
...,
49+
pretty = pretty,
50+
auto_unbox = auto_unbox
51+
)
52+
}
53+
54+
copy_from_pkg <- function(pkg_name, pkg_dir, local_dir, version_dir = path_dir(local_dir)) {
55+
# `version_dir` is "equal to" or "contains" `local_dir`
56+
stopifnot(path_has_parent(local_dir, version_dir))
57+
if (dir_exists(version_dir)) dir_delete(version_dir)
58+
dir_create(local_dir)
59+
60+
stopifnot(local_dir != ".")
61+
62+
# Copy other folder into local parent folder
63+
dir_copy(
64+
system.file(pkg_dir, package = pkg_name),
65+
dirname(local_dir)
66+
)
67+
# Rename folder to local folder name
68+
if (basename(local_dir) != basename(pkg_dir)) {
69+
file.rename(
70+
path(dirname(local_dir), basename(pkg_dir)),
71+
local_dir
72+
)
73+
}
74+
# Save pkg version info
75+
write_json(
76+
path(version_dir, "_version.json"),
77+
list(
78+
package = pkg_name,
79+
version = pkg_source_version(pkg_name)
80+
)
81+
)
82+
83+
invisible(local_dir)
84+
}
85+
86+
delete_non_minified <- function(dir) {
87+
file_delete(
88+
dir_ls(
89+
dir,
90+
type = "file",
91+
recurse = TRUE,
92+
regexp = "\\.(min\\.|css)",
93+
invert = TRUE
94+
)
95+
)
96+
}
97+
98+
write_deps_ionrangeslider <- function(theme, www_shared) {
99+
ion_dep <- shiny:::ionRangeSliderDependencyCSS(theme)
100+
ion_dep_css <- path(ion_dep$src$file, ion_dep$stylesheet)
101+
102+
# Preset="shiny" additional ionRangeSlider rules
103+
ion_preset_rules <- system.file("builtin", "bs5", "shiny", "ionrangeslider", "_rules.scss", package = "bslib")
104+
105+
ion_preset_compiled <-
106+
sass::sass_partial(
107+
readLines(ion_preset_rules),
108+
theme,
109+
write_attachments = FALSE,
110+
cache = FALSE
111+
)
112+
113+
# Append preset styles to the base ionRangeSlider CSS
114+
cat(
115+
c("\n\n/* shiny preset styles */\n\n", ion_preset_compiled),
116+
file = ion_dep_css,
117+
sep = "\n",
118+
append = TRUE
119+
)
120+
121+
if (inherits(ion_dep, "html_dependency")) {
122+
ion_dep <- list(ion_dep)
123+
}
124+
125+
# Save to temp folder
126+
temp_ion_dep_dir <- withr::local_tempdir("shiny-ion-range-slider")
127+
128+
withr::with_options(
129+
list(htmltools.dir.version = FALSE),
130+
ignore <- lapply(ion_dep, htmltools::copyDependencyToDir, temp_ion_dep_dir)
131+
)
132+
133+
# Overwrite css file
134+
ion_dep_dir <- path(www_shared, "ionrangeslider")
135+
ion_dep_css <- path(ion_dep_dir, "css", "ion.rangeSlider.css")
136+
137+
file_move(
138+
path(temp_ion_dep_dir, "ionRangeSlider", "ionRangeSlider.min.css"),
139+
ion_dep_css
140+
)
141+
142+
invisible(ion_dep_css)
143+
}
144+
145+
write_bootstrap_bslib_deps <- function(theme, www_shared) {
146+
deps <- bslib::bs_theme_dependencies(theme)
147+
148+
withr::with_options(
149+
list(htmltools.dir.version = FALSE),
150+
for (dep in deps) {
151+
if (dep$name %in% c("bslib-component-css", "bslib-component-js")) {
152+
next
153+
}
154+
copyDependencyToDir(dep, www_shared)
155+
}
156+
)
157+
158+
write_json(
159+
path(www_shared, "bootstrap/_version.json"),
160+
list(
161+
shiny_version = pkg_source_version("shiny"),
162+
bslib_version = pkg_source_version("bslib"),
163+
htmltools_version = pkg_source_version("htmltools"),
164+
bootstrap_version = bs_version_full(bslib::theme_version(theme))
165+
)
166+
)
167+
168+
message("Reduce font files")
169+
path_bootstrap <- path(www_shared, "bootstrap")
170+
171+
font_css_text <- paste(readLines(path(path_bootstrap, "font.css")), collapse = "\n")
172+
173+
woff_files <- dir_ls(path(path_bootstrap, "fonts"), regexp = "[.]woff")
174+
175+
for (woff_file in woff_files) {
176+
font_file_name <- path_file(woff_file)
177+
if (!grepl(font_file_name, font_css_text, fixed = TRUE)) {
178+
file_delete(woff_file)
179+
}
180+
}
181+
182+
invisible()
183+
}
184+
185+
extract_css_path <- function(dep) {
186+
stopifnot(inherits(dep, "html_dependency"))
187+
path(dep$src$file, dep$stylesheet)
188+
}
189+
190+
write_shiny_css <- function(theme, www_shared) {
191+
shiny_css_dep <- shiny:::shinyDependencyCSS(theme)
192+
shiny_css_bslib <- extract_css_path(shiny_css_dep)
193+
shiny_css_shared <- path(www_shared, "shiny.min.css")
194+
writeLines(
195+
c(
196+
readLines(shiny_css_shared, n = 1), # keep header of original minified css
197+
readLines(shiny_css_bslib)
198+
),
199+
con = shiny_css_shared
200+
)
201+
202+
invisible(shiny_css_shared)
203+
}
204+
205+
write_selectize_css <- function(theme, www_shared) {
206+
selectize_css_dep <- shiny:::selectizeDependencyFunc(theme)
207+
selectize_css_bslib <- extract_css_path(selectize_css_dep)
208+
selectize_shared <- path(www_shared, "selectize", "css")
209+
210+
file_delete(path(selectize_shared, "selectize.bootstrap3.css"))
211+
212+
file_copy(
213+
selectize_css_bslib,
214+
path(selectize_shared, "selectize.min.css"),
215+
overwrite = TRUE
216+
)
217+
218+
invisible(path(selectize_shared, "selectize.min.css"))
219+
}
220+
221+
write_datepicker_css <- function(theme, www_shared) {
222+
datepicker_css_dep <- shiny:::datePickerCSS(theme)
223+
datepicker_css_bslib <- extract_css_path(datepicker_css_dep)
224+
datepicker_shared <- path(www_shared, "datepicker", "css")
225+
226+
file_copy(
227+
datepicker_css_bslib,
228+
path(datepicker_shared, "bootstrap-datepicker3.min.css"),
229+
overwrite = TRUE
230+
)
231+
232+
invisible(path(datepicker_shared, "bootstrap-datepicker3.min.css"))
233+
}
234+
235+
delete_from_www_shared <- function(www_shared, ...) {
236+
files <- path(www_shared, c(...))
237+
238+
dirs <- files[is_dir(files)]
239+
files <- files[!is_dir(files)]
240+
241+
dir_delete(dirs)
242+
file_delete(files)
243+
}
244+
245+
write_require_js <- function(requirejs_version, www_shared) {
246+
requirejs <- path(www_shared, "requirejs")
247+
dir_create(requirejs)
248+
249+
download.file(
250+
paste0("https://cdnjs.cloudflare.com/ajax/libs/require.js/", requirejs_version, "/require.min.js"),
251+
path(requirejs, "require.min.js"),
252+
quiet = TRUE
253+
)
254+
255+
shims <- path_root("scripts", "define-shims.js")
256+
257+
cat(
258+
"\n\n",
259+
paste(readLines(shims), collapse = "\n"),
260+
file = path(requirejs, "require.min.js"),
261+
append = TRUE
262+
)
263+
264+
invisible(path(requirejs, "require.min.js"))
265+
}
266+
267+
write_versions_py <- function(bootstrap, requirejs) {
268+
versions["shiny_html_deps"] <- as.character(packageVersion("shiny"))
269+
versions["bslib"] <- as.character(packageVersion("bslib"))
270+
versions["htmltools"] <- as.character(packageVersion("htmltools"))
271+
versions["bootstrap"] <- bs_version_full(bootstrap)
272+
versions["requirejs"] <- requirejs
273+
274+
path_versions_py <- path_root("shiny", "_versions.py")
275+
276+
version_vars <- paste0(names(versions), " = ", "\"", versions, "\"\n", collapse = "")
277+
version_all <- paste0(
278+
collapse = "",
279+
"__all__ = (\n",
280+
paste0(" \"", names(versions), "\",\n", collapse = ""),
281+
")\n"
282+
)
283+
284+
cat(
285+
file = path_versions_py,
286+
version_vars,
287+
"\n",
288+
version_all,
289+
sep = ""
290+
)
291+
292+
invisible(path_versions_py)
293+
}
294+
295+
npm_install_dependencies <- function() {
296+
withr::local_dir(path_root("js"))
297+
invisible(system("npm install && npm run build", intern = TRUE, ignore.stderr = TRUE))
298+
}

scripts/_functions_setup.R

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,8 @@ pak_install <- function(...) {
3333

3434
invisible(pkgs)
3535
}
36+
37+
bs_version_full <- function(version) {
38+
bs_v <- bslib::versions()
39+
names(bs_v)[bs_v == version]
40+
}

0 commit comments

Comments
 (0)