Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid exernal assets #2249

Merged
merged 38 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
4a6b950
Avoid exernal assets
salim-b Dec 5, 2022
fba7f1e
Add news bullet
salim-b Dec 5, 2022
ab3989c
Fix URL assembly
salim-b Dec 5, 2022
710184f
Check integrity of downloaded asset files
salim-b Dec 12, 2022
d6d2fd5
Tweak error msg wording
salim-b Dec 12, 2022
a41303c
Fix dependencies
salim-b Dec 12, 2022
bff4af6
Always assume UTF-8 ext asset file encoding
salim-b Dec 12, 2022
e2b9fa5
Fix asset file integrity validation on Windows
salim-b Dec 12, 2022
7d8cbeb
Merge branch 'incl-assets' of github.com:salim-b/pkgdown into incl-as…
salim-b Dec 12, 2022
672d329
Download subresources in binary mode
salim-b Dec 13, 2022
153c3b0
Merge branch 'main' into incl-assets
salim-b Dec 14, 2022
e5d68f7
Update NEWS
salim-b Dec 14, 2022
0d0f2b4
Remove `template.params.external_assets` config option
salim-b May 9, 2023
c348147
Merge branch 'main' into incl-assets
salim-b May 9, 2023
810dd6f
Switch to minified `fuse.js`
salim-b May 9, 2023
f5e01f0
Merge branch 'main' into incl-assets
salim-b Oct 18, 2023
75ceecc
Merge branch 'main' into incl-assets
salim-b Mar 12, 2024
fff85e8
Roxygenize
salim-b Mar 12, 2024
f465d9a
Merge branch 'main' into incl-assets
salim-b Mar 15, 2024
0711219
Merge branch 'main' into incl-assets
salim-b Apr 10, 2024
9849096
increase pkg version
salim-b Apr 11, 2024
a9e36bc
Merge branch 'main' into incl-assets
salim-b Apr 18, 2024
a50e1da
Merge remote-tracking branch 'upstream/main' into incl-assets
salim-b Apr 19, 2024
e407ace
Update clipboards.js to v2.0.11
salim-b Apr 19, 2024
e5c9996
Merge commit '1e078c1bdad239c8d8e8945db383f11ee474ffb2'
hadley May 26, 2024
a26473c
Revert unrelated WS changes
hadley May 26, 2024
d28dbc2
Get fontawesome deps from package
hadley May 28, 2024
8d94b63
New external assets file
hadley May 28, 2024
319fb45
Break up into smaller functions and add some tests
hadley May 28, 2024
4cf0d92
Use user cache dir + html dep
hadley May 28, 2024
1bac1bc
Rename to external deps
hadley May 28, 2024
32401dd
Move fontawesome to external-deps
hadley May 28, 2024
447ee95
Update news
hadley May 28, 2024
01ff67b
Fix incorrect merge conflict resolution
hadley May 28, 2024
1a578ae
Restore original function name
hadley May 28, 2024
75216ae
Fix lint
hadley May 28, 2024
fd71d1a
Force consistent sort
hadley May 28, 2024
3ae43e3
Merge branch 'main' into incl-assets
salim-b May 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Imports:
jsonlite,
magrittr,
memoise,
openssl,
purrr,
ragg,
rlang (>= 1.0.0),
Expand All @@ -49,7 +50,6 @@ Suggests:
knitr,
lifecycle,
methods,
openssl,
pkgload (>= 1.0.2),
rsconnect,
rstudioapi,
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# pkgdown (development version)

