Skip to content

fix: prevent querySelector crash on empty heading slug#4135

Open
Bowl42 wants to merge 2 commits intomarktext:developfrom
Bowl42:fix/queryselector-crash
Open

fix: prevent querySelector crash on empty heading slug#4135
Bowl42 wants to merge 2 commits intomarktext:developfrom
Bowl42:fix/queryselector-crash

Conversation

@Bowl42
Copy link

@Bowl42 Bowl42 commented Mar 4, 2026

Summary

Fixes #4087
Also fixes #4092 (duplicate)

When a heading has no text content or contains only special characters, the slugger produces an empty slug. This causes querySelector('#') to throw "Failed to execute 'querySelector': '#' is not a valid selector", crashing the renderer process.

Changes:

  • slugger.js: Return fallback slug 'heading' when content produces an empty slug (with deduplication support for multiple empty headings)
  • editor.vue: Add empty-slug guard in scrollToHeader and wrap querySelector in try/catch in scrollToElement
  • tableDragBarCtrl.js: Add null guards in calculateAspects, getAllTableCells, and getDragCells to prevent the same crash when table IDs are missing

Test plan

  • Add 14 unit tests for Slugger covering normal slugs, empty strings, whitespace-only input, special-character-only input, fallback deduplication, and collision with real headings (test/unit/specs/slugger.spec.js)
  • Manual: Create a heading with only special characters (e.g. # !@#$%), verify no crash
  • Manual: Create an empty heading (# with no text), click it in the TOC sidebar, verify no crash
  • Manual: Export a document with empty headings to PDF, verify no crash

🤖 Generated with Claude Code

Bowl42 and others added 2 commits March 4, 2026 21:23
When a heading has no text content or contains only special characters,
the slugger produces an empty slug. This causes querySelector('#') to
throw "Failed to execute 'querySelector': '#' is not a valid selector",
crashing the renderer process.

- Slugger now returns fallback 'heading' slug for empty content
- scrollToHeader guards against empty slug
- scrollToElement wraps querySelector in try/catch for invalid selectors
- tableDragBarCtrl guards against empty/missing table IDs
- Add comprehensive unit tests for Slugger including edge cases

Fixes marktext#4087

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add reverse-collision test: empty heading before real "heading"
- Add chained collision test: multiple empty + explicit "heading-1"
- Add Unicode tests: CJK characters, emoji-only, mixed ASCII+Unicode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant