Preserve embedded media through extraction: iframes, video aspect ratio, raw-text escaping - #23
Draft
SunChJ wants to merge 1 commit into
Draft
Preserve embedded media through extraction: iframes, video aspect ratio, raw-text escaping#23SunChJ wants to merge 1 commit into
SunChJ wants to merge 1 commit into
Conversation
…t ratio - Keep iframe/video/audio embeds across the Readability + Turndown pipeline (Readability strips iframes, so swap them for placeholder images around parsing and restore them afterwards, including their sizing wrappers). - Probe the video's real aspect ratio from its poster frame (JPEG/PNG header) and emit a responsive .video-wrap container (position:relative + padding-top + iframe 100%x100%) instead of carrying the source site's fixed layout (e.g. Cloudflare's padding-top:53.46% / width:84%, which depends on external CSS that extraction does not keep). - Escape bare raw-text tags (script/style/textarea/title/...) that appear as literal prose so a browser cannot treat them as real elements and swallow the rest of the rendered page. - Ask the translation model to keep media embed HTML unchanged. - Add regression tests and a verify script with reproducible scenarios.
SunChJ
marked this pull request as draft
August 7, 2026 09:00
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two silent content-loss bugs in the HTML→Markdown extraction pipeline:
@mozilla/readabilitystrips<iframe>from its output, so video demos / interactive embeds never reached the translated page. A translated page would say "Here's Kitesurf running Doom" and show nothing — the article just ended mid-sentence.<script>in prose truncated the page. The article text mentions<script>as a tag name; extraction decoded the source's<script>into a bare tag, which the renderer emitted as real HTML. Browsers then treated the rest of the page as a script element and swallowed all following content.Both are reproducible on a single real-world page: https://blog.cloudflare.com/kitesurf/ (2 Cloudflare Stream video embeds + a literal
<script>mention in prose).Changes
Preserve embeds through extraction (
scripts/transcrab-core.mjs)iframe/video/audioin the Turndown keep list.Adapt video display to the real aspect ratio
<div class="video-wrap" style="position:relative;width:100%;padding-top:…%">+ iframe100%×100%) instead of carrying the source site's fixed layout (Cloudflare'spadding-top:53.46%/width:84%relies on external CSS that extraction doesn't keep, so absolute iframes mis-layout).src/layouts/Base.astro:.video-wrapCSS fallback so absolute iframes always have a positioned container.Escape raw-text tags in prose (
scripts/transcrab-core.mjs)script/style/textarea/title/… mentioned as literal text are escaped to<…>(fenced code blocks untouched).Supporting changes
scripts/lib/translate-prompt.mjs: translation contract asks the model to keep media embed HTML unchanged.scripts/verify-embed-extraction.mjs: reproducible verification scenarios.test/core.test.mjs: regression tests (embed preservation, wrapper normalization, ratio computation, JPEG/PNG header parsing, raw-text escaping).npm test→ 41 pass.Before / After (extraction of https://blog.cloudflare.com/kitesurf/)
Verification
Notes