diff --git a/package.json b/package.json index 8868ba6..2746b7d 100644 --- a/package.json +++ b/package.json @@ -96,8 +96,8 @@ "vite-plugin-dts": "^4.5.4" }, "dependencies": { - "@shotstack/schemas": "1.9.3", - "@shotstack/shotstack-canvas": "^2.1.12", + "@shotstack/schemas": "1.9.5", + "@shotstack/shotstack-canvas": "2.1.15", "howler": "^2.2.4", "mediabunny": "^1.11.2", "opentype.js": "^1.3.4", diff --git a/src/components/canvas/players/rich-caption-player.ts b/src/components/canvas/players/rich-caption-player.ts index a27396b..7a2daf7 100644 --- a/src/components/canvas/players/rich-caption-player.ts +++ b/src/components/canvas/players/rich-caption-player.ts @@ -484,7 +484,7 @@ export class RichCaptionPlayer extends Player { border: asset.border, padding: asset.padding, style: asset.style, - wordAnimation: asset.wordAnimation, + animation: asset.animation, align: asset.align, pauseThreshold: this.resolvedPauseThreshold }; diff --git a/src/core/ui/rich-caption-toolbar.ts b/src/core/ui/rich-caption-toolbar.ts index d09d22c..900b031 100644 --- a/src/core/ui/rich-caption-toolbar.ts +++ b/src/core/ui/rich-caption-toolbar.ts @@ -162,8 +162,8 @@ export class RichCaptionToolbar extends RichTextToolbar { if (!asset) return; // ─── Word Animation ──────────────────────────────── - const wordAnim = asset.wordAnimation; - const animStyle = wordAnim?.style ?? "karaoke"; + const anim = asset.animation; + const animStyle = anim?.style ?? "karaoke"; this.container?.querySelectorAll("[data-caption-word-style]").forEach(btn => { this.setButtonActive(btn, btn.dataset["captionWordStyle"] === animStyle); }); @@ -172,7 +172,7 @@ export class RichCaptionToolbar extends RichTextToolbar { this.wordAnimDirectionSection.style.display = animStyle === "slide" ? "" : "none"; } - const direction = wordAnim?.direction ?? "up"; + const direction = anim?.direction ?? "up"; this.container?.querySelectorAll("[data-caption-word-direction]").forEach(btn => { this.setButtonActive(btn, btn.dataset["captionWordDirection"] === direction); }); @@ -586,7 +586,7 @@ export class RichCaptionToolbar extends RichTextToolbar { const style = btn.dataset["captionWordStyle"]; if (!style) return; const asset = this.getCaptionAsset(); - this.updateClipProperty({ wordAnimation: { ...(asset?.wordAnimation ?? {}), style } }); + this.updateClipProperty({ animation: { ...(asset?.animation ?? {}), style } }); }); }); @@ -596,7 +596,7 @@ export class RichCaptionToolbar extends RichTextToolbar { const direction = btn.dataset["captionWordDirection"]; if (!direction) return; const asset = this.getCaptionAsset(); - this.updateClipProperty({ wordAnimation: { style: "slide" as const, ...(asset?.wordAnimation ?? {}), direction } }); + this.updateClipProperty({ animation: { style: "slide" as const, ...(asset?.animation ?? {}), direction } }); }); }); } diff --git a/test-package.js b/test-package.js index ff08fe5..9dddcaa 100644 --- a/test-package.js +++ b/test-package.js @@ -305,6 +305,13 @@ const checkUmdGlobalMappings = () => { const fullPath = resolve(__dirname, bundlePath); const fd = readFileSync(fullPath, "utf-8").slice(0, 2048); + const requirePattern = /require\("([^"]+)"\)/g; + const requiredModules = []; + let match; + while ((match = requirePattern.exec(fd)) !== null) { + requiredModules.push(match[1]); + } + const iifeMatch = fd.match(/\((\w+)=typeof globalThis[^)]+,(\w+)\(([^)]+)\)\)/); if (!iifeMatch) { errors.push(`${bundlePath}: Could not parse IIFE global branch from UMD wrapper.`); diff --git a/tests/rich-caption-player.test.ts b/tests/rich-caption-player.test.ts index fffc2b7..3b5e784 100644 --- a/tests/rich-caption-player.test.ts +++ b/tests/rich-caption-player.test.ts @@ -520,7 +520,7 @@ describe("RichCaptionPlayer", () => { it("renders karaoke animation on every update", async () => { const asset = createAsset({ - wordAnimation: { style: "karaoke", speed: 1, direction: "up" } + animation: { style: "karaoke", speed: 1, direction: "up" } } as Partial); const edit = createMockEdit(); const player = new RichCaptionPlayer(edit, createClip(asset)); diff --git a/tests/rich-caption-toolbar.test.ts b/tests/rich-caption-toolbar.test.ts index 6a5eedf..b0ed52a 100644 --- a/tests/rich-caption-toolbar.test.ts +++ b/tests/rich-caption-toolbar.test.ts @@ -134,7 +134,7 @@ function createMockEdit(overrides: Record = {}) { function createCaptionAsset(overrides: Record = {}) { return { type: "rich-caption", - wordAnimation: { style: "karaoke", direction: "up" }, + animation: { style: "karaoke", direction: "up" }, active: { font: { color: "#ffff00", opacity: 1 }, stroke: { width: 2, color: "#000000", opacity: 1 } @@ -281,7 +281,7 @@ describe("RichCaptionToolbar", () => { describe("syncState", () => { it("should sync word animation style buttons", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "pop" } }); + setupCaptionClip(mockEdit, { animation: { style: "pop" } }); toolbar.mount(container); toolbar.show(0, 0); @@ -293,7 +293,7 @@ describe("RichCaptionToolbar", () => { }); it("should show direction section only for 'slide' animation", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "slide", direction: "left" } }); + setupCaptionClip(mockEdit, { animation: { style: "slide", direction: "left" } }); toolbar.mount(container); toolbar.show(0, 0); @@ -302,7 +302,7 @@ describe("RichCaptionToolbar", () => { }); it("should hide direction section for non-slide animations", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "karaoke" } }); + setupCaptionClip(mockEdit, { animation: { style: "karaoke" } }); toolbar.mount(container); toolbar.show(0, 0); @@ -347,7 +347,7 @@ describe("RichCaptionToolbar", () => { }); it("should show scale section when word animation is 'pop'", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "pop" }, active: { scale: 1.5 } }); + setupCaptionClip(mockEdit, { animation: { style: "pop" }, active: { scale: 1.5 } }); toolbar.mount(container); toolbar.show(0, 0); @@ -359,7 +359,7 @@ describe("RichCaptionToolbar", () => { }); it("should hide scale section when word animation is not 'pop'", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "karaoke" } }); + setupCaptionClip(mockEdit, { animation: { style: "karaoke" } }); toolbar.mount(container); toolbar.show(0, 0); @@ -386,14 +386,14 @@ describe("RichCaptionToolbar", () => { 0, 0, expect.objectContaining({ asset: expect.objectContaining({ - wordAnimation: expect.objectContaining({ style: "pop" }) + animation: expect.objectContaining({ style: "pop" }) }) }) ); }); it("should call updateClip when direction button is clicked", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "slide", direction: "up" } }); + setupCaptionClip(mockEdit, { animation: { style: "slide", direction: "up" } }); toolbar.mount(container); toolbar.show(0, 0); @@ -404,7 +404,7 @@ describe("RichCaptionToolbar", () => { 0, 0, expect.objectContaining({ asset: expect.objectContaining({ - wordAnimation: expect.objectContaining({ direction: "left" }) + animation: expect.objectContaining({ direction: "left" }) }) }) ); @@ -474,7 +474,7 @@ describe("RichCaptionToolbar", () => { }); it("should call updateClip when scale slider changes", () => { - setupCaptionClip(mockEdit, { wordAnimation: { style: "pop" }, active: { scale: 1 } }); + setupCaptionClip(mockEdit, { animation: { style: "pop" }, active: { scale: 1 } }); toolbar.mount(container); toolbar.show(0, 0);