summaryrefslogtreecommitdiffstats
path: root/static
diff options
context:
space:
mode:
Diffstat (limited to 'static')
-rw-r--r--static/reveal-unfold.js127
-rw-r--r--static/unfold.js86
2 files changed, 127 insertions, 86 deletions
diff --git a/static/reveal-unfold.js b/static/reveal-unfold.js
new file mode 100644
index 0000000..931b058
--- /dev/null
+++ b/static/reveal-unfold.js
@@ -0,0 +1,127 @@
+window.Unfold = {
+ activate: async function (opts) {
+ const separator = opts.separator || "hr";
+ const content = opts.content || "main";
+ const theme = opts.theme || "moon";
+ const revealCdn = opts.revealCdn || "https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.6.0";
+ const revealPlugins = opts.revealPlugins || []; // e.g. ["notes"]
+ const revealOptions = opts.revealOptions || {};
+ const revealCss = opts.revealCss || "";
+
+ const contentElem = document.querySelector(content);
+ if (!contentElem) {
+ console.error(`Unfold: content element not found`);
+ return;
+ }
+
+ const nodes = [...contentElem.childNodes];
+
+ const newBody = document.createElement("body");
+ newBody.setAttribute("class", "reveal");
+ const slides = document.createElement("div");
+ slides.setAttribute("class", "slides");
+ newBody.appendChild(slides);
+
+ const newHead = document.createElement("head");
+
+ const titleSlide = document.createElement("section");
+ const titleH1 = document.createElement("h1");
+ titleH1.textContent = document.title;
+ titleSlide.appendChild(titleH1);
+ slides.appendChild(titleSlide);
+
+ let currentSlide = document.createElement("section");
+ for (const node of nodes) {
+ if (node.hasAttribute && node.hasAttribute("data-unfold-hidden")) {
+ continue;
+ }
+
+ if (node.tagName?.toLowerCase() === separator.toLowerCase()) {
+ slides.appendChild(currentSlide);
+ currentSlide = document.createElement("section");
+ } else if (node.matches && node.matches("figure:has(img)")) {
+ const figcaption = node.querySelector("figcaption");
+ if (figcaption) {
+ const small = document.createElement("small");
+ small.textContent = figcaption.textContent;
+ small.style.display = "block";
+ currentSlide.appendChild(small);
+ }
+
+ const img = node.querySelector("img");
+ img.classList.add("r-stretch");
+ currentSlide.appendChild(img);
+ } else {
+ currentSlide.appendChild(node);
+ }
+ }
+ slides.appendChild(currentSlide);
+
+ const revealCssTag = document.createElement("link");
+ revealCssTag.rel = "stylesheet";
+ revealCssTag.href = `${revealCdn}/css/reveal.min.css`;
+ newHead.appendChild(revealCssTag);
+
+ const revealThemeCssTag = document.createElement("link");
+ revealThemeCssTag.rel = "stylesheet";
+ revealThemeCssTag.href = `${revealCdn}/css/theme/${theme}.css`;
+ newHead.appendChild(revealThemeCssTag);
+
+ for (const plugin of revealPlugins) {
+ const pluginJsTag = document.createElement("script");
+ pluginJsTag.src = `${revealCdn}/plugin/${plugin}/${plugin}.js`;
+ newHead.appendChild(pluginJsTag);
+ }
+
+ const revealJsTag = document.createElement("script");
+ revealJsTag.src = `${revealCdn}/js/reveal.min.js`;
+ revealJsTag.onload = () => {
+ // evaluate plugins in a dynamic scope in order to access plugins etc.
+ const evaledPlugins = revealPlugins.map(p => {
+ const symbolName = `Reveal${p.charAt(0).toUpperCase() + p.slice(1)}`;
+ return eval(symbolName);
+ });
+ // activate Reveal slideshow
+ const reveal = { ...revealOptions, plugins: evaledPlugins };
+ console.log(reveal);
+ Reveal.initialize(reveal);
+ // fix vertical positioning issue that happens often
+ setTimeout(() => Reveal.sync(), 100);
+ };
+ newHead.appendChild(revealJsTag);
+
+ const revealCustomCssTag = document.createElement("style");
+ revealCustomCssTag.innerHTML = revealCss;
+ newHead.appendChild(revealCustomCssTag);
+
+ document.head.replaceWith(newHead);
+ document.body.replaceWith(newBody);
+ },
+ enable: function (opts = {}) {
+ // if the URL has ?unfold=1, activate the slideshow
+ const qp = new URLSearchParams(location.search);
+ if (qp.get("unfold") === "1") {
+ void Unfold.activate(opts)
+ }
+
+ // listen for clicks on links with ?unfold=1
+ // to activate the slideshow without a page reload for a smoother experience
+ const unfoldLinks = document.querySelectorAll("a[href*='unfold=1']");
+ for (const link of unfoldLinks) {
+ link.addEventListener("click", function (e) {
+ e.preventDefault();
+ history.pushState({}, "", this.href);
+ void Unfold.activate(opts);
+ });
+ }
+ }
+}
+
+const previousOnPopState = window.onpopstate;
+window.onpopstate = function() {
+ if (typeof previousOnPopState === "function") {
+ previousOnPopState();
+ }
+ location.reload();
+};
+
diff --git a/static/unfold.js b/static/unfold.js
deleted file mode 100644
index e27dbb5..0000000
--- a/static/unfold.js
+++ /dev/null
@@ -1,86 +0,0 @@
-window.Unfold = {
- activate: function (opts) {
- const separator = opts.separator || "hr";
- const content = opts.content || "main";
- const theme = opts.theme || "moon";
- const revealCdn = opts.revealCdn || "https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.6.0";
-
- const contentElem = document.querySelector(content);
- if (!contentElem) {
- console.error(`Unfold: content element not found`);
- return;
- }
-
- const nodes = [...contentElem.childNodes];
-
- const newBody = document.createElement("body");
- newBody.setAttribute("class", "reveal");
- const slides = document.createElement("div");
- slides.setAttribute("class", "slides");
- newBody.appendChild(slides);
-
- const newHead = document.createElement("head");
-
- let currentSlide = document.createElement("section");
- for (const node of nodes) {
- if (node.hasAttribute && node.hasAttribute("data-unfold-hidden")) {
- continue;
- }
-
- if (node.tagName?.toLowerCase() === separator.toLowerCase()) {
- slides.appendChild(currentSlide);
- currentSlide = document.createElement("section");
- } else {
- currentSlide.appendChild(node);
- }
- }
- slides.appendChild(currentSlide);
-
- const revealCssTag = document.createElement("link");
- revealCssTag.rel = "stylesheet";
- revealCssTag.href = `${revealCdn}/css/reveal.min.css`;
- newHead.appendChild(revealCssTag);
-
- const revealThemeCssTag = document.createElement("link");
- revealThemeCssTag.rel = "stylesheet";
- revealThemeCssTag.href = `${revealCdn}/css/theme/${theme}.css`;
- newHead.appendChild(revealThemeCssTag);
-
- const revealJsTag = document.createElement("script");
- revealJsTag.src = `${revealCdn}/js/reveal.min.js`;
- revealJsTag.onload = () => {
- // activate Reveal slideshow
- Reveal.initialize();
- // fix vertical positioning issue that happens often
- setTimeout(() => Reveal.sync(), 100);
- };
- newHead.appendChild(revealJsTag);
-
- document.head.replaceWith(newHead);
- document.body.replaceWith(newBody);
- },
- bind: function (selector, opts = {}) {
- const elem = document.querySelector(selector);
- elem.addEventListener("click", () => {
- Unfold.activate(opts)
- // enable back button by hooking into History API
- const qp = new URLSearchParams(location.search);
- qp.set("unfold", "1");
- history.pushState({}, "", `${location.protocol}//${location.host}${location.pathname}?${qp.toString()}`);
- })
-
- const qp = new URLSearchParams(location.search);
- if (qp.get("unfold") === "1") {
- Unfold.activate(opts)
- }
- }
-}
-
-const previousOnPopState = window.onpopstate;
-window.onpopstate = function() {
- if (typeof previousOnPopState === "function") {
- previousOnPopState();
- }
- location.reload();
-};
-