Refactor the two new modules to clear the flagged patterns without any
behavior change:
- Build the search dropdown with DOM nodes + textContent instead of
innerHTML string concatenation, removing the XSS sinks and the manual
escapeHtml helper it needed.
- Replace numeric index access (index[i], terms[j], opts[idx],
currentResults[i]) with array iteration methods, NodeList.item(), and
Array.prototype.at() to clear detect-object-injection.
- Use === via a shared termsMatch() helper, optional-catch binding, and
drop a useless initial assignment.
Verified with ESLint (eslint:recommended + eslint-plugin-security) at zero
findings and re-ran the headless-Chromium behavior test (tooltip, per-tab
filter, global search navigation) — all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014gZxznuxw8L92FUMBN3Nqz
Help users quickly find settings and understand how each one works.
Tooltips: a new delegated controller (static/v3/js/tooltips.js) drives an
accessible (i) info tooltip that appears on hover, keyboard focus, and tap.
A shared `help_tip` Jinja macro (partials/_macros.html) emits the trigger;
the plugin config macro and the core settings partials now surface help
text through it. Per the design, the always-visible field help paragraphs
are folded into the tooltip to declutter the forms, and the hardware/display
settings carry authored detail (default, range, recommendation).
Search: a global header search box finds settings across every settings tab
— even ones not yet opened — via a lazy client-side index built by scanning
the same field markup (static/v3/js/settings-search.js). Selecting a result
switches tabs, waits for the field to load, then scrolls to and flashes it.
A per-tab filter box hides non-matching fields on the current tab.
Plugin settings get tooltips for free by reusing each field's schema
`description`; every settings field also gets a stable `setting-<tab>-<key>`
anchor id for search navigation.
Styling uses the existing --color-* theme vars so light/dark mode both work,
and honors prefers-reduced-motion. Adds Flask render smoke tests that assert
each settings partial ships tooltips, anchors, and a filter box.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014gZxznuxw8L92FUMBN3Nqz