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 `