@arsedizioni/ars-utils 22.6.86 → 22.6.88
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/fesm2022/arsedizioni-ars-utils-clipper.common.mjs +3158 -3344
- package/fesm2022/arsedizioni-ars-utils-clipper.common.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs +7616 -4772
- package/fesm2022/arsedizioni-ars-utils-clipper.ui.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.date.mjs +321 -702
- package/fesm2022/arsedizioni-ars-utils-core.date.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.markdown.mjs +445 -590
- package/fesm2022/arsedizioni-ars-utils-core.markdown.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.mjs +1735 -2370
- package/fesm2022/arsedizioni-ars-utils-core.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs +1280 -1470
- package/fesm2022/arsedizioni-ars-utils-core.validators.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs +1097 -1528
- package/fesm2022/arsedizioni-ars-utils-evolution.common.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-support.common.mjs +198 -294
- package/fesm2022/arsedizioni-ars-utils-support.common.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.controls.date.mjs +115 -117
- package/fesm2022/arsedizioni-ars-utils-ui.controls.date.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs +1607 -613
- package/fesm2022/arsedizioni-ars-utils-ui.controls.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.controls.tree.mjs +840 -367
- package/fesm2022/arsedizioni-ars-utils-ui.controls.tree.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs +1634 -651
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.auth.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.mjs +1255 -792
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs +1410 -357
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.prompt.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs +2401 -944
- package/fesm2022/arsedizioni-ars-utils-ui.dialogs.select.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.files.mjs +1553 -741
- package/fesm2022/arsedizioni-ars-utils-ui.files.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.filters.mjs +901 -430
- package/fesm2022/arsedizioni-ars-utils-ui.filters.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.help.mjs +737 -530
- package/fesm2022/arsedizioni-ars-utils-ui.help.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.mjs +6638 -1755
- package/fesm2022/arsedizioni-ars-utils-ui.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.navigation.mjs +1479 -1207
- package/fesm2022/arsedizioni-ars-utils-ui.navigation.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.notifications.mjs +1003 -270
- package/fesm2022/arsedizioni-ars-utils-ui.notifications.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs +497 -278
- package/fesm2022/arsedizioni-ars-utils-ui.oauth.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.paginator.mjs +48 -52
- package/fesm2022/arsedizioni-ars-utils-ui.paginator.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.shell.mjs +464 -704
- package/fesm2022/arsedizioni-ars-utils-ui.shell.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils-ui.tinymce.mjs +724 -657
- package/fesm2022/arsedizioni-ars-utils-ui.tinymce.mjs.map +1 -1
- package/fesm2022/arsedizioni-ars-utils.mjs +3 -19
- package/fesm2022/arsedizioni-ars-utils.mjs.map +1 -1
- package/package.json +1 -1
- package/types/arsedizioni-ars-utils-clipper.common.d.ts +1151 -1163
- package/types/arsedizioni-ars-utils-clipper.ui.d.ts +1588 -1426
- package/types/arsedizioni-ars-utils-core.d.ts +1169 -1172
- package/types/arsedizioni-ars-utils-core.date.d.ts +204 -208
- package/types/arsedizioni-ars-utils-core.markdown.d.ts +128 -126
- package/types/arsedizioni-ars-utils-core.validators.d.ts +270 -236
- package/types/arsedizioni-ars-utils-evolution.common.d.ts +1054 -1067
- package/types/arsedizioni-ars-utils-support.common.d.ts +225 -234
- package/types/arsedizioni-ars-utils-ui.controls.d.ts +440 -278
- package/types/arsedizioni-ars-utils-ui.controls.date.d.ts +24 -28
- package/types/arsedizioni-ars-utils-ui.controls.tree.d.ts +172 -136
- package/types/arsedizioni-ars-utils-ui.d.ts +2035 -821
- package/types/arsedizioni-ars-utils-ui.dialogs.auth.d.ts +327 -322
- package/types/arsedizioni-ars-utils-ui.dialogs.d.ts +343 -347
- package/types/arsedizioni-ars-utils-ui.dialogs.prompt.d.ts +167 -167
- package/types/arsedizioni-ars-utils-ui.dialogs.select.d.ts +373 -367
- package/types/arsedizioni-ars-utils-ui.files.d.ts +335 -283
- package/types/arsedizioni-ars-utils-ui.filters.d.ts +232 -160
- package/types/arsedizioni-ars-utils-ui.help.d.ts +204 -211
- package/types/arsedizioni-ars-utils-ui.navigation.d.ts +811 -646
- package/types/arsedizioni-ars-utils-ui.notifications.d.ts +74 -78
- package/types/arsedizioni-ars-utils-ui.oauth.d.ts +102 -62
- package/types/arsedizioni-ars-utils-ui.paginator.d.ts +19 -22
- package/types/arsedizioni-ars-utils-ui.shell.d.ts +376 -382
- package/types/arsedizioni-ars-utils-ui.tinymce.d.ts +244 -231
- package/types/arsedizioni-ars-utils.d.ts +1 -3
|
@@ -1,591 +1,446 @@
|
|
|
1
|
-
import * as i0 from
|
|
2
|
-
import {
|
|
3
|
-
import { DomSanitizer } from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
});
|
|
445
|
-
// 4. Links: [text](url "title")
|
|
446
|
-
s = s.replace(/\[([^\]]+)\]\(\s*([^)\s]+)(?:\s+(?:"|")(.+?)(?:"|"))?\s*\)/g, (_m, txt, href, title) => {
|
|
447
|
-
const url = this.safeUrl(href);
|
|
448
|
-
if (!url)
|
|
449
|
-
return txt;
|
|
450
|
-
const t = title ? ` title="${this.escapeAttr(title)}"` : '';
|
|
451
|
-
return stash(`<a href="${url}"${t} target="_blank" rel="noopener noreferrer">${txt}</a>`);
|
|
452
|
-
});
|
|
453
|
-
// 5. Autolink remaining bare URLs (markdown links are already stashed)
|
|
454
|
-
s = s.replace(/https?:\/\/[^\s<>"']+/g, url => stash(`<a href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>`));
|
|
455
|
-
// 6. Bold / italic / strikethrough.
|
|
456
|
-
// Delimiters must hug the text; underscore emphasis only at word
|
|
457
|
-
// boundaries so identifiers like snake_case are left untouched.
|
|
458
|
-
s = s.replace(/\*\*\*(?=\S)([\s\S]*?\S)\*\*\*/g, '<strong><em>$1</em></strong>');
|
|
459
|
-
s = s.replace(/(?<![\w*])___(?=\S)([\s\S]*?\S)___(?![\w*])/g, '<strong><em>$1</em></strong>');
|
|
460
|
-
s = s.replace(/\*\*(?=\S)([\s\S]*?\S)\*\*/g, '<strong>$1</strong>');
|
|
461
|
-
s = s.replace(/(?<![\w*])__(?=\S)([\s\S]*?\S)__(?![\w*])/g, '<strong>$1</strong>');
|
|
462
|
-
s = s.replace(/\*(?=\S)([^*\n]*?\S)\*/g, '<em>$1</em>');
|
|
463
|
-
s = s.replace(/(?<![\w_])_(?=\S)([^_\n]*?\S)_(?![\w_])/g, '<em>$1</em>');
|
|
464
|
-
s = s.replace(/~~(?=\S)([\s\S]*?\S)~~/g, '<del>$1</del>');
|
|
465
|
-
// 7. Restore stashed HTML
|
|
466
|
-
return s.replace(/\u0000(\d+)\u0000/g, (_m, idx) => store[Number(idx)] ?? '');
|
|
467
|
-
}
|
|
468
|
-
// #endregion
|
|
469
|
-
// #region Security helpers
|
|
470
|
-
/** Escapes quotes for safe interpolation inside a double-quoted HTML attribute. */
|
|
471
|
-
static escapeAttr(s) {
|
|
472
|
-
return s.replace(/&(?!(?:amp|lt|gt|quot|#\d+);)/g, '&').replace(/"/g, '"');
|
|
473
|
-
}
|
|
474
|
-
/** Escapes &, <, > and " for safe HTML interpolation. */
|
|
475
|
-
static escape(s) {
|
|
476
|
-
return s
|
|
477
|
-
.replace(/&/g, '&')
|
|
478
|
-
.replace(/</g, '<')
|
|
479
|
-
.replace(/>/g, '>')
|
|
480
|
-
.replace(/"/g, '"');
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Returns a sanitized URL or undefined when the scheme is dangerous.
|
|
484
|
-
* Blocks javascript:, vbscript: and data: (also when obfuscated with
|
|
485
|
-
* whitespace/control characters, e.g. "java\tscript:").
|
|
486
|
-
*/
|
|
487
|
-
static safeUrl(url) {
|
|
488
|
-
const compact = url.replace(/[\s\u0000-\u001f]/g, '');
|
|
489
|
-
if (/^(javascript|vbscript|data):/i.test(compact))
|
|
490
|
-
return undefined;
|
|
491
|
-
return url.replace(/"/g, '%22');
|
|
492
|
-
}
|
|
493
|
-
// #endregion
|
|
494
|
-
// #region Clipboard
|
|
495
|
-
/**
|
|
496
|
-
* Copies markdown content to the clipboard in two flavors:
|
|
497
|
-
* - text/html : the rendered HTML (rich paste into Word, Outlook, Gmail...)
|
|
498
|
-
* - text/plain : the original markdown source (paste into editors, IDEs...)
|
|
499
|
-
* @param markdown : the markdown source
|
|
500
|
-
* @param options : conversion options for the HTML flavor
|
|
501
|
-
* @returns : true on success
|
|
502
|
-
*/
|
|
503
|
-
static async copyToClipboard(markdown, options) {
|
|
504
|
-
if (!markdown || typeof navigator === 'undefined' || !navigator.clipboard)
|
|
505
|
-
return false;
|
|
506
|
-
try {
|
|
507
|
-
if (typeof ClipboardItem !== 'undefined') {
|
|
508
|
-
const html = this.toHtml(markdown, options);
|
|
509
|
-
await navigator.clipboard.write([
|
|
510
|
-
new ClipboardItem({
|
|
511
|
-
'text/html': new Blob([html], { type: 'text/html' }),
|
|
512
|
-
'text/plain': new Blob([markdown], { type: 'text/plain' }),
|
|
513
|
-
}),
|
|
514
|
-
]);
|
|
515
|
-
}
|
|
516
|
-
else {
|
|
517
|
-
// Older engines: plain text only
|
|
518
|
-
await navigator.clipboard.writeText(markdown);
|
|
519
|
-
}
|
|
520
|
-
return true;
|
|
521
|
-
}
|
|
522
|
-
catch {
|
|
523
|
-
// Clipboard API requires a secure context and user activation
|
|
524
|
-
return false;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
/**
|
|
528
|
-
* Copies plain text (e.g. the content of a single code block) to the clipboard.
|
|
529
|
-
* @param text : the text to copy
|
|
530
|
-
* @returns : true on success
|
|
531
|
-
*/
|
|
532
|
-
static async copyText(text) {
|
|
533
|
-
if (!text || typeof navigator === 'undefined' || !navigator.clipboard)
|
|
534
|
-
return false;
|
|
535
|
-
try {
|
|
536
|
-
await navigator.clipboard.writeText(text);
|
|
537
|
-
return true;
|
|
538
|
-
}
|
|
539
|
-
catch {
|
|
540
|
-
return false;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
/**
|
|
544
|
-
* Extracts the visible plain text from a rendered element
|
|
545
|
-
* (what the user sees, entities already decoded by the browser).
|
|
546
|
-
* @param element : the element hosting the rendered markdown
|
|
547
|
-
* @returns : the plain text
|
|
548
|
-
*/
|
|
549
|
-
static elementToText(element) {
|
|
550
|
-
return element.innerText ?? element.textContent ?? '';
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* Pipe that converts a Markdown string to sanitized HTML using `MarkdownUtils.toHtml`.
|
|
556
|
-
*
|
|
557
|
-
* Usage: `{{ text | formatMarkdown }}`
|
|
558
|
-
*/
|
|
559
|
-
class FormatMarkdownPipe {
|
|
560
|
-
constructor() {
|
|
561
|
-
this.sanitizer = inject(DomSanitizer);
|
|
562
|
-
}
|
|
563
|
-
/**
|
|
564
|
-
* Transforms a Markdown string into sanitized HTML.
|
|
565
|
-
* @param value - The Markdown input to convert. Treated as an empty string when `undefined`.
|
|
566
|
-
* @returns A `SafeHtml` value that can be rendered with `[innerHTML]`.
|
|
567
|
-
*/
|
|
568
|
-
transform(value) {
|
|
569
|
-
return this.sanitizer.bypassSecurityTrustHtml(MarkdownUtils.toHtml(value ?? '', { escapeHtml: false }));
|
|
570
|
-
}
|
|
571
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FormatMarkdownPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
572
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.7", ngImport: i0, type: FormatMarkdownPipe, isStandalone: true, name: "formatMarkdown" }); }
|
|
573
|
-
}
|
|
574
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: FormatMarkdownPipe, decorators: [{
|
|
575
|
-
type: Pipe,
|
|
576
|
-
args: [{
|
|
577
|
-
name: 'formatMarkdown',
|
|
578
|
-
standalone: true
|
|
579
|
-
}]
|
|
580
|
-
}] });
|
|
581
|
-
|
|
582
|
-
/*
|
|
583
|
-
* Public API Surface of @arsedizioni/ars-utils/core.markdown
|
|
584
|
-
*/
|
|
585
|
-
|
|
586
|
-
/**
|
|
587
|
-
* Generated bundle index. Do not edit.
|
|
588
|
-
*/
|
|
589
|
-
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
import { Pipe, SecurityContext, inject } from "@angular/core";
|
|
3
|
+
import { DomSanitizer } from "@angular/platform-browser";
|
|
4
|
+
var MarkdownUtils = class MarkdownUtils {
|
|
5
|
+
static {
|
|
6
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
7
|
+
}
|
|
8
|
+
static {
|
|
9
|
+
this.CACHE_MAX = 200;
|
|
10
|
+
}
|
|
11
|
+
static clearCache() {
|
|
12
|
+
this.cache.clear();
|
|
13
|
+
}
|
|
14
|
+
static toHtml(markdown, options) {
|
|
15
|
+
if (!markdown) return "";
|
|
16
|
+
const opts = {
|
|
17
|
+
escapeHtml: false,
|
|
18
|
+
breaks: true,
|
|
19
|
+
...options
|
|
20
|
+
};
|
|
21
|
+
const key = `${opts.escapeHtml ? 1 : 0}${opts.breaks ? 1 : 0}|${markdown}`;
|
|
22
|
+
const hit = this.cache.get(key);
|
|
23
|
+
if (hit !== void 0) return hit;
|
|
24
|
+
const source = markdown.replace(/\r\n?/g, "\n").replace(/([a-zà-ÿ][!?])([A-ZÀ-Þ])/g, "$1 $2");
|
|
25
|
+
const html = this.parseBlocks(source.split("\n"), opts).trim();
|
|
26
|
+
if (this.cache.size >= this.CACHE_MAX) this.cache.delete(this.cache.keys().next().value);
|
|
27
|
+
this.cache.set(key, html);
|
|
28
|
+
return html;
|
|
29
|
+
}
|
|
30
|
+
static {
|
|
31
|
+
this.htmlBlockTags = /* @__PURE__ */ new Set([
|
|
32
|
+
"address",
|
|
33
|
+
"article",
|
|
34
|
+
"aside",
|
|
35
|
+
"blockquote",
|
|
36
|
+
"caption",
|
|
37
|
+
"colgroup",
|
|
38
|
+
"col",
|
|
39
|
+
"dd",
|
|
40
|
+
"details",
|
|
41
|
+
"dialog",
|
|
42
|
+
"div",
|
|
43
|
+
"dl",
|
|
44
|
+
"dt",
|
|
45
|
+
"fieldset",
|
|
46
|
+
"figcaption",
|
|
47
|
+
"figure",
|
|
48
|
+
"footer",
|
|
49
|
+
"form",
|
|
50
|
+
"h1",
|
|
51
|
+
"h2",
|
|
52
|
+
"h3",
|
|
53
|
+
"h4",
|
|
54
|
+
"h5",
|
|
55
|
+
"h6",
|
|
56
|
+
"header",
|
|
57
|
+
"hr",
|
|
58
|
+
"iframe",
|
|
59
|
+
"li",
|
|
60
|
+
"main",
|
|
61
|
+
"nav",
|
|
62
|
+
"ol",
|
|
63
|
+
"p",
|
|
64
|
+
"pre",
|
|
65
|
+
"section",
|
|
66
|
+
"summary",
|
|
67
|
+
"table",
|
|
68
|
+
"tbody",
|
|
69
|
+
"td",
|
|
70
|
+
"tfoot",
|
|
71
|
+
"thead",
|
|
72
|
+
"th",
|
|
73
|
+
"tr",
|
|
74
|
+
"ul"
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
static {
|
|
78
|
+
this.htmlVoidTags = /* @__PURE__ */ new Set([
|
|
79
|
+
"hr",
|
|
80
|
+
"col",
|
|
81
|
+
"img",
|
|
82
|
+
"input"
|
|
83
|
+
]);
|
|
84
|
+
}
|
|
85
|
+
static {
|
|
86
|
+
this.htmlBlockScanRe = new RegExp(`<(\\/?)(${[...MarkdownUtils.htmlBlockTags].join("|")})(?=[\\s/>])`, "gi");
|
|
87
|
+
}
|
|
88
|
+
static findHtmlBlockStart(line) {
|
|
89
|
+
let comment = line.indexOf("<!--");
|
|
90
|
+
while (comment !== -1 && this.insideCodeSpan(line, comment)) comment = line.indexOf("<!--", comment + 4);
|
|
91
|
+
const re = this.htmlBlockScanRe;
|
|
92
|
+
re.lastIndex = 0;
|
|
93
|
+
let m;
|
|
94
|
+
let tagHit;
|
|
95
|
+
while ((m = re.exec(line)) !== null) if (!this.insideCodeSpan(line, m.index)) {
|
|
96
|
+
tagHit = {
|
|
97
|
+
index: m.index,
|
|
98
|
+
tag: m[2].toLowerCase(),
|
|
99
|
+
isClose: m[1] === "/"
|
|
100
|
+
};
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
if (comment !== -1 && (!tagHit || comment < tagHit.index)) return {
|
|
104
|
+
index: comment,
|
|
105
|
+
tag: "",
|
|
106
|
+
isClose: false,
|
|
107
|
+
isComment: true
|
|
108
|
+
};
|
|
109
|
+
return tagHit ? {
|
|
110
|
+
...tagHit,
|
|
111
|
+
isComment: false
|
|
112
|
+
} : void 0;
|
|
113
|
+
}
|
|
114
|
+
static insideCodeSpan(line, index) {
|
|
115
|
+
let count = 0;
|
|
116
|
+
for (let i = 0; i < index; i++) if (line.charCodeAt(i) === 96) count++;
|
|
117
|
+
return (count & 1) === 1;
|
|
118
|
+
}
|
|
119
|
+
static scanHtmlDepth(text, tag, depth) {
|
|
120
|
+
const lower = text.toLowerCase();
|
|
121
|
+
const open = "<" + tag;
|
|
122
|
+
const close = "</" + tag;
|
|
123
|
+
let i = 0;
|
|
124
|
+
while ((i = lower.indexOf("<", i)) !== -1) if (lower.startsWith(close, i) && this.isTagBoundary(lower, i + close.length)) {
|
|
125
|
+
depth--;
|
|
126
|
+
const gt = lower.indexOf(">", i);
|
|
127
|
+
const end = gt === -1 ? lower.length : gt + 1;
|
|
128
|
+
if (depth <= 0) return [0, end];
|
|
129
|
+
i = end;
|
|
130
|
+
} else if (lower.startsWith(open, i) && this.isTagBoundary(lower, i + open.length)) {
|
|
131
|
+
const gt = lower.indexOf(">", i);
|
|
132
|
+
if (gt !== -1 && lower.charCodeAt(gt - 1) === 47) {
|
|
133
|
+
if (depth === 0) return [0, gt + 1];
|
|
134
|
+
} else depth++;
|
|
135
|
+
i = gt === -1 ? lower.length : gt + 1;
|
|
136
|
+
} else i++;
|
|
137
|
+
return [depth, -1];
|
|
138
|
+
}
|
|
139
|
+
static isTagBoundary(s, idx) {
|
|
140
|
+
if (idx >= s.length) return true;
|
|
141
|
+
const c = s.charCodeAt(idx);
|
|
142
|
+
return c === 62 || c === 47 || c === 32 || c === 9;
|
|
143
|
+
}
|
|
144
|
+
static pushBack(lines, i, remainder) {
|
|
145
|
+
if (remainder.trim()) {
|
|
146
|
+
lines[i] = remainder;
|
|
147
|
+
return i - 1;
|
|
148
|
+
}
|
|
149
|
+
return i;
|
|
150
|
+
}
|
|
151
|
+
static emitHtmlBlock(lines, i, hit, out) {
|
|
152
|
+
const line = lines[i];
|
|
153
|
+
if (hit.isComment) {
|
|
154
|
+
let end = line.indexOf("-->", hit.index);
|
|
155
|
+
if (end !== -1) {
|
|
156
|
+
out.push(line.slice(hit.index, end + 3));
|
|
157
|
+
return this.pushBack(lines, i, line.slice(end + 3));
|
|
158
|
+
}
|
|
159
|
+
out.push(line.slice(hit.index));
|
|
160
|
+
while (++i < lines.length) {
|
|
161
|
+
end = lines[i].indexOf("-->");
|
|
162
|
+
if (end !== -1) {
|
|
163
|
+
out.push(lines[i].slice(0, end + 3));
|
|
164
|
+
return this.pushBack(lines, i, lines[i].slice(end + 3));
|
|
165
|
+
}
|
|
166
|
+
out.push(lines[i]);
|
|
167
|
+
}
|
|
168
|
+
return lines.length - 1;
|
|
169
|
+
}
|
|
170
|
+
if (hit.isClose || this.htmlVoidTags.has(hit.tag)) {
|
|
171
|
+
const gt = line.indexOf(">", hit.index);
|
|
172
|
+
const end = gt === -1 ? line.length : gt + 1;
|
|
173
|
+
out.push(line.slice(hit.index, end));
|
|
174
|
+
return this.pushBack(lines, i, line.slice(end));
|
|
175
|
+
}
|
|
176
|
+
let [depth, split] = this.scanHtmlDepth(line.slice(hit.index), hit.tag, 0);
|
|
177
|
+
if (split !== -1) {
|
|
178
|
+
out.push(line.slice(hit.index, hit.index + split));
|
|
179
|
+
return this.pushBack(lines, i, line.slice(hit.index + split));
|
|
180
|
+
}
|
|
181
|
+
out.push(line.slice(hit.index));
|
|
182
|
+
while (depth > 0 && ++i < lines.length) {
|
|
183
|
+
[depth, split] = this.scanHtmlDepth(lines[i], hit.tag, depth);
|
|
184
|
+
if (split !== -1) {
|
|
185
|
+
out.push(lines[i].slice(0, split));
|
|
186
|
+
return this.pushBack(lines, i, lines[i].slice(split));
|
|
187
|
+
}
|
|
188
|
+
out.push(lines[i]);
|
|
189
|
+
}
|
|
190
|
+
return Math.min(i, lines.length - 1);
|
|
191
|
+
}
|
|
192
|
+
static parseBlocks(lines, opts) {
|
|
193
|
+
const out = [];
|
|
194
|
+
let paragraph = [];
|
|
195
|
+
const flush = () => {
|
|
196
|
+
if (paragraph.length > 0) {
|
|
197
|
+
const sep = opts.breaks ? "<br>" : " ";
|
|
198
|
+
out.push(`<p>${paragraph.map((l) => this.inline(l, opts)).join(sep)}</p>`);
|
|
199
|
+
paragraph = [];
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
for (let i = 0; i < lines.length; i++) {
|
|
203
|
+
const line = lines[i];
|
|
204
|
+
const trimmed = line.trim();
|
|
205
|
+
const fence = trimmed.match(/^```([\w+-]+)?\s*$/);
|
|
206
|
+
if (fence) {
|
|
207
|
+
flush();
|
|
208
|
+
const lang = fence[1] ? ` class="language-${fence[1]}"` : "";
|
|
209
|
+
const code = [];
|
|
210
|
+
i++;
|
|
211
|
+
while (i < lines.length && !/^```\s*$/.test(lines[i].trim())) {
|
|
212
|
+
code.push(lines[i]);
|
|
213
|
+
i++;
|
|
214
|
+
}
|
|
215
|
+
out.push(`<pre><code${lang}>${this.escape(code.join("\n"))}</code></pre>`);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (!trimmed) {
|
|
219
|
+
flush();
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
if (!opts.escapeHtml && line.includes("<")) {
|
|
223
|
+
const hit = this.findHtmlBlockStart(line);
|
|
224
|
+
if (hit) {
|
|
225
|
+
const before = line.slice(0, hit.index).trim();
|
|
226
|
+
if (before) paragraph.push(before);
|
|
227
|
+
flush();
|
|
228
|
+
i = this.emitHtmlBlock(lines, i, hit, out);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const heading = trimmed.match(/^(#{1,6})\s+(.+?)\s*#*\s*$/);
|
|
233
|
+
if (heading) {
|
|
234
|
+
flush();
|
|
235
|
+
const level = heading[1].length;
|
|
236
|
+
out.push(`<h${level}>${this.inline(heading[2], opts)}</h${level}>`);
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (/^(?:-{3,}|\*{3,}|_{3,})$/.test(trimmed)) {
|
|
240
|
+
flush();
|
|
241
|
+
out.push("<hr>");
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (/^>\s?/.test(trimmed)) {
|
|
245
|
+
flush();
|
|
246
|
+
const quoted = [];
|
|
247
|
+
while (i < lines.length && /^>\s?/.test(lines[i].trim())) {
|
|
248
|
+
quoted.push(lines[i].trim().replace(/^>\s?/, ""));
|
|
249
|
+
i++;
|
|
250
|
+
}
|
|
251
|
+
i--;
|
|
252
|
+
out.push(`<blockquote>${this.parseBlocks(quoted, opts)}</blockquote>`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (trimmed.includes("|") && i + 1 < lines.length && lines[i + 1].includes("-") && /^\|?[\s:\-|]+\|?$/.test(lines[i + 1].trim())) {
|
|
256
|
+
flush();
|
|
257
|
+
const aligns = this.tableAligns(lines[i + 1].trim());
|
|
258
|
+
const head = this.tableRow(trimmed, "th", aligns, opts);
|
|
259
|
+
const body = [];
|
|
260
|
+
i += 2;
|
|
261
|
+
while (i < lines.length && lines[i].trim().includes("|")) {
|
|
262
|
+
body.push(this.tableRow(lines[i].trim(), "td", aligns, opts));
|
|
263
|
+
i++;
|
|
264
|
+
}
|
|
265
|
+
i--;
|
|
266
|
+
out.push(`<table>\n<thead>\n${head}\n</thead>` + (body.length > 0 ? `\n<tbody>\n${body.join("\n")}\n</tbody>` : "") + `\n</table>`);
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (MarkdownUtils.listItemRe.test(line)) {
|
|
270
|
+
flush();
|
|
271
|
+
const [html, last] = this.parseList(lines, i, opts);
|
|
272
|
+
out.push(html);
|
|
273
|
+
i = last;
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
paragraph.push(trimmed);
|
|
277
|
+
}
|
|
278
|
+
flush();
|
|
279
|
+
return out.join("\n");
|
|
280
|
+
}
|
|
281
|
+
static {
|
|
282
|
+
this.listItemRe = /^(\s*)([-*+]|\d+[.)])\s+(.*)$/;
|
|
283
|
+
}
|
|
284
|
+
static parseList(lines, start, opts) {
|
|
285
|
+
const block = [];
|
|
286
|
+
let i = start;
|
|
287
|
+
while (i < lines.length) {
|
|
288
|
+
const l = lines[i];
|
|
289
|
+
if (!l.trim()) break;
|
|
290
|
+
if (this.listItemRe.test(l) || /^\s{2,}\S/.test(l)) {
|
|
291
|
+
block.push(l);
|
|
292
|
+
i++;
|
|
293
|
+
} else break;
|
|
294
|
+
}
|
|
295
|
+
return [this.buildList(block, opts), i - 1];
|
|
296
|
+
}
|
|
297
|
+
static buildList(block, opts) {
|
|
298
|
+
const first = block[0].match(this.listItemRe);
|
|
299
|
+
const baseIndent = first[1].length;
|
|
300
|
+
const ordered = /^\d/.test(first[2]);
|
|
301
|
+
const startNum = ordered ? parseInt(first[2], 10) : 1;
|
|
302
|
+
const items = [];
|
|
303
|
+
for (const l of block) {
|
|
304
|
+
const m = l.match(this.listItemRe);
|
|
305
|
+
if (m && m[1].length <= baseIndent) items.push({
|
|
306
|
+
text: m[3],
|
|
307
|
+
childLines: []
|
|
308
|
+
});
|
|
309
|
+
else if (items.length > 0) items[items.length - 1].childLines.push(l.length > baseIndent + 2 ? l.slice(baseIndent + 2) : l.trim());
|
|
310
|
+
}
|
|
311
|
+
const lis = items.map((item) => {
|
|
312
|
+
let inner;
|
|
313
|
+
const task = item.text.match(/^\[([ xX])\]\s+(.*)$/);
|
|
314
|
+
if (task) inner = `<input type="checkbox" disabled${task[1] !== " " ? " checked" : ""}> ${this.inline(task[2], opts)}`;
|
|
315
|
+
else inner = this.inline(item.text, opts);
|
|
316
|
+
if (item.childLines.length > 0) inner += "\n" + this.parseBlocks(item.childLines, opts);
|
|
317
|
+
return `<li>${inner}</li>`;
|
|
318
|
+
});
|
|
319
|
+
const tag = ordered ? "ol" : "ul";
|
|
320
|
+
return `<${tag}${ordered && startNum > 1 ? ` start="${startNum}"` : ""}>\n${lis.join("\n")}\n</${tag}>`;
|
|
321
|
+
}
|
|
322
|
+
static tableAligns(separator) {
|
|
323
|
+
return separator.replace(/^\||\|$/g, "").split("|").map((cell) => {
|
|
324
|
+
const t = cell.trim();
|
|
325
|
+
if (t.startsWith(":") && t.endsWith(":")) return "center";
|
|
326
|
+
if (t.endsWith(":")) return "right";
|
|
327
|
+
if (t.startsWith(":")) return "left";
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
static tableRow(row, tag, aligns, opts) {
|
|
331
|
+
return `<tr>${row.replace(/^\||\|$/g, "").split("|").map((c) => c.trim()).map((cell, j) => {
|
|
332
|
+
return `<${tag}${aligns[j] ? ` align="${aligns[j]}"` : ""}>${this.inline(cell, opts)}</${tag}>`;
|
|
333
|
+
}).join("")}</tr>`;
|
|
334
|
+
}
|
|
335
|
+
static inline(text, opts) {
|
|
336
|
+
const store = [];
|
|
337
|
+
const stash = (html) => `\u0000${store.push(html) - 1}\u0000`;
|
|
338
|
+
let s = text.replace(/`([^`]+)`/g, (_m, code) => stash(`<code>${this.escape(code)}</code>`));
|
|
339
|
+
if (opts.escapeHtml) s = this.escape(s);
|
|
340
|
+
s = s.replace(/!\[([^\]]*)\]\(\s*([^)\s]+)(?:\s+(?:"|")(.+?)(?:"|"))?\s*\)/g, (_m, alt, src, title) => {
|
|
341
|
+
const url = this.safeUrl(src);
|
|
342
|
+
if (!url) return alt;
|
|
343
|
+
const t = title ? ` title="${this.escapeAttr(title)}"` : "";
|
|
344
|
+
return stash(`<img src="${url}" alt="${this.escapeAttr(alt)}"${t} loading="lazy">`);
|
|
345
|
+
});
|
|
346
|
+
s = s.replace(/\[([^\]]+)\]\(\s*([^)\s]+)(?:\s+(?:"|")(.+?)(?:"|"))?\s*\)/g, (_m, txt, href, title) => {
|
|
347
|
+
const url = this.safeUrl(href);
|
|
348
|
+
if (!url) return txt;
|
|
349
|
+
const t = title ? ` title="${this.escapeAttr(title)}"` : "";
|
|
350
|
+
return stash(`<a href="${url}"${t} target="_blank" rel="noopener noreferrer">${txt}</a>`);
|
|
351
|
+
});
|
|
352
|
+
s = s.replace(/https?:\/\/[^\s<>"']+/g, (url) => stash(`<a href="${url}" target="_blank" rel="noopener noreferrer">${url}</a>`));
|
|
353
|
+
s = s.replace(/\*\*\*(?=\S)([\s\S]*?\S)\*\*\*/g, "<strong><em>$1</em></strong>");
|
|
354
|
+
s = s.replace(/(?<![\w*])___(?=\S)([\s\S]*?\S)___(?![\w*])/g, "<strong><em>$1</em></strong>");
|
|
355
|
+
s = s.replace(/\*\*(?=\S)([\s\S]*?\S)\*\*/g, "<strong>$1</strong>");
|
|
356
|
+
s = s.replace(/(?<![\w*])__(?=\S)([\s\S]*?\S)__(?![\w*])/g, "<strong>$1</strong>");
|
|
357
|
+
s = s.replace(/\*(?=\S)([^*\n]*?\S)\*/g, "<em>$1</em>");
|
|
358
|
+
s = s.replace(/(?<![\w_])_(?=\S)([^_\n]*?\S)_(?![\w_])/g, "<em>$1</em>");
|
|
359
|
+
s = s.replace(/~~(?=\S)([\s\S]*?\S)~~/g, "<del>$1</del>");
|
|
360
|
+
return s.replace(/\u0000(\d+)\u0000/g, (_m, idx) => store[Number(idx)] ?? "");
|
|
361
|
+
}
|
|
362
|
+
static escapeAttr(s) {
|
|
363
|
+
return s.replace(/&(?!(?:amp|lt|gt|quot|#\d+);)/g, "&").replace(/"/g, """);
|
|
364
|
+
}
|
|
365
|
+
static escape(s) {
|
|
366
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
367
|
+
}
|
|
368
|
+
static safeUrl(url) {
|
|
369
|
+
const compact = url.replace(/[\s\u0000-\u001f]/g, "");
|
|
370
|
+
if (/^(javascript|vbscript|data):/i.test(compact)) return void 0;
|
|
371
|
+
return url.replace(/"/g, "%22");
|
|
372
|
+
}
|
|
373
|
+
static async copyToClipboard(markdown, options) {
|
|
374
|
+
if (!markdown || typeof navigator === "undefined" || !navigator.clipboard) return false;
|
|
375
|
+
try {
|
|
376
|
+
if (typeof ClipboardItem !== "undefined") {
|
|
377
|
+
const html = this.toHtml(markdown, options);
|
|
378
|
+
await navigator.clipboard.write([new ClipboardItem({
|
|
379
|
+
"text/html": new Blob([html], { type: "text/html" }),
|
|
380
|
+
"text/plain": new Blob([markdown], { type: "text/plain" })
|
|
381
|
+
})]);
|
|
382
|
+
} else await navigator.clipboard.writeText(markdown);
|
|
383
|
+
return true;
|
|
384
|
+
} catch {
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
static async copyText(text) {
|
|
389
|
+
if (!text || typeof navigator === "undefined" || !navigator.clipboard) return false;
|
|
390
|
+
try {
|
|
391
|
+
await navigator.clipboard.writeText(text);
|
|
392
|
+
return true;
|
|
393
|
+
} catch {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
static elementToText(element) {
|
|
398
|
+
return element.innerText ?? element.textContent ?? "";
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
var FormatMarkdownPipe = class FormatMarkdownPipe {
|
|
402
|
+
constructor() {
|
|
403
|
+
this.sanitizer = inject(DomSanitizer);
|
|
404
|
+
}
|
|
405
|
+
transform(value) {
|
|
406
|
+
const html = MarkdownUtils.toHtml(value ?? "", { escapeHtml: false });
|
|
407
|
+
const clean = this.sanitizer.sanitize(SecurityContext.HTML, html) ?? "";
|
|
408
|
+
return this.sanitizer.bypassSecurityTrustHtml(clean);
|
|
409
|
+
}
|
|
410
|
+
static {
|
|
411
|
+
this.ɵfac = i0.ɵɵngDeclareFactory({
|
|
412
|
+
minVersion: "12.0.0",
|
|
413
|
+
version: "22.2.1",
|
|
414
|
+
ngImport: i0,
|
|
415
|
+
type: FormatMarkdownPipe,
|
|
416
|
+
deps: [],
|
|
417
|
+
target: i0.ɵɵFactoryTarget.Pipe
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
static {
|
|
421
|
+
this.ɵpipe = i0.ɵɵngDeclarePipe({
|
|
422
|
+
minVersion: "14.0.0",
|
|
423
|
+
version: "22.2.1",
|
|
424
|
+
ngImport: i0,
|
|
425
|
+
type: FormatMarkdownPipe,
|
|
426
|
+
isStandalone: true,
|
|
427
|
+
name: "formatMarkdown"
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
432
|
+
minVersion: "12.0.0",
|
|
433
|
+
version: "22.2.1",
|
|
434
|
+
ngImport: i0,
|
|
435
|
+
type: FormatMarkdownPipe,
|
|
436
|
+
decorators: [{
|
|
437
|
+
type: Pipe,
|
|
438
|
+
args: [{
|
|
439
|
+
name: "formatMarkdown",
|
|
440
|
+
standalone: true
|
|
441
|
+
}]
|
|
442
|
+
}]
|
|
443
|
+
});
|
|
590
444
|
export { FormatMarkdownPipe, MarkdownUtils };
|
|
591
|
-
|
|
445
|
+
|
|
446
|
+
//# sourceMappingURL=arsedizioni-ars-utils-core.markdown.mjs.map
|