@mui/internal-docs-infra 0.3.1-canary.3 → 0.3.1-canary.5
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/esm/CodeControllerContext/CodeControllerContext.js +2 -2
- package/esm/CodeExternalsContext/CodeExternalsContext.js +1 -1
- package/esm/CodeHighlighter/CodeHighlighter.js +247 -329
- package/esm/CodeHighlighter/CodeHighlighterClient.js +447 -653
- package/esm/CodeHighlighter/CodeHighlighterContext.js +2 -2
- package/esm/CodeHighlighter/CodeHighlighterFallbackContext.js +2 -2
- package/esm/CodeHighlighter/codeToFallbackProps.js +21 -37
- package/esm/CodeHighlighter/errors.js +248 -400
- package/esm/CodeHighlighter/parseControlledCode.js +12 -20
- package/esm/CodeProvider/CodeContext.js +3 -3
- package/esm/CodeProvider/CodeProvider.js +31 -40
- package/esm/abstractCreateDemo/abstractCreateDemo.js +13 -17
- package/esm/abstractCreateDemoClient/abstractCreateDemoClient.js +12 -12
- package/esm/cli/index.js +1 -1
- package/esm/cli/runValidate.js +160 -264
- package/esm/createDemoData/createDemoData.js +11 -12
- package/esm/createSitemap/createSitemap.js +2 -2
- package/esm/pipeline/getFileConventions/fileConventions.js +1 -1
- package/esm/pipeline/getFileConventions/getFileConventions.js +2 -15
- package/esm/pipeline/hastUtils/hastUtils.js +16 -17
- package/esm/pipeline/loadCodeVariant/addCodeVariantPaths.js +24 -24
- package/esm/pipeline/loadCodeVariant/applyCodeTransform.js +12 -22
- package/esm/pipeline/loadCodeVariant/calculateMainFilePath.js +30 -37
- package/esm/pipeline/loadCodeVariant/computeHastDeltas.js +107 -185
- package/esm/pipeline/loadCodeVariant/diffHast.js +18 -53
- package/esm/pipeline/loadCodeVariant/examineCodeVariant.js +24 -27
- package/esm/pipeline/loadCodeVariant/flattenCodeVariant.js +9 -10
- package/esm/pipeline/loadCodeVariant/hasAllCodeVariants.js +5 -5
- package/esm/pipeline/loadCodeVariant/loadCodeFallback.js +516 -731
- package/esm/pipeline/loadCodeVariant/loadCodeVariant.js +679 -1079
- package/esm/pipeline/loadCodeVariant/maybeCodeInitialData.js +14 -20
- package/esm/pipeline/loadCodeVariant/mergeCodeMetadata.js +53 -63
- package/esm/pipeline/loadCodeVariant/parseCode.js +40 -48
- package/esm/pipeline/loadCodeVariant/pathUtils.js +43 -64
- package/esm/pipeline/loadCodeVariant/transformSource.js +55 -125
- package/esm/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.js +160 -221
- package/esm/pipeline/loadPrecomputedCodeHighlighter/parseCreateFactoryCall.js +377 -479
- package/esm/pipeline/loadPrecomputedCodeHighlighter/parseFunctionArguments.js +171 -173
- package/esm/pipeline/loadPrecomputedCodeHighlighter/performanceLogger.js +14 -30
- package/esm/pipeline/loadPrecomputedCodeHighlighter/replacePrecomputeValue.js +19 -21
- package/esm/pipeline/loadPrecomputedCodeHighlighter/serializeFunctionArguments.js +37 -71
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/filterRuntimeExternals.js +3 -9
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/generateImportStatements.js +54 -80
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/generateResolvedExternals.js +71 -98
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/injectImportsIntoSource.js +5 -5
- package/esm/pipeline/loadPrecomputedCodeHighlighterClient/loadPrecomputedCodeHighlighterClient.js +161 -211
- package/esm/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.js +159 -207
- package/esm/pipeline/loadServerCodeMeta/loadServerCodeMeta.js +42 -64
- package/esm/pipeline/loadServerCodeMeta/resolveModulePathWithFs.js +20 -96
- package/esm/pipeline/loadServerPageIndex/loadServerPageIndex.js +66 -85
- package/esm/pipeline/loadServerSitemap/loadServerSitemap.js +71 -118
- package/esm/pipeline/loadServerSource/loadServerSource.js +121 -148
- package/esm/pipeline/loaderUtils/externalsToPackages.js +7 -7
- package/esm/pipeline/loaderUtils/extractNameAndSlugFromUrl.js +8 -12
- package/esm/pipeline/loaderUtils/fileUrlToPortablePath.js +5 -5
- package/esm/pipeline/loaderUtils/getFileNameFromUrl.js +19 -29
- package/esm/pipeline/loaderUtils/getLanguageFromExtension.js +3 -4
- package/esm/pipeline/loaderUtils/mergeExternals.js +15 -35
- package/esm/pipeline/loaderUtils/parseImportsAndComments.js +413 -433
- package/esm/pipeline/loaderUtils/processRelativeImports.js +153 -239
- package/esm/pipeline/loaderUtils/resolveModulePath.js +544 -1303
- package/esm/pipeline/loaderUtils/rewriteImports.js +73 -111
- package/esm/pipeline/parseSource/addLineGutters.js +33 -45
- package/esm/pipeline/parseSource/grammars.js +3 -3
- package/esm/pipeline/parseSource/parseSource.js +13 -31
- package/esm/pipeline/syncPageIndex/createMarkdownNodes.js +32 -55
- package/esm/pipeline/syncPageIndex/mergeMetadataMarkdown.js +107 -160
- package/esm/pipeline/syncPageIndex/metadataToMarkdown.js +846 -1033
- package/esm/pipeline/syncPageIndex/syncPageIndex.js +291 -438
- package/esm/pipeline/transformHtmlCodePrecomputed/transformHtmlCodePrecomputed.js +213 -311
- package/esm/pipeline/transformMarkdownBlockquoteCallouts/transformMarkdownBlockquoteCallouts.js +10 -10
- package/esm/pipeline/transformMarkdownCode/transformMarkdownCode.js +133 -193
- package/esm/pipeline/transformMarkdownDemoLinks/transformMarkdownDemoLinks.js +25 -27
- package/esm/pipeline/transformMarkdownMetadata/transformMarkdownMetadata.js +572 -717
- package/esm/pipeline/transformMarkdownRelativePaths/transformMarkdownRelativePaths.js +8 -8
- package/esm/pipeline/transformTypescriptToJavascript/removeTypes.js +84 -113
- package/esm/pipeline/transformTypescriptToJavascript/transformTypescriptToJavascript.js +10 -26
- package/esm/useCode/Pre.js +58 -62
- package/esm/useCode/useCode.js +59 -61
- package/esm/useCode/useCodeUtils.js +54 -63
- package/esm/useCode/useCopyFunctionality.js +10 -9
- package/esm/useCode/useFileNavigation.js +150 -212
- package/esm/useCode/useSourceEditing.js +17 -14
- package/esm/useCode/useTransformManagement.js +23 -26
- package/esm/useCode/useUIState.js +12 -20
- package/esm/useCode/useVariantSelection.js +62 -79
- package/esm/useCopier/index.js +29 -56
- package/esm/useDemo/createCodeSandbox.js +12 -15
- package/esm/useDemo/createStackBlitz.js +14 -20
- package/esm/useDemo/exportVariant.js +200 -180
- package/esm/useDemo/exportVariantAsCra.js +22 -25
- package/esm/useDemo/useDemo.js +80 -84
- package/esm/useErrors/ErrorsContext.js +1 -1
- package/esm/useErrors/useErrors.js +3 -3
- package/esm/useLocalStorageState/useLocalStorageState.js +23 -39
- package/esm/usePreference/PreferencesProvider.js +1 -1
- package/esm/usePreference/usePreference.js +9 -11
- package/esm/useSearch/useSearch.js +290 -387
- package/esm/useUrlHashState/useUrlHashState.js +11 -14
- package/esm/withDocsInfra/withDeploymentConfig.js +26 -21
- package/esm/withDocsInfra/withDocsInfra.js +99 -101
- package/package.json +7 -4
|
@@ -16,21 +16,21 @@ import { fileUrlToPortablePath } from "../loaderUtils/fileUrlToPortablePath.js";
|
|
|
16
16
|
* - /(public)/components/page.tsx -> /components
|
|
17
17
|
* This allows URLs to resolve when reading in VSCode and Github
|
|
18
18
|
*/
|
|
19
|
-
export
|
|
20
|
-
return
|
|
21
|
-
visit(tree, 'link',
|
|
19
|
+
export const transformMarkdownRelativePaths = () => {
|
|
20
|
+
return (tree, file) => {
|
|
21
|
+
visit(tree, 'link', node => {
|
|
22
22
|
if (node.url) {
|
|
23
23
|
node.url = node.url.replace(/\/page\.(tsx|jsx|js|mdx|md)$/g, '');
|
|
24
24
|
node.url = node.url.replace(/\/page\.(tsx|jsx|js|mdx|md)(\?[^#]*)?(#.*)?$/g, '$2$3');
|
|
25
25
|
if ((node.url.startsWith('./') || node.url.startsWith('../')) && file.path) {
|
|
26
26
|
// Convert filesystem path to portable path for cross-platform compatibility
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const portablePath = fileUrlToPortablePath(pathToFileURL(file.path).href);
|
|
28
|
+
const currentDir = path.dirname(portablePath);
|
|
29
|
+
const appIndex = currentDir.indexOf('/app/');
|
|
30
|
+
const baseDir = appIndex !== -1 ? currentDir.substring(appIndex + 4) : '/';
|
|
31
31
|
|
|
32
32
|
// Resolve the relative path from the current directory
|
|
33
|
-
|
|
33
|
+
const resolvedPath = path.resolve('/', baseDir, node.url);
|
|
34
34
|
node.url = resolvedPath;
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import _regenerator from "@babel/runtime/helpers/esm/regenerator";
|
|
2
|
-
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
3
|
-
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
4
1
|
// Based on https://github.com/ember-cli/babel-remove-types/blob/fc3be010e99c4f4926fd70d00242d6777ab1b8d7/src/index.ts
|
|
5
2
|
// Converted to use Babel standalone, with added TSX support
|
|
6
3
|
|
|
7
4
|
import * as Babel from '@babel/standalone';
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
5
|
+
import { format } from 'prettier/standalone';
|
|
6
|
+
import pluginBabel from 'prettier/plugins/babel';
|
|
7
|
+
import pluginEstree from 'prettier/plugins/estree';
|
|
11
8
|
/**
|
|
12
9
|
* Strips TypeScript types and decorators from code (including React in TSX),
|
|
13
10
|
* preserving blank lines and optionally formatting with Prettier.
|
|
@@ -19,113 +16,87 @@ import parserBabel from 'prettier/parser-babel';
|
|
|
19
16
|
* or a Prettier options object to customize.
|
|
20
17
|
* @returns The transformed (and optionally formatted) code.
|
|
21
18
|
*/
|
|
22
|
-
export function removeTypes(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
removeComments,
|
|
30
|
-
isTSX,
|
|
31
|
-
transformed,
|
|
32
|
-
fixed,
|
|
33
|
-
standardPrettierOptions,
|
|
34
|
-
mergedPrettierOptions,
|
|
35
|
-
_args = arguments;
|
|
36
|
-
return _regenerator().w(function (_context) {
|
|
37
|
-
while (1) switch (_context.n) {
|
|
38
|
-
case 0:
|
|
39
|
-
filename = _args.length > 1 && _args[1] !== undefined ? _args[1] : 'file.ts';
|
|
40
|
-
prettierConfig = _args.length > 2 && _args[2] !== undefined ? _args[2] : true;
|
|
41
|
-
// Babel collapses newlines all over the place, which messes with the formatting of almost any
|
|
42
|
-
// code you pass to it. To preserve the formatting, we go through and mark all the empty lines
|
|
43
|
-
// in the code string *before* transforming it. This allows us to go back through after the
|
|
44
|
-
// transformation re-insert the empty lines in the correct place relative to the new code that
|
|
45
|
-
// has been generated.
|
|
46
|
-
code = code.replace(/\n\n+/g, '/* ___NEWLINE___ */\n');
|
|
19
|
+
export async function removeTypes(code, filename = 'file.ts', prettierConfig = true) {
|
|
20
|
+
// Babel collapses newlines all over the place, which messes with the formatting of almost any
|
|
21
|
+
// code you pass to it. To preserve the formatting, we go through and mark all the empty lines
|
|
22
|
+
// in the code string *before* transforming it. This allows us to go back through after the
|
|
23
|
+
// transformation re-insert the empty lines in the correct place relative to the new code that
|
|
24
|
+
// has been generated.
|
|
25
|
+
code = code.replace(/\n\n+/g, '/* ___NEWLINE___ */\n');
|
|
47
26
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
isTSX = /\.tsx$/i.test(filename);
|
|
69
|
-
transformed = Babel.transform(code, {
|
|
70
|
-
filename: filename,
|
|
71
|
-
plugins: [{
|
|
72
|
-
name: 'comment-remover',
|
|
73
|
-
visitor: {
|
|
74
|
-
TSTypeAliasDeclaration: removeComments,
|
|
75
|
-
TSInterfaceDeclaration: removeComments,
|
|
76
|
-
TSDeclareFunction: removeComments,
|
|
77
|
-
TSDeclareMethod: removeComments,
|
|
78
|
-
TSImportType: removeComments,
|
|
79
|
-
TSModuleDeclaration: removeComments
|
|
80
|
-
}
|
|
81
|
-
}, ['transform-typescript', {
|
|
82
|
-
onlyRemoveTypeImports: true,
|
|
83
|
-
isTSX: isTSX,
|
|
84
|
-
allExtensions: true
|
|
85
|
-
}], ['proposal-decorators', {
|
|
86
|
-
legacy: true
|
|
87
|
-
}]],
|
|
88
|
-
generatorOpts: {
|
|
89
|
-
retainLines: true,
|
|
90
|
-
shouldPrintComment: function shouldPrintComment(c) {
|
|
91
|
-
return c !== '___REMOVE_ME___';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
if (!(!transformed || !transformed.code)) {
|
|
96
|
-
_context.n = 1;
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
throw new Error('There was an issue with the Babel transform.');
|
|
100
|
-
case 1:
|
|
101
|
-
fixed = transformed.code.replace(/\/\* ___NEWLINE___ \*\//g, '\n'); // If the user has *explicitly* passed `false` here, it means they do not want us to run Prettier
|
|
102
|
-
// at all, so we bail here.
|
|
103
|
-
if (!(prettierConfig === false)) {
|
|
104
|
-
_context.n = 2;
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
107
|
-
return _context.a(2, fixed);
|
|
108
|
-
case 2:
|
|
109
|
-
standardPrettierOptions = {
|
|
110
|
-
parser: 'babel',
|
|
111
|
-
singleQuote: true,
|
|
112
|
-
plugins: [prettierPluginEstree, parserBabel]
|
|
113
|
-
}; // If `prettierConfig` is *explicitly* true (as opposed to truthy), it means the user has opted in
|
|
114
|
-
// to default behavior either explicitly or implicitly. Either way, we run basic Prettier on it.
|
|
115
|
-
if (!(prettierConfig === true)) {
|
|
116
|
-
_context.n = 3;
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
return _context.a(2, prettier.format(fixed, standardPrettierOptions));
|
|
120
|
-
case 3:
|
|
121
|
-
// If we've made it here, the user has passed their own Prettier options so we merge it with ours
|
|
122
|
-
// and let theirs overwrite any of the default settings.
|
|
123
|
-
mergedPrettierOptions = _extends(_extends(_extends({}, standardPrettierOptions), prettierConfig), {}, {
|
|
124
|
-
plugins: standardPrettierOptions.plugins
|
|
125
|
-
});
|
|
126
|
-
return _context.a(2, prettier.format(fixed, mergedPrettierOptions));
|
|
27
|
+
// When removing TS-specific constructs (e.g. interfaces), we want to make sure we also remove
|
|
28
|
+
// any comments that are associated with those constructs, since otherwise we'll be left with
|
|
29
|
+
// comments that refer to something that isn't actually there.
|
|
30
|
+
// Credit to https://github.com/cyco130/detype for figuring out this very useful pattern
|
|
31
|
+
const removeComments = {
|
|
32
|
+
enter(nodePath) {
|
|
33
|
+
if (!nodePath.node.leadingComments) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
for (let i = nodePath.node.leadingComments.length - 1; i >= 0; i -= 1) {
|
|
37
|
+
const comment = nodePath.node.leadingComments[i];
|
|
38
|
+
if (code.slice(comment.end).match(/^\s*\n\s*\n/) || comment.value.includes('___NEWLINE___')) {
|
|
39
|
+
// There is at least one empty line between the comment and the TypeScript specific construct
|
|
40
|
+
// We should keep this comment and those before it
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
comment.value = '___REMOVE_ME___';
|
|
127
44
|
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const isTSX = /\.tsx$/i.test(filename);
|
|
48
|
+
const transformed = Babel.transform(code, {
|
|
49
|
+
filename,
|
|
50
|
+
plugins: [{
|
|
51
|
+
name: 'comment-remover',
|
|
52
|
+
visitor: {
|
|
53
|
+
TSTypeAliasDeclaration: removeComments,
|
|
54
|
+
TSInterfaceDeclaration: removeComments,
|
|
55
|
+
TSDeclareFunction: removeComments,
|
|
56
|
+
TSDeclareMethod: removeComments,
|
|
57
|
+
TSImportType: removeComments,
|
|
58
|
+
TSModuleDeclaration: removeComments
|
|
59
|
+
}
|
|
60
|
+
}, ['transform-typescript', {
|
|
61
|
+
onlyRemoveTypeImports: true,
|
|
62
|
+
isTSX,
|
|
63
|
+
allExtensions: true
|
|
64
|
+
}], ['proposal-decorators', {
|
|
65
|
+
legacy: true
|
|
66
|
+
}]],
|
|
67
|
+
generatorOpts: {
|
|
68
|
+
retainLines: true,
|
|
69
|
+
shouldPrintComment: c => c !== '___REMOVE_ME___'
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
if (!transformed || !transformed.code) {
|
|
73
|
+
throw new Error('There was an issue with the Babel transform.');
|
|
74
|
+
}
|
|
75
|
+
const fixed = transformed.code.replace(/\/\* ___NEWLINE___ \*\//g, '\n');
|
|
76
|
+
|
|
77
|
+
// If the user has *explicitly* passed `false` here, it means they do not want us to run Prettier
|
|
78
|
+
// at all, so we bail here.
|
|
79
|
+
if (prettierConfig === false) {
|
|
80
|
+
return fixed;
|
|
81
|
+
}
|
|
82
|
+
const standardPrettierOptions = {
|
|
83
|
+
parser: 'babel',
|
|
84
|
+
singleQuote: true,
|
|
85
|
+
plugins: [pluginBabel, pluginEstree]
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// If `prettierConfig` is *explicitly* true (as opposed to truthy), it means the user has opted in
|
|
89
|
+
// to default behavior either explicitly or implicitly. Either way, we run basic Prettier on it.
|
|
90
|
+
if (prettierConfig === true) {
|
|
91
|
+
return format(fixed, standardPrettierOptions);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// If we've made it here, the user has passed their own Prettier options so we merge it with ours
|
|
95
|
+
// and let theirs overwrite any of the default settings.
|
|
96
|
+
const mergedPrettierOptions = {
|
|
97
|
+
...standardPrettierOptions,
|
|
98
|
+
...prettierConfig,
|
|
99
|
+
plugins: standardPrettierOptions.plugins
|
|
100
|
+
};
|
|
101
|
+
return format(fixed, mergedPrettierOptions);
|
|
131
102
|
}
|
|
@@ -1,31 +1,15 @@
|
|
|
1
|
-
import _regenerator from "@babel/runtime/helpers/esm/regenerator";
|
|
2
|
-
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
1
|
import { removeTypes } from "./removeTypes.js";
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
case 1:
|
|
13
|
-
transformed = _context.v;
|
|
14
|
-
transformedFileName = fileName.replace(/\.ts$/, '.js').replace(/\.tsx$/, '.jsx');
|
|
15
|
-
return _context.a(2, {
|
|
16
|
-
js: {
|
|
17
|
-
source: transformed,
|
|
18
|
-
fileName: transformedFileName
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}, _callee);
|
|
23
|
-
}));
|
|
24
|
-
return function transformTypescriptToJavascript(_x, _x2) {
|
|
25
|
-
return _ref.apply(this, arguments);
|
|
2
|
+
export const transformTypescriptToJavascript = async (source, fileName) => {
|
|
3
|
+
const transformed = await removeTypes(source, fileName);
|
|
4
|
+
const transformedFileName = fileName.replace(/\.ts$/, '.js').replace(/\.tsx$/, '.jsx');
|
|
5
|
+
return {
|
|
6
|
+
js: {
|
|
7
|
+
source: transformed,
|
|
8
|
+
fileName: transformedFileName
|
|
9
|
+
}
|
|
26
10
|
};
|
|
27
|
-
}
|
|
28
|
-
export
|
|
11
|
+
};
|
|
12
|
+
export const TypescriptToJavascriptTransformer = {
|
|
29
13
|
extensions: ['ts', 'tsx'],
|
|
30
14
|
transformer: transformTypescriptToJavascript
|
|
31
15
|
};
|
package/esm/useCode/Pre.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
4
|
-
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
5
|
-
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
|
|
6
3
|
import * as React from 'react';
|
|
7
4
|
import { toText } from 'hast-util-to-text';
|
|
8
5
|
import { decompressSync, strFromU8 } from 'fflate';
|
|
9
6
|
import { decode } from 'uint8-to-base64';
|
|
10
7
|
import { hastToJsx } from "../pipeline/hastUtils/index.js";
|
|
11
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
const hastChildrenCache = new WeakMap();
|
|
10
|
+
const textChildrenCache = new WeakMap();
|
|
14
11
|
function renderCode(hastChildren, renderHast, text) {
|
|
15
12
|
if (renderHast) {
|
|
16
|
-
|
|
13
|
+
let jsx = hastChildrenCache.get(hastChildren);
|
|
17
14
|
if (!jsx) {
|
|
18
15
|
jsx = hastToJsx({
|
|
19
16
|
type: 'root',
|
|
@@ -26,7 +23,7 @@ function renderCode(hastChildren, renderHast, text) {
|
|
|
26
23
|
if (text !== undefined) {
|
|
27
24
|
return text;
|
|
28
25
|
}
|
|
29
|
-
|
|
26
|
+
let txt = textChildrenCache.get(hastChildren);
|
|
30
27
|
if (!txt) {
|
|
31
28
|
txt = toText({
|
|
32
29
|
type: 'root',
|
|
@@ -38,15 +35,15 @@ function renderCode(hastChildren, renderHast, text) {
|
|
|
38
35
|
}
|
|
39
36
|
return txt;
|
|
40
37
|
}
|
|
41
|
-
export function Pre(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
38
|
+
export function Pre({
|
|
39
|
+
children,
|
|
40
|
+
className,
|
|
41
|
+
language,
|
|
42
|
+
ref,
|
|
43
|
+
shouldHighlight,
|
|
44
|
+
hydrateMargin = '200px 0px 200px 0px'
|
|
45
|
+
}) {
|
|
46
|
+
const hast = React.useMemo(() => {
|
|
50
47
|
if (typeof children === 'string') {
|
|
51
48
|
return null;
|
|
52
49
|
}
|
|
@@ -58,12 +55,11 @@ export function Pre(_ref) {
|
|
|
58
55
|
}
|
|
59
56
|
return children;
|
|
60
57
|
}, [children]);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
var bindIntersectionObserver = React.useCallback(function (root) {
|
|
58
|
+
const [visibleFrames, setVisibleFrames] = React.useState({
|
|
59
|
+
[0]: true
|
|
60
|
+
});
|
|
61
|
+
const observer = React.useRef(null);
|
|
62
|
+
const bindIntersectionObserver = React.useCallback(root => {
|
|
67
63
|
if (!root) {
|
|
68
64
|
if (observer.current) {
|
|
69
65
|
observer.current.disconnect();
|
|
@@ -71,52 +67,53 @@ export function Pre(_ref) {
|
|
|
71
67
|
observer.current = null;
|
|
72
68
|
return;
|
|
73
69
|
}
|
|
74
|
-
observer.current = new IntersectionObserver(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
70
|
+
observer.current = new IntersectionObserver(entries => setVisibleFrames(prev => {
|
|
71
|
+
const visible = [];
|
|
72
|
+
const invisible = [];
|
|
73
|
+
entries.forEach(entry => {
|
|
74
|
+
if (entry.isIntersecting) {
|
|
75
|
+
visible.push(Number(entry.target.getAttribute('data-frame')));
|
|
76
|
+
} else {
|
|
77
|
+
invisible.push(Number(entry.target.getAttribute('data-frame')));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
81
|
+
// avoid mutating the object if nothing changed
|
|
82
|
+
let frames;
|
|
83
|
+
visible.forEach(frame => {
|
|
84
|
+
if (prev[frame] !== true) {
|
|
85
|
+
if (!frames) {
|
|
86
|
+
frames = {
|
|
87
|
+
...prev
|
|
88
|
+
};
|
|
94
89
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
frames[frame] = true;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
invisible.forEach(frame => {
|
|
94
|
+
if (prev[frame]) {
|
|
95
|
+
if (!frames) {
|
|
96
|
+
frames = {
|
|
97
|
+
...prev
|
|
98
|
+
};
|
|
102
99
|
}
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
delete frames[frame];
|
|
101
|
+
}
|
|
105
102
|
});
|
|
106
|
-
|
|
103
|
+
return frames || prev;
|
|
104
|
+
}), {
|
|
107
105
|
rootMargin: hydrateMargin
|
|
108
106
|
});
|
|
109
107
|
|
|
110
108
|
// <pre><code><span class="frame" data-frame="0">...</span><span class="frame" data-frame="1">...</span>...</code></pre>
|
|
111
|
-
root.childNodes[0].childNodes.forEach(
|
|
109
|
+
root.childNodes[0].childNodes.forEach(node => {
|
|
112
110
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
113
|
-
|
|
114
|
-
var element = node;
|
|
111
|
+
const element = node;
|
|
115
112
|
if (!element.hasAttribute('data-frame')) {
|
|
116
113
|
console.warn('Expected frame element in useCode <Pre>', element);
|
|
117
114
|
return;
|
|
118
115
|
}
|
|
119
|
-
|
|
116
|
+
observer.current?.observe(element);
|
|
120
117
|
}
|
|
121
118
|
});
|
|
122
119
|
if (ref) {
|
|
@@ -127,13 +124,13 @@ export function Pre(_ref) {
|
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
126
|
}, [ref, hydrateMargin]);
|
|
130
|
-
|
|
127
|
+
const observeFrame = React.useCallback(node => {
|
|
131
128
|
if (observer.current && node) {
|
|
132
129
|
observer.current.observe(node);
|
|
133
130
|
}
|
|
134
131
|
}, []);
|
|
135
|
-
|
|
136
|
-
return hast
|
|
132
|
+
const frames = React.useMemo(() => {
|
|
133
|
+
return hast?.children.map((child, index) => {
|
|
137
134
|
if (child.type !== 'element') {
|
|
138
135
|
if (child.type === 'text') {
|
|
139
136
|
return /*#__PURE__*/_jsx(React.Fragment, {
|
|
@@ -143,13 +140,12 @@ export function Pre(_ref) {
|
|
|
143
140
|
return null;
|
|
144
141
|
}
|
|
145
142
|
if (child.properties.className === 'frame') {
|
|
146
|
-
|
|
147
|
-
var isVisible = Boolean(visibleFrames[index]);
|
|
143
|
+
const isVisible = Boolean(visibleFrames[index]);
|
|
148
144
|
return /*#__PURE__*/_jsx("span", {
|
|
149
145
|
className: "frame",
|
|
150
146
|
"data-frame": index,
|
|
151
147
|
ref: observeFrame,
|
|
152
|
-
children: renderCode(child.children, shouldHighlight && isVisible,
|
|
148
|
+
children: renderCode(child.children, shouldHighlight && isVisible, child.properties?.dataAsString ? String(child.properties?.dataAsString) : undefined)
|
|
153
149
|
}, index);
|
|
154
150
|
}
|
|
155
151
|
return /*#__PURE__*/_jsx(React.Fragment, {
|
|
@@ -163,7 +159,7 @@ export function Pre(_ref) {
|
|
|
163
159
|
ref: bindIntersectionObserver,
|
|
164
160
|
className: className,
|
|
165
161
|
children: /*#__PURE__*/_jsx("code", {
|
|
166
|
-
className: language ?
|
|
162
|
+
className: language ? `language-${language}` : undefined,
|
|
167
163
|
children: typeof children === 'string' ? children : frames
|
|
168
164
|
})
|
|
169
165
|
});
|