@nuxt/scripts 0.13.2 → 1.0.0-beta.2
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.md +15 -0
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/B66N9HCo.js +1 -0
- package/dist/client/_nuxt/B8XOar-X.js +162 -0
- package/dist/client/_nuxt/{Bje-0OHL.js → DfLgoB--.js} +1 -1
- package/dist/client/_nuxt/DvH517bE.js +1 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/133a46c5-a5c1-4a63-87d1-037947a5bcdb.json +1 -0
- package/dist/client/_nuxt/entry.D45OuV0w.css +1 -0
- package/dist/client/_nuxt/error-404.B57D-jUQ.css +1 -0
- package/dist/client/_nuxt/error-500.DTHUW7BI.css +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +106 -4
- package/dist/module.json +1 -1
- package/dist/module.mjs +705 -173
- package/dist/registry.mjs +63 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +29 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +35 -10
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +29 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +20 -8
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +2 -2
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +20 -8
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +7 -1
- package/dist/runtime/components/ScriptCrisp.d.vue.ts +1 -1
- package/dist/runtime/components/ScriptCrisp.vue.d.ts +1 -1
- package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +53 -0
- package/dist/runtime/components/ScriptInstagramEmbed.vue +38 -0
- package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +53 -0
- package/dist/runtime/components/ScriptIntercom.d.vue.ts +1 -1
- package/dist/runtime/components/ScriptIntercom.vue.d.ts +1 -1
- package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptXEmbed.d.vue.ts +82 -0
- package/dist/runtime/components/ScriptXEmbed.vue +76 -0
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +82 -0
- package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +12 -1
- package/dist/runtime/components/ScriptYouTubePlayer.vue +41 -16
- package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +12 -1
- package/dist/runtime/composables/useScript.js +34 -3
- package/dist/runtime/composables/useScriptTriggerServiceWorker.d.ts +7 -0
- package/dist/runtime/composables/useScriptTriggerServiceWorker.js +39 -0
- package/dist/runtime/npm-script-stub.d.ts +20 -0
- package/dist/runtime/npm-script-stub.js +73 -0
- package/dist/runtime/plugins/sw-register.client.d.ts +2 -0
- package/dist/runtime/plugins/sw-register.client.js +12 -0
- package/dist/runtime/registry/google-recaptcha.d.ts +27 -0
- package/dist/runtime/registry/google-recaptcha.js +45 -0
- package/dist/runtime/registry/google-sign-in.d.ts +84 -0
- package/dist/runtime/registry/google-sign-in.js +50 -0
- package/dist/runtime/registry/google-tag-manager.d.ts +3 -1
- package/dist/runtime/registry/google-tag-manager.js +15 -5
- package/dist/runtime/registry/instagram-embed.d.ts +23 -0
- package/dist/runtime/registry/instagram-embed.js +22 -0
- package/dist/runtime/registry/lemon-squeezy.d.ts +0 -1
- package/dist/runtime/registry/matomo-analytics.js +1 -1
- package/dist/runtime/registry/plausible-analytics.js +8 -6
- package/dist/runtime/registry/posthog.d.ts +26 -0
- package/dist/runtime/registry/posthog.js +92 -0
- package/dist/runtime/registry/rybbit-analytics.js +38 -8
- package/dist/runtime/registry/tiktok-pixel.d.ts +44 -0
- package/dist/runtime/registry/tiktok-pixel.js +44 -0
- package/dist/runtime/registry/x-embed.d.ts +77 -0
- package/dist/runtime/registry/x-embed.js +41 -0
- package/dist/runtime/server/google-static-maps-proxy.d.ts +2 -0
- package/dist/runtime/server/google-static-maps-proxy.js +54 -0
- package/dist/runtime/server/instagram-embed-asset.d.ts +2 -0
- package/dist/runtime/server/instagram-embed-asset.js +42 -0
- package/dist/runtime/server/instagram-embed-image.d.ts +2 -0
- package/dist/runtime/server/instagram-embed-image.js +54 -0
- package/dist/runtime/server/instagram-embed.d.ts +2 -0
- package/dist/runtime/server/instagram-embed.js +91 -0
- package/dist/runtime/server/proxy-handler.d.ts +6 -0
- package/dist/runtime/server/proxy-handler.js +230 -0
- package/dist/runtime/server/sw-handler.d.ts +2 -0
- package/dist/runtime/server/sw-handler.js +25 -0
- package/dist/runtime/server/utils/privacy.d.ts +97 -0
- package/dist/runtime/server/utils/privacy.js +268 -0
- package/dist/runtime/server/x-embed-image.d.ts +2 -0
- package/dist/runtime/server/x-embed-image.js +53 -0
- package/dist/runtime/server/x-embed.d.ts +49 -0
- package/dist/runtime/server/x-embed.js +31 -0
- package/dist/runtime/sw/proxy-sw.template.d.ts +1 -0
- package/dist/runtime/sw/proxy-sw.template.js +54 -0
- package/dist/runtime/types.d.ts +42 -1
- package/dist/runtime/utils/pure.d.ts +13 -0
- package/dist/runtime/utils/pure.js +67 -0
- package/dist/runtime/utils.d.ts +3 -2
- package/dist/runtime/utils.js +11 -1
- package/dist/types.d.mts +1 -1
- package/package.json +39 -32
- package/dist/client/_nuxt/DMut0W-e.js +0 -162
- package/dist/client/_nuxt/builds/meta/5e0206fe-a683-423c-8d59-2596d0b16fee.json +0 -1
- package/dist/client/_nuxt/entry.BjfcJo5q.css +0 -1
- package/dist/client/_nuxt/error-404.B0ZhSNwd.css +0 -1
- package/dist/client/_nuxt/error-500.D4MdgPaC.css +0 -1
- package/dist/client/_nuxt/iNmKC7TZ.js +0 -1
- package/dist/client/_nuxt/rttsH3SL.js +0 -1
|
@@ -64,6 +64,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
64
64
|
getPlaybackRate: () => Promise<number> | undefined;
|
|
65
65
|
setPlaybackRate: (rate: number) => Promise<number> | undefined;
|
|
66
66
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
67
|
+
progress: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
67
68
|
error: (event: import("@vimeo/player").Error, player: Vimeo.Player) => any;
|
|
68
69
|
loaded: (event: import("@vimeo/player").LoadedEvent, player: Vimeo.Player) => any;
|
|
69
70
|
cuechange: (event: import("@vimeo/player").CueChangeEvent, player: Vimeo.Player) => any;
|
|
@@ -72,7 +73,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
72
73
|
pause: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
73
74
|
play: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
74
75
|
playing: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
75
|
-
progress: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
76
76
|
resize: (event: import("@vimeo/player").ResizeEvent, player: Vimeo.Player) => any;
|
|
77
77
|
seeked: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
78
78
|
seeking: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
@@ -90,6 +90,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
90
90
|
enterpictureinpicture: (event: never, player: Vimeo.Player) => any;
|
|
91
91
|
leavepictureinpicture: (event: never, player: Vimeo.Player) => any;
|
|
92
92
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
93
|
+
onProgress?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
93
94
|
onError?: ((event: import("@vimeo/player").Error, player: Vimeo.Player) => any) | undefined;
|
|
94
95
|
onLoaded?: ((event: import("@vimeo/player").LoadedEvent, player: Vimeo.Player) => any) | undefined;
|
|
95
96
|
onCuechange?: ((event: import("@vimeo/player").CueChangeEvent, player: Vimeo.Player) => any) | undefined;
|
|
@@ -98,7 +99,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
98
99
|
onPause?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
99
100
|
onPlay?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
100
101
|
onPlaying?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
101
|
-
onProgress?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
102
102
|
onResize?: ((event: import("@vimeo/player").ResizeEvent, player: Vimeo.Player) => any) | undefined;
|
|
103
103
|
onSeeked?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
104
104
|
onSeeking?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
@@ -64,6 +64,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
64
64
|
getPlaybackRate: () => Promise<number> | undefined;
|
|
65
65
|
setPlaybackRate: (rate: number) => Promise<number> | undefined;
|
|
66
66
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
67
|
+
progress: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
67
68
|
error: (event: import("@vimeo/player").Error, player: Vimeo.Player) => any;
|
|
68
69
|
loaded: (event: import("@vimeo/player").LoadedEvent, player: Vimeo.Player) => any;
|
|
69
70
|
cuechange: (event: import("@vimeo/player").CueChangeEvent, player: Vimeo.Player) => any;
|
|
@@ -72,7 +73,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
72
73
|
pause: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
73
74
|
play: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
74
75
|
playing: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
75
|
-
progress: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
76
76
|
resize: (event: import("@vimeo/player").ResizeEvent, player: Vimeo.Player) => any;
|
|
77
77
|
seeked: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
78
78
|
seeking: (event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any;
|
|
@@ -90,6 +90,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
90
90
|
enterpictureinpicture: (event: never, player: Vimeo.Player) => any;
|
|
91
91
|
leavepictureinpicture: (event: never, player: Vimeo.Player) => any;
|
|
92
92
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
93
|
+
onProgress?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
93
94
|
onError?: ((event: import("@vimeo/player").Error, player: Vimeo.Player) => any) | undefined;
|
|
94
95
|
onLoaded?: ((event: import("@vimeo/player").LoadedEvent, player: Vimeo.Player) => any) | undefined;
|
|
95
96
|
onCuechange?: ((event: import("@vimeo/player").CueChangeEvent, player: Vimeo.Player) => any) | undefined;
|
|
@@ -98,7 +99,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
98
99
|
onPause?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
99
100
|
onPlay?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
100
101
|
onPlaying?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
101
|
-
onProgress?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
102
102
|
onResize?: ((event: import("@vimeo/player").ResizeEvent, player: Vimeo.Player) => any) | undefined;
|
|
103
103
|
onSeeked?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
104
104
|
onSeeking?: ((event: import("@vimeo/player").TimeEvent, player: Vimeo.Player) => any) | undefined;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'vue';
|
|
2
|
+
import type { XEmbedTweetData } from '../registry/x-embed.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
/**
|
|
5
|
+
* The tweet ID to embed
|
|
6
|
+
*/
|
|
7
|
+
tweetId: string;
|
|
8
|
+
/**
|
|
9
|
+
* Custom API endpoint for fetching tweet data
|
|
10
|
+
* @default '/_scripts/x-embed'
|
|
11
|
+
*/
|
|
12
|
+
apiEndpoint?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom image proxy endpoint
|
|
15
|
+
* @default '/_scripts/x-embed-image'
|
|
16
|
+
*/
|
|
17
|
+
imageProxyEndpoint?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Root element attributes
|
|
20
|
+
*/
|
|
21
|
+
rootAttrs?: HTMLAttributes;
|
|
22
|
+
};
|
|
23
|
+
declare var __VLS_1: {}, __VLS_3: {
|
|
24
|
+
error: import("nuxt/app").NuxtError<unknown> | undefined;
|
|
25
|
+
}, __VLS_5: {
|
|
26
|
+
tweet: XEmbedTweetData;
|
|
27
|
+
userName: string;
|
|
28
|
+
userHandle: string;
|
|
29
|
+
userAvatar: string;
|
|
30
|
+
userAvatarOriginal: string;
|
|
31
|
+
isVerified: boolean | undefined;
|
|
32
|
+
text: string;
|
|
33
|
+
datetime: string;
|
|
34
|
+
createdAt: Date;
|
|
35
|
+
likes: number;
|
|
36
|
+
likesFormatted: string;
|
|
37
|
+
replies: number;
|
|
38
|
+
repliesFormatted: string;
|
|
39
|
+
photos: {
|
|
40
|
+
proxiedUrl: string;
|
|
41
|
+
url: string;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}[] | undefined;
|
|
45
|
+
video: {
|
|
46
|
+
posterProxied: string;
|
|
47
|
+
poster: string;
|
|
48
|
+
variants: Array<{
|
|
49
|
+
type: string;
|
|
50
|
+
src: string;
|
|
51
|
+
}>;
|
|
52
|
+
} | null;
|
|
53
|
+
tweetUrl: string;
|
|
54
|
+
userUrl: string;
|
|
55
|
+
quotedTweet: XEmbedTweetData | undefined;
|
|
56
|
+
isReply: boolean;
|
|
57
|
+
replyToUser: string | undefined;
|
|
58
|
+
proxyImage: (url: string) => string;
|
|
59
|
+
};
|
|
60
|
+
type __VLS_Slots = {} & {
|
|
61
|
+
loading?: (props: typeof __VLS_1) => any;
|
|
62
|
+
} & {
|
|
63
|
+
error?: (props: typeof __VLS_3) => any;
|
|
64
|
+
} & {
|
|
65
|
+
default?: (props: typeof __VLS_5) => any;
|
|
66
|
+
};
|
|
67
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
68
|
+
tweet: import("vue").Ref<XEmbedTweetData | undefined, XEmbedTweetData | undefined>;
|
|
69
|
+
status: import("vue").Ref<import("nuxt/app").AsyncDataRequestStatus, import("nuxt/app").AsyncDataRequestStatus>;
|
|
70
|
+
error: import("vue").Ref<import("nuxt/app").NuxtError<unknown> | undefined, import("nuxt/app").NuxtError<unknown> | undefined>;
|
|
71
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
72
|
+
apiEndpoint: string;
|
|
73
|
+
imageProxyEndpoint: string;
|
|
74
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
75
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
76
|
+
declare const _default: typeof __VLS_export;
|
|
77
|
+
export default _default;
|
|
78
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
79
|
+
new (): {
|
|
80
|
+
$slots: S;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { useAsyncData } from "nuxt/app";
|
|
4
|
+
import { formatCount, formatTweetDate, proxyXImageUrl } from "../registry/x-embed";
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
tweetId: { type: String, required: true },
|
|
7
|
+
apiEndpoint: { type: String, required: false, default: "/api/_scripts/x-embed" },
|
|
8
|
+
imageProxyEndpoint: { type: String, required: false, default: "/api/_scripts/x-embed-image" },
|
|
9
|
+
rootAttrs: { type: Object, required: false }
|
|
10
|
+
});
|
|
11
|
+
const cacheKey = computed(() => `x-embed-${props.tweetId}`);
|
|
12
|
+
const { data: tweet, status, error } = useAsyncData(
|
|
13
|
+
cacheKey,
|
|
14
|
+
() => $fetch(`${props.apiEndpoint}?id=${props.tweetId}`)
|
|
15
|
+
);
|
|
16
|
+
const slotProps = computed(() => {
|
|
17
|
+
if (!tweet.value)
|
|
18
|
+
return null;
|
|
19
|
+
const t = tweet.value;
|
|
20
|
+
return {
|
|
21
|
+
// Raw data
|
|
22
|
+
tweet: t,
|
|
23
|
+
// User info
|
|
24
|
+
userName: t.user.name,
|
|
25
|
+
userHandle: t.user.screen_name,
|
|
26
|
+
userAvatar: proxyXImageUrl(t.user.profile_image_url_https, props.imageProxyEndpoint),
|
|
27
|
+
userAvatarOriginal: t.user.profile_image_url_https,
|
|
28
|
+
isVerified: t.user.verified || t.user.is_blue_verified,
|
|
29
|
+
// Tweet content
|
|
30
|
+
text: t.text,
|
|
31
|
+
// Formatted values
|
|
32
|
+
datetime: formatTweetDate(t.created_at),
|
|
33
|
+
createdAt: new Date(t.created_at),
|
|
34
|
+
likes: t.favorite_count,
|
|
35
|
+
likesFormatted: formatCount(t.favorite_count),
|
|
36
|
+
replies: t.conversation_count,
|
|
37
|
+
repliesFormatted: formatCount(t.conversation_count),
|
|
38
|
+
// Media
|
|
39
|
+
photos: t.photos?.map((p) => ({
|
|
40
|
+
...p,
|
|
41
|
+
proxiedUrl: proxyXImageUrl(p.url, props.imageProxyEndpoint)
|
|
42
|
+
})),
|
|
43
|
+
video: t.video ? {
|
|
44
|
+
...t.video,
|
|
45
|
+
posterProxied: proxyXImageUrl(t.video.poster, props.imageProxyEndpoint)
|
|
46
|
+
} : null,
|
|
47
|
+
// Links
|
|
48
|
+
tweetUrl: `https://x.com/${t.user.screen_name}/status/${t.id_str}`,
|
|
49
|
+
userUrl: `https://x.com/${t.user.screen_name}`,
|
|
50
|
+
// Quoted tweet
|
|
51
|
+
quotedTweet: t.quoted_tweet,
|
|
52
|
+
// Reply context
|
|
53
|
+
isReply: !!t.parent,
|
|
54
|
+
replyToUser: t.parent?.user.screen_name,
|
|
55
|
+
// Helpers
|
|
56
|
+
proxyImage: (url) => proxyXImageUrl(url, props.imageProxyEndpoint)
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
defineExpose({
|
|
60
|
+
tweet,
|
|
61
|
+
status,
|
|
62
|
+
error
|
|
63
|
+
});
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<template>
|
|
67
|
+
<div v-bind="rootAttrs">
|
|
68
|
+
<slot v-if="status === 'pending'" name="loading">
|
|
69
|
+
<div>Loading tweet...</div>
|
|
70
|
+
</slot>
|
|
71
|
+
<slot v-else-if="status === 'error'" name="error" :error="error">
|
|
72
|
+
<div>Failed to load tweet</div>
|
|
73
|
+
</slot>
|
|
74
|
+
<slot v-else-if="slotProps" v-bind="slotProps" />
|
|
75
|
+
</div>
|
|
76
|
+
</template>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'vue';
|
|
2
|
+
import type { XEmbedTweetData } from '../registry/x-embed.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
/**
|
|
5
|
+
* The tweet ID to embed
|
|
6
|
+
*/
|
|
7
|
+
tweetId: string;
|
|
8
|
+
/**
|
|
9
|
+
* Custom API endpoint for fetching tweet data
|
|
10
|
+
* @default '/_scripts/x-embed'
|
|
11
|
+
*/
|
|
12
|
+
apiEndpoint?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom image proxy endpoint
|
|
15
|
+
* @default '/_scripts/x-embed-image'
|
|
16
|
+
*/
|
|
17
|
+
imageProxyEndpoint?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Root element attributes
|
|
20
|
+
*/
|
|
21
|
+
rootAttrs?: HTMLAttributes;
|
|
22
|
+
};
|
|
23
|
+
declare var __VLS_1: {}, __VLS_3: {
|
|
24
|
+
error: import("nuxt/app").NuxtError<unknown> | undefined;
|
|
25
|
+
}, __VLS_5: {
|
|
26
|
+
tweet: XEmbedTweetData;
|
|
27
|
+
userName: string;
|
|
28
|
+
userHandle: string;
|
|
29
|
+
userAvatar: string;
|
|
30
|
+
userAvatarOriginal: string;
|
|
31
|
+
isVerified: boolean | undefined;
|
|
32
|
+
text: string;
|
|
33
|
+
datetime: string;
|
|
34
|
+
createdAt: Date;
|
|
35
|
+
likes: number;
|
|
36
|
+
likesFormatted: string;
|
|
37
|
+
replies: number;
|
|
38
|
+
repliesFormatted: string;
|
|
39
|
+
photos: {
|
|
40
|
+
proxiedUrl: string;
|
|
41
|
+
url: string;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}[] | undefined;
|
|
45
|
+
video: {
|
|
46
|
+
posterProxied: string;
|
|
47
|
+
poster: string;
|
|
48
|
+
variants: Array<{
|
|
49
|
+
type: string;
|
|
50
|
+
src: string;
|
|
51
|
+
}>;
|
|
52
|
+
} | null;
|
|
53
|
+
tweetUrl: string;
|
|
54
|
+
userUrl: string;
|
|
55
|
+
quotedTweet: XEmbedTweetData | undefined;
|
|
56
|
+
isReply: boolean;
|
|
57
|
+
replyToUser: string | undefined;
|
|
58
|
+
proxyImage: (url: string) => string;
|
|
59
|
+
};
|
|
60
|
+
type __VLS_Slots = {} & {
|
|
61
|
+
loading?: (props: typeof __VLS_1) => any;
|
|
62
|
+
} & {
|
|
63
|
+
error?: (props: typeof __VLS_3) => any;
|
|
64
|
+
} & {
|
|
65
|
+
default?: (props: typeof __VLS_5) => any;
|
|
66
|
+
};
|
|
67
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
68
|
+
tweet: import("vue").Ref<XEmbedTweetData | undefined, XEmbedTweetData | undefined>;
|
|
69
|
+
status: import("vue").Ref<import("nuxt/app").AsyncDataRequestStatus, import("nuxt/app").AsyncDataRequestStatus>;
|
|
70
|
+
error: import("vue").Ref<import("nuxt/app").NuxtError<unknown> | undefined, import("nuxt/app").NuxtError<unknown> | undefined>;
|
|
71
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
72
|
+
apiEndpoint: string;
|
|
73
|
+
imageProxyEndpoint: string;
|
|
74
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
75
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
76
|
+
declare const _default: typeof __VLS_export;
|
|
77
|
+
export default _default;
|
|
78
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
79
|
+
new (): {
|
|
80
|
+
$slots: S;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
@@ -10,6 +10,7 @@ type __VLS_Props = {
|
|
|
10
10
|
playerVars?: YT.PlayerVars;
|
|
11
11
|
width?: number;
|
|
12
12
|
height?: number;
|
|
13
|
+
ratio?: string;
|
|
13
14
|
/**
|
|
14
15
|
* Whether to use youtube-nocookie.com for embedding.
|
|
15
16
|
*
|
|
@@ -19,9 +20,15 @@ type __VLS_Props = {
|
|
|
19
20
|
playerOptions?: YT.PlayerOptions;
|
|
20
21
|
thumbnailSize?: YoutubeThumbnailSize;
|
|
21
22
|
webp?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Object-fit for the placeholder image.
|
|
25
|
+
*
|
|
26
|
+
* @default 'cover'
|
|
27
|
+
*/
|
|
28
|
+
placeholderObjectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
22
29
|
};
|
|
23
30
|
declare var __VLS_1: {
|
|
24
|
-
placeholder:
|
|
31
|
+
placeholder: string;
|
|
25
32
|
}, __VLS_3: {}, __VLS_10: {}, __VLS_12: {}, __VLS_14: {};
|
|
26
33
|
type __VLS_Slots = {} & {
|
|
27
34
|
placeholder?: (props: typeof __VLS_1) => any;
|
|
@@ -42,20 +49,24 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
42
49
|
"state-change": (e: YT.OnStateChangeEvent, target: YT.Player) => any;
|
|
43
50
|
"playback-quality-change": (e: YT.OnPlaybackQualityChangeEvent, target: YT.Player) => any;
|
|
44
51
|
"playback-rate-change": (e: YT.OnPlaybackRateChangeEvent, target: YT.Player) => any;
|
|
52
|
+
"api-change": (e: YT.PlayerEvent, target: YT.Player) => any;
|
|
45
53
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
46
54
|
onError?: ((e: YT.OnErrorEvent, target: YT.Player) => any) | undefined;
|
|
47
55
|
onReady?: ((e: YT.PlayerEvent) => any) | undefined;
|
|
48
56
|
"onState-change"?: ((e: YT.OnStateChangeEvent, target: YT.Player) => any) | undefined;
|
|
49
57
|
"onPlayback-quality-change"?: ((e: YT.OnPlaybackQualityChangeEvent, target: YT.Player) => any) | undefined;
|
|
50
58
|
"onPlayback-rate-change"?: ((e: YT.OnPlaybackRateChangeEvent, target: YT.Player) => any) | undefined;
|
|
59
|
+
"onApi-change"?: ((e: YT.PlayerEvent, target: YT.Player) => any) | undefined;
|
|
51
60
|
}>, {
|
|
52
61
|
trigger: ElementScriptTrigger;
|
|
53
62
|
width: number;
|
|
54
63
|
height: number;
|
|
55
64
|
playerVars: YT.PlayerVars;
|
|
65
|
+
ratio: string;
|
|
56
66
|
cookies: boolean;
|
|
57
67
|
thumbnailSize: YoutubeThumbnailSize;
|
|
58
68
|
webp: boolean;
|
|
69
|
+
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
59
70
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
60
71
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
61
72
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, onMounted, ref, watch } from "vue";
|
|
2
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
3
3
|
import { defu } from "defu";
|
|
4
4
|
import { useHead } from "nuxt/app";
|
|
5
5
|
import { useScriptTriggerElement } from "../composables/useScriptTriggerElement";
|
|
@@ -14,12 +14,14 @@ const props = defineProps({
|
|
|
14
14
|
playerVars: { type: null, required: false, default: { autoplay: 0, playsinline: 1 } },
|
|
15
15
|
width: { type: Number, required: false, default: 640 },
|
|
16
16
|
height: { type: Number, required: false, default: 360 },
|
|
17
|
+
ratio: { type: String, required: false, default: "16/9" },
|
|
17
18
|
cookies: { type: Boolean, required: false, default: false },
|
|
18
19
|
playerOptions: { type: null, required: false },
|
|
19
20
|
thumbnailSize: { type: String, required: false, default: "hq720" },
|
|
20
|
-
webp: { type: Boolean, required: false, default: true }
|
|
21
|
+
webp: { type: Boolean, required: false, default: true },
|
|
22
|
+
placeholderObjectFit: { type: String, required: false, default: "cover" }
|
|
21
23
|
});
|
|
22
|
-
const emits = defineEmits(["ready", "state-change", "playback-quality-change", "playback-rate-change", "error"]);
|
|
24
|
+
const emits = defineEmits(["ready", "state-change", "playback-quality-change", "playback-rate-change", "error", "api-change"]);
|
|
23
25
|
const events = [
|
|
24
26
|
"onReady",
|
|
25
27
|
"onStateChange",
|
|
@@ -31,24 +33,46 @@ const events = [
|
|
|
31
33
|
const rootEl = ref();
|
|
32
34
|
const youtubeEl = ref();
|
|
33
35
|
const ready = ref(false);
|
|
36
|
+
const isTriggered = ref(false);
|
|
34
37
|
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl });
|
|
35
38
|
const script = useScriptYouTubePlayer({
|
|
36
39
|
scriptOptions: {
|
|
40
|
+
// Use immediate trigger so script loads when ANY player needs it
|
|
41
|
+
// Each player will wait for its own trigger before creating iframe
|
|
37
42
|
trigger
|
|
38
43
|
}
|
|
39
44
|
});
|
|
40
45
|
const { onLoaded, status } = script;
|
|
41
46
|
const player = ref();
|
|
42
|
-
|
|
43
|
-
if (
|
|
47
|
+
const clickTriggered = ref(false);
|
|
48
|
+
if (trigger instanceof Promise) {
|
|
44
49
|
trigger.then((triggered) => {
|
|
45
50
|
if (triggered) {
|
|
46
|
-
|
|
51
|
+
isTriggered.value = true;
|
|
52
|
+
if (props.trigger === "mousedown") {
|
|
53
|
+
clickTriggered.value = true;
|
|
54
|
+
}
|
|
47
55
|
}
|
|
48
56
|
});
|
|
57
|
+
} else {
|
|
58
|
+
isTriggered.value = true;
|
|
49
59
|
}
|
|
60
|
+
const stopVideoIdWatch = watch(() => props.videoId, (newId) => {
|
|
61
|
+
if (ready.value && player.value) {
|
|
62
|
+
player.value.loadVideoById(newId);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
onBeforeUnmount(() => {
|
|
66
|
+
stopVideoIdWatch();
|
|
67
|
+
player.value?.destroy();
|
|
68
|
+
});
|
|
50
69
|
onMounted(() => {
|
|
51
70
|
onLoaded(async (instance) => {
|
|
71
|
+
if (!isTriggered.value && trigger instanceof Promise) {
|
|
72
|
+
const triggered = await trigger;
|
|
73
|
+
if (!triggered) return;
|
|
74
|
+
}
|
|
75
|
+
if (!youtubeEl.value) return;
|
|
52
76
|
const YouTube = instance.YT instanceof Promise ? await instance.YT : instance.YT;
|
|
53
77
|
await new Promise((resolve) => {
|
|
54
78
|
if (typeof YT.Player === "undefined")
|
|
@@ -56,22 +80,23 @@ onMounted(() => {
|
|
|
56
80
|
else
|
|
57
81
|
resolve();
|
|
58
82
|
});
|
|
83
|
+
if (!youtubeEl.value) return;
|
|
59
84
|
player.value = new YT.Player(youtubeEl.value, {
|
|
60
85
|
host: !props.cookies ? "https://www.youtube-nocookie.com" : "https://www.youtube.com",
|
|
61
|
-
|
|
86
|
+
videoId: props.videoId,
|
|
87
|
+
width: props.width,
|
|
88
|
+
height: props.height,
|
|
89
|
+
playerVars: props.playerVars,
|
|
62
90
|
...props.playerOptions,
|
|
63
91
|
events: Object.fromEntries(events.map((event) => [event, (e) => {
|
|
64
92
|
const emitEventName = event.replace(/([A-Z])/g, "-$1").replace("on-", "").toLowerCase();
|
|
65
93
|
emits(emitEventName, e);
|
|
66
94
|
if (event === "onReady") {
|
|
67
95
|
ready.value = true;
|
|
68
|
-
if (clickTriggered) {
|
|
96
|
+
if (clickTriggered.value) {
|
|
69
97
|
player.value?.playVideo();
|
|
70
|
-
clickTriggered = false;
|
|
98
|
+
clickTriggered.value = false;
|
|
71
99
|
}
|
|
72
|
-
watch(() => props.videoId, () => {
|
|
73
|
-
player.value?.loadVideoById(props.videoId);
|
|
74
|
-
});
|
|
75
100
|
}
|
|
76
101
|
}]))
|
|
77
102
|
});
|
|
@@ -96,7 +121,7 @@ const rootAttrs = computed(() => {
|
|
|
96
121
|
position: "relative",
|
|
97
122
|
backgroundColor: "black",
|
|
98
123
|
width: "100%",
|
|
99
|
-
aspectRatio:
|
|
124
|
+
aspectRatio: props.ratio
|
|
100
125
|
},
|
|
101
126
|
...trigger instanceof Promise ? trigger.ssrAttrs || {} : {}
|
|
102
127
|
});
|
|
@@ -108,12 +133,12 @@ if (import.meta.server) {
|
|
|
108
133
|
useHead({
|
|
109
134
|
link: [
|
|
110
135
|
{
|
|
111
|
-
key:
|
|
136
|
+
key: "nuxt-script-youtube-img-preconnect",
|
|
112
137
|
rel: props.aboveTheFold ? "preconnect" : "dns-prefetch",
|
|
113
138
|
href: "https://i.ytimg.com"
|
|
114
139
|
},
|
|
115
140
|
props.aboveTheFold ? {
|
|
116
|
-
key: `nuxt-script-youtube-img`,
|
|
141
|
+
key: `nuxt-script-youtube-img-preload-${props.videoId}`,
|
|
117
142
|
rel: "preload",
|
|
118
143
|
as: "image",
|
|
119
144
|
href: placeholder.value
|
|
@@ -128,7 +153,7 @@ const placeholderAttrs = computed(() => {
|
|
|
128
153
|
loading: props.aboveTheFold ? "eager" : "lazy",
|
|
129
154
|
style: {
|
|
130
155
|
width: "100%",
|
|
131
|
-
objectFit:
|
|
156
|
+
objectFit: props.placeholderObjectFit,
|
|
132
157
|
height: "100%"
|
|
133
158
|
},
|
|
134
159
|
onLoad(payload) {
|
|
@@ -10,6 +10,7 @@ type __VLS_Props = {
|
|
|
10
10
|
playerVars?: YT.PlayerVars;
|
|
11
11
|
width?: number;
|
|
12
12
|
height?: number;
|
|
13
|
+
ratio?: string;
|
|
13
14
|
/**
|
|
14
15
|
* Whether to use youtube-nocookie.com for embedding.
|
|
15
16
|
*
|
|
@@ -19,9 +20,15 @@ type __VLS_Props = {
|
|
|
19
20
|
playerOptions?: YT.PlayerOptions;
|
|
20
21
|
thumbnailSize?: YoutubeThumbnailSize;
|
|
21
22
|
webp?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Object-fit for the placeholder image.
|
|
25
|
+
*
|
|
26
|
+
* @default 'cover'
|
|
27
|
+
*/
|
|
28
|
+
placeholderObjectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
22
29
|
};
|
|
23
30
|
declare var __VLS_1: {
|
|
24
|
-
placeholder:
|
|
31
|
+
placeholder: string;
|
|
25
32
|
}, __VLS_3: {}, __VLS_10: {}, __VLS_12: {}, __VLS_14: {};
|
|
26
33
|
type __VLS_Slots = {} & {
|
|
27
34
|
placeholder?: (props: typeof __VLS_1) => any;
|
|
@@ -42,20 +49,24 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
42
49
|
"state-change": (e: YT.OnStateChangeEvent, target: YT.Player) => any;
|
|
43
50
|
"playback-quality-change": (e: YT.OnPlaybackQualityChangeEvent, target: YT.Player) => any;
|
|
44
51
|
"playback-rate-change": (e: YT.OnPlaybackRateChangeEvent, target: YT.Player) => any;
|
|
52
|
+
"api-change": (e: YT.PlayerEvent, target: YT.Player) => any;
|
|
45
53
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
46
54
|
onError?: ((e: YT.OnErrorEvent, target: YT.Player) => any) | undefined;
|
|
47
55
|
onReady?: ((e: YT.PlayerEvent) => any) | undefined;
|
|
48
56
|
"onState-change"?: ((e: YT.OnStateChangeEvent, target: YT.Player) => any) | undefined;
|
|
49
57
|
"onPlayback-quality-change"?: ((e: YT.OnPlaybackQualityChangeEvent, target: YT.Player) => any) | undefined;
|
|
50
58
|
"onPlayback-rate-change"?: ((e: YT.OnPlaybackRateChangeEvent, target: YT.Player) => any) | undefined;
|
|
59
|
+
"onApi-change"?: ((e: YT.PlayerEvent, target: YT.Player) => any) | undefined;
|
|
51
60
|
}>, {
|
|
52
61
|
trigger: ElementScriptTrigger;
|
|
53
62
|
width: number;
|
|
54
63
|
height: number;
|
|
55
64
|
playerVars: YT.PlayerVars;
|
|
65
|
+
ratio: string;
|
|
56
66
|
cookies: boolean;
|
|
57
67
|
thumbnailSize: YoutubeThumbnailSize;
|
|
58
68
|
webp: boolean;
|
|
69
|
+
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
59
70
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
60
71
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
61
72
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
2
|
import { useScript as _useScript } from "@unhead/vue/scripts";
|
|
3
|
-
import { reactive } from "vue";
|
|
4
|
-
import { onNuxtReady, useNuxtApp, useRuntimeConfig, injectHead } from "nuxt/app";
|
|
3
|
+
import { reactive, ref } from "vue";
|
|
4
|
+
import { onNuxtReady, useNuxtApp, useRuntimeConfig, injectHead, useHead } from "nuxt/app";
|
|
5
5
|
import { logger } from "../logger.js";
|
|
6
6
|
import { resolveTrigger } from "#build/nuxt-scripts-trigger-resolver";
|
|
7
7
|
function useNuxtScriptRuntimeConfig() {
|
|
@@ -13,6 +13,27 @@ export function resolveScriptKey(input) {
|
|
|
13
13
|
export function useScript(input, options) {
|
|
14
14
|
input = typeof input === "string" ? { src: input } : input;
|
|
15
15
|
options = defu(options, useNuxtScriptRuntimeConfig()?.defaultScriptOptions);
|
|
16
|
+
if (options.partytown) {
|
|
17
|
+
const src = input.src;
|
|
18
|
+
if (!src) {
|
|
19
|
+
throw new Error("useScript with partytown requires a src");
|
|
20
|
+
}
|
|
21
|
+
useHead({
|
|
22
|
+
script: [{ src, type: "text/partytown" }]
|
|
23
|
+
});
|
|
24
|
+
const nuxtApp2 = useNuxtApp();
|
|
25
|
+
nuxtApp2.$scripts = nuxtApp2.$scripts || reactive({});
|
|
26
|
+
const status = ref("loaded");
|
|
27
|
+
const stub = {
|
|
28
|
+
id: src,
|
|
29
|
+
status,
|
|
30
|
+
load: () => Promise.resolve({}),
|
|
31
|
+
remove: () => false,
|
|
32
|
+
entry: void 0
|
|
33
|
+
};
|
|
34
|
+
nuxtApp2.$scripts[src] = stub;
|
|
35
|
+
return stub;
|
|
36
|
+
}
|
|
16
37
|
if (import.meta.dev && options.bundle === "unsupported") {
|
|
17
38
|
console.warn("[Nuxt Scripts] Bundling is not supported for dynamic script sources. Static URLs are required for bundling.");
|
|
18
39
|
options.bundle = false;
|
|
@@ -23,8 +44,8 @@ export function useScript(input, options) {
|
|
|
23
44
|
options.trigger = resolved;
|
|
24
45
|
}
|
|
25
46
|
}
|
|
26
|
-
const id = String(resolveScriptKey(input));
|
|
27
47
|
const nuxtApp = useNuxtApp();
|
|
48
|
+
const id = String(resolveScriptKey(input));
|
|
28
49
|
options.head = options.head || injectHead();
|
|
29
50
|
if (!options.head) {
|
|
30
51
|
throw new Error("useScript() has been called without Nuxt context.");
|
|
@@ -65,6 +86,16 @@ export function useScript(input, options) {
|
|
|
65
86
|
}
|
|
66
87
|
return _load();
|
|
67
88
|
};
|
|
89
|
+
instance.reload = async () => {
|
|
90
|
+
instance.remove();
|
|
91
|
+
const reloadInput = typeof input === "string" ? { src: input, key: `${id}-${Date.now()}` } : { ...input, key: `${id}-${Date.now()}` };
|
|
92
|
+
const reloaded = _useScript(reloadInput, { ...options, trigger: "client" });
|
|
93
|
+
Object.assign(instance, {
|
|
94
|
+
status: reloaded.status,
|
|
95
|
+
entry: reloaded.entry
|
|
96
|
+
});
|
|
97
|
+
return reloaded.load();
|
|
98
|
+
};
|
|
68
99
|
nuxtApp.$scripts[id] = instance;
|
|
69
100
|
if (import.meta.dev && import.meta.client) {
|
|
70
101
|
let syncScripts = function() {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a trigger that loads a script after the service worker is controlling the page.
|
|
3
|
+
* Falls back to immediate loading if service workers are not supported or after timeout.
|
|
4
|
+
*/
|
|
5
|
+
export declare function useScriptTriggerServiceWorker(options?: {
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}): Promise<boolean>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { tryOnScopeDispose } from "@vueuse/shared";
|
|
2
|
+
export function useScriptTriggerServiceWorker(options) {
|
|
3
|
+
if (import.meta.server)
|
|
4
|
+
return new Promise(() => {
|
|
5
|
+
});
|
|
6
|
+
const timeout = options?.timeout ?? 3e3;
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
if (!("serviceWorker" in navigator)) {
|
|
9
|
+
resolve(true);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
let resolved = false;
|
|
13
|
+
const done = () => {
|
|
14
|
+
if (resolved)
|
|
15
|
+
return;
|
|
16
|
+
resolved = true;
|
|
17
|
+
resolve(true);
|
|
18
|
+
};
|
|
19
|
+
if (navigator.serviceWorker.controller) {
|
|
20
|
+
done();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const onControllerChange = () => {
|
|
24
|
+
navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
|
|
25
|
+
done();
|
|
26
|
+
};
|
|
27
|
+
navigator.serviceWorker.addEventListener("controllerchange", onControllerChange);
|
|
28
|
+
const timer = setTimeout(() => {
|
|
29
|
+
navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
|
|
30
|
+
console.warn("[nuxt-scripts] Service worker not controlling after timeout, loading scripts anyway");
|
|
31
|
+
done();
|
|
32
|
+
}, timeout);
|
|
33
|
+
tryOnScopeDispose(() => {
|
|
34
|
+
navigator.serviceWorker.removeEventListener("controllerchange", onControllerChange);
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
resolve(false);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|