vitepress
vitepress copied to clipboard
Can't auto generate anchor when only special characters are there in heading
Describe the bug
If the md file’s h2 title start with special character,
page can't scroll to the right place as usual when I click toc in .VPDocAsideOutline , on the right side of the web,
Reproduction
For example: The md file is like this:
# Reading
...
...
## `- + * /`
...
...
If I click toc in .VPDocAsideOutline , on the right side of the web,
the page can't scroll to the right place as usual.
Chrome terminal report :
DOMException: Failed to execute 'querySelector' on 'Document': '#-5' is not a valid selector.
at c (https://www.gyhyfj.com/assets/app.4bd937d4.js:1:124560)
at $t (https://www.gyhyfj.com/assets/app.4bd937d4.js:1:12734)
at qe (https://www.gyhyfj.com/assets/app.4bd937d4.js:1:12813)
at HTMLAnchorElement.n (https://www.gyhyfj.com/assets/app.4bd937d4.js:1:56875)
System Info
System:
OS: Windows 10 10.0.19044
CPU: (8) x64 Intel(R) Core(TM) i5-9300H CPU @ 2.40GHz
Memory: 1.59 GB / 7.92 GB
Binaries:
Node: 16.16.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.18 - ~\AppData\Roaming\npm\yarn.CMD
npm: 8.15.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: Spartan (44.19041.1266.0), Chromium (103.0.1264.62)
Internet Explorer: 11.0.19041.1566
Validations
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
begin with special char
No, its actually when heading "only" has special characters 😅.
One way to fix this is to generate IDs using the hash of the section's content (like Bikeshed does), so that the generated ID is relatively stable.
Another way is to use something like generateID-1, but if a new section is inserted before this section, the id of this section will change.
The fixed should be applied here - it's the slugify function used in VitePress. We should add a valid leading char if it is not after all the transforms.
/cc @meteorlxy
I think a better fix would be to use document.getElementById() instead of querySelector() as a hash always refers to an id and it's always unique in the page. getElementById() supports more characters like $ that are used in titles for properties (especially in API docs) or even numbers so replacements like this in mdit-vue are not necessary
This will fix many issues with API docs for Router and Pinia
- https://github.com/vuejs/pinia/pull/2292
Sorry for delay. I ignored the message. I'll check the default slugify function.
~~@posva What you mentioned seems not the same issue. But they are related for sure. Maybe you can create another issue for that.~~
What I'm saying is that #-7 or #3 is a valid id. In more real scenarios $pinia is a valid title but the problem doesn't come from mdit-vue, in fact, it should not escape those characters. Instead, vitepress should use getElementbyId to find the elements
I see. I just checked the spec and found the root cause.
Per HTML5 spec, IDs in html attrs can consist of just punctuation, so the id generated by mdit-vue should be valid.
The querySelector() accepts CSS selectors. Per CSS spec, IDs in css selectors do not allow special chars:
Thus, what you suggested should be the correct solution @posva 👍 Otherwise we need to escape those chars when using querySelector()
Special characters don't allow sroll down when I open links like the one below. Is it only happening to me?
https://pinia.vuejs.org/api/interfaces/pinia._StoreWithState.html#Methods-$patch
It's because it uses querySelector() instead of getElementById @ByMykel . That should work in the next version of vitepress