(assetsList: HTMLElement)
| 32 | } |
| 33 | |
| 34 | async function addCounts(assetsList: HTMLElement): Promise<void> { |
| 35 | // Both pages have .Box but in the list .Box doesn't include the tag |
| 36 | const container = closestElementOptional('section', assetsList) // Single-release page |
| 37 | ?? closestElement('.Box:not(.Box--condensed)', assetsList); // Releases list, excludes the assets list’s own .Box |
| 38 | |
| 39 | // .octicon-code required by visit-tag feature |
| 40 | const releaseName = $(['.octicon-tag ~ span', '.octicon-code ~ span'], container) |
| 41 | .textContent |
| 42 | .trim(); |
| 43 | |
| 44 | const assets = await getAssetsForTag(releaseName); |
| 45 | |
| 46 | const calculateHeatIndex = createHeatIndexFunction(Object.values(assets)); |
| 47 | for (const assetLink of $$('.octicon-package ~ a', assetsList)) { |
| 48 | // Match the asset in the DOM to the asset in the API response |
| 49 | const downloadCount = assets[assetLink.pathname.split('/').pop()!] ?? 0; |
| 50 | |
| 51 | // Re-align the asset size |
| 52 | const assetSize = $(':scope > .flex-justify-end > span:has(+ span relative-time)', closestElement('.Box-row', assetLink)); |
| 53 | assertNodeContent(assetSize.firstChild, /^\d+(?:\.\d+)? \w{2,5}$/); |
| 54 | |
| 55 | assetSize.classList.replace('text-sm-left', 'text-md-right'); |
| 56 | |
| 57 | const classes = getClasses(assetSize); |
| 58 | if (downloadCount === 0) { |
| 59 | // Don't show, but preserve space/column |
| 60 | classes.add('v-hidden'); |
| 61 | } |
| 62 | |
| 63 | // Add class to parent in order to define "columns" |
| 64 | assetSize.parentElement!.classList.add('rgh-release-download-count', 'gap-4'); |
| 65 | |
| 66 | const hash = $optional(':scope > div:has(clipboard-copy)', assetSize.parentElement!); |
| 67 | // Hide sha on mobile. They have the classes but they're not correct (they hide in mid sizes, but show on smallest and largest) |
| 68 | hash?.classList.add('d-none'); |
| 69 | // Prevent sha from being clipped |
| 70 | hash?.style.setProperty('min-width', '100px'); |
| 71 | |
| 72 | // Add at the beginning of the line to avoid content shift |
| 73 | assetSize.parentElement!.prepend( |
| 74 | <span className={cx(getClasses(assetSize))}> |
| 75 | <span |
| 76 | className="d-inline-block text-right" |
| 77 | title={`${downloadCount} downloads`} |
| 78 | data-rgh-heat={calculateHeatIndex(downloadCount)} |
| 79 | > |
| 80 | {abbreviateNumber(downloadCount)} <DownloadIcon /> |
| 81 | </span> |
| 82 | </span>, |
| 83 | ); |
| 84 | |
| 85 | // Unset all margin we added `gap` like sane people. |
| 86 | // Unset via JS because we can't override utility classes. |
| 87 | for (const column of assetSize.parentElement!.children) { |
| 88 | (column as HTMLElement).style.setProperty('margin', '0', 'important'); |
| 89 | } |
| 90 | } |
| 91 | } |
nothing calls this directly
no test coverage detected