@mui/internal-docs-infra 0.10.1-canary.3 → 0.10.1-canary.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mui/internal-docs-infra",
3
- "version": "0.10.1-canary.3",
3
+ "version": "0.10.1-canary.4",
4
4
  "author": "MUI Team",
5
5
  "description": "MUI Infra - internal documentation creation tools.",
6
6
  "license": "MIT",
@@ -643,5 +643,5 @@
643
643
  "bin": {
644
644
  "docs-infra": "./cli/index.mjs"
645
645
  },
646
- "gitSha": "cad4d117211040086fea5435a525d50f80a8cf34"
646
+ "gitSha": "a6c1a30f23657628b384ef27f0c3c4cb7f37869b"
647
647
  }
@@ -0,0 +1,9 @@
1
+ import type { Root as HastRoot, Element, Text, RootContent } from 'hast';
2
+ /**
3
+ * Extracts all text content from a HAST node recursively.
4
+ */
5
+ export declare function getHastTextContent(node: HastRoot | Element | Text | RootContent): string;
6
+ /**
7
+ * Gets the direct text content of a HAST element (non-recursive, first level only).
8
+ */
9
+ export declare function getShallowTextContent(element: Element): string;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Extracts all text content from a HAST node recursively.
3
+ */
4
+ export function getHastTextContent(node) {
5
+ if (node.type === 'text') {
6
+ return node.value || '';
7
+ }
8
+ if ('children' in node && Array.isArray(node.children)) {
9
+ return node.children.map(child => getHastTextContent(child)).join('');
10
+ }
11
+ return '';
12
+ }
13
+
14
+ /**
15
+ * Gets the direct text content of a HAST element (non-recursive, first level only).
16
+ */
17
+ export function getShallowTextContent(element) {
18
+ let text = '';
19
+ for (const child of element.children) {
20
+ if (child.type === 'text') {
21
+ text += child.value;
22
+ }
23
+ }
24
+ return text;
25
+ }
@@ -1,3 +1,4 @@
1
1
  export * from "./hastCompression.mjs";
2
2
  export * from "./hastUtils.mjs";
3
+ export { getHastTextContent, getShallowTextContent } from "./getHastTextContent.mjs";
3
4
  export { stripHighlightingSpans } from "./stripHighlightingSpans.mjs";
@@ -1,3 +1,4 @@
1
1
  export * from "./hastCompression.mjs";
2
2
  export * from "./hastUtils.mjs";
3
+ export { getHastTextContent, getShallowTextContent } from "./getHastTextContent.mjs";
3
4
  export { stripHighlightingSpans } from "./stripHighlightingSpans.mjs";
@@ -4,20 +4,14 @@
4
4
  * These utilities work on already-highlighted HAST nodes to detect type patterns
5
5
  * (unions, functions, objects) and derive shortType/detailedType variants.
6
6
  */
7
- import type { Root as HastRoot, Element, Text, RootContent } from 'hast';
8
- /**
9
- * Extracts all text content from a HAST node recursively.
10
- */
11
- export declare function getHastTextContent(node: HastRoot | Element | Text | RootContent): string;
7
+ import type { Root as HastRoot, Element } from 'hast';
8
+ import { getHastTextContent, getShallowTextContent } from "../hastUtils/index.mjs";
9
+ export { getHastTextContent, getShallowTextContent };
12
10
  /**
13
11
  * Checks if a HAST element has a specific CSS class.
14
12
  * Handles both string and array class representations.
15
13
  */
16
14
  export declare function hasClass(element: Element, className: string): boolean;
17
- /**
18
- * Gets the direct text content of a HAST element (non-recursive, first level only).
19
- */
20
- export declare function getShallowTextContent(element: Element): string;
21
15
  /**
22
16
  * Checks if a HAST element is a span with class `line`.
23
17
  */
@@ -5,20 +5,8 @@
5
5
  * (unions, functions, objects) and derive shortType/detailedType variants.
6
6
  */
7
7
 
8
- import { compressHast } from "../hastUtils/index.mjs";
9
-
10
- /**
11
- * Extracts all text content from a HAST node recursively.
12
- */
13
- export function getHastTextContent(node) {
14
- if (node.type === 'text') {
15
- return node.value || '';
16
- }
17
- if ('children' in node && Array.isArray(node.children)) {
18
- return node.children.map(child => getHastTextContent(child)).join('');
19
- }
20
- return '';
21
- }
8
+ import { compressHast, getHastTextContent, getShallowTextContent } from "../hastUtils/index.mjs";
9
+ export { getHastTextContent, getShallowTextContent };
22
10
 
