@juspay/svelte-ui-components 4.11.5 → 4.12.0
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/MarkdownText/markdown.js +34 -5
- package/dist/MarkdownText/properties.d.ts +28 -8
- package/dist-wc/index.js +4676 -18
- package/package.json +4 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Marked } from 'marked';
|
|
2
|
+
import { parseFragment } from 'parse5';
|
|
2
3
|
/**
|
|
3
4
|
* Chat content comes from models and users, not from the app's own templates,
|
|
4
5
|
* so the output must be safe without asking consumers to run a sanitizer:
|
|
5
|
-
* raw HTML never passes through (
|
|
6
|
+
* raw HTML never passes through (escaped by default, tags optionally stripped), and only these
|
|
6
7
|
* URL protocols survive on links. Everything else in the output is built by
|
|
7
8
|
* marked from markdown syntax alone.
|
|
8
9
|
*/
|
|
@@ -109,10 +110,36 @@ function resolveTagAllowList(allowedTags) {
|
|
|
109
110
|
function tagAllowed(allowed, tag) {
|
|
110
111
|
return allowed === null || allowed.has(tag);
|
|
111
112
|
}
|
|
112
|
-
|
|
113
|
+
/**
|
|
114
|
+
* As with `narrow` and `resolveTagAllowList`, a plain-JS or web-component
|
|
115
|
+
* consumer can hand this anything at runtime, so anything other than the one
|
|
116
|
+
* recognised opt-in degrades to today's escaping rather than throwing — an
|
|
117
|
+
* unrecognised value must never be the reason content silently disappears.
|
|
118
|
+
*/
|
|
119
|
+
function resolveRawHtmlMode(rawHtml) {
|
|
120
|
+
return rawHtml === 'strip' ? 'strip' : 'escape';
|
|
121
|
+
}
|
|
122
|
+
// An inert, server-compatible HTML parser handles quoted delimiters, entities
|
|
123
|
+
// and raw-text elements. Escaping its text nodes prevents decoded entities from
|
|
124
|
+
// becoming markup when the resulting string is rendered by Svelte.
|
|
125
|
+
function rawHtmlText(node) {
|
|
126
|
+
if ('value' in node) {
|
|
127
|
+
return escapeHtml(node.value);
|
|
128
|
+
}
|
|
129
|
+
// A <template>'s children live in a separate `content` fragment rather than
|
|
130
|
+
// in childNodes, so recursing only through childNodes loses its text.
|
|
131
|
+
if ('content' in node) {
|
|
132
|
+
return rawHtmlText(node.content);
|
|
133
|
+
}
|
|
134
|
+
if ('childNodes' in node) {
|
|
135
|
+
return node.childNodes.map(rawHtmlText).join('');
|
|
136
|
+
}
|
|
137
|
+
return '';
|
|
138
|
+
}
|
|
139
|
+
function createSanitizingRenderer(protocols, allowedTags, disableTaskLists, rawHtml) {
|
|
113
140
|
return {
|
|
114
141
|
html(token) {
|
|
115
|
-
return escapeHtml(token.text);
|
|
142
|
+
return rawHtml === 'strip' ? rawHtmlText(parseFragment(token.text)) : escapeHtml(token.text);
|
|
116
143
|
},
|
|
117
144
|
link(token) {
|
|
118
145
|
if (hasSafeProtocol(token.href, protocols.links) && tagAllowed(allowedTags, 'a')) {
|
|
@@ -233,19 +260,21 @@ function instanceFor(options) {
|
|
|
233
260
|
const protocols = resolveProtocolSets(options.sanitize);
|
|
234
261
|
const allowedTags = resolveTagAllowList(options.sanitize?.allowedTags);
|
|
235
262
|
const disableTaskLists = options.sanitize?.disableTaskLists === true;
|
|
263
|
+
const rawHtml = resolveRawHtmlMode(options.sanitize?.rawHtml);
|
|
236
264
|
const key = [
|
|
237
265
|
breaks ? 'breaks' : 'default',
|
|
238
266
|
[...protocols.links].sort().join(','),
|
|
239
267
|
[...protocols.images].sort().join(','),
|
|
240
268
|
allowedTags ? [...allowedTags].sort().join(',') : '*',
|
|
241
|
-
disableTaskLists ? 'no-tasks' : 'tasks'
|
|
269
|
+
disableTaskLists ? 'no-tasks' : 'tasks',
|
|
270
|
+
rawHtml
|
|
242
271
|
].join('|');
|
|
243
272
|
let instance = instances.get(key);
|
|
244
273
|
if (!instance) {
|
|
245
274
|
instance = new Marked({
|
|
246
275
|
gfm: true,
|
|
247
276
|
breaks,
|
|
248
|
-
renderer: createSanitizingRenderer(protocols, allowedTags, disableTaskLists)
|
|
277
|
+
renderer: createSanitizingRenderer(protocols, allowedTags, disableTaskLists, rawHtml)
|
|
249
278
|
});
|
|
250
279
|
instances.set(key, instance);
|
|
251
280
|
}
|
|
@@ -2,7 +2,7 @@ export type MarkdownTextProperties = OptionalMarkdownTextProperties & MandatoryM
|
|
|
2
2
|
export type MandatoryMarkdownTextProperties = {
|
|
3
3
|
/**
|
|
4
4
|
* Markdown source. Rendered through the library's sanitized-by-construction
|
|
5
|
-
* pipeline: raw HTML
|
|
5
|
+
* pipeline: raw HTML is escaped by default (or stripped via sanitize.rawHtml), and
|
|
6
6
|
* link/image URLs outside the safe-protocol allow-list are stripped while
|
|
7
7
|
* their text is kept.
|
|
8
8
|
*/
|
|
@@ -34,8 +34,9 @@ export type OptionalMarkdownTextProperties = {
|
|
|
34
34
|
* with the library's own allow-list for each surface, so it can only NARROW
|
|
35
35
|
* what already renders, never widen it (listing `javascript:` here can never
|
|
36
36
|
* resurrect it). Omitting `sanitize`, or `allowedProtocols`, keeps today's
|
|
37
|
-
* defaults untouched. This is independent of
|
|
38
|
-
*
|
|
37
|
+
* defaults untouched. This is independent of how raw HTML is disposed of,
|
|
38
|
+
* which `rawHtml` governs separately; raw HTML is never inserted as markup
|
|
39
|
+
* either way, so neither option can widen what renders.
|
|
39
40
|
*/
|
|
40
41
|
export type MarkdownSanitizeOptions = {
|
|
41
42
|
/**
|
|
@@ -58,9 +59,8 @@ export type MarkdownSanitizeOptions = {
|
|
|
58
59
|
* `'blockquote'`, `'ul'`, `'ol'`, `'table'`, `'hr'`, and `'h1'`–`'h6'`. An
|
|
59
60
|
* unrecognised name is simply ignored — it narrows nothing, it does not
|
|
60
61
|
* error. Omitting `allowedTags` keeps today's defaults untouched: every tag
|
|
61
|
-
* renders as it does now. This
|
|
62
|
-
*
|
|
63
|
-
* list.
|
|
62
|
+
* renders as it does now. This list governs markdown-GENERATED tags only and
|
|
63
|
+
* never affects raw HTML from the source, whose disposal is `rawHtml`'s job.
|
|
64
64
|
*/
|
|
65
65
|
allowedTags?: string[];
|
|
66
66
|
/**
|
|
@@ -71,15 +71,35 @@ export type MarkdownSanitizeOptions = {
|
|
|
71
71
|
* safety one. Defaults to `false`, keeping today's checkbox rendering.
|
|
72
72
|
*/
|
|
73
73
|
disableTaskLists?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* What to do with raw HTML typed literally into the markdown source, as
|
|
76
|
+
* opposed to the tags markdown itself generates (which `allowedTags`
|
|
77
|
+
* governs). Defaults to `'escape'` — today's behaviour, where
|
|
78
|
+
* `<script>alert(1)</script>` renders as visible escaped tag text.
|
|
79
|
+
*
|
|
80
|
+
* `'strip'` removes raw tags and comments while retaining their text:
|
|
81
|
+
* `<div>hello</div>` becomes `hello`. An inert HTML parser handles quoted
|
|
82
|
+
* delimiters and entities; every retained text node is escaped before output.
|
|
83
|
+
* Script/style contents remain visible text, never executable elements.
|
|
84
|
+
* Fenced code and ordinary angle-bracket prose are not raw HTML tokens and
|
|
85
|
+
* keep their existing rendering. Neither mode inserts source HTML into the DOM.
|
|
86
|
+
*/
|
|
87
|
+
rawHtml?: MarkdownRawHtmlMode;
|
|
74
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* `'escape'` renders raw HTML as visible escaped text (the default, and what
|
|
91
|
+
* the component has always done); `'strip'` removes it. See
|
|
92
|
+
* `MarkdownSanitizeOptions.rawHtml`.
|
|
93
|
+
*/
|
|
94
|
+
export type MarkdownRawHtmlMode = 'escape' | 'strip';
|
|
75
95
|
export type RenderMarkdownOptions = {
|
|
76
96
|
/** Render single newlines as `<br>` (GFM "breaks" mode). */
|
|
77
97
|
breaks?: boolean;
|
|
78
98
|
/**
|
|
79
99
|
* Parse as inline markdown: no block elements (`<p>`, lists, tables) are
|
|
80
100
|
* produced, so the output can sit inside an existing `<p>` or `<span>`.
|
|
81
|
-
* The same sanitization applies — inline raw HTML is escaped
|
|
82
|
-
* link/image protocols are stripped.
|
|
101
|
+
* The same sanitization applies — inline raw HTML is escaped (or dropped,
|
|
102
|
+
* per `sanitize.rawHtml`) and unsafe link/image protocols are stripped.
|
|
83
103
|
*/
|
|
84
104
|
inline?: boolean;
|
|
85
105
|
/** Accessible name for the scroll region wrapping each table. See `MarkdownTextProperties.tableLabel`. */
|