diff --git a/packages/gutenberg-to-portable-text/src/index.ts b/packages/gutenberg-to-portable-text/src/index.ts index 74ee28f..b704a74 100644 --- a/packages/gutenberg-to-portable-text/src/index.ts +++ b/packages/gutenberg-to-portable-text/src/index.ts @@ -9,7 +9,7 @@ import { parse } from "@wordpress/block-serialization-default-parser"; import { parseInlineContent } from "./inline.js"; -import { getTransformer, defaultTransformers, fallbackTransformer } from "./transformers/index.js"; +import { getTransformer } from "./transformers/index.js"; import type { GutenbergBlock, PortableTextBlock, diff --git a/packages/gutenberg-to-portable-text/src/transformers/core.ts b/packages/gutenberg-to-portable-text/src/transformers/core.ts index 5ac5cd7..bbaffc1 100644 --- a/packages/gutenberg-to-portable-text/src/transformers/core.ts +++ b/packages/gutenberg-to-portable-text/src/transformers/core.ts @@ -550,8 +550,6 @@ export const group: BlockTransformer = (block, _options, context) => { * core/table → table block */ export const table: BlockTransformer = (block, _options, context) => { - const _hasFixedLayout = attrBoolean(block.attrs, "hasFixedLayout"); - // Parse the table HTML const tableMatch = block.innerHTML.match(TABLE_TAG_PATTERN); if (!tableMatch) { diff --git a/packages/gutenberg-to-portable-text/tests/converter.test.ts b/packages/gutenberg-to-portable-text/tests/converter.test.ts index e5f756a..0433893 100644 --- a/packages/gutenberg-to-portable-text/tests/converter.test.ts +++ b/packages/gutenberg-to-portable-text/tests/converter.test.ts @@ -5,9 +5,29 @@ import { describe, it, expect } from "vitest"; import { gutenbergToPortableText, htmlToPortableText, parseGutenbergBlocks } from "../src/index.js"; -import type { PortableTextTextBlock, PortableTextImageBlock } from "../src/types.js"; +import type { + PortableTextTextBlock, + PortableTextImageBlock, + PortableTextGalleryBlock, + PortableTextTableBlock, + PortableTextButtonsBlock, +} from "../src/types.js"; const HTML_TAG_PATTERN = /<[^>]+>/g; +const knownProviders = [ + ["youtube.com", "youtube"], + ["youtu.be", "youtube"], + ["vimeo.com", "vimeo"], + ["twitter.com", "twitter"], + ["x.com", "twitter"], + ["instagram.com", "instagram"], + ["facebook.com", "facebook"], + ["tiktok.com", "tiktok"], + ["spotify.com", "spotify"], + ["soundcloud.com", "soundcloud"], + ["codepen.io", "codepen"], + ["gist.github.com", "gist"], +] as const; describe("gutenbergToPortableText", () => { describe("empty content", () => { @@ -25,6 +45,68 @@ describe("gutenbergToPortableText", () => { }); }); + describe("basic HTML content", () => { + it("converts simple HTML to a paragraph block", () => { + const content = "

Hello world

"; + const result = gutenbergToPortableText(content); + expect(result).toHaveLength(1); + expect(result[0]).toMatchObject({ + _type: "block", + style: "normal", + }); + const block = result[0] as PortableTextTextBlock; + expect(block.children[0]?.text).toBe("Hello world"); + }); + + it("converts mixed blocks and text", () => { + const content = `

Intro text

weird middle text

More text

`; + const result = gutenbergToPortableText(content); + + expect(result).toHaveLength(3); + expect(result[0]).toMatchObject({ + _type: "block", + style: "normal", + }); + expect(result[1]).toMatchObject({ + _type: "block", + style: "normal", + }); + expect(result[2]).toMatchObject({ + _type: "block", + style: "normal", + }); + + const block1 = result[0] as PortableTextTextBlock; + const block2 = result[1] as PortableTextTextBlock; + const block3 = result[2] as PortableTextTextBlock; + + expect(block1.children[0]?.text).toBe("Intro text"); + expect(block2.children[0]?.text).toBe("weird middle text"); + expect(block3.children[0]?.text).toBe("More text"); + }); + + it("handles trailing text content", () => { + const content = `

Paragraph text

Trailing text`; + const result = gutenbergToPortableText(content); + + expect(result).toHaveLength(2); + expect(result[0]).toMatchObject({ + _type: "block", + style: "normal", + }); + expect(result[1]).toMatchObject({ + _type: "block", + style: "normal", + }); + + const block1 = result[0] as PortableTextTextBlock; + const block2 = result[1] as PortableTextTextBlock; + + expect(block1.children[0]?.text).toBe("Paragraph text"); + expect(block2.children[0]?.text).toBe("Trailing text"); + }); + }); + describe("paragraph blocks", () => { it("converts simple paragraph", () => { const content = ` @@ -418,20 +500,75 @@ https://twitter.com/user/status/123 }); }); - it("detects provider from URL when not specified", () => { - const content = ` + it.each(knownProviders)( + "detects provider from URL when not specified for %s", + (domain, provider) => { + const content = `
-https://vimeo.com/123456 +https://${domain}/123456
`; - const result = gutenbergToPortableText(content); + const result = gutenbergToPortableText(content); + expect(result[0]).toMatchObject({ + _type: "embed", + provider, + }); + }, + ); + + it("converts audio embeds", () => { + const content = ` + +`; + + const result = gutenbergToPortableText(content); expect(result[0]).toMatchObject({ _type: "embed", - provider: "vimeo", + url: "https://example.com/audio.mp3", + provider: "audio", + }); + }); + + it("converts video embeds", () => { + const content = ` + +`; + + const result = gutenbergToPortableText(content); + expect(result[0]).toMatchObject({ + _type: "embed", + url: "https://example.com/video.mp4", + provider: "video", + }); + }); + + it("infers video source from