mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 05:28:59 +01:00 
			
		
		
		
	feat(export/zip): get CSS to load
This commit is contained in:
		
							parent
							
								
									f189deb415
								
							
						
					
					
						commit
						4d5e866db6
					
				@ -2,11 +2,11 @@
 | 
			
		||||
 | 
			
		||||
import html from "html";
 | 
			
		||||
import dateUtils from "../date_utils.js";
 | 
			
		||||
import path from "path";
 | 
			
		||||
import path, { join } from "path";
 | 
			
		||||
import mimeTypes from "mime-types";
 | 
			
		||||
import mdService from "./markdown.js";
 | 
			
		||||
import packageInfo from "../../../package.json" with { type: "json" };
 | 
			
		||||
import { getContentDisposition, escapeHtml, getResourceDir } from "../utils.js";
 | 
			
		||||
import { getContentDisposition, escapeHtml, getResourceDir, isDev } from "../utils.js";
 | 
			
		||||
import protectedSessionService from "../protected_session.js";
 | 
			
		||||
import sanitize from "sanitize-filename";
 | 
			
		||||
import fs from "fs";
 | 
			
		||||
@ -22,7 +22,7 @@ import type BBranch from "../../becca/entities/bbranch.js";
 | 
			
		||||
import type BNote from "../../becca/entities/bnote.js";
 | 
			
		||||
import type { Response } from "express";
 | 
			
		||||
import type { NoteMetaFile } from "../meta/note_meta.js";
 | 
			
		||||
import cssContent from "@triliumnext/ckeditor5/content.css";
 | 
			
		||||
//import cssContent from "@triliumnext/ckeditor5/content.css";
 | 
			
		||||
import { renderNoteForExport } from "../../share/content_renderer.js";
 | 
			
		||||
 | 
			
		||||
type RewriteLinksFn = (content: string, noteMeta: NoteMeta) => string;
 | 
			
		||||
