mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01: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