fix(content): pasted screenshots keep their proportions in posts and comments - #25
Merged
Conversation
…comments A screenshot pasted into the editor is inserted with no dimensions, so the image extension stores its 500x500 defaults with the node. The reader turned those into a bare `aspect-ratio: 500 / 500`, which overrides the image's own proportions once it has loaded, so every wide screenshot was squashed into a square in posts, comments, changelog entries and the widget. The editor never showed it, because it only sets a maximum width. The reader now writes `aspect-ratio: auto W / H`: the stored box is reserved until the image has loaded, then the image's own proportions win. Existing content is fixed without a migration, because the correction is in rendering. Measured in headless Chromium with a 1000x250 image stored as 500x500: 500x500 before, 500x125 after, through DOMPurify with the reader's configuration. After deploying: images with stored dimensions render in their own proportions everywhere the rich-text reader is used. The stored 500x500 defaults are still wrong data, so a mail client that honours width/height attributes literally can still squash an image in a notification email; fixing that means storing the real dimensions at insertion time, which this change does not do. The test module now states the reader's promises about image dimensions (V1-V6), including the pre-existing 4096 px trust bound the first property run surfaced. Also bumps the SELF-IMPROVE counter on the gates reading HEAD instead of the working tree. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
What changed
A screenshot pasted into the editor is inserted with no dimensions, so the image extension stores its 500x500 defaults with the node. The read-only renderer turned those into a bare
aspect-ratio: 500 / 500, which overrides the image's own proportions once it has loaded, so every wide screenshot was squashed into a square in posts, comments, changelog entries and the widget. The editor never showed it, because it only sets a maximum width.The renderer now writes
aspect-ratio: auto W / H: the stored box is reserved until the image has loaded, then the image's own proportions win. Existing content is fixed without a migration, because the correction is in rendering.Verification
Headless Chromium, a 1000x250 image stored as 500x500, real serializer output through DOMPurify with the reader's configuration:
aspect-ratio: 500 / 500aspect-ratio: auto 500 / 500content-html.test.tsstates the reader's promises about image dimensions as V1-V6, with a fast-check property over width and height up to the extension's maximum. Its first run failed at[1, 4097]: the reader trusts stored dimensions only up to 4096 px (safePositiveInt), a pre-existing bound that is now stated as V4 rather than excluded from the generator. The property keeps one unguarded assertion across both branches: never a ratio withoutauto.content-html.tswith the suites that reach it: on the image branch 21 killed, 8 survived before this PR's extra tests; both changed lines are killed; three survivors on the branch are killed by two added tests, each verified by hand mutation; the remaining five are equivalent (optional chaining behind thesrccheck, ternaries with identical results). Whole file: 117 killed, 47 survived, 159 no coverage. The file is not in the mutation manifest and this PR does not add it, for the reasons in SELF-IMPROVE.md ("all-or-nothing per file").What this does not fix
The stored 500x500 defaults are still wrong data. In the browser that is now only a short layout shift while the image loads. Mail clients honour
width/heightattributes literally, so a changelog or conversation notification email can still show a squashed image. The fix for that is to read the real dimensions at insertion time, at the four insertion points inrich-text-editor.tsx.Also bumps the SELF-IMPROVE counter on "the coverage and mutation gates read HEAD, not the working tree" to 2x.
🤖 Generated with Claude Code