diff --git a/packages/core/src/slideshow/parseSlideshow.test.ts b/packages/core/src/slideshow/parseSlideshow.test.ts index 1633d58818..8251a16405 100644 --- a/packages/core/src/slideshow/parseSlideshow.test.ts +++ b/packages/core/src/slideshow/parseSlideshow.test.ts @@ -196,4 +196,23 @@ describe("resolveSlideshow", () => { expect(resolved.slides[0].start).toBe(1); expect(resolved.slides[0].end).toBe(4); }); + + it("parses and carries through the per-slide autoplay flag", () => { + const island = ``; + const m = parseSlideshowManifest(island); + expect(m?.slides[0].autoplay).toBe(true); + expect(m?.slides[1].autoplay).toBeUndefined(); + const { resolved } = resolveSlideshow(m!, SCENES); + expect(resolved.slides[0].autoplay).toBe(true); + expect(resolved.slides[1].autoplay).toBeUndefined(); + }); + + it("rejects a manifest whose slide autoplay is not a boolean", () => { + const island = ``; + expect(() => parseSlideshowManifest(island)).toThrow(); + }); }); diff --git a/packages/core/src/slideshow/parseSlideshow.ts b/packages/core/src/slideshow/parseSlideshow.ts index a7583f8406..a05537ce50 100644 --- a/packages/core/src/slideshow/parseSlideshow.ts +++ b/packages/core/src/slideshow/parseSlideshow.ts @@ -44,16 +44,21 @@ export function parseSlideshowManifest(html: string): SlideshowManifest | null { return parsed; } +function isOptionalNumberArray(v: unknown): boolean { + return v === undefined || (Array.isArray(v) && v.every((n) => typeof n === "number")); +} + +function isOptionalBoolean(v: unknown): v is boolean | undefined { + return v === undefined || typeof v === "boolean"; +} + function isSlideRef(v: unknown): v is SlideRef { if (typeof v !== "object" || v === null) return false; const r = v as Record; if (typeof r["sceneId"] !== "string") return false; - if ( - r["fragments"] !== undefined && - !(Array.isArray(r["fragments"]) && r["fragments"].every((n) => typeof n === "number")) - ) - return false; + if (!isOptionalNumberArray(r["fragments"])) return false; if (r["hotspots"] !== undefined && !Array.isArray(r["hotspots"])) return false; + if (!isOptionalBoolean(r["autoplay"])) return false; return true; } diff --git a/packages/core/src/slideshow/slideshow.types.ts b/packages/core/src/slideshow/slideshow.types.ts index fdddf1d243..4d148d8156 100644 --- a/packages/core/src/slideshow/slideshow.types.ts +++ b/packages/core/src/slideshow/slideshow.types.ts @@ -19,6 +19,14 @@ export interface SlideRef { notes?: string; fragments?: number[]; hotspots?: SlideHotspot[]; + /** + * When true, the slide's first `