Skip to content

Commit 0762f98

Browse files
committed
[docs] Fix heading fragment id mismatch
1 parent 7c610f0 commit 0762f98

File tree

3 files changed

+28
-23
lines changed

3 files changed

+28
-23
lines changed

docs/src/modules/components/MarkdownElement.js

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,6 @@ marked.Lexer.prototype.lex = function lex(src) {
1919
};
2020

2121
const renderer = new marked.Renderer();
22-
renderer.heading = (text, level) => {
23-
// Small title. No need for an anchor.
24-
// It's reducing the risk of duplicated id and it's fewer elements in the DOM.
25-
if (level >= 4) {
26-
return `<h${level}>${text}</h${level}>`;
27-
}
28-
29-
// eslint-disable-next-line no-underscore-dangle
30-
const hash = textToHash(text, global.__MARKED_UNIQUE__);
31-
32-
return [
33-
`<h${level}>`,
34-
`<a class="anchor-link" id="${hash}"></a>`,
35-
text,
36-
`<a class="anchor-link-style" aria-hidden="true" aria-label="anchor" href="#${hash}">`,
37-
'<svg><use xlink:href="#anchor-link-icon" /></svg>',
38-
'</a>',
39-
`</h${level}>`,
40-
].join('');
41-
};
4222

4323
const externs = [
4424
'https://material.io/',
@@ -304,6 +284,28 @@ function MarkdownElement(props) {
304284
// eslint-disable-next-line no-underscore-dangle
305285
global.__MARKED_USER_LANGUAGE__ = userLanguage;
306286

287+
// need to reset on every render to make textToHash concurrent-safe
288+
const headingIdCache = {};
289+
renderer.heading = (headingText, level) => {
290+
// Small title. No need for an anchor.
291+
// It's reducing the risk of duplicated id and it's fewer elements in the DOM.
292+
if (level >= 4) {
293+
return `<h${level}>${headingText}</h${level}>`;
294+
}
295+
296+
const hash = textToHash(headingText, headingIdCache);
297+
298+
return [
299+
`<h${level}>`,
300+
`<a class="anchor-link" id="${hash}"></a>`,
301+
headingText,
302+
`<a class="anchor-link-style" aria-hidden="true" aria-label="anchor" href="#${hash}">`,
303+
'<svg><use xlink:href="#anchor-link-icon" /></svg>',
304+
'</a>',
305+
`</h${level}>`,
306+
].join('');
307+
};
308+
307309
/* eslint-disable react/no-danger */
308310
return (
309311
<div

docs/src/modules/components/useMarkdownDocs.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ ${headers.components
8686
`);
8787
}
8888

89-
// eslint-disable-next-line no-underscore-dangle
90-
global.__MARKED_UNIQUE__ = {};
91-
9289
const element = (
9390
<React.Fragment>
9491
<svg style={{ display: 'none' }} xmlns="http://www.w3.org/2000/svg">

docs/src/modules/utils/textToHash.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ function makeUnique(hash, unique, i = 1) {
99
return makeUnique(hash, unique, i + 1);
1010
}
1111

12+
/**
13+
* @param {string} text
14+
* @param {object} unique - cache object, if provided textToHash has side-effects.
15+
* If you use it when rendering a react component be sure
16+
* to always pass a new cache object.
17+
*/
1218
export default function textToHash(text, unique = {}) {
1319
return makeUnique(
1420
encodeURI(

0 commit comments

Comments
 (0)