fix(desktop): keep a bare URL's full text visible in chat markdown (#121007)
MarkdownLink nulled fallbackLabel whenever the link text matched the target URL — exactly the bare-autolink case — so PrettyLink fell through to urlSlugTitleLabel and rendered a host-only label (`ncpssd.org` for https://www.ncpssd.org/), with the address readable only via hover/inspect. The user could not read an address sent in chat. The link's own text is always a legitimate fallback label; pass it through. Labeled links are unchanged: their authored label already wins display, and that shape (a label hiding the address) is PrettyLink's documented contract, not a bug. Salvaged from PR #38213 by Phantomthedog (the fallbackLabel change and the localhost/example.com render tests), reworked to keep the change scoped to the bare-autolink shape and reshaped into an end-to-end MarkdownTextContent test alongside the existing session/filelinks suites.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import { cleanup, render, screen } from '@testing-library/react'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { MarkdownTextContent } from './markdown-text'
|
||||
|
||||
afterEach(() => cleanup())
|
||||
|
||||
// End-to-end for the bare-autolink shape of #121007: a bare URL an agent sent
|
||||
// must render with its full text visible — PrettyLink used to collapse it to a
|
||||
// host-only label (`ncpssd.org`) with the address readable only via hover.
|
||||
// Labeled links keep their authored label (that hiding is intended design).
|
||||
describe('MarkdownTextContent bare URLs', () => {
|
||||
it('shows the full URL text for a bare autolink', () => {
|
||||
render(<MarkdownTextContent isRunning={false} text="See https://www.ncpssd.org/ for the database." />)
|
||||
|
||||
const link = screen.getByRole('link') as HTMLAnchorElement
|
||||
|
||||
expect(link.getAttribute('href')).toBe('https://www.ncpssd.org/')
|
||||
expect(link.textContent).toContain('https://www.ncpssd.org/')
|
||||
})
|
||||
|
||||
it('does not collapse a host-only URL to a bare hostname', () => {
|
||||
render(<MarkdownTextContent isRunning={false} text="Docs live at https://example.com/ now." />)
|
||||
|
||||
const link = screen.getByRole('link') as HTMLAnchorElement
|
||||
|
||||
// urlSlugTitleLabel would render `example.com`; the full URL is the label.
|
||||
expect(link.textContent).toContain('https://example.com/')
|
||||
})
|
||||
|
||||
it('keeps the authored label for a labeled markdown link', () => {
|
||||
render(<MarkdownTextContent isRunning={false} text="See [the database](https://www.ncpssd.org/) first." />)
|
||||
|
||||
const link = screen.getByRole('link') as HTMLAnchorElement
|
||||
|
||||
expect(link.getAttribute('href')).toBe('https://www.ncpssd.org/')
|
||||
expect(link.textContent).toContain('the database')
|
||||
expect(link.textContent).not.toContain('ncpssd.org/')
|
||||
})
|
||||
})
|
||||
@@ -345,7 +345,14 @@ function MarkdownLink({ children, className, href, ...props }: ComponentProps<'a
|
||||
}
|
||||
}
|
||||
|
||||
const fallbackLabel = text && normalizeExternalUrl(text) !== target ? text : undefined
|
||||
// Always pass the link's own text as the fallback label so a bare URL stays
|
||||
// fully visible (#121007): previously this was `undefined` when the child
|
||||
// text matched the target URL (the bare-autolink case), so PrettyLink fell
|
||||
// through to urlSlugTitleLabel — a host-only label like `ncpssd.org` with
|
||||
// the address readable only via hover/inspect. The full URL is the label the
|
||||
// sender actually wrote into the chat. Labeled links are unchanged: their
|
||||
// authored label already wins display by design.
|
||||
const fallbackLabel = text || undefined
|
||||
|
||||
return (
|
||||
<PrettyLink className={cn('wrap-anywhere', className)} fallbackLabel={fallbackLabel} href={target} {...props} />
|
||||
|
||||
Reference in New Issue
Block a user