@ -328,12 +328,13 @@ async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "h
 | 
			
		||||
                    throw new Error("Missing note path.");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const cssUrl = `${"../".repeat(noteMeta.notePath.length - 1)}style.css`;
 | 
			
		||||
                const basePath = "../".repeat(noteMeta.notePath.length - 1);
 | 
			
		||||
                const htmlTitle = escapeHtml(title);
 | 
			
		||||
 | 
			
		||||
                if (note) {
 | 
			
		||||
                    content = renderNoteForExport(note, branch);
 | 
			
		||||
                    content = renderNoteForExport(note, branch, basePath);
 | 
			
		||||
                } else {
 | 
			
		||||
                    const cssUrl = basePath + "style.css";
 | 
			
		||||
                    // <base> element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809
 | 
			
		||||
                    content = `<html>
 | 
			
		||||
<head>
 | 
			
		||||
@ -518,6 +519,7 @@ ${markdownContent}`;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let cssContent = getShareThemeAssets("css");
 | 
			
		||||
        archive.append(cssContent, { name: cssMeta.dataFileName });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -629,6 +631,19 @@ async function exportToZipFile(noteId: string, format: "markdown" | "html", zipF
 | 
			
		||||
    log.info(`Exported '${noteId}' with format '${format}' to '${zipFilePath}'`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getShareThemeAssets(extension: string) {
 | 
			
		||||
    let path: string | undefined;
 | 
			
		||||
    if (isDev) {
 | 
			
		||||
        path = join(getResourceDir(), "..", "..", "client", "dist", "src", `share.${extension}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!path) {
 | 
			
		||||
        throw new Error("Not yet defined.");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return fs.readFileSync(path, "utf-8");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    exportToZip,
 | 
			
		||||
    exportToZipFile
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,8 @@ import log from "../services/log.js";
 | 
			
		||||
import { join } from "path";
 | 
			
		||||
import { readFileSync } from "fs";
 | 
			
		||||
 | 
			
		||||
const shareAdjustedAssetPath = isDev ? assetPath : `../${assetPath}`;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Represents the output of the content renderer.
 | 
			
		||||
 */
 | 
			
		||||
@ -58,20 +60,50 @@ function getSharedSubTreeRoot(note: SNote | BNote | undefined): Subroot {
 | 
			
		||||
    return getSharedSubTreeRoot(parentBranch.getParentNote());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function renderNoteForExport(note: BNote, parentBranch: BBranch) {
 | 
			
		||||
export function renderNoteForExport(note: BNote, parentBranch: BBranch, basePath: string) {
 | 
			
		||||
    const subRoot: Subroot = {
 | 
			
		||||
        branch: parentBranch,
 | 
			
		||||
        note: parentBranch.getNote()
 | 
			
		||||
    };
 | 
			
		||||
    return renderNoteContentInternal(note, subRoot, note.getParentNotes()[0].noteId);
 | 
			
		||||
 | 
			
		||||
    return renderNoteContentInternal(note, {
 | 
			
		||||
        subRoot,
 | 
			
		||||
        rootNoteId: note.getParentNotes()[0].noteId,
 | 
			
		||||
        cssToLoad: [
 | 
			
		||||
            `${basePath}style.css`
 | 
			
		||||
        ]
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function renderNoteContent(note: SNote) {
 | 
			
		||||
    const subRoot = getSharedSubTreeRoot(note);
 | 
			
		||||
    return renderNoteContentInternal(note, subRoot, "_share");
 | 
			
		||||
 | 
			
		||||
    // Determine CSS to load.
 | 
			
		||||
    const cssToLoad: string[] = [];
 | 
			
		||||
    if (!isDev && !note.isLabelTruthy("shareOmitDefaultCss")) {
 | 
			
		||||
        cssToLoad.push(`${shareAdjustedAssetPath}/src/share.css`);
 | 
			
		||||
        cssToLoad.push(`${shareAdjustedAssetPath}/src/boxicons.css`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Support custom CSS too.
 | 
			
		||||
    for (const cssRelation of note.getRelations("shareCss")) {
 | 
			
		||||
        cssToLoad.push(`api/notes/${cssRelation.value}/download`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return renderNoteContentInternal(note, {
 | 
			
		||||
        subRoot,
 | 
			
		||||
        rootNoteId: "_share",
 | 
			
		||||
        cssToLoad
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function renderNoteContentInternal(note: SNote | BNote, subRoot: Subroot, rootNoteId: string) {
 | 
			
		||||
interface RenderArgs {
 | 
			
		||||
    subRoot: Subroot;
 | 
			
		||||
    rootNoteId: string;
 | 
			
		||||
    cssToLoad: string[];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function renderNoteContentInternal(note: SNote | BNote, renderArgs: RenderArgs) {
 | 
			
		||||
    const { header, content, isEmpty } = getContent(note);
 | 
			
		||||
    const showLoginInShareTheme = options.getOption("showLoginInShareTheme");
 | 
			
		||||
    const opts = {
 | 
			
		||||
@ -79,14 +111,13 @@ function renderNoteContentInternal(note: SNote | BNote, subRoot: Subroot, rootNo
 | 
			
		||||
        header,
 | 
			
		||||
        content,
 | 
			
		||||
        isEmpty,
 | 
			
		||||
        subRoot,
 | 
			
		||||
        assetPath: isDev ? assetPath : `../${assetPath}`,
 | 
			
		||||
        assetPath: shareAdjustedAssetPath,
 | 
			
		||||
        assetUrlFragment,
 | 
			
		||||
        appPath: isDev ? app_path : `../${app_path}`,
 | 
			
		||||
        showLoginInShareTheme,
 | 
			
		||||
        t,
 | 
			
		||||
        isDev,
 | 
			
		||||
        rootNoteId
 | 
			
		||||
        ...renderArgs
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Check if the user has their own template.
 | 
			
		||||
 | 
			
		||||
@ -6,14 +6,8 @@
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
			
		||||
 | 
			
		||||
    <link rel="shortcut icon" href="<% if (note.hasRelation("shareFavicon")) { %>api/notes/<%= note.getRelation("shareFavicon").value %>/download<% } else { %>../favicon.ico<% } %>">
 | 
			
		||||
    <script src="<%= appPath %>/share.js" type="module"></script>
 | 
			
		||||
    <% if (!isDev && !note.isLabelTruthy("shareOmitDefaultCss")) { %>
 | 
			
		||||
        <link href="<%= assetPath %>/src/share.css" rel="stylesheet">
 | 
			
		||||
        <link href="<%= assetPath %>/src/boxicons.css" rel="stylesheet">
 | 
			
		||||
    <% } %>
 | 
			
		||||
 | 
			
		||||
    <% for (const cssRelation of note.getRelations("shareCss")) { %>
 | 
			
		||||
        <link href="api/notes/<%= cssRelation.value %>/download" rel="stylesheet">
 | 
			
		||||
    <% for (const url of cssToLoad) { %>
 | 
			
		||||
        <link href="<%= url %>" rel="stylesheet">
 | 
			
		||||
    <% } %>
 | 
			
		||||
    <% for (const jsRelation of note.getRelations("shareJs")) { %>
 | 
			
		||||
        <script type="module" src="api/notes/<%= jsRelation.value %>/download"></script>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user