feat(desktop): render HTML file previews as a sandboxed page - #25
Merged
Merged
Conversation
HTML attachments now open as a laid-out page in the Slack-style preview dialog. Bytes still come only from fetch_media_bytes; the iframe is srcdoc with an empty sandbox so scripts and same-origin cannot be enabled. Download and the 10 MiB cap are unchanged. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: jmfcamp <jmfcamp@users.noreply.github.com>
jmfcamp
marked this pull request as ready for review
August 21, 2026 00:09
This was referenced Aug 21, 2026
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.
Summary
Follow-up to #23 (Slack-style file preview) and #24 (10 MiB cap). HTML attachments previously opened as inert syntax-highlighted source. They now open as a laid-out page by default, like Slack file preview.
Hard security constraints are unchanged and not weakened:
fetch_media_bytespath. The iframesrcis never the relay/media/URL, and Download is still a button that invokesdownload_file.<iframe>withsrcDocfrom the fetched bytes and an emptysandbox. The plan type locksallowScripts: false,iframeSrc: null, andsandbox: ""— there is no token list a caller can upgrade to include scripts or same-origin.allow-scripts. Static HTML/CSS may display; JS must not run.FILE_PREVIEW_MAX_BYTEScap stay.serve_inline/ MIME deny lists, and Hula branding (productName,com.huladesk.buzz,hulabuzz://) are untouched.An optional Source tab still shows the highlighted markup. Default tab is the rendered page.
Related issue
Follow-up to #23 / #24. None found for rendered HTML specifically.
Testing
Locally verified:
pnpm typecheck(desktop) passednode --import ./test-loader.mjs --experimental-strip-types --test src/shared/ui/filePreview.test.mjs— 28 passed (HTML kind ishtmlwith a rendered/sandboxed srcdoc plan; 3.3 MiB HTML is under the cap; iframesrccannot be/media/; sandbox cannot includeallow-scripts)pnpm exec playwright test tests/e2e/file-attachment.spec.ts --project=smoke— 19 passed, including:/media/src)<h1>Live?</h1>renders inside the frame, not in the parent webviewwindow.__XSS__stays unset in the parent and frame