Fix live detector empty state (#190)

* Fix live detector empty state

* Fix live detector stale scan results
This commit is contained in:
Abdul Wahab
2026-06-01 14:44:45 -07:00
committed by GitHub
parent 3f8d002b76
commit 69b5f3af49
44 changed files with 853 additions and 224 deletions
@@ -1437,13 +1437,20 @@ if (IS_BROWSER) {
return true;
}
function postSerializedFindings(groupMap) {
function scanResultMeta(options = {}) {
const scanId = options.scanId;
if (typeof scanId !== 'string' && typeof scanId !== 'number') return {};
return { scanId: String(scanId) };
}
function postSerializedFindings(groupMap, options = {}) {
if (!EXTENSION_MODE) return;
const allFindings = browserFindingsFromMap(groupMap);
window.postMessage({
source: 'impeccable-results',
findings: serializeFindings(allFindings),
count: allFindings.length,
...scanResultMeta(options),
}, '*');
}
@@ -1497,7 +1504,7 @@ if (IS_BROWSER) {
rememberVisualContrastAnalysis(result);
const added = addVisualContrastResult(groupMap, result, { decorate: true });
if (added) {
postSerializedFindings(groupMap);
postSerializedFindings(groupMap, options);
window.dispatchEvent(new CustomEvent('impeccable-visual-contrast-resolved', {
detail: {
selector: result.selector,
@@ -1565,7 +1572,7 @@ if (IS_BROWSER) {
overlayIndex = 0;
}
function renderBrowserFindings(collected) {
function renderBrowserFindings(collected, options = {}) {
const { allFindings, pageLevelFindings } = collected;
for (const { el, findings } of allFindings) {
@@ -1585,6 +1592,7 @@ if (IS_BROWSER) {
source: 'impeccable-results',
findings: serializeFindings(allFindings),
count: allFindings.length,
...scanResultMeta(options),
}, '*');
}
@@ -1599,11 +1607,11 @@ if (IS_BROWSER) {
clearOverlays();
const generation = scanGeneration;
const collected = collectBrowserFindings();
const allFindings = renderBrowserFindings(collected);
const allFindings = renderBrowserFindings(collected, options);
if (shouldRunVisualContrast(options)) {
addVisualContrastFindings(collected.groupMap, options, { decorate: true, generation })
.then(() => {
if (generation === scanGeneration) postSerializedFindings(collected.groupMap);
if (generation === scanGeneration) postSerializedFindings(collected.groupMap, options);
})
.catch(err => {
reportVisualContrastError(err);
@@ -1618,10 +1626,10 @@ if (IS_BROWSER) {
if (shouldRunVisualContrast(options)) {
const collected = await collectBrowserFindingsAsync(options, { generation, scheduleLazy: true });
if (generation !== scanGeneration) return [];
return renderBrowserFindings(collected);
return renderBrowserFindings(collected, options);
}
lastVisualContrastAnalyses = [];
return renderBrowserFindings(collectBrowserFindings());
return renderBrowserFindings(collectBrowserFindings(), options);
};
const detect = function(options = {}) {
@@ -4253,13 +4253,20 @@ if (IS_BROWSER) {
return true;
}
function postSerializedFindings(groupMap) {
function scanResultMeta(options = {}) {
const scanId = options.scanId;
if (typeof scanId !== 'string' && typeof scanId !== 'number') return {};
return { scanId: String(scanId) };
}
function postSerializedFindings(groupMap, options = {}) {
if (!EXTENSION_MODE) return;
const allFindings = browserFindingsFromMap(groupMap);
window.postMessage({
source: 'impeccable-results',
findings: serializeFindings(allFindings),
count: allFindings.length,
...scanResultMeta(options),
}, '*');
}
@@ -4313,7 +4320,7 @@ if (IS_BROWSER) {
rememberVisualContrastAnalysis(result);
const added = addVisualContrastResult(groupMap, result, { decorate: true });
if (added) {
postSerializedFindings(groupMap);
postSerializedFindings(groupMap, options);
window.dispatchEvent(new CustomEvent('impeccable-visual-contrast-resolved', {
detail: {
selector: result.selector,
@@ -4381,7 +4388,7 @@ if (IS_BROWSER) {
overlayIndex = 0;
}
function renderBrowserFindings(collected) {
function renderBrowserFindings(collected, options = {}) {
const { allFindings, pageLevelFindings } = collected;
for (const { el, findings } of allFindings) {
@@ -4401,6 +4408,7 @@ if (IS_BROWSER) {
source: 'impeccable-results',
findings: serializeFindings(allFindings),
count: allFindings.length,
...scanResultMeta(options),
}, '*');
}
@@ -4415,11 +4423,11 @@ if (IS_BROWSER) {
clearOverlays();
const generation = scanGeneration;
const collected = collectBrowserFindings();
const allFindings = renderBrowserFindings(collected);
const allFindings = renderBrowserFindings(collected, options);
if (shouldRunVisualContrast(options)) {
addVisualContrastFindings(collected.groupMap, options, { decorate: true, generation })
.then(() => {
if (generation === scanGeneration) postSerializedFindings(collected.groupMap);
if (generation === scanGeneration) postSerializedFindings(collected.groupMap, options);
})
.catch(err => {
reportVisualContrastError(err);
@@ -4434,10 +4442,10 @@ if (IS_BROWSER) {
if (shouldRunVisualContrast(options)) {
const collected = await collectBrowserFindingsAsync(options, { generation, scheduleLazy: true });
if (generation !== scanGeneration) return [];
return renderBrowserFindings(collected);
return renderBrowserFindings(collected, options);
}
lastVisualContrastAnalyses = [];
return renderBrowserFindings(collectBrowserFindings());
return renderBrowserFindings(collectBrowserFindings(), options);
};
const detect = function(options = {}) {
@@ -6088,6 +6088,10 @@ void main() {
let steerFocusRecoverTimer = null;
const STEER_PAGE_FOCUS_PAUSE_MS = 500;
let detectActive = false;
let detectScanSeq = 0;
let activeDetectScanId = null;
let pendingDetectScanId = null;
const DETECT_EMPTY_MESSAGE = 'No detector issues found.';
const PICK_PREFS_KEY = 'impeccable-live-pick';
const INTERACTION_PREFS_KEY = 'impeccable-live-interaction';
const PLACEHOLDER_DEFAULT_HEIGHT = 80;
@@ -7601,6 +7605,17 @@ void main() {
let detectReady = false; // true once detect script posts 'impeccable-ready'
let detectPendingScan = false; // scan requested before script was ready
function requestDetectScan() {
const scanId = String(++detectScanSeq);
activeDetectScanId = scanId;
pendingDetectScanId = scanId;
window.postMessage({
source: 'impeccable-command',
action: 'scan',
config: { scanId },
}, '*');
}
function toggleDetect() {
if (pendingApplyInFlight) { showManualApplyBusyToast(); return; }
detectActive = !detectActive;
@@ -7611,12 +7626,14 @@ void main() {
detectPendingScan = true;
loadDetectScript();
} else if (detectReady) {
window.postMessage({ source: 'impeccable-command', action: 'scan' }, '*');
requestDetectScan();
} else {
detectPendingScan = true;
}
} else {
window.postMessage({ source: 'impeccable-command', action: 'remove' }, '*');
activeDetectScanId = null;
pendingDetectScanId = null;
detectCount = 0;
updateGlobalBarState();
}
@@ -7686,12 +7703,18 @@ void main() {
detectReady = true;
if (detectPendingScan && detectActive) {
detectPendingScan = false;
window.postMessage({ source: 'impeccable-command', action: 'scan' }, '*');
requestDetectScan();
}
}
// Scan results arrived
if (e.data.source === 'impeccable-results') {
if (!detectActive) return;
if (activeDetectScanId && e.data.scanId !== activeDetectScanId) return;
detectCount = e.data.count || 0;
if (detectActive && pendingDetectScanId && detectCount === 0) {
showToast(DETECT_EMPTY_MESSAGE, 3200);
}
pendingDetectScanId = null;
updateGlobalBarState();
}
}