Repository navigation
Name the enlarged chat image for VoiceOver - #6262
Merged
Merged
Conversation
The native zoom view rendered the enlarged image with no accessibility label, so VoiceOver landed on a bare "image". Inline markdown images already carry alt text in the WebView, but the enlarge bridge dropped it. Send the tapped image's alt text with the enlarge message, carry it on the image zoom target, and label the zoomed image with it. Images with no description, such as attachments, are named "Enlarged image". Cover the label rule and the bridge in the unit bundle, add a UI test that opens the zoom fixture and checks the enlarged image's name, and pin the bridge field and label in the accessible-controls source test. Refs #5314
This was referenced Oct 26, 2026
BunsDev
added a commit
that referenced
this pull request
Oct 26, 2026
## Summary - Stamp v0.5.18 across `package.json`, `tauri.conf.json`, `Cargo.toml`, `Cargo.lock` and the iOS `project.yml` (marketing version 0.5.18, build `2026102622`). - Curate the notes for the changes since v0.5.17: the Next.js and DOMPurify security updates (#6267, #6264), local-model checks on every launch path (#6263), Coven history metadata export (#6255), the VoiceOver label for enlarged chat images (#6262), and maintenance (#6254, #6253, #6256, #6260). - State plainly that Cave doesn't enable the Next.js features the advisories target, rather than overstating exposure. - Disclose again that the Windows MSI is not Authenticode-signed in this cut. Refs #6270 ## Verification - `node scripts/stamp-release.mjs --prepare-only --level patch --allow-version-gap`, from the managed `release/stamp-v0.5.18` worktree at live `origin/main` `a95e34d0a`. There is no gap: `GET /releases/latest` returns `v0.5.17` (GraphQL was rate-limited), and the continuity check below passes. - `pnpm release:verify --version 0.5.18`: five manifests and the final changelog agree. - `pnpm release:verify-continuity --published 0.5.17`: 0.5.17 → 0.5.18. - `src/lib/app-version.test.ts` and `scripts/stamp-release.test.mjs` pass.
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.
Refs #5314 (task T2). The issue stays open for the physical-device capture and the VoiceOver and copy/share pass.
What
The native zoom view rendered the enlarged image with no accessibility label. On
main, the zoom cover's accessibility tree shows the enlarged image asImage, {{0.0, 317.3}, {402.0, 301.3}}with no label or identifier, so VoiceOver announces a bare "image". Inline markdown images already carry alt text in the WebView (the fixture'sis labelled there), but the enlarge bridge dropped it.Change
apps/ios/markdown/entry.mjs: theenlargemessage also carries the tapped<img>'salt.MarkdownWebView.swift:handleEnlargereadsalt, andpresentImage(src:alt:fallbackHTML:)passes it toContentZoom.image(_:description:).ContentZoom.swift:ZoomTarget.Content.imagegains an optionaldescription.ZoomTarget.imageAccessibilityLabel(description:)returns the trimmed description, or "Enlarged image" when there is none (attachments, or images with empty alt text).ZoomableImageViewapplies that label and aZoomed imageidentifier. No hint was added: the design language doesn't call for one, and pinch or double-tap hints would mislead VoiceOver users (see the note below).Tests
ContentZoomTests: label from a description (trimmed), the fallback for nil/blank, andContentZoom.image(_:description:)keeping the description.MarkdownWebViewLifecycleTests.testInlineImageZoomKeepsItsAltTextForVoiceOver: anenlargescript message withaltproduces a zoom target carrying it.PerformanceBaselineUITests.testZoomedImageIsNamedByItsAltText: opens the image-zoom fixture, taps image A, and asserts the enlarged image's accessibility label isZoom fixture image A.scripts/ios-accessible-controls.test.mjs: pins the bridge'saltfield and the view's label and identifier, because CI compiles UI tests but doesn't run them.Verification
xcodebuild test, schemeCovenCave, iPhone 17 simulator,CODE_SIGNING_ALLOWED=NO, run onContentZoomTests,MarkdownWebViewLifecycleTestsandCaveImageCacheTests: 45 tests, 0 failures. All four new unit tests ran.xcodebuild test, schemeCovenCavePerformance(Release), same simulator:testZoomedImageIsNamedByItsAltTextpassed, andtestImageZoomCyclespassed all 100 cycles.pnpm test:mobile(106 files),pnpm check:tests-wired, andnode --test scripts/ios-accessible-controls.test.mjs(4/4) pass.Note for the VoiceOver pass (T6): the zoom gestures (pinch, drag, double-tap at
count: 2) have no accessibility actions, so VoiceOver users can read the image but probably can't zoom it. That is out of scope here and worth checking on device.