fix: address PR review bot findings on background resolution

- Treat a url() image layer stacked above a gradient as an occluding,
  unreadable surface: resolveBackgroundInfo now returns unresolved so the
  gradient-stop fallback never measures stops the image hides
  (greptile-apps finding, reproduced in Chrome).
- Route the glow and AI-palette DOM adapters through resolveBackgroundInfo
  so an unresolved surface makes them abstain instead of hunting gradient
  ancestors past an unreadable layer (Cursor Bugbot finding).
- Resolve background-color keywords jsdom hands through verbatim:
  inherit now reads as no-paint (the ancestor walk IS its resolution) and
  currentcolor substitutes the element's own computed text color instead
  of forcing an abstention (Copilot finding).
- Regression coverage in the dark-theme fixture for all three, asserted in
  both the jsdom and real-Chrome suites; browser detector regenerated.

AI-assisted: prepared with Claude Code at the maintainer's direction.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-08-09 16:00:51 -07:00
co-authored by Claude
parent 331af89eae
commit 6df96fbced
6 changed files with 157 additions and 20 deletions
+9 -1
View File
@@ -548,10 +548,18 @@ function parseAnyColor(s) {
// True when a computed background-color string names no paint at all. Used to
// tell "this layer is see-through" (walk on to the ancestor) apart from "this
// layer has a color we could not read" (stop and abstain).
//
// `inherit` belongs here even though it is not literally see-through: it means
// "paint with the parent's background-color", and walking on to the parent IS
// that resolution. Real browsers resolve the keyword before getComputedStyle
// output; only jsdom's partial cascade hands it through verbatim, and treating
// it as unreadable would make the walk abstain on a surface it can know.
// (`currentcolor` is NOT here — it is real paint in the element's own text
// color; resolveBackgroundInfo substitutes the computed color for it.)
function isNoPaintColorValue(value) {
const v = String(value || '').trim().toLowerCase();
if (!v) return true;
return v === 'transparent' || v === 'none' || v === 'initial' || v === 'unset' || v === 'revert' || v === 'revert-layer';
return v === 'transparent' || v === 'none' || v === 'initial' || v === 'inherit' || v === 'unset' || v === 'revert' || v === 'revert-layer';
}
export {