@carbon/ai-chat-components 1.4.0 → 1.5.0-rc.1
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/custom-elements.json +837 -284
- package/es/components/chat-history/src/chat-history.scss.js +1 -1
- package/es/components/chat-history/src/history-panel-item.d.ts +14 -0
- package/es/components/chat-history/src/history-panel-item.js +30 -0
- package/es/components/chat-history/src/history-panel-item.js.map +1 -1
- package/es/components/code-snippet/src/code-snippet.d.ts +5 -0
- package/es/components/code-snippet/src/code-snippet.js +17 -5
- package/es/components/code-snippet/src/code-snippet.js.map +1 -1
- package/es/components/feedback/src/feedback.d.ts +4 -0
- package/es/components/feedback/src/feedback.js +6 -4
- package/es/components/feedback/src/feedback.js.map +1 -1
- package/es/components/markdown/index.d.ts +3 -1
- package/es/components/markdown/index.js +1 -1
- package/es/components/markdown/src/markdown-renderer-types.d.ts +100 -0
- package/es/components/markdown/src/markdown-renderer-types.js +8 -0
- package/es/components/markdown/src/markdown-renderer-types.js.map +1 -0
- package/es/components/markdown/src/markdown-renderer.d.ts +14 -64
- package/es/components/markdown/src/markdown-renderer.js +120 -134
- package/es/components/markdown/src/markdown-renderer.js.map +1 -1
- package/es/components/markdown/src/markdown-token-tree.d.ts +50 -5
- package/es/components/markdown/src/markdown-token-tree.js +182 -47
- package/es/components/markdown/src/markdown-token-tree.js.map +1 -1
- package/es/components/markdown/src/markdown.d.ts +49 -1
- package/es/components/markdown/src/markdown.js +307 -106
- package/es/components/markdown/src/markdown.js.map +1 -1
- package/es/components/markdown/src/markdown.scss.js +1 -1
- package/es/components/markdown/src/plugins/markdown-it-task-lists.js +2 -5
- package/es/components/markdown/src/plugins/markdown-it-task-lists.js.map +1 -1
- package/es/components/markdown/src/utils/lit-directives.d.ts +17 -0
- package/es/components/markdown/src/utils/lit-directives.js +84 -0
- package/es/components/markdown/src/utils/lit-directives.js.map +1 -0
- package/es/components/markdown/src/utils/plugin-fallback.d.ts +33 -0
- package/es/components/markdown/src/utils/plugin-fallback.js +219 -0
- package/es/components/markdown/src/utils/plugin-fallback.js.map +1 -0
- package/es/components/markdown/src/utils/streaming-table.d.ts +28 -0
- package/es/components/markdown/src/utils/streaming-table.js +86 -0
- package/es/components/markdown/src/utils/streaming-table.js.map +1 -0
- package/es/components/markdown/src/utils/table-helpers.d.ts +17 -0
- package/es/components/markdown/src/utils/table-helpers.js +104 -2
- package/es/components/markdown/src/utils/table-helpers.js.map +1 -1
- package/es/components/table/src/table.js +4 -1
- package/es/components/table/src/table.js.map +1 -1
- package/es/components/truncated-text/src/truncated-text.scss.js +1 -1
- package/es/components/workspace-shell/src/workspace-shell.scss.js +1 -1
- package/es/react/markdown.d.ts +46 -2
- package/es/react/markdown.js +177 -20
- package/es/react/markdown.js.map +1 -1
- package/es-custom/components/chat-history/src/chat-history.scss.js +1 -1
- package/es-custom/components/chat-history/src/history-panel-item.d.ts +14 -0
- package/es-custom/components/chat-history/src/history-panel-item.js +30 -0
- package/es-custom/components/chat-history/src/history-panel-item.js.map +1 -1
- package/es-custom/components/code-snippet/src/code-snippet.d.ts +5 -0
- package/es-custom/components/code-snippet/src/code-snippet.js +17 -5
- package/es-custom/components/code-snippet/src/code-snippet.js.map +1 -1
- package/es-custom/components/feedback/src/feedback.d.ts +4 -0
- package/es-custom/components/feedback/src/feedback.js +6 -4
- package/es-custom/components/feedback/src/feedback.js.map +1 -1
- package/es-custom/components/markdown/index.d.ts +3 -1
- package/es-custom/components/markdown/index.js +1 -1
- package/es-custom/components/markdown/src/markdown-renderer-types.d.ts +100 -0
- package/es-custom/components/markdown/src/markdown-renderer-types.js +8 -0
- package/es-custom/components/markdown/src/markdown-renderer-types.js.map +1 -0
- package/es-custom/components/markdown/src/markdown-renderer.d.ts +14 -64
- package/es-custom/components/markdown/src/markdown-renderer.js +120 -134
- package/es-custom/components/markdown/src/markdown-renderer.js.map +1 -1
- package/es-custom/components/markdown/src/markdown-token-tree.d.ts +50 -5
- package/es-custom/components/markdown/src/markdown-token-tree.js +182 -47
- package/es-custom/components/markdown/src/markdown-token-tree.js.map +1 -1
- package/es-custom/components/markdown/src/markdown.d.ts +49 -1
- package/es-custom/components/markdown/src/markdown.js +307 -106
- package/es-custom/components/markdown/src/markdown.js.map +1 -1
- package/es-custom/components/markdown/src/markdown.scss.js +1 -1
- package/es-custom/components/markdown/src/plugins/markdown-it-task-lists.js +2 -5
- package/es-custom/components/markdown/src/plugins/markdown-it-task-lists.js.map +1 -1
- package/es-custom/components/markdown/src/utils/lit-directives.d.ts +17 -0
- package/es-custom/components/markdown/src/utils/lit-directives.js +84 -0
- package/es-custom/components/markdown/src/utils/lit-directives.js.map +1 -0
- package/es-custom/components/markdown/src/utils/plugin-fallback.d.ts +33 -0
- package/es-custom/components/markdown/src/utils/plugin-fallback.js +219 -0
- package/es-custom/components/markdown/src/utils/plugin-fallback.js.map +1 -0
- package/es-custom/components/markdown/src/utils/streaming-table.d.ts +28 -0
- package/es-custom/components/markdown/src/utils/streaming-table.js +86 -0
- package/es-custom/components/markdown/src/utils/streaming-table.js.map +1 -0
- package/es-custom/components/markdown/src/utils/table-helpers.d.ts +17 -0
- package/es-custom/components/markdown/src/utils/table-helpers.js +104 -2
- package/es-custom/components/markdown/src/utils/table-helpers.js.map +1 -1
- package/es-custom/components/table/src/table.js +4 -1
- package/es-custom/components/table/src/table.js.map +1 -1
- package/es-custom/components/truncated-text/src/truncated-text.scss.js +1 -1
- package/es-custom/components/workspace-shell/src/workspace-shell.scss.js +1 -1
- package/es-custom/react/markdown.d.ts +46 -2
- package/es-custom/react/markdown.js +177 -20
- package/es-custom/react/markdown.js.map +1 -1
- package/package.json +5 -4
- package/es/components/markdown/src/utils.d.ts +0 -4
- package/es/components/markdown/src/utils.js +0 -25
- package/es/components/markdown/src/utils.js.map +0 -1
- package/es-custom/components/markdown/src/utils.d.ts +0 -4
- package/es-custom/components/markdown/src/utils.js +0 -25
- package/es-custom/components/markdown/src/utils.js.map +0 -1
|
@@ -1,4 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The parse/diff layer between raw markdown source and the renderer. Parses with markdown-it (built-in plugins plus any caller-supplied `markdownItPlugins`), builds a nested {@link TokenTree}, and diffs it against the previous tree so streaming updates can reuse stable subtrees.
|
|
3
|
+
*
|
|
4
|
+
* ### Why diff
|
|
5
|
+
*
|
|
6
|
+
* `diffTokenTree` reuses old nodes by `key` whenever the key matches. This is what lets `./markdown-renderer.ts`'s use of Lit's `repeat` directive keep DOM stable during streaming: each incoming chunk re-parses the full source, but matched keys reuse the prior subtree, so only the genuinely new tail differs.
|
|
7
|
+
*
|
|
8
|
+
* ### Why `cachedHtml`
|
|
9
|
+
*
|
|
10
|
+
* For the leaf token types in {@link PLUGIN_DELEGABLE_TOKEN_TYPES}, when a user plugin's renderer rule produces the HTML (via `./utils/plugin-fallback.ts`), the result is cached on the `TokenTree` node and carried forward by `diffTokenTree` whenever the underlying token's `content` / `attrs` / `info` are unchanged. A stable earlier-in-document fence/image/etc. therefore isn't re-rendered through the plugin's rule on every streaming chunk. The cache is tagged with the `MarkdownIt` instance that produced it; a plugin swap (which builds a fresh instance) invalidates the cache on read.
|
|
11
|
+
*
|
|
12
|
+
* The block comment on {@link PLUGIN_DELEGABLE_TOKEN_TYPES} explains why only those four token types are eligible for delegation.
|
|
13
|
+
*
|
|
14
|
+
* ### Related files
|
|
15
|
+
*
|
|
16
|
+
* - `./markdown-renderer.ts` — consumes the `TokenTree` and produces a Lit `TemplateResult`.
|
|
17
|
+
* - `./utils/plugin-fallback.ts` — reads `cachedHtml` and {@link getPluginOverriddenRules} to drive the delegated-render flow.
|
|
18
|
+
*/
|
|
19
|
+
import MarkdownIt, { Token } from "markdown-it";
|
|
2
20
|
/**
|
|
3
21
|
* Represents a node in the token tree structure.
|
|
4
22
|
*/
|
|
@@ -11,9 +29,20 @@ export interface TokenTree {
|
|
|
11
29
|
children: TokenTree[];
|
|
12
30
|
}
|
|
13
31
|
/**
|
|
14
|
-
*
|
|
32
|
+
* A markdown-it plugin reference. Either a bare plugin function or a
|
|
33
|
+
* `[plugin, options]` / `[plugin, ...params]` tuple matching
|
|
34
|
+
* `MarkdownIt.use(...)`.
|
|
35
|
+
*
|
|
36
|
+
* @experimental
|
|
37
|
+
*/
|
|
38
|
+
export type MarkdownItPlugin = MarkdownIt.PluginSimple | [MarkdownIt.PluginWithOptions<unknown>, unknown] | [MarkdownIt.PluginWithParams, ...unknown[]];
|
|
39
|
+
/**
|
|
40
|
+
* Returns a (cached) markdown-it instance for the given plugin set, choosing the
|
|
41
|
+
* html-enabled variant or the html-disabled (HTML-neutralizing) variant based on
|
|
42
|
+
* `removeHtml`. Calling with the same `plugins` reference and `removeHtml` returns
|
|
43
|
+
* the same instance.
|
|
15
44
|
*/
|
|
16
|
-
export declare function
|
|
45
|
+
export declare function getMarkdownIt(plugins?: MarkdownItPlugin[], removeHtml?: boolean): MarkdownIt;
|
|
17
46
|
/**
|
|
18
47
|
* Converts a flat list of markdown-it tokens into a tree.
|
|
19
48
|
*/
|
|
@@ -27,6 +56,22 @@ export declare function buildTokenTree(tokens: Token[]): TokenTree;
|
|
|
27
56
|
*/
|
|
28
57
|
export declare function diffTokenTree(oldTree: TokenTree | undefined, newTree: TokenTree): TokenTree;
|
|
29
58
|
/**
|
|
30
|
-
*
|
|
59
|
+
* Result of {@link markdownToTokenTree}. Returns the parsed tree plus the
|
|
60
|
+
* markdown-it instance used to produce it so the renderer can fall back to
|
|
61
|
+
* `md.renderer.render()` for plugin-introduced tokens. The set of
|
|
62
|
+
* plugin-overridden rules is read from the per-instance WeakMap via
|
|
63
|
+
* {@link getPluginOverriddenRules} as needed.
|
|
64
|
+
*/
|
|
65
|
+
export interface MarkdownToTokenTreeResult {
|
|
66
|
+
tree: TokenTree;
|
|
67
|
+
md: MarkdownIt;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Converts markdown into a tree with keys on it for Lit. The returned `md` is the
|
|
71
|
+
* (cached) markdown-it instance keyed by `markdownItPlugins` identity and the
|
|
72
|
+
* `removeHtml` flag (html-enabled vs html-neutralizing variant).
|
|
31
73
|
*/
|
|
32
|
-
export declare function markdownToTokenTree(markdown: string, lastTree
|
|
74
|
+
export declare function markdownToTokenTree(markdown: string, lastTree: TokenTree | undefined, opts?: {
|
|
75
|
+
removeHtml?: boolean;
|
|
76
|
+
markdownItPlugins?: MarkdownItPlugin[];
|
|
77
|
+
}): MarkdownToTokenTreeResult;
|
|
@@ -19,48 +19,148 @@ import { markdownItTaskLists } from './plugins/markdown-it-task-lists.js';
|
|
|
19
19
|
* @license
|
|
20
20
|
*/
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* The parse/diff layer between raw markdown source and the renderer. Parses with markdown-it (built-in plugins plus any caller-supplied `markdownItPlugins`), builds a nested {@link TokenTree}, and diffs it against the previous tree so streaming updates can reuse stable subtrees.
|
|
23
|
+
*
|
|
24
|
+
* ### Why diff
|
|
25
|
+
*
|
|
26
|
+
* `diffTokenTree` reuses old nodes by `key` whenever the key matches. This is what lets `./markdown-renderer.ts`'s use of Lit's `repeat` directive keep DOM stable during streaming: each incoming chunk re-parses the full source, but matched keys reuse the prior subtree, so only the genuinely new tail differs.
|
|
27
|
+
*
|
|
28
|
+
* ### Why `cachedHtml`
|
|
29
|
+
*
|
|
30
|
+
* For the leaf token types in {@link PLUGIN_DELEGABLE_TOKEN_TYPES}, when a user plugin's renderer rule produces the HTML (via `./utils/plugin-fallback.ts`), the result is cached on the `TokenTree` node and carried forward by `diffTokenTree` whenever the underlying token's `content` / `attrs` / `info` are unchanged. A stable earlier-in-document fence/image/etc. therefore isn't re-rendered through the plugin's rule on every streaming chunk. The cache is tagged with the `MarkdownIt` instance that produced it; a plugin swap (which builds a fresh instance) invalidates the cache on read.
|
|
31
|
+
*
|
|
32
|
+
* The block comment on {@link PLUGIN_DELEGABLE_TOKEN_TYPES} explains why only those four token types are eligible for delegation.
|
|
33
|
+
*
|
|
34
|
+
* ### Related files
|
|
35
|
+
*
|
|
36
|
+
* - `./markdown-renderer.ts` — consumes the `TokenTree` and produces a Lit `TemplateResult`.
|
|
37
|
+
* - `./utils/plugin-fallback.ts` — reads `cachedHtml` and {@link getPluginOverriddenRules} to drive the delegated-render flow.
|
|
24
38
|
*/
|
|
25
|
-
const htmlMarkdown = new MarkdownIt("commonmark", {
|
|
26
|
-
html: true,
|
|
27
|
-
breaks: true,
|
|
28
|
-
linkify: true,
|
|
29
|
-
})
|
|
30
|
-
.enable("table")
|
|
31
|
-
.enable("strikethrough")
|
|
32
|
-
.enable("linkify")
|
|
33
|
-
.use(markdownItAttrs)
|
|
34
|
-
.use(markdownItHighlight)
|
|
35
|
-
.use(markdownItTaskLists);
|
|
36
39
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
40
|
+
* Token types whose renderer rule, when overridden by a user-supplied
|
|
41
|
+
* markdown-it plugin, will be honored — instead of the native Lit dispatch.
|
|
42
|
+
* All four are leaf tokens (`nesting === 0`) so the slice handed to
|
|
43
|
+
* `md.renderer.render()` is a single token and the rendered HTML can be
|
|
44
|
+
* safely cached on the {@link TokenTree} node.
|
|
45
|
+
*
|
|
46
|
+
* Container tokens (paragraph_open, heading_open, list_*_open, table_open)
|
|
47
|
+
* are intentionally excluded: delegating them would erase Carbon custom
|
|
48
|
+
* elements (cds-unordered-list, cds-list-item, cds-aichat-table) and break
|
|
49
|
+
* streaming-friendly per-child diffing for the subtree. Link tokens are
|
|
50
|
+
* excluded because the native `<a>` dispatch injects `target="_blank"` for
|
|
51
|
+
* chat-link safety.
|
|
52
|
+
*
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
const PLUGIN_DELEGABLE_TOKEN_TYPES = new Set([
|
|
56
|
+
"fence",
|
|
57
|
+
"image",
|
|
58
|
+
"code_inline",
|
|
59
|
+
"html_block",
|
|
60
|
+
]);
|
|
61
|
+
// Per-instance set of renderer-rule keys that user plugins overrode (or
|
|
62
|
+
// added) relative to the snapshot taken after our built-in plugins ran.
|
|
63
|
+
// WeakMap so cleanup follows the MarkdownIt instance's lifetime.
|
|
64
|
+
const pluginOverriddenRulesByMd = new WeakMap();
|
|
65
|
+
const EMPTY_RULE_SET = new Set();
|
|
66
|
+
/**
|
|
67
|
+
* Returns the set of renderer-rule keys that user-supplied plugins overrode
|
|
68
|
+
* (or freshly added) on the given markdown-it instance, relative to the
|
|
69
|
+
* baseline established after our built-in plugins (markdownItAttrs,
|
|
70
|
+
* markdownItHighlight, markdownItTaskLists) ran. The renderer uses this to
|
|
71
|
+
* decide which token types to route through `md.renderer.render()` instead
|
|
72
|
+
* of native Lit dispatch. Returns an empty set for instances we didn't build.
|
|
73
|
+
*
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
function getPluginOverriddenRules(md) {
|
|
77
|
+
return pluginOverriddenRulesByMd.get(md) ?? EMPTY_RULE_SET;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Builds a new markdown-it instance with the built-in plugins and any user-supplied
|
|
81
|
+
* plugins applied on top. `options.html` selects whether raw HTML is parsed as HTML
|
|
82
|
+
* (`true`, the default) or neutralized to inert escaped text (`false`, used when
|
|
83
|
+
* {@link CDSAIChatMarkdown.removeHTML} is set). Both variants are built through this
|
|
84
|
+
* same path so plugin application and overridden-rule snapshotting stay identical.
|
|
85
|
+
*
|
|
86
|
+
* Snapshots `md.renderer.rules` after the built-in plugins but before the user
|
|
87
|
+
* plugins, then records the keys whose function reference changed (or whose
|
|
88
|
+
* key was added) into {@link pluginOverriddenRulesByMd}.
|
|
89
|
+
*/
|
|
90
|
+
function createMarkdownIt(plugins, options = {}) {
|
|
91
|
+
const md = new MarkdownIt("commonmark", {
|
|
92
|
+
html: options.html ?? true,
|
|
93
|
+
breaks: true,
|
|
94
|
+
linkify: true,
|
|
95
|
+
})
|
|
96
|
+
.enable("table")
|
|
97
|
+
.enable("strikethrough")
|
|
98
|
+
.enable("linkify")
|
|
99
|
+
.use(markdownItAttrs)
|
|
100
|
+
.use(markdownItHighlight)
|
|
101
|
+
.use(markdownItTaskLists);
|
|
102
|
+
const baselineRules = {
|
|
103
|
+
...md.renderer.rules,
|
|
104
|
+
};
|
|
105
|
+
for (const plugin of plugins ?? []) {
|
|
106
|
+
if (Array.isArray(plugin)) {
|
|
107
|
+
const [fn, ...args] = plugin;
|
|
108
|
+
md.use(fn, ...args);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
md.use(plugin);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const currentRules = md.renderer.rules;
|
|
115
|
+
const overridden = new Set();
|
|
116
|
+
const allKeys = new Set([
|
|
117
|
+
...Object.keys(baselineRules),
|
|
118
|
+
...Object.keys(currentRules),
|
|
119
|
+
]);
|
|
120
|
+
for (const key of allKeys) {
|
|
121
|
+
if (currentRules[key] !== baselineRules[key]) {
|
|
122
|
+
overridden.add(key);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
pluginOverriddenRulesByMd.set(md, overridden);
|
|
126
|
+
return md;
|
|
127
|
+
}
|
|
128
|
+
// Cache for the no-plugins default instances.
|
|
129
|
+
const defaultMarkdownIt = {};
|
|
130
|
+
// Cache keyed by plugin-array identity. WeakMap so plugin arrays that go out of
|
|
131
|
+
// scope can be collected.
|
|
132
|
+
const markdownItCache = new WeakMap();
|
|
133
|
+
/**
|
|
134
|
+
* Returns a (cached) markdown-it instance for the given plugin set, choosing the
|
|
135
|
+
* html-enabled variant or the html-disabled (HTML-neutralizing) variant based on
|
|
136
|
+
* `removeHtml`. Calling with the same `plugins` reference and `removeHtml` returns
|
|
137
|
+
* the same instance.
|
|
39
138
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
139
|
+
function getMarkdownIt(plugins, removeHtml = false) {
|
|
140
|
+
const variants = !plugins || plugins.length === 0
|
|
141
|
+
? defaultMarkdownIt
|
|
142
|
+
: (markdownItCache.get(plugins) ??
|
|
143
|
+
(() => {
|
|
144
|
+
const created = {};
|
|
145
|
+
markdownItCache.set(plugins, created);
|
|
146
|
+
return created;
|
|
147
|
+
})());
|
|
148
|
+
const slot = removeHtml ? "noHtml" : "html";
|
|
149
|
+
if (!variants[slot]) {
|
|
150
|
+
variants[slot] = createMarkdownIt(plugins, { html: !removeHtml });
|
|
151
|
+
}
|
|
152
|
+
return variants[slot];
|
|
153
|
+
}
|
|
51
154
|
// markdown-it treats a closing HTML tag and the next markdown line (ie. </div>\n##Heading) as one HTML
|
|
52
155
|
// block when there is no blank line between them. Insert an extra newline so the
|
|
53
156
|
// following markdown is parsed as markdown, not swallowed into the HTML token.
|
|
54
|
-
function normalizeHtmlBlockBoundaries(markdown
|
|
55
|
-
if (!allowHtml) {
|
|
56
|
-
return markdown;
|
|
57
|
-
}
|
|
157
|
+
function normalizeHtmlBlockBoundaries(markdown) {
|
|
58
158
|
return markdown.replace(/(^|\n)(\s*<\/\s*[A-Za-z][\w:-]*\s*>)(\r?\n)(?=\S)/g, "$1$2$3$3");
|
|
59
159
|
}
|
|
60
160
|
// Fallback for html_block tokens that still bundle a closing tag with trailing
|
|
61
161
|
// markdown on the next line. Split them so the closer stays HTML and the rest
|
|
62
162
|
// is re-parsed as markdown.
|
|
63
|
-
function splitHtmlBlockTrailingMarkdown(tokens,
|
|
163
|
+
function splitHtmlBlockTrailingMarkdown(tokens, md) {
|
|
64
164
|
return tokens.flatMap((token) => {
|
|
65
165
|
if (token.type !== "html_block") {
|
|
66
166
|
return [token];
|
|
@@ -77,18 +177,23 @@ function splitHtmlBlockTrailingMarkdown(tokens, allowHtml) {
|
|
|
77
177
|
};
|
|
78
178
|
return [
|
|
79
179
|
htmlToken,
|
|
80
|
-
...
|
|
180
|
+
...md.parse(`${leadingWhitespace}${trailingMarkdown}`, {}),
|
|
81
181
|
];
|
|
82
182
|
});
|
|
83
183
|
}
|
|
84
184
|
/**
|
|
85
|
-
* Parses markdown text into a flat array of markdown-it tokens.
|
|
185
|
+
* Parses markdown text into a flat array of markdown-it tokens using the given instance.
|
|
186
|
+
*
|
|
187
|
+
* When `removeHtml` is set, `md` is the html-disabled instance: raw HTML is
|
|
188
|
+
* neutralized to inert escaped text (content preserved) and there are no HTML
|
|
189
|
+
* blocks to normalize or split, so the boundary fixups are skipped.
|
|
86
190
|
*/
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
191
|
+
function parseMarkdown(fullText, md, removeHtml) {
|
|
192
|
+
if (removeHtml) {
|
|
193
|
+
return md.parse(fullText, {});
|
|
194
|
+
}
|
|
195
|
+
const normalizedText = normalizeHtmlBlockBoundaries(fullText);
|
|
196
|
+
return splitHtmlBlockTrailingMarkdown(md.parse(normalizedText, {}), md);
|
|
92
197
|
}
|
|
93
198
|
/**
|
|
94
199
|
* Generates a unique string key for a markdown-it token.
|
|
@@ -156,6 +261,23 @@ function buildTokenTree(tokens) {
|
|
|
156
261
|
});
|
|
157
262
|
return root;
|
|
158
263
|
}
|
|
264
|
+
function attrsEqual(a, b) {
|
|
265
|
+
if (a === b) {
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
if (!a || !b) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
if (a.length !== b.length) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
for (let i = 0; i < a.length; i++) {
|
|
275
|
+
if (a[i][0] !== b[i][0] || a[i][1] !== b[i][1]) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
159
281
|
/**
|
|
160
282
|
* Compares two TokenTree structures and creates a new tree that reuses
|
|
161
283
|
* unchanged nodes from the old tree.
|
|
@@ -174,6 +296,18 @@ function diffTokenTree(oldTree, newTree) {
|
|
|
174
296
|
token: newTree.token,
|
|
175
297
|
children: [],
|
|
176
298
|
};
|
|
299
|
+
// Carry forward the rendered-HTML cache for leaf tokens delegated to the
|
|
300
|
+
// markdown-it renderer. Skip when the underlying token content, attrs, or
|
|
301
|
+
// info changed (info is the fence's language string and drives the rendered
|
|
302
|
+
// output for plugins like markdown-it-mermaid / syntax highlighters).
|
|
303
|
+
if (oldTree.cachedHtml !== undefined &&
|
|
304
|
+
typeof newTree.token.type === "string" &&
|
|
305
|
+
PLUGIN_DELEGABLE_TOKEN_TYPES.has(newTree.token.type) &&
|
|
306
|
+
oldTree.token.content === newTree.token.content &&
|
|
307
|
+
oldTree.token.info === newTree.token.info &&
|
|
308
|
+
attrsEqual(oldTree.token.attrs ?? undefined, newTree.token.attrs ?? undefined)) {
|
|
309
|
+
merged.cachedHtml = oldTree.cachedHtml;
|
|
310
|
+
}
|
|
177
311
|
// Create lookup map of old children by key for efficient comparison
|
|
178
312
|
const oldChildrenByKey = new Map(oldTree.children.map((child) => [child.key, child]));
|
|
179
313
|
// Process each new child, reusing old ones where possible
|
|
@@ -191,16 +325,17 @@ function diffTokenTree(oldTree, newTree) {
|
|
|
191
325
|
return merged;
|
|
192
326
|
}
|
|
193
327
|
/**
|
|
194
|
-
* Converts markdown into a tree with keys on it for Lit.
|
|
328
|
+
* Converts markdown into a tree with keys on it for Lit. The returned `md` is the
|
|
329
|
+
* (cached) markdown-it instance keyed by `markdownItPlugins` identity and the
|
|
330
|
+
* `removeHtml` flag (html-enabled vs html-neutralizing variant).
|
|
195
331
|
*/
|
|
196
|
-
function markdownToTokenTree(markdown, lastTree,
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
const tree = buildTokenTree(tokens);
|
|
201
|
-
|
|
202
|
-
return diffTokenTree(lastTree, tree);
|
|
332
|
+
function markdownToTokenTree(markdown, lastTree, opts = {}) {
|
|
333
|
+
const removeHtml = opts.removeHtml ?? false;
|
|
334
|
+
const md = getMarkdownIt(opts.markdownItPlugins, removeHtml);
|
|
335
|
+
const tokens = parseMarkdown(markdown, md, removeHtml);
|
|
336
|
+
const tree = diffTokenTree(lastTree, buildTokenTree(tokens));
|
|
337
|
+
return { tree, md };
|
|
203
338
|
}
|
|
204
339
|
|
|
205
|
-
export { buildTokenTree, diffTokenTree,
|
|
340
|
+
export { PLUGIN_DELEGABLE_TOKEN_TYPES, buildTokenTree, diffTokenTree, getMarkdownIt, getPluginOverriddenRules, markdownToTokenTree };
|
|
206
341
|
//# sourceMappingURL=markdown-token-tree.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-token-tree.js","sources":["../../../../src/components/markdown/src/markdown-token-tree.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;;;;;AAOG;
|
|
1
|
+
{"version":3,"file":"markdown-token-tree.js","sources":["../../../../src/components/markdown/src/markdown-token-tree.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import { LitElement, PropertyValues, TemplateResult } from "lit";
|
|
2
|
+
import { type MarkdownItPlugin } from "./markdown-token-tree.js";
|
|
3
|
+
import { type MarkdownCustomRenderers } from "./markdown-renderer.js";
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* Renders markdown as Carbon-styled DOM. Streaming-friendly: incremental updates reparse the markdown source into a `TokenTree`, diff it against the prior tree to reuse stable subtrees, then walk it into a Lit `TemplateResult` — Lit's `repeat` directive keys off the diffed nodes so unchanged DOM stays put.
|
|
6
|
+
*
|
|
7
|
+
* ### Lifecycle
|
|
8
|
+
*
|
|
9
|
+
* 1. A property setter (or a light-DOM mutation) lands. `willUpdate` decides whether the change requires a reparse (`markdown`, `removeHTML`, `markdownItPlugins`) or only a re-render (translated strings, `streaming`, `sanitizeHTML`, `customRenderers`).
|
|
10
|
+
* 2. `scheduleRender` throttles bursts to 100ms (leading + trailing).
|
|
11
|
+
* 3. `renderMarkdown` parses (if needed) via {@link markdownToTokenTree}, then calls {@link renderMarkdownTree} to produce both a `TemplateResult` and a batch of {@link MarkdownRendererSlotDescriptor} records.
|
|
12
|
+
* 4. After Lit commits, `updated()` runs `reconcileCustomRendererHosts` — that is where consumer-supplied `customRenderers` callbacks fire and plugin-fallback HTML is adopted into light-DOM slot hosts.
|
|
13
|
+
*
|
|
14
|
+
* ### Extensibility
|
|
15
|
+
*
|
|
16
|
+
* - {@link markdownItPlugins} runs after the built-in markdown-it plugins (markdown-it-attrs, highlight, task-lists). A new array identity rebuilds the markdown-it instance and forces a full reparse. Tokens introduced by a plugin that the native dispatch can't handle — either an unknown tag, or a plugin-overridden rule on a curated allow-list of leaf tokens — route through `md.renderer.render()` via `./utils/plugin-fallback.ts` and surface as `pluginFallback` descriptors. Their rendered HTML is adopted into a light-DOM slot host so consumer-supplied CSS (e.g. a KaTeX stylesheet on the host page) reaches it.
|
|
17
|
+
* - {@link customRenderers} overrides per-element rendering for `table` and `codeBlock`. The renderer emits a named `<slot>` placeholder; the reconciler invokes the consumer's callback with the parsed data and appends the returned `HTMLElement` as a `<div slot="…">` light-DOM child. Returning the same element reference across renders avoids DOM churn.
|
|
18
|
+
*
|
|
19
|
+
* ### Light-DOM source adoption
|
|
20
|
+
*
|
|
21
|
+
* When the `markdown` property has never been set explicitly, the element treats its light-DOM text content as the initial source and watches for further mutations via a `MutationObserver`. Setting the property explicitly stops the observer — the property is then the authoritative source.
|
|
22
|
+
*
|
|
23
|
+
* ### Related files
|
|
24
|
+
*
|
|
25
|
+
* - `./markdown-token-tree.ts` — markdown-it parse + tree builder + streaming-aware diff (with `cachedHtml` carry-forward for plugin-delegated tokens).
|
|
26
|
+
* - `./markdown-renderer.ts` — `TokenTree` → Lit `TemplateResult`, plus descriptor collection.
|
|
27
|
+
* - `./markdown-renderer-types.ts` — public ({@link MarkdownCustomRenderers}) and internal ({@link MarkdownRendererSlotDescriptor}, `RenderTokenTreeOptions`) contracts.
|
|
28
|
+
* - `./utils/plugin-fallback.ts` — delegation to `md.renderer.render()` for plugin-introduced tokens.
|
|
29
|
+
* - `./utils/streaming-table.ts` — heuristics that hold a streaming table in a skeleton "loading" state until its tail stabilizes.
|
|
30
|
+
*
|
|
4
31
|
* @element cds-aichat-markdown
|
|
5
32
|
*/
|
|
6
33
|
declare class CDSAIChatMarkdown extends LitElement {
|
|
@@ -61,6 +88,26 @@ declare class CDSAIChatMarkdown extends LitElement {
|
|
|
61
88
|
end: number;
|
|
62
89
|
count: number;
|
|
63
90
|
}) => string;
|
|
91
|
+
/**
|
|
92
|
+
* Markdown-it plugins applied after the built-in plugins
|
|
93
|
+
* (markdown-it-attrs, markdown-it-highlight, markdown-it-task-lists).
|
|
94
|
+
* Changes force a reparse. Memoize this array — a new reference each render
|
|
95
|
+
* rebuilds the markdown-it instance.
|
|
96
|
+
*/
|
|
97
|
+
markdownItPlugins?: MarkdownItPlugin[];
|
|
98
|
+
/**
|
|
99
|
+
* Per-element render overrides. For each `kind` whose callback is provided,
|
|
100
|
+
* the markdown element emits a named `<slot>` placeholder in its shadow
|
|
101
|
+
* DOM, then — after each render — invokes the callback with the parsed
|
|
102
|
+
* data and adopts the returned `HTMLElement` as a `<div slot="…">`
|
|
103
|
+
* light-DOM child of this element. Return `null` to fall back to the
|
|
104
|
+
* default Carbon rendering. Returning the same element reference across
|
|
105
|
+
* renders avoids DOM churn.
|
|
106
|
+
*
|
|
107
|
+
* The consumer's returned element lives in this element's light DOM, not
|
|
108
|
+
* in its shadow root, so external CSS applies normally.
|
|
109
|
+
*/
|
|
110
|
+
customRenderers?: MarkdownCustomRenderers;
|
|
64
111
|
private hasRenderedStreamingTableLoadingFrame;
|
|
65
112
|
private stagedStreamingTokenTree;
|
|
66
113
|
private isStreamingTableLoadingMode;
|
|
@@ -72,6 +119,7 @@ declare class CDSAIChatMarkdown extends LitElement {
|
|
|
72
119
|
private stopObservingLightDom;
|
|
73
120
|
protected willUpdate(changed: PropertyValues<this>): void;
|
|
74
121
|
protected getUpdateComplete(): Promise<boolean>;
|
|
122
|
+
protected updated(changed: PropertyValues<this>): void;
|
|
75
123
|
protected render(): TemplateResult<1>;
|
|
76
124
|
}
|
|
77
125
|
declare global {
|