vitepress icon indicating copy to clipboard operation
vitepress copied to clipboard

Can't auto generate anchor when only special characters are there in heading

Open gyhyfj opened this issue 3 years ago • 2 comments

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.

gyhyfj avatar Jul 22 '22 03:07 gyhyfj

begin with special char

No, its actually when heading "only" has special characters 😅.

brc-dd avatar Jul 22 '22 06:07 brc-dd

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.

xfq avatar Jul 22 '22 13:07 xfq

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

yyx990803 avatar Mar 13 '23 07:03 yyx990803

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

posva avatar Jun 30 '23 14:06 posva

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.~~

meteorlxy avatar Jun 30 '23 15:06 meteorlxy

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

posva avatar Jun 30 '23 15:06 posva

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.

image

The querySelector() accepts CSS selectors. Per CSS spec, IDs in css selectors do not allow special chars:

image

Thus, what you suggested should be the correct solution @posva 👍 Otherwise we need to escape those chars when using querySelector()

meteorlxy avatar Jun 30 '23 15:06 meteorlxy

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

ByMykel avatar Jun 30 '23 16:06 ByMykel

It's because it uses querySelector() instead of getElementById @ByMykel . That should work in the next version of vitepress

posva avatar Jun 30 '23 20:06 posva