@bendyline/squisq 2.12.1 → 2.12.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/{Doc-CHD4fxfm.d.ts → Doc-BkSiCJnM.d.ts} +28 -2
- package/dist/{ImageEditDoc-DSUM5MiA.d.ts → ImageEditDoc-UjQv8q3j.d.ts} +1 -1
- package/dist/{chunk-WAX4QYHA.js → chunk-E2NFHYCB.js} +14 -3
- package/dist/{chunk-H54A35NZ.js → chunk-EX75I5HX.js} +3 -3
- package/dist/{chunk-3H7SYCZS.js → chunk-FTN6SGW5.js} +1 -1
- package/dist/{chunk-QHNO67JS.js → chunk-GX3VSKYS.js} +1 -1
- package/dist/{chunk-I4L4GYDN.js → chunk-HYJ63N6V.js} +1 -1
- package/dist/{chunk-ISH4HDH7.js → chunk-J6AGNXFO.js} +1 -1
- package/dist/{chunk-B3AFOXMA.js → chunk-MPEGJKFJ.js} +1031 -3
- package/dist/chunk-MWSGNEH6.js +2376 -0
- package/dist/{chunk-M6YXFNGO.js → chunk-P53Z4RYC.js} +10 -0
- package/dist/{chunk-B2BQFF5B.js → chunk-SK5TQSYN.js} +20 -20
- package/dist/{chunk-RKCARBWM.js → chunk-VTVBSZXB.js} +78 -1048
- package/dist/chunk-Y25EJEZN.js +178 -0
- package/dist/{chunk-LN72K54P.js → chunk-ZBPWNH4L.js} +10 -9
- package/dist/{chunk-VTG7PNOL.js → chunk-ZKDJHO6Y.js} +3 -8
- package/dist/doc/index.d.ts +17 -9
- package/dist/doc/index.js +41 -39
- package/dist/fence/index.d.ts +1 -1
- package/dist/generate/index.d.ts +1 -1
- package/dist/imageEdit/index.d.ts +3 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.js +68 -48
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/jsonForm/index.js +4 -4
- package/dist/markdown/index.d.ts +143 -1
- package/dist/markdown/index.js +29 -10
- package/dist/{materializePageSection-Dx1Sz0vK.d.ts → materializePageSection-DEXohgVt.d.ts} +1 -1
- package/dist/mediaEdit/index.d.ts +2 -2
- package/dist/narration/index.d.ts +1 -1
- package/dist/narration/index.js +8 -8
- package/dist/recommend/index.js +3 -2
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/index.js +3 -3
- package/dist/{themeLibrary-DLmZ1Ct8.d.ts → themeLibrary-BrBc0mrP.d.ts} +1 -1
- package/dist/timing/index.d.ts +1 -1
- package/dist/transform/index.d.ts +2 -2
- package/dist/transform/index.js +8 -8
- package/package.json +1 -1
- package/dist/chunk-NNJA7ICB.js +0 -1088
- package/dist/chunk-ZYWYSM6W.js +0 -657
package/dist/chunk-ZYWYSM6W.js
DELETED
|
@@ -1,657 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
videoEmbedFromIframe,
|
|
3
|
-
videoEmbedIframeAttributes
|
|
4
|
-
} from "./chunk-NNJA7ICB.js";
|
|
5
|
-
import {
|
|
6
|
-
BUILD_EFFECTS,
|
|
7
|
-
BUILD_MODES,
|
|
8
|
-
BUILD_PREVIOUS,
|
|
9
|
-
TRANSITION_DIRECTIONS,
|
|
10
|
-
TRANSITION_TYPES,
|
|
11
|
-
normalizeTransitionDirection,
|
|
12
|
-
normalizeTransitionType
|
|
13
|
-
} from "./chunk-M6YXFNGO.js";
|
|
14
|
-
|
|
15
|
-
// src/markdown/annotationCoercion.ts
|
|
16
|
-
var KNOWN_BLOCK_META_KEYS = {
|
|
17
|
-
build: "build",
|
|
18
|
-
buildEffect: "buildEffect",
|
|
19
|
-
buildDuration: "time",
|
|
20
|
-
buildPrevious: "buildPrevious",
|
|
21
|
-
x: "number",
|
|
22
|
-
y: "number",
|
|
23
|
-
startTime: "time",
|
|
24
|
-
duration: "time",
|
|
25
|
-
connectsTo: "connectionList",
|
|
26
|
-
transition: "transition",
|
|
27
|
-
transitionDuration: "time",
|
|
28
|
-
transitionDirection: "transitionDirection"
|
|
29
|
-
};
|
|
30
|
-
var BLOCK_META_KEY_DESCRIPTORS = [
|
|
31
|
-
{ key: "build", description: "Progressive reveal grouping", values: BUILD_MODES },
|
|
32
|
-
{ key: "buildEffect", description: "Build entrance effect", values: BUILD_EFFECTS },
|
|
33
|
-
{
|
|
34
|
-
key: "buildDuration",
|
|
35
|
-
description: "Build entrance duration",
|
|
36
|
-
valueHint: "seconds \u2014 e.g. 0.4, 400ms"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
key: "buildPrevious",
|
|
40
|
-
description: "Appearance of previous build steps",
|
|
41
|
-
values: BUILD_PREVIOUS
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
key: "transition",
|
|
45
|
-
description: "Block-to-block transition effect",
|
|
46
|
-
values: TRANSITION_TYPES
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
key: "transitionDuration",
|
|
50
|
-
description: "How long the transition lasts",
|
|
51
|
-
valueHint: "seconds \u2014 e.g. 0.7, 700ms"
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
key: "transitionDirection",
|
|
55
|
-
description: "Directional variant for the transition",
|
|
56
|
-
values: TRANSITION_DIRECTIONS
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
key: "startTime",
|
|
60
|
-
description: "Timeline start time of this block",
|
|
61
|
-
valueHint: "mm:ss or seconds \u2014 e.g. 01:30, 5, 1500ms"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
key: "duration",
|
|
65
|
-
description: "How long this block lasts",
|
|
66
|
-
valueHint: "mm:ss or seconds \u2014 e.g. 45, 1500ms"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
key: "x",
|
|
70
|
-
description: "Horizontal position on the diagram canvas",
|
|
71
|
-
valueHint: "number \u2014 e.g. 600"
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
key: "y",
|
|
75
|
-
description: "Vertical position on the diagram canvas",
|
|
76
|
-
valueHint: "number \u2014 e.g. 300"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
key: "connectsTo",
|
|
80
|
-
description: "Diagram connections to other blocks",
|
|
81
|
-
valueHint: "comma-separated target or target:type \u2014 e.g. foo,bar:flow"
|
|
82
|
-
}
|
|
83
|
-
];
|
|
84
|
-
function coerceAnnotationValues(params) {
|
|
85
|
-
const blockMeta = {};
|
|
86
|
-
const metadata = {};
|
|
87
|
-
const warnings = [];
|
|
88
|
-
const build = {};
|
|
89
|
-
let transitionType = null;
|
|
90
|
-
let transitionDuration;
|
|
91
|
-
let transitionDirection;
|
|
92
|
-
for (const [key, raw] of Object.entries(params)) {
|
|
93
|
-
const kind = KNOWN_BLOCK_META_KEYS[key];
|
|
94
|
-
if (!kind) {
|
|
95
|
-
metadata[key] = raw;
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
if (kind === "number") {
|
|
99
|
-
const n = parseNumber(raw);
|
|
100
|
-
if (n == null) {
|
|
101
|
-
warnings.push(`Invalid number for "${key}": ${JSON.stringify(raw)}`);
|
|
102
|
-
} else {
|
|
103
|
-
blockMeta[key] = n;
|
|
104
|
-
}
|
|
105
|
-
} else if (kind === "time") {
|
|
106
|
-
const s = parseTimeSeconds(raw);
|
|
107
|
-
if (s == null) {
|
|
108
|
-
warnings.push(`Invalid time for "${key}": ${JSON.stringify(raw)}`);
|
|
109
|
-
} else if (key === "buildDuration") {
|
|
110
|
-
if (s < 0) warnings.push("Build duration must be non-negative.");
|
|
111
|
-
else build.duration = s;
|
|
112
|
-
} else if (key === "transitionDuration") {
|
|
113
|
-
transitionDuration = s;
|
|
114
|
-
} else {
|
|
115
|
-
blockMeta[key] = s;
|
|
116
|
-
}
|
|
117
|
-
} else if (kind === "build" || kind === "buildEffect" || kind === "buildPrevious") {
|
|
118
|
-
const values = kind === "build" ? BUILD_MODES : kind === "buildEffect" ? BUILD_EFFECTS : BUILD_PREVIOUS;
|
|
119
|
-
if (!values.includes(raw))
|
|
120
|
-
warnings.push(`Invalid value for "${key}": ${JSON.stringify(raw)}`);
|
|
121
|
-
else if (kind === "build") build.mode = raw;
|
|
122
|
-
else if (kind === "buildEffect") build.effect = raw;
|
|
123
|
-
else build.previous = raw;
|
|
124
|
-
} else if (kind === "connectionList") {
|
|
125
|
-
const { list, warning } = parseConnectionList(raw);
|
|
126
|
-
if (warning) warnings.push(`"${key}": ${warning}`);
|
|
127
|
-
blockMeta.connectsTo = list;
|
|
128
|
-
} else if (kind === "transition") {
|
|
129
|
-
const transition = normalizeTransitionType(raw);
|
|
130
|
-
if (transition == null) {
|
|
131
|
-
warnings.push(`Invalid transition for "${key}": ${JSON.stringify(raw)}`);
|
|
132
|
-
} else {
|
|
133
|
-
transitionType = transition;
|
|
134
|
-
}
|
|
135
|
-
} else if (kind === "transitionDirection") {
|
|
136
|
-
const direction = normalizeTransitionDirection(raw);
|
|
137
|
-
if (direction == null) {
|
|
138
|
-
warnings.push(`Invalid transition direction for "${key}": ${JSON.stringify(raw)}`);
|
|
139
|
-
} else {
|
|
140
|
-
transitionDirection = direction;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (build.mode) blockMeta.build = { ...build, mode: build.mode };
|
|
145
|
-
if (transitionType) {
|
|
146
|
-
blockMeta.transition = {
|
|
147
|
-
type: transitionType,
|
|
148
|
-
...transitionDuration !== void 0 ? { duration: transitionDuration } : {},
|
|
149
|
-
...transitionDirection !== void 0 ? { direction: transitionDirection } : {}
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
return { blockMeta, metadata, warnings };
|
|
153
|
-
}
|
|
154
|
-
function parseNumber(raw) {
|
|
155
|
-
if (raw.trim() === "") return null;
|
|
156
|
-
const n = Number(raw);
|
|
157
|
-
return Number.isFinite(n) ? n : null;
|
|
158
|
-
}
|
|
159
|
-
var TIME_BARE_RE = /^\d+(?:\.\d+)?$/;
|
|
160
|
-
var TIME_MS_RE = /^(\d+(?:\.\d+)?)ms$/;
|
|
161
|
-
var TIME_MMSS_RE = /^(\d+):(\d{1,2})(?:\.(\d+))?$/;
|
|
162
|
-
function parseTimeSeconds(raw) {
|
|
163
|
-
const trimmed = raw.trim();
|
|
164
|
-
if (!trimmed) return null;
|
|
165
|
-
if (TIME_BARE_RE.test(trimmed)) {
|
|
166
|
-
const n = Number(trimmed);
|
|
167
|
-
return Number.isFinite(n) ? n : null;
|
|
168
|
-
}
|
|
169
|
-
const msMatch = trimmed.match(TIME_MS_RE);
|
|
170
|
-
if (msMatch) {
|
|
171
|
-
const n = Number(msMatch[1]);
|
|
172
|
-
return Number.isFinite(n) ? n / 1e3 : null;
|
|
173
|
-
}
|
|
174
|
-
const mmssMatch = trimmed.match(TIME_MMSS_RE);
|
|
175
|
-
if (mmssMatch) {
|
|
176
|
-
const mins = Number(mmssMatch[1]);
|
|
177
|
-
const secs = Number(mmssMatch[2]);
|
|
178
|
-
const frac = mmssMatch[3] ? Number(`0.${mmssMatch[3]}`) : 0;
|
|
179
|
-
if (!Number.isFinite(mins) || !Number.isFinite(secs) || !Number.isFinite(frac)) {
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
if (secs >= 60) return null;
|
|
183
|
-
return mins * 60 + secs + frac;
|
|
184
|
-
}
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
function parseConnectionList(raw) {
|
|
188
|
-
const trimmed = raw.trim();
|
|
189
|
-
if (!trimmed) return { list: [], warning: null };
|
|
190
|
-
const list = [];
|
|
191
|
-
let droppedEmpty = false;
|
|
192
|
-
for (const part of trimmed.split(",")) {
|
|
193
|
-
const entry = part.trim();
|
|
194
|
-
if (!entry) {
|
|
195
|
-
droppedEmpty = true;
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
const colonIdx = entry.indexOf(":");
|
|
199
|
-
if (colonIdx < 0) {
|
|
200
|
-
list.push({ target: entry });
|
|
201
|
-
} else {
|
|
202
|
-
const target = entry.slice(0, colonIdx).trim();
|
|
203
|
-
const type = entry.slice(colonIdx + 1).trim();
|
|
204
|
-
if (!target) {
|
|
205
|
-
droppedEmpty = true;
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
list.push(type ? { target, type } : { target });
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return {
|
|
212
|
-
list,
|
|
213
|
-
warning: droppedEmpty ? "dropped empty connection entries" : null
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// src/doc/templates/templateNames.ts
|
|
218
|
-
var TEMPLATE_ALIASES = Object.freeze({
|
|
219
|
-
titleBlock: "title",
|
|
220
|
-
quoteBlock: "quote",
|
|
221
|
-
mapBlock: "map",
|
|
222
|
-
listBlock: "list",
|
|
223
|
-
diagramBlock: "diagram",
|
|
224
|
-
diagramNode: "diagram"
|
|
225
|
-
});
|
|
226
|
-
function resolveTemplateName(name) {
|
|
227
|
-
return TEMPLATE_ALIASES[name] ?? name;
|
|
228
|
-
}
|
|
229
|
-
var TABLE_FED_TEMPLATES = /* @__PURE__ */ new Set([
|
|
230
|
-
"dataTable",
|
|
231
|
-
"barChart",
|
|
232
|
-
"columnChart",
|
|
233
|
-
"pieChart",
|
|
234
|
-
"donutChart",
|
|
235
|
-
"lineChart",
|
|
236
|
-
"areaChart",
|
|
237
|
-
"scatterChart"
|
|
238
|
-
]);
|
|
239
|
-
var CONTAINER_TEMPLATES = /* @__PURE__ */ new Set(["diagram", "drawing", "layout"]);
|
|
240
|
-
function isContainerTemplate(name) {
|
|
241
|
-
return !!name && CONTAINER_TEMPLATES.has(resolveTemplateName(name));
|
|
242
|
-
}
|
|
243
|
-
var TEMPLATE_TOKEN_NAMES = /* @__PURE__ */ new Set([
|
|
244
|
-
"title",
|
|
245
|
-
"sectionHeader",
|
|
246
|
-
"bigText",
|
|
247
|
-
"transcript",
|
|
248
|
-
"content",
|
|
249
|
-
"statHighlight",
|
|
250
|
-
"quote",
|
|
251
|
-
"factCard",
|
|
252
|
-
"twoColumn",
|
|
253
|
-
"dateEvent",
|
|
254
|
-
"imageWithCaption",
|
|
255
|
-
"leftFeature",
|
|
256
|
-
"rightFeature",
|
|
257
|
-
"map",
|
|
258
|
-
"fullBleedQuote",
|
|
259
|
-
"list",
|
|
260
|
-
"photoGrid",
|
|
261
|
-
"definitionCard",
|
|
262
|
-
"comparisonBar",
|
|
263
|
-
"pullQuote",
|
|
264
|
-
"videoWithCaption",
|
|
265
|
-
"videoPullQuote",
|
|
266
|
-
"dataTable",
|
|
267
|
-
"barChart",
|
|
268
|
-
"columnChart",
|
|
269
|
-
"pieChart",
|
|
270
|
-
"donutChart",
|
|
271
|
-
"lineChart",
|
|
272
|
-
"areaChart",
|
|
273
|
-
"scatterChart",
|
|
274
|
-
"diagram",
|
|
275
|
-
"tree",
|
|
276
|
-
"timeline",
|
|
277
|
-
"layout",
|
|
278
|
-
"drawing"
|
|
279
|
-
]);
|
|
280
|
-
function isReservedAnnotationToken(token) {
|
|
281
|
-
return TEMPLATE_TOKEN_NAMES.has(resolveTemplateName(token));
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// src/markdown/sanitize.ts
|
|
285
|
-
var SAFE_LINK_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "mailto", "tel"]);
|
|
286
|
-
var SAFE_MEDIA_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "blob"]);
|
|
287
|
-
var NEVER_ALLOWED_SCHEMES = /* @__PURE__ */ new Set(["javascript", "vbscript", "data"]);
|
|
288
|
-
var SAFE_DATA_MEDIA_RE = /^data:(?:image\/(?!svg\+xml)[a-z0-9.+-]+|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+);/i;
|
|
289
|
-
var SAFE_TAGS = /* @__PURE__ */ new Set([
|
|
290
|
-
"a",
|
|
291
|
-
"abbr",
|
|
292
|
-
"b",
|
|
293
|
-
"blockquote",
|
|
294
|
-
"br",
|
|
295
|
-
"caption",
|
|
296
|
-
"cite",
|
|
297
|
-
"code",
|
|
298
|
-
"col",
|
|
299
|
-
"colgroup",
|
|
300
|
-
"data",
|
|
301
|
-
"dd",
|
|
302
|
-
"del",
|
|
303
|
-
"details",
|
|
304
|
-
"dfn",
|
|
305
|
-
"div",
|
|
306
|
-
"dl",
|
|
307
|
-
"dt",
|
|
308
|
-
"em",
|
|
309
|
-
"figcaption",
|
|
310
|
-
"figure",
|
|
311
|
-
"h1",
|
|
312
|
-
"h2",
|
|
313
|
-
"h3",
|
|
314
|
-
"h4",
|
|
315
|
-
"h5",
|
|
316
|
-
"h6",
|
|
317
|
-
"hr",
|
|
318
|
-
"i",
|
|
319
|
-
"img",
|
|
320
|
-
"kbd",
|
|
321
|
-
"li",
|
|
322
|
-
"mark",
|
|
323
|
-
"ol",
|
|
324
|
-
"p",
|
|
325
|
-
"pre",
|
|
326
|
-
"q",
|
|
327
|
-
"s",
|
|
328
|
-
"samp",
|
|
329
|
-
"small",
|
|
330
|
-
"source",
|
|
331
|
-
"span",
|
|
332
|
-
"strong",
|
|
333
|
-
"sub",
|
|
334
|
-
"summary",
|
|
335
|
-
"sup",
|
|
336
|
-
"table",
|
|
337
|
-
"tbody",
|
|
338
|
-
"td",
|
|
339
|
-
"tfoot",
|
|
340
|
-
"th",
|
|
341
|
-
"thead",
|
|
342
|
-
"time",
|
|
343
|
-
"tr",
|
|
344
|
-
"track",
|
|
345
|
-
"u",
|
|
346
|
-
"ul",
|
|
347
|
-
"var",
|
|
348
|
-
"video",
|
|
349
|
-
"audio"
|
|
350
|
-
]);
|
|
351
|
-
var DROP_WITH_CONTENT_TAGS = /* @__PURE__ */ new Set([
|
|
352
|
-
"base",
|
|
353
|
-
"button",
|
|
354
|
-
"embed",
|
|
355
|
-
"form",
|
|
356
|
-
"iframe",
|
|
357
|
-
"input",
|
|
358
|
-
"link",
|
|
359
|
-
"meta",
|
|
360
|
-
"object",
|
|
361
|
-
"option",
|
|
362
|
-
"script",
|
|
363
|
-
"select",
|
|
364
|
-
"style",
|
|
365
|
-
"svg",
|
|
366
|
-
"template",
|
|
367
|
-
"textarea"
|
|
368
|
-
]);
|
|
369
|
-
var GLOBAL_ATTRS = /* @__PURE__ */ new Set(["class", "id", "title", "role"]);
|
|
370
|
-
var TAG_ATTRS = {
|
|
371
|
-
a: /* @__PURE__ */ new Set(["href", "target", "rel"]),
|
|
372
|
-
audio: /* @__PURE__ */ new Set(["src", "controls", "preload", "muted", "loop"]),
|
|
373
|
-
col: /* @__PURE__ */ new Set(["span", "width"]),
|
|
374
|
-
colgroup: /* @__PURE__ */ new Set(["span"]),
|
|
375
|
-
data: /* @__PURE__ */ new Set(["value"]),
|
|
376
|
-
img: /* @__PURE__ */ new Set(["src", "alt", "width", "height", "loading", "decoding"]),
|
|
377
|
-
li: /* @__PURE__ */ new Set(["value"]),
|
|
378
|
-
ol: /* @__PURE__ */ new Set(["start", "type"]),
|
|
379
|
-
q: /* @__PURE__ */ new Set(["cite"]),
|
|
380
|
-
source: /* @__PURE__ */ new Set(["src", "type", "media"]),
|
|
381
|
-
td: /* @__PURE__ */ new Set(["colspan", "rowspan", "align"]),
|
|
382
|
-
th: /* @__PURE__ */ new Set(["colspan", "rowspan", "align", "scope"]),
|
|
383
|
-
time: /* @__PURE__ */ new Set(["datetime"]),
|
|
384
|
-
track: /* @__PURE__ */ new Set(["src", "kind", "label", "srclang", "default"]),
|
|
385
|
-
video: /* @__PURE__ */ new Set([
|
|
386
|
-
"src",
|
|
387
|
-
"poster",
|
|
388
|
-
"width",
|
|
389
|
-
"height",
|
|
390
|
-
"controls",
|
|
391
|
-
"preload",
|
|
392
|
-
"muted",
|
|
393
|
-
"loop",
|
|
394
|
-
"playsinline"
|
|
395
|
-
])
|
|
396
|
-
};
|
|
397
|
-
var SAFE_ATTR_NAME_RE = /^[a-z][a-z0-9:_.-]*$/;
|
|
398
|
-
var SAFE_OL_TYPES = /* @__PURE__ */ new Set(["1", "a", "A", "i", "I"]);
|
|
399
|
-
var SAFE_PRELOAD_VALUES = /* @__PURE__ */ new Set(["none", "metadata", "auto"]);
|
|
400
|
-
var SAFE_TRACK_KINDS = /* @__PURE__ */ new Set(["subtitles", "captions", "descriptions", "chapters", "metadata"]);
|
|
401
|
-
function sanitizeUrl(url, kind = "link", options) {
|
|
402
|
-
if (typeof url !== "string") return null;
|
|
403
|
-
const trimmed = url.trim();
|
|
404
|
-
if (!trimmed) return null;
|
|
405
|
-
const compact = stripUrlSchemeNoise(trimmed);
|
|
406
|
-
const colon = compact.indexOf(":");
|
|
407
|
-
const firstPathChar = firstIndexOfAny(compact, ["/", "?", "#"]);
|
|
408
|
-
const hasScheme = colon >= 0 && (firstPathChar < 0 || colon < firstPathChar);
|
|
409
|
-
if (!hasScheme) return trimmed;
|
|
410
|
-
const scheme = compact.slice(0, colon).toLowerCase();
|
|
411
|
-
if (kind === "media") {
|
|
412
|
-
if (scheme === "data") return SAFE_DATA_MEDIA_RE.test(compact) ? trimmed : null;
|
|
413
|
-
return SAFE_MEDIA_SCHEMES.has(scheme) ? trimmed : null;
|
|
414
|
-
}
|
|
415
|
-
if (SAFE_LINK_SCHEMES.has(scheme)) return trimmed;
|
|
416
|
-
if (options?.extraLinkSchemes?.includes(scheme) && !NEVER_ALLOWED_SCHEMES.has(scheme)) {
|
|
417
|
-
return trimmed;
|
|
418
|
-
}
|
|
419
|
-
return null;
|
|
420
|
-
}
|
|
421
|
-
function sanitizeHtmlNodes(nodes) {
|
|
422
|
-
const out = [];
|
|
423
|
-
for (const node of nodes) {
|
|
424
|
-
out.push(...sanitizeHtmlNode(node));
|
|
425
|
-
}
|
|
426
|
-
return out;
|
|
427
|
-
}
|
|
428
|
-
function sanitizeHtmlNode(node) {
|
|
429
|
-
switch (node.type) {
|
|
430
|
-
case "htmlText":
|
|
431
|
-
return [node];
|
|
432
|
-
case "htmlComment":
|
|
433
|
-
return [];
|
|
434
|
-
case "htmlElement":
|
|
435
|
-
return sanitizeHtmlElement(node);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
function sanitizeHtmlElement(node) {
|
|
439
|
-
const tag = node.tagName.toLowerCase();
|
|
440
|
-
if (tag === "iframe") return sanitizeVideoEmbedIframe(node);
|
|
441
|
-
if (DROP_WITH_CONTENT_TAGS.has(tag)) return [];
|
|
442
|
-
const children = sanitizeHtmlNodes(node.children);
|
|
443
|
-
if (!SAFE_TAGS.has(tag)) return children;
|
|
444
|
-
return [
|
|
445
|
-
{
|
|
446
|
-
type: "htmlElement",
|
|
447
|
-
tagName: tag,
|
|
448
|
-
attributes: sanitizeAttrs(tag, node.attributes),
|
|
449
|
-
children,
|
|
450
|
-
selfClosing: node.selfClosing
|
|
451
|
-
}
|
|
452
|
-
];
|
|
453
|
-
}
|
|
454
|
-
function sanitizeVideoEmbedIframe(node) {
|
|
455
|
-
const found = videoEmbedFromIframe(node);
|
|
456
|
-
if (!found) return [];
|
|
457
|
-
const attributes = videoEmbedIframeAttributes(found.embed, found.title);
|
|
458
|
-
for (const [rawName, value] of Object.entries(node.attributes)) {
|
|
459
|
-
const name = rawName.toLowerCase();
|
|
460
|
-
if ((name === "width" || name === "height") && isNonNegativeInteger(value)) {
|
|
461
|
-
attributes[name] = value.trim();
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
return [{ type: "htmlElement", tagName: "iframe", attributes, children: [], selfClosing: false }];
|
|
465
|
-
}
|
|
466
|
-
function sanitizeAttrs(tag, attrs) {
|
|
467
|
-
const out = {};
|
|
468
|
-
for (const [rawName, rawValue] of Object.entries(attrs)) {
|
|
469
|
-
const name = rawName.toLowerCase();
|
|
470
|
-
if (!isAllowedAttr(tag, name)) continue;
|
|
471
|
-
const value = String(rawValue);
|
|
472
|
-
const safeValue = sanitizeAttrValue(tag, name, value);
|
|
473
|
-
if (safeValue === null) continue;
|
|
474
|
-
out[name] = safeValue;
|
|
475
|
-
}
|
|
476
|
-
if (tag === "a" && out.target === "_blank") {
|
|
477
|
-
out.rel = ensureRelTokens(out.rel, ["noopener", "noreferrer"]);
|
|
478
|
-
}
|
|
479
|
-
return out;
|
|
480
|
-
}
|
|
481
|
-
function isAllowedAttr(tag, name) {
|
|
482
|
-
if (!SAFE_ATTR_NAME_RE.test(name)) return false;
|
|
483
|
-
if (name.startsWith("on")) return false;
|
|
484
|
-
if (name.startsWith("aria-") || name.startsWith("data-")) return true;
|
|
485
|
-
if (GLOBAL_ATTRS.has(name)) return true;
|
|
486
|
-
return TAG_ATTRS[tag]?.has(name) ?? false;
|
|
487
|
-
}
|
|
488
|
-
function sanitizeAttrValue(tag, name, value) {
|
|
489
|
-
if (name === "href") return sanitizeUrl(value, "link");
|
|
490
|
-
if (name === "src" || name === "poster") return sanitizeUrl(value, "media");
|
|
491
|
-
if ((name === "width" || name === "height" || name === "span" || name === "colspan" || name === "rowspan" || name === "value") && !isNonNegativeInteger(value)) {
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
if (name === "start" && !isInteger(value)) return null;
|
|
495
|
-
if (name === "type" && tag === "ol" && !SAFE_OL_TYPES.has(value)) return null;
|
|
496
|
-
if (name === "preload" && !SAFE_PRELOAD_VALUES.has(value)) return null;
|
|
497
|
-
if (name === "kind" && tag === "track" && !SAFE_TRACK_KINDS.has(value)) return null;
|
|
498
|
-
if (name === "align" && value !== "left" && value !== "right" && value !== "center") return null;
|
|
499
|
-
if (name === "target")
|
|
500
|
-
return value === "_blank" || value === "_self" || value === "_parent" || value === "_top" ? value : null;
|
|
501
|
-
if (name === "rel") return sanitizeRel(value);
|
|
502
|
-
return value;
|
|
503
|
-
}
|
|
504
|
-
function sanitizeRel(value) {
|
|
505
|
-
return relTokens(value).join(" ");
|
|
506
|
-
}
|
|
507
|
-
function ensureRelTokens(value, required) {
|
|
508
|
-
const tokens = new Set(value ? relTokens(value) : []);
|
|
509
|
-
for (const token of required) tokens.add(token);
|
|
510
|
-
return Array.from(tokens).join(" ");
|
|
511
|
-
}
|
|
512
|
-
function relTokens(value) {
|
|
513
|
-
const tokens = value.split(/\s+/).map((token) => token.trim().toLowerCase()).filter(Boolean).filter((token) => /^[a-z0-9_-]+$/.test(token));
|
|
514
|
-
return Array.from(new Set(tokens));
|
|
515
|
-
}
|
|
516
|
-
function isInteger(value) {
|
|
517
|
-
return /^-?\d+$/.test(value.trim());
|
|
518
|
-
}
|
|
519
|
-
function isNonNegativeInteger(value) {
|
|
520
|
-
return /^\d+$/.test(value.trim());
|
|
521
|
-
}
|
|
522
|
-
function firstIndexOfAny(value, needles) {
|
|
523
|
-
let result = -1;
|
|
524
|
-
for (const needle of needles) {
|
|
525
|
-
const index = value.indexOf(needle);
|
|
526
|
-
if (index >= 0 && (result < 0 || index < result)) result = index;
|
|
527
|
-
}
|
|
528
|
-
return result;
|
|
529
|
-
}
|
|
530
|
-
function stripUrlSchemeNoise(value) {
|
|
531
|
-
let out = "";
|
|
532
|
-
for (const char of value) {
|
|
533
|
-
const code = char.charCodeAt(0);
|
|
534
|
-
if (code <= 32 || code === 127 || char.trim() === "") continue;
|
|
535
|
-
out += char;
|
|
536
|
-
}
|
|
537
|
-
return out;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// src/markdown/attrTokens.ts
|
|
541
|
-
var DQ_RUN = `"(?:[^"\\\\]|\\\\.)*"`;
|
|
542
|
-
var SQ_RUN = `'(?:[^'\\\\]|\\\\.)*'`;
|
|
543
|
-
var TEMPLATE_STRICT_RE = new RegExp(
|
|
544
|
-
`\\s*\\{\\[((?:[^\\]"']|${DQ_RUN}|${SQ_RUN})*)\\]\\}[\\s\\]}]*$`
|
|
545
|
-
);
|
|
546
|
-
var TEMPLATE_LEGACY_RE = /\s*\{\[([^\]]*)\]\}[\s\]}]*$/;
|
|
547
|
-
var PANDOC_STRICT_RE = new RegExp(`\\s*\\{(?!\\[)((?:[^}"']|${DQ_RUN}|${SQ_RUN})*)\\}\\s*$`);
|
|
548
|
-
var PANDOC_LEGACY_RE = /\s*\{(?!\[)([^}]*)\}\s*$/;
|
|
549
|
-
function matchTrailing(text, strict, legacy) {
|
|
550
|
-
const m = strict.exec(text) ?? legacy.exec(text);
|
|
551
|
-
return m ? { inner: m[1], index: m.index } : null;
|
|
552
|
-
}
|
|
553
|
-
function matchTrailingTemplateAnnotation(text) {
|
|
554
|
-
return matchTrailing(text, TEMPLATE_STRICT_RE, TEMPLATE_LEGACY_RE);
|
|
555
|
-
}
|
|
556
|
-
function matchTrailingPandocAttr(text) {
|
|
557
|
-
return matchTrailing(text, PANDOC_STRICT_RE, PANDOC_LEGACY_RE);
|
|
558
|
-
}
|
|
559
|
-
var WHITESPACE_RE = /\s/;
|
|
560
|
-
function tokenizeAttrTokens(input) {
|
|
561
|
-
const tokens = [];
|
|
562
|
-
let i = 0;
|
|
563
|
-
const n = input.length;
|
|
564
|
-
while (i < n) {
|
|
565
|
-
while (i < n && WHITESPACE_RE.test(input[i])) i++;
|
|
566
|
-
if (i >= n) break;
|
|
567
|
-
let token = "";
|
|
568
|
-
while (i < n && !WHITESPACE_RE.test(input[i])) {
|
|
569
|
-
const ch = input[i];
|
|
570
|
-
const atValueStart = token === "" || token.endsWith("=");
|
|
571
|
-
if ((ch === '"' || ch === "'") && atValueStart) {
|
|
572
|
-
token += ch;
|
|
573
|
-
i++;
|
|
574
|
-
while (i < n && input[i] !== ch) {
|
|
575
|
-
if (input[i] === "\\" && i + 1 < n && (input[i + 1] === ch || input[i + 1] === "\\")) {
|
|
576
|
-
token += input[i] + input[i + 1];
|
|
577
|
-
i += 2;
|
|
578
|
-
} else {
|
|
579
|
-
token += input[i];
|
|
580
|
-
i++;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
if (i < n && input[i] === ch) {
|
|
584
|
-
token += ch;
|
|
585
|
-
i++;
|
|
586
|
-
}
|
|
587
|
-
} else {
|
|
588
|
-
token += ch;
|
|
589
|
-
i++;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
if (token) tokens.push(token);
|
|
593
|
-
}
|
|
594
|
-
return tokens;
|
|
595
|
-
}
|
|
596
|
-
var DQ_UNESCAPE_RE = /\\([\\"])/g;
|
|
597
|
-
var SQ_UNESCAPE_RE = /\\([\\'])/g;
|
|
598
|
-
function unquoteAttrValue(raw) {
|
|
599
|
-
if (raw.length >= 2) {
|
|
600
|
-
const q = raw[0];
|
|
601
|
-
if ((q === '"' || q === "'") && raw.endsWith(q)) {
|
|
602
|
-
const body = raw.slice(1, -1);
|
|
603
|
-
return body.replace(q === '"' ? DQ_UNESCAPE_RE : SQ_UNESCAPE_RE, "$1");
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
return raw;
|
|
607
|
-
}
|
|
608
|
-
function splitKeyValueToken(token) {
|
|
609
|
-
const eqIdx = token.indexOf("=");
|
|
610
|
-
if (eqIdx <= 0) return null;
|
|
611
|
-
return { key: token.slice(0, eqIdx), value: unquoteAttrValue(token.slice(eqIdx + 1)) };
|
|
612
|
-
}
|
|
613
|
-
var NEEDS_QUOTING_RE = /[\s"'[\]{}]/;
|
|
614
|
-
var DQ_ESCAPE_RE = /[\\"]/g;
|
|
615
|
-
var SQ_ESCAPE_RE = /[\\']/g;
|
|
616
|
-
function needsQuoting(value) {
|
|
617
|
-
return value === "" || NEEDS_QUOTING_RE.test(value);
|
|
618
|
-
}
|
|
619
|
-
function quoteAttrValue(value) {
|
|
620
|
-
if (!needsQuoting(value)) return value;
|
|
621
|
-
if (value.includes('"') && !value.includes("'")) {
|
|
622
|
-
return `'${value.replace(SQ_ESCAPE_RE, (ch) => `\\${ch}`)}'`;
|
|
623
|
-
}
|
|
624
|
-
return `"${value.replace(DQ_ESCAPE_RE, (ch) => `\\${ch}`)}"`;
|
|
625
|
-
}
|
|
626
|
-
function serializeAnnotation(template, params) {
|
|
627
|
-
const parts = [];
|
|
628
|
-
if (template) parts.push(template);
|
|
629
|
-
for (const [key, value] of Object.entries(params ?? {})) {
|
|
630
|
-
parts.push(`${key}=${quoteAttrValue(value)}`);
|
|
631
|
-
}
|
|
632
|
-
return `{[${parts.join(" ")}]}`;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
export {
|
|
636
|
-
KNOWN_BLOCK_META_KEYS,
|
|
637
|
-
BLOCK_META_KEY_DESCRIPTORS,
|
|
638
|
-
coerceAnnotationValues,
|
|
639
|
-
parseNumber,
|
|
640
|
-
parseTimeSeconds,
|
|
641
|
-
TEMPLATE_ALIASES,
|
|
642
|
-
resolveTemplateName,
|
|
643
|
-
TABLE_FED_TEMPLATES,
|
|
644
|
-
CONTAINER_TEMPLATES,
|
|
645
|
-
isContainerTemplate,
|
|
646
|
-
isReservedAnnotationToken,
|
|
647
|
-
sanitizeUrl,
|
|
648
|
-
sanitizeHtmlNodes,
|
|
649
|
-
matchTrailingTemplateAnnotation,
|
|
650
|
-
matchTrailingPandocAttr,
|
|
651
|
-
tokenizeAttrTokens,
|
|
652
|
-
unquoteAttrValue,
|
|
653
|
-
splitKeyValueToken,
|
|
654
|
-
needsQuoting,
|
|
655
|
-
quoteAttrValue,
|
|
656
|
-
serializeAnnotation
|
|
657
|
-
};
|