Skip to content

Commit 92e4213

Browse files
authored
Merge pull request #10695 from quarto-dev/revealjs/clean-footer-handling
2 parents c96fd24 + da6cb8d commit 92e4213

File tree

11 files changed

+100
-43
lines changed

11 files changed

+100
-43
lines changed

news/changelog-1.6.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ All changes included in 1.6:
2525
- Remove wrong `sourceMappingUrl` entry in SASS built css.
2626
- ([#7715](https://github.com/quarto-dev/quarto-cli/issues/7715)): Revealjs don't support anymore special Pandoc syntax making BulletList in Blockquotes become incremental list. This was confusing and unexpected behavior. Supported syntax for incremental list is documented at <https://quarto.org/docs/presentations/revealjs/#incremental-lists>.
2727
- ([#9742](https://github.com/quarto-dev/quarto-cli/issues/9742)): Links to cross-referenced images correctly works.
28+
- ([#9558](https://github.com/quarto-dev/quarto-cli/issues/9558)): To prevent default footer to show on slide, set `footer='false'` attribute on the slide header, e.g. `## Slide with no footer {footer='false'}`
2829
- ([#6012](https://github.com/quarto-dev/quarto-cli/issues/6012)): Add styling for `kbd` element in Revealjs slides.
2930

3031
## `typst` Format

src/format/reveal/format-reveal.ts

+8-25
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ export function revealjsFormat() {
320320

321321
function revealMarkdownAfterBody(format: Format) {
322322
const lines: string[] = [];
323-
lines.push("::: {.quarto-auto-generated-content}\n");
323+
lines.push("::: {.quarto-auto-generated-content style='display: none;'}\n");
324324
if (format.metadata[kSlideLogo]) {
325325
lines.push(
326326
`<img src="${format.metadata[kSlideLogo]}" class="slide-logo" />`,
@@ -396,30 +396,13 @@ const handleHashTypeNumber = (
396396
};
397397

398398
const handleAutoGeneratedContent = (doc: Document) => {
399-
// bugfix for #6800
400-
// if slides have content that was added by quarto then move that to the parent node
401-
for (const slide of doc.querySelectorAll("section.slide")) {
402-
const slideContentFromQuarto = (slide as Element).querySelector(
403-
".quarto-auto-generated-content",
404-
);
405-
if (
406-
slideContentFromQuarto &&
407-
(slide as Element).getAttribute("data-visibility") === "hidden"
408-
) {
409-
if (slideContentFromQuarto.childElementCount === 0) {
410-
slideContentFromQuarto.remove();
411-
} else {
412-
for (const otherSlide of doc.querySelectorAll("section.slide")) {
413-
if (
414-
(otherSlide as Element).getAttribute("data-visibility") !==
415-
"hidden"
416-
) {
417-
otherSlide.appendChild(slideContentFromQuarto);
418-
break;
419-
}
420-
}
421-
}
422-
}
399+
// Move quarto auto-generated content outside of slides and hide it
400+
// Content is moved with appendChild in quarto-support plugin
401+
const slideContentFromQuarto = doc.querySelector(
402+
".quarto-auto-generated-content",
403+
);
404+
if (slideContentFromQuarto) {
405+
doc.querySelector("div.reveal")?.appendChild(slideContentFromQuarto);
423406
}
424407
};
425408

src/resources/formats/revealjs/plugins/support/support.js

+41-15
Original file line numberDiff line numberDiff line change
@@ -136,34 +136,51 @@ window.QuartoSupport = function () {
136136
})
137137
}
138138

139-
// add footer text
140-
function addFooter(deck) {
139+
// add footer text
140+
function addFooter(deck) {
141141
const revealParent = deck.getRevealElement();
142142
const defaultFooterDiv = document.querySelector(".footer-default");
143+
// Set per slide footer if any defined,
144+
// or show default unless data-footer="false" for no footer on this slide
145+
const setSlideFooter = (ev, defaultFooterDiv) => {
146+
const currentSlideFooter = ev.currentSlide.querySelector(".footer");
147+
const onDarkBackground = deck.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-dark-background')
148+
const onLightBackground = deck.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-light-background')
149+
if (currentSlideFooter) {
150+
defaultFooterDiv.style.display = "none";
151+
const slideFooter = currentSlideFooter.cloneNode(true);
152+
handleLinkClickEvents(deck, slideFooter);
153+
deck.getRevealElement().appendChild(slideFooter);
154+
toggleBackgroundTheme(slideFooter, onDarkBackground, onLightBackground)
155+
} else if (ev.currentSlide.getAttribute("data-footer") === "false") {
156+
defaultFooterDiv.style.display = "none";
157+
} else {
158+
defaultFooterDiv.style.display = "block";
159+
toggleBackgroundTheme(defaultFooterDiv, onDarkBackground, onLightBackground)
160+
}
161+
}
143162
if (defaultFooterDiv) {
163+
// move default footnote to the div.reveal element
144164
revealParent.appendChild(defaultFooterDiv);
145165
handleLinkClickEvents(deck, defaultFooterDiv);
166+
146167
if (!isPrintView()) {
168+
// Ready even is needed so that footer customization applies on first loaded slide
169+
deck.on('ready', (ev) => {
170+
// Set footer (custom, default or none)
171+
setSlideFooter(ev, defaultFooterDiv)
172+
});
173+
// Any new navigated new slide will get the custom footnote check
147174
deck.on("slidechanged", function (ev) {
175+
// Remove presentation footer defined by previous slide
148176
const prevSlideFooter = document.querySelector(
149177
".reveal > .footer:not(.footer-default)"
150178
);
151179
if (prevSlideFooter) {
152180
prevSlideFooter.remove();
153181
}
154-
const currentSlideFooter = ev.currentSlide.querySelector(".footer");
155-
const onDarkBackground = Reveal.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-dark-background')
156-
const onLightBackground = Reveal.getSlideBackground(ev.indexh, ev.indexv).classList.contains('has-light-background')
157-
if (currentSlideFooter) {
158-
defaultFooterDiv.style.display = "none";
159-
const slideFooter = currentSlideFooter.cloneNode(true);
160-
handleLinkClickEvents(deck, slideFooter);
161-
deck.getRevealElement().appendChild(slideFooter);
162-
toggleBackgroundTheme(slideFooter, onDarkBackground, onLightBackground)
163-
} else {
164-
defaultFooterDiv.style.display = "block";
165-
toggleBackgroundTheme(defaultFooterDiv, onDarkBackground, onLightBackground)
166-
}
182+
// Set new one (custom, default or none)
183+
setSlideFooter(ev, defaultFooterDiv)
167184
});
168185
}
169186
}
@@ -318,6 +335,13 @@ window.QuartoSupport = function () {
318335
}
319336
}
320337

338+
function cleanEmptyAutpGeneratedContent(deck) {
339+
const div = document.querySelector('div.quarto-auto-generated-content')
340+
if (div.textContent.trim() === '') {
341+
div.remove()
342+
}
343+
}
344+
321345
return {
322346
id: "quarto-support",
323347
init: function (deck) {
@@ -333,6 +357,8 @@ window.QuartoSupport = function () {
333357
handleSlideChanges(deck);
334358
workaroundMermaidDistance(deck);
335359
handleWhiteSpaceInColumns(deck);
360+
// should stay last
361+
cleanEmptyAutpGeneratedContent(deck);
336362
},
337363
};
338364
};

tests/docs/playwright/ojs/test-ojs-echo-false-codetools-dropdown-2.qmd

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
title: Reproing a bug on codetools dropdown
3+
format: html
34
code-tools: true
45
---
56

tests/docs/playwright/ojs/test-ojs-echo-false-codetools-dropdown.qmd

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
title: Reproing a bug on codetools dropdown
3+
format: html
34
code-tools: true
45
---
56

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.quarto/
2+
*.html
3+
*_files/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
format:
3+
revealjs:
4+
logo: quarto.png
5+
footer: "Footer text"
6+
---
7+
8+
## Slide 1
9+
10+
Footer is shown on all slides
11+
12+
## Slide 2
13+
14+
Like logo
15+
16+
## Slide 3 {footer=false}
17+
18+
unless `{footer=false}` is set, which will remove the footer
19+
20+
## Slide 4
21+
22+
Custom footer can also be set
23+
24+
::: {.footer}
25+
A different footer
26+
:::
11.5 KB
Loading

tests/docs/smoke-all/2023/09/11/6800.qmd

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ title: "test"
33
format:
44
revealjs:
55
footer: "hello world"
6-
keep-md: true
76
_quarto:
87
tests:
98
revealjs:
109
ensureHtmlElements:
11-
- ["div.footer"]
10+
- ["div.footer", "div.footer-default"]
1211
---
1312

1413
## Quarto

tests/integration/playwright-tests.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ for (const { path: fileName } of globOutput) {
3939
// mediabag inspection if we don't wait all renders
4040
// individually. This is very slow..
4141
await execProcess({
42-
cmd: [quartoDevCmd(), "render", input, "--to", "html"],
42+
cmd: [quartoDevCmd(), "render", input],
4343
});
4444
fileNames.push(fileName);
4545
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test('logo and footer are correctly shown', async ({ page }) => {
4+
await page.goto('./revealjs/logo-footer.html#/slide-1');
5+
await expect(page.locator('.reveal > .footer.footer-default')).toContainText('Footer text');
6+
await expect(page.locator('.slide-logo')).toHaveAttribute("src", "quarto.png");
7+
await page.keyboard.press('ArrowRight'); // Next slide
8+
await expect(page.locator('.reveal > .footer.footer-default')).toContainText('Footer text');
9+
await expect(page.locator('.slide-logo')).toHaveAttribute("src", "quarto.png");
10+
await page.keyboard.press('ArrowRight'); // Next slide
11+
await expect(page.locator('.reveal > .footer')).toBeHidden();
12+
await expect(page.locator('.slide-logo')).toHaveAttribute("src", "quarto.png");
13+
await page.keyboard.press('ArrowRight'); // Next slide
14+
await expect(page.locator('.reveal > .footer.footer-default')).toBeHidden();
15+
await expect(page.locator('.reveal > .footer:not(.footer-default)')).toContainText('A different footer');
16+
await expect(page.locator('.slide-logo')).toHaveAttribute("src", "quarto.png");
17+
});

0 commit comments

Comments
 (0)