(html: string)
| 62 | // ── Async media URL accessibility checker ───────────────────────────────── |
| 63 | |
| 64 | function extractMediaUrls(html: string): Array<{ |
| 65 | url: string; |
| 66 | tagName: string; |
| 67 | elementId?: string; |
| 68 | snippet: string; |
| 69 | }> { |
| 70 | const results: Array<{ |
| 71 | url: string; |
| 72 | tagName: string; |
| 73 | elementId?: string; |
| 74 | snippet: string; |
| 75 | }> = []; |
| 76 | const tagRe = /<(video|audio|img|source)\b[^>]*>/gi; |
| 77 | let match: RegExpExecArray | null; |
| 78 | while ((match = tagRe.exec(html)) !== null) { |
| 79 | const tagName = (match[1] ?? "").toLowerCase(); |
| 80 | const raw = match[0]; |
| 81 | const src = readAttr(raw, "src"); |
| 82 | if (!src) continue; |
| 83 | if (/^https?:\/\//i.test(src)) { |
| 84 | results.push({ |
| 85 | url: src, |
| 86 | tagName, |
| 87 | elementId: readAttr(raw, "id") || undefined, |
| 88 | snippet: truncateSnippet(raw) ?? "", |
| 89 | }); |
| 90 | } |
| 91 | } |
| 92 | return results; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Async lint pass: HEAD-checks every remote media URL in the HTML. |
no test coverage detected