@nuxt/scripts 0.11.0 → 0.11.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 +71 -71
- package/dist/client/200.html +9 -9
- package/dist/client/404.html +9 -9
- package/dist/client/_nuxt/BwTzWwlf.js +21 -0
- package/dist/client/_nuxt/{BSA2bgdb.js → CJaqyBTv.js} +1 -1
- package/dist/client/_nuxt/{CtQNcfGE.js → XZaFTD3R.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/ccdd3650-9466-4597-a4e4-6464577f0b3e.json +1 -0
- package/dist/client/_nuxt/{entry.ipQkUTQD.css → entry.CJckMUzn.css} +1 -1
- package/dist/client/_nuxt/error-404.kHO_CZtx.css +1 -0
- package/dist/client/_nuxt/error-500.CICk5yq7.css +1 -0
- package/dist/client/_nuxt/{BFM-Ncmx.js → gy_iwf94.js} +1 -1
- package/dist/client/index.html +9 -9
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -1
- package/dist/runtime/components/ScriptAriaLoadingIndicator.vue +5 -5
- package/dist/runtime/components/ScriptCarbonAds.vue +83 -83
- package/dist/runtime/components/ScriptCrisp.vue +94 -94
- package/dist/runtime/components/ScriptGoogleAdsense.vue +93 -93
- package/dist/runtime/components/ScriptGoogleMaps.vue +470 -469
- package/dist/runtime/components/ScriptIntercom.vue +103 -103
- package/dist/runtime/components/ScriptLemonSqueezy.vue +52 -52
- package/dist/runtime/components/ScriptLoadingIndicator.vue +22 -22
- package/dist/runtime/components/ScriptStripePricingTable.vue +74 -74
- package/dist/runtime/components/ScriptVimeoPlayer.vue +288 -289
- package/dist/runtime/components/ScriptYouTubePlayer.vue +215 -215
- package/dist/runtime/composables/useScript.d.ts +1 -5
- package/dist/runtime/composables/useScriptEventPage.js +1 -2
- package/dist/runtime/registry/clarity.d.ts +1 -1
- package/dist/runtime/registry/cloudflare-web-analytics.d.ts +1 -1
- package/dist/runtime/registry/google-adsense.js +1 -1
- package/dist/runtime/registry/google-maps.d.ts +1 -1
- package/dist/runtime/registry/google-maps.js +4 -2
- package/dist/runtime/types.d.ts +6 -10
- package/dist/runtime/utils.d.ts +2 -2
- package/dist/runtime/utils.js +1 -1
- package/dist/runtime/validation/mock.d.ts +13 -13
- package/dist/runtime/validation/mock.js +7 -1
- package/package.json +11 -11
- package/dist/client/_nuxt/DuCkB5R-.js +0 -21
- package/dist/client/_nuxt/builds/meta/e03354ab-f2ce-4d6b-8542-7b38262b3671.json +0 -1
- package/dist/client/_nuxt/error-404.BdjopNsg.css +0 -1
- package/dist/client/_nuxt/error-500.Bd7Z7Q7I.css +0 -1
|
@@ -1,215 +1,215 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
-
// @ts-nocheck
|
|
4
|
-
|
|
5
|
-
/// <reference types="youtube" />
|
|
6
|
-
import { computed, onMounted, ref, watch } from 'vue'
|
|
7
|
-
import type { HTMLAttributes, ImgHTMLAttributes, Ref } from 'vue'
|
|
8
|
-
import { defu } from 'defu'
|
|
9
|
-
import { useHead } from '
|
|
10
|
-
import type { ElementScriptTrigger } from '../types'
|
|
11
|
-
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
12
|
-
import { useScriptYouTubePlayer } from '../registry/youtube-player'
|
|
13
|
-
import ScriptAriaLoadingIndicator from './ScriptAriaLoadingIndicator.vue'
|
|
14
|
-
|
|
15
|
-
export type YoutubeThumbnailSize =
|
|
16
|
-
// 120x90
|
|
17
|
-
'1' | '2' | '3' | 'default' |
|
|
18
|
-
// 320x180
|
|
19
|
-
'mq1' | 'mq2' | 'mq3' | 'mqdefault' |
|
|
20
|
-
// 480x360
|
|
21
|
-
'0' | 'hq1' | 'hq2' | 'hq3' | 'hqdefault' |
|
|
22
|
-
// 640x480
|
|
23
|
-
'sd1' | 'sd2' | 'sd3' | 'sddefault' |
|
|
24
|
-
// 1280x720
|
|
25
|
-
'hq720' |
|
|
26
|
-
// 1920x1080
|
|
27
|
-
'maxresdefault'
|
|
28
|
-
|
|
29
|
-
const props = withDefaults(defineProps<{
|
|
30
|
-
placeholderAttrs?: ImgHTMLAttributes
|
|
31
|
-
rootAttrs?: HTMLAttributes
|
|
32
|
-
aboveTheFold?: boolean
|
|
33
|
-
trigger?: ElementScriptTrigger
|
|
34
|
-
videoId: string
|
|
35
|
-
playerVars?: YT.PlayerVars
|
|
36
|
-
width?: number
|
|
37
|
-
height?: number
|
|
38
|
-
/**
|
|
39
|
-
* Whether to use youtube-nocookie.com for embedding.
|
|
40
|
-
*
|
|
41
|
-
* @default false
|
|
42
|
-
*/
|
|
43
|
-
cookies?: boolean
|
|
44
|
-
playerOptions?: YT.PlayerOptions
|
|
45
|
-
thumbnailSize?: YoutubeThumbnailSize
|
|
46
|
-
webp?: boolean
|
|
47
|
-
}>(), {
|
|
48
|
-
cookies: false,
|
|
49
|
-
trigger: 'mousedown',
|
|
50
|
-
thumbnailSize: 'hq720',
|
|
51
|
-
webp: true,
|
|
52
|
-
// @ts-expect-error untyped
|
|
53
|
-
playerVars: { autoplay: 0, playsinline: 1 },
|
|
54
|
-
width: 640,
|
|
55
|
-
height: 360,
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
const emits = defineEmits<{
|
|
59
|
-
'ready': [e: YT.PlayerEvent]
|
|
60
|
-
'state-change': [e: YT.OnStateChangeEvent, target: YT.Player]
|
|
61
|
-
'playback-quality-change': [e: YT.OnPlaybackQualityChangeEvent, target: YT.Player]
|
|
62
|
-
'playback-rate-change': [e: YT.OnPlaybackRateChangeEvent, target: YT.Player]
|
|
63
|
-
'error': [e: YT.OnErrorEvent, target: YT.Player]
|
|
64
|
-
}>()
|
|
65
|
-
const events: (keyof YT.Events)[] = [
|
|
66
|
-
'onReady',
|
|
67
|
-
'onStateChange',
|
|
68
|
-
'onPlaybackQualityChange',
|
|
69
|
-
'onPlaybackRateChange',
|
|
70
|
-
'onError',
|
|
71
|
-
'onApiChange',
|
|
72
|
-
]
|
|
73
|
-
const rootEl = ref()
|
|
74
|
-
const youtubeEl = ref()
|
|
75
|
-
const ready = ref(false)
|
|
76
|
-
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
|
|
77
|
-
const script = useScriptYouTubePlayer({
|
|
78
|
-
scriptOptions: {
|
|
79
|
-
trigger,
|
|
80
|
-
},
|
|
81
|
-
})
|
|
82
|
-
const { onLoaded, status } = script
|
|
83
|
-
|
|
84
|
-
const player: Ref<YT.Player | undefined> = ref()
|
|
85
|
-
let clickTriggered = false
|
|
86
|
-
if (props.trigger === 'mousedown' && trigger instanceof Promise) {
|
|
87
|
-
trigger.then((triggered) => {
|
|
88
|
-
if (triggered) {
|
|
89
|
-
clickTriggered = true
|
|
90
|
-
}
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
onMounted(() => {
|
|
94
|
-
onLoaded(async (instance) => {
|
|
95
|
-
const YouTube = instance.YT instanceof Promise ? await instance.YT : instance.YT
|
|
96
|
-
await new Promise<void>((resolve) => {
|
|
97
|
-
if (typeof YT.Player === 'undefined')
|
|
98
|
-
YouTube.ready(resolve)
|
|
99
|
-
else
|
|
100
|
-
resolve()
|
|
101
|
-
})
|
|
102
|
-
player.value = new YT.Player(youtubeEl.value, {
|
|
103
|
-
host: !props.cookies ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com',
|
|
104
|
-
...props,
|
|
105
|
-
...props.playerOptions,
|
|
106
|
-
events: Object.fromEntries(events.map(event => [event, (e: any) => {
|
|
107
|
-
const emitEventName = event.replace(/([A-Z])/g, '-$1').replace('on-', '').toLowerCase()
|
|
108
|
-
// @ts-expect-error untyped
|
|
109
|
-
emits(emitEventName, e)
|
|
110
|
-
if (event === 'onReady') {
|
|
111
|
-
ready.value = true
|
|
112
|
-
if (clickTriggered) {
|
|
113
|
-
player.value?.playVideo()
|
|
114
|
-
clickTriggered = false
|
|
115
|
-
}
|
|
116
|
-
watch(() => props.videoId, () => {
|
|
117
|
-
player.value?.loadVideoById(props.videoId)
|
|
118
|
-
})
|
|
119
|
-
}
|
|
120
|
-
}])),
|
|
121
|
-
})
|
|
122
|
-
})
|
|
123
|
-
watch(status, (status) => {
|
|
124
|
-
if (status === 'error') {
|
|
125
|
-
// @ts-expect-error untyped
|
|
126
|
-
emits('error')
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
defineExpose({
|
|
132
|
-
player,
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
const rootAttrs = computed(() => {
|
|
136
|
-
return defu(props.rootAttrs, {
|
|
137
|
-
'aria-busy': status.value === 'loading',
|
|
138
|
-
'aria-label': status.value === 'awaitingLoad'
|
|
139
|
-
? 'YouTube Player - Placeholder'
|
|
140
|
-
: status.value === 'loading'
|
|
141
|
-
? 'YouTube Player - Loading'
|
|
142
|
-
: 'YouTube Player - Loaded',
|
|
143
|
-
'aria-live': 'polite',
|
|
144
|
-
'role': 'application',
|
|
145
|
-
'style': {
|
|
146
|
-
cursor: 'pointer',
|
|
147
|
-
position: 'relative',
|
|
148
|
-
backgroundColor: 'black',
|
|
149
|
-
width: '100%',
|
|
150
|
-
aspectRatio: `${props.width}/${props.height}`,
|
|
151
|
-
},
|
|
152
|
-
...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}),
|
|
153
|
-
}) as HTMLAttributes
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
const fallbackPlaceHolder = computed(() => `https://i.ytimg.com/vi/${props.videoId}/hqdefault.jpg`)
|
|
157
|
-
const placeholder = computed(() => `https://i.ytimg.com/${props.webp ? 'vi_webp' : 'vi'}/${props.videoId}/${props.thumbnailSize}.${props.webp ? 'webp' : 'jpg'}`)
|
|
158
|
-
const isFallbackPlaceHolder = ref(false)
|
|
159
|
-
|
|
160
|
-
if (import.meta.server) {
|
|
161
|
-
// dns-prefetch https://i.vimeocdn.com
|
|
162
|
-
useHead({
|
|
163
|
-
link: [
|
|
164
|
-
{
|
|
165
|
-
key: `nuxt-script-youtube-img`,
|
|
166
|
-
rel: props.aboveTheFold ? 'preconnect' : 'dns-prefetch',
|
|
167
|
-
href: 'https://i.ytimg.com',
|
|
168
|
-
},
|
|
169
|
-
props.aboveTheFold
|
|
170
|
-
// we can preload the placeholder image
|
|
171
|
-
? {
|
|
172
|
-
key: `nuxt-script-youtube-img`,
|
|
173
|
-
rel: 'preload',
|
|
174
|
-
as: 'image',
|
|
175
|
-
href: placeholder.value,
|
|
176
|
-
}
|
|
177
|
-
: {},
|
|
178
|
-
],
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const placeholderAttrs = computed(() => {
|
|
183
|
-
return defu(props.placeholderAttrs, {
|
|
184
|
-
src: isFallbackPlaceHolder.value ? fallbackPlaceHolder.value : placeholder.value,
|
|
185
|
-
alt: '',
|
|
186
|
-
loading: props.aboveTheFold ? 'eager' : 'lazy',
|
|
187
|
-
style: {
|
|
188
|
-
width: '100%',
|
|
189
|
-
objectFit: 'contain',
|
|
190
|
-
height: '100%',
|
|
191
|
-
},
|
|
192
|
-
onLoad(payload) {
|
|
193
|
-
const img = payload.target as HTMLImageElement
|
|
194
|
-
if (img.naturalWidth === 120 && img.naturalHeight === 90) {
|
|
195
|
-
isFallbackPlaceHolder.value = true
|
|
196
|
-
}
|
|
197
|
-
},
|
|
198
|
-
} satisfies ImgHTMLAttributes)
|
|
199
|
-
})
|
|
200
|
-
</script>
|
|
201
|
-
|
|
202
|
-
<template>
|
|
203
|
-
<div ref="rootEl" v-bind="rootAttrs">
|
|
204
|
-
<div ref="youtubeEl" style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;" />
|
|
205
|
-
<slot v-if="!ready" :placeholder="placeholder" name="placeholder">
|
|
206
|
-
<img v-bind="placeholderAttrs">
|
|
207
|
-
</slot>
|
|
208
|
-
<slot v-if="status === 'loading'" name="loading">
|
|
209
|
-
<ScriptAriaLoadingIndicator />
|
|
210
|
-
</slot>
|
|
211
|
-
<slot v-if="status === 'awaitingLoad'" name="awaitingLoad" />
|
|
212
|
-
<slot v-else-if="status === 'error'" name="error" />
|
|
213
|
-
<slot />
|
|
214
|
-
</div>
|
|
215
|
-
</template>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
|
|
5
|
+
/// <reference types="youtube" />
|
|
6
|
+
import { computed, onMounted, ref, watch } from 'vue'
|
|
7
|
+
import type { HTMLAttributes, ImgHTMLAttributes, Ref } from 'vue'
|
|
8
|
+
import { defu } from 'defu'
|
|
9
|
+
import { useHead } from 'nuxt/app'
|
|
10
|
+
import type { ElementScriptTrigger } from '../types'
|
|
11
|
+
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
12
|
+
import { useScriptYouTubePlayer } from '../registry/youtube-player'
|
|
13
|
+
import ScriptAriaLoadingIndicator from './ScriptAriaLoadingIndicator.vue'
|
|
14
|
+
|
|
15
|
+
export type YoutubeThumbnailSize =
|
|
16
|
+
// 120x90
|
|
17
|
+
'1' | '2' | '3' | 'default' |
|
|
18
|
+
// 320x180
|
|
19
|
+
'mq1' | 'mq2' | 'mq3' | 'mqdefault' |
|
|
20
|
+
// 480x360
|
|
21
|
+
'0' | 'hq1' | 'hq2' | 'hq3' | 'hqdefault' |
|
|
22
|
+
// 640x480
|
|
23
|
+
'sd1' | 'sd2' | 'sd3' | 'sddefault' |
|
|
24
|
+
// 1280x720
|
|
25
|
+
'hq720' |
|
|
26
|
+
// 1920x1080
|
|
27
|
+
'maxresdefault'
|
|
28
|
+
|
|
29
|
+
const props = withDefaults(defineProps<{
|
|
30
|
+
placeholderAttrs?: ImgHTMLAttributes
|
|
31
|
+
rootAttrs?: HTMLAttributes
|
|
32
|
+
aboveTheFold?: boolean
|
|
33
|
+
trigger?: ElementScriptTrigger
|
|
34
|
+
videoId: string
|
|
35
|
+
playerVars?: YT.PlayerVars
|
|
36
|
+
width?: number
|
|
37
|
+
height?: number
|
|
38
|
+
/**
|
|
39
|
+
* Whether to use youtube-nocookie.com for embedding.
|
|
40
|
+
*
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
cookies?: boolean
|
|
44
|
+
playerOptions?: YT.PlayerOptions
|
|
45
|
+
thumbnailSize?: YoutubeThumbnailSize
|
|
46
|
+
webp?: boolean
|
|
47
|
+
}>(), {
|
|
48
|
+
cookies: false,
|
|
49
|
+
trigger: 'mousedown',
|
|
50
|
+
thumbnailSize: 'hq720',
|
|
51
|
+
webp: true,
|
|
52
|
+
// @ts-expect-error untyped
|
|
53
|
+
playerVars: { autoplay: 0, playsinline: 1 },
|
|
54
|
+
width: 640,
|
|
55
|
+
height: 360,
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
const emits = defineEmits<{
|
|
59
|
+
'ready': [e: YT.PlayerEvent]
|
|
60
|
+
'state-change': [e: YT.OnStateChangeEvent, target: YT.Player]
|
|
61
|
+
'playback-quality-change': [e: YT.OnPlaybackQualityChangeEvent, target: YT.Player]
|
|
62
|
+
'playback-rate-change': [e: YT.OnPlaybackRateChangeEvent, target: YT.Player]
|
|
63
|
+
'error': [e: YT.OnErrorEvent, target: YT.Player]
|
|
64
|
+
}>()
|
|
65
|
+
const events: (keyof YT.Events)[] = [
|
|
66
|
+
'onReady',
|
|
67
|
+
'onStateChange',
|
|
68
|
+
'onPlaybackQualityChange',
|
|
69
|
+
'onPlaybackRateChange',
|
|
70
|
+
'onError',
|
|
71
|
+
'onApiChange',
|
|
72
|
+
]
|
|
73
|
+
const rootEl = ref()
|
|
74
|
+
const youtubeEl = ref()
|
|
75
|
+
const ready = ref(false)
|
|
76
|
+
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
|
|
77
|
+
const script = useScriptYouTubePlayer({
|
|
78
|
+
scriptOptions: {
|
|
79
|
+
trigger,
|
|
80
|
+
},
|
|
81
|
+
})
|
|
82
|
+
const { onLoaded, status } = script
|
|
83
|
+
|
|
84
|
+
const player: Ref<YT.Player | undefined> = ref()
|
|
85
|
+
let clickTriggered = false
|
|
86
|
+
if (props.trigger === 'mousedown' && trigger instanceof Promise) {
|
|
87
|
+
trigger.then((triggered) => {
|
|
88
|
+
if (triggered) {
|
|
89
|
+
clickTriggered = true
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
onMounted(() => {
|
|
94
|
+
onLoaded(async (instance) => {
|
|
95
|
+
const YouTube = instance.YT instanceof Promise ? await instance.YT : instance.YT
|
|
96
|
+
await new Promise<void>((resolve) => {
|
|
97
|
+
if (typeof YT.Player === 'undefined')
|
|
98
|
+
YouTube.ready(resolve)
|
|
99
|
+
else
|
|
100
|
+
resolve()
|
|
101
|
+
})
|
|
102
|
+
player.value = new YT.Player(youtubeEl.value, {
|
|
103
|
+
host: !props.cookies ? 'https://www.youtube-nocookie.com' : 'https://www.youtube.com',
|
|
104
|
+
...props,
|
|
105
|
+
...props.playerOptions,
|
|
106
|
+
events: Object.fromEntries(events.map(event => [event, (e: any) => {
|
|
107
|
+
const emitEventName = event.replace(/([A-Z])/g, '-$1').replace('on-', '').toLowerCase()
|
|
108
|
+
// @ts-expect-error untyped
|
|
109
|
+
emits(emitEventName, e)
|
|
110
|
+
if (event === 'onReady') {
|
|
111
|
+
ready.value = true
|
|
112
|
+
if (clickTriggered) {
|
|
113
|
+
player.value?.playVideo()
|
|
114
|
+
clickTriggered = false
|
|
115
|
+
}
|
|
116
|
+
watch(() => props.videoId, () => {
|
|
117
|
+
player.value?.loadVideoById(props.videoId)
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
}])),
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
watch(status, (status) => {
|
|
124
|
+
if (status === 'error') {
|
|
125
|
+
// @ts-expect-error untyped
|
|
126
|
+
emits('error')
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
defineExpose({
|
|
132
|
+
player,
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
const rootAttrs = computed(() => {
|
|
136
|
+
return defu(props.rootAttrs, {
|
|
137
|
+
'aria-busy': status.value === 'loading',
|
|
138
|
+
'aria-label': status.value === 'awaitingLoad'
|
|
139
|
+
? 'YouTube Player - Placeholder'
|
|
140
|
+
: status.value === 'loading'
|
|
141
|
+
? 'YouTube Player - Loading'
|
|
142
|
+
: 'YouTube Player - Loaded',
|
|
143
|
+
'aria-live': 'polite',
|
|
144
|
+
'role': 'application',
|
|
145
|
+
'style': {
|
|
146
|
+
cursor: 'pointer',
|
|
147
|
+
position: 'relative',
|
|
148
|
+
backgroundColor: 'black',
|
|
149
|
+
width: '100%',
|
|
150
|
+
aspectRatio: `${props.width}/${props.height}`,
|
|
151
|
+
},
|
|
152
|
+
...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}),
|
|
153
|
+
}) as HTMLAttributes
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
const fallbackPlaceHolder = computed(() => `https://i.ytimg.com/vi/${props.videoId}/hqdefault.jpg`)
|
|
157
|
+
const placeholder = computed(() => `https://i.ytimg.com/${props.webp ? 'vi_webp' : 'vi'}/${props.videoId}/${props.thumbnailSize}.${props.webp ? 'webp' : 'jpg'}`)
|
|
158
|
+
const isFallbackPlaceHolder = ref(false)
|
|
159
|
+
|
|
160
|
+
if (import.meta.server) {
|
|
161
|
+
// dns-prefetch https://i.vimeocdn.com
|
|
162
|
+
useHead({
|
|
163
|
+
link: [
|
|
164
|
+
{
|
|
165
|
+
key: `nuxt-script-youtube-img`,
|
|
166
|
+
rel: props.aboveTheFold ? 'preconnect' : 'dns-prefetch',
|
|
167
|
+
href: 'https://i.ytimg.com',
|
|
168
|
+
},
|
|
169
|
+
props.aboveTheFold
|
|
170
|
+
// we can preload the placeholder image
|
|
171
|
+
? {
|
|
172
|
+
key: `nuxt-script-youtube-img`,
|
|
173
|
+
rel: 'preload',
|
|
174
|
+
as: 'image',
|
|
175
|
+
href: placeholder.value,
|
|
176
|
+
}
|
|
177
|
+
: {},
|
|
178
|
+
],
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const placeholderAttrs = computed(() => {
|
|
183
|
+
return defu(props.placeholderAttrs, {
|
|
184
|
+
src: isFallbackPlaceHolder.value ? fallbackPlaceHolder.value : placeholder.value,
|
|
185
|
+
alt: '',
|
|
186
|
+
loading: props.aboveTheFold ? 'eager' : 'lazy',
|
|
187
|
+
style: {
|
|
188
|
+
width: '100%',
|
|
189
|
+
objectFit: 'contain',
|
|
190
|
+
height: '100%',
|
|
191
|
+
},
|
|
192
|
+
onLoad(payload) {
|
|
193
|
+
const img = payload.target as HTMLImageElement
|
|
194
|
+
if (img.naturalWidth === 120 && img.naturalHeight === 90) {
|
|
195
|
+
isFallbackPlaceHolder.value = true
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
} satisfies ImgHTMLAttributes)
|
|
199
|
+
})
|
|
200
|
+
</script>
|
|
201
|
+
|
|
202
|
+
<template>
|
|
203
|
+
<div ref="rootEl" v-bind="rootAttrs">
|
|
204
|
+
<div ref="youtubeEl" style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;" />
|
|
205
|
+
<slot v-if="!ready" :placeholder="placeholder" name="placeholder">
|
|
206
|
+
<img v-bind="placeholderAttrs">
|
|
207
|
+
</slot>
|
|
208
|
+
<slot v-if="status === 'loading'" name="loading">
|
|
209
|
+
<ScriptAriaLoadingIndicator />
|
|
210
|
+
</slot>
|
|
211
|
+
<slot v-if="status === 'awaitingLoad'" name="awaitingLoad" />
|
|
212
|
+
<slot v-else-if="status === 'error'" name="error" />
|
|
213
|
+
<slot />
|
|
214
|
+
</div>
|
|
215
|
+
</template>
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import type { UseScriptInput } from '@unhead/vue/scripts';
|
|
2
|
-
import type { NuxtUseScriptOptions, UseScriptContext } from '../types.js';
|
|
3
|
-
type UseFunctionType<T, U> = T extends {
|
|
4
|
-
use: infer V;
|
|
5
|
-
} ? V extends (...args: any) => any ? ReturnType<V> : U : U;
|
|
2
|
+
import type { NuxtUseScriptOptions, UseFunctionType, UseScriptContext } from '../types.js';
|
|
6
3
|
export declare function resolveScriptKey(input: any): string;
|
|
7
4
|
export declare function useScript<T extends Record<symbol | string, any> = Record<symbol | string, any>>(input: UseScriptInput, options?: NuxtUseScriptOptions<T>): UseScriptContext<UseFunctionType<NuxtUseScriptOptions<T>, T>>;
|
|
8
|
-
export {};
|
|
@@ -26,7 +26,7 @@ export declare const ClarityOptions: import("valibot").ObjectSchema<{
|
|
|
26
26
|
/**
|
|
27
27
|
* The Clarity token.
|
|
28
28
|
*/
|
|
29
|
-
readonly id: import("valibot").SchemaWithPipe<[import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 10, undefined>]>;
|
|
29
|
+
readonly id: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 10, undefined>]>;
|
|
30
30
|
}, undefined>;
|
|
31
31
|
export type ClarityInput = RegistryScriptInput<typeof ClarityOptions>;
|
|
32
32
|
export declare function useScriptClarity<T extends ClarityApi>(_options?: ClarityInput): import("#nuxt-scripts/types").UseScriptContext<T>;
|
|
@@ -20,7 +20,7 @@ export declare const CloudflareWebAnalyticsOptions: import("valibot").ObjectSche
|
|
|
20
20
|
/**
|
|
21
21
|
* The Cloudflare Web Analytics token.
|
|
22
22
|
*/
|
|
23
|
-
readonly token: import("valibot").SchemaWithPipe<[import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 32, undefined>]>;
|
|
23
|
+
readonly token: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MinLengthAction<string, 32, undefined>]>;
|
|
24
24
|
/**
|
|
25
25
|
* Cloudflare Web Analytics enables measuring SPAs automatically by overriding the History API’s pushState function
|
|
26
26
|
* and listening to the onpopstate. Hash-based router is not supported.
|
|
@@ -4,7 +4,7 @@ export declare const GoogleMapsOptions: import("valibot").ObjectSchema<{
|
|
|
4
4
|
readonly libraries: import("valibot").OptionalSchema<import("valibot").ArraySchema<import("valibot").StringSchema<undefined>, undefined>, undefined>;
|
|
5
5
|
readonly language: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
6
6
|
readonly region: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
7
|
-
readonly v: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"weekly", undefined>, import("valibot").LiteralSchema<"beta", undefined>, import("valibot").LiteralSchema<"alpha", undefined>], undefined>, undefined>;
|
|
7
|
+
readonly v: import("valibot").OptionalSchema<import("valibot").UnionSchema<[import("valibot").LiteralSchema<"weekly", undefined>, import("valibot").LiteralSchema<"quarterly", undefined>, import("valibot").LiteralSchema<"beta", undefined>, import("valibot").LiteralSchema<"alpha", undefined>, import("valibot").StringSchema<undefined>], undefined>, undefined>;
|
|
8
8
|
}, undefined>;
|
|
9
9
|
export type GoogleMapsInput = RegistryScriptInput<typeof GoogleMapsOptions>;
|
|
10
10
|
type MapsNamespace = typeof window.google.maps;
|
|
@@ -6,7 +6,7 @@ export const GoogleMapsOptions = object({
|
|
|
6
6
|
libraries: optional(array(string())),
|
|
7
7
|
language: optional(string()),
|
|
8
8
|
region: optional(string()),
|
|
9
|
-
v: optional(union([literal("weekly"), literal("beta"), literal("alpha")]))
|
|
9
|
+
v: optional(union([literal("weekly"), literal("quarterly"), literal("beta"), literal("alpha"), string()]))
|
|
10
10
|
});
|
|
11
11
|
export function useScriptGoogleMaps(_options) {
|
|
12
12
|
let readyPromise = Promise.resolve();
|
|
@@ -14,6 +14,7 @@ export function useScriptGoogleMaps(_options) {
|
|
|
14
14
|
const libraries = options?.libraries || ["places"];
|
|
15
15
|
const language = options?.language ? { language: options.language } : void 0;
|
|
16
16
|
const region = options?.region ? { region: options.region } : void 0;
|
|
17
|
+
const version = options?.v ? { v: options.v } : void 0;
|
|
17
18
|
return {
|
|
18
19
|
scriptInput: {
|
|
19
20
|
src: withQuery(`https://maps.googleapis.com/maps/api/js`, {
|
|
@@ -22,7 +23,8 @@ export function useScriptGoogleMaps(_options) {
|
|
|
22
23
|
loading: "async",
|
|
23
24
|
callback: "google.maps.__ib__",
|
|
24
25
|
...language,
|
|
25
|
-
...region
|
|
26
|
+
...region,
|
|
27
|
+
...version
|
|
26
28
|
})
|
|
27
29
|
},
|
|
28
30
|
clientInit: import.meta.server ? void 0 : () => {
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Script } from '@unhead/vue/types';
|
|
2
2
|
import type { UseScriptInput, VueScriptInstance, UseScriptOptions } from '@unhead/vue';
|
|
3
3
|
import type { ComputedRef, Ref } from 'vue';
|
|
4
4
|
import type { InferInput, ObjectSchema } from 'valibot';
|
|
@@ -26,14 +26,7 @@ import type { GoogleAnalyticsInput } from './registry/google-analytics.js';
|
|
|
26
26
|
import type { GoogleTagManagerInput } from './registry/google-tag-manager.js';
|
|
27
27
|
import type { UmamiAnalyticsInput } from './registry/umami-analytics.js';
|
|
28
28
|
export type WarmupStrategy = false | 'preload' | 'preconnect' | 'dns-prefetch';
|
|
29
|
-
export type UseScriptContext<T extends Record<symbol | string, any>> =
|
|
30
|
-
/**
|
|
31
|
-
* @deprecated Use top-level functions instead.
|
|
32
|
-
*/
|
|
33
|
-
$script: Promise<T> & VueScriptInstance<T>;
|
|
34
|
-
warmup: (rel: WarmupStrategy) => void;
|
|
35
|
-
_warmupEl?: void | ActiveHeadEntry<any>;
|
|
36
|
-
};
|
|
29
|
+
export type UseScriptContext<T extends Record<symbol | string, any>> = VueScriptInstance<T>;
|
|
37
30
|
export type NuxtUseScriptOptions<T extends Record<symbol | string, any> = {}> = Omit<UseScriptOptions<T>, 'trigger'> & {
|
|
38
31
|
/**
|
|
39
32
|
* The trigger to load the script:
|
|
@@ -148,9 +141,12 @@ export type NuxtConfigScriptRegistryEntry<T> = true | 'mock' | T | [T, NuxtUseSc
|
|
|
148
141
|
export type NuxtConfigScriptRegistry<T extends keyof ScriptRegistry = keyof ScriptRegistry> = Partial<{
|
|
149
142
|
[key in T]: NuxtConfigScriptRegistryEntry<ScriptRegistry[key]>;
|
|
150
143
|
}>;
|
|
144
|
+
export type UseFunctionType<T, U> = T extends {
|
|
145
|
+
use: infer V;
|
|
146
|
+
} ? V extends (...args: any) => any ? ReturnType<V> : U : U;
|
|
151
147
|
declare const _emptyOptions: ObjectSchema<{}, undefined>;
|
|
152
148
|
export type EmptyOptionsSchema = typeof _emptyOptions;
|
|
153
|
-
type ScriptInput =
|
|
149
|
+
type ScriptInput = Script;
|
|
154
150
|
export type InferIfSchema<T> = T extends ObjectSchema<any, any> ? InferInput<T> : T;
|
|
155
151
|
export type RegistryScriptInput<T = EmptyOptionsSchema, Bundelable extends boolean = true, Usable extends boolean = false, CanBypassOptions extends boolean = true> = (InferIfSchema<T> & {
|
|
156
152
|
/**
|
package/dist/runtime/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ObjectSchema } from 'valibot';
|
|
2
2
|
import type { UseScriptInput } from '@unhead/vue';
|
|
3
|
-
import type { EmptyOptionsSchema, InferIfSchema, NuxtUseScriptOptions, RegistryScriptInput, ScriptRegistry } from '#nuxt-scripts/types';
|
|
3
|
+
import type { EmptyOptionsSchema, InferIfSchema, NuxtUseScriptOptions, RegistryScriptInput, UseFunctionType, ScriptRegistry, UseScriptContext } from '#nuxt-scripts/types';
|
|
4
4
|
export type MaybePromise<T> = Promise<T> | T;
|
|
5
5
|
type OptionsFn<O> = (options: InferIfSchema<O>) => ({
|
|
6
6
|
scriptInput?: UseScriptInput;
|
|
@@ -9,6 +9,6 @@ type OptionsFn<O> = (options: InferIfSchema<O>) => ({
|
|
|
9
9
|
clientInit?: () => void;
|
|
10
10
|
});
|
|
11
11
|
export declare function scriptRuntimeConfig<T extends keyof ScriptRegistry>(key: T): ScriptRegistry[T];
|
|
12
|
-
export declare function useRegistryScript<T extends Record<string | symbol, any>, O = EmptyOptionsSchema, U = {}>(registryKey: keyof ScriptRegistry | string, optionsFn: OptionsFn<O>, _userOptions?: RegistryScriptInput<O>):
|
|
12
|
+
export declare function useRegistryScript<T extends Record<string | symbol, any>, O = EmptyOptionsSchema, U = {}>(registryKey: keyof ScriptRegistry | string, optionsFn: OptionsFn<O>, _userOptions?: RegistryScriptInput<O>): UseScriptContext<UseFunctionType<NuxtUseScriptOptions<T>, T>>;
|
|
13
13
|
export declare function pick(obj: Record<string, any>, keys: string[]): Record<string, any>;
|
|
14
14
|
export {};
|
package/dist/runtime/utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
2
|
import { useRuntimeConfig } from "nuxt/app";
|
|
3
|
-
import { useScript } from "
|
|
3
|
+
import { useScript } from "./composables/useScript.js";
|
|
4
4
|
import { parse } from "#nuxt-scripts-validator";
|
|
5
5
|
function validateScriptInputSchema(key, schema, options) {
|
|
6
6
|
if (import.meta.dev) {
|
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
export declare const parse: (() => void) & {
|
|
2
|
-
|
|
2
|
+
__mock__: boolean;
|
|
3
3
|
};
|
|
4
4
|
export declare const object: (() => void) & {
|
|
5
|
-
|
|
5
|
+
__mock__: boolean;
|
|
6
6
|
};
|
|
7
7
|
export declare const array: (() => void) & {
|
|
8
|
-
|
|
8
|
+
__mock__: boolean;
|
|
9
9
|
};
|
|
10
10
|
export declare const string: (() => void) & {
|
|
11
|
-
|
|
11
|
+
__mock__: boolean;
|
|
12
12
|
};
|
|
13
13
|
export declare const number: (() => void) & {
|
|
14
|
-
|
|
14
|
+
__mock__: boolean;
|
|
15
15
|
};
|
|
16
16
|
export declare const boolean: (() => void) & {
|
|
17
|
-
|
|
17
|
+
__mock__: boolean;
|
|
18
18
|
};
|
|
19
19
|
export declare const optional: (() => void) & {
|
|
20
|
-
|
|
20
|
+
__mock__: boolean;
|
|
21
21
|
};
|
|
22
22
|
export declare const literal: (() => void) & {
|
|
23
|
-
|
|
23
|
+
__mock__: boolean;
|
|
24
24
|
};
|
|
25
25
|
export declare const union: (() => void) & {
|
|
26
|
-
|
|
26
|
+
__mock__: boolean;
|
|
27
27
|
};
|
|
28
28
|
export declare const record: (() => void) & {
|
|
29
|
-
|
|
29
|
+
__mock__: boolean;
|
|
30
30
|
};
|
|
31
31
|
export declare const any: (() => void) & {
|
|
32
|
-
|
|
32
|
+
__mock__: boolean;
|
|
33
33
|
};
|
|
34
34
|
export declare const minLength: (() => void) & {
|
|
35
|
-
|
|
35
|
+
__mock__: boolean;
|
|
36
36
|
};
|
|
37
37
|
export declare const pipe: (() => void) & {
|
|
38
|
-
|
|
38
|
+
__mock__: boolean;
|
|
39
39
|
};
|