import "./content_renderer.css"; import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons"; import WheelZoom from 'vanilla-js-wheel-zoom'; import FAttachment from "../entities/fattachment.js"; import FNote from "../entities/fnote.js"; import imageContextMenuService from "../menus/image_context_menu.js"; import { t } from "../services/i18n.js"; import renderText from "./content_renderer_text.js"; import renderDoc from "./doc_renderer.js"; import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js"; import openService from "./open.js"; import protectedSessionService from "./protected_session.js"; import protectedSessionHolder from "./protected_session_holder.js"; import renderService from "./render.js"; import { applySingleBlockSyntaxHighlight } from "./syntax_highlight.js"; import utils, { getErrorMessage } from "./utils.js"; let idCounter = 1; export interface RenderOptions { tooltip?: boolean; trim?: boolean; imageHasZoom?: boolean; /** If enabled, it will prevent the default behavior in which an empty note would display a list of children. */ noChildrenList?: boolean; /** If enabled, it will prevent rendering of included notes. */ noIncludedNotes?: boolean; /** If enabled, it will include archived notes when rendering children list. */ includeArchivedNotes?: boolean; /** Set of note IDs that have already been seen during rendering to prevent infinite recursion. */ seenNoteIds?: Set; } const CODE_MIME_TYPES = new Set(["application/json"]); export async function getRenderedContent(this: {} | { ctx: string }, entity: FNote | FAttachment, options: RenderOptions = {}) { options = Object.assign( { tooltip: false }, options ); const type = getRenderingType(entity); // attachment supports only image and file/pdf/audio/video const $renderedContent = $('
'); if (type === "text" || type === "book") { await renderText(entity, $renderedContent, options); } else if (type === "code") { await renderCode(entity, $renderedContent); } else if (["image", "canvas", "mindMap"].includes(type)) { renderImage(entity, $renderedContent, options); } else if (!options.tooltip && ["file", "pdf", "audio", "video"].includes(type)) { renderFile(entity, type, $renderedContent); } else if (type === "mermaid") { await renderMermaid(entity, $renderedContent); } else if (type === "render" && entity instanceof FNote) { const $content = $("
"); await renderService.render(entity, $content, (e) => { const $error = $("
").addClass("admonition caution").text(typeof e === "string" ? e : getErrorMessage(e)); $content.empty().append($error); }); $renderedContent.append($content); } else if (type === "doc" && "noteId" in entity) { const $content = await renderDoc(entity); $renderedContent.html($content.html()); } else if (!options.tooltip && type === "protectedSession") { const $button = $(``).on("click", protectedSessionService.enterProtectedSession); $renderedContent.append($("
").append("
This note is protected and to access it you need to enter password.
").append("
").append($button)); } else if (entity instanceof FNote) { $renderedContent.addClass("no-preview"); $renderedContent.append( $("
").append($("").addClass(entity.getIcon())) ); if (entity.type === "webView" && entity.hasLabel("webViewSrc")) { const $footer = $("