(href: string, label: string)
| 603 | // Used by both the markdown renderer.link and the HTML <a> interceptor so that |
| 604 | // all link processing happens in a single pass during marked rendering. |
| 605 | function processLink(href: string, label: string): { resolvedHref: string; extraAttrs: string } { |
| 606 | const resolvedHref = resolveUrl(href, packageName, repoInfo) |
| 607 | |
| 608 | // Collect playground links |
| 609 | const provider = matchPlaygroundProvider(resolvedHref) |
| 610 | if (provider && !seenUrls.has(resolvedHref)) { |
| 611 | seenUrls.add(resolvedHref) |
| 612 | collectedLinks.push({ |
| 613 | url: resolvedHref, |
| 614 | provider: provider.id, |
| 615 | providerName: provider.name, |
| 616 | label: decodeHtmlEntities(label || provider.name), |
| 617 | }) |
| 618 | } |
| 619 | |
| 620 | // Security attributes for external links |
| 621 | let extraAttrs = |
| 622 | resolvedHref && hasProtocol(resolvedHref, { acceptRelative: true }) |
| 623 | ? ' rel="nofollow noreferrer noopener" target="_blank"' |
| 624 | : '' |
| 625 | |
| 626 | return { resolvedHref, extraAttrs } |
| 627 | } |
| 628 | |
| 629 | // Resolve link URLs, add security attributes, and collect playground links |
| 630 | // — all in a single pass during marked rendering (no deferred processing) |
no test coverage detected