@fsegurai/marked-extended-embeds 17.0.0-beta.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/README.custom.md +641 -0
- package/README.md +730 -0
- package/dist/index.cjs +744 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.esm.js +742 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/renderer.d.ts +23 -0
- package/dist/tokenizer.d.ts +10 -0
- package/dist/types.d.ts +136 -0
- package/dist/utils/constants.d.ts +29 -0
- package/dist/utils/helpers.d.ts +38 -0
- package/dist/utils/inject-styles.d.ts +4 -0
- package/package.json +53 -0
- package/src/global.d.ts +13 -0
- package/src/index.ts +61 -0
- package/src/renderer.ts +212 -0
- package/src/tokenizer.ts +133 -0
- package/src/types.ts +163 -0
- package/src/utils/constants.ts +154 -0
- package/src/utils/helpers.ts +318 -0
- package/src/utils/inject-styles.ts +15 -0
package/README.custom.md
ADDED
|
@@ -0,0 +1,641 @@
|
|
|
1
|
+
<!-- SECTION:CUSTOM_INTRO -->
|
|
2
|
+
---
|
|
3
|
+
|
|
4
|
+
This extension enables seamless integration of external content with automatic platform detection, responsive layouts,
|
|
5
|
+
privacy controls, and extensive customization options. Perfect for documentation, blogs, portfolios, and educational
|
|
6
|
+
content.
|
|
7
|
+
|
|
8
|
+
<!-- SECTION:CUSTOM_TOC_USAGE -->
|
|
9
|
+
|
|
10
|
+
- [Supported Platforms](#supported-platforms)
|
|
11
|
+
|
|
12
|
+
- [Configuration Options](#configuration-options)
|
|
13
|
+
- [Embed Properties](#embed-properties)
|
|
14
|
+
- [Advanced Examples](#advanced-examples)
|
|
15
|
+
|
|
16
|
+
<!-- SECTION:CUSTOM_BASIC_USAGE -->
|
|
17
|
+
**The extension automatically detects the platform from URLs or accepts explicit `provider` specification.**
|
|
18
|
+
|
|
19
|
+
<!-- SECTION:CUSTOM_USAGE_EXAMPLE -->
|
|
20
|
+
const markdown = `
|
|
21
|
+
::::embed{title="My Video" aspectRatio="16:9"}
|
|
22
|
+
https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
23
|
+
::::embedend
|
|
24
|
+
|
|
25
|
+
::::embed{provider="codepen" theme="dark"}
|
|
26
|
+
https://codepen.io/username/pen/abc123
|
|
27
|
+
::::embedend
|
|
28
|
+
|
|
29
|
+
::::embed{title="Spotify Playlist"}
|
|
30
|
+
https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M
|
|
31
|
+
::::embedend
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
marked.parse(markdown);
|
|
35
|
+
|
|
36
|
+
<!-- SECTION:CUSTOM_USAGE_NOTES -->
|
|
37
|
+
The extension automatically detects providers, applies responsive layouts with proper aspect ratios, and includes
|
|
38
|
+
accessibility features. All embeds support lazy loading, sandbox security, and customizable styling.
|
|
39
|
+
|
|
40
|
+
### Styling Your Embeds
|
|
41
|
+
|
|
42
|
+
This extension follows a **separation of concerns** approach, injecting only minimal structural CSS. Visual styling is completely separated for maximum flexibility.
|
|
43
|
+
|
|
44
|
+
#### Generated HTML Structure
|
|
45
|
+
|
|
46
|
+
```html
|
|
47
|
+
|
|
48
|
+
<div class="marked-extended-embed-container"
|
|
49
|
+
data-provider="youtube"
|
|
50
|
+
data-embed-id="dQw4w9WgXcQ">
|
|
51
|
+
<!-- Loading state -->
|
|
52
|
+
<div class="marked-extended-embed-loading">
|
|
53
|
+
<div class="marked-extended-embed-spinner"></div>
|
|
54
|
+
<p>Loading...</p>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<!-- Embedded content (iframe) -->
|
|
58
|
+
<iframe
|
|
59
|
+
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
|
|
60
|
+
loading="lazy"
|
|
61
|
+
sandbox="allow-scripts allow-same-origin"
|
|
62
|
+
allowfullscreen>
|
|
63
|
+
</iframe>
|
|
64
|
+
|
|
65
|
+
<!-- Optional caption -->
|
|
66
|
+
<div class="marked-extended-embed-caption">
|
|
67
|
+
Video description
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
#### CSS Classes Reference
|
|
73
|
+
|
|
74
|
+
| Class | Purpose | Element |
|
|
75
|
+
|-------|---------|---------|
|
|
76
|
+
| `.marked-extended-embed-container` | Main wrapper | Container |
|
|
77
|
+
| `.marked-extended-embed-container[data-provider="youtube"]` | Provider-specific styling | Container |
|
|
78
|
+
| `.marked-extended-embed-loading` | Loading state overlay | Loading div |
|
|
79
|
+
| `.marked-extended-embed-spinner` | Loading spinner animation | Spinner div |
|
|
80
|
+
| `.marked-extended-embed-loading-text` | "Loading..." text | Text element |
|
|
81
|
+
| `.marked-extended-embed-caption` | Caption/description | Caption div |
|
|
82
|
+
| `iframe` | Embedded content | Iframe |
|
|
83
|
+
|
|
84
|
+
#### Complete Styling Example
|
|
85
|
+
|
|
86
|
+
```css
|
|
87
|
+
/* Base Container */
|
|
88
|
+
.marked-extended-embed-container {
|
|
89
|
+
position: relative;
|
|
90
|
+
width: 100%;
|
|
91
|
+
margin: 1.5rem 0;
|
|
92
|
+
border-radius: 8px;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
background: #f5f5f5;
|
|
95
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Responsive aspect ratio wrapper */
|
|
99
|
+
.marked-extended-embed-container::before {
|
|
100
|
+
content: '';
|
|
101
|
+
display: block;
|
|
102
|
+
padding-top: 56.25%; /* 16:9 aspect ratio */
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.marked-extended-embed-container iframe {
|
|
106
|
+
position: absolute;
|
|
107
|
+
top: 0;
|
|
108
|
+
left: 0;
|
|
109
|
+
width: 100%;
|
|
110
|
+
height: 100%;
|
|
111
|
+
border: none;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Loading State */
|
|
115
|
+
.marked-extended-embed-loading {
|
|
116
|
+
position: absolute;
|
|
117
|
+
top: 0;
|
|
118
|
+
left: 0;
|
|
119
|
+
width: 100%;
|
|
120
|
+
height: 100%;
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-direction: column;
|
|
123
|
+
align-items: center;
|
|
124
|
+
justify-content: center;
|
|
125
|
+
background: rgba(0, 0, 0, 0.05);
|
|
126
|
+
z-index: 1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.marked-extended-embed-spinner {
|
|
130
|
+
width: 40px;
|
|
131
|
+
height: 40px;
|
|
132
|
+
border: 4px solid #e0e0e0;
|
|
133
|
+
border-top-color: #2196F3;
|
|
134
|
+
border-radius: 50%;
|
|
135
|
+
animation: spin 1s linear infinite;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@keyframes spin {
|
|
139
|
+
0% { transform: rotate(0deg); }
|
|
140
|
+
100% { transform: rotate(360deg); }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.marked-extended-embed-loading-text {
|
|
144
|
+
margin-top: 1rem;
|
|
145
|
+
font-size: 0.875rem;
|
|
146
|
+
font-weight: 500;
|
|
147
|
+
color: #666;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/* Caption Styling */
|
|
151
|
+
.marked-extended-embed-caption {
|
|
152
|
+
padding: 0.75rem 1rem;
|
|
153
|
+
font-size: 0.875rem;
|
|
154
|
+
color: #666;
|
|
155
|
+
background: #fafafa;
|
|
156
|
+
border-top: 1px solid #e0e0e0;
|
|
157
|
+
text-align: center;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* Provider-Specific Backgrounds */
|
|
161
|
+
.marked-extended-embed-container[data-provider="youtube"] {
|
|
162
|
+
background: #000;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.marked-extended-embed-container[data-provider="vimeo"] {
|
|
166
|
+
background: #000;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.marked-extended-embed-container[data-provider="codepen"] {
|
|
170
|
+
background: #1e1e1e;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.marked-extended-embed-container[data-provider="codesandbox"] {
|
|
174
|
+
background: #151515;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.marked-extended-embed-container[data-provider="spotify"] {
|
|
178
|
+
background: #191414;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.marked-extended-embed-container[data-provider="soundcloud"] {
|
|
182
|
+
background: #ff5500;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.marked-extended-embed-container[data-provider="twitter"] {
|
|
186
|
+
background: #fff;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.marked-extended-embed-container[data-provider="github-gist"] {
|
|
190
|
+
background: #f6f8fa;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.marked-extended-embed-container[data-provider="figma"] {
|
|
194
|
+
background: #fff;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.marked-extended-embed-container[data-provider="mermaid"] {
|
|
198
|
+
background: #fff;
|
|
199
|
+
padding: 1rem;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.marked-extended-embed-container[data-provider="pdf"] {
|
|
203
|
+
background: #525659;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.marked-extended-embed-container[data-provider="loom"] {
|
|
207
|
+
background: #000;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.marked-extended-embed-container[data-provider="miro"] {
|
|
211
|
+
background: #fff;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.marked-extended-embed-container[data-provider="excalidraw"] {
|
|
215
|
+
background: #fff;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.marked-extended-embed-container[data-provider="drawio"],
|
|
219
|
+
.marked-extended-embed-container[data-provider="diagrams-net"] {
|
|
220
|
+
background: #fff;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### Dark Mode Support
|
|
225
|
+
|
|
226
|
+
```css
|
|
227
|
+
/* Light theme */
|
|
228
|
+
body.light .marked-extended-embed-container {
|
|
229
|
+
background: #f5f5f5;
|
|
230
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
body.light .marked-extended-embed-caption {
|
|
234
|
+
background: #fafafa;
|
|
235
|
+
color: #666;
|
|
236
|
+
border-top-color: #e0e0e0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
body.light .marked-extended-embed-loading {
|
|
240
|
+
color: #666;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
body.light .marked-extended-embed-spinner {
|
|
244
|
+
border-color: #e0e0e0;
|
|
245
|
+
border-top-color: #2196F3;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Dark theme */
|
|
249
|
+
body.dark .marked-extended-embed-container {
|
|
250
|
+
background: #1e1e1e;
|
|
251
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
body.dark .marked-extended-embed-caption {
|
|
255
|
+
background: #2a2a2a;
|
|
256
|
+
color: #e0e0e0;
|
|
257
|
+
border-top-color: #3a3a3a;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
body.dark .marked-extended-embed-loading {
|
|
261
|
+
color: #ccc;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
body.dark .marked-extended-embed-spinner {
|
|
265
|
+
border-color: #333;
|
|
266
|
+
border-top-color: #2196F3;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* Provider-specific dark mode overrides */
|
|
270
|
+
body.dark .marked-extended-embed-container[data-provider="mermaid"],
|
|
271
|
+
body.dark .marked-extended-embed-container[data-provider="twitter"],
|
|
272
|
+
body.dark .marked-extended-embed-container[data-provider="figma"],
|
|
273
|
+
body.dark .marked-extended-embed-container[data-provider="miro"],
|
|
274
|
+
body.dark .marked-extended-embed-container[data-provider="excalidraw"],
|
|
275
|
+
body.dark .marked-extended-embed-container[data-provider="drawio"],
|
|
276
|
+
body.dark .marked-extended-embed-container[data-provider="diagrams-net"] {
|
|
277
|
+
background: #1e1e1e;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
body.dark .marked-extended-embed-container[data-provider="github-gist"] {
|
|
281
|
+
background: #0d1117;
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Custom Aspect Ratios
|
|
286
|
+
|
|
287
|
+
```css
|
|
288
|
+
/* 16:9 (default - videos) */
|
|
289
|
+
.marked-extended-embed-container[data-provider="youtube"]::before,
|
|
290
|
+
.marked-extended-embed-container[data-provider="vimeo"]::before,
|
|
291
|
+
.marked-extended-embed-container[data-provider="loom"]::before {
|
|
292
|
+
padding-top: 56.25%;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* 1:1 (square - music players) */
|
|
296
|
+
.marked-extended-embed-container[data-provider="spotify"]::before,
|
|
297
|
+
.marked-extended-embed-container[data-provider="soundcloud"]::before {
|
|
298
|
+
padding-top: 100%;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* 4:3 (presentations) */
|
|
302
|
+
.marked-extended-embed-container[data-provider="google-slides"]::before {
|
|
303
|
+
padding-top: 75%;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/* Full height (code editors) */
|
|
307
|
+
.marked-extended-embed-container[data-provider="codepen"]::before,
|
|
308
|
+
.marked-extended-embed-container[data-provider="codesandbox"]::before,
|
|
309
|
+
.marked-extended-embed-container[data-provider="replit"]::before {
|
|
310
|
+
padding-top: 100%;
|
|
311
|
+
min-height: 500px;
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### Responsive Adjustments
|
|
316
|
+
|
|
317
|
+
```css
|
|
318
|
+
@media (max-width: 768px) {
|
|
319
|
+
.marked-extended-embed-container {
|
|
320
|
+
margin: 1rem 0;
|
|
321
|
+
border-radius: 4px;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.marked-extended-embed-caption {
|
|
325
|
+
padding: 0.5rem 0.75rem;
|
|
326
|
+
font-size: 0.8125rem;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/* Reduce height for code editors on mobile */
|
|
330
|
+
.marked-extended-embed-container[data-provider="codepen"]::before,
|
|
331
|
+
.marked-extended-embed-container[data-provider="codesandbox"]::before {
|
|
332
|
+
min-height: 400px;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
#### Print Styles
|
|
338
|
+
|
|
339
|
+
```css
|
|
340
|
+
@media print {
|
|
341
|
+
.marked-extended-embed-container {
|
|
342
|
+
break-inside: avoid;
|
|
343
|
+
box-shadow: none;
|
|
344
|
+
border: 1px solid #ccc;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.marked-extended-embed-loading {
|
|
348
|
+
display: none;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/* Show caption */
|
|
352
|
+
.marked-extended-embed-caption {
|
|
353
|
+
display: block !important;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/* Hide interactive embeds, show placeholder */
|
|
357
|
+
.marked-extended-embed-container iframe {
|
|
358
|
+
display: none;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.marked-extended-embed-container::after {
|
|
362
|
+
content: "Embedded content: " attr(data-provider);
|
|
363
|
+
display: block;
|
|
364
|
+
padding: 2rem;
|
|
365
|
+
text-align: center;
|
|
366
|
+
color: #666;
|
|
367
|
+
font-style: italic;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
#### Copy Demo Theme
|
|
373
|
+
|
|
374
|
+
For complete styling with all 18+ providers: [embed-theme.css](https://github.com/fsegurai/marked-extensions/blob/main/demo/styles/extensions/embed-theme.css)
|
|
375
|
+
|
|
376
|
+
Check the [demo](https://fsegurai.github.io/marked-extensions) to see all embed types in action.
|
|
377
|
+
|
|
378
|
+
<!-- SECTION:CUSTOM_SECTIONS -->
|
|
379
|
+
|
|
380
|
+
### Supported Platforms
|
|
381
|
+
|
|
382
|
+
The extension supports **18 different platforms** with automatic URL detection:
|
|
383
|
+
|
|
384
|
+
| Platform | Type | Example URL |
|
|
385
|
+
|------------------|---------------|-------------------------------|
|
|
386
|
+
| **YouTube** | Video | `youtube.com/watch?v=...` |
|
|
387
|
+
| **Vimeo** | Video | `vimeo.com/123456789` |
|
|
388
|
+
| **CodePen** | Code | `codepen.io/user/pen/abc` |
|
|
389
|
+
| **CodeSandbox** | Code | `codesandbox.io/s/abc` |
|
|
390
|
+
| **Twitter** | Social | `twitter.com/user/status/123` |
|
|
391
|
+
| **GitHub Gist** | Code | `gist.github.com/user/abc` |
|
|
392
|
+
| **Spotify** | Music | `open.spotify.com/track/abc` |
|
|
393
|
+
| **SoundCloud** | Music | `soundcloud.com/user/track` |
|
|
394
|
+
| **SlideShare** | Presentation | `slideshare.net/user/slides` |
|
|
395
|
+
| **Figma** | Design | `figma.com/file/abc` |
|
|
396
|
+
| **Loom** | Video | `loom.com/share/abc` |
|
|
397
|
+
| **Miro** | Collaboration | `miro.com/app/board/abc` |
|
|
398
|
+
| **Mermaid** | Diagram | `mermaid://graph TD; A-->B;` |
|
|
399
|
+
| **Excalidraw** | Drawing | `excalidraw.com/#room=abc` |
|
|
400
|
+
| **Draw.io** | Diagram | `diagrams.net/...` |
|
|
401
|
+
| **Diagrams.net** | Diagram | `diagrams.net/...` |
|
|
402
|
+
| **PDF** | Document | Any PDF URL |
|
|
403
|
+
| **iframe** | Generic | Any URL |
|
|
404
|
+
|
|
405
|
+
Each platform is automatically detected from the URL pattern. You can also explicitly specify the provider using the
|
|
406
|
+
`provider` property.
|
|
407
|
+
|
|
408
|
+
## Configuration Options
|
|
409
|
+
|
|
410
|
+
The marked-extended-embeds extension accepts the following configuration options:
|
|
411
|
+
|
|
412
|
+
- `className`: The base CSS class name for embeds. Defaults to 'marked-extended-embed.'
|
|
413
|
+
- `prefixId`: The prefix ID for embed elements. Defaults to 'embed'.
|
|
414
|
+
- `defaultAspectRatio`: Default aspect ratio ('16:9', '4:3', '1:1', '21:9'). Defaults to '16:9'.
|
|
415
|
+
- `allowFullscreen`: Allow fullscreen mode for embeds. Defaults to true.
|
|
416
|
+
- `lazyLoad`: Enable lazy loading for better performance. Defaults to true.
|
|
417
|
+
- `privacyMode`: Use privacy-enhanced domains when available. Defaults to false.
|
|
418
|
+
- `template`: Custom HTML template for rendering embeds. Defaults to built-in template.
|
|
419
|
+
- `customizeToken`: Function to customize embed tokens. Defaults to null.
|
|
420
|
+
- `injectStyles`: Whether to inject default styles. Defaults to true.
|
|
421
|
+
- `enableSandbox`: Enable iframe sandbox for security. Defaults to true.
|
|
422
|
+
- `sandboxPermissions`: Array of sandbox permissions. Defaults
|
|
423
|
+
to ['allow-scripts', 'allow-same-origin', 'allow-popups', 'allow-presentation'].
|
|
424
|
+
- `providers`: Custom provider configurations. Defaults to {}.
|
|
425
|
+
- `onEmbedLoad`: Callback when embed loads. Defaults to null.
|
|
426
|
+
- `onEmbedError`: Callback when embed fails. Defaults to null.
|
|
427
|
+
|
|
428
|
+
### Embed Properties
|
|
429
|
+
|
|
430
|
+
Embed syntax supports the following properties:
|
|
431
|
+
|
|
432
|
+
**Common Properties:**
|
|
433
|
+
|
|
434
|
+
- `title`: Title/caption for the embed
|
|
435
|
+
- `aspectRatio`: Aspect ratio ('16:9', '4:3', '1:1', '21:9', 'custom')
|
|
436
|
+
- `width`: Custom width (e.g., '800px')
|
|
437
|
+
- `height`: Custom height (e.g., '600px')
|
|
438
|
+
- `provider`: Explicit provider name
|
|
439
|
+
- `id`: Custom identifier for the embed
|
|
440
|
+
- `className`: Custom CSS class
|
|
441
|
+
|
|
442
|
+
**Media Properties:**
|
|
443
|
+
|
|
444
|
+
- `autoplay`: Auto-play video/audio (boolean)
|
|
445
|
+
- `muted`: Start muted (boolean)
|
|
446
|
+
- `loop`: Loop playback (boolean)
|
|
447
|
+
- `startTime`: Start time for videos (e.g., '30')
|
|
448
|
+
- `controls`: Show media controls (boolean)
|
|
449
|
+
|
|
450
|
+
**Display Properties:**
|
|
451
|
+
|
|
452
|
+
- `lazyLoad`: Enable lazy loading (boolean)
|
|
453
|
+
- `allowFullscreen`: Allow fullscreen mode (boolean)
|
|
454
|
+
- `privacyMode`: Use privacy-enhanced mode (boolean)
|
|
455
|
+
- `theme`: Theme setting ('light', 'dark')
|
|
456
|
+
|
|
457
|
+
**Custom Parameters:**
|
|
458
|
+
|
|
459
|
+
- `param-*`: Any property starting with 'param-' becomes a URL parameter
|
|
460
|
+
|
|
461
|
+
### Advanced Examples
|
|
462
|
+
|
|
463
|
+
#### YouTube Video with Options
|
|
464
|
+
|
|
465
|
+
```markdown
|
|
466
|
+
::::embed{
|
|
467
|
+
title="Tutorial Video"
|
|
468
|
+
aspectRatio="16:9"
|
|
469
|
+
autoplay="true"
|
|
470
|
+
muted="true"
|
|
471
|
+
startTime="30"
|
|
472
|
+
privacyMode="true"
|
|
473
|
+
}
|
|
474
|
+
https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
475
|
+
::::embedend
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
#### CodePen with Dark Theme
|
|
479
|
+
|
|
480
|
+
```markdown
|
|
481
|
+
::::embed{title="Interactive Demo" theme="dark"}
|
|
482
|
+
https://codepen.io/username/pen/abc123
|
|
483
|
+
::::embedend
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
#### Responsive Design File
|
|
487
|
+
|
|
488
|
+
```markdown
|
|
489
|
+
::::embed{
|
|
490
|
+
title="Mobile App Design"
|
|
491
|
+
aspectRatio="4:3"
|
|
492
|
+
width="100%"
|
|
493
|
+
}
|
|
494
|
+
https://www.figma.com/file/abc123/Mobile-App
|
|
495
|
+
::::embedend
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
#### Spotify Playlist
|
|
499
|
+
|
|
500
|
+
```markdown
|
|
501
|
+
::::embed{title="Coding Playlist" aspectRatio="1:1"}
|
|
502
|
+
https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M
|
|
503
|
+
::::embedend
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
#### CodeSandbox Project
|
|
507
|
+
|
|
508
|
+
```markdown
|
|
509
|
+
::::embed{
|
|
510
|
+
title="React Example"
|
|
511
|
+
theme="dark"
|
|
512
|
+
param-view="preview"
|
|
513
|
+
}
|
|
514
|
+
https://codesandbox.io/s/react-new
|
|
515
|
+
::::embedend
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
#### Mermaid Diagram
|
|
519
|
+
|
|
520
|
+
```markdown
|
|
521
|
+
::::embed{provider="mermaid" title="System Architecture"}
|
|
522
|
+
mermaid://graph TD;
|
|
523
|
+
A[Client] -->|Request| B[API Gateway];
|
|
524
|
+
B --> C[Service 1];
|
|
525
|
+
B --> D[Service 2];
|
|
526
|
+
C --> E[Database];
|
|
527
|
+
D --> E;
|
|
528
|
+
::::embedend
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
#### PDF Document
|
|
532
|
+
|
|
533
|
+
```markdown
|
|
534
|
+
::::embed{
|
|
535
|
+
provider="pdf"
|
|
536
|
+
title="Technical Specification"
|
|
537
|
+
aspectRatio="4:3"
|
|
538
|
+
}
|
|
539
|
+
https://example.com/document.pdf
|
|
540
|
+
::::embedend
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
#### Loom Video with Custom Size
|
|
544
|
+
|
|
545
|
+
```markdown
|
|
546
|
+
::::embed{
|
|
547
|
+
title="Product Demo"
|
|
548
|
+
width="800px"
|
|
549
|
+
height="450px"
|
|
550
|
+
}
|
|
551
|
+
https://www.loom.com/share/abc123
|
|
552
|
+
::::embedend
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
#### Twitter Thread
|
|
556
|
+
|
|
557
|
+
```markdown
|
|
558
|
+
::::embed{title="Latest Announcement"}
|
|
559
|
+
https://twitter.com/username/status/1234567890
|
|
560
|
+
::::embedend
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
#### GitHub Gist
|
|
564
|
+
|
|
565
|
+
```markdown
|
|
566
|
+
::::embed{title="Code Snippet"}
|
|
567
|
+
https://gist.github.com/username/abc123
|
|
568
|
+
::::embedend
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
#### Excalidraw Sketch
|
|
572
|
+
|
|
573
|
+
```markdown
|
|
574
|
+
::::embed{title="Whiteboard Sketch" aspectRatio="16:9"}
|
|
575
|
+
https://excalidraw.com/#room=abc123,def456
|
|
576
|
+
::::embedend
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
#### Draw.io Diagram
|
|
580
|
+
|
|
581
|
+
```markdown
|
|
582
|
+
::::embed{provider="drawio" title="System Architecture" aspectRatio="4:3"}
|
|
583
|
+
https://viewer.diagrams.net/?highlight=0000ff&edit=_blank&title=diagram
|
|
584
|
+
::::embedend
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
## Privacy Mode
|
|
588
|
+
|
|
589
|
+
Enable privacy-enhanced embedding for supported platforms:
|
|
590
|
+
|
|
591
|
+
```markdown
|
|
592
|
+
::::embed{privacyMode="true"}
|
|
593
|
+
https://www.youtube.com/watch?v=abc123
|
|
594
|
+
::::embedend
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
This uses `youtube-nocookie.com` for YouTube and similar privacy-focused domains when available.
|
|
598
|
+
|
|
599
|
+
## Custom Provider Configuration
|
|
600
|
+
|
|
601
|
+
Configure provider-specific settings:
|
|
602
|
+
|
|
603
|
+
```javascript
|
|
604
|
+
marked.use(markedExtendedEmbeds({
|
|
605
|
+
providers: {
|
|
606
|
+
youtube: {
|
|
607
|
+
domain: 'www.youtube-nocookie.com',
|
|
608
|
+
params: {
|
|
609
|
+
rel: '0',
|
|
610
|
+
modestbranding: '1',
|
|
611
|
+
},
|
|
612
|
+
},
|
|
613
|
+
spotify: {
|
|
614
|
+
params: {
|
|
615
|
+
theme: '0',
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
}));
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
## Security Features
|
|
623
|
+
|
|
624
|
+
The extension includes several security features:
|
|
625
|
+
|
|
626
|
+
- **Sandbox by default**: Iframes use sandbox attribute with restricted permissions
|
|
627
|
+
- **Configurable permissions**: Customize allowed iframe capabilities
|
|
628
|
+
- **Privacy mode**: Use no-cookie domains when available
|
|
629
|
+
- **XSS protection**: All user input is escaped
|
|
630
|
+
- **HTTPS enforcement**: Embed URLs use secure protocols
|
|
631
|
+
|
|
632
|
+
## Accessibility
|
|
633
|
+
|
|
634
|
+
All embeds include proper accessibility features:
|
|
635
|
+
|
|
636
|
+
- Semantic HTML with proper roles
|
|
637
|
+
- Alt text and titles
|
|
638
|
+
- Keyboard navigation support
|
|
639
|
+
- Screen reader compatibility
|
|
640
|
+
- Loading states with aria-labels
|
|
641
|
+
|