diff --git a/apps/client/src/components/note_context.ts b/apps/client/src/components/note_context.ts index f897e0673..767206167 100644 --- a/apps/client/src/components/note_context.ts +++ b/apps/client/src/components/note_context.ts @@ -122,12 +122,17 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded"> // Clear context data when switching notes and notify subscribers const oldKeys = Array.from(this.contextData.keys()); this.contextData.clear(); - for (const key of oldKeys) { - this.triggerEvent("contextDataChanged", { - noteContext: this, - key, - value: undefined - }); + if (oldKeys.length > 0) { + // Notify subscribers asynchronously to avoid blocking navigation + window.setTimeout(() => { + for (const key of oldKeys) { + this.triggerEvent("contextDataChanged", { + noteContext: this, + key, + value: undefined + }); + } + }, 0); } this.saveToRecentNotes(resolvedNotePath); diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts index 8d9ce1014..74de00884 100644 --- a/apps/client/src/services/utils.ts +++ b/apps/client/src/services/utils.ts @@ -192,7 +192,7 @@ export function formatSize(size: number | null | undefined) { } const k = 1024; - const sizes = ["B", "KB", "MB", "GB"]; + const sizes = ["B", "KiB", "MiB", "GiB"]; const i = Math.floor(Math.log(size) / Math.log(k)); return `${Math.round((size / Math.pow(k, i)) * 100) / 100} ${sizes[i]}`; diff --git a/apps/client/src/widgets/note_types.tsx b/apps/client/src/widgets/note_types.tsx index 76142b7af..3f3ab5e6f 100644 --- a/apps/client/src/widgets/note_types.tsx +++ b/apps/client/src/widgets/note_types.tsx @@ -4,7 +4,7 @@ */ import { NoteType } from "@triliumnext/commons"; -import { type JSX,VNode } from "preact"; +import { type JSX, VNode } from "preact"; import { TypeWidgetProps } from "./type_widgets/type_widget"; diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index 07b9ac2d8..f9ab7faad 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -1213,23 +1213,18 @@ export function useSetContextData( key: K, value: NoteContextDataMap[K] | undefined ) { - const valueRef = useRef(value); - valueRef.current = value; - useEffect(() => { - if (!noteContext || valueRef.current === undefined) return; + if (!noteContext) return; - noteContext.setContextData(key, valueRef.current); + if (value !== undefined) { + noteContext.setContextData(key, value); + } else { + noteContext.clearContextData(key); + } return () => { noteContext.clearContextData(key); }; - }, [noteContext, key]); - - // Update when value changes - useEffect(() => { - if (!noteContext || value === undefined) return; - noteContext.setContextData(key, value); }, [noteContext, key, value]); } @@ -1253,23 +1248,7 @@ export function useSetContextData( */ export function useGetContextData(key: K): NoteContextDataMap[K] | undefined { const { noteContext } = useActiveNoteContext(); - const [data, setData] = useState(() => - noteContext?.getContextData(key) - ); - - // Update initial value when noteContext changes - useEffect(() => { - setData(noteContext?.getContextData(key)); - }, [noteContext, key]); - - // Subscribe to changes via Trilium event system - useTriliumEvent("contextDataChanged", ({ noteContext: eventNoteContext, key: changedKey, value }) => { - if (eventNoteContext === noteContext && changedKey === key) { - setData(value as NoteContextDataMap[K]); - } - }); - - return data; + return useGetContextDataFrom(noteContext, key); } /** diff --git a/apps/server-e2e/src/note_types/pdf.spec.ts b/apps/server-e2e/src/note_types/pdf.spec.ts index d3bfee80d..1d37a5129 100644 --- a/apps/server-e2e/src/note_types/pdf.spec.ts +++ b/apps/server-e2e/src/note_types/pdf.spec.ts @@ -61,7 +61,7 @@ describe("PDF sidebar", () => { await expect(attachmentsList.locator(".pdf-attachment-item")).toHaveCount(2); const attachmentInfo = attachmentsList.locator(".pdf-attachment-item", { hasText: "Note.trilium" }); - await expect(attachmentInfo).toContainText("3.36 MB"); + await expect(attachmentInfo).toContainText("3.36 MiB"); // Download the attachment and check its size. const [ download ] = await Promise.all([ diff --git a/packages/pdfjs-viewer/src/attachments.ts b/packages/pdfjs-viewer/src/attachments.ts index 3016ec8e1..bfaf2eb52 100644 --- a/packages/pdfjs-viewer/src/attachments.ts +++ b/packages/pdfjs-viewer/src/attachments.ts @@ -1,11 +1,12 @@ export async function setupPdfAttachments() { - const app = window.PDFViewerApplication; - // Extract immediately since we're called after documentloaded await extractAndSendAttachments(); // Listen for download requests window.addEventListener("message", async (event) => { + // Only accept messages from the same origin to prevent malicious iframes + if (event.origin !== window.location.origin) return; + if (event.data?.type === "trilium-download-attachment") { const filename = event.data.filename; await downloadAttachment(filename); @@ -18,7 +19,6 @@ async function extractAndSendAttachments() { try { const attachments = await app.pdfDocument.getAttachments(); - console.log("Got attachments:", attachments); if (!attachments) { window.parent.postMessage({ diff --git a/packages/pdfjs-viewer/src/custom.ts b/packages/pdfjs-viewer/src/custom.ts index 919a03d62..2688991fc 100644 --- a/packages/pdfjs-viewer/src/custom.ts +++ b/packages/pdfjs-viewer/src/custom.ts @@ -35,7 +35,7 @@ function hideSidebar() { const toggleButtonEl = document.getElementById("viewsManagerToggleButton"); if (toggleButtonEl) { const spacer = toggleButtonEl.nextElementSibling.nextElementSibling; - if (spacer.classList.contains("toolbarButtonSpacer")) { + if (spacer instanceof HTMLElement && spacer.classList.contains("toolbarButtonSpacer")) { spacer.remove(); } toggleButtonEl.remove(); @@ -47,10 +47,7 @@ function getCustomAppOptions(urlParams: URLSearchParams) { localeProperties: { // Read from URL query lang: urlParams.get("lang") || "en" - }, - // Control sidebar visibility via query parameter - // sidebarViewOnLoad: -1 disables sidebar, 0 = NONE (default) - viewsManager: null + } }; } diff --git a/packages/pdfjs-viewer/src/layers.ts b/packages/pdfjs-viewer/src/layers.ts index bb4b12a5a..3097aa1ec 100644 --- a/packages/pdfjs-viewer/src/layers.ts +++ b/packages/pdfjs-viewer/src/layers.ts @@ -1,11 +1,12 @@ export async function setupPdfLayers() { - const app = window.PDFViewerApplication; - // Extract immediately since we're called after documentloaded await extractAndSendLayers(); // Listen for layer visibility toggle requests window.addEventListener("message", async (event) => { + // Only accept messages from the same origin to prevent malicious iframes + if (event.origin !== window.location.origin) return; + if (event.data?.type === "trilium-toggle-layer") { const layerId = event.data.layerId; const visible = event.data.visible; diff --git a/packages/pdfjs-viewer/src/pages.ts b/packages/pdfjs-viewer/src/pages.ts index 89403eeed..4a4e65a96 100644 --- a/packages/pdfjs-viewer/src/pages.ts +++ b/packages/pdfjs-viewer/src/pages.ts @@ -19,16 +19,15 @@ export function setupPdfPages() { }, window.location.origin); }); - // Listen for scroll-to-page requests - window.addEventListener("message", (event) => { + window.addEventListener("message", async(event) => { + // Only accept messages from the same origin to prevent malicious iframes + if (event.origin !== window.location.origin) return; + if (event.data?.type === "trilium-scroll-to-page") { const pageNumber = event.data.pageNumber; app.pdfViewer.currentPageNumber = pageNumber; } - }); - // Listen for thumbnail requests - window.addEventListener("message", async (event) => { if (event.data?.type === "trilium-request-thumbnail") { const pageNumber = event.data.pageNumber; await generateThumbnail(pageNumber); diff --git a/packages/pdfjs-viewer/src/toc.ts b/packages/pdfjs-viewer/src/toc.ts index ddc2db707..dca8a94b4 100644 --- a/packages/pdfjs-viewer/src/toc.ts +++ b/packages/pdfjs-viewer/src/toc.ts @@ -55,6 +55,9 @@ function convertOutlineToToc(outline: any[], level = 0, outlineMap?: Map { + // Only accept messages from the same origin to prevent malicious iframes + if (event.origin !== window.location.origin) return; + if (event.data?.type === "trilium-scroll-to-heading") { const headingId = event.data.headingId;