Skip to content

Fix axe scan hiding the current revealjs slide after navigation - #15030

Merged
cderv merged 2 commits into
mainfrom
fix/axe-reveal-restore-current-slide
Oct 12, 2026
Merged

cderv merged 2 commits into
mainfrom
fix/axe-reveal-restore-current-slide

Conversation

@cderv

@cderv cderv commented Oct 12, 2026

Copy link
Copy Markdown
Member

With axe enabled in a revealjs presentation, moving to another slide while the scan runs leaves the new current slide with hidden and aria-hidden="true". Screen readers skip it until the next navigation. With output: console or output: json nothing navigates after the scan, so the state stays wrong.

Root cause

Since #14125 (first shipped in v1.9.26), the axe checker removes hidden and aria-hidden from every slide so axe can check off-screen slides, then puts them back once axe.run resolves. The values put back are a snapshot taken before the scan, so a slide change in between gives the new current slide its old hidden state. #15010 already recomputes inert from the live Reveal state at that point, but hidden and aria-hidden were still replayed from the snapshot.

Fix

revealRestoreSlides() in src/resources/formats/html/axe/axe-check.js no longer replays the saved values on the current slide and its vertical stack, and uses the same check for inert. Other slides get their saved values back, and reveal.js has already hidden the slide that was left.

The new Playwright test navigates as soon as the scan unhides the slides. It fails before the fix, including on v1.10.19, and passes after.

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes
  • updated the appropriate changelog in the PR
  • ensured the present test suite passes
  • added new tests
  • created a separate documentation PR in Quarto's website repo and linked it to this PR
AI-assisted PR
  • AI tool used: Claude Code
  • Codebase grounding: local clone
  • Human review: I have reviewed, tested, and verified the AI-generated content before submitting.

Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.

To let axe check every slide, the scan strips hidden, aria-hidden and
inert from all slides and restores them afterwards. inert was already
recomputed from the live Reveal state, but hidden and aria-hidden were
replayed from the snapshot taken before the scan. Moving to another
slide while axe.run is pending therefore put aria-hidden="true" back on
the slide now on screen, hiding it from screen readers until the next
navigation. The console and json output modes never navigate after the
scan, so nothing corrected it.

Skip replaying the saved attributes for the current slide (and the
stack containing it) and apply the same check to inert. Other slides
keep their saved values, and reveal.js has already hidden the slide
that was left.
@posit-snyk-bot

posit-snyk-bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cderv
cderv merged commit a2c9322 into main Oct 12, 2026
51 checks passed
@cderv
cderv deleted the fix/axe-reveal-restore-current-slide branch October 12, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants