diff --git a/src/command/render/pandoc-dependencies-html.ts b/src/command/render/pandoc-dependencies-html.ts
index ce2ccbc971e..0775b08c75e 100644
--- a/src/command/render/pandoc-dependencies-html.ts
+++ b/src/command/render/pandoc-dependencies-html.ts
@@ -209,6 +209,7 @@ interface HtmlInjector {
href: string,
rel: string,
type?: string,
+ media?: string,
): void;
injectHtml(html: string): void;
@@ -350,7 +351,7 @@ function processHtmlDependencies(
// Link tags
if (dependency.links) {
dependency.links.forEach((link) => {
- injector.injectLink(link.href, link.rel, link.type);
+ injector.injectLink(link.href, link.rel, link.type, link.media);
});
}
@@ -515,6 +516,7 @@ function domDependencyInjector(
href: string,
rel: string,
type?: string,
+ media?: string,
) => {
const linkEl = doc.createElement("link");
linkEl.setAttribute("href", pathWithForwardSlashes(href));
@@ -522,6 +524,9 @@ function domDependencyInjector(
if (type) {
linkEl.setAttribute("type", type);
}
+ if (media) {
+ linkEl.setAttribute("media", media);
+ }
injectEl(linkEl);
};
@@ -575,7 +580,7 @@ function lineDependencyInjector(
` href="<%- href %>" rel="stylesheet" />`,
);
const rawLinkTemplate = ld.template(
- ` type="<%- type %>"<% } %> />`,
+ ` type="<%- type %>"<% } %><% if (media) { %> media="<%- media %>"<% } %> />`,
);
const inject = (content: string, afterBody?: boolean) => {
@@ -625,6 +630,7 @@ function lineDependencyInjector(
href: string,
rel: string,
type?: string,
+ media?: string,
) => {
if (!type) {
type = "";
diff --git a/src/config/types.ts b/src/config/types.ts
index 09daafe951d..71cb95e0c62 100644
--- a/src/config/types.ts
+++ b/src/config/types.ts
@@ -269,7 +269,7 @@ export interface FormatDependency {
version?: string;
external?: boolean;
meta?: Record;
- links?: { rel: string; href: string; type?: string }[];
+ links?: { rel: string; href: string; type?: string; media?: string }[];
scripts?: DependencyHtmlFile[];
stylesheets?: DependencyHtmlFile[];
serviceworkers?: DependencyServiceWorker[];
diff --git a/src/project/types/website/website.ts b/src/project/types/website/website.ts
index 3a924975abf..b3bc5752e53 100644
--- a/src/project/types/website/website.ts
+++ b/src/project/types/website/website.ts
@@ -19,6 +19,7 @@ import {
import { ProjectCreate, ProjectOutputFile, ProjectType } from "../types.ts";
import {
Format,
+ FormatDependency,
FormatExtras,
kDependencies,
kHtmlFinalizers,
@@ -179,25 +180,42 @@ export const websiteProjectType: ProjectType = {
}
// dependency for favicon if we have one
- let favicon = websiteConfigString(kSiteFavicon, project.config);
- if (!favicon) {
+ let faviconLight = websiteConfigString(kSiteFavicon, project.config);
+ let faviconDark = undefined; // until schema upgrade
+ if (!faviconLight) {
const brand = await project.resolveBrand();
if (brand?.light) {
- favicon = getFavicon(brand.light);
+ faviconLight = getFavicon(brand.light);
+ }
+ if (brand?.dark) {
+ faviconDark = getFavicon(brand.dark);
}
}
- if (favicon) {
+ if (faviconLight || faviconDark) {
const offset = projectOffset(project, source);
extras.html = extras.html || {};
extras.html.dependencies = extras.html.dependencies || [];
- extras.html.dependencies.push({
+ const faviconDep: FormatDependency = {
name: kSiteFavicon,
- links: [{
+ links: [],
+ };
+ if (faviconDark) {
+ faviconDep.links!.push({
rel: "icon",
- href: offset + "/" + favicon,
- type: contentType(favicon),
- }],
- });
+ href: offset + "/" + faviconDark,
+ type: contentType(faviconDark),
+ media: "(prefers-color-scheme:dark)",
+ });
+ }
+ if (faviconLight) {
+ faviconDep.links!.push({
+ rel: "icon",
+ href: offset + "/" + faviconLight,
+ type: contentType(faviconLight),
+ media: "(prefers-color-scheme:light)",
+ });
+ }
+ extras.html.dependencies.push(faviconDep);
}
// pagetitle for home page if it has no title
diff --git a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd
index 06ec2006de2..eee7c533986 100644
--- a/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd
+++ b/tests/docs/smoke-all/brand/logo/brand-icon-small-favicon-book/index.qmd
@@ -2,8 +2,8 @@
_quarto:
tests:
html:
- ensureFileRegexMatches:
- - ['']
+ ensureHtmlElements:
+ - ['link[href="./logos/small.png"][rel="icon"][type="image/png"]']
- []
---
diff --git a/tests/docs/smoke-all/brand/logo/favicon/.gitignore b/tests/docs/smoke-all/brand/logo/favicon/.gitignore
new file mode 100644
index 00000000000..075b2542afb
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/favicon/.gitignore
@@ -0,0 +1 @@
+/.quarto/
diff --git a/tests/docs/smoke-all/brand/logo/favicon/_brand.yml b/tests/docs/smoke-all/brand/logo/favicon/_brand.yml
new file mode 100644
index 00000000000..f619452e818
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/favicon/_brand.yml
@@ -0,0 +1,11 @@
+color:
+ background:
+ light: "#fff"
+ dark: "#111"
+ foreground:
+ light: "#111"
+ dark: "#fff"
+logo:
+ small:
+ light: sun-face.png
+ dark: moon-face.png
diff --git a/tests/docs/smoke-all/brand/logo/favicon/_quarto.yml b/tests/docs/smoke-all/brand/logo/favicon/_quarto.yml
new file mode 100644
index 00000000000..e82461507d8
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/favicon/_quarto.yml
@@ -0,0 +1,2 @@
+project:
+ type: website
diff --git a/tests/docs/smoke-all/brand/logo/favicon/index.qmd b/tests/docs/smoke-all/brand/logo/favicon/index.qmd
new file mode 100644
index 00000000000..e37a1f3c45d
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/favicon/index.qmd
@@ -0,0 +1,22 @@
+---
+brand:
+ color:
+ background:
+ light: "#fff"
+ dark: "#111"
+ foreground:
+ light: "#111"
+ dark: "#fff"
+ logo:
+ small:
+ light: sun-face.png
+ dark: moon-face.png
+_quarto:
+ tests:
+ html:
+ ensureHtmlElements:
+ -
+ - 'link[rel="icon"][href="./sun-face.png"][media="(prefers-color-scheme:light)"]'
+ - 'link[rel="icon"][href="./moon-face.png"][media="(prefers-color-scheme:dark)"]'
+ - []
+---
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/_brand.yml b/tests/docs/smoke-all/brand/logo/navbar/favicon/_brand.yml
new file mode 100644
index 00000000000..f619452e818
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/navbar/favicon/_brand.yml
@@ -0,0 +1,11 @@
+color:
+ background:
+ light: "#fff"
+ dark: "#111"
+ foreground:
+ light: "#111"
+ dark: "#fff"
+logo:
+ small:
+ light: sun-face.png
+ dark: moon-face.png
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/_quarto.yml b/tests/docs/smoke-all/brand/logo/navbar/favicon/_quarto.yml
new file mode 100644
index 00000000000..5e981a2e5cb
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/navbar/favicon/_quarto.yml
@@ -0,0 +1,12 @@
+project:
+ type: website
+theme:
+ light: brand
+ dark: [brand, dark-fixups.scss]
+website:
+ navbar:
+ style: "docked"
+ search: true
+ contents:
+ - index.qmd
+ - conclusion.qmd
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/conclusion.qmd b/tests/docs/smoke-all/brand/logo/navbar/favicon/conclusion.qmd
new file mode 100644
index 00000000000..adaa3368882
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/navbar/favicon/conclusion.qmd
@@ -0,0 +1,3 @@
+---
+title: conclusion
+---
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/dark-fixups.scss b/tests/docs/smoke-all/brand/logo/navbar/favicon/dark-fixups.scss
new file mode 100644
index 00000000000..4b1e9601a6a
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/navbar/favicon/dark-fixups.scss
@@ -0,0 +1,9 @@
+/*-- scss:rules --*/
+
+nav.sidebar.sidebar-navigation:not(.rollup) {
+ background-color: #282b30;
+}
+
+nav.navbar {
+ background-color: rgba(13, 108, 251, 25%);
+}
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/index.qmd b/tests/docs/smoke-all/brand/logo/navbar/favicon/index.qmd
new file mode 100644
index 00000000000..715790258ac
--- /dev/null
+++ b/tests/docs/smoke-all/brand/logo/navbar/favicon/index.qmd
@@ -0,0 +1,15 @@
+---
+title: intro
+_quarto:
+ tests:
+ html:
+ ensureHtmlElements:
+ -
+ # favicon
+ - 'link[rel="icon"][href="./sun-face.png"][media="(prefers-color-scheme:light)"]'
+ - 'link[rel="icon"][href="./moon-face.png"][media="(prefers-color-scheme:dark)"]'
+ # navbar
+ - 'img[class*="light-content"][src="./sun-face.png"][alt=""]'
+ - 'img[class*="dark-content"][src="./moon-face.png"][alt=""]'
+ - []
+---
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/moon-face.png b/tests/docs/smoke-all/brand/logo/navbar/favicon/moon-face.png
new file mode 100644
index 00000000000..ee057e972b9
Binary files /dev/null and b/tests/docs/smoke-all/brand/logo/navbar/favicon/moon-face.png differ
diff --git a/tests/docs/smoke-all/brand/logo/navbar/favicon/sun-face.png b/tests/docs/smoke-all/brand/logo/navbar/favicon/sun-face.png
new file mode 100644
index 00000000000..62a734cb8db
Binary files /dev/null and b/tests/docs/smoke-all/brand/logo/navbar/favicon/sun-face.png differ
diff --git a/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd b/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd
index f20e6354104..25b8f343c84 100644
--- a/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd
+++ b/tests/docs/smoke-all/brand/logo/website-favicon/index.qmd
@@ -3,8 +3,8 @@ title: "test-brand-favicon"
_quarto:
tests:
html:
- ensureFileRegexMatches:
- - ['']
+ ensureHtmlElements:
+ - ['link[href="./logos/small.png"][rel="icon"][type="image/png"]']
- []
---