/* Paste into the Firefox console (F12) on the graph page, WITHOUT the extension. * Prints and copies a summary of the graph, which is what is needed to adjust the * parser if the graph generator ever changes shape. * * Firefox may require typing "allow pasting" in the console first. */ (() => { const RE = /_required=(true|false)\/_validated=(true|false)\/_accessible=(true|false)\/([^"]+)"-\d+$/; const nodes = []; const skipped = []; document.querySelectorAll('svg g.node').forEach((g) => { const id = g.getAttribute('id') || ''; const m = id.match(RE); if (!m) { skipped.push(id); return; } const [, required, validated, accessible, path] = m; const seg = path.split('/'); const link = g.querySelector('a'); const label = g.querySelector('.nodeLabel'); nodes.push({ slug: seg[seg.length - 1].replace(/~/g, '-'), project: seg[seg.length - 2], label: label ? label.textContent.trim() : '', href: link ? link.getAttribute('href') || '' : '', required: required === 'true', validated: validated === 'true', accessible: accessible === 'true', }); }); const count = (fn) => nodes.filter(fn).length; const report = { url: location.href, total: nodes.length, counts: { validated: count((n) => n.validated), requiredLeft: count((n) => !n.validated && n.accessible && n.required), bonusLeft: count((n) => !n.validated && n.accessible && !n.required), locked: count((n) => !n.validated && !n.accessible), }, skippedIds: skipped, // start/end markers land here, that is expected nodes, sampleHtml: document.querySelector('svg g.node')?.outerHTML.slice(0, 900) || '', }; console.log(report); (navigator.clipboard?.writeText(JSON.stringify(report, null, 2)) || Promise.reject()).then( () => console.log('%c copied to clipboard', 'color:#22c55e'), () => console.log('%c clipboard refused — right-click the object above > Copy', 'color:#f59e0b') ); return report; })();