Skip to content

Keep the keyboard focus where it was when a revealjs presentation is shown again - #15090

Open
jooyoungseo wants to merge 2 commits into
quarto-dev:mainfrom
jooyoungseo:bugfix/15079-revealjs-visibility-focus
Open

jooyoungseo wants to merge 2 commits into
quarto-dev:mainfrom
jooyoungseo:bugfix/15079-revealjs-visibility-focus

Conversation

@jooyoungseo

@jooyoungseo jooyoungseo commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Fixes #15079.

Each time the page becomes visible again, for example after switching tabs, the bundled reveal.js moved the focus to <body> if anything else had it (onPageVisibilityChange()). A reader lost their place on a link or in a chart. NVDA and JAWS, which pass the arrow keys on only while the focus is in the deck, went back to browse mode.

reveal.js does this "to ensure we can use keyboard shortcuts". But keys pressed on a link or a button reach it anyway: it ignores keys only in inputs, text areas and editable content. The keys it cannot get are the ones pressed inside a frame. So the new source patch revealjs-0003-focus-on-return.patch moves the focus only out of a frame, and onto the deck (with tabindex="-1") rather than the body. It blurs the frame first, as reveal.js did: Playwright's Firefox, which CI runs, otherwise leaves the focus in the frame. Anywhere else, the focus stays where the reader left it.

The patch follows #15020 and #15034. update-html-dependencies.ts applies it after 0001 and 0002, and the bundles and maps are rebuilt from 5.1.0 with npm ci --ignore-scripts and gulp js, as that step does. Before adding the patch, the same build with 0001 and 0002 alone reproduced all four committed files byte for byte. That needed the sources the committed maps embed with CRLF line endings to have CRLF line endings in the build too. With 0003, only js/reveal.js's source and the mappings change in the maps.

Every reveal.js release from 3.9.2 to 6.0.2 does this, so I'm reporting it to reveal.js as well.

Validation

  • revealjs-visibility-focus.spec.ts, with a new fixture, checks what happens after the page is hidden and shown again:

    • a focused link keeps the focus;
    • a focused frame hands it to the deck;
    • the deck keeps it;
    • a focus on the body stays there;
    • after the first two, → still changes slides.

    Playwright does not hide the page when another tab comes to the front, so the test marks the page hidden and then visible and dispatches visibilitychange. The first three fail without the patch.

  • All revealjs Playwright specs pass in Chromium, except revealjs-multiplex.spec.ts, which needs the multiplex server that the CI wrapper starts. revealjs-visibility-focus.spec.ts also passes in Firefox 158 over WebDriver BiDi. WebKit and Playwright's own Firefox were not run locally.

  • The three patches apply in order to a pristine 5.1.0 tree with git apply --ignore-space-change.

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 (revealjs Playwright specs in Chromium only; full suite not run)
  • added new tests
  • created a separate documentation PR in Quarto's website repo and linked it to this PR (not applicable)
AI-assisted PR

Generated by Claude Code

…shown again

The bundled reveal.js moves the focus to the body each time the page
becomes visible, if anything else had it (onPageVisibilityChange).
Switching tabs and back therefore took a reader off the link or chart
they were on, and NVDA and JAWS, which pass the arrow keys on only while
the focus is in the deck, went back to browse mode.

reveal.js does this so that its shortcuts work after the reader clicked
into something, but keys pressed on a link or a button reach it anyway.
Only keys pressed inside a frame do not, so the new revealjs-0003 patch
moves the focus only out of a frame, and onto the deck rather than the
body. The bundles are rebuilt from 5.1.0 with the three patches; with
patches 0001 and 0002 alone the same build reproduces the current
bundles byte for byte.

Fixes quarto-dev#15079
@jooyoungseo
jooyoungseo requested review from cderv and a balanced review from Copilot October 16, 2026 16:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@posit-snyk-bot

posit-snyk-bot commented Oct 16, 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.

The test of a frame handing the focus to the deck failed in Firefox on CI.
Playwright's Firefox emulates a focused page by skipping the blur when the
focus leaves a document, so focusing the deck straight from a frame left
the focus in the frame. Blurring the frame first, as reveal.js did before
moving the focus to the body, takes the focus out of the frame, and
focusing the deck then works. Firefox 158 moves the focus either way.
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.

revealjs: switching to another tab and back moves the keyboard focus to the page body

3 participants