mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-10 10:22:29 +08:00
refactor(client): extract doc rendering to dedicated service
This commit is contained in:
parent
4124c96e02
commit
32f84e8378
59
src/public/app/services/doc_renderer.ts
Normal file
59
src/public/app/services/doc_renderer.ts
Normal 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}`;
|
||||
}
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user