From 32f84e8378395b205fa347871c4597bd86e80b12 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Tue, 11 Mar 2025 21:32:48 +0200 Subject: [PATCH] refactor(client): extract doc rendering to dedicated service --- src/public/app/services/doc_renderer.ts | 59 +++++++++++++++++++++ src/public/app/widgets/type_widgets/doc.ts | 61 ++-------------------- 2 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 src/public/app/services/doc_renderer.ts diff --git a/src/public/app/services/doc_renderer.ts b/src/public/app/services/doc_renderer.ts new file mode 100644 index 000000000..ac1560d4c --- /dev/null +++ b/src/public/app/services/doc_renderer.ts @@ -0,0 +1,59 @@ +import type FNote from "../entities/fnote.js"; +import { getCurrentLanguage } from "./i18n.js"; +import { applySyntaxHighlight } from "./syntax_highlight.js"; + +export default function renderDoc(note: FNote) { + return new Promise>((resolve) => { + let docName = note.getLabelValue("docName"); + const $content = $("
"); + + if (docName) { + // find doc based on language + const url = getUrl(docName, getCurrentLanguage()); + $content.load(url, (response, status) => { + // fallback to english doc if no translation available + if (status === "error") { + const fallbackUrl = getUrl(docName, "en"); + $content.load(fallbackUrl, () => processContent(fallbackUrl, $content)); + resolve($content); + return; + } + + processContent(url, $content); + resolve($content); + }); + } else { + resolve($content); + } + + return $content; + }); +} + +function processContent(url: string, $content: JQuery) { + const dir = url.substring(0, url.lastIndexOf("/")); + + // Remove top-level heading since it's already handled by the note title + $content.find("h1").remove(); + + // Images are relative to the docnote but that will not work when rendered in the application since the path breaks. + $content.find("img").each((i, el) => { + const $img = $(el); + $img.attr("src", dir + "/" + $img.attr("src")); + }); + + applySyntaxHighlight($content); +} + +function getUrl(docNameValue: string, language: string) { + // For help notes, we only get the content to avoid loading of styles and meta. + let suffix = ""; + if (docNameValue?.startsWith("User Guide")) { + suffix = " .content"; + } + + // Cannot have spaces in the URL due to how JQuery.load works. + docNameValue = docNameValue.replaceAll(" ", "%20"); + + return `${window.glob.appPath}/doc_notes/${language}/${docNameValue}.html${suffix}`; +} diff --git a/src/public/app/widgets/type_widgets/doc.ts b/src/public/app/widgets/type_widgets/doc.ts index 8cac941f2..8dfdd1237 100644 --- a/src/public/app/widgets/type_widgets/doc.ts +++ b/src/public/app/widgets/type_widgets/doc.ts @@ -1,8 +1,7 @@ import type { EventData } from "../../components/app_context.js"; import type FNote from "../../entities/fnote.js"; -import { applySyntaxHighlight } from "../../services/syntax_highlight.js"; +import renderDoc from "../../services/doc_renderer.js"; import TypeWidget from "./type_widget.js"; -import { getCurrentLanguage } from "../../services/i18n.js"; const TPL = `