@bendyline/squisq 2.3.2 → 2.3.3
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/{chunk-ZQKZSJAX.js → chunk-2VCNTDNZ.js} +245 -0
- package/dist/{chunk-BCHAXKKI.js → chunk-ABP4LAJS.js} +1 -1
- package/dist/{chunk-ACZOVWX3.js → chunk-G3JOS25T.js} +1 -1
- package/dist/{chunk-CKZY6K5R.js → chunk-GQNH7PLN.js} +3786 -3676
- package/dist/{chunk-ZAFLMJPD.js → chunk-IZLKI3IL.js} +10 -4
- package/dist/{chunk-3IGPAPQ7.js → chunk-UA5DTYAY.js} +1 -246
- package/dist/doc/index.d.ts +11 -3
- package/dist/doc/index.js +6 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +10 -8
- package/dist/markdown/index.js +5 -5
- package/dist/{materializePageSection-DAbyLi-k.d.ts → materializePageSection-CrZWYnXM.d.ts} +2 -0
- package/dist/narration/index.js +3 -3
- package/dist/transform/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -5,6 +5,249 @@ import {
|
|
|
5
5
|
normalizeTransitionType
|
|
6
6
|
} from "./chunk-4VOD55SX.js";
|
|
7
7
|
|
|
8
|
+
// src/markdown/sanitize.ts
|
|
9
|
+
var SAFE_LINK_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "mailto", "tel"]);
|
|
10
|
+
var SAFE_MEDIA_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "blob"]);
|
|
11
|
+
var NEVER_ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["javascript", "vbscript", "data"]);
|
|
12
|
+
var SAFE_DATA_MEDIA_RE = /^data:(?:image\/(?!svg\+xml)[a-z0-9.+-]+|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+);/i;
|
|
13
|
+
var SAFE_TAGS = /* @__PURE__ */ new Set([
|
|
14
|
+
"a",
|
|
15
|
+
"abbr",
|
|
16
|
+
"b",
|
|
17
|
+
"blockquote",
|
|
18
|
+
"br",
|
|
19
|
+
"caption",
|
|
20
|
+
"cite",
|
|
21
|
+
"code",
|
|
22
|
+
"col",
|
|
23
|
+
"colgroup",
|
|
24
|
+
"data",
|
|
25
|
+
"dd",
|
|
26
|
+
"del",
|
|
27
|
+
"details",
|
|
28
|
+
"dfn",
|
|
29
|
+
"div",
|
|
30
|
+
"dl",
|
|
31
|
+
"dt",
|
|
32
|
+
"em",
|
|
33
|
+
"figcaption",
|
|
34
|
+
"figure",
|
|
35
|
+
"h1",
|
|
36
|
+
"h2",
|
|
37
|
+
"h3",
|
|
38
|
+
"h4",
|
|
39
|
+
"h5",
|
|
40
|
+
"h6",
|
|
41
|
+
"hr",
|
|
42
|
+
"i",
|
|
43
|
+
"img",
|
|
44
|
+
"kbd",
|
|
45
|
+
"li",
|
|
46
|
+
"mark",
|
|
47
|
+
"ol",
|
|
48
|
+
"p",
|
|
49
|
+
"pre",
|
|
50
|
+
"q",
|
|
51
|
+
"s",
|
|
52
|
+
"samp",
|
|
53
|
+
"small",
|
|
54
|
+
"source",
|
|
55
|
+
"span",
|
|
56
|
+
"strong",
|
|
57
|
+
"sub",
|
|
58
|
+
"summary",
|
|
59
|
+
"sup",
|
|
60
|
+
"table",
|
|
61
|
+
"tbody",
|
|
62
|
+
"td",
|
|
63
|
+
"tfoot",
|
|
64
|
+
"th",
|
|
65
|
+
"thead",
|
|
66
|
+
"time",
|
|
67
|
+
"tr",
|
|
68
|
+
"track",
|
|
69
|
+
"u",
|
|
70
|
+
"ul",
|
|
71
|
+
"var",
|
|
72
|
+
"video",
|
|
73
|
+
"audio"
|
|
74
|
+
]);
|
|
75
|
+
var DROP_WITH_CONTENT_TAGS = /* @__PURE__ */ new Set([
|
|
76
|
+
"base",
|
|
77
|
+
"button",
|
|
78
|
+
"embed",
|
|
79
|
+
"form",
|
|
80
|
+
"iframe",
|
|
81
|
+
"input",
|
|
82
|
+
"link",
|
|
83
|
+
"meta",
|
|
84
|
+
"object",
|
|
85
|
+
"option",
|
|
86
|
+
"script",
|
|
87
|
+
"select",
|
|
88
|
+
"style",
|
|
89
|
+
"svg",
|
|
90
|
+
"template",
|
|
91
|
+
"textarea"
|
|
92
|
+
]);
|
|
93
|
+
var GLOBAL_ATTRS = /* @__PURE__ */ new Set(["class", "id", "title", "role"]);
|
|
94
|
+
var TAG_ATTRS = {
|
|
95
|
+
a: /* @__PURE__ */ new Set(["href", "target", "rel"]),
|
|
96
|
+
audio: /* @__PURE__ */ new Set(["src", "controls", "preload", "muted", "loop"]),
|
|
97
|
+
col: /* @__PURE__ */ new Set(["span", "width"]),
|
|
98
|
+
colgroup: /* @__PURE__ */ new Set(["span"]),
|
|
99
|
+
data: /* @__PURE__ */ new Set(["value"]),
|
|
100
|
+
img: /* @__PURE__ */ new Set(["src", "alt", "width", "height", "loading", "decoding"]),
|
|
101
|
+
li: /* @__PURE__ */ new Set(["value"]),
|
|
102
|
+
ol: /* @__PURE__ */ new Set(["start", "type"]),
|
|
103
|
+
q: /* @__PURE__ */ new Set(["cite"]),
|
|
104
|
+
source: /* @__PURE__ */ new Set(["src", "type", "media"]),
|
|
105
|
+
td: /* @__PURE__ */ new Set(["colspan", "rowspan", "align"]),
|
|
106
|
+
th: /* @__PURE__ */ new Set(["colspan", "rowspan", "align", "scope"]),
|
|
107
|
+
time: /* @__PURE__ */ new Set(["datetime"]),
|
|
108
|
+
track: /* @__PURE__ */ new Set(["src", "kind", "label", "srclang", "default"]),
|
|
109
|
+
video: /* @__PURE__ */ new Set([
|
|
110
|
+
"src",
|
|
111
|
+
"poster",
|
|
112
|
+
"width",
|
|
113
|
+
"height",
|
|
114
|
+
"controls",
|
|
115
|
+
"preload",
|
|
116
|
+
"muted",
|
|
117
|
+
"loop",
|
|
118
|
+
"playsinline"
|
|
119
|
+
])
|
|
120
|
+
};
|
|
121
|
+
var SAFE_ATTR_NAME_RE = /^[a-z][a-z0-9:_.-]*$/;
|
|
122
|
+
var SAFE_OL_TYPES = /* @__PURE__ */ new Set(["1", "a", "A", "i", "I"]);
|
|
123
|
+
var SAFE_PRELOAD_VALUES = /* @__PURE__ */ new Set(["none", "metadata", "auto"]);
|
|
124
|
+
var SAFE_TRACK_KINDS = /* @__PURE__ */ new Set(["subtitles", "captions", "descriptions", "chapters", "metadata"]);
|
|
125
|
+
function sanitizeUrl(url, kind = "link", options) {
|
|
126
|
+
if (typeof url !== "string") return null;
|
|
127
|
+
const trimmed = url.trim();
|
|
128
|
+
if (!trimmed) return null;
|
|
129
|
+
const compact = stripUrlSchemeNoise(trimmed);
|
|
130
|
+
const colon = compact.indexOf(":");
|
|
131
|
+
const firstPathChar = firstIndexOfAny(compact, ["/", "?", "#"]);
|
|
132
|
+
const hasScheme = colon >= 0 && (firstPathChar < 0 || colon < firstPathChar);
|
|
133
|
+
if (!hasScheme) return trimmed;
|
|
134
|
+
const scheme = compact.slice(0, colon).toLowerCase();
|
|
135
|
+
if (kind === "media") {
|
|
136
|
+
if (scheme === "data") return SAFE_DATA_MEDIA_RE.test(compact) ? trimmed : null;
|
|
137
|
+
return SAFE_MEDIA_SCHEMES.has(scheme) ? trimmed : null;
|
|
138
|
+
}
|
|
139
|
+
if (SAFE_LINK_SCHEMES.has(scheme)) return trimmed;
|
|
140
|
+
if (options?.extraLinkSchemes?.includes(scheme) && !NEVER_ALLOWED_SCHEMES.has(scheme)) {
|
|
141
|
+
return trimmed;
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
function sanitizeHtmlNodes(nodes) {
|
|
146
|
+
const out = [];
|
|
147
|
+
for (const node of nodes) {
|
|
148
|
+
out.push(...sanitizeHtmlNode(node));
|
|
149
|
+
}
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
function sanitizeHtmlNode(node) {
|
|
153
|
+
switch (node.type) {
|
|
154
|
+
case "htmlText":
|
|
155
|
+
return [node];
|
|
156
|
+
case "htmlComment":
|
|
157
|
+
return [];
|
|
158
|
+
case "htmlElement":
|
|
159
|
+
return sanitizeHtmlElement(node);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function sanitizeHtmlElement(node) {
|
|
163
|
+
const tag = node.tagName.toLowerCase();
|
|
164
|
+
if (DROP_WITH_CONTENT_TAGS.has(tag)) return [];
|
|
165
|
+
const children = sanitizeHtmlNodes(node.children);
|
|
166
|
+
if (!SAFE_TAGS.has(tag)) return children;
|
|
167
|
+
return [
|
|
168
|
+
{
|
|
169
|
+
type: "htmlElement",
|
|
170
|
+
tagName: tag,
|
|
171
|
+
attributes: sanitizeAttrs(tag, node.attributes),
|
|
172
|
+
children,
|
|
173
|
+
selfClosing: node.selfClosing
|
|
174
|
+
}
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
function sanitizeAttrs(tag, attrs) {
|
|
178
|
+
const out = {};
|
|
179
|
+
for (const [rawName, rawValue] of Object.entries(attrs)) {
|
|
180
|
+
const name = rawName.toLowerCase();
|
|
181
|
+
if (!isAllowedAttr(tag, name)) continue;
|
|
182
|
+
const value = String(rawValue);
|
|
183
|
+
const safeValue = sanitizeAttrValue(tag, name, value);
|
|
184
|
+
if (safeValue === null) continue;
|
|
185
|
+
out[name] = safeValue;
|
|
186
|
+
}
|
|
187
|
+
if (tag === "a" && out.target === "_blank") {
|
|
188
|
+
out.rel = ensureRelTokens(out.rel, ["noopener", "noreferrer"]);
|
|
189
|
+
}
|
|
190
|
+
return out;
|
|
191
|
+
}
|
|
192
|
+
function isAllowedAttr(tag, name) {
|
|
193
|
+
if (!SAFE_ATTR_NAME_RE.test(name)) return false;
|
|
194
|
+
if (name.startsWith("on")) return false;
|
|
195
|
+
if (name.startsWith("aria-") || name.startsWith("data-")) return true;
|
|
196
|
+
if (GLOBAL_ATTRS.has(name)) return true;
|
|
197
|
+
return TAG_ATTRS[tag]?.has(name) ?? false;
|
|
198
|
+
}
|
|
199
|
+
function sanitizeAttrValue(tag, name, value) {
|
|
200
|
+
if (name === "href") return sanitizeUrl(value, "link");
|
|
201
|
+
if (name === "src" || name === "poster") return sanitizeUrl(value, "media");
|
|
202
|
+
if ((name === "width" || name === "height" || name === "span" || name === "colspan" || name === "rowspan" || name === "value") && !isNonNegativeInteger(value)) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
if (name === "start" && !isInteger(value)) return null;
|
|
206
|
+
if (name === "type" && tag === "ol" && !SAFE_OL_TYPES.has(value)) return null;
|
|
207
|
+
if (name === "preload" && !SAFE_PRELOAD_VALUES.has(value)) return null;
|
|
208
|
+
if (name === "kind" && tag === "track" && !SAFE_TRACK_KINDS.has(value)) return null;
|
|
209
|
+
if (name === "align" && value !== "left" && value !== "right" && value !== "center") return null;
|
|
210
|
+
if (name === "target")
|
|
211
|
+
return value === "_blank" || value === "_self" || value === "_parent" || value === "_top" ? value : null;
|
|
212
|
+
if (name === "rel") return sanitizeRel(value);
|
|
213
|
+
return value;
|
|
214
|
+
}
|
|
215
|
+
function sanitizeRel(value) {
|
|
216
|
+
return relTokens(value).join(" ");
|
|
217
|
+
}
|
|
218
|
+
function ensureRelTokens(value, required) {
|
|
219
|
+
const tokens = new Set(value ? relTokens(value) : []);
|
|
220
|
+
for (const token of required) tokens.add(token);
|
|
221
|
+
return Array.from(tokens).join(" ");
|
|
222
|
+
}
|
|
223
|
+
function relTokens(value) {
|
|
224
|
+
const tokens = value.split(/\s+/).map((token) => token.trim().toLowerCase()).filter(Boolean).filter((token) => /^[a-z0-9_-]+$/.test(token));
|
|
225
|
+
return Array.from(new Set(tokens));
|
|
226
|
+
}
|
|
227
|
+
function isInteger(value) {
|
|
228
|
+
return /^-?\d+$/.test(value.trim());
|
|
229
|
+
}
|
|
230
|
+
function isNonNegativeInteger(value) {
|
|
231
|
+
return /^\d+$/.test(value.trim());
|
|
232
|
+
}
|
|
233
|
+
function firstIndexOfAny(value, needles) {
|
|
234
|
+
let result = -1;
|
|
235
|
+
for (const needle of needles) {
|
|
236
|
+
const index = value.indexOf(needle);
|
|
237
|
+
if (index >= 0 && (result < 0 || index < result)) result = index;
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
function stripUrlSchemeNoise(value) {
|
|
242
|
+
let out = "";
|
|
243
|
+
for (const char of value) {
|
|
244
|
+
const code = char.charCodeAt(0);
|
|
245
|
+
if (code <= 32 || code === 127 || char.trim() === "") continue;
|
|
246
|
+
out += char;
|
|
247
|
+
}
|
|
248
|
+
return out;
|
|
249
|
+
}
|
|
250
|
+
|
|
8
251
|
// src/markdown/annotationCoercion.ts
|
|
9
252
|
var KNOWN_BLOCK_META_KEYS = {
|
|
10
253
|
x: "number",
|
|
@@ -275,6 +518,8 @@ function serializeAnnotation(template, params) {
|
|
|
275
518
|
}
|
|
276
519
|
|
|
277
520
|
export {
|
|
521
|
+
sanitizeUrl,
|
|
522
|
+
sanitizeHtmlNodes,
|
|
278
523
|
KNOWN_BLOCK_META_KEYS,
|
|
279
524
|
BLOCK_META_KEY_DESCRIPTORS,
|
|
280
525
|
coerceAnnotationValues,
|