diff --git a/docs/assets/cve.js b/docs/assets/cve.js index ed1b8d49a7..54eabe4d9a 100644 --- a/docs/assets/cve.js +++ b/docs/assets/cve.js @@ -6,14 +6,12 @@ const titleEl = document.getElementById("cve-title"); const summaryEl = document.getElementById("cve-summary"); const metaEl = document.getElementById("cve-meta"); - const descEl = document.getElementById("cve-description"); const factsEl = document.getElementById("cve-facts"); const pocRowsEl = document.getElementById("cve-poc-rows"); const kevRowsEl = document.getElementById("kev-rows"); const detailSection = document.getElementById("cve-details"); const notFoundSection = document.getElementById("not-found"); - const descriptionBlock = document.getElementById("cve-description-block"); function setLoading(message) { titleEl.textContent = cveId || "CVE details"; @@ -133,14 +131,6 @@ titleEl.textContent = data.cve || cveId; const desc = getDescriptionText(data); summaryEl.textContent = desc; - const hasDescContent = desc && desc !== "No description available."; - if (hasDescContent) { - descEl.textContent = desc; - descriptionBlock.style.display = ""; - } else { - descEl.textContent = ""; - descriptionBlock.style.display = "none"; - } renderFacts(data); renderPocs(data.poc_links || data.poc || []); renderKev(data.kev); @@ -157,14 +147,6 @@ titleEl.textContent = fallback.cve; const desc = getDescriptionText(fallback); summaryEl.textContent = desc; - const hasDescContent = desc && desc !== "No description available."; - if (hasDescContent) { - descEl.textContent = desc; - descriptionBlock.style.display = ""; - } else { - descEl.textContent = ""; - descriptionBlock.style.display = "none"; - } renderFacts(fallback); renderPocs(fallback.poc_links || fallback.poc || []); renderKev(null); @@ -176,7 +158,6 @@ notFoundSection.style.display = ""; detailSection.style.display = "none"; metaEl.innerHTML = ""; - descriptionBlock.style.display = "none"; titleEl.textContent = cveId; summaryEl.textContent = "No data found for this CVE."; } diff --git a/docs/assets/site.js b/docs/assets/site.js index c46f72f3c3..4c459f0716 100644 --- a/docs/assets/site.js +++ b/docs/assets/site.js @@ -1,15 +1,110 @@ (function(){ - const filterInputs = document.querySelectorAll('[data-filter-table]'); - filterInputs.forEach(input => { - const tableId = input.dataset.filterTable; - const table = document.getElementById(tableId); - if (!table) return; - input.addEventListener('input', () => { - const term = input.value.trim().toLowerCase(); - for (const row of table.querySelectorAll('tbody tr')) { - const text = row.innerText.toLowerCase(); - row.style.display = text.includes(term) ? '' : 'none'; + let datasetPromise = null; + let pocSet = null; + + function fetchDataset() { + if (datasetPromise) return datasetPromise; + const candidates = [ + new URL('/CVE_list.json', window.location.origin).href, + new URL('CVE_list.json', window.location.href).href, + new URL('../CVE_list.json', window.location.href).href + ]; + datasetPromise = (async () => { + for (const url of candidates) { + try { + const res = await fetch(url, { cache: 'no-store' }); + if (!res.ok) continue; + const data = await res.json(); + return Array.isArray(data) ? data : []; + } catch (err) { + console.warn('Dataset fetch failed', err); + } + } + return []; + })(); + return datasetPromise; + } + + async function ensurePocSet() { + if (pocSet) return pocSet; + const dataset = await fetchDataset(); + pocSet = new Set( + dataset + .filter(item => Array.isArray(item.poc) && item.poc.length > 0) + .map(item => (item.cve || '').toUpperCase()) + ); + return pocSet; + } + + function bindColumnFilters() { + const filterInputs = document.querySelectorAll('[data-filter-table]'); + filterInputs.forEach(input => { + const tableId = input.dataset.filterTable; + const table = document.getElementById(tableId); + if (!table) return; + input.addEventListener('input', () => { + const term = input.value.trim().toLowerCase(); + for (const row of table.querySelectorAll('tbody tr')) { + const text = row.innerText.toLowerCase(); + row.style.display = text.includes(term) ? '' : 'none'; + } + }); + }); + } + + async function filterTablesByPoc() { + const set = await ensurePocSet(); + document.querySelectorAll('table[data-require-poc]').forEach(table => { + for (const row of Array.from(table.querySelectorAll('tbody tr'))) { + const link = row.querySelector('a'); + const idText = (link ? link.textContent : row.textContent || '').trim().toUpperCase(); + if (!set.has(idText)) { + row.remove(); + } } }); + } + + function truncate(text, limit = 140) { + if (!text) return ''; + return text.length > limit ? `${text.slice(0, limit - 1)}…` : text; + } + + async function renderTrending() { + const container = document.querySelector('[data-trending]'); + const tbody = document.getElementById('trending-body'); + if (!container || !tbody) return; + + const data = await fetchDataset(); + const trending = data + .filter(item => item && item.cve && Array.isArray(item.poc) && item.poc.length > 0) + .map(item => ({ cve: item.cve, desc: item.desc || 'No description available.', poc: item.poc })) + .sort((a, b) => { + const delta = (b.poc?.length || 0) - (a.poc?.length || 0); + if (delta !== 0) return delta; + return (b.cve || '').localeCompare(a.cve || ''); + }) + .slice(0, 12); + + if (trending.length === 0) { + tbody.innerHTML = '
| CVE | Vendor | Product | EPSS | Percentile | Date Added | Due |
|---|---|---|---|---|---|---|