diff --git a/apps/server/src/services/export/zip.ts b/apps/server/src/services/export/zip.ts
index a175241d8..8d8d2de07 100644
--- a/apps/server/src/services/export/zip.ts
+++ b/apps/server/src/services/export/zip.ts
@@ -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";
// element will make sure external links are openable - https://github.com/zadam/trilium/issues/1289#issuecomment-704066809
content = `
@@ -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
diff --git a/apps/server/src/share/content_renderer.ts b/apps/server/src/share/content_renderer.ts
index 465c605ca..4fbae0586 100644
--- a/apps/server/src/share/content_renderer.ts
+++ b/apps/server/src/share/content_renderer.ts
@@ -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.
diff --git a/packages/share-theme/src/templates/page.ejs b/packages/share-theme/src/templates/page.ejs
index ba3d45b44..820e32ad5 100644
--- a/packages/share-theme/src/templates/page.ejs
+++ b/packages/share-theme/src/templates/page.ejs
@@ -6,14 +6,8 @@
api/notes/<%= note.getRelation("shareFavicon").value %>/download<% } else { %>../favicon.ico<% } %>">
-
- <% if (!isDev && !note.isLabelTruthy("shareOmitDefaultCss")) { %>
-
-
- <% } %>
-
- <% for (const cssRelation of note.getRelations("shareCss")) { %>
-
+ <% for (const url of cssToLoad) { %>
+
<% } %>
<% for (const jsRelation of note.getRelations("shareJs")) { %>