@meowdown/embed 0.3.1 → 0.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/{fetch-Djnul03u.d.ts → fetch-gxdhOZP6.d.ts} +0 -2
- package/dist/{is-plain-click-QDpLdFP7.js → is-plain-click-Dbydr3nX.js} +6 -10
- package/dist/x/index.d.ts +3 -11
- package/dist/x/index.js +25 -26
- package/dist/x/theme.css +35 -15
- package/dist/youtube/index.d.ts +3 -11
- package/dist/youtube/index.js +9 -14
- package/dist/youtube/theme.css +1 -1
- package/package.json +5 -5
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { HostElement, State } from "@aria-ui/core";
|
|
2
|
-
//#region src/fetch.d.ts
|
|
3
2
|
/**
|
|
4
3
|
* Loads the snapshot for `url`. Return `undefined` when nothing was found.
|
|
5
4
|
*/
|
|
@@ -18,5 +17,4 @@ interface FetchProps<T> {
|
|
|
18
17
|
*/
|
|
19
18
|
resolver: Resolver<T> | null;
|
|
20
19
|
}
|
|
21
|
-
//#endregion
|
|
22
20
|
export { Resolver as n, FetchProps as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createSignal, useEffect } from "@aria-ui/core";
|
|
2
2
|
import el from "crelt";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
// src/fetch.ts
|
|
5
5
|
/**
|
|
6
6
|
* Runs `resolver(url)` whenever `data` is `null` and both `url` and `resolver`
|
|
7
7
|
* are set, ignoring results that arrive after the inputs changed or the host
|
|
@@ -10,6 +10,7 @@ import el from "crelt";
|
|
|
10
10
|
* @internal
|
|
11
11
|
*/
|
|
12
12
|
function useFetch(host, props, label) {
|
|
13
|
+
"use no memo";
|
|
13
14
|
const fetched = createSignal(null);
|
|
14
15
|
const pending = createSignal(false);
|
|
15
16
|
useEffect(host, () => {
|
|
@@ -53,8 +54,7 @@ function isPromiseLike(value) {
|
|
|
53
54
|
return typeof value === "object" && value !== null && typeof value.then === "function";
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
//#region src/safe-url.ts
|
|
57
|
+
// src/safe-url.ts
|
|
58
58
|
function getSafeUrl(value, protocols) {
|
|
59
59
|
if (Array.from(value).some((character) => {
|
|
60
60
|
return character.charCodeAt(0) <= 32 || character.charCodeAt(0) === 127;
|
|
@@ -68,8 +68,7 @@ function getSafeUrl(value, protocols) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
//#region src/render-link.ts
|
|
71
|
+
// src/render-link.ts
|
|
73
72
|
function renderLink(content, destination) {
|
|
74
73
|
const href = destination && getSafeUrl(destination);
|
|
75
74
|
return href ? el("a", {
|
|
@@ -79,8 +78,7 @@ function renderLink(content, destination) {
|
|
|
79
78
|
}, content) : content;
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
//#region src/root.ts
|
|
81
|
+
// src/root.ts
|
|
84
82
|
/**
|
|
85
83
|
* The direct `<div data-root>` child that holds the rendered snapshot. Reused
|
|
86
84
|
* across updates so other children the host appended survive; created on
|
|
@@ -96,11 +94,9 @@ function getRootContainer(host) {
|
|
|
96
94
|
return container;
|
|
97
95
|
}
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
//#region src/is-plain-click.ts
|
|
97
|
+
// src/is-plain-click.ts
|
|
101
98
|
function isPlainClick(event) {
|
|
102
99
|
return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
//#endregion
|
|
106
102
|
export { useFetch as a, getSafeUrl as i, getRootContainer as n, renderLink as r, isPlainClick as t };
|
package/dist/x/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { n as Resolver, t as FetchProps } from "../fetch-
|
|
1
|
+
import { n as Resolver, t as FetchProps } from "../fetch-gxdhOZP6.js";
|
|
2
2
|
import { HostElement, State } from "@aria-ui/core";
|
|
3
3
|
import { XPost, XPostMedia } from "@post-embed/types";
|
|
4
|
-
//#region src/x/media-click.d.ts
|
|
5
4
|
export declare const X_POST_MEDIA_CLICK = "meowdown-embed-media-click";
|
|
6
5
|
interface XPostMediaClickDetail {
|
|
7
6
|
/**
|
|
@@ -23,19 +22,13 @@ interface XPostMediaClickDetail {
|
|
|
23
22
|
element: HTMLElement;
|
|
24
23
|
}
|
|
25
24
|
type XPostMediaClickEvent = CustomEvent<XPostMediaClickDetail>;
|
|
26
|
-
//#endregion
|
|
27
|
-
//#region src/x/x-post.d.ts
|
|
28
25
|
interface XPostProps extends FetchProps<XPost> {
|
|
29
26
|
mediaUrlProtocols: readonly string[] | null;
|
|
30
27
|
}
|
|
31
28
|
interface XPostElement extends HTMLElement, XPostProps {}
|
|
32
29
|
/** @internal */
|
|
33
|
-
export declare function
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/x/register.d.ts
|
|
30
|
+
export declare function setupXPost(host: HostElement, props: State<XPostProps>): void;
|
|
36
31
|
export declare function registerXPost(name?: string): void;
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region src/x/index.d.ts
|
|
39
32
|
declare global {
|
|
40
33
|
interface HTMLElementTagNameMap {
|
|
41
34
|
'meowdown-embed-x': XPostElement;
|
|
@@ -44,5 +37,4 @@ declare global {
|
|
|
44
37
|
'meowdown-embed-media-click': XPostMediaClickEvent;
|
|
45
38
|
}
|
|
46
39
|
}
|
|
47
|
-
|
|
48
|
-
export type { Resolver, XPostElement, XPostMediaClickDetail, XPostMediaClickEvent, XPostProps };
|
|
40
|
+
export { type Resolver, type XPostElement, type XPostMediaClickDetail, type XPostMediaClickEvent, type XPostProps, setupXPost as useXPost };
|
package/dist/x/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { a as useFetch, i as getSafeUrl, n as getRootContainer, r as renderLink, t as isPlainClick } from "../is-plain-click-
|
|
1
|
+
import { a as useFetch, i as getSafeUrl, n as getRootContainer, r as renderLink, t as isPlainClick } from "../is-plain-click-Dbydr3nX.js";
|
|
2
2
|
import { defineCustomElement, defineProps, registerCustomElement, useEffect } from "@aria-ui/core";
|
|
3
3
|
import { parseXPost, parseXPostId } from "@post-embed/schema";
|
|
4
4
|
import el from "crelt";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// src/x/media-click.ts
|
|
7
7
|
const X_POST_MEDIA_CLICK = "meowdown-embed-media-click";
|
|
8
8
|
/**
|
|
9
9
|
* Returns false when a listener called `preventDefault()`: the host shows the
|
|
@@ -18,8 +18,7 @@ function dispatchMediaClick(target, detail) {
|
|
|
18
18
|
}));
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
//#region src/x/render-author.ts
|
|
21
|
+
// src/x/render-author.ts
|
|
23
22
|
function renderAuthor(author, protocols, date) {
|
|
24
23
|
if (!author.name && !author.handle) return;
|
|
25
24
|
const validHandle = /^\w{1,15}$/.test(author.handle);
|
|
@@ -37,8 +36,15 @@ function renderAuthor(author, protocols, date) {
|
|
|
37
36
|
}) : void 0, el("div", { "data-author-details": "" }, el("div", { "data-author-name": "" }, el("bdi", {}, author.name || author.handle)), author.handle ? el("bdi", {}, renderLink(`@${author.handle}`, validHandle ? `https://x.com/${author.handle}` : void 0)) : void 0), date ? el("span", { "data-date": "" }, date) : void 0);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
// ../../node_modules/.pnpm/@ocavue+utils@1.11.0/node_modules/@ocavue/utils/dist/index.js
|
|
40
|
+
/**
|
|
41
|
+
* Returns true if the given value is not null or undefined.
|
|
42
|
+
*/
|
|
43
|
+
function isNotNullish(value) {
|
|
44
|
+
return value != null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/to-positive-number.ts
|
|
42
48
|
/**
|
|
43
49
|
* The value rounded to an integer, or nothing unless it is a finite number
|
|
44
50
|
* above zero.
|
|
@@ -47,8 +53,7 @@ function toPositiveNumber(value) {
|
|
|
47
53
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.round(value);
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
//#region src/x/sort-video-sources.ts
|
|
56
|
+
// src/x/sort-video-sources.ts
|
|
52
57
|
/**
|
|
53
58
|
* Orders the sources the way a `<video>` should try them: it plays the first
|
|
54
59
|
* `<source>` it supports, so MP4 files come before HLS playlists (which only
|
|
@@ -61,8 +66,7 @@ function sortVideoSources(sources) {
|
|
|
61
66
|
});
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
//#region src/x/render-media.ts
|
|
69
|
+
// src/x/render-media.ts
|
|
66
70
|
function getSizeAttrs(media) {
|
|
67
71
|
return {
|
|
68
72
|
width: toPositiveNumber(media.width),
|
|
@@ -97,13 +101,13 @@ function getDisplayable(media, protocols) {
|
|
|
97
101
|
url
|
|
98
102
|
} : void 0;
|
|
99
103
|
}
|
|
100
|
-
const sources = sortVideoSources(media.sources.
|
|
104
|
+
const sources = sortVideoSources(media.sources.map((source) => {
|
|
101
105
|
const url = getSafeMediaUrl(source.url, protocols);
|
|
102
|
-
return url ?
|
|
106
|
+
return url ? {
|
|
103
107
|
...source,
|
|
104
108
|
url
|
|
105
|
-
}
|
|
106
|
-
}));
|
|
109
|
+
} : null;
|
|
110
|
+
}).filter(isNotNullish));
|
|
107
111
|
if (sources.length === 0) return;
|
|
108
112
|
const poster = media.poster && getSafeMediaUrl(media.poster, protocols);
|
|
109
113
|
return {
|
|
@@ -231,8 +235,7 @@ function renderMedia(media, protocols, permalink) {
|
|
|
231
235
|
}));
|
|
232
236
|
}
|
|
233
237
|
|
|
234
|
-
|
|
235
|
-
//#region src/x/render-shared.ts
|
|
238
|
+
// src/x/render-shared.ts
|
|
236
239
|
function getPermalink(post) {
|
|
237
240
|
return /^\w{1,15}$/.test(post.author.handle) && /^\d+$/.test(post.id) ? `https://x.com/${post.author.handle}/status/${post.id}` : void 0;
|
|
238
241
|
}
|
|
@@ -257,8 +260,7 @@ function renderDate(post) {
|
|
|
257
260
|
}).format(date)), getPermalink(post));
|
|
258
261
|
}
|
|
259
262
|
|
|
260
|
-
|
|
261
|
-
//#region src/x/render-post.ts
|
|
263
|
+
// src/x/render-post.ts
|
|
262
264
|
function renderBody(post) {
|
|
263
265
|
const permalink = getPermalink(post);
|
|
264
266
|
return el("p", {
|
|
@@ -287,10 +289,9 @@ function renderPost(post, protocols = null) {
|
|
|
287
289
|
return el("article", {}, el("div", { "data-content": "" }, renderAuthor(post.author, protocols, renderDate(post)), reply ? el("div", { "data-reply-to": "" }, renderLink(`Replying to @${reply.handle}`, replyUrl)) : void 0, renderBody(post), renderMedia(post.media, protocols, getPermalink(post)), post.quote ? renderQuoted(post.quote, protocols) : void 0, renderEdit(post)), el("details", { "data-show-more": "" }, el("summary", {})));
|
|
288
290
|
}
|
|
289
291
|
|
|
290
|
-
|
|
291
|
-
//#region src/x/x-post.ts
|
|
292
|
+
// src/x/x-post.ts
|
|
292
293
|
/** @internal */
|
|
293
|
-
function
|
|
294
|
+
function setupXPost(host, props) {
|
|
294
295
|
const { fetched, pending } = useFetch(host, props, "X post");
|
|
295
296
|
useEffect(host, () => {
|
|
296
297
|
host.dataset.meowdownEmbed = "x";
|
|
@@ -315,7 +316,7 @@ function renderFallback(pending, url) {
|
|
|
315
316
|
"data-pending": ""
|
|
316
317
|
} : { "data-fallback": "" }, el("header", { "data-author": "" }, el("bdi", {}, "X post")), el("p", { "data-body": "" }, pending ? "Loading this post…" : "This post is unavailable."), pending ? null : el("footer", { "data-footer": "" }, permalink ? renderLink("View on X", permalink) : "No saved post could be displayed."));
|
|
317
318
|
}
|
|
318
|
-
const XPost = defineCustomElement(
|
|
319
|
+
const XPost = defineCustomElement(setupXPost, defineProps({
|
|
319
320
|
data: {
|
|
320
321
|
default: null,
|
|
321
322
|
attribute: false
|
|
@@ -334,11 +335,9 @@ const XPost = defineCustomElement(useXPost, defineProps({
|
|
|
334
335
|
}
|
|
335
336
|
}));
|
|
336
337
|
|
|
337
|
-
|
|
338
|
-
//#region src/x/register.ts
|
|
338
|
+
// src/x/register.ts
|
|
339
339
|
function registerXPost(name = "meowdown-embed-x") {
|
|
340
340
|
registerCustomElement(name, class extends XPost {});
|
|
341
341
|
}
|
|
342
342
|
|
|
343
|
-
|
|
344
|
-
export { X_POST_MEDIA_CLICK, registerXPost, useXPost };
|
|
343
|
+
export { X_POST_MEDIA_CLICK, registerXPost, setupXPost, setupXPost as useXPost };
|
package/dist/x/theme.css
CHANGED
|
@@ -51,6 +51,22 @@
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
@keyframes meowdown-embed-fade {
|
|
55
|
+
from,
|
|
56
|
+
to {
|
|
57
|
+
mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), transparent);
|
|
58
|
+
mask-size: 100% calc(var(--_body-limit) - var(--_show-more-height) - 2 * var(--_clip-gutter));
|
|
59
|
+
mask-repeat: no-repeat;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
@keyframes meowdown-embed-show {
|
|
64
|
+
from,
|
|
65
|
+
to {
|
|
66
|
+
visibility: visible;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
/*
|
|
55
71
|
* Hard reset. `all: revert` rolls every property on every box inside the card
|
|
56
72
|
* back to the user-agent default, so a host rule on `p`, `a`, `img`,
|
|
@@ -216,6 +232,9 @@
|
|
|
216
232
|
* when the card is too tall. Then the article gives up one row, which the
|
|
217
233
|
* "Show more" toggle takes, so the whole card is exactly the limit. The
|
|
218
234
|
* toggle is anchored to the card's padding box, out of the article's clip.
|
|
235
|
+
* The fade and the toggle run their own animations on the article's named
|
|
236
|
+
* timeline, which update on every scroll in every engine. Firefox applies
|
|
237
|
+
* a `style()` query on an animated value only after a full restyle.
|
|
219
238
|
* Browsers without scroll-driven animations show the whole card. */
|
|
220
239
|
& > article {
|
|
221
240
|
/* Room inside the clip for focus rings at the article's edges. */
|
|
@@ -264,6 +283,7 @@
|
|
|
264
283
|
margin-block-end: calc(var(--_overflowing) * var(--_show-more-height) - var(--_clip-gutter));
|
|
265
284
|
animation: meowdown-embed-overflowing linear both;
|
|
266
285
|
animation-timeline: scroll(self);
|
|
286
|
+
scroll-timeline: --meowdown-embed-clip block;
|
|
267
287
|
}
|
|
268
288
|
/* Opened, or holding keyboard focus that the clip could hide. */
|
|
269
289
|
& > article:has(> [data-show-more][open]),
|
|
@@ -272,21 +292,20 @@
|
|
|
272
292
|
overflow: visible;
|
|
273
293
|
margin-block-end: calc(-1 * var(--_clip-gutter));
|
|
274
294
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
295
|
+
/* On the content, not the article: a mask on the article would also
|
|
296
|
+
* hide the toggle below it. */
|
|
297
|
+
& > article > [data-content] {
|
|
298
|
+
animation: meowdown-embed-fade linear both;
|
|
299
|
+
animation-timeline: --meowdown-embed-clip;
|
|
300
|
+
}
|
|
301
|
+
& > article > [data-show-more] {
|
|
302
|
+
display: block;
|
|
303
|
+
position: absolute;
|
|
304
|
+
inset-inline-start: var(--meowdown-embed-padding, 1rem);
|
|
305
|
+
bottom: var(--meowdown-embed-padding, 1rem);
|
|
306
|
+
visibility: hidden;
|
|
307
|
+
animation: meowdown-embed-show linear both;
|
|
308
|
+
animation-timeline: --meowdown-embed-clip;
|
|
290
309
|
}
|
|
291
310
|
/* Opened, "Show less" sticks to the bottom of the scrollport until the
|
|
292
311
|
* card's end scrolls into view. */
|
|
@@ -294,6 +313,7 @@
|
|
|
294
313
|
display: block;
|
|
295
314
|
position: sticky;
|
|
296
315
|
bottom: 0.75rem;
|
|
316
|
+
visibility: visible;
|
|
297
317
|
z-index: 1;
|
|
298
318
|
width: fit-content;
|
|
299
319
|
margin: 0.5rem auto 0;
|
package/dist/youtube/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { n as Resolver, t as FetchProps } from "../fetch-
|
|
1
|
+
import { n as Resolver, t as FetchProps } from "../fetch-gxdhOZP6.js";
|
|
2
2
|
import { HostElement, State } from "@aria-ui/core";
|
|
3
3
|
import { YouTubeVideo } from "@post-embed/types";
|
|
4
|
-
//#region src/youtube/video-click.d.ts
|
|
5
4
|
export declare const YOUTUBE_VIDEO_CLICK = "meowdown-embed-youtube-click";
|
|
6
5
|
interface YouTubeVideoClickDetail {
|
|
7
6
|
/**
|
|
@@ -28,8 +27,6 @@ interface YouTubeVideoClickDetail {
|
|
|
28
27
|
element: HTMLElement;
|
|
29
28
|
}
|
|
30
29
|
type YouTubeVideoClickEvent = CustomEvent<YouTubeVideoClickDetail>;
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/youtube/youtube-video.d.ts
|
|
33
30
|
interface YouTubeVideoProps extends FetchProps<YouTubeVideo> {
|
|
34
31
|
/**
|
|
35
32
|
* `link` (default) opens the watch page; `inline` swaps in the YouTube
|
|
@@ -39,12 +36,8 @@ interface YouTubeVideoProps extends FetchProps<YouTubeVideo> {
|
|
|
39
36
|
}
|
|
40
37
|
interface YouTubeVideoElement extends HTMLElement, YouTubeVideoProps {}
|
|
41
38
|
/** @internal */
|
|
42
|
-
export declare function
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/youtube/register.d.ts
|
|
39
|
+
export declare function setupYouTubeVideo(host: HostElement, props: State<YouTubeVideoProps>): void;
|
|
45
40
|
export declare function registerYouTubeVideo(name?: string): void;
|
|
46
|
-
//#endregion
|
|
47
|
-
//#region src/youtube/index.d.ts
|
|
48
41
|
declare global {
|
|
49
42
|
interface HTMLElementTagNameMap {
|
|
50
43
|
'meowdown-embed-youtube': YouTubeVideoElement;
|
|
@@ -53,5 +46,4 @@ declare global {
|
|
|
53
46
|
'meowdown-embed-youtube-click': YouTubeVideoClickEvent;
|
|
54
47
|
}
|
|
55
48
|
}
|
|
56
|
-
|
|
57
|
-
export type { Resolver, YouTubeVideoClickDetail, YouTubeVideoClickEvent, YouTubeVideoElement, YouTubeVideoProps };
|
|
49
|
+
export { type Resolver, type YouTubeVideoClickDetail, type YouTubeVideoClickEvent, type YouTubeVideoElement, type YouTubeVideoProps, setupYouTubeVideo as useYouTubeVideo };
|
package/dist/youtube/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { a as useFetch, i as getSafeUrl, n as getRootContainer, r as renderLink, t as isPlainClick } from "../is-plain-click-
|
|
1
|
+
import { a as useFetch, i as getSafeUrl, n as getRootContainer, r as renderLink, t as isPlainClick } from "../is-plain-click-Dbydr3nX.js";
|
|
2
2
|
import { defineCustomElement, defineProps, registerCustomElement, useEffect } from "@aria-ui/core";
|
|
3
3
|
import { parseYouTubeVideo } from "@post-embed/schema";
|
|
4
4
|
import el from "crelt";
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// src/youtube/parse-url.ts
|
|
7
7
|
const YOUTUBE_HOSTS = /^(?:www\.|m\.)?(?:youtube\.com|youtube-nocookie\.com)$/i;
|
|
8
8
|
const YOUTU_BE_HOST = /^(?:www\.)?youtu\.be$/i;
|
|
9
9
|
const VIDEO_ID = /^[\w-]{11}$/;
|
|
@@ -56,8 +56,7 @@ function getEmbedUrl(ref) {
|
|
|
56
56
|
return `https://www.youtube-nocookie.com/embed/${ref.videoId}?${params}`;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
//#region src/youtube/video-click.ts
|
|
59
|
+
// src/youtube/video-click.ts
|
|
61
60
|
const YOUTUBE_VIDEO_CLICK = "meowdown-embed-youtube-click";
|
|
62
61
|
/**
|
|
63
62
|
* Returns false when a listener called `preventDefault()`: the host plays the
|
|
@@ -72,8 +71,7 @@ function dispatchVideoClick(target, detail) {
|
|
|
72
71
|
}));
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
//#region src/youtube/render-video.ts
|
|
74
|
+
// src/youtube/render-video.ts
|
|
77
75
|
function renderFrame(ref, title) {
|
|
78
76
|
return el("iframe", {
|
|
79
77
|
src: getEmbedUrl(ref),
|
|
@@ -144,10 +142,9 @@ function renderVideo(video, ref, playback) {
|
|
|
144
142
|
}, title), video.author_name ? renderLink(el("span", { "data-author": "" }, video.author_name), video.author_url) : void 0));
|
|
145
143
|
}
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
//#region src/youtube/youtube-video.ts
|
|
145
|
+
// src/youtube/youtube-video.ts
|
|
149
146
|
/** @internal */
|
|
150
|
-
function
|
|
147
|
+
function setupYouTubeVideo(host, props) {
|
|
151
148
|
const { fetched, pending } = useFetch(host, props, "YouTube video");
|
|
152
149
|
useEffect(host, () => {
|
|
153
150
|
host.dataset.meowdownEmbed = "youtube";
|
|
@@ -166,7 +163,7 @@ function renderFallback(pending) {
|
|
|
166
163
|
"data-pending": ""
|
|
167
164
|
} : { "data-fallback": "" }, el("div", { "data-details": "" }, el("span", { "data-title": "" }, "YouTube video")), el("p", { "data-body": "" }, pending ? "Loading this video…" : "This video is unavailable."), pending ? null : el("footer", { "data-footer": "" }, "No saved video could be displayed."));
|
|
168
165
|
}
|
|
169
|
-
const YouTubeVideoCustomElement = defineCustomElement(
|
|
166
|
+
const YouTubeVideoCustomElement = defineCustomElement(setupYouTubeVideo, defineProps({
|
|
170
167
|
data: {
|
|
171
168
|
default: null,
|
|
172
169
|
attribute: false
|
|
@@ -186,11 +183,9 @@ const YouTubeVideoCustomElement = defineCustomElement(useYouTubeVideo, definePro
|
|
|
186
183
|
}
|
|
187
184
|
}));
|
|
188
185
|
|
|
189
|
-
|
|
190
|
-
//#region src/youtube/register.ts
|
|
186
|
+
// src/youtube/register.ts
|
|
191
187
|
function registerYouTubeVideo(name = "meowdown-embed-youtube") {
|
|
192
188
|
registerCustomElement(name, class extends YouTubeVideoCustomElement {});
|
|
193
189
|
}
|
|
194
190
|
|
|
195
|
-
|
|
196
|
-
export { YOUTUBE_VIDEO_CLICK, registerYouTubeVideo, useYouTubeVideo };
|
|
191
|
+
export { YOUTUBE_VIDEO_CLICK, registerYouTubeVideo, setupYouTubeVideo, setupYouTubeVideo as useYouTubeVideo };
|
package/dist/youtube/theme.css
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
);
|
|
42
42
|
--_muted: var(--meowdown-embed-muted-color, color-mix(in srgb, currentColor 58%, transparent));
|
|
43
43
|
--_link: var(--meowdown-embed-link-color, #1d9bf0);
|
|
44
|
-
--_radius: var(--meowdown-embed-radius,
|
|
44
|
+
--_radius: var(--meowdown-embed-radius, 0.75rem);
|
|
45
45
|
--_page: var(--meowdown-embed-background, Canvas);
|
|
46
46
|
--_play: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 68 48'%3E%3Cpath d='M66.52 7.74c-.78-2.93-2.49-5.41-5.42-6.19C55.79.13 34 0 34 0S12.21.13 6.9 1.55C3.97 2.33 2.27 4.81 1.48 7.74.06 13.05 0 24 0 24s.06 10.95 1.48 16.26c.78 2.93 2.49 5.41 5.42 6.19C12.21 47.87 34 48 34 48s21.79-.13 27.1-1.55c2.93-.78 4.64-3.26 5.42-6.19C67.94 34.95 68 24 68 24S67.94 13.05 66.52 7.74z' fill='%23f00'/%3E%3Cpath d='M45 24 27 14v20z' fill='%23fff'/%3E%3C/svg%3E");
|
|
47
47
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meowdown/embed",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@meowdown/vitest": "0.0.0",
|
|
33
33
|
"@ocavue/tsconfig": "^0.7.1",
|
|
34
|
-
"@ocavue/utils": "^1.
|
|
35
|
-
"@vitest/browser-playwright": "^5.0.
|
|
36
|
-
"tsdown": "^0.23.
|
|
37
|
-
"vitest": "^5.0.
|
|
34
|
+
"@ocavue/utils": "^1.11.0",
|
|
35
|
+
"@vitest/browser-playwright": "^5.0.5",
|
|
36
|
+
"tsdown": "^0.23.3",
|
|
37
|
+
"vitest": "^5.0.5"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|