@readme/markdown 13.8.1 → 13.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/components/TableOfContents/index.tsx +32 -9
- package/dist/main.js +48 -20
- package/dist/main.node.js +58 -30
- package/dist/main.node.js.map +1 -1
- package/dist/processor/transform/mdxish/variables-text.d.ts +0 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -125,9 +125,29 @@ To make changes to the RDMD engine locally, run the local development server. Cl
|
|
|
125
125
|
|
|
126
126
|
If you make changes to the docs or how the markdown is rendered, you may need to update the visual regression snapshots by running `make updateSnapshot`. Running these browser tests requires `docker`. Follow the docker [install instructions for mac](https://docs.docker.com/docker-for-mac/install/). You may want to increase the [memory usage](https://docs.docker.com/docker-for-mac/#resources). If you have not already, you'll need to create an account for `docker hub` and [sign-in locally](https://docs.docker.com/docker-for-mac/#docker-hub).
|
|
127
127
|
|
|
128
|
+
### Linking Changes to the Main Repo
|
|
129
|
+
|
|
130
|
+
To test local changes in the main readme app, use `npm pack` (not `npm link`) and clear the webpack cache:
|
|
131
|
+
|
|
132
|
+
**In this repo, run:**
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
npm run build && npm pack
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**In the main app repo, run:**
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
npm install ../markdown/readme-markdown-<version>.tgz
|
|
142
|
+
rm -rf webpack-cache
|
|
143
|
+
make start
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
> **Note:** You must clear `webpack-cache` after every reinstall or the app will serve the old version.
|
|
147
|
+
|
|
128
148
|
### Linking Changes to Storybook
|
|
129
149
|
|
|
130
|
-
|
|
150
|
+
`npm link` works with the storybook app:
|
|
131
151
|
|
|
132
152
|
**In this repo, run:**
|
|
133
153
|
|
|
@@ -21,6 +21,22 @@ const VISIBLE_RATIO = 0.4;
|
|
|
21
21
|
/** Tolerance for subpixel rounding when checking if scrolled to the bottom. */
|
|
22
22
|
const SCROLL_BOTTOM_TOLERANCE = 1;
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Walk up the DOM to find the nearest scrollable ancestor.
|
|
26
|
+
* Falls back to `window` when the page itself scrolls.
|
|
27
|
+
*/
|
|
28
|
+
function getScrollParent(el: HTMLElement): HTMLElement | Window {
|
|
29
|
+
let parent = el.parentElement;
|
|
30
|
+
while (parent) {
|
|
31
|
+
const { overflow, overflowY } = getComputedStyle(parent);
|
|
32
|
+
if (/(auto|scroll)/.test(overflow + overflowY) && parent.scrollHeight > parent.clientHeight) {
|
|
33
|
+
return parent;
|
|
34
|
+
}
|
|
35
|
+
parent = parent.parentElement;
|
|
36
|
+
}
|
|
37
|
+
return window;
|
|
38
|
+
}
|
|
39
|
+
|
|
24
40
|
/**
|
|
25
41
|
* Watches headings in the viewport and toggles `active` on the
|
|
26
42
|
* corresponding TOC links so the reader always knows where they are.
|
|
@@ -50,9 +66,14 @@ function useScrollHighlight(navRef: React.RefObject<HTMLElement | null>) {
|
|
|
50
66
|
let activeId: string | null = null;
|
|
51
67
|
let clickLocked = false;
|
|
52
68
|
const visible = new Set<string>();
|
|
69
|
+
const scrollParent = getScrollParent(headings[0]);
|
|
53
70
|
|
|
54
|
-
const isAtBottom = () =>
|
|
55
|
-
|
|
71
|
+
const isAtBottom = () => {
|
|
72
|
+
if (scrollParent instanceof Window) {
|
|
73
|
+
return window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - SCROLL_BOTTOM_TOLERANCE;
|
|
74
|
+
}
|
|
75
|
+
return scrollParent.scrollTop + scrollParent.clientHeight >= scrollParent.scrollHeight - SCROLL_BOTTOM_TOLERANCE;
|
|
76
|
+
};
|
|
56
77
|
|
|
57
78
|
const activate = (id: string | null) => {
|
|
58
79
|
if (id === activeId) return;
|
|
@@ -97,8 +118,9 @@ function useScrollHighlight(navRef: React.RefObject<HTMLElement | null>) {
|
|
|
97
118
|
{ rootMargin: `0px 0px -${(1 - VISIBLE_RATIO) * 100}% 0px`, threshold: 0 },
|
|
98
119
|
);
|
|
99
120
|
|
|
100
|
-
//
|
|
121
|
+
// Check on scroll so bottom-of-page detection works even when
|
|
101
122
|
// no headings are crossing the intersection boundary.
|
|
123
|
+
const scrollTarget = scrollParent instanceof Window ? window : scrollParent;
|
|
102
124
|
const onScroll = () => { updateActive(); };
|
|
103
125
|
|
|
104
126
|
// Click a ToC link → immediately activate it, suppress the observer
|
|
@@ -114,25 +136,26 @@ function useScrollHighlight(navRef: React.RefObject<HTMLElement | null>) {
|
|
|
114
136
|
clickLocked = true;
|
|
115
137
|
|
|
116
138
|
const unlock = () => { clickLocked = false; };
|
|
117
|
-
|
|
139
|
+
scrollTarget.addEventListener('scrollend', unlock, { once: true });
|
|
118
140
|
|
|
119
141
|
document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });
|
|
120
142
|
};
|
|
121
143
|
|
|
122
144
|
headings.forEach(el => { observer.observe(el); });
|
|
123
|
-
|
|
145
|
+
scrollTarget.addEventListener('scroll', onScroll, { passive: true });
|
|
124
146
|
nav.addEventListener('click', onClick);
|
|
125
147
|
|
|
126
|
-
// Set initial active state for the first heading visible in the viewport
|
|
148
|
+
// Set initial active state for the first heading visible in the viewport,
|
|
149
|
+
// falling back to the first heading if none is in the observation zone yet.
|
|
127
150
|
const initialHeading = headings.find(el => {
|
|
128
151
|
const rect = el.getBoundingClientRect();
|
|
129
152
|
return rect.top >= 0 && rect.top < window.innerHeight * VISIBLE_RATIO;
|
|
130
|
-
});
|
|
131
|
-
|
|
153
|
+
}) || headings[0];
|
|
154
|
+
activate(initialHeading.id);
|
|
132
155
|
|
|
133
156
|
return () => {
|
|
134
157
|
observer.disconnect();
|
|
135
|
-
|
|
158
|
+
scrollTarget.removeEventListener('scroll', onScroll);
|
|
136
159
|
nav.removeEventListener('click', onClick);
|
|
137
160
|
};
|
|
138
161
|
}, [navRef, linkCount]);
|
package/dist/main.js
CHANGED
|
@@ -12090,6 +12090,21 @@ function buildLinkMap(nav) {
|
|
|
12090
12090
|
const VISIBLE_RATIO = 0.4;
|
|
12091
12091
|
/** Tolerance for subpixel rounding when checking if scrolled to the bottom. */
|
|
12092
12092
|
const SCROLL_BOTTOM_TOLERANCE = 1;
|
|
12093
|
+
/**
|
|
12094
|
+
* Walk up the DOM to find the nearest scrollable ancestor.
|
|
12095
|
+
* Falls back to `window` when the page itself scrolls.
|
|
12096
|
+
*/
|
|
12097
|
+
function getScrollParent(el) {
|
|
12098
|
+
let parent = el.parentElement;
|
|
12099
|
+
while (parent) {
|
|
12100
|
+
const { overflow, overflowY } = getComputedStyle(parent);
|
|
12101
|
+
if (/(auto|scroll)/.test(overflow + overflowY) && parent.scrollHeight > parent.clientHeight) {
|
|
12102
|
+
return parent;
|
|
12103
|
+
}
|
|
12104
|
+
parent = parent.parentElement;
|
|
12105
|
+
}
|
|
12106
|
+
return window;
|
|
12107
|
+
}
|
|
12093
12108
|
/**
|
|
12094
12109
|
* Watches headings in the viewport and toggles `active` on the
|
|
12095
12110
|
* corresponding TOC links so the reader always knows where they are.
|
|
@@ -12118,7 +12133,13 @@ function useScrollHighlight(navRef) {
|
|
|
12118
12133
|
let activeId = null;
|
|
12119
12134
|
let clickLocked = false;
|
|
12120
12135
|
const visible = new Set();
|
|
12121
|
-
const
|
|
12136
|
+
const scrollParent = getScrollParent(headings[0]);
|
|
12137
|
+
const isAtBottom = () => {
|
|
12138
|
+
if (scrollParent instanceof Window) {
|
|
12139
|
+
return window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - SCROLL_BOTTOM_TOLERANCE;
|
|
12140
|
+
}
|
|
12141
|
+
return scrollParent.scrollTop + scrollParent.clientHeight >= scrollParent.scrollHeight - SCROLL_BOTTOM_TOLERANCE;
|
|
12142
|
+
};
|
|
12122
12143
|
const activate = (id) => {
|
|
12123
12144
|
if (id === activeId)
|
|
12124
12145
|
return;
|
|
@@ -12158,8 +12179,9 @@ function useScrollHighlight(navRef) {
|
|
|
12158
12179
|
});
|
|
12159
12180
|
updateActive();
|
|
12160
12181
|
}, { rootMargin: `0px 0px -${(1 - VISIBLE_RATIO) * 100}% 0px`, threshold: 0 });
|
|
12161
|
-
//
|
|
12182
|
+
// Check on scroll so bottom-of-page detection works even when
|
|
12162
12183
|
// no headings are crossing the intersection boundary.
|
|
12184
|
+
const scrollTarget = scrollParent instanceof Window ? window : scrollParent;
|
|
12163
12185
|
const onScroll = () => { updateActive(); };
|
|
12164
12186
|
// Click a ToC link → immediately activate it, suppress the observer
|
|
12165
12187
|
// until the smooth scroll finishes, then hand control back.
|
|
@@ -12174,22 +12196,22 @@ function useScrollHighlight(navRef) {
|
|
|
12174
12196
|
activate(id);
|
|
12175
12197
|
clickLocked = true;
|
|
12176
12198
|
const unlock = () => { clickLocked = false; };
|
|
12177
|
-
|
|
12199
|
+
scrollTarget.addEventListener('scrollend', unlock, { once: true });
|
|
12178
12200
|
document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });
|
|
12179
12201
|
};
|
|
12180
12202
|
headings.forEach(el => { observer.observe(el); });
|
|
12181
|
-
|
|
12203
|
+
scrollTarget.addEventListener('scroll', onScroll, { passive: true });
|
|
12182
12204
|
nav.addEventListener('click', onClick);
|
|
12183
|
-
// Set initial active state for the first heading visible in the viewport
|
|
12205
|
+
// Set initial active state for the first heading visible in the viewport,
|
|
12206
|
+
// falling back to the first heading if none is in the observation zone yet.
|
|
12184
12207
|
const initialHeading = headings.find(el => {
|
|
12185
12208
|
const rect = el.getBoundingClientRect();
|
|
12186
12209
|
return rect.top >= 0 && rect.top < window.innerHeight * VISIBLE_RATIO;
|
|
12187
|
-
});
|
|
12188
|
-
|
|
12189
|
-
activate(initialHeading.id);
|
|
12210
|
+
}) || headings[0];
|
|
12211
|
+
activate(initialHeading.id);
|
|
12190
12212
|
return () => {
|
|
12191
12213
|
observer.disconnect();
|
|
12192
|
-
|
|
12214
|
+
scrollTarget.removeEventListener('scroll', onScroll);
|
|
12193
12215
|
nav.removeEventListener('click', onClick);
|
|
12194
12216
|
};
|
|
12195
12217
|
}, [navRef, linkCount]);
|
|
@@ -98763,25 +98785,31 @@ function makeVariableNode(varName, rawValue) {
|
|
|
98763
98785
|
}
|
|
98764
98786
|
/**
|
|
98765
98787
|
* A remark plugin that parses {user.<field>} patterns from text nodes and
|
|
98766
|
-
*
|
|
98788
|
+
* mdx expression nodes, creating Variable nodes for runtime resolution.
|
|
98767
98789
|
*
|
|
98768
|
-
* Handles
|
|
98790
|
+
* Handles:
|
|
98769
98791
|
* - `text` nodes: when safeMode is true or after expression evaluation
|
|
98770
98792
|
* - `mdxTextExpression` nodes: when mdxExpression has parsed {user.*} before evaluation
|
|
98793
|
+
* - `mdxFlowExpression` nodes: when {user.*} appears on its own line (e.g. inside JSX table cells)
|
|
98771
98794
|
*
|
|
98772
98795
|
* Supports any user field: name, email, email_verified, exp, iat, etc.
|
|
98773
98796
|
*/
|
|
98797
|
+
function visitExpressionNode(node, index, parent) {
|
|
98798
|
+
if (index === undefined || !parent)
|
|
98799
|
+
return;
|
|
98800
|
+
const wrapped = `{${(node.value ?? '').trim()}}`;
|
|
98801
|
+
const matches = [...wrapped.matchAll(USER_VAR_REGEX)];
|
|
98802
|
+
if (matches.length !== 1)
|
|
98803
|
+
return;
|
|
98804
|
+
const varName = matches[0][1] || matches[0][2];
|
|
98805
|
+
parent.children.splice(index, 1, makeVariableNode(varName, wrapped));
|
|
98806
|
+
}
|
|
98774
98807
|
const variablesTextTransformer = () => tree => {
|
|
98775
|
-
// Handle mdxTextExpression nodes (e.g. {user.name} parsed by mdxExpression)
|
|
98776
98808
|
visit(tree, 'mdxTextExpression', (node, index, parent) => {
|
|
98777
|
-
|
|
98778
|
-
|
|
98779
|
-
|
|
98780
|
-
|
|
98781
|
-
if (matches.length !== 1)
|
|
98782
|
-
return;
|
|
98783
|
-
const varName = matches[0][1] || matches[0][2];
|
|
98784
|
-
parent.children.splice(index, 1, makeVariableNode(varName, wrapped));
|
|
98809
|
+
visitExpressionNode(node, index, parent);
|
|
98810
|
+
});
|
|
98811
|
+
visit(tree, 'mdxFlowExpression', (node, index, parent) => {
|
|
98812
|
+
visitExpressionNode(node, index, parent);
|
|
98785
98813
|
});
|
|
98786
98814
|
visit(tree, 'text', (node, index, parent) => {
|
|
98787
98815
|
if (index === undefined || !parent)
|
package/dist/main.node.js
CHANGED
|
@@ -19670,14 +19670,14 @@ function getWindowScrollBarX(element) {
|
|
|
19670
19670
|
}
|
|
19671
19671
|
;// ./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
|
|
19672
19672
|
|
|
19673
|
-
function
|
|
19673
|
+
function getComputedStyle_getComputedStyle(element) {
|
|
19674
19674
|
return getWindow(element).getComputedStyle(element);
|
|
19675
19675
|
}
|
|
19676
19676
|
;// ./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
|
|
19677
19677
|
|
|
19678
19678
|
function isScrollParent(element) {
|
|
19679
19679
|
// Firefox wants us to check `-x` and `-y` variations as well
|
|
19680
|
-
var _getComputedStyle =
|
|
19680
|
+
var _getComputedStyle = getComputedStyle_getComputedStyle(element),
|
|
19681
19681
|
overflow = _getComputedStyle.overflow,
|
|
19682
19682
|
overflowX = _getComputedStyle.overflowX,
|
|
19683
19683
|
overflowY = _getComputedStyle.overflowY;
|
|
@@ -19849,7 +19849,7 @@ function isTableElement(element) {
|
|
|
19849
19849
|
|
|
19850
19850
|
function getTrueOffsetParent(element) {
|
|
19851
19851
|
if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
|
|
19852
|
-
|
|
19852
|
+
getComputedStyle_getComputedStyle(element).position === 'fixed') {
|
|
19853
19853
|
return null;
|
|
19854
19854
|
}
|
|
19855
19855
|
|
|
@@ -19864,7 +19864,7 @@ function getContainingBlock(element) {
|
|
|
19864
19864
|
|
|
19865
19865
|
if (isIE && isHTMLElement(element)) {
|
|
19866
19866
|
// In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
|
|
19867
|
-
var elementCss =
|
|
19867
|
+
var elementCss = getComputedStyle_getComputedStyle(element);
|
|
19868
19868
|
|
|
19869
19869
|
if (elementCss.position === 'fixed') {
|
|
19870
19870
|
return null;
|
|
@@ -19878,7 +19878,7 @@ function getContainingBlock(element) {
|
|
|
19878
19878
|
}
|
|
19879
19879
|
|
|
19880
19880
|
while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
|
|
19881
|
-
var css =
|
|
19881
|
+
var css = getComputedStyle_getComputedStyle(currentNode); // This is non-exhaustive but covers the most common CSS properties that
|
|
19882
19882
|
// create a containing block.
|
|
19883
19883
|
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
|
|
19884
19884
|
|
|
@@ -19898,11 +19898,11 @@ function getOffsetParent(element) {
|
|
|
19898
19898
|
var window = getWindow(element);
|
|
19899
19899
|
var offsetParent = getTrueOffsetParent(element);
|
|
19900
19900
|
|
|
19901
|
-
while (offsetParent && isTableElement(offsetParent) &&
|
|
19901
|
+
while (offsetParent && isTableElement(offsetParent) && getComputedStyle_getComputedStyle(offsetParent).position === 'static') {
|
|
19902
19902
|
offsetParent = getTrueOffsetParent(offsetParent);
|
|
19903
19903
|
}
|
|
19904
19904
|
|
|
19905
|
-
if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' &&
|
|
19905
|
+
if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle_getComputedStyle(offsetParent).position === 'static')) {
|
|
19906
19906
|
return window;
|
|
19907
19907
|
}
|
|
19908
19908
|
|
|
@@ -20447,7 +20447,7 @@ function mapToStyles(_ref2) {
|
|
|
20447
20447
|
if (offsetParent === getWindow(popper)) {
|
|
20448
20448
|
offsetParent = getDocumentElement(popper);
|
|
20449
20449
|
|
|
20450
|
-
if (
|
|
20450
|
+
if (getComputedStyle_getComputedStyle(offsetParent).position !== 'static' && position === 'absolute') {
|
|
20451
20451
|
heightProp = 'scrollHeight';
|
|
20452
20452
|
widthProp = 'scrollWidth';
|
|
20453
20453
|
}
|
|
@@ -20759,7 +20759,7 @@ function getDocumentRect(element) {
|
|
|
20759
20759
|
var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
|
|
20760
20760
|
var y = -winScroll.scrollTop;
|
|
20761
20761
|
|
|
20762
|
-
if (
|
|
20762
|
+
if (getComputedStyle_getComputedStyle(body || html).direction === 'rtl') {
|
|
20763
20763
|
x += math_max(html.clientWidth, body ? body.clientWidth : 0) - width;
|
|
20764
20764
|
}
|
|
20765
20765
|
|
|
@@ -20841,7 +20841,7 @@ function getClientRectFromMixedType(element, clippingParent, strategy) {
|
|
|
20841
20841
|
|
|
20842
20842
|
function getClippingParents(element) {
|
|
20843
20843
|
var clippingParents = listScrollParents(getParentNode(element));
|
|
20844
|
-
var canEscapeClipping = ['absolute', 'fixed'].indexOf(
|
|
20844
|
+
var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle_getComputedStyle(element).position) >= 0;
|
|
20845
20845
|
var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
|
|
20846
20846
|
|
|
20847
20847
|
if (!isElement(clipperElement)) {
|
|
@@ -24686,6 +24686,21 @@ function buildLinkMap(nav) {
|
|
|
24686
24686
|
const VISIBLE_RATIO = 0.4;
|
|
24687
24687
|
/** Tolerance for subpixel rounding when checking if scrolled to the bottom. */
|
|
24688
24688
|
const SCROLL_BOTTOM_TOLERANCE = 1;
|
|
24689
|
+
/**
|
|
24690
|
+
* Walk up the DOM to find the nearest scrollable ancestor.
|
|
24691
|
+
* Falls back to `window` when the page itself scrolls.
|
|
24692
|
+
*/
|
|
24693
|
+
function TableOfContents_getScrollParent(el) {
|
|
24694
|
+
let parent = el.parentElement;
|
|
24695
|
+
while (parent) {
|
|
24696
|
+
const { overflow, overflowY } = getComputedStyle(parent);
|
|
24697
|
+
if (/(auto|scroll)/.test(overflow + overflowY) && parent.scrollHeight > parent.clientHeight) {
|
|
24698
|
+
return parent;
|
|
24699
|
+
}
|
|
24700
|
+
parent = parent.parentElement;
|
|
24701
|
+
}
|
|
24702
|
+
return window;
|
|
24703
|
+
}
|
|
24689
24704
|
/**
|
|
24690
24705
|
* Watches headings in the viewport and toggles `active` on the
|
|
24691
24706
|
* corresponding TOC links so the reader always knows where they are.
|
|
@@ -24714,7 +24729,13 @@ function useScrollHighlight(navRef) {
|
|
|
24714
24729
|
let activeId = null;
|
|
24715
24730
|
let clickLocked = false;
|
|
24716
24731
|
const visible = new Set();
|
|
24717
|
-
const
|
|
24732
|
+
const scrollParent = TableOfContents_getScrollParent(headings[0]);
|
|
24733
|
+
const isAtBottom = () => {
|
|
24734
|
+
if (scrollParent instanceof Window) {
|
|
24735
|
+
return window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - SCROLL_BOTTOM_TOLERANCE;
|
|
24736
|
+
}
|
|
24737
|
+
return scrollParent.scrollTop + scrollParent.clientHeight >= scrollParent.scrollHeight - SCROLL_BOTTOM_TOLERANCE;
|
|
24738
|
+
};
|
|
24718
24739
|
const activate = (id) => {
|
|
24719
24740
|
if (id === activeId)
|
|
24720
24741
|
return;
|
|
@@ -24754,8 +24775,9 @@ function useScrollHighlight(navRef) {
|
|
|
24754
24775
|
});
|
|
24755
24776
|
updateActive();
|
|
24756
24777
|
}, { rootMargin: `0px 0px -${(1 - VISIBLE_RATIO) * 100}% 0px`, threshold: 0 });
|
|
24757
|
-
//
|
|
24778
|
+
// Check on scroll so bottom-of-page detection works even when
|
|
24758
24779
|
// no headings are crossing the intersection boundary.
|
|
24780
|
+
const scrollTarget = scrollParent instanceof Window ? window : scrollParent;
|
|
24759
24781
|
const onScroll = () => { updateActive(); };
|
|
24760
24782
|
// Click a ToC link → immediately activate it, suppress the observer
|
|
24761
24783
|
// until the smooth scroll finishes, then hand control back.
|
|
@@ -24770,22 +24792,22 @@ function useScrollHighlight(navRef) {
|
|
|
24770
24792
|
activate(id);
|
|
24771
24793
|
clickLocked = true;
|
|
24772
24794
|
const unlock = () => { clickLocked = false; };
|
|
24773
|
-
|
|
24795
|
+
scrollTarget.addEventListener('scrollend', unlock, { once: true });
|
|
24774
24796
|
document.getElementById(id)?.scrollIntoView({ behavior: 'smooth' });
|
|
24775
24797
|
};
|
|
24776
24798
|
headings.forEach(el => { observer.observe(el); });
|
|
24777
|
-
|
|
24799
|
+
scrollTarget.addEventListener('scroll', onScroll, { passive: true });
|
|
24778
24800
|
nav.addEventListener('click', onClick);
|
|
24779
|
-
// Set initial active state for the first heading visible in the viewport
|
|
24801
|
+
// Set initial active state for the first heading visible in the viewport,
|
|
24802
|
+
// falling back to the first heading if none is in the observation zone yet.
|
|
24780
24803
|
const initialHeading = headings.find(el => {
|
|
24781
24804
|
const rect = el.getBoundingClientRect();
|
|
24782
24805
|
return rect.top >= 0 && rect.top < window.innerHeight * VISIBLE_RATIO;
|
|
24783
|
-
});
|
|
24784
|
-
|
|
24785
|
-
activate(initialHeading.id);
|
|
24806
|
+
}) || headings[0];
|
|
24807
|
+
activate(initialHeading.id);
|
|
24786
24808
|
return () => {
|
|
24787
24809
|
observer.disconnect();
|
|
24788
|
-
|
|
24810
|
+
scrollTarget.removeEventListener('scroll', onScroll);
|
|
24789
24811
|
nav.removeEventListener('click', onClick);
|
|
24790
24812
|
};
|
|
24791
24813
|
}, [navRef, linkCount]);
|
|
@@ -118957,25 +118979,31 @@ function makeVariableNode(varName, rawValue) {
|
|
|
118957
118979
|
}
|
|
118958
118980
|
/**
|
|
118959
118981
|
* A remark plugin that parses {user.<field>} patterns from text nodes and
|
|
118960
|
-
*
|
|
118982
|
+
* mdx expression nodes, creating Variable nodes for runtime resolution.
|
|
118961
118983
|
*
|
|
118962
|
-
* Handles
|
|
118984
|
+
* Handles:
|
|
118963
118985
|
* - `text` nodes: when safeMode is true or after expression evaluation
|
|
118964
118986
|
* - `mdxTextExpression` nodes: when mdxExpression has parsed {user.*} before evaluation
|
|
118987
|
+
* - `mdxFlowExpression` nodes: when {user.*} appears on its own line (e.g. inside JSX table cells)
|
|
118965
118988
|
*
|
|
118966
118989
|
* Supports any user field: name, email, email_verified, exp, iat, etc.
|
|
118967
118990
|
*/
|
|
118991
|
+
function visitExpressionNode(node, index, parent) {
|
|
118992
|
+
if (index === undefined || !parent)
|
|
118993
|
+
return;
|
|
118994
|
+
const wrapped = `{${(node.value ?? '').trim()}}`;
|
|
118995
|
+
const matches = [...wrapped.matchAll(USER_VAR_REGEX)];
|
|
118996
|
+
if (matches.length !== 1)
|
|
118997
|
+
return;
|
|
118998
|
+
const varName = matches[0][1] || matches[0][2];
|
|
118999
|
+
parent.children.splice(index, 1, makeVariableNode(varName, wrapped));
|
|
119000
|
+
}
|
|
118968
119001
|
const variablesTextTransformer = () => tree => {
|
|
118969
|
-
// Handle mdxTextExpression nodes (e.g. {user.name} parsed by mdxExpression)
|
|
118970
119002
|
visit(tree, 'mdxTextExpression', (node, index, parent) => {
|
|
118971
|
-
|
|
118972
|
-
|
|
118973
|
-
|
|
118974
|
-
|
|
118975
|
-
if (matches.length !== 1)
|
|
118976
|
-
return;
|
|
118977
|
-
const varName = matches[0][1] || matches[0][2];
|
|
118978
|
-
parent.children.splice(index, 1, makeVariableNode(varName, wrapped));
|
|
119003
|
+
visitExpressionNode(node, index, parent);
|
|
119004
|
+
});
|
|
119005
|
+
visit(tree, 'mdxFlowExpression', (node, index, parent) => {
|
|
119006
|
+
visitExpressionNode(node, index, parent);
|
|
118979
119007
|
});
|
|
118980
119008
|
visit(tree, 'text', (node, index, parent) => {
|
|
118981
119009
|
if (index === undefined || !parent)
|