From 2a8db06f0d777760ce4884b2d07343a0cb47f2ce Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Wed, 18 Mar 2026 11:04:07 +0000 Subject: [PATCH] Fix: load adjusted score when reopening document from history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit handleResult() now overlays accessibility_score/wcag_compliance from .adjusted.json (if it exists) while keeping the original severity_counts as the recalculation baseline — prevents double-subtraction. displayResults() auto-calls applyScoreRecalc() on load when the result was previously adjusted, restoring the (Adjusted) label and WCAG badges without triggering another server save. Co-Authored-By: Claude Sonnet 4.6 --- api.php | 12 ++++++++++++ js/results.js | 23 +++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/api.php b/api.php index 383d2e1..3dee428 100644 --- a/api.php +++ b/api.php @@ -673,6 +673,18 @@ function handleResult() { $result = json_decode(file_get_contents($result_file), true); + // If an adjusted result exists, overlay only the score/wcag fields so the + // frontend can display the adjusted score on reload while keeping the original + // severity_counts and score_breakdown as the recalculation baseline. + $adjusted_file = RESULTS_DIR . '/' . $job_id . '.adjusted.json'; + if (file_exists($adjusted_file)) { + $adjusted = json_decode(file_get_contents($adjusted_file), true); + $result['accessibility_score'] = $adjusted['accessibility_score'] ?? $result['accessibility_score']; + $result['grade'] = $adjusted['grade'] ?? $result['grade']; + $result['wcag_compliance'] = $adjusted['wcag_compliance'] ?? $result['wcag_compliance']; + $result['score_breakdown']['adjusted'] = true; + } + // Inject dismissed indices so frontend can restore dismiss state on reload $dismiss_file = RESULTS_DIR . '/' . $job_id . '.dismissed.json'; $result['dismissed_indices'] = file_exists($dismiss_file) diff --git a/js/results.js b/js/results.js index f74d08f..65ffce8 100644 --- a/js/results.js +++ b/js/results.js @@ -58,6 +58,10 @@ function displayResults(data) { displayScoreBreakdown(data.score_breakdown); renderRecalcButton(); displayIssues(allIssues); + // If this result was previously adjusted, restore the adjusted view without saving again + if (data.score_breakdown?.adjusted && (dismissedIndices.size > 0 || overriddenChecks.size > 0)) { + applyScoreRecalc(); + } initializePageViewer(data); displayRemediationOptions(data); lastMatterhornData = data.matterhorn_summary || null; @@ -623,8 +627,9 @@ function renderRecalcButton() { if (btn) btn.style.display = 'inline-block'; } -async function recalculateScore() { - if (!scoreBreakdownData || !originalSeverityCounts) return; +// Pure DOM update — called both on user action and on initial load of adjusted result +function applyScoreRecalc() { + if (!scoreBreakdownData || !originalSeverityCounts) return null; const bd = scoreBreakdownData; const origSC = originalSeverityCounts; @@ -645,7 +650,7 @@ async function recalculateScore() { const new_passed = Math.min(bd.checks_total, bd.checks_passed + overriddenChecks.size); const new_base = bd.checks_total > 0 ? Math.round(100 * new_passed / bd.checks_total) : 0; - // 4. Final score + grade + // 4. Final score const new_score = Math.max(0, new_base - new_penalty); // 5. Update DOM @@ -656,7 +661,7 @@ async function recalculateScore() { updateStatsGrid(adj_crit, adj_err); updateBreakdownSummary(new_passed, bd.checks_total, new_base, new_penalty, new_score); - // 6. Recompute WCAG compliance badges based on remaining non-dismissed issues + // 6. Recompute WCAG compliance badges const failingA = [], failingAA = []; allIssues.forEach((issue, idx) => { if (dismissedIndices.has(idx)) return; @@ -675,8 +680,14 @@ async function recalculateScore() { level_aa_failures: failingAA, }); - // 7. Persist adjusted result to server so history + exports reflect the new score - if (!currentJobId) return; + return new_score; +} + +async function recalculateScore() { + const new_score = applyScoreRecalc(); + if (new_score === null || !currentJobId) return; + + // Persist adjusted result so history + exports reflect the new score try { const btn = document.getElementById('recheckBtn'); if (btn) { btn.disabled = true; btn.textContent = 'Saving…'; }