import renderService from "./render.js"; import protectedSessionService from "./protected_session.js"; import protectedSessionHolder from "./protected_session_holder.js"; import openService from "./open.js"; import froca from "./froca.js"; import utils from "./utils.js"; import linkService from "./link.js"; import treeService from "./tree.js"; import FNote from "../entities/fnote.js"; import FAttachment from "../entities/fattachment.js"; import imageContextMenuService from "../menus/image_context_menu.js"; import { applySingleBlockSyntaxHighlight, formatCodeBlocks } from "./syntax_highlight.js"; import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js"; import renderDoc from "./doc_renderer.js"; import { t } from "../services/i18n.js"; import WheelZoom from 'vanilla-js-wheel-zoom'; import { renderMathInElement } from "./math.js"; import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons"; let idCounter = 1; interface Options { tooltip?: boolean; trim?: boolean; imageHasZoom?: boolean; } const CODE_MIME_TYPES = new Set(["application/json"]); async function getRenderedContent(this: {} | { ctx: string }, entity: FNote | FAttachment, options: Options = {}) { options = Object.assign( { tooltip: false }, options ); const type = getRenderingType(entity); // attachment supports only image and file/pdf/audio/video const $renderedContent = $('
");
$codeBlock.text(content);
$renderedContent.append($("").append($codeBlock));
await applySingleBlockSyntaxHighlight($codeBlock, normalizeMimeTypeForCKEditor(note.mime));
}
function renderImage(entity: FNote | FAttachment, $renderedContent: JQuery, options: Options = {}) {
const encodedTitle = encodeURIComponent(entity.title);
let url;
if (entity instanceof FNote) {
url = `api/images/${entity.noteId}/${encodedTitle}?${Math.random()}`;
} else if (entity instanceof FAttachment) {
url = `api/attachments/${entity.attachmentId}/image/${encodedTitle}?${entity.utcDateModified}">`;
}
$renderedContent // styles needed for the zoom to work well
.css("display", "flex")
.css("align-items", "center")
.css("justify-content", "center");
const $img = $("
")
.attr("src", url || "")
.attr("id", "attachment-image-" + idCounter++)
.css("max-width", "100%");
$renderedContent.append($img);
if (options.imageHasZoom) {
const initZoom = async () => {
const element = document.querySelector(`#${$img.attr("id")}`);
if (element) {
WheelZoom.create(`#${$img.attr("id")}`, {
maxScale: 50,
speed: 1.3,
zoomOnClick: false
});
} else {
requestAnimationFrame(initZoom);
}
};
initZoom();
}
imageContextMenuService.setupContextMenu($img);
}
function renderFile(entity: FNote | FAttachment, type: string, $renderedContent: JQuery) {
let entityType, entityId;
if (entity instanceof FNote) {
entityType = "notes";
entityId = entity.noteId;
} else if (entity instanceof FAttachment) {
entityType = "attachments";
entityId = entity.attachmentId;
} else {
throw new Error(`Can't recognize entity type of '${entity}'`);
}
const $content = $('');
if (type === "pdf") {
const $pdfPreview = $('');
$pdfPreview.attr("src", openService.getUrlForDownload(`api/${entityType}/${entityId}/open`));
$content.append($pdfPreview);
} else if (type === "audio") {
const $audioPreview = $("")
.attr("src", openService.getUrlForDownload(`api/${entityType}/${entityId}/open-partial`))
.attr("type", entity.mime)
.css("width", "100%");
$content.append($audioPreview);
} else if (type === "video") {
const $videoPreview = $("")
.attr("src", openService.getUrlForDownload(`api/${entityType}/${entityId}/open-partial`))
.attr("type", entity.mime)
.css("width", "100%");
$content.append($videoPreview);
}
if (entityType === "notes" && "noteId" in entity) {
// TODO: we should make this available also for attachments, but there's a problem with "Open externally" support
// in attachment list
const $downloadButton = $(`
`);
const $openButton = $(`
`);
$downloadButton.on("click", () => openService.downloadFileNote(entity.noteId));
$openButton.on("click", () => openService.openNoteExternally(entity.noteId, entity.mime));
// open doesn't work for protected notes since it works through a browser which isn't in protected session
$openButton.toggle(!entity.isProtected);
$content.append($('