From 80d3564b61f083ae07c8d4c918fd589a2e2e2e5e Mon Sep 17 00:00:00 2001 From: Erin Schnabel Date: Thu, 19 Dec 2024 12:05:44 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20biome:=20plugin=20and=20reveal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugin/reveal.js-elapsed-time-bar/LICENSE | 2 +- .../reveal.js-elapsed-time-bar/README.md | 10 +- .../elapsed-time-bar.js | 43 ++-- src/reveal/markdown.js | 2 +- src/reveal/revealExporter.ts | 44 ++-- src/reveal/revealPreviewView.ts | 104 ++++----- src/reveal/revealRenderer.ts | 61 +++--- src/reveal/revealServer.ts | 202 +++++++++--------- 8 files changed, 234 insertions(+), 234 deletions(-) diff --git a/src/plugin/reveal.js-elapsed-time-bar/LICENSE b/src/plugin/reveal.js-elapsed-time-bar/LICENSE index 465570b..fa020fc 100644 --- a/src/plugin/reveal.js-elapsed-time-bar/LICENSE +++ b/src/plugin/reveal.js-elapsed-time-bar/LICENSE @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/src/plugin/reveal.js-elapsed-time-bar/README.md b/src/plugin/reveal.js-elapsed-time-bar/README.md index c1993bf..97537ee 100644 --- a/src/plugin/reveal.js-elapsed-time-bar/README.md +++ b/src/plugin/reveal.js-elapsed-time-bar/README.md @@ -7,7 +7,7 @@ Keeping to time in presentations! [Check out the live demo](https://tkrkt.github.com/reveal.js-elapsed-time-bar/) -## Installation +## Installation Copy the folder ``plugin/elapsed-time-bar`` into plugin folder of your reveal.js project. @@ -28,7 +28,6 @@ Reveal.initialize({ }); ``` - ## Configurations ```js @@ -49,7 +48,6 @@ Reveal.initialize({ }); ``` - ## API You can use APIs from global ``ElapsedTimeBar`` object. @@ -63,7 +61,6 @@ You can use APIs from global ``ElapsedTimeBar`` object. |pause()|pause timer| |resume()|resume timer| - ## Keyboard binding example ```js @@ -83,7 +80,6 @@ Reveal.initialize({ }); ``` +## License -# License - -MIT \ No newline at end of file +MIT diff --git a/src/plugin/reveal.js-elapsed-time-bar/elapsed-time-bar.js b/src/plugin/reveal.js-elapsed-time-bar/elapsed-time-bar.js index 104d03a..9a4880a 100644 --- a/src/plugin/reveal.js-elapsed-time-bar/elapsed-time-bar.js +++ b/src/plugin/reveal.js-elapsed-time-bar/elapsed-time-bar.js @@ -1,24 +1,19 @@ window.ElapsedTimeBar = window.ElapsedTimeBar || { id: 'ElapsedTimeBar', - start: function(allottedTime, elapsedTime) { + start: (allottedTime, elapsedTime) => { ElapsedTimeBar.start(allottedTime, elapsedTime); }, - reset: function() { + reset: () => { ElapsedTimeBar.reset(); }, - pause: function() { + pause: () => { ElapsedTimeBar.pause(); }, - resume: function() { + resume: () => { ElapsedTimeBar.resume(); } }; -if (Reveal.isReady()) { - ElapsedTimeBar.handleReady(); -} else { - Reveal.addEventListener('ready', () => ElapsedTimeBar.handleReady()); -} const ElapsedTimeBar = { id: 'ElapsedTimeBar', @@ -56,13 +51,15 @@ const ElapsedTimeBar = { let barHeight; const pageProgressContainer = document.querySelector('.progress'); if (config.progressBarHeight) { - barHeight = parseInt(config.progressBarHeight, 10) + 'px'; + barHeight = `${Number.parseInt(config.progressBarHeight, 10)}px`; // override height of page-progress container - pageProgressContainer && (pageProgressContainer.style.height = barHeight); + if (pageProgressContainer) { + pageProgressContainer.style.height = barHeight; + } } else if (config.progress && pageProgressContainer) { // get height from page-progress container - barHeight = pageProgressContainer.getBoundingClientRect().height + 'px'; + barHeight = `${pageProgressContainer.getBoundingClientRect().height}px`; } else { // default barHeight = '3px'; @@ -71,25 +68,27 @@ const ElapsedTimeBar = { // create container of time-progress const timeProgressContainer = document.createElement('div'); timeProgressContainer.classList.add('progress'); - Object.entries({ + for (const [k, v] of Object.entries({ display: 'block', position: 'fixed', bottom: config.progress ? barHeight : 0, width: '100%', height: barHeight - }).forEach(([k, v]) => { + })) { timeProgressContainer.style[k] = v; - }); + } + document.querySelector('.reveal').appendChild(timeProgressContainer); // create content of time-progress this.timeProgressBar = document.createElement('div'); - Object.entries({ + for (const [k, v] of Object.entries({ height: '100%', willChange: 'width' - }).forEach(([k, v]) => { + })) { this.timeProgressBar.style[k] = v; - }); + } + timeProgressContainer.appendChild(this.timeProgressBar); // start timer @@ -107,7 +106,7 @@ const ElapsedTimeBar = { this.timeProgressBar.style.width = '100%'; this.isFinished = true; } else { - this.timeProgressBar.style.width = elapsedTime / this.allottedTime * 100 + '%'; + this.timeProgressBar.style.width = `${elapsedTime / this.allottedTime * 100}%`; requestAnimationFrame(this.loop.bind(this)); } }, @@ -160,3 +159,9 @@ const ElapsedTimeBar = { this.loop(); } }; + +if (Reveal.isReady()) { + ElapsedTimeBar.handleReady(); +} else { + Reveal.addEventListener('ready', () => ElapsedTimeBar.handleReady()); +} diff --git a/src/reveal/markdown.js b/src/reveal/markdown.js index daa190d..bc6eb3e 100644 --- a/src/reveal/markdown.js +++ b/src/reveal/markdown.js @@ -2,7 +2,7 @@ export const md = (() => { // Hack required since https://github.com/hakimel/reveal.js/commit/d780352b7f78e16635ce9fabf2dbb53639610f18 // eslint-disable-next-line no-undef global.Reveal = { - registerPlugin: () => {} + registerPlugin: () => { } }; // eslint-disable-next-line no-undef return require('reveal.js/plugin/markdown/markdown')(); diff --git a/src/reveal/revealExporter.ts b/src/reveal/revealExporter.ts index 22d76f4..159b217 100644 --- a/src/reveal/revealExporter.ts +++ b/src/reveal/revealExporter.ts @@ -4,10 +4,10 @@ import { writeFile, existsSync, outputFileSync, -} from 'fs-extra'; -import path from 'path'; -import { ObsidianUtils } from '../obsidian/obsidianUtils'; -import { Platform } from 'obsidian'; +} from "fs-extra"; +import path from "node:path"; +import type { ObsidianUtils } from "../obsidian/obsidianUtils"; +import { Platform } from "obsidian"; export class RevealExporter { private pluginDirectory: string; @@ -22,42 +22,42 @@ export class RevealExporter { public async export(filePath: string, html: string, imgList: string[]) { const ext = path.extname(filePath); - const folderName = path.basename(filePath).replaceAll(ext, ''); + const folderName = path.basename(filePath).replaceAll(ext, ""); const folderDir = path.join(this.exportDirectory, folderName); const sourceDir = path.dirname(filePath); - const vaultDir = this.vaultDirectory.replace(/\/$/, ''); + const vaultDir = this.vaultDirectory.replace(/\/$/, ""); - console.debug('export', sourceDir, vaultDir, folderDir); + console.debug("export", sourceDir, vaultDir, folderDir); await emptyDir(folderDir); - await writeFile(path.join(folderDir, 'index.html'), html); + await writeFile(path.join(folderDir, "index.html"), html); // TODO: let's track what css, scripts, and plugins are actually used // rather than copying everything. await copy( - path.join(this.pluginDirectory, 'css'), - path.join(folderDir, 'css'), + path.join(this.pluginDirectory, "css"), + path.join(folderDir, "css"), ); await copy( - path.join(this.pluginDirectory, 'dist'), - path.join(folderDir, 'dist'), + path.join(this.pluginDirectory, "dist"), + path.join(folderDir, "dist"), ); await copy( - path.join(this.pluginDirectory, 'plugin'), - path.join(folderDir, 'plugin'), + path.join(this.pluginDirectory, "plugin"), + path.join(folderDir, "plugin"), ); for (const img of imgList) { - console.log('export', img); - if (img.startsWith('http')) { + console.log("export", img); + if (img.startsWith("http")) { continue; } - if (img.startsWith('/local-file-url')) { + if (img.startsWith("/local-file-url")) { const urlpath = img.replace( - '/local-file-url', + "/local-file-url", Platform.resourcePathPrefix, ); - const result = await fetch(urlpath).catch(error => { + const result = await fetch(urlpath).catch((error) => { return new Response(null, { status: 404, statusText: error.messge, @@ -73,7 +73,7 @@ export class RevealExporter { ); } else { console.info( - 'open a bug to handle this kind of response. Include this message', + "open a bug to handle this kind of response. Include this message", result, ); } @@ -89,10 +89,10 @@ export class RevealExporter { imgPath = relative; } } - console.debug('img', img, imgPath, sourceDir != vaultDir); + console.debug("img", img, imgPath, sourceDir !== vaultDir); await copy(imgPath, path.join(folderDir, img)); } - window.open('file://' + folderDir); + window.open(`file://${folderDir}`); } } diff --git a/src/reveal/revealPreviewView.ts b/src/reveal/revealPreviewView.ts index 22035fd..f429fcb 100644 --- a/src/reveal/revealPreviewView.ts +++ b/src/reveal/revealPreviewView.ts @@ -1,11 +1,16 @@ -import { ItemView, MarkdownView, Menu, WorkspaceLeaf } from 'obsidian'; -import { YamlParser } from '../yaml/yamlParser'; -import { SlidesExtendedSettings, Options } from '../@types'; +import { + ItemView, + MarkdownView, + type Menu, + type WorkspaceLeaf, +} from "obsidian"; +import { YamlParser } from "../yaml/yamlParser"; +import type { SlidesExtendedSettings, Options } from "../@types"; -export const REVEAL_PREVIEW_VIEW = 'reveal-preview-view'; +export const REVEAL_PREVIEW_VIEW = "reveal-preview-view"; export class RevealPreviewView extends ItemView { - url = 'about:blank'; + url = "about:blank"; private home: URL; private onCloseListener: () => void; @@ -23,60 +28,60 @@ export class RevealPreviewView extends ItemView { this.yaml = new YamlParser(settings); this.onCloseListener = onCloseListener; - this.addAction('globe', 'Open in browser', () => { + this.addAction("globe", "Open in browser", () => { window.open(home); }); - this.addAction('grid', 'Show grid', () => { + this.addAction("grid", "Show grid", () => { settings.showGrid = !settings.showGrid; this.reloadIframe(); }); - this.addAction('refresh', 'Refresh slides', () => { + this.addAction("refresh", "Refresh slides", () => { this.reloadIframe(); }); - if (settings.paneMode === 'sidebar') { - this.addAction('monitor-x', 'Close preview', () => { + if (settings.paneMode === "sidebar") { + this.addAction("monitor-x", "Close preview", () => { this.leaf.detach(); }); } - window.addEventListener('message', this.onMessage.bind(this)); + window.addEventListener("message", this.onMessage.bind(this)); } onPaneMenu( menu: Menu, - source: 'more-options' | 'tab-header' | string, + source: "more-options" | "tab-header" | string, ): void { super.onPaneMenu(menu, source); - if (source != 'more-options') { + if (source !== "more-options") { return; } menu.addSeparator(); - menu.addItem(item => { - item.setIcon('document') - .setTitle('Print presentation') + menu.addItem((item) => { + item.setIcon("document") + .setTitle("Print presentation") .onClick(() => { - window.open(this.home.toString() + '?print-pdf'); + window.open(`${this.home.toString()}?print-pdf`); }); }); - menu.addItem(item => { - item.setIcon('install') - .setTitle('Export as html') + menu.addItem((item) => { + item.setIcon("install") + .setTitle("Export as html") .onClick(() => { const url = new URL(this.url); - url.searchParams.append('export', 'true'); + url.searchParams.append("export", "true"); this.setUrl(url.toString()); }); }); } onMessage(msg: MessageEvent) { - if (msg.data.includes('?export')) { - this.setUrl(msg.data.split('?')[0]); + if (msg.data.includes("?export")) { + this.setUrl(msg.data.split("?")[0]); return; } @@ -84,10 +89,10 @@ export class RevealPreviewView extends ItemView { const url = new URL(msg.data); let filename = decodeURI(url.pathname); - filename = filename.substring(filename.lastIndexOf('/') + 1); + filename = filename.substring(filename.lastIndexOf("/") + 1); const view = this.app.workspace.getActiveViewOfType(MarkdownView); - if (view && view.file.name.includes(filename)) { + if (view?.file.name.includes(filename)) { const line = this.getTargetLine(url, view.data); view.editor.setCursor(view.editor.lastLine()); view.editor.setCursor({ line: line, ch: 0 }); @@ -97,7 +102,7 @@ export class RevealPreviewView extends ItemView { onLineChanged(line: number) { const view = this.app.workspace.getActiveViewOfType(MarkdownView); const viewContent = this.containerEl.children[1]; - const iframe = viewContent.getElementsByTagName('iframe')[0]; + const iframe = viewContent.getElementsByTagName("iframe")[0]; if (view && iframe) { const [x, y] = this.getTargetSlide(line, view.data); @@ -128,15 +133,14 @@ export class RevealPreviewView extends ItemView { } if (resultKey) { - const keys = resultKey.split(','); + const keys = resultKey.split(","); return [Number.parseInt(keys[0]), Number.parseInt(keys[1])]; - } else { - return [0, 0]; } + return [0, 0]; } getTargetLine(url: URL, source: string): number { - const pageString = url.href.substring(url.href.lastIndexOf('#')); + const pageString = url.href.substring(url.href.lastIndexOf("#")); const [, h, v] = this.urlRegex.exec(pageString); const { yamlOptions, markdown } = this.yaml.parseYamlFrontMatter(source); @@ -145,10 +149,10 @@ export class RevealPreviewView extends ItemView { const offset = source.substring(0, yamlLength).split(/^/gm).length; const slides = this.getSlideLines(markdown, separators); - const hX = parseInt(h) || 0; - const vX = parseInt(v) || 0; + const hX = Number.parseInt(h) || 0; + const vX = Number.parseInt(v) || 0; - return slides.get([hX, vX].join(',')) + offset; + return slides.get([hX, vX].join(",")) + offset; } getSlideLines(source: string, separators: Options) { @@ -156,7 +160,7 @@ export class RevealPreviewView extends ItemView { const l = this.getIdxOfRegex(/^/gm, source); const h = this.getIdxOfRegex( - RegExp(separators.separator, 'gm'), + RegExp(separators.separator, "gm"), source, ); @@ -164,14 +168,14 @@ export class RevealPreviewView extends ItemView { for (let index = 0; index < l.length; index++) { const line = l[index]; if (line > item) { - store.set(index, 'h'); + store.set(index, "h"); break; } } } const v = this.getIdxOfRegex( - RegExp(separators.verticalSeparator, 'gm'), + RegExp(separators.verticalSeparator, "gm"), source, ); @@ -179,13 +183,13 @@ export class RevealPreviewView extends ItemView { for (let index = 0; index < l.length; index++) { const line = l[index]; if (line > item) { - store.set(index, 'v'); + store.set(index, "v"); break; } } } - store.set(0, 'h'); + store.set(0, "h"); store = new Map( [...store].sort((a, b) => { @@ -198,23 +202,23 @@ export class RevealPreviewView extends ItemView { let hV = -1; let vV = 0; for (const [key, value] of store.entries()) { - if (value == 'h') { + if (value === "h") { hV++; vV = 0; } - if (value == 'v') { + if (value === "v") { vV++; } - result.set([hV, vV].join(','), key); + result.set([hV, vV].join(","), key); } return result; } getIdxOfRegex(regex: RegExp, source: string): number[] { const idxs: Array = new Array(); - let m; + let m: RegExpExecArray | null; do { m = regex.exec(source); if (m) { @@ -232,11 +236,11 @@ export class RevealPreviewView extends ItemView { } getDisplayText() { - return 'Slide preview'; + return "Slide preview"; } getIcon() { - return 'slides'; + return "slides"; } setUrl(url: string, rerender = true) { @@ -251,26 +255,26 @@ export class RevealPreviewView extends ItemView { } async onClose() { - window.removeEventListener('message', this.onMessage); + window.removeEventListener("message", this.onMessage); this.onCloseListener(); } private reloadIframe() { const viewContent = this.containerEl.children[1]; - const iframe = viewContent.getElementsByTagName('iframe')[0]; - iframe.contentWindow.postMessage('reload', this.url); + const iframe = viewContent.getElementsByTagName("iframe")[0]; + iframe.contentWindow.postMessage("reload", this.url); } private renderView() { const viewContent = this.containerEl.children[1]; viewContent.empty(); - viewContent.addClass('reveal-preview-view'); - viewContent.createEl('iframe', { + viewContent.addClass("reveal-preview-view"); + viewContent.createEl("iframe", { attr: { // @ts-ignore: src: this.url, - sandbox: 'allow-scripts allow-same-origin allow-popups', + sandbox: "allow-scripts allow-same-origin allow-popups", }, }); } diff --git a/src/reveal/revealRenderer.ts b/src/reveal/revealRenderer.ts index ea5b49b..7737dac 100644 --- a/src/reveal/revealRenderer.ts +++ b/src/reveal/revealRenderer.ts @@ -1,16 +1,19 @@ -import path, { basename, extname, join } from 'path'; - -import Mustache from 'mustache'; -import { MarkdownProcessor } from '../obsidian/markdownProcessor'; -import { getMediaCollector, ObsidianUtils } from '../obsidian/obsidianUtils'; -import { RevealExporter } from './revealExporter'; -import { YamlParser } from '../yaml/yamlParser'; -import { glob } from 'glob'; -import { md } from './markdown'; -import { exists, readFile } from 'fs-extra'; -import { has, isEmpty } from '../util'; -import { DEFAULTS } from '../slidesExtended-constants'; -import { QueryString } from '../@types'; +import path, { basename, extname, join } from "node:path"; + +import Mustache from "mustache"; +import type { MarkdownProcessor } from "../obsidian/markdownProcessor"; +import { + getMediaCollector, + type ObsidianUtils, +} from "../obsidian/obsidianUtils"; +import { RevealExporter } from "./revealExporter"; +import { YamlParser } from "../yaml/yamlParser"; +import { glob } from "glob"; +import { md } from "./markdown"; +import { exists, readFile } from "fs-extra"; +import { has, isEmpty } from "../util"; +import { DEFAULTS } from "../slidesExtended-constants"; +import type { QueryString } from "../@types"; export class RevealRenderer { private processor: MarkdownProcessor; @@ -31,15 +34,15 @@ export class RevealRenderer { let renderForEmbed = false; if (!isEmpty(params)) { - if (has(params, 'export')) { + if (has(params, "export")) { renderForExport = params?.export; } - if (has(params, 'print-pdf')) { + if (has(params, "print-pdf")) { renderForPrint = true; } - if (has(params, 'embed')) { + if (has(params, "embed")) { renderForEmbed = params?.embed; } } @@ -106,9 +109,9 @@ export class RevealRenderer { enablePointer, } = settings; - let base = ''; + let base = ""; if (!getMediaCollector().shouldCollect()) { - base = '/'; + base = "/"; } const context = Object.assign(options, { @@ -154,15 +157,15 @@ export class RevealRenderer { } for (const themeDir of searchPath) { - const revealThemes = glob.sync('*.css', { + const revealThemes = glob.sync("*.css", { cwd: themeDir, }); // We're doing some compensation + matching here - const key = basename(theme).replace(extname(theme), ''); + const key = basename(theme).replace(extname(theme), ""); const revealTheme = revealThemes.find( - themePath => - basename(themePath).replace(extname(themePath), '') === key, + (themePath) => + basename(themePath).replace(extname(themePath), "") === key, ); if (revealTheme) { @@ -174,12 +177,12 @@ export class RevealRenderer { private toExternalPath(urlPath: string): string { return urlPath - .replace(this.utils.pluginDirectory, '') - .replace(this.utils.vaultDirectory, ''); + .replace(this.utils.pluginDirectory, "") + .replace(this.utils.vaultDirectory, ""); } private async getPageTemplate(embed = false) { - const relativePath = embed ? 'embed.html' : DEFAULTS.template; + const relativePath = embed ? "embed.html" : DEFAULTS.template; const searchPath = this.utils.getHtmlTemplateSearchPath(); for (const dir of searchPath) { @@ -192,7 +195,7 @@ export class RevealRenderer { console.error( `Template file ${relativePath} not found in search path: ${searchPath}.`, ); - return ''; + return ""; } private slidify(markdown: string, slidifyOptions: unknown) { @@ -204,13 +207,13 @@ export class RevealRenderer { if (!css) { return input; } - if (typeof css === 'string') { - input = css.split(','); + if (typeof css === "string") { + input = css.split(","); } else { input = css; } - return input.map(css => { + return input.map((css) => { if (this.isValidUrl(css)) { return css; } diff --git a/src/reveal/revealServer.ts b/src/reveal/revealServer.ts index d4e56af..7ad1ece 100644 --- a/src/reveal/revealServer.ts +++ b/src/reveal/revealServer.ts @@ -1,13 +1,13 @@ -import Fastify, { FastifyInstance } from 'fastify'; +import Fastify, { type FastifyInstance } from "fastify"; -import { RevealRenderer } from './revealRenderer'; -import { ObsidianUtils } from '../obsidian/obsidianUtils'; -import { Notice, Platform, TAbstractFile } from 'obsidian'; -import { fastifyStatic, ListDir, ListFile } from '@fastify/static'; -import path from 'path'; -import { QueryString } from '../@types'; -import { existsSync } from 'fs'; -import { Buffer } from 'buffer'; +import { RevealRenderer } from "./revealRenderer"; +import type { ObsidianUtils } from "../obsidian/obsidianUtils"; +import { Notice, Platform, type TAbstractFile } from "obsidian"; +import { fastifyStatic, type ListDir, type ListFile } from "@fastify/static"; +import path from "node:path"; +import type { QueryString } from "../@types"; +import { existsSync } from "node:fs"; +import { Buffer } from "node:buffer"; export class RevealServer { private _server: FastifyInstance; @@ -29,106 +29,100 @@ export class RevealServer { serve: false, }); - this._server.get<{ Querystring: QueryString }>( - '/', - async (request, reply) => { - if (this.filePath === null) { - reply.type('text/html').send(chooseSlides); - } else { - const markup = await this._revealRenderer.renderFile( - this.filePath, - request.query, - ); - reply.type('text/html').send(markup); - } - return reply; - }, - ); + this._server.get<{ Querystring: QueryString }>("/", async (request, reply) => { + if (this.filePath === null) { + reply.type("text/html").send(chooseSlides); + } else { + const markup = await this._revealRenderer.renderFile( + this.filePath, + request.query, + ); + reply.type("text/html").send(markup); + } + return reply; + }); - ['plugin', 'dist', 'css'].forEach(dir => { + for (const dir of ["plugin", "dist", "css"]) { this._server.register(fastifyStatic, { root: path.join(utils.pluginDirectory, dir), - prefix: '/' + dir, + prefix: `/${dir}`, wildcard: true, index: false, decorateReply: false, list: { - format: 'html', + format: "html", render: renderIndex, }, }); - }); + } - this._server.get<{ Querystring: QueryString }>( - '/*', - async (request, reply) => { - // @ts-ignore - const file = request.params['*']; - - const renderMarkdownFile = async (filePath: string) => { - const markup = await this._revealRenderer.renderFile( - filePath, - request.query, - ); - reply.type('text/html').send(markup); - }; - - if (file.startsWith('local-file-url')) { - const urlpath = file.replace( - 'local-file-url', - Platform.resourcePathPrefix, - ); - const result = await fetch(urlpath).catch(error => { - return new Response(null, { - status: 404, - statusText: error.messge, - }); + this._server.get<{ Querystring: QueryString }>("/*", async (request, reply) => { + // @ts-ignore + const file = request.params["*"]; + + const renderMarkdownFile = async (filePath: string) => { + const markup = await this._revealRenderer.renderFile( + filePath, + request.query, + ); + reply.type("text/html").send(markup); + }; + + if (file.startsWith("local-file-url")) { + const urlpath = file.replace( + "local-file-url", + Platform.resourcePathPrefix, + ); + const result = await fetch(urlpath).catch((error) => { + return new Response(null, { + status: 404, + statusText: error.messge, }); - if (result.ok) { - if (result.blob) { - const blob = await result.blob(); - const bytes = await blob.arrayBuffer(); - reply.type(blob.type).send(Buffer.from(bytes)); - } else { - console.info( - 'open a bug to handle this kind of response. Include this message', - result, - ); - } + }); + if (result.ok) { + if (result.blob) { + const blob = await result.blob(); + const bytes = await blob.arrayBuffer(); + reply.type(blob.type).send(Buffer.from(bytes)); } else { - reply.code(404).send(result.statusText); + console.info( + "open a bug to handle this kind of response. Include this message", + result, + ); } - } else if (file.startsWith('embed/') && file.endsWith('.md')) { - const filePath = path.join( - utils.vaultDirectory, - file.replace('embed/', ''), - ); - await renderMarkdownFile(filePath); - } else if (file.endsWith('.md')) { - // top-level slide - this.filePath = path.join(utils.vaultDirectory, file); - await renderMarkdownFile(this.filePath); } else { - let fetch = file; - const sourceDir = path.dirname(this.filePath); - if (sourceDir != utils.vaultDirectory) { - const srcPath = path.join(sourceDir, file); - if (existsSync(srcPath)) { - fetch = srcPath.replace(utils.vaultDirectory, ''); - } + reply.code(404).send(result.statusText); + } + } else if (file.startsWith("embed/") && file.endsWith(".md")) { + const filePath = path.join( + utils.vaultDirectory, + file.replace("embed/", ""), + ); + await renderMarkdownFile(filePath); + } else if (file.endsWith(".md")) { + // top-level slide + this.filePath = path.join(utils.vaultDirectory, file); + await renderMarkdownFile(this.filePath); + } else { + let fetch = file; + const sourceDir = path.dirname(this.filePath); + if (sourceDir !== utils.vaultDirectory) { + const srcPath = path.join(sourceDir, file); + if (existsSync(srcPath)) { + fetch = srcPath.replace(utils.vaultDirectory, ""); } - console.debug( - 'serve file', - file, - sourceDir, - utils.vaultDirectory, - fetch, - ); - reply.sendFile(fetch); } - return reply; - }, - ); + console.debug( + "serve file", + file, + sourceDir, + utils.vaultDirectory, + fetch, + ); + reply.sendFile(fetch); + } + return reply; + }); } get running(): boolean { @@ -142,45 +136,43 @@ export class RevealServer { } private fixedEncodeURIComponent(str: string) { - return str.replace(/[!'()*]/g, function (c) { - return '%' + c.charCodeAt(0).toString(16); - }); + return str.replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16)}`); } async start() { if (this.running) { console.debug( - 'Slides Extended server is already running', + "Slides Extended server is already running", this._server.listeningOrigin.replace( /(127\.0\.0\.1|\[::1\])/, - 'localhost', + "localhost", ), ); return; } try { - await this._server.listen({ host: 'localhost', port: this._port }); + await this._server.listen({ host: "localhost", port: this._port }); console.info( - 'Slides Extended is ready to go.', + "Slides Extended is ready to go.", this._server.listeningOrigin.replace( /(127\.0\.0\.1|\[::1\])/, - 'localhost', + "localhost", ), ); } catch (err) { new Notice( `Unable to start server. Is ${this._port} already in use?`, ); - console.error('Unable to start server', err); + console.error("Unable to start server", err); } } async stop() { if (this.running) { - console.info('stopping Slides Extended server', this.running); + console.info("stopping Slides Extended server", this.running); await this._server.close(); } else { - console.debug('Slides Extended server is not running'); + console.debug("Slides Extended server is not running"); } } } @@ -194,10 +186,10 @@ const renderIndex = (dirs: ListDir[], files: ListFile[]) => { return ` `; };