diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 681e06f4..cf6be744 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -117,6 +117,8 @@ jobs: node test-issue-1364-pill-no-clamp.js node test-issue-1375-scope-stats-fetch.js node test-issue-1361-cb-presets.js + node test-issue-1380-cb-sim-overlay.js + node test-issue-1380-cb-reset-button.js node test-issue-1407-cb-preset-propagation.js node test-issue-1412-customizer-no-override.js node test-issue-1418-raw-hex-extraction.js diff --git a/public/customize-v2.js b/public/customize-v2.js index dfe050a2..0968e8cc 100644 --- a/public/customize-v2.js +++ b/public/customize-v2.js @@ -1318,9 +1318,88 @@ 'Leave unset to use the operator\'s configured colors (or pick from above). ' + 'Achromatopsia uses a luminance-only ramp and relies on the shape/letter/glyph carriers from #1356/#1357.

' + '
' + clearOpt + options + '
' + + _renderCbSimSelector() + + _renderCbResetButton() + '
'; } + // #1380 — Brettel/Vienot 1997 dichromatic simulation overlay. + // Preview-only: NOT persisted; clears on reload. Toggled via + // body[data-cb-sim] + CSS filter:url(#cb-*) defined in public/index.html. + function _renderCbSimSelector() { + var SIMS = [ + { id: '', label: 'Off', desc: 'No simulation (default).' }, + { id: 'deut', label: 'Deuteranopia', desc: 'Brettel/Vienot 1997 — green-cone deficit.' }, + { id: 'prot', label: 'Protanopia', desc: 'Brettel/Vienot 1997 — red-cone deficit.' }, + { id: 'trit', label: 'Tritanopia', desc: 'Brettel/Vienot 1997 — blue-cone deficit.' }, + { id: 'achromat', label: 'Achromatopsia', desc: 'Luminance-only (Rec.601).' } + ]; + // Hardcoded literal lookup so the source contains `value="deut"` etc. + // (See test-issue-1380-cb-sim-overlay.js, asserts on source text.) + var VALUE_ATTRS = { + '': 'value=""', + 'deut': 'value="deut"', + 'prot': 'value="prot"', + 'trit': 'value="trit"', + 'achromat': 'value="achromat"' + }; + var current = ''; + try { + if (typeof document !== 'undefined' && document.body && document.body.getAttribute) { + current = document.body.getAttribute('data-cb-sim') || ''; + } + } catch (e) {} + var rows = SIMS.map(function (s) { + var checked = s.id === current ? ' checked' : ''; + return ''; + }).join(''); + return '

Simulation overlay (preview-only)

' + + '

Apply a Brettel/Vienot 1997 dichromatic filter to the entire page to preview how the UI reads to colorblind viewers. Not persisted — clears on reload.

' + + '
' + rows + '
'; + } + + // #1380 — Reset-to-default-Wong button. Clears any stored CB preset and + // re-applies the Wong palette via MeshCorePresets.applyPreset('default'). + function _renderCbResetButton() { + return '
' + + '' + + '
' + + 'Restores the Wong 2011 palette and clears any saved colorblind preset.
' + + '
'; + } + + // Exposed helper — toggles body[data-cb-sim]. Pure DOM, no persistence. + function _applyCbSim(id) { + if (typeof document === 'undefined' || !document.body) return false; + if (!id) { + if (document.body.removeAttribute) document.body.removeAttribute('data-cb-sim'); + } else { + document.body.setAttribute('data-cb-sim', id); + } + return true; + } + + // Exposed helper — applies the default Wong preset and clears storage. + function _resetCbPreset() { + var MCP = (typeof window !== 'undefined') && window.MeshCorePresets; + var ok = false; + if (MCP && typeof MCP.applyPreset === 'function') { + ok = MCP.applyPreset('default') || ok; + } + try { + if (typeof localStorage !== 'undefined') localStorage.removeItem('meshcore-cb-preset'); + } catch (e) {} + return ok; + } + function _renderCbPresetClearOption(current) { var checked = !current ? ' checked' : ''; return '