Skip to content

Fix website listings stacking update handlers on hash change - #15214

Merged
cderv merged 2 commits into
mainfrom
fix/listing-hashchange-stacking
Oct 27, 2026
Merged

cderv merged 2 commits into
mainfrom
fix/listing-hashchange-stacking

Conversation

@cderv

@cderv cderv commented Oct 27, 2026

Copy link
Copy Markdown
Member

Website listings attached another list.on("updated") handler on every URL hash change, and a page with several listings started with extra ones, so a single listing update reran the same work several times. Found while reviewing #9469, details in #15206.

Fix

window["quarto-listing-loaded"] now wires each listing once, keyed by its id, and the hash handling moved to its own applyListingHash(). The hashchange listener emitted for each listing in website-listing-template.ts is replaced by a single one in quarto-listing.js that only applies the hash. That listener came from 962d83d for #1139, and back/forward between categories still relies on it.

applyListingHash() returns early when no listing is registered yet, as the single listener is now attached before any listing script runs.

Tests

listing-interactions.spec.ts pins the current category, page hash, back/forward, progressive image and no-matching behavior on a page with two paginated listings. It passes before and after the fix.

listing-update-handlers.spec.ts counts handler runs for one list.update(). Before the fix, the first listing ran it 2 times after load, and the two listings 8 and 7 times after three hash changes. It is now 1 in every case.

Fixes #15206

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.

cderv added 2 commits October 27, 2026 16:04
quarto-listing-loaded both applied the URL hash and attached list.on("updated")
to every listing registered so far. Each listing's inline script called it on
DOMContentLoaded and again from its own window hashchange listener, so the
first of two listings started with two handlers and every hash change added
one handler per listing on the page to each listing.

The hashchange listener was added in 962d83d for #1139 and only needs the
hash part; back/forward between categories relies on it too. Wiring is now
guarded per listing id, and a single hashchange listener in quarto-listing.js
only applies the hash.

Fixes #15206
@posit-snyk-bot

posit-snyk-bot commented Oct 27, 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 4906587 into main Oct 27, 2026
52 checks passed
@cderv
cderv deleted the fix/listing-hashchange-stacking branch October 27, 2026 16:07
cderv added a commit that referenced this pull request Oct 28, 2026
A click on a page link in a website listing ran list.update() twice,
so every "updated" handler ran twice per click. Quarto's link onclick
called showPage() on top of list.js's own pagination click listener,
which also shows the page. The onclick now only records the page in the
URL hash and leaves showing the page to list.js.

See #15214
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.

Website listings add another update handler on every URL hash change

2 participants