uttrflow / uttrflow/uttrflow-swift
HTML-only clipboard conversion drops a link destination when URL paths differ only by case
- Dominant language
- Swift
- Stars
- 4
- Forks
- 17
- Avg merge
- 4h 27m
- Merged PRs (30d)
- 286
Description
## Problem
`PlainTextRenderer.sameDestination` lowercases the entire link label and href before comparing them. Paths can be case-sensitive, so two different destinations can be treated as identical. `closeLink` then omits the href and retains only the displayed text, defeating the converter's purpose of preserving a link's destination in plain text.
## Reproduction
```html
https://example.com/report
```
Expected plain text: `https://example.com/report (https://example.com/Report)`.
Actual plain text: `https://example.com/report`. The actual destination `/Report` is absent. Both the direct converter assertion and the watcher clip-text assertion fail.
[RFC 3986 section 6.2.2.1](https://www.rfc-editor.org/rfc/rfc3986#section-6.2.2.1) distinguishes case-insensitive scheme/host components from other components, which are assumed case-sensitive unless their scheme defines otherwise. The reproduction uses reserved example addresses and makes no request to a real server.
## Reachability and verification limits
Reviewed unmodified main `8d93f5b8574f3c7b8c30086d9c817bf7f5d4827d`. Verified both the converter and `PasteboardWatcher.newClip(at:)`, supplying HTML with no plain-string or image representation through the existing `FakeClipboard` test seam. The watcher returns a clip whose `text` has the incorrect conversion; its `richText` retains the original HTML. A control with an explicit plain-string representation passes, because that representation bypasses conversion. This is an HTML-only clipboard path, not a claim that all browser copies are affected. No live application clipboard or UI was exercised.
The existing rich-text suites passed in the preceding review pass. The new tests assert expected content independently of the converter.
## Fix and acceptance checks
Compare URL components with their appropriate equivalence rules instead of lowercasing the complete strings. Preserve destination text whenever equivalence is uncertain. Add path-case and query-case fixtures, while retaining the existing host-case and identical-URL controls. Keep the exact destination when printing it.
Code: `Sources/UttrflowClipboard/RichTextPlainForm.swift:628-666` (`closeLink`, `sameDestination`) and `PasteboardWatcher.swift:118-121`. `Docs/clipboard-plain-form.md` promises to preserve destinations except when already present in the text. #742 covers empty labels and tokenizer branches; #741 covers the fallback path, neither this false-equivalence behavior.
Contributor guide
Research direction
Start in Sources/UttrflowClipboard/RichTextPlainForm.swift:628-666, reading sameDestination and closeLink, then inspect PasteboardWatcher.swift:118-121 and the existing FakeClipboard-based converter and watcher assertions. Verify that path-case and query-case differences preserve the destination, while host-case and identical-URL controls retain their existing behavior; the documented destination-preservation promise should remain satisfied.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- macos, swift
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100