Spaces:
Sleeping
Sleeping
| // Accept either the raw analysis body or the `/analysis` wrapper returned by the backend. | |
| function normalizeAnalysis(analysis) { | |
| return analysis && analysis.analysis ? analysis.analysis : analysis; | |
| } | |
| // Lets the modal recover constraint type labels even when the backend response omits them. | |
| function constraintTypeLookup(constraints) { | |
| return new Map((constraints || []).map((constraint) => [constraint.name, constraint.type])); | |
| } | |
| // Renders one analysis table into the modal container. | |
| function appendAnalysisSection(document, container, title, analysis, constraintTypes) { | |
| const analysisBody = normalizeAnalysis(analysis); | |
| if (!analysisBody || !Array.isArray(analysisBody.constraints)) return; | |
| if (container.childNodes.length) { | |
| container.appendChild(document.createElement('hr')); | |
| } | |
| const heading = document.createElement('h3'); | |
| heading.textContent = title; | |
| container.appendChild(heading); | |
| const scoreLine = document.createElement('p'); | |
| const scoreLabel = document.createElement('strong'); | |
| scoreLabel.textContent = 'Score:'; | |
| scoreLine.appendChild(scoreLabel); | |
| scoreLine.appendChild(document.createTextNode(` ${String(analysisBody.score || '—')}`)); | |
| container.appendChild(scoreLine); | |
| const table = document.createElement('table'); | |
| table.className = 'sf-table'; | |
| const thead = document.createElement('thead'); | |
| const headerRow = document.createElement('tr'); | |
| ['Constraint', 'Type', 'Score', 'Matches'].forEach((label) => { | |
| const cell = document.createElement('th'); | |
| cell.textContent = label; | |
| headerRow.appendChild(cell); | |
| }); | |
| thead.appendChild(headerRow); | |
| table.appendChild(thead); | |
| const tbody = document.createElement('tbody'); | |
| analysisBody.constraints.forEach((constraint) => { | |
| const row = document.createElement('tr'); | |
| [ | |
| constraint.name || '', | |
| constraint.constraintType || constraint.type || constraintTypes.get(constraint.name) || '', | |
| constraint.score || '', | |
| String(constraint.matchCount != null ? constraint.matchCount : 0), | |
| ].forEach((value) => { | |
| const cell = document.createElement('td'); | |
| cell.textContent = String(value); | |
| row.appendChild(cell); | |
| }); | |
| tbody.appendChild(row); | |
| }); | |
| table.appendChild(tbody); | |
| container.appendChild(table); | |
| } | |
| // Builds DOM content instead of raw HTML so tests can verify escaping and structure. | |
| export function buildAnalysisBody(document, analysis, constraints = []) { | |
| const analysisBody = normalizeAnalysis(analysis); | |
| const constraintTypes = constraintTypeLookup(constraints); | |
| const container = document.createElement('div'); | |
| if (!analysisBody || !Array.isArray(analysisBody.constraints)) { | |
| const empty = document.createElement('p'); | |
| empty.textContent = 'No analysis available.'; | |
| container.appendChild(empty); | |
| return container; | |
| } | |
| appendAnalysisSection(document, container, 'Current retained snapshot', analysisBody, constraintTypes); | |
| return container; | |
| } | |