23
11
  /**
24
12
  * Checks if a HAST element has a specific CSS class.
@@ -35,19 +23,6 @@ export function hasClass(element, className) {
35
23
  return false;
36
24
  }
37
25
 
38
- /**
39
- * Gets the direct text content of a HAST element (non-recursive, first level only).
40
- */
41
- export function getShallowTextContent(element) {
42
- let text = '';
43
- for (const child of element.children) {
44
- if (child.type === 'text') {
45
- text += child.value;
46
- }
47
- }
48
- return text;
49
- }
50
-
51
26
  /**
52
27
  * Checks if a HAST element is a span with class `line`.
53
28
  */
@@ -127,16 +127,26 @@ export function starryNightGutter(tree, sourceLines, frameSize = 120) {
127
127
  replacement.push(createFrame(frameLines));
128
128
  }
129
129
 
130
- // If there are multiple frames and sourceLines provided, add dataAsString to each frame
130
+ // If there are multiple frames and sourceLines provided, add dataAsString to each frame.
131
+ // Every frame except the last covers `frameSize` source lines, each of which
132
+ // was followed by a newline separator in the original source, so its text
133
+ // ends with a trailing '\n'. The final frame only carries a trailing newline
134
+ // if the source itself ends with one. Without this trailing '\n', the
135
+ // plain-text fallback and the highlighted render disagree by exactly one
136
+ // newline per non-final frame, which causes a layout shift during lazy
137
+ // hydration when a frame toggles between the two.
131
138
  if (replacement.length > 1 && sourceLines) {
132
- for (const frame of replacement) {
139
+ const lastIndex = replacement.length - 1;
140
+ for (let frameIndex = 0; frameIndex < replacement.length; frameIndex += 1) {
141
+ const frame = replacement[frameIndex];
133
142
  if (frame.type === 'element' && frame.tagName === 'span' && frame.properties?.className === 'frame') {
134
143
  // Extract line range from child .line elements
135
144
  const lineChildren = frame.children.filter(c => c.type === 'element' && c.properties?.className === 'line' && typeof c.properties.dataLn === 'number');
136
145
  if (lineChildren.length > 0) {
137
146
  const startLine = Number(lineChildren[0].properties.dataLn) - 1;
138
147
  const endLine = Number(lineChildren[lineChildren.length - 1].properties.dataLn);
139
- frame.properties.dataAsString = sourceLines.slice(startLine, endLine).join('\n');
148
+ const joined = sourceLines.slice(startLine, endLine).join('\n');
149
+ frame.properties.dataAsString = frameIndex < lastIndex ? `${joined}\n` : joined;
140
150
  }
141
151
  }
142
152
  }
@@ -2,6 +2,7 @@ import { createStarryNight } from '@wooorm/starry-night';
2
2
  import { visit } from 'unist-util-visit';
3
3
  import { grammars, extensionMap } from "../parseSource/grammars.mjs";
4
4
  import { extendSyntaxTokens } from "../parseSource/extendSyntaxTokens.mjs";
5
+ import { getHastTextContent } from "../hastUtils/index.mjs";
5
6
  import { removePrefixFromHighlightedNodes } from "./removePrefixFromHighlightedNodes.mjs";
6
7
  const STARRY_NIGHT_KEY = '__docs_infra_starry_night_instance__';
7
8
 
@@ -56,18 +57,7 @@ export default function transformHtmlCodeInline(options = {}) {
56
57
  }
57
58
 
58
59
  // Extract all text content from children (handles multiple text nodes and newlines)
59
- const getTextContent = children => {
60
- return children.map(child => {
61
- if (child.type === 'text') {
62
- return child.value;
63
- }
64
- if (child.type === 'element' && 'children' in child) {
65
- return getTextContent(child.children);
66
- }
67
- return '';
68
- }).join('');
69
- };
70
- const source = getTextContent(node.children);
60
+ const source = node.children.map(child => getHastTextContent(child)).join('');
71
61
  if (!source) {
72
62
  return;
73
63
  }