@nuxt/scripts 0.7.1 → 0.8.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.md +73 -73
- package/dist/client/200.html +9 -9
- package/dist/client/404.html +9 -9
- package/dist/client/_nuxt/{C1IUq70_.js → B7a7KwY0.js} +1 -1
- package/dist/client/_nuxt/{DOi3Eb0n.js → BYm2jJpo.js} +11 -11
- package/dist/client/_nuxt/{iQqcKxZm.js → CEoS15Fi.js} +1 -1
- package/dist/client/_nuxt/{CnUvXFHd.js → Nd9uLa0s.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/ec7cd9b1-e776-4993-98a3-da039c5325b9.json +1 -0
- package/dist/client/_nuxt/{entry.FVeyw1Qn.css → entry.BAZUAl3s.css} +1 -1
- package/dist/client/_nuxt/error-404.ChzstOPh.css +1 -0
- package/dist/client/_nuxt/error-500.BaOmLlKq.css +1 -0
- package/dist/client/index.html +9 -9
- package/dist/module.d.mts +2 -2
- package/dist/module.d.ts +2 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +2 -0
- package/dist/runtime/components/ScriptCarbonAds.vue +78 -71
- package/dist/runtime/components/ScriptCrisp.vue +94 -87
- package/dist/runtime/components/ScriptGoogleAdsense.vue +75 -69
- package/dist/runtime/components/ScriptGoogleMaps.vue +457 -435
- package/dist/runtime/components/ScriptIntercom.vue +103 -96
- package/dist/runtime/components/ScriptLemonSqueezy.vue +52 -45
- package/dist/runtime/components/ScriptLoadingIndicator.vue +22 -22
- package/dist/runtime/components/ScriptStripePricingTable.vue +75 -68
- package/dist/runtime/components/ScriptVimeoPlayer.vue +281 -280
- package/dist/runtime/components/ScriptYouTubePlayer.vue +174 -171
- package/dist/runtime/composables/useScript.js +25 -7
- package/dist/runtime/composables/useScriptTriggerElement.d.ts +3 -1
- package/dist/runtime/composables/useScriptTriggerElement.js +46 -19
- package/dist/runtime/registry/google-adsense.js +11 -14
- package/dist/runtime/types.js +1 -1
- package/package.json +29 -28
- package/dist/client/_nuxt/builds/meta/e4092e18-9a58-41ab-947e-35e1f2082b75.json +0 -1
- package/dist/client/_nuxt/error-404.CHrXIISA.css +0 -1
- package/dist/client/_nuxt/error-500.CrsjMPPf.css +0 -1
|
@@ -1,171 +1,174 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
/// <reference types="youtube" />
|
|
3
|
-
import { computed, onMounted, ref, watch } from 'vue'
|
|
4
|
-
import type { HTMLAttributes, ImgHTMLAttributes, Ref } from 'vue'
|
|
5
|
-
import { defu } from 'defu'
|
|
6
|
-
import type { ElementScriptTrigger } from '../types'
|
|
7
|
-
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
8
|
-
import { useScriptYouTubePlayer } from '../registry/youtube-player'
|
|
9
|
-
import { useHead } from '#imports'
|
|
10
|
-
|
|
11
|
-
const props = withDefaults(defineProps<{
|
|
12
|
-
placeholderAttrs?: ImgHTMLAttributes
|
|
13
|
-
rootAttrs?: HTMLAttributes
|
|
14
|
-
aboveTheFold?: boolean
|
|
15
|
-
trigger?: ElementScriptTrigger
|
|
16
|
-
videoId: string
|
|
17
|
-
playerVars?: YT.PlayerVars
|
|
18
|
-
width?: number
|
|
19
|
-
height?: number
|
|
20
|
-
}>(), {
|
|
21
|
-
trigger: 'mousedown',
|
|
22
|
-
// @ts-expect-error untyped
|
|
23
|
-
playerVars: { autoplay: 0, playsinline: 1 },
|
|
24
|
-
width: 640,
|
|
25
|
-
height: 480,
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
const emits = defineEmits<{
|
|
29
|
-
'ready': [e: YT.PlayerEvent]
|
|
30
|
-
'state-change': [e: YT.OnStateChangeEvent, target: YT.Player]
|
|
31
|
-
'playback-quality-change': [e: YT.OnPlaybackQualityChangeEvent, target: YT.Player]
|
|
32
|
-
'playback-rate-change': [e: YT.OnPlaybackRateChangeEvent, target: YT.Player]
|
|
33
|
-
'error': [e: YT.OnErrorEvent, target: YT.Player]
|
|
34
|
-
}>()
|
|
35
|
-
const events: (keyof YT.Events)[] = [
|
|
36
|
-
'onReady',
|
|
37
|
-
'onStateChange',
|
|
38
|
-
'onPlaybackQualityChange',
|
|
39
|
-
'onPlaybackRateChange',
|
|
40
|
-
'onError',
|
|
41
|
-
'onApiChange',
|
|
42
|
-
]
|
|
43
|
-
const rootEl = ref()
|
|
44
|
-
const youtubeEl = ref()
|
|
45
|
-
const ready = ref(false)
|
|
46
|
-
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
|
|
47
|
-
const { onLoaded, status } = useScriptYouTubePlayer({
|
|
48
|
-
scriptOptions: {
|
|
49
|
-
trigger,
|
|
50
|
-
},
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const player: Ref<YT.Player | undefined> = ref()
|
|
54
|
-
let clickTriggered = false
|
|
55
|
-
if (props.trigger === 'mousedown') {
|
|
56
|
-
trigger.then(() => {
|
|
57
|
-
clickTriggered = true
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
onMounted(() => {
|
|
61
|
-
onLoaded(async (instance) => {
|
|
62
|
-
const YouTube: typeof YT & { ready: (fn: () => void) => void } = await instance.YT
|
|
63
|
-
await new Promise<void>((resolve) => {
|
|
64
|
-
if (typeof YT.Player === 'undefined')
|
|
65
|
-
YouTube.ready(resolve)
|
|
66
|
-
else
|
|
67
|
-
resolve()
|
|
68
|
-
})
|
|
69
|
-
player.value = new YT.Player(youtubeEl.value, {
|
|
70
|
-
...props,
|
|
71
|
-
events: Object.fromEntries(events.map(event => [event, (e: any) => {
|
|
72
|
-
const emitEventName = event.replace(/([A-Z])/g, '-$1').replace('on-', '').toLowerCase()
|
|
73
|
-
// @ts-expect-error untyped
|
|
74
|
-
emits(emitEventName, e)
|
|
75
|
-
if (event === 'onReady') {
|
|
76
|
-
ready.value = true
|
|
77
|
-
if (clickTriggered) {
|
|
78
|
-
player.value?.playVideo()
|
|
79
|
-
clickTriggered = false
|
|
80
|
-
}
|
|
81
|
-
watch(() => props.videoId, () => {
|
|
82
|
-
player.value?.loadVideoById(props.videoId)
|
|
83
|
-
})
|
|
84
|
-
}
|
|
85
|
-
}])),
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
watch(status, (status) => {
|
|
89
|
-
if (status === 'error') {
|
|
90
|
-
// @ts-expect-error untyped
|
|
91
|
-
emits('error')
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
defineExpose({
|
|
97
|
-
player,
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
const rootAttrs = computed(() => {
|
|
101
|
-
return defu(props.rootAttrs, {
|
|
102
|
-
'aria-busy': status.value === 'loading',
|
|
103
|
-
'aria-label': status.value === 'awaitingLoad'
|
|
104
|
-
? 'YouTube Player - Placeholder'
|
|
105
|
-
: status.value === 'loading'
|
|
106
|
-
? 'YouTube Player - Loading'
|
|
107
|
-
: 'YouTube Player - Loaded',
|
|
108
|
-
'aria-live': 'polite',
|
|
109
|
-
'role': 'application',
|
|
110
|
-
'style': {
|
|
111
|
-
cursor: 'pointer',
|
|
112
|
-
position: 'relative',
|
|
113
|
-
backgroundColor: 'black',
|
|
114
|
-
maxWidth: '100%',
|
|
115
|
-
width: `${props.width}px`,
|
|
116
|
-
height: `'auto'`,
|
|
117
|
-
aspectRatio: `${props.width}/${props.height}`,
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
<slot v-if="
|
|
165
|
-
<
|
|
166
|
-
</slot>
|
|
167
|
-
<slot v-if="status === '
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/// <reference types="youtube" />
|
|
3
|
+
import { computed, onMounted, ref, watch } from 'vue'
|
|
4
|
+
import type { HTMLAttributes, ImgHTMLAttributes, Ref } from 'vue'
|
|
5
|
+
import { defu } from 'defu'
|
|
6
|
+
import type { ElementScriptTrigger } from '../types'
|
|
7
|
+
import { useScriptTriggerElement } from '../composables/useScriptTriggerElement'
|
|
8
|
+
import { useScriptYouTubePlayer } from '../registry/youtube-player'
|
|
9
|
+
import { useHead } from '#imports'
|
|
10
|
+
|
|
11
|
+
const props = withDefaults(defineProps<{
|
|
12
|
+
placeholderAttrs?: ImgHTMLAttributes
|
|
13
|
+
rootAttrs?: HTMLAttributes
|
|
14
|
+
aboveTheFold?: boolean
|
|
15
|
+
trigger?: ElementScriptTrigger
|
|
16
|
+
videoId: string
|
|
17
|
+
playerVars?: YT.PlayerVars
|
|
18
|
+
width?: number
|
|
19
|
+
height?: number
|
|
20
|
+
}>(), {
|
|
21
|
+
trigger: 'mousedown',
|
|
22
|
+
// @ts-expect-error untyped
|
|
23
|
+
playerVars: { autoplay: 0, playsinline: 1 },
|
|
24
|
+
width: 640,
|
|
25
|
+
height: 480,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const emits = defineEmits<{
|
|
29
|
+
'ready': [e: YT.PlayerEvent]
|
|
30
|
+
'state-change': [e: YT.OnStateChangeEvent, target: YT.Player]
|
|
31
|
+
'playback-quality-change': [e: YT.OnPlaybackQualityChangeEvent, target: YT.Player]
|
|
32
|
+
'playback-rate-change': [e: YT.OnPlaybackRateChangeEvent, target: YT.Player]
|
|
33
|
+
'error': [e: YT.OnErrorEvent, target: YT.Player]
|
|
34
|
+
}>()
|
|
35
|
+
const events: (keyof YT.Events)[] = [
|
|
36
|
+
'onReady',
|
|
37
|
+
'onStateChange',
|
|
38
|
+
'onPlaybackQualityChange',
|
|
39
|
+
'onPlaybackRateChange',
|
|
40
|
+
'onError',
|
|
41
|
+
'onApiChange',
|
|
42
|
+
]
|
|
43
|
+
const rootEl = ref()
|
|
44
|
+
const youtubeEl = ref()
|
|
45
|
+
const ready = ref(false)
|
|
46
|
+
const trigger = useScriptTriggerElement({ trigger: props.trigger, el: rootEl })
|
|
47
|
+
const { onLoaded, status } = useScriptYouTubePlayer({
|
|
48
|
+
scriptOptions: {
|
|
49
|
+
trigger,
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const player: Ref<YT.Player | undefined> = ref()
|
|
54
|
+
let clickTriggered = false
|
|
55
|
+
if (props.trigger === 'mousedown' && trigger instanceof Promise) {
|
|
56
|
+
trigger.then(() => {
|
|
57
|
+
clickTriggered = true
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
onMounted(() => {
|
|
61
|
+
onLoaded(async (instance) => {
|
|
62
|
+
const YouTube: typeof YT & { ready: (fn: () => void) => void } = await instance.YT
|
|
63
|
+
await new Promise<void>((resolve) => {
|
|
64
|
+
if (typeof YT.Player === 'undefined')
|
|
65
|
+
YouTube.ready(resolve)
|
|
66
|
+
else
|
|
67
|
+
resolve()
|
|
68
|
+
})
|
|
69
|
+
player.value = new YT.Player(youtubeEl.value, {
|
|
70
|
+
...props,
|
|
71
|
+
events: Object.fromEntries(events.map(event => [event, (e: any) => {
|
|
72
|
+
const emitEventName = event.replace(/([A-Z])/g, '-$1').replace('on-', '').toLowerCase()
|
|
73
|
+
// @ts-expect-error untyped
|
|
74
|
+
emits(emitEventName, e)
|
|
75
|
+
if (event === 'onReady') {
|
|
76
|
+
ready.value = true
|
|
77
|
+
if (clickTriggered) {
|
|
78
|
+
player.value?.playVideo()
|
|
79
|
+
clickTriggered = false
|
|
80
|
+
}
|
|
81
|
+
watch(() => props.videoId, () => {
|
|
82
|
+
player.value?.loadVideoById(props.videoId)
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
}])),
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
watch(status, (status) => {
|
|
89
|
+
if (status === 'error') {
|
|
90
|
+
// @ts-expect-error untyped
|
|
91
|
+
emits('error')
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
defineExpose({
|
|
97
|
+
player,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const rootAttrs = computed(() => {
|
|
101
|
+
return defu(props.rootAttrs, {
|
|
102
|
+
'aria-busy': status.value === 'loading',
|
|
103
|
+
'aria-label': status.value === 'awaitingLoad'
|
|
104
|
+
? 'YouTube Player - Placeholder'
|
|
105
|
+
: status.value === 'loading'
|
|
106
|
+
? 'YouTube Player - Loading'
|
|
107
|
+
: 'YouTube Player - Loaded',
|
|
108
|
+
'aria-live': 'polite',
|
|
109
|
+
'role': 'application',
|
|
110
|
+
'style': {
|
|
111
|
+
cursor: 'pointer',
|
|
112
|
+
position: 'relative',
|
|
113
|
+
backgroundColor: 'black',
|
|
114
|
+
maxWidth: '100%',
|
|
115
|
+
width: `${props.width}px`,
|
|
116
|
+
height: `'auto'`,
|
|
117
|
+
aspectRatio: `${props.width}/${props.height}`,
|
|
118
|
+
},
|
|
119
|
+
...(trigger instanceof Promise ? trigger.ssrAttrs || {} : {}),
|
|
120
|
+
}) as HTMLAttributes
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
const placeholder = computed(() => `https://i.ytimg.com/vi_webp/${props.videoId}/sddefault.webp`)
|
|
124
|
+
|
|
125
|
+
if (import.meta.server) {
|
|
126
|
+
// dns-prefetch https://i.vimeocdn.com
|
|
127
|
+
useHead({
|
|
128
|
+
link: [
|
|
129
|
+
{
|
|
130
|
+
key: `nuxt-script-youtube-img`,
|
|
131
|
+
rel: props.aboveTheFold ? 'preconnect' : 'dns-prefetch',
|
|
132
|
+
href: 'https://i.ytimg.com',
|
|
133
|
+
},
|
|
134
|
+
props.aboveTheFold
|
|
135
|
+
// we can preload the placeholder image
|
|
136
|
+
? {
|
|
137
|
+
key: `nuxt-script-youtube-img`,
|
|
138
|
+
rel: 'preload',
|
|
139
|
+
as: 'image',
|
|
140
|
+
href: placeholder.value,
|
|
141
|
+
}
|
|
142
|
+
: {},
|
|
143
|
+
],
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const placeholderAttrs = computed(() => {
|
|
148
|
+
return defu(props.placeholderAttrs, {
|
|
149
|
+
src: placeholder.value,
|
|
150
|
+
alt: '',
|
|
151
|
+
loading: props.aboveTheFold ? 'eager' : 'lazy',
|
|
152
|
+
style: {
|
|
153
|
+
width: '100%',
|
|
154
|
+
objectFit: 'contain',
|
|
155
|
+
height: '100%',
|
|
156
|
+
},
|
|
157
|
+
} satisfies ImgHTMLAttributes)
|
|
158
|
+
})
|
|
159
|
+
</script>
|
|
160
|
+
|
|
161
|
+
<template>
|
|
162
|
+
<div ref="rootEl" v-bind="rootAttrs">
|
|
163
|
+
<div ref="youtubeEl" style="width: 100%; height: 100%; position: absolute; top: 0; left: 0;" />
|
|
164
|
+
<slot v-if="!ready" :placeholder="placeholder" name="placeholder">
|
|
165
|
+
<img v-bind="placeholderAttrs">
|
|
166
|
+
</slot>
|
|
167
|
+
<slot v-if="status === 'loading'" name="loading">
|
|
168
|
+
<ScriptLoadingIndicator />
|
|
169
|
+
</slot>
|
|
170
|
+
<slot v-if="status === 'awaitingLoad'" name="awaitingLoad" />
|
|
171
|
+
<slot v-else-if="status === 'error'" name="error" />
|
|
172
|
+
<slot />
|
|
173
|
+
</div>
|
|
174
|
+
</template>
|
|
@@ -1,23 +1,38 @@
|
|
|
1
1
|
import { resolveScriptKey } from "unhead";
|
|
2
2
|
import { defu } from "defu";
|
|
3
3
|
import { useScript as _useScript } from "@unhead/vue";
|
|
4
|
-
import { injectHead, onNuxtReady, useNuxtApp, useRuntimeConfig, reactive } from "#imports";
|
|
4
|
+
import { injectHead, onNuxtReady, useHead, useNuxtApp, useRuntimeConfig, reactive } from "#imports";
|
|
5
5
|
function useNuxtScriptRuntimeConfig() {
|
|
6
6
|
return useRuntimeConfig().public["nuxt-scripts"];
|
|
7
7
|
}
|
|
8
8
|
export function useScript(input, options) {
|
|
9
9
|
input = typeof input === "string" ? { src: input } : input;
|
|
10
10
|
options = defu(options, useNuxtScriptRuntimeConfig()?.defaultScriptOptions);
|
|
11
|
-
|
|
11
|
+
const rel = options.trigger === "onNuxtReady" ? "preload" : "preconnect";
|
|
12
|
+
const id = resolveScriptKey(input);
|
|
13
|
+
if (options.trigger !== "server" && (rel === "preload" || !input.src.startsWith("/"))) {
|
|
14
|
+
useHead({
|
|
15
|
+
link: [
|
|
16
|
+
{
|
|
17
|
+
rel,
|
|
18
|
+
as: rel === "preload" ? "script" : void 0,
|
|
19
|
+
href: input.src,
|
|
20
|
+
crossorigin: input.src.startsWith("/") ? void 0 : typeof input.crossorigin !== "undefined" ? input.crossorigin : "anonymous",
|
|
21
|
+
key: `nuxt-script-${id}`,
|
|
22
|
+
tagPriority: rel === "preload" ? "high" : 0,
|
|
23
|
+
fetchpriority: "low"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (options.trigger === "onNuxtReady") {
|
|
12
29
|
options.trigger = onNuxtReady;
|
|
30
|
+
}
|
|
13
31
|
const nuxtApp = useNuxtApp();
|
|
14
|
-
const id = resolveScriptKey(input);
|
|
15
32
|
nuxtApp.$scripts = nuxtApp.$scripts || reactive({});
|
|
16
|
-
|
|
17
|
-
return nuxtApp.$scripts[id];
|
|
18
|
-
}
|
|
33
|
+
const exists = !!nuxtApp.$scripts?.[id];
|
|
19
34
|
if (import.meta.client) {
|
|
20
|
-
if (!
|
|
35
|
+
if (!exists) {
|
|
21
36
|
performance?.mark?.("mark_feature_usage", {
|
|
22
37
|
detail: {
|
|
23
38
|
feature: options.performanceMarkFeature ?? `nuxt-scripts:${id}`
|
|
@@ -32,6 +47,9 @@ export function useScript(input, options) {
|
|
|
32
47
|
nuxtApp._scripts[instance.id] = payload;
|
|
33
48
|
nuxtApp.hooks.callHook("scripts:updated", { scripts: nuxtApp._scripts });
|
|
34
49
|
};
|
|
50
|
+
if (exists) {
|
|
51
|
+
return instance;
|
|
52
|
+
}
|
|
35
53
|
const payload = {
|
|
36
54
|
...options.devtools,
|
|
37
55
|
src: input.src,
|
|
@@ -14,4 +14,6 @@ export interface ElementScriptTriggerOptions {
|
|
|
14
14
|
/**
|
|
15
15
|
* Create a trigger for an element to load a script based on specific element events.
|
|
16
16
|
*/
|
|
17
|
-
export declare function useScriptTriggerElement(options: ElementScriptTriggerOptions): Promise<void
|
|
17
|
+
export declare function useScriptTriggerElement(options: ElementScriptTriggerOptions): Promise<void> & {
|
|
18
|
+
ssrAttrs?: Record<string, string>;
|
|
19
|
+
} | 'onNuxtReady';
|
|
@@ -2,9 +2,11 @@ import {
|
|
|
2
2
|
useEventListener,
|
|
3
3
|
useIntersectionObserver
|
|
4
4
|
} from "@vueuse/core";
|
|
5
|
+
import { tryOnScopeDispose, tryOnMounted } from "@vueuse/shared";
|
|
6
|
+
import { watch } from "vue";
|
|
5
7
|
function useElementVisibilityPromise(element) {
|
|
6
8
|
let observer;
|
|
7
|
-
return new Promise((resolve) => {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
8
10
|
observer = useIntersectionObserver(
|
|
9
11
|
element,
|
|
10
12
|
(intersectionObserverEntries) => {
|
|
@@ -18,32 +20,57 @@ function useElementVisibilityPromise(element) {
|
|
|
18
20
|
threshold: 0
|
|
19
21
|
}
|
|
20
22
|
);
|
|
23
|
+
tryOnScopeDispose(reject);
|
|
24
|
+
}).catch(() => {
|
|
21
25
|
}).finally(() => {
|
|
22
26
|
observer.stop();
|
|
23
27
|
});
|
|
24
28
|
}
|
|
25
29
|
export function useScriptTriggerElement(options) {
|
|
26
30
|
const { el, trigger } = options;
|
|
27
|
-
if (import.meta.server || !el)
|
|
28
|
-
return new Promise(() => {
|
|
29
|
-
});
|
|
30
31
|
const triggers = (Array.isArray(options.trigger) ? options.trigger : [options.trigger]).filter(Boolean);
|
|
31
|
-
if (
|
|
32
|
+
if (!trigger || triggers.includes("immediate") || triggers.includes("onNuxtReady")) {
|
|
33
|
+
return "onNuxtReady";
|
|
34
|
+
}
|
|
35
|
+
if (triggers.some((t) => ["visibility", "visible"].includes(t))) {
|
|
36
|
+
if (import.meta.server || !el)
|
|
37
|
+
return new Promise(() => {
|
|
38
|
+
});
|
|
32
39
|
return useElementVisibilityPromise(el);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
typeof el !== "undefined" ? el : document.body,
|
|
39
|
-
triggers,
|
|
40
|
-
() => {
|
|
41
|
-
resolve();
|
|
42
|
-
_();
|
|
43
|
-
},
|
|
44
|
-
{ once: true, passive: true }
|
|
45
|
-
);
|
|
40
|
+
}
|
|
41
|
+
const ssrAttrs = {};
|
|
42
|
+
if (import.meta.server) {
|
|
43
|
+
triggers.forEach((trigger2) => {
|
|
44
|
+
ssrAttrs[`on${trigger2}`] = `this.dataset.script_${trigger2} = true`;
|
|
46
45
|
});
|
|
47
46
|
}
|
|
48
|
-
|
|
47
|
+
const p = new Promise((resolve, reject) => {
|
|
48
|
+
const target = typeof el !== "undefined" ? el : document.body;
|
|
49
|
+
const _ = useEventListener(
|
|
50
|
+
target,
|
|
51
|
+
triggers,
|
|
52
|
+
() => {
|
|
53
|
+
_();
|
|
54
|
+
resolve();
|
|
55
|
+
},
|
|
56
|
+
{ once: true, passive: true }
|
|
57
|
+
);
|
|
58
|
+
tryOnMounted(() => {
|
|
59
|
+
watch(target, ($el) => {
|
|
60
|
+
if ($el) {
|
|
61
|
+
triggers.forEach((trigger2) => {
|
|
62
|
+
if ($el.dataset[`script_${trigger2}`]) {
|
|
63
|
+
_();
|
|
64
|
+
resolve();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
immediate: true
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
tryOnScopeDispose(reject);
|
|
73
|
+
}).catch(() => {
|
|
74
|
+
});
|
|
75
|
+
return Object.assign(p, { ssrAttrs });
|
|
49
76
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { optional } from "valibot";
|
|
2
1
|
import { useRegistryScript } from "../utils.js";
|
|
3
|
-
import { object, string } from "#nuxt-scripts-validator";
|
|
2
|
+
import { object, string, optional } from "#nuxt-scripts-validator";
|
|
4
3
|
import { useHead } from "#imports";
|
|
5
4
|
export const GoogleAdsenseOptions = object({
|
|
6
5
|
/**
|
|
@@ -18,19 +17,17 @@ export function useScriptGoogleAdsense(_options) {
|
|
|
18
17
|
use() {
|
|
19
18
|
return { adsbygoogle: window.adsbygoogle };
|
|
20
19
|
},
|
|
21
|
-
// allow dataLayer to be accessed on the server
|
|
22
|
-
stub: import.meta.client ? void 0 : ({ fn }) => {
|
|
23
|
-
return fn === "adsbygoogle" ? [] : void 0;
|
|
24
|
-
},
|
|
25
20
|
beforeInit() {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
21
|
+
if (options?.client) {
|
|
22
|
+
useHead({
|
|
23
|
+
meta: [
|
|
24
|
+
{
|
|
25
|
+
name: "google-adsense-account",
|
|
26
|
+
content: options?.client
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
});
|
|
30
|
+
}
|
|
34
31
|
}
|
|
35
32
|
}
|
|
36
33
|
}), _options);
|
package/dist/runtime/types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { object } from "
|
|
1
|
+
import { object } from "#nuxt-scripts-validator";
|
|
2
2
|
const _emptyOptions = object({});
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt/scripts",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"packageManager": "pnpm@9.
|
|
4
|
+
"version": "0.8.0",
|
|
5
|
+
"packageManager": "pnpm@9.9.0",
|
|
6
6
|
"description": "Load third-party scripts with better performance, privacy and DX in Nuxt Apps.",
|
|
7
7
|
"author": {
|
|
8
8
|
"website": "https://harlanzw.com",
|
|
@@ -65,15 +65,15 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@nuxt/devtools-kit": "^1.
|
|
69
|
-
"@nuxt/devtools-ui-kit": "^1.
|
|
70
|
-
"@nuxt/kit": "^3.
|
|
71
|
-
"@types/google.maps": "^3.
|
|
68
|
+
"@nuxt/devtools-kit": "^1.4.1",
|
|
69
|
+
"@nuxt/devtools-ui-kit": "^1.4.1",
|
|
70
|
+
"@nuxt/kit": "^3.13.0",
|
|
71
|
+
"@types/google.maps": "^3.57.0",
|
|
72
72
|
"@types/stripe-v3": "^3.1.33",
|
|
73
73
|
"@types/vimeo__player": "^2.18.3",
|
|
74
|
-
"@types/youtube": "^0.0
|
|
75
|
-
"@unhead/vue": "^1.10.
|
|
76
|
-
"@vueuse/core": "^11.0.
|
|
74
|
+
"@types/youtube": "^0.1.0",
|
|
75
|
+
"@unhead/vue": "^1.10.3",
|
|
76
|
+
"@vueuse/core": "^11.0.3",
|
|
77
77
|
"consola": "^3.2.3",
|
|
78
78
|
"defu": "^6.1.4",
|
|
79
79
|
"h3": "^1.12.0",
|
|
@@ -82,33 +82,33 @@
|
|
|
82
82
|
"ofetch": "^1.3.4",
|
|
83
83
|
"ohash": "^1.1.3",
|
|
84
84
|
"pathe": "^1.1.2",
|
|
85
|
-
"pkg-types": "^1.
|
|
85
|
+
"pkg-types": "^1.2.0",
|
|
86
86
|
"semver": "^7.6.3",
|
|
87
|
-
"shiki": "1.
|
|
87
|
+
"shiki": "1.16.1",
|
|
88
88
|
"sirv": "^2.0.4",
|
|
89
89
|
"std-env": "^3.7.0",
|
|
90
90
|
"third-party-capital": "2.3.0",
|
|
91
91
|
"ufo": "^1.5.4",
|
|
92
|
-
"unimport": "^3.11.
|
|
93
|
-
"unplugin": "^1.12.
|
|
92
|
+
"unimport": "^3.11.1",
|
|
93
|
+
"unplugin": "^1.12.3",
|
|
94
94
|
"unstorage": "^1.10.2",
|
|
95
|
-
"valibot": "^0.
|
|
95
|
+
"valibot": "^0.41.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
-
"@nuxt/devtools-ui-kit": "^1.
|
|
99
|
-
"@nuxt/eslint-config": "^0.5.
|
|
98
|
+
"@nuxt/devtools-ui-kit": "^1.4.1",
|
|
99
|
+
"@nuxt/eslint-config": "^0.5.5",
|
|
100
100
|
"@nuxt/module-builder": "^0.8.3",
|
|
101
101
|
"@nuxt/test-utils": "3.14.1",
|
|
102
102
|
"@types/semver": "^7.5.8",
|
|
103
|
-
"@typescript-eslint/typescript-estree": "^8.
|
|
104
|
-
"@unhead/schema": "^1.10.
|
|
103
|
+
"@typescript-eslint/typescript-estree": "^8.4.0",
|
|
104
|
+
"@unhead/schema": "^1.10.3",
|
|
105
105
|
"acorn-loose": "^8.4.0",
|
|
106
|
-
"bumpp": "^9.5.
|
|
106
|
+
"bumpp": "^9.5.2",
|
|
107
107
|
"changelogen": "^0.5.5",
|
|
108
|
-
"eslint": "9.9.
|
|
108
|
+
"eslint": "9.9.1",
|
|
109
109
|
"eslint-plugin-n": "^17.10.2",
|
|
110
110
|
"knitwork": "^1.1.0",
|
|
111
|
-
"nuxt": "^3.
|
|
111
|
+
"nuxt": "^3.13.0",
|
|
112
112
|
"nuxt-scripts-devtools": "workspace:*",
|
|
113
113
|
"playwright-core": "^1.46.1",
|
|
114
114
|
"typescript": "^5.5.4",
|
|
@@ -117,16 +117,17 @@
|
|
|
117
117
|
"vue-router": "^4.4.3"
|
|
118
118
|
},
|
|
119
119
|
"resolutions": {
|
|
120
|
+
"@nuxt/schema": "3.13.0",
|
|
120
121
|
"@nuxt/scripts": "workspace:*",
|
|
121
|
-
"@unhead/dom": "1.10.
|
|
122
|
-
"@unhead/schema": "1.10.
|
|
123
|
-
"@unhead/shared": "1.10.
|
|
124
|
-
"@unhead/ssr": "1.10.
|
|
125
|
-
"@unhead/vue": "1.10.
|
|
126
|
-
"nuxt": "^3.
|
|
122
|
+
"@unhead/dom": "1.10.2",
|
|
123
|
+
"@unhead/schema": "1.10.4",
|
|
124
|
+
"@unhead/shared": "1.10.4",
|
|
125
|
+
"@unhead/ssr": "1.10.4",
|
|
126
|
+
"@unhead/vue": "1.10.4",
|
|
127
|
+
"nuxt": "^3.13.0",
|
|
127
128
|
"nuxt-scripts-devtools": "workspace:*",
|
|
128
129
|
"shiki": "1.10.3",
|
|
129
|
-
"unhead": "1.10.
|
|
130
|
+
"unhead": "1.10.4",
|
|
130
131
|
"vue": "^3.4.38",
|
|
131
132
|
"vue-router": "^4.4.3"
|
|
132
133
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"e4092e18-9a58-41ab-947e-35e1f2082b75","timestamp":1724318010522,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.spotlight[data-v-379fced0]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-379fced0]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-379fced0]{background-color:#ffffff4d}.gradient-border[data-v-379fced0]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-379fced0]{background-color:#1414144d}.gradient-border[data-v-379fced0]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-379fced0]:before{background-size:400% auto;border-radius:.5rem;bottom:0;content:"";left:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;right:0;top:0;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-379fced0]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-379fced0]{position:fixed}.left-0[data-v-379fced0]{left:0}.right-0[data-v-379fced0]{right:0}.z-10[data-v-379fced0]{z-index:10}.z-20[data-v-379fced0]{z-index:20}.grid[data-v-379fced0]{display:grid}.mb-16[data-v-379fced0]{margin-bottom:4rem}.mb-8[data-v-379fced0]{margin-bottom:2rem}.max-w-520px[data-v-379fced0]{max-width:520px}.min-h-screen[data-v-379fced0]{min-height:100vh}.w-full[data-v-379fced0]{width:100%}.flex[data-v-379fced0]{display:flex}.cursor-pointer[data-v-379fced0]{cursor:pointer}.place-content-center[data-v-379fced0]{place-content:center}.items-center[data-v-379fced0]{align-items:center}.justify-center[data-v-379fced0]{justify-content:center}.overflow-hidden[data-v-379fced0]{overflow:hidden}.bg-white[data-v-379fced0]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-379fced0]{padding-left:1rem;padding-right:1rem}.px-8[data-v-379fced0]{padding-left:2rem;padding-right:2rem}.py-2[data-v-379fced0]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-379fced0]{text-align:center}.text-8xl[data-v-379fced0]{font-size:6rem;line-height:1}.text-xl[data-v-379fced0]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-379fced0]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-379fced0]{font-weight:300}.font-medium[data-v-379fced0]{font-weight:500}.leading-tight[data-v-379fced0]{line-height:1.25}.font-sans[data-v-379fced0]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-379fced0]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-379fced0]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-379fced0]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-379fced0]{padding-left:0;padding-right:0}.sm\:px-6[data-v-379fced0]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-379fced0]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-379fced0]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-379fced0]{font-size:1.25rem;line-height:1.75rem}}
|