* All external assets are now directly included in the site by default instead of
salim-b marked this conversation as resolved.
Show resolved Hide resolved
being fetched from external CDNs. The old behaviour can be restored via
setting the YAML option `template.params.external_assets: true` (@salim-b, #2249)

# pkgdown 2.0.7

* Fix topic match selection when there is an unmatched selection followed by a matched selection (@bundfussr, #2234)
Expand Down
41 changes: 28 additions & 13 deletions R/build.R
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
#' The `template` field is mostly used to control the appearance of the site.
#' See `vignette("customise")` for details.
#'
#' There are two other `template` fields that control other aspects of the
#' There are three other `template` fields that control other aspects of the
#' site:
#'
#' * `noindex: true` will suppress indexing of your pages by search engines:
Expand All @@ -152,23 +152,38 @@
#' noindex: true
#' ```
#'
#' * `google_site_verification` allows you to verify your site with google:
#' * `google_site_verification` allows you to verify your site with google:
#'
#' ```yaml
#' template:
#' params:
#' google_site_verification: _nn6ile-a6x6lctOW
#' ```
#' ```yaml
#' template:
#' params:
#' google_site_verification: _nn6ile-a6x6lctOW
#' ```
#'
#' * `trailing_slash_redirect: true` will automatically redirect
#' `your-package-url.com` to `your-package-url.com/`, using a JS script
#' added to the `<head>` of the home page. This is useful in certain
#' redirect scenarios.
#' added to the `<head>` of the home page. This is useful in certain
#' redirect scenarios.
#'
#' ```yaml
#' template:
#' trailing_slash_redirect: true
#' ```
#' ```yaml
#' template:
#' trailing_slash_redirect: true
#' ```
#'
#' * `external_assets: true` will avoid the direct inclusion of certain
#' JS and CSS assets in the built site and instead let them be fetched
#' remotely from content delivery networks (CDNs). Enabling this option
#' results in additional cross-origin requests which might have adverse
#' effects on the privacy of your site's visitors. Your site will also stop
#' to work properly in case the CDN operators should decide to shut down
#' their service or stop hosting the specific versions of the assets pkgdown
#' uses.
#'
#' ```yaml
#' template:
#' params:
#' external_assets: true
#' ```
#'
#' @section Analytics:
#'
Expand Down
108 changes: 102 additions & 6 deletions R/theme.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,125 @@ build_bslib <- function(pkg = ".") {
bs_theme <- bs_theme(pkg)

deps <- bslib::bs_theme_dependencies(bs_theme)
deps <- lapply(deps, htmltools::copyDependencyToDir, file.path(pkg$dst_path, "deps"))
deps <- lapply(deps, htmltools::copyDependencyToDir, path_deps(pkg))
deps <- lapply(deps, htmltools::makeDependencyRelative, pkg$dst_path)

head <- htmltools::renderDependencies(deps, srcType = "file")
write_lines(head, data_deps_path(pkg))

# include additional external assets
use_ext <- isTRUE(pkg$meta$template$params$external_assets)
head <- paste(
head,
paste0(assemble_ext_assets(pkg, use_ext), collapse = "\n"),
sep = "\n"
)

write_lines(head, path_data_deps(pkg))
}

assemble_ext_assets <- function(pkg,
use_ext = FALSE) {
path_assets_yaml <- path_pkgdown(paste0("BS", pkg$bs_version), "assets_external.yaml")
deps_ext <- yaml::read_yaml(path_assets_yaml)

purrr::map_chr(deps_ext, ~ {
# download resource if necessary
if (!use_ext) {
path <- path_deps(pkg, basename(.x$url))
download.file(.x$url, path, quiet = TRUE, mode = "wb")

# check file integrity
sha_size <- as.integer(regmatches(
.x$integrity,
regexpr("(?<=^sha)\\d{3}", .x$integrity, perl = TRUE)
))
if (!(sha_size %in% c(256L, 384L, 512L))) {
cli::cli_abort(paste0(
"Invalid {.field integrity} value set in {.file ",
"{path_assets_yaml}}: {.val {(.x$integrity)}} Allowed are only ",
"SHA-256, SHA-384 and SHA-512."
))
}
con <- file(path, encoding = "UTF-8")
hash <- openssl::base64_encode(openssl::sha2(con, sha_size))
hash_target <- regmatches(
.x$integrity,
regexpr("(?<=^sha\\d{3}-).+", .x$integrity, perl = TRUE)
)

if (hash != hash_target) {
cli::cli_abort(paste0(
"Hash of downloaded {(.x$type)} asset doesn't match {.field ",
"integrity} value of {.val {(.x$integrity)}}. Asset URL is: {.url ",
"{(.x$url)}}"
))
}

# download subresources (webfonts etc.) if necessary
if (isTRUE(.x$has_subresources)) {
file_content <- read_file(path)
pos <- gregexpr("(?<=\\burl\\((?!(data|https?):))[^)?#]*", file_content, perl = TRUE)
urls <- unique(unlist(regmatches(file_content, pos)))
subdirs <- unique(fs::path_dir(urls))
fs::dir_create(
fs::path_norm(fs::path(path_deps(pkg), subdirs)),
recurse = TRUE
)
url_parsed <- xml2::url_parse(.x$url)
url_excl_scheme <- fs::path(url_parsed$server, url_parsed$path)
remote_urls <- paste0(
url_parsed$scheme, "://",
fs::path_norm(fs::path(fs::path_dir(url_excl_scheme), urls))
)
purrr::walk2(
remote_urls,
urls,
~ download.file(.x, fs::path_norm(path_deps(pkg, .y)), quiet = TRUE, mode = "wb")
)
}
.x$url <- fs::path_rel(path, pkg$dst_path)
}

# assemble HTML tag
switch(
.x$type,
"stylesheet" = paste0(
sprintf('<link rel="stylesheet" href="%s"', .x$url),
if (use_ext) sprintf(' integrity="%s" crossorigin="anonymous"', .x$integrity),
' />'
),
"script" = paste0(
sprintf('<script src="%s"', .x$url),
if (use_ext) sprintf(' integrity="%s" crossorigin="anonymous"', .x$integrity),
'></script>'
),
cli::cli_abort(
"Unknown asset type {.val {.x$type}} defined in {.file path_assets_yaml}."
)
)
})
}

data_deps <- function(pkg, depth) {
if (!file.exists(data_deps_path(pkg))) {
if (!file.exists(path_data_deps(pkg))) {
abort("Run pkgdown::init_site() first.")
}

deps_path <- paste0(up_path(depth), "deps")

data_deps <- read_lines(data_deps_path(pkg))
data_deps <- read_lines(path_data_deps(pkg))
data_deps <- gsub('src="deps', sprintf('src="%s', deps_path), data_deps)
data_deps <- gsub('href="deps', sprintf('href="%s', deps_path), data_deps)

paste0(data_deps, collapse = "")
}

data_deps_path <- function(pkg) {
file.path(pkg$dst_path, "deps", "data-deps.txt")
path_deps <- function(pkg, ...) {
file.path(pkg$dst_path, "deps", ...)
}

path_data_deps <- function(pkg) {
file.path(path_deps(pkg), "data-deps.txt")
}

bs_theme <- function(pkg = ".") {
Expand Down
45 changes: 45 additions & 0 deletions inst/BS5/assets_external.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Font Awesome icons
- type: "stylesheet"
url: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css"
integrity: "sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk="
has_subresources: true
- type: "stylesheet"
url: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css"
integrity: "sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw="

# bootstrap-toc
- type: "script"
url: "https://cdn.jsdelivr.net/gh/afeld/[email protected]/dist/bootstrap-toc.min.js"
integrity: "sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo="

# headroom.js
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js"
integrity: "sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0="
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js"
integrity: "sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4="

# clipboard.js
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js"
integrity: "sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI="

# search
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js"
integrity: "sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A=="
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js"
integrity: "sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg=="
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js"
integrity: "sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww=="

# MathJax
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js"
integrity: "sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k="
- type: "script"
url: "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js"
integrity: "sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA="
22 changes: 0 additions & 22 deletions inst/BS5/templates/head.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,6 @@
{{/has_favicons}}

{{{headdeps}}}
<!-- Font Awesome icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous" />

<!-- bootstrap-toc -->
<script src="https://cdn.jsdelivr.net/gh/afeld/[email protected]/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script>

<!-- headroom.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script>

<!-- clipboard.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script>

<!-- search -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script>

<!-- pkgdown -->
<script src="{{#site}}{{root}}{{/site}}pkgdown.js"></script>
Expand Down Expand Up @@ -80,10 +62,6 @@
<meta name="google-site-verification" content="{{{.}}}" />
{{/google_site_verification}}{{/yaml}}

<!-- mathjax -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script>

<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
Expand Down
15 changes: 14 additions & 1 deletion man/build_site.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.