refactor(client): extract doc rendering to dedicated service

This commit is contained in:
Elian Doran 2025-03-11 21:32:48 +02:00
parent 4124c96e02
commit 32f84e8378
No known key found for this signature in database
2 changed files with 63 additions and 57 deletions

View File

@ -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<JQuery<HTMLElement>>((resolve) => {
let docName = note.getLabelValue("docName");
const $content = $("<div>");
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<HTMLElement>) {
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}`;
}

View File

@ -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 = `<div class="note-detail-doc note-detail-printable">
<style>
@ -68,64 +67,12 @@ export default class DocTypeWidget extends TypeWidget {
}
async doRefresh(note: FNote) {
this.initialized = this.#loadContent(note);
this.initialized = renderDoc(note).then(($content) => {
this.$content.html($content.html());
});
this.$widget.toggleClass("contextual-help", this.noteContext?.viewScope?.viewMode === "contextual-help");
}
#loadContent(note: FNote) {
return new Promise<void>((resolve) => {
let docName = note.getLabelValue("docName");
if (docName) {
// find doc based on language
const url = this.#getUrl(docName, getCurrentLanguage());
this.$content.load(url, (response, status) => {
// fallback to english doc if no translation available
if (status === "error") {
const fallbackUrl = this.#getUrl(docName, "en");
this.$content.load(fallbackUrl, () => this.#processContent(fallbackUrl));
resolve();
return;
}
this.#processContent(url);
resolve();
});
} else {
this.$content.empty();
resolve();
}
});
}
#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}`;
}
#processContent(url: string) {
const dir = url.substring(0, url.lastIndexOf("/"));
// Remove top-level heading since it's already handled by the note title
this.$content.find("h1").remove();
// Images are relative to the docnote but that will not work when rendered in the application since the path breaks.
this.$content.find("img").each((i, el) => {
const $img = $(el);
$img.attr("src", dir + "/" + $img.attr("src"));
});
applySyntaxHighlight(this.$content);
}
async executeWithContentElementEvent({ resolve, ntxId }: EventData<"executeWithContentElement">) {
if (!this.isNoteContext(ntxId)) {
return;