Skip to content

Preserve illustrative inline SVG inline instead of externalizing to a blocked .svg asset (#238)#257

Merged
chubes4 merged 1 commit into
trunkfrom
fix/inline-svg-preserve-238
Jun 28, 2026
Merged

Preserve illustrative inline SVG inline instead of externalizing to a blocked .svg asset (#238)#257
chubes4 merged 1 commit into
trunkfrom
fix/inline-svg-preserve-238

Conversation

@chubes4

@chubes4 chubes4 commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #238 (SVG-render half). The hero layout-misplacement is a separate layout-fidelity concern and is intentionally out of scope here; it remains tracked independently.

An inline illustrative <svg> (e.g. album/EP cover art, viewBox-based, decorative) was externalized by the PHP transformer into an assets/inline-svg-*.svg asset and emitted as core/image url="assets/inline-svg-*.svg". WordPress blocks SVG uploads by default, so that image never renders and the artwork is lost.

Fix (generic, SVG-rendering only)

HtmlTransformer::inlineSvgBlockFromElement() now emits a core/html block that preserves the inline <svg> (renders anywhere, no SVG-upload support needed) instead of writing a .svg asset + core/image.

  • Keys off the element being a safe inline <svg> — no fixture-specific strings.
  • Reuses the existing safety gates: safeFallbackHtml() (strips <script>/<style>, on*= handlers, javascript: URLs, srcdoc) + isSafeSvgContent(). Unsafe/scriptable SVG still falls back via the existing diagnostic path and is never inlined raw.
  • Preserves viewBox/role/aria-label/class (they live in the SVG markup).
  • Adds restoreSvgAttributeCasing() so DOMDocument's lowercasing (viewBoxviewbox) is reverted. SVG attribute names are case-sensitive; a lowercased viewbox is ignored by browsers and would break scaling.
  • Removes the now-dead materializeInlineSvgAsset() helper.

Negative cases preserved

  • Real <img>/raster images → still core/image (untouched).
  • Unsafe/scriptable SVG → still sanitized fallback diagnostic (html_unsafe_inline_svg).
  • Icon SVGs → still core/icon (untouched).

Did not touch Classification/, Style/, or Diagnostics/.

Before / after (scratch repro)

Safe inline <svg class="ep-cover" viewBox="0 0 500 500" role="img" aria-label="..."> inside a .hero-art wrapper:

  • Before: core/image with url="assets/inline-svg-….svg", <svg> count in blocks = 0 (lost in WP).
  • After: core/html containing the <svg> (viewBox casing intact), <svg> count = N > 0, 0 generated .svg assets.

Tests

  • composer test:canonical ✅ (updated the SVG-specific contract assertions: large illustrative SVG, decorative logo-context SVG, and the artifact inline-SVG case now assert inline core/html + no generated asset).
  • composer parity ✅ 128 fixtures.
  • composer test ✅ (canonical + parity + packaging).

Parity fixtures changed (intended behavior change for this fix)

These four carried safe illustrative inline SVG that legitimately moves from core/image(external .svg) → core/html(inline), so each now asserts inline content + assets count 0:

  • html-flex-media-text-columns
  • html-single-child-flex-svg
  • html-single-child-flex-svg-address
  • html-product-card-svg-price-grid

Unchanged (negative cases): html-inline-svg-decorative (core/icon), html-inline-svg-unsafe (fallback), html-inline-svg-fallback (core/icon).

DO NOT MERGE without review.

🤖 Generated with Claude Code

… blocked .svg asset

Issue #238: the PHP transformer externalized illustrative/decorative inline
`<svg>` elements (e.g. album/EP cover art) into an `assets/inline-svg-*.svg`
file and emitted them as `core/image`. WordPress blocks SVG uploads by default,
so that image never renders and the artwork is lost.

Fix the SVG-render half generically: `inlineSvgBlockFromElement` now emits a
`core/html` block that preserves the inline `<svg>` (renders anywhere, no
SVG-upload support required) instead of writing a `.svg` asset. The markup is
still safe-sanitized via the existing `safeFallbackHtml` + `isSafeSvgContent`
gates, so unsafe/scriptable SVG continues to fall back as before and is never
inlined raw. Genuine `<img>`/raster images and icon SVGs (core/icon) are
unchanged.

Also restore the canonical camelCase casing of SVG attribute names that
DOMDocument lowercases (e.g. `viewBox`), since SVG attributes are case-sensitive
and a lowercased `viewbox` would be ignored by browsers, breaking scaling.

Updates the SVG-specific contract assertions and the four parity fixtures whose
safe illustrative SVG legitimately moves from core/image(external) to
core/html(inline). Decorative-icon, unsafe-SVG, and core/icon fixtures are
unchanged.

Closes #238 (SVG-render half; the hero layout-misplacement is a separate
layout-fidelity concern tracked independently).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chubes4 chubes4 merged commit d470c43 into trunk Jun 28, 2026
1 check passed
@chubes4 chubes4 deleted the fix/inline-svg-preserve-238 branch June 28, 2026 00:36
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.

Inline illustrative SVG externalized to a .svg asset → core/image WP can't render (album cover lost); hero layout flattened (misplaced)

1 participant