diff --git a/apps/client/src/test/easy-froca.ts b/apps/client/src/test/easy-froca.ts index c282baf23..e6a9aeaff 100644 --- a/apps/client/src/test/easy-froca.ts +++ b/apps/client/src/test/easy-froca.ts @@ -4,6 +4,7 @@ import froca from "../services/froca.js"; import FAttribute from "../entities/fattribute.js"; import noteAttributeCache from "../services/note_attribute_cache.js"; import FBranch from "../entities/fbranch.js"; +import FBlob from "../entities/fblob.js"; type AttributeDefinitions = { [key in `#${string}`]: string; }; type RelationDefinitions = { [key in `~${string}`]: string; }; @@ -12,6 +13,7 @@ interface NoteDefinition extends AttributeDefinitions, RelationDefinitions { id?: string | undefined; title: string; children?: NoteDefinition[]; + content?: string; } /** @@ -51,6 +53,20 @@ export function buildNote(noteDef: NoteDefinition) { froca.notes[note.noteId] = note; let childNotePosition = 0; + // Manage content. + const content = noteDef.content ?? ""; + note.getContent = async () => content; + + const blob = new FBlob({ + blobId: utils.randomString(10), + content, + contentLength: content.length, + dateModified: new Date().toISOString(), + utcDateModified: new Date().toISOString() + }); + note.getBlob = async () => blob; + + // Manage children. if (noteDef.children) { for (const childDef of noteDef.children) { const childNote = buildNote(childDef); diff --git a/apps/client/src/widgets/collections/presentation/index.tsx b/apps/client/src/widgets/collections/presentation/index.tsx index b079522c6..df7be7f2b 100644 --- a/apps/client/src/widgets/collections/presentation/index.tsx +++ b/apps/client/src/widgets/collections/presentation/index.tsx @@ -177,6 +177,7 @@ function Presentation({ presentation, setApi } : { presentation: PresentationMod function Slide({ slide }: { slide: PresentationSlideBaseModel }) { return (
{ beforeAll(async () => { presentationNote = buildNote({ title: "Presentation", + id: "presentation", "#viewType": "presentation", "children": [ { @@ -26,6 +26,7 @@ describe("Presentation model", () => { { title: "Second slide", id: "slide3", + content: `

Go to First slide.

`, children: [ { id: "slide4", @@ -64,4 +65,12 @@ describe("Presentation model", () => { it("empty slides don't render children", () => { expect(data.slides[0].content.__html).toStrictEqual(""); }); + + it("rewrites links to other slides", () => { + expect(data.slides[1].content.__html).toStrictEqual(`

Go to First slide.

`); + }); + + it("doesn't rewrite links if they are not part of the slideshow", () => { + + }); }); diff --git a/apps/client/src/widgets/collections/presentation/model.ts b/apps/client/src/widgets/collections/presentation/model.ts index c38b1d62d..769a8d6da 100644 --- a/apps/client/src/widgets/collections/presentation/model.ts +++ b/apps/client/src/widgets/collections/presentation/model.ts @@ -1,3 +1,4 @@ +import { NoteType } from "@triliumnext/commons"; import FNote from "../../../entities/fnote"; import contentRenderer from "../../../services/content_renderer"; @@ -11,6 +12,7 @@ interface PresentationSlideModel extends PresentationSlideBaseModel { /** Either a top-level slide or a vertical slide. */ export interface PresentationSlideBaseModel { noteId: string; + type: NoteType; content: DangerouslySetInnerHTML; backgroundColor?: string; backgroundGradient?: string; @@ -25,8 +27,9 @@ export async function buildPresentationModel(note: FNote): Promise ({ ...(await buildSlideModel(slideNote)), verticalSlides: await buildVerticalSlides(slideNote) - }))) + }))); + postProcessSlides(slides); return { slides }; } @@ -45,6 +48,7 @@ async function buildSlideModel(note: FNote): Promise return { noteId: note.noteId, + type: note.type, content: await processContent(note), backgroundColor: !isGradient ? slideBackground : undefined, backgroundGradient: isGradient ? slideBackground : undefined @@ -57,3 +61,10 @@ async function processContent(note: FNote): Promise { }); return { __html: $renderedContent.html() }; } + +async function postProcessSlides(slides: PresentationSlideModel[]) { + for (const slide of slides) { + if (slide.type !== "text") continue; + slide.content.__html = slide.content.__html.replaceAll(/href="[^"]*#root[a-zA-Z0-9_\/]*\/([a-zA-Z0-9_]+)[^"]*"/g, `href="#/$1"`); + } +}