xmlui 0.9.21 → 0.9.25
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/dist/apiInterceptorWorker-CFF3bC6o.mjs +818 -0
- package/dist/{index-B3CWFAxa.mjs → index-DtxDGaqF.mjs} +11942 -3291
- package/dist/index.css +1301 -564
- package/dist/language-server-web-worker.mjs +1 -1
- package/dist/language-server.mjs +1 -1
- package/dist/lint-CYAUfk0_.mjs +168 -0
- package/dist/metadata-utils-CCIMqe69.mjs +466 -0
- package/dist/scripts/package.json +252 -0
- package/dist/scripts/src/components/App/AppLayoutContext.js +0 -1
- package/dist/scripts/src/components/App/AppNative.js +21 -9
- package/dist/scripts/src/components/AppHeader/AppHeader.js +1 -1
- package/dist/scripts/src/components/AutoComplete/AutoComplete.js +5 -2
- package/dist/scripts/src/components/AutoComplete/AutoCompleteNative.js +13 -10
- package/dist/scripts/src/components/Bookmark/BookmarkNative.js +5 -1
- package/dist/scripts/src/components/CodeBlock/CodeBlock.js +31 -0
- package/dist/scripts/src/components/CodeBlock/CodeBlockNative.js +82 -0
- package/dist/scripts/src/components/ComponentProvider.js +5 -0
- package/dist/scripts/src/components/DatePicker/DatePickerNative.js +1 -0
- package/dist/scripts/src/components/Form/FormContext.js +5 -4
- package/dist/scripts/src/components/Form/FormNative.js +41 -43
- package/dist/scripts/src/components/Form/formActions.js +1 -1
- package/dist/scripts/src/components/FormItem/FormItem.js +6 -3
- package/dist/scripts/src/components/FormItem/FormItemNative.js +56 -15
- package/dist/scripts/src/components/FormItem/ItemWithLabel.js +1 -1
- package/dist/scripts/src/components/Heading/Heading.js +13 -0
- package/dist/scripts/src/components/Heading/HeadingNative.js +1 -1
- package/dist/scripts/src/components/HtmlTags/HtmlTags.js +7 -3
- package/dist/scripts/src/components/Icon/DarkToLightIcon.js +10 -0
- package/dist/scripts/src/components/Icon/LightToDark.js +10 -0
- package/dist/scripts/src/components/IconProvider.js +4 -0
- package/dist/scripts/src/components/Image/ImageNative.js +1 -1
- package/dist/scripts/src/components/Items/ItemsNative.js +8 -6
- package/dist/scripts/src/components/Link/Link.js +5 -5
- package/dist/scripts/src/components/List/ListNative.js +1 -1
- package/dist/scripts/src/components/Markdown/Markdown.js +52 -16
- package/dist/scripts/src/components/Markdown/MarkdownNative.js +34 -73
- package/dist/scripts/src/components/Markdown/highlight-code.js +160 -0
- package/dist/scripts/src/components/Markdown/parse-binding-expr.js +60 -0
- package/dist/scripts/src/components/Markdown/utils.js +282 -0
- package/dist/scripts/src/components/ModalDialog/ConfirmationModalContextProvider.js +116 -0
- package/dist/scripts/src/components/ModalDialog/Dialog.js +20 -0
- package/dist/scripts/src/components/NavGroup/NavGroupNative.js +4 -5
- package/dist/scripts/src/components/NestedApp/NestedApp.js +61 -0
- package/dist/scripts/src/components/NestedApp/NestedAppNative.js +125 -0
- package/dist/scripts/src/components/NestedApp/Tooltip.js +46 -0
- package/dist/scripts/src/components/NumberBox/NumberBox.js +4 -1
- package/dist/scripts/src/components/NumberBox/NumberBoxNative.js +2 -2
- package/dist/scripts/src/components/Option/Option.js +3 -2
- package/dist/scripts/src/components/Select/Select.js +5 -3
- package/dist/scripts/src/components/Select/SelectNative.js +53 -40
- package/dist/scripts/src/components/SelectionStore/SelectionStore.js +1 -1
- package/dist/scripts/src/components/Spinner/Spinner.js +0 -1
- package/dist/scripts/src/components/TableOfContents/TableOfContents.js +1 -0
- package/dist/scripts/src/components/Text/Text.js +12 -1
- package/dist/scripts/src/components/Text/TextNative.js +5 -1
- package/dist/scripts/src/components/TextBox/TextBox.js +6 -1
- package/dist/scripts/src/components/TextBox/TextBoxNative.js +2 -2
- package/dist/scripts/src/components/Theme/ThemeNative.js +7 -3
- package/dist/scripts/src/components/ToneChangerButton/ToneChangerButton.js +1 -3
- package/dist/scripts/src/components-core/RestApiProxy.js +10 -7
- package/dist/scripts/src/components-core/TableOfContentsContext.js +1 -1
- package/dist/scripts/src/components-core/appContext/date-functions.js +23 -0
- package/dist/scripts/src/components-core/appContext/math-function.js +27 -0
- package/dist/scripts/src/components-core/appContext/misc-utils.js +13 -0
- package/dist/scripts/src/components-core/interception/ApiInterceptor.js +199 -0
- package/dist/scripts/src/components-core/interception/ApiInterceptorProvider.js +94 -0
- package/dist/scripts/src/components-core/interception/Backend.js +128 -0
- package/dist/scripts/src/components-core/interception/Errors.js +129 -0
- package/dist/scripts/src/components-core/interception/InMemoryDb.js +41 -0
- package/dist/scripts/src/components-core/interception/IndexedDb.js +207 -0
- package/dist/scripts/src/components-core/interception/ReadonlyCollection.js +145 -0
- package/dist/scripts/src/components-core/interception/abstractions.js +2 -0
- package/dist/scripts/src/components-core/interception/apiInterceptorWorker.js +46 -0
- package/dist/scripts/src/components-core/interception/useApiInterceptorContext.js +9 -0
- package/dist/scripts/src/components-core/rendering/AppContent.js +336 -0
- package/dist/scripts/src/components-core/rendering/AppRoot.js +84 -0
- package/dist/scripts/src/components-core/rendering/AppWrapper.js +49 -0
- package/dist/scripts/src/components-core/rendering/ComponentAdapter.js +17 -7
- package/dist/scripts/src/components-core/rendering/Container.js +2 -1
- package/dist/scripts/src/components-core/theming/ThemeProvider.js +2 -7
- package/dist/scripts/src/components-core/theming/themes/root.js +1 -0
- package/dist/scripts/src/components-core/utils/date-utils.js +78 -0
- package/dist/scripts/src/components-core/utils/hooks.js +26 -0
- package/dist/scripts/src/components-core/utils/misc.js +1 -1
- package/dist/scripts/src/components-core/utils/request-params.js +70 -0
- package/dist/scripts/src/logging/LoggerContext.js +22 -0
- package/dist/scripts/src/logging/LoggerInitializer.js +14 -0
- package/dist/scripts/src/logging/LoggerService.js +60 -0
- package/dist/scripts/src/parsers/xmlui-parser/transform.js +7 -0
- package/dist/{server-common-DW5h7Q34.mjs → server-common-9TiLMTJj.mjs} +106 -98
- package/dist/style.css +3314 -2823
- package/dist/{lint-EcgF-9Wr.mjs → transform-DC0Gy6qw.mjs} +1246 -540
- package/dist/xmlui-metadata.mjs +2850 -2665
- package/dist/xmlui-metadata.umd.js +2850 -2665
- package/dist/xmlui-parser.d.ts +49 -4
- package/dist/xmlui-parser.mjs +49 -48
- package/dist/xmlui-standalone.umd.js +34674 -31457
- package/dist/xmlui.d.ts +3 -1
- package/dist/xmlui.mjs +10 -10
- package/package.json +3 -1
- package/dist/apiInterceptorWorker-7aKQ2rBj.mjs +0 -8447
- package/dist/parser-CBXS8ft2.mjs +0 -1196
|
@@ -10,12 +10,19 @@ const ComponentDefs_1 = require("../../abstractions/ComponentDefs");
|
|
|
10
10
|
const renderers_1 = require("../../components-core/renderers");
|
|
11
11
|
const themeVars_1 = require("../../components-core/theming/themeVars");
|
|
12
12
|
const MarkdownNative_1 = require("./MarkdownNative");
|
|
13
|
+
const react_1 = require("react");
|
|
14
|
+
const parse_binding_expr_1 = require("./parse-binding-expr");
|
|
15
|
+
const utils_1 = require("./utils");
|
|
13
16
|
const COMP = "Markdown";
|
|
14
17
|
exports.MarkdownMd = (0, ComponentDefs_1.createMetadata)({
|
|
15
18
|
description: `\`${COMP}\` displays plain text styled using markdown syntax.`,
|
|
16
19
|
themeVars: (0, themeVars_1.parseScssVar)(Markdown_module_scss_1.default.themeVars),
|
|
17
20
|
props: {
|
|
18
21
|
content: (0, ComponentDefs_1.d)("This property sets the markdown content to display."),
|
|
22
|
+
codeHighlighter: {
|
|
23
|
+
description: "This property sets the code highlighter to use.",
|
|
24
|
+
isInternal: true,
|
|
25
|
+
},
|
|
19
26
|
removeIndents: {
|
|
20
27
|
description: "This boolean property specifies whether leading indents should be " +
|
|
21
28
|
"removed from the markdown content. If set to `true`, the shortest " +
|
|
@@ -26,26 +33,33 @@ exports.MarkdownMd = (0, ComponentDefs_1.createMetadata)({
|
|
|
26
33
|
},
|
|
27
34
|
},
|
|
28
35
|
defaultThemeVars: {
|
|
29
|
-
"backgroundColor-Admonition": "$color-
|
|
30
|
-
"borderRadius-Admonition": "$space-
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
+
"backgroundColor-Admonition": "$color-primary-100",
|
|
37
|
+
"borderRadius-Admonition": "$space-2",
|
|
38
|
+
"border-Admonition": "1px solid $color-primary-300",
|
|
39
|
+
"iconSize-Admonition": "$space-5",
|
|
40
|
+
"paddingLeft-Admonition": "$space-2",
|
|
41
|
+
"paddingRight-Admonition": "$space-6",
|
|
42
|
+
"paddingTop-Admonition": "$space-3",
|
|
43
|
+
"paddingBottom-Admonition": "$space-2",
|
|
44
|
+
"marginLeft-Admonition-content": "$space-1_5",
|
|
45
|
+
"marginTop-Admonition": "$space-7",
|
|
46
|
+
"marginBottom-Admonition": "$space-7",
|
|
47
|
+
"marginTop-Blockquote": "$space-7",
|
|
48
|
+
"marginBottom-Blockquote": "$space-7",
|
|
49
|
+
"paddingHorizontal-Blockquote": "$space-6",
|
|
50
|
+
"paddingTop-Blockquote": "$space-3",
|
|
51
|
+
"paddingBottom-Blockquote": "$space-2_5",
|
|
52
|
+
"backgroundColor-Blockquote": "$color-surface-100",
|
|
36
53
|
"accentWidth-Blockquote": "3px",
|
|
37
54
|
"accentColor-Blockquote": "$color-surface-500",
|
|
38
|
-
"
|
|
39
|
-
"marginBottom-
|
|
40
|
-
"marginBottom-Text-codefence": "$space-2",
|
|
41
|
-
"marginBottom-Text-markdown": "$space-2",
|
|
42
|
-
"marginTop-HtmlLi": "$space-2",
|
|
43
|
-
"marginBottom-HtmlLi": "$space-2",
|
|
55
|
+
"marginTop-HtmlLi": "$space-2_5",
|
|
56
|
+
"marginBottom-HtmlLi": "$space-2_5",
|
|
44
57
|
light: {
|
|
45
58
|
// --- No light-specific theme vars
|
|
46
59
|
},
|
|
47
60
|
dark: {
|
|
48
|
-
|
|
61
|
+
"backgroundColor-Blockquote": "$color-surface-50",
|
|
62
|
+
"backgroundColor-Admonition": "$color-primary-200",
|
|
49
63
|
},
|
|
50
64
|
},
|
|
51
65
|
});
|
|
@@ -56,7 +70,7 @@ exports.markdownComponentRenderer = (0, renderers_1.createComponentRenderer)(COM
|
|
|
56
70
|
if (!renderedChildren) {
|
|
57
71
|
renderedChildren = extractValue.asString(node.props.content);
|
|
58
72
|
}
|
|
59
|
-
// 2. "data" property fallback
|
|
73
|
+
// 2. "data" property fallback
|
|
60
74
|
if (!renderedChildren) {
|
|
61
75
|
renderedChildren = extractValue.asString(node.props.data);
|
|
62
76
|
}
|
|
@@ -69,7 +83,29 @@ exports.markdownComponentRenderer = (0, renderers_1.createComponentRenderer)(COM
|
|
|
69
83
|
}
|
|
70
84
|
});
|
|
71
85
|
}
|
|
72
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
86
|
+
return ((0, jsx_runtime_1.jsx)(TransformedMarkdown, { style: layoutCss, removeIndents: extractValue.asOptionalBoolean(node.props.removeIndents, true), codeHighlighter: extractValue(node.props.codeHighlighter), extractValue: extractValue, children: renderedChildren }));
|
|
73
87
|
});
|
|
88
|
+
const TransformedMarkdown = ({ children, removeIndents, style, extractValue, codeHighlighter, }) => {
|
|
89
|
+
const markdownContent = (0, react_1.useMemo)(() => {
|
|
90
|
+
if (typeof children !== "string") {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
// --- Resolve binding expression values
|
|
94
|
+
// --- Resolve xmlui playground definitions
|
|
95
|
+
let resolvedMd = children;
|
|
96
|
+
while (true) {
|
|
97
|
+
const nextPlayground = (0, utils_1.observePlaygroundPattern)(resolvedMd);
|
|
98
|
+
if (!nextPlayground)
|
|
99
|
+
break;
|
|
100
|
+
resolvedMd =
|
|
101
|
+
resolvedMd.slice(0, nextPlayground[0]) +
|
|
102
|
+
(0, utils_1.convertPlaygroundPatternToMarkdown)(nextPlayground[2]) +
|
|
103
|
+
resolvedMd.slice(nextPlayground[1]);
|
|
104
|
+
}
|
|
105
|
+
resolvedMd = (0, parse_binding_expr_1.parseBindingExpression)(resolvedMd, extractValue);
|
|
106
|
+
return resolvedMd;
|
|
107
|
+
}, [children, extractValue]);
|
|
108
|
+
return ((0, jsx_runtime_1.jsx)(MarkdownNative_1.Markdown, { removeIndents: removeIndents, codeHighlighter: codeHighlighter, style: style, children: markdownContent }));
|
|
109
|
+
};
|
|
74
110
|
var MarkdownNative_2 = require("./MarkdownNative");
|
|
75
111
|
Object.defineProperty(exports, "Markdown", { enumerable: true, get: function () { return MarkdownNative_2.Markdown; } });
|
|
@@ -18,23 +18,38 @@ exports.Markdown = void 0;
|
|
|
18
18
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
19
|
const react_1 = require("react");
|
|
20
20
|
const react_2 = __importDefault(require("react"));
|
|
21
|
-
const react_markdown_1 =
|
|
21
|
+
const react_markdown_1 = require("react-markdown");
|
|
22
22
|
const remark_gfm_1 = __importDefault(require("remark-gfm"));
|
|
23
23
|
const rehype_raw_1 = __importDefault(require("rehype-raw"));
|
|
24
|
-
const unist_util_visit_1 = require("unist-util-visit");
|
|
25
24
|
const Markdown_module_scss_1 = __importDefault(require("./Markdown.module.scss"));
|
|
26
25
|
const HtmlTags_module_scss_1 = __importDefault(require("../HtmlTags/HtmlTags.module.scss"));
|
|
27
26
|
const HeadingNative_1 = require("../Heading/HeadingNative");
|
|
28
27
|
const TextNative_1 = require("../Text/TextNative");
|
|
29
28
|
const LinkNative_1 = require("../Link/LinkNative");
|
|
30
29
|
const Toggle_1 = require("../Toggle/Toggle");
|
|
31
|
-
const
|
|
32
|
-
|
|
30
|
+
const NestedAppNative_1 = require("../NestedApp/NestedAppNative");
|
|
31
|
+
const highlight_code_1 = require("./highlight-code");
|
|
32
|
+
const ThemeContext_1 = require("../../components-core/theming/ThemeContext");
|
|
33
|
+
const CodeBlockNative_1 = require("../CodeBlock/CodeBlockNative");
|
|
34
|
+
function PreTagComponent({ id, children, codeHighlighter }) {
|
|
35
|
+
// TEMP: After ironing out theming for syntax highlighting, this should be removed
|
|
36
|
+
const { activeThemeTone } = (0, ThemeContext_1.useTheme)();
|
|
37
|
+
const defaultCodefence = ((0, jsx_runtime_1.jsx)(CodeBlockNative_1.CodeBlock, { children: (0, jsx_runtime_1.jsx)(TextNative_1.Text, { uid: id, variant: "codefence", children: children }) }));
|
|
38
|
+
if (!codeHighlighter) {
|
|
39
|
+
return defaultCodefence;
|
|
40
|
+
}
|
|
41
|
+
const highlighterResult = (0, highlight_code_1.parseMetaAndHighlightCode)(children, codeHighlighter, activeThemeTone);
|
|
42
|
+
if (!highlighterResult) {
|
|
43
|
+
return defaultCodefence;
|
|
44
|
+
}
|
|
45
|
+
return ((0, jsx_runtime_1.jsx)(CodeBlockNative_1.CodeBlock, { meta: highlighterResult.meta, textToCopy: highlighterResult.codeStr, children: (0, jsx_runtime_1.jsx)(TextNative_1.Text, { uid: id, variant: "codefence", syntaxHighlightClasses: highlighterResult.classNames, dangerouslySetInnerHTML: { __html: highlighterResult.cleanedHtmlStr } }) }));
|
|
46
|
+
}
|
|
47
|
+
exports.Markdown = (0, react_1.memo)(function Markdown({ removeIndents = true, children, style, codeHighlighter, }) {
|
|
33
48
|
if (typeof children !== "string") {
|
|
34
49
|
return null;
|
|
35
50
|
}
|
|
36
51
|
children = removeIndents ? removeTextIndents(children) : children;
|
|
37
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: Markdown_module_scss_1.default.markdownContent, style: Object.assign({}, style), children: (0, jsx_runtime_1.jsx)(react_markdown_1.
|
|
52
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: Markdown_module_scss_1.default.markdownContent, style: Object.assign({}, style), children: (0, jsx_runtime_1.jsx)(react_markdown_1.MarkdownHooks, { remarkPlugins: [remark_gfm_1.default, CodeBlockNative_1.markdownCodeBlockParser], rehypePlugins: [rehype_raw_1.default], components: {
|
|
38
53
|
details(_a) {
|
|
39
54
|
var { children, node } = _a, props = __rest(_a, ["children", "node"]);
|
|
40
55
|
return ((0, jsx_runtime_1.jsx)("details", Object.assign({ className: HtmlTags_module_scss_1.default.htmlDetails }, props, { children: children })));
|
|
@@ -48,7 +63,7 @@ exports.Markdown = (0, react_1.memo)(function Markdown({ extractValue, removeInd
|
|
|
48
63
|
const src = props === null || props === void 0 ? void 0 : props.src;
|
|
49
64
|
const popOut = props === null || props === void 0 ? void 0 : props["data-popout"];
|
|
50
65
|
if (popOut) {
|
|
51
|
-
return ((0, jsx_runtime_1.jsx)("a", { href: src, target: "_blank", children: (0, jsx_runtime_1.jsx)("img", Object.assign({ className: HtmlTags_module_scss_1.default.htmlImage }, props, { children: children })) }));
|
|
66
|
+
return ((0, jsx_runtime_1.jsx)("a", { href: src, target: "_blank", rel: "noreferrer", children: (0, jsx_runtime_1.jsx)("img", Object.assign({ className: HtmlTags_module_scss_1.default.htmlImage }, props, { children: children })) }));
|
|
52
67
|
}
|
|
53
68
|
else {
|
|
54
69
|
return ((0, jsx_runtime_1.jsx)("img", Object.assign({ className: HtmlTags_module_scss_1.default.htmlImage }, props, { children: children })));
|
|
@@ -79,7 +94,7 @@ exports.Markdown = (0, react_1.memo)(function Markdown({ extractValue, removeInd
|
|
|
79
94
|
return ((0, jsx_runtime_1.jsx)(TextNative_1.Text, { uid: id, variant: "code", children: children }));
|
|
80
95
|
},
|
|
81
96
|
pre({ id, children }) {
|
|
82
|
-
return (
|
|
97
|
+
return (0, jsx_runtime_1.jsx)(PreTagComponent, { id: id, codeHighlighter: codeHighlighter, children: children });
|
|
83
98
|
},
|
|
84
99
|
strong({ id, children }) {
|
|
85
100
|
return ((0, jsx_runtime_1.jsx)(TextNative_1.Text, { uid: id, variant: "strong", children: children }));
|
|
@@ -110,8 +125,7 @@ exports.Markdown = (0, react_1.memo)(function Markdown({ extractValue, removeInd
|
|
|
110
125
|
},
|
|
111
126
|
a(_a) {
|
|
112
127
|
var { children, href } = _a, props = __rest(_a, ["children", "href"]);
|
|
113
|
-
|
|
114
|
-
return ((0, jsx_runtime_1.jsx)(LinkNative_1.LocalLink, Object.assign({ to: href }, allowedProps, { children: children })));
|
|
128
|
+
return ((0, jsx_runtime_1.jsx)(LinkNative_1.LocalLink, Object.assign({ to: href }, props, { children: children })));
|
|
115
129
|
},
|
|
116
130
|
// TODO: somehow get the label from the containing li element
|
|
117
131
|
input({ disabled, checked }) {
|
|
@@ -138,6 +152,17 @@ exports.Markdown = (0, react_1.memo)(function Markdown({ extractValue, removeInd
|
|
|
138
152
|
tfoot({ children }) {
|
|
139
153
|
return (0, jsx_runtime_1.jsx)("tfoot", { className: HtmlTags_module_scss_1.default.htmlTfoot, children: children });
|
|
140
154
|
},
|
|
155
|
+
samp(_a) {
|
|
156
|
+
var props = __rest(_a, []);
|
|
157
|
+
const nestedProps = props;
|
|
158
|
+
const dataContentBase64 = props === null || props === void 0 ? void 0 : props["data-pg-content"];
|
|
159
|
+
if (dataContentBase64 !== undefined) {
|
|
160
|
+
const jsonContent = atob(dataContentBase64);
|
|
161
|
+
const appProps = JSON.parse(jsonContent);
|
|
162
|
+
return ((0, jsx_runtime_1.jsx)(NestedAppNative_1.NestedApp, { app: appProps.app, config: appProps.config, components: appProps.components, api: appProps.api, activeTheme: appProps.activeTheme, activeTone: appProps.activeTone, title: appProps.name, height: appProps.height, allowPlaygroundPopup: !appProps.noPopup }));
|
|
163
|
+
}
|
|
164
|
+
return ((0, jsx_runtime_1.jsx)(NestedAppNative_1.NestedApp, { app: nestedProps.app, config: nestedProps.config, components: nestedProps.components, api: nestedProps.api, activeTheme: nestedProps.activeTheme, activeTone: nestedProps.activeTone, title: nestedProps.title, height: nestedProps.height, allowPlaygroundPopup: true }));
|
|
165
|
+
},
|
|
141
166
|
}, children: children }) }));
|
|
142
167
|
});
|
|
143
168
|
function removeTextIndents(input) {
|
|
@@ -225,67 +250,3 @@ const OrderedList = ({ children, style }) => {
|
|
|
225
250
|
const ListItem = ({ children, style }) => {
|
|
226
251
|
return ((0, jsx_runtime_1.jsx)("li", { className: Markdown_module_scss_1.default.listItem, style: style, children: children }));
|
|
227
252
|
};
|
|
228
|
-
/**
|
|
229
|
-
* Finds and evaluates given binding expressions in markdown text.
|
|
230
|
-
* The binding expressions are of the form `${...}$`.
|
|
231
|
-
* @param extractValue The function to resolve binding expressions
|
|
232
|
-
* @returns visitor function that processes the binding expressions
|
|
233
|
-
*/
|
|
234
|
-
function bindingExpression({ extractValue }) {
|
|
235
|
-
return (tree) => {
|
|
236
|
-
(0, unist_util_visit_1.visit)(tree, "text", (node) => {
|
|
237
|
-
return detectBindingExpression(node);
|
|
238
|
-
});
|
|
239
|
-
};
|
|
240
|
-
function detectBindingExpression(node) {
|
|
241
|
-
// Remove empty ${} expressions first
|
|
242
|
-
node.value = node.value.replace(/\$\{\s*\}/g, "");
|
|
243
|
-
const regex = /\$\{((?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*)\}/g;
|
|
244
|
-
const parts = node.value.split(regex);
|
|
245
|
-
if (parts.length > 1) {
|
|
246
|
-
node.type = "html";
|
|
247
|
-
node.value = parts
|
|
248
|
-
.map((part, index) => {
|
|
249
|
-
const extracted = index % 2 === 0 ? part : extractValue(`{${part}}`);
|
|
250
|
-
const resultExpr = mapByType(extracted);
|
|
251
|
-
// The result expression might be an object, in that case we stringify it here,
|
|
252
|
-
// at the last step, so that there are no unnecessary apostrophes
|
|
253
|
-
return typeof resultExpr === "object" && resultExpr !== null
|
|
254
|
-
? JSON.stringify(resultExpr)
|
|
255
|
-
: resultExpr;
|
|
256
|
-
})
|
|
257
|
-
.join("");
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
function mapByType(extracted) {
|
|
261
|
-
if (extracted === null) {
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
else if (extracted === undefined || typeof extracted === "undefined") {
|
|
265
|
-
return undefined;
|
|
266
|
-
}
|
|
267
|
-
else if (typeof extracted === "object") {
|
|
268
|
-
const arrowFuncResult = parseArrowFunc(extracted);
|
|
269
|
-
if (arrowFuncResult) {
|
|
270
|
-
return arrowFuncResult;
|
|
271
|
-
}
|
|
272
|
-
if (Array.isArray(extracted)) {
|
|
273
|
-
return extracted;
|
|
274
|
-
}
|
|
275
|
-
return Object.fromEntries(Object.entries(extracted).map(([key, value]) => {
|
|
276
|
-
return [key, mapByType(value)];
|
|
277
|
-
}));
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
return extracted;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
function parseArrowFunc(extracted) {
|
|
284
|
-
if (extracted.hasOwnProperty("type") &&
|
|
285
|
-
extracted.type === ScriptingSourceTree_1.T_ARROW_EXPRESSION &&
|
|
286
|
-
(extracted === null || extracted === void 0 ? void 0 : extracted._ARROW_EXPR_)) {
|
|
287
|
-
return "[xmlui function]";
|
|
288
|
-
}
|
|
289
|
-
return "";
|
|
290
|
-
}
|
|
291
|
-
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.CodeHighlighterMetaKeysData = exports.CodeHighlighterMetaKeys = void 0;
|
|
15
|
+
exports.parseMetaAndHighlightCode = parseMetaAndHighlightCode;
|
|
16
|
+
const react_1 = require("react");
|
|
17
|
+
/**
|
|
18
|
+
* This function handles two things:
|
|
19
|
+
* 1. The extraction of meta information from code blocks and exposing them as data-meta attributes
|
|
20
|
+
* 2. The highlighting of code blocks providing the highlighter function with meta information
|
|
21
|
+
* @param node The React node containing the code block
|
|
22
|
+
* @param codeHighlighter The highlighter object containing the highlight function and the available languages
|
|
23
|
+
* @returns CSS class names for the codefence and the HTML string with highlighted code tokens
|
|
24
|
+
*/
|
|
25
|
+
function parseMetaAndHighlightCode(node, codeHighlighter, themeTone) {
|
|
26
|
+
const codeStr = mapTextContent(node);
|
|
27
|
+
const meta = extractMetaFromChildren(node, exports.CodeHighlighterMetaKeysData, codeStr.split("\n").length);
|
|
28
|
+
const { language } = meta, restMeta = __rest(meta, ["language"]);
|
|
29
|
+
if (language && codeHighlighter.availableLangs.includes(language)) {
|
|
30
|
+
// NOTE: Keep in mind, at this point, we are working with the markdown text
|
|
31
|
+
const htmlCodeStr = codeHighlighter.highlight(codeStr, language, restMeta, themeTone);
|
|
32
|
+
const match = htmlCodeStr.match(/<pre\b[^>]*\bclass\s*=\s*["']([^"']*)["'][^>]*>/i);
|
|
33
|
+
const classNames = match ? match[1] : null;
|
|
34
|
+
// NOTE: Why remove the <pre>?
|
|
35
|
+
// Shiki appends <pre> tags to the highlighted code,
|
|
36
|
+
// so we would get <pre><pre><code>...</code></pre></pre>
|
|
37
|
+
let cleanedHtmlStr = htmlCodeStr.replace(/<pre\b[^>]*>|<\/pre>/gi, "");
|
|
38
|
+
const numberedRowClass = meta.rowNumbers ? "numbered" : "";
|
|
39
|
+
cleanedHtmlStr = cleanedHtmlStr.replaceAll(/<span class="line"/g, `<span class="line ${numberedRowClass}"`);
|
|
40
|
+
return { classNames, cleanedHtmlStr, codeStr, meta };
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function mapTextContent(node) {
|
|
45
|
+
if (typeof node === "string") {
|
|
46
|
+
return transformCodeLines(node);
|
|
47
|
+
}
|
|
48
|
+
if ((0, react_1.isValidElement)(node) && node.props && node.props.children) {
|
|
49
|
+
if (Array.isArray(node.props.children)) {
|
|
50
|
+
return node.props.children.map(mapTextContent).join("");
|
|
51
|
+
}
|
|
52
|
+
return mapTextContent(node.props.children);
|
|
53
|
+
}
|
|
54
|
+
return "";
|
|
55
|
+
// ---
|
|
56
|
+
function transformCodeLines(node) {
|
|
57
|
+
const splitNode = node.split(/\r?\n/);
|
|
58
|
+
for (let i = 0; i < splitNode.length; i++) {
|
|
59
|
+
// Backslash before a codefence indicates an escaped codefence
|
|
60
|
+
// -> don't render the backslash
|
|
61
|
+
if (splitNode[i].startsWith("\\```")) {
|
|
62
|
+
splitNode[i] = splitNode[i].replace("\\```", "```");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Remove empty lines from start and end
|
|
66
|
+
let startTrimIdx = 0;
|
|
67
|
+
let endTrimIdx = splitNode.length - 1;
|
|
68
|
+
for (let i = 0; i < splitNode.length; i++) {
|
|
69
|
+
if (splitNode[i].trim() !== "") {
|
|
70
|
+
startTrimIdx = i;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (let i = splitNode.length - 1; i >= 0; i--) {
|
|
75
|
+
if (splitNode[i].trim() !== "") {
|
|
76
|
+
endTrimIdx = i;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
splitNode.splice(0, startTrimIdx);
|
|
81
|
+
splitNode.splice(endTrimIdx + 1);
|
|
82
|
+
return splitNode.join("\n");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function extractMetaFromChildren(node, keys, codeLength = 0) {
|
|
86
|
+
if (!node)
|
|
87
|
+
return {};
|
|
88
|
+
if (typeof node === "string")
|
|
89
|
+
return {};
|
|
90
|
+
if (typeof node === "number")
|
|
91
|
+
return {};
|
|
92
|
+
if (typeof node === "boolean")
|
|
93
|
+
return {};
|
|
94
|
+
if (Array.isArray(node))
|
|
95
|
+
return {};
|
|
96
|
+
if ((0, react_1.isValidElement)(node) &&
|
|
97
|
+
node.props &&
|
|
98
|
+
node.props.children &&
|
|
99
|
+
typeof node.props.children === "string") {
|
|
100
|
+
const meta = Object.entries(node.props)
|
|
101
|
+
.filter(([key, _]) => keys.includes(key))
|
|
102
|
+
.reduce((acc, [key, value]) => {
|
|
103
|
+
acc[key] = value;
|
|
104
|
+
return acc;
|
|
105
|
+
}, {});
|
|
106
|
+
return {
|
|
107
|
+
[exports.CodeHighlighterMetaKeys.language.prop]: meta[exports.CodeHighlighterMetaKeys.language.data],
|
|
108
|
+
[exports.CodeHighlighterMetaKeys.copy.prop]: parseBoolean(meta[exports.CodeHighlighterMetaKeys.copy.data]),
|
|
109
|
+
[exports.CodeHighlighterMetaKeys.filename.prop]: meta[exports.CodeHighlighterMetaKeys.filename.data],
|
|
110
|
+
[exports.CodeHighlighterMetaKeys.rowNumbers.prop]: parseBoolean(meta[exports.CodeHighlighterMetaKeys.rowNumbers.data]),
|
|
111
|
+
[exports.CodeHighlighterMetaKeys.highlightRows.prop]: meta[exports.CodeHighlighterMetaKeys.highlightRows.data]
|
|
112
|
+
? parseRowHighlights(meta[exports.CodeHighlighterMetaKeys.highlightRows.data], codeLength)
|
|
113
|
+
: [],
|
|
114
|
+
[exports.CodeHighlighterMetaKeys.highlightSubstrings.prop]: [], // TODO
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {};
|
|
118
|
+
}
|
|
119
|
+
function parseBoolean(str) {
|
|
120
|
+
if (str === "true")
|
|
121
|
+
return true;
|
|
122
|
+
if (str === "false")
|
|
123
|
+
return false;
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
function parseRowHighlights(str, codeLines) {
|
|
127
|
+
if (str === "")
|
|
128
|
+
return [];
|
|
129
|
+
return str
|
|
130
|
+
.split(",")
|
|
131
|
+
.map((item) => {
|
|
132
|
+
item = item.trim();
|
|
133
|
+
const splitted = item.split("-");
|
|
134
|
+
const start = Number.isNaN(parseInt(splitted[0], 10)) ? -1 : parseInt(splitted[0], 10);
|
|
135
|
+
let end = 0;
|
|
136
|
+
if (splitted.length === 1) {
|
|
137
|
+
end = Number.isNaN(start + 1) ? -1 : start + 1;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
end = Number.isNaN(parseInt(splitted[1], 10)) ? -1 : parseInt(splitted[1], 10);
|
|
141
|
+
}
|
|
142
|
+
return { start, end };
|
|
143
|
+
})
|
|
144
|
+
.filter((item) => {
|
|
145
|
+
if (item.start === -1 || item.end === -1)
|
|
146
|
+
return false;
|
|
147
|
+
if (item.start > codeLines || item.end > codeLines)
|
|
148
|
+
return false;
|
|
149
|
+
return true;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
exports.CodeHighlighterMetaKeys = {
|
|
153
|
+
language: { data: "data-language", prop: "language" },
|
|
154
|
+
copy: { data: "data-copy", prop: "copy" },
|
|
155
|
+
filename: { data: "data-filename", prop: "filename" },
|
|
156
|
+
rowNumbers: { data: "data-row-numbers", prop: "rowNumbers" },
|
|
157
|
+
highlightRows: { data: "data-highlight-rows", prop: "highlightRows" },
|
|
158
|
+
highlightSubstrings: { data: "data-highlight-substrings", prop: "highlightSubstrings" },
|
|
159
|
+
};
|
|
160
|
+
exports.CodeHighlighterMetaKeysData = Object.values(exports.CodeHighlighterMetaKeys).map((item) => item.data);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseBindingExpression = parseBindingExpression;
|
|
4
|
+
const ScriptingSourceTree_1 = require("../../abstractions/scripting/ScriptingSourceTree");
|
|
5
|
+
/**
|
|
6
|
+
* Finds and evaluates given binding expressions in markdown text.
|
|
7
|
+
* The binding expressions are of the form `@{...}`.
|
|
8
|
+
* @param text The markdown text
|
|
9
|
+
* @param extractValue The function to resolve binding expressions
|
|
10
|
+
* @returns the parsed text with resolved binding expressions
|
|
11
|
+
*/
|
|
12
|
+
function parseBindingExpression(text, extractValue) {
|
|
13
|
+
// Remove empty @{} expressions first
|
|
14
|
+
text = text.replaceAll(/(?<!\\)\@\{\s*\}/g, "");
|
|
15
|
+
// The (?<!\\) is a "negative lookbehind" in regex that ensures that
|
|
16
|
+
// if escaping the @{...} expression like this: \@{...}, we don't match it
|
|
17
|
+
const regex = /(?<!\\)\@\{((?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*)\}/g;
|
|
18
|
+
const result = text.replace(regex, (_, expr) => {
|
|
19
|
+
const extracted = extractValue(`{${expr}}`);
|
|
20
|
+
const resultExpr = mapByType(extracted);
|
|
21
|
+
// The result expression might be an object, in that case we stringify it here,
|
|
22
|
+
// at the last step, so that there are no unnecessary apostrophes
|
|
23
|
+
return typeof resultExpr === "object" && resultExpr !== null
|
|
24
|
+
? JSON.stringify(resultExpr)
|
|
25
|
+
: resultExpr;
|
|
26
|
+
});
|
|
27
|
+
return result;
|
|
28
|
+
// ---
|
|
29
|
+
function mapByType(extracted) {
|
|
30
|
+
if (extracted === null) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
else if (extracted === undefined || typeof extracted === "undefined") {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
else if (typeof extracted === "object") {
|
|
37
|
+
const arrowFuncResult = parseArrowFunc(extracted);
|
|
38
|
+
if (arrowFuncResult) {
|
|
39
|
+
return arrowFuncResult;
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(extracted)) {
|
|
42
|
+
return extracted;
|
|
43
|
+
}
|
|
44
|
+
return Object.fromEntries(Object.entries(extracted).map(([key, value]) => {
|
|
45
|
+
return [key, mapByType(value)];
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
return extracted;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseArrowFunc(extracted) {
|
|
53
|
+
if (extracted.hasOwnProperty("type") &&
|
|
54
|
+
extracted.type === ScriptingSourceTree_1.T_ARROW_EXPRESSION &&
|
|
55
|
+
(extracted === null || extracted === void 0 ? void 0 : extracted._ARROW_EXPR_)) {
|
|
56
|
+
return "[xmlui function]";
|
|
57
|
+
}
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
}
|