Skip to content

Keep card and callout content through conversion and canonicalize - #3468

Merged
chubes4 merged 1 commit into
trunkfrom
fix/issue-3458-blocks-engine
Oct 26, 2026
Merged

chubes4 merged 1 commit into
trunkfrom
fix/issue-3458-blocks-engine

Conversation

@chubes4

@chubes4 chubes4 commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Related issues

Fixes #3458.

How AI was used

Claude (via the Pi coding agent in a Roadie session) traced the root cause, wrote the change and tests, and ran the verification below on the Lab runner. A Homeboy cook attempt stopped at promotion (homeboy#16453, fixed after the installed release), so this was finalized outside Homeboy with the operator's authorization.

Proposed Changes

  • Container inner content is always block markup (catalog.ts recurseInner). When no catalog pattern matches inside a callout, details or media-text, the inner HTML becomes the same html-fallback island an unmatched top-level element gets. It is no longer raw HTML, which the container's re-save discards.
  • Callout groups keep the authored classes (paw-card, notice callout). They are no longer replaced with an is-style-<word> class that no theme registers.
  • Canonicalize keeps content (wp/canonicalize.ts). If an invalid block's re-save would drop words or media sources it showed, the block is kept as written. serialize() emits an invalid block's original source, which is what the editor does until a person recovers it. The block is listed in FixResult.preservedBlocks and reported as an invalid_block_preserved warning, so the status is success_with_warnings.
  • The 4 affected compose fixtures (generic-callout, generic-details, generic-media-text, sample-callout-div) are updated. Each new expected output canonicalizes with no validation issues.

Card contents now become a group containing an html island, not image/heading/paragraph blocks. Lowering the ordinary elements inside an island into real blocks belongs to the raw conversion path and is left for a follow-up. This PR removes the content loss.

Testing Instructions

cd packages/blocks-engine && pnpm typecheck && pnpm test
  • src/__tests__/content-preservation.test.ts (20 tests) converts the issue's cards, a card grid, a callout, an accordion item and every compose fixture through convertReport on the real worker. It checks that the output keeps the input's words and media sources, and that none depend on the canonicalize guard. Guard cases cover a top-level group and a group nested in columns, plus a lossless invalid paragraph that is still fixed.

  • Mutation check of the new tests plus the compose goldens (30 tests):

    Variant Failing tests
    trunk 16
    catalog change reverted 13
    guard disabled 3
    raw inner HTML restored 12
    class replaced with is-style-card 2
  • Full suite on Lab: 523 passed. 3 tests in 2 files fail identically on unmodified trunk in that checkout, because it has no pnpm build bundle and no php-transformer vendor/ (wp-runtime-bundle, associated-label-save-validity).

Pre-merge Checklist

  • Tests added and failing on trunk
  • Typecheck clean
  • CI green

A class-bearing card <div> converted to an empty core/group and was
reported as success (#3458). The catalog's container converters (callout,
details, media-text) built their inner markup by falling back to raw HTML
when no catalog pattern matched inside. A container block saves only its
inner blocks, so canonicalize's re-save of that group discarded the image,
heading and text and was adopted as an info-level normalization.

Container inner content is now always block markup: unmatched inner HTML
becomes the same html-fallback island an unmatched top-level element gets.
The callout group keeps the authored classes the site's CSS targets
instead of replacing them with an is-style-<word> class no theme registers.

Canonicalize gains one guard at the owning layer: when an invalid block's
re-save would drop words or media sources it showed, the block is kept as
written (serialize() emits an invalid block's original source, as the
editor does until a person recovers it), listed in preservedBlocks, and
reported as an invalid_block_preserved warning.

The new content-preservation table converts the issue's cards and every
compose fixture through convertReport on the real worker and checks the
output keeps the input's words and media. It fails on trunk (16 of 30),
with the catalog change reverted (13), with the guard disabled (3), and
with raw inner HTML restored (12).
@chubes4
chubes4 merged commit 7054e1e into trunk Oct 26, 2026
2 checks passed
@chubes4
chubes4 deleted the fix/issue-3458-blocks-engine branch October 26, 2026 06:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Card divs convert to empty groups: content deleted, reported as success

1 participant