@nuxt/scripts 1.0.0-beta.3 → 1.0.0-beta.31
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 +3 -3
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/{DdVDSbUA.js → 6CwTUC2b.js} +1 -1
- package/dist/client/_nuxt/{CD5B-xvT.js → B71AlSZ1.js} +1 -1
- package/dist/client/_nuxt/{Ds2G8aQM.js → BYGJV5dd.js} +1 -1
- package/dist/client/_nuxt/V4W-T8W6.js +162 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/70b59a3e-a025-4a77-a25a-dfadf5b1749d.json +1 -0
- package/dist/client/_nuxt/entry.C5SUNdim.css +1 -0
- package/dist/client/_nuxt/error-404.1K8v8Su2.css +1 -0
- package/dist/client/_nuxt/error-500.B9qvKpQm.css +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +6 -18
- package/dist/module.d.ts +164 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +908 -645
- package/dist/registry.d.ts +6 -0
- package/dist/registry.mjs +244 -78
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.d.vue.ts +16 -9
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue +57 -30
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMaps.vue.d.ts +16 -9
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.d.vue.ts +22 -39
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue +69 -72
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsAdvancedMarkerElement.vue.d.ts +22 -39
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.d.vue.ts +5 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue +25 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsCircle.vue.d.ts +5 -1
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.d.vue.ts +43 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue +61 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsGeoJson.vue.d.ts +43 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.d.vue.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue +22 -26
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsHeatmapLayer.vue.d.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.d.vue.ts +9 -5
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue +62 -53
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsInfoWindow.vue.d.ts +9 -5
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.d.vue.ts +26 -11
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue +48 -45
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarker.vue.d.ts +26 -11
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.d.vue.ts +15 -4
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue +47 -37
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsMarkerClusterer.vue.d.ts +15 -4
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.d.vue.ts +77 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue +209 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsOverlayView.vue.d.ts +77 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.d.vue.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue +23 -32
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPinElement.vue.d.ts +4 -0
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue +24 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolygon.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue +24 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsPolyline.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.d.vue.ts +7 -3
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue +25 -38
- package/dist/runtime/components/GoogleMaps/ScriptGoogleMapsRectangle.vue.d.ts +7 -3
- package/dist/runtime/components/GoogleMaps/bindGoogleMapsEvents.d.ts +13 -0
- package/dist/runtime/components/GoogleMaps/bindGoogleMapsEvents.js +8 -0
- package/dist/runtime/components/GoogleMaps/injectionKeys.d.ts +13 -0
- package/dist/runtime/components/GoogleMaps/injectionKeys.js +3 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.d.ts +26 -0
- package/dist/runtime/components/GoogleMaps/useGoogleMapsResource.js +42 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.d.vue.ts +87 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.vue +85 -0
- package/dist/runtime/components/ScriptBlueskyEmbed.vue.d.ts +87 -0
- package/dist/runtime/components/ScriptCrisp.vue +1 -1
- package/dist/runtime/components/ScriptGoogleAdsense.vue +1 -1
- package/dist/runtime/components/ScriptGravatar.d.vue.ts +22 -0
- package/dist/runtime/components/ScriptGravatar.vue +46 -0
- package/dist/runtime/components/ScriptGravatar.vue.d.ts +22 -0
- package/dist/runtime/components/ScriptInstagramEmbed.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptInstagramEmbed.vue +5 -2
- package/dist/runtime/components/ScriptInstagramEmbed.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptIntercom.vue +4 -3
- package/dist/runtime/components/ScriptPayPalButtons.d.vue.ts +43 -32
- package/dist/runtime/components/ScriptPayPalButtons.vue +48 -79
- package/dist/runtime/components/ScriptPayPalButtons.vue.d.ts +43 -32
- package/dist/runtime/components/ScriptPayPalMessages.d.vue.ts +37 -23
- package/dist/runtime/components/ScriptPayPalMessages.vue +46 -50
- package/dist/runtime/components/ScriptPayPalMessages.vue.d.ts +37 -23
- package/dist/runtime/components/ScriptStripePricingTable.vue +2 -2
- package/dist/runtime/components/ScriptVimeoPlayer.d.vue.ts +9 -0
- package/dist/runtime/components/ScriptVimeoPlayer.vue +13 -10
- package/dist/runtime/components/ScriptVimeoPlayer.vue.d.ts +9 -0
- package/dist/runtime/components/ScriptXEmbed.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptXEmbed.vue +6 -3
- package/dist/runtime/components/ScriptXEmbed.vue.d.ts +2 -2
- package/dist/runtime/components/ScriptYouTubePlayer.d.vue.ts +2 -2
- package/dist/runtime/components/ScriptYouTubePlayer.vue +11 -5
- package/dist/runtime/components/ScriptYouTubePlayer.vue.d.ts +2 -2
- package/dist/runtime/composables/useScript.js +13 -6
- package/dist/runtime/composables/useScriptEventPage.js +2 -2
- package/dist/runtime/composables/useScriptTriggerConsent.d.ts +10 -0
- package/dist/runtime/composables/useScriptTriggerConsent.js +33 -20
- package/dist/runtime/composables/useScriptTriggerElement.js +1 -1
- package/dist/runtime/composables/useScriptTriggerIdleTimeout.js +1 -1
- package/dist/runtime/registry/bing-uet.d.ts +20 -0
- package/dist/runtime/registry/bing-uet.js +29 -0
- package/dist/runtime/registry/bluesky-embed.d.ts +116 -0
- package/dist/runtime/registry/bluesky-embed.js +72 -0
- package/dist/runtime/registry/clarity.d.ts +10 -15
- package/dist/runtime/registry/clarity.js +22 -31
- package/dist/runtime/registry/cloudflare-web-analytics.d.ts +2 -13
- package/dist/runtime/registry/cloudflare-web-analytics.js +2 -14
- package/dist/runtime/registry/crisp.d.ts +10 -40
- package/dist/runtime/registry/crisp.js +2 -33
- package/dist/runtime/registry/databuddy-analytics.d.ts +2 -35
- package/dist/runtime/registry/databuddy-analytics.js +20 -45
- package/dist/runtime/registry/fathom-analytics.d.ts +7 -26
- package/dist/runtime/registry/fathom-analytics.js +2 -24
- package/dist/runtime/registry/google-adsense.d.ts +3 -11
- package/dist/runtime/registry/google-adsense.js +2 -11
- package/dist/runtime/registry/google-analytics.d.ts +3 -5
- package/dist/runtime/registry/google-analytics.js +3 -8
- package/dist/runtime/registry/google-maps.d.ts +3 -9
- package/dist/runtime/registry/google-maps.js +2 -8
- package/dist/runtime/registry/google-recaptcha.d.ts +2 -6
- package/dist/runtime/registry/google-recaptcha.js +4 -12
- package/dist/runtime/registry/google-sign-in.d.ts +2 -13
- package/dist/runtime/registry/google-sign-in.js +2 -22
- package/dist/runtime/registry/google-tag-manager.d.ts +3 -28
- package/dist/runtime/registry/google-tag-manager.js +4 -27
- package/dist/runtime/registry/gravatar.d.ts +26 -0
- package/dist/runtime/registry/gravatar.js +33 -0
- package/dist/runtime/registry/hotjar.d.ts +4 -6
- package/dist/runtime/registry/hotjar.js +2 -5
- package/dist/runtime/registry/instagram-embed.d.ts +3 -18
- package/dist/runtime/registry/instagram-embed.js +4 -19
- package/dist/runtime/registry/intercom.d.ts +4 -12
- package/dist/runtime/registry/intercom.js +2 -12
- package/dist/runtime/registry/matomo-analytics.d.ts +3 -12
- package/dist/runtime/registry/matomo-analytics.js +3 -12
- package/dist/runtime/registry/meta-pixel.d.ts +4 -6
- package/dist/runtime/registry/meta-pixel.js +2 -4
- package/dist/runtime/registry/mixpanel-analytics.d.ts +22 -0
- package/dist/runtime/registry/mixpanel-analytics.js +46 -0
- package/dist/runtime/registry/npm.d.ts +3 -7
- package/dist/runtime/registry/npm.js +2 -9
- package/dist/runtime/registry/paypal.d.ts +4 -25
- package/dist/runtime/registry/paypal.js +3 -66
- package/dist/runtime/registry/plausible-analytics.js +18 -13
- package/dist/runtime/registry/posthog.d.ts +10 -12
- package/dist/runtime/registry/posthog.js +7 -14
- package/dist/runtime/registry/reddit-pixel.d.ts +5 -6
- package/dist/runtime/registry/reddit-pixel.js +2 -4
- package/dist/runtime/registry/rybbit-analytics.d.ts +2 -14
- package/dist/runtime/registry/rybbit-analytics.js +10 -20
- package/dist/runtime/registry/schemas.d.ts +982 -0
- package/dist/runtime/registry/schemas.js +937 -0
- package/dist/runtime/registry/segment.d.ts +2 -5
- package/dist/runtime/registry/segment.js +2 -5
- package/dist/runtime/registry/snapchat-pixel.d.ts +4 -33
- package/dist/runtime/registry/snapchat-pixel.js +2 -20
- package/dist/runtime/registry/stripe.d.ts +3 -4
- package/dist/runtime/registry/stripe.js +2 -4
- package/dist/runtime/registry/tiktok-pixel.d.ts +4 -7
- package/dist/runtime/registry/tiktok-pixel.js +2 -6
- package/dist/runtime/registry/umami-analytics.d.ts +2 -31
- package/dist/runtime/registry/umami-analytics.js +2 -36
- package/dist/runtime/registry/vercel-analytics.d.ts +29 -0
- package/dist/runtime/registry/vercel-analytics.js +84 -0
- package/dist/runtime/registry/vimeo-player.d.ts +2 -2
- package/dist/runtime/registry/vimeo-player.js +1 -1
- package/dist/runtime/registry/x-embed.d.ts +3 -17
- package/dist/runtime/registry/x-embed.js +3 -18
- package/dist/runtime/registry/x-pixel.d.ts +4 -7
- package/dist/runtime/registry/x-pixel.js +2 -5
- package/dist/runtime/registry/youtube-player.d.ts +7 -7
- package/dist/runtime/registry/youtube-player.js +1 -1
- package/dist/runtime/server/{sw-handler.d.ts → bluesky-embed-image.d.ts} +1 -1
- package/dist/runtime/server/bluesky-embed-image.js +7 -0
- package/dist/runtime/server/bluesky-embed.d.ts +16 -0
- package/dist/runtime/server/bluesky-embed.js +59 -0
- package/dist/runtime/server/google-maps-geocode-proxy.d.ts +2 -0
- package/dist/runtime/server/google-maps-geocode-proxy.js +34 -0
- package/dist/runtime/server/google-static-maps-proxy.js +2 -13
- package/dist/runtime/server/gravatar-proxy.d.ts +2 -0
- package/dist/runtime/server/gravatar-proxy.js +46 -0
- package/dist/runtime/server/instagram-embed-asset.js +8 -41
- package/dist/runtime/server/instagram-embed-image.js +6 -53
- package/dist/runtime/server/instagram-embed.d.ts +16 -0
- package/dist/runtime/server/instagram-embed.js +173 -35
- package/dist/runtime/server/proxy-handler.js +144 -113
- package/dist/runtime/server/utils/image-proxy.d.ts +12 -0
- package/dist/runtime/server/utils/image-proxy.js +70 -0
- package/dist/runtime/server/utils/privacy.d.ts +1 -2
- package/dist/runtime/server/utils/privacy.js +54 -34
- package/dist/runtime/server/x-embed-image.js +5 -49
- package/dist/runtime/server/x-embed.js +3 -2
- package/dist/runtime/types.d.ts +74 -40
- package/dist/runtime/utils/pure.d.ts +1 -5
- package/dist/runtime/utils/pure.js +0 -67
- package/dist/runtime/utils.d.ts +4 -3
- package/dist/runtime/utils.js +24 -10
- package/dist/shared/scripts.D7e2ENu6.mjs +211 -0
- package/dist/stats.d.mts +202 -0
- package/dist/stats.d.ts +202 -0
- package/dist/stats.mjs +3860 -0
- package/dist/types-source.d.mts +17 -0
- package/dist/types-source.d.ts +17 -0
- package/dist/types-source.mjs +3614 -0
- package/package.json +52 -38
- package/dist/client/_nuxt/D-kOnTuH.js +0 -162
- package/dist/client/_nuxt/builds/meta/f1474569-6922-450d-bc3f-4fd5f3e1391a.json +0 -1
- package/dist/client/_nuxt/entry.D45OuV0w.css +0 -1
- package/dist/client/_nuxt/error-404.B57D-jUQ.css +0 -1
- package/dist/client/_nuxt/error-500.DTHUW7BI.css +0 -1
- package/dist/runtime/components/ScriptPayPalMarks.d.vue.ts +0 -52
- package/dist/runtime/components/ScriptPayPalMarks.vue +0 -69
- package/dist/runtime/components/ScriptPayPalMarks.vue.d.ts +0 -52
- package/dist/runtime/plugins/sw-register.client.d.ts +0 -2
- package/dist/runtime/plugins/sw-register.client.js +0 -12
- package/dist/runtime/server/sw-handler.js +0 -25
- package/dist/runtime/sw/proxy-sw.template.d.ts +0 -1
- package/dist/runtime/sw/proxy-sw.template.js +0 -54
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
3
2
|
import { defu } from "defu";
|
|
4
3
|
import { useAsyncData, useHead } from "nuxt/app";
|
|
4
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
5
5
|
import { useScriptTriggerElement } from "../composables/useScriptTriggerElement";
|
|
6
6
|
import { useScriptVimeoPlayer } from "../registry/vimeo-player";
|
|
7
7
|
import ScriptAriaLoadingIndicator from "./ScriptAriaLoadingIndicator.vue";
|
|
@@ -12,7 +12,9 @@ const props = defineProps({
|
|
|
12
12
|
aboveTheFold: { type: Boolean, required: false },
|
|
13
13
|
vimeoOptions: { type: Object, required: false },
|
|
14
14
|
id: { type: null, required: false },
|
|
15
|
-
url: { type: null, required: false }
|
|
15
|
+
url: { type: null, required: false },
|
|
16
|
+
ratio: { type: String, required: false, default: "16/9" },
|
|
17
|
+
placeholderObjectFit: { type: String, required: false, default: "contain" }
|
|
16
18
|
});
|
|
17
19
|
const emits = defineEmits(["play", "playing", "pause", "ended", "timeupdate", "progress", "seeking", "seeked", "texttrackchange", "chapterchange", "cuechange", "cuepoint", "volumechange", "playbackratechange", "bufferstart", "bufferend", "error", "loaded", "durationchange", "fullscreenchange", "qualitychange", "camerachange", "resize", "enterpictureinpicture", "leavepictureinpicture"]);
|
|
18
20
|
const events = [
|
|
@@ -153,12 +155,13 @@ const rootAttrs = computed(() => {
|
|
|
153
155
|
"aria-live": "polite",
|
|
154
156
|
"role": "application",
|
|
155
157
|
"style": {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
"--vimeo-ratio": props.ratio,
|
|
159
|
+
"maxWidth": "100%",
|
|
160
|
+
"width": `auto`,
|
|
161
|
+
"height": "auto",
|
|
162
|
+
"aspectRatio": props.ratio,
|
|
163
|
+
"position": "relative",
|
|
164
|
+
"backgroundColor": "black"
|
|
162
165
|
},
|
|
163
166
|
...trigger instanceof Promise ? trigger.ssrAttrs || {} : {}
|
|
164
167
|
});
|
|
@@ -173,7 +176,7 @@ const placeholderAttrs = computed(() => {
|
|
|
173
176
|
style: {
|
|
174
177
|
cursor: "pointer",
|
|
175
178
|
width: "100%",
|
|
176
|
-
objectFit:
|
|
179
|
+
objectFit: props.placeholderObjectFit,
|
|
177
180
|
height: "100%"
|
|
178
181
|
}
|
|
179
182
|
});
|
|
@@ -197,5 +200,5 @@ onBeforeUnmount(() => player?.unload());
|
|
|
197
200
|
</template>
|
|
198
201
|
|
|
199
202
|
<style>
|
|
200
|
-
.vimeo-player iframe{aspect-ratio:16/9;height:auto;max-width:100%!important;width:100%}
|
|
203
|
+
.vimeo-player iframe{aspect-ratio:var(--vimeo-ratio,16/9);height:auto;max-width:100%!important;width:100%}
|
|
201
204
|
</style>
|
|
@@ -36,6 +36,13 @@ type __VLS_Props = {
|
|
|
36
36
|
vimeoOptions?: VimeoOptions;
|
|
37
37
|
id?: number | undefined;
|
|
38
38
|
url?: string | undefined;
|
|
39
|
+
ratio?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Object-fit for the placeholder image.
|
|
42
|
+
*
|
|
43
|
+
* @default 'contain'
|
|
44
|
+
*/
|
|
45
|
+
placeholderObjectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
39
46
|
};
|
|
40
47
|
declare var __VLS_1: any, __VLS_3: {}, __VLS_10: {}, __VLS_12: {}, __VLS_14: {};
|
|
41
48
|
type __VLS_Slots = {} & {
|
|
@@ -117,6 +124,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
117
124
|
onLeavepictureinpicture?: ((event: never, player: Vimeo.Player) => any) | undefined;
|
|
118
125
|
}>, {
|
|
119
126
|
trigger: ElementScriptTrigger;
|
|
127
|
+
ratio: string;
|
|
128
|
+
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
120
129
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
121
130
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
122
131
|
declare const _default: typeof __VLS_export;
|
|
@@ -7,12 +7,12 @@ type __VLS_Props = {
|
|
|
7
7
|
tweetId: string;
|
|
8
8
|
/**
|
|
9
9
|
* Custom API endpoint for fetching tweet data
|
|
10
|
-
* @default '/_scripts/x
|
|
10
|
+
* @default '/_scripts/embed/x'
|
|
11
11
|
*/
|
|
12
12
|
apiEndpoint?: string;
|
|
13
13
|
/**
|
|
14
14
|
* Custom image proxy endpoint
|
|
15
|
-
* @default '/_scripts/x-
|
|
15
|
+
* @default '/_scripts/embed/x-image'
|
|
16
16
|
*/
|
|
17
17
|
imageProxyEndpoint?: string;
|
|
18
18
|
/**
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed } from "vue";
|
|
3
2
|
import { useAsyncData } from "nuxt/app";
|
|
3
|
+
import { computed } from "vue";
|
|
4
4
|
import { formatCount, formatTweetDate, proxyXImageUrl } from "../registry/x-embed";
|
|
5
|
+
import { requireRegistryEndpoint } from "../utils";
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
tweetId: { type: String, required: true },
|
|
7
|
-
apiEndpoint: { type: String, required: false, default: "/
|
|
8
|
-
imageProxyEndpoint: { type: String, required: false, default: "/
|
|
8
|
+
apiEndpoint: { type: String, required: false, default: "/_scripts/embed/x" },
|
|
9
|
+
imageProxyEndpoint: { type: String, required: false, default: "/_scripts/embed/x-image" },
|
|
9
10
|
rootAttrs: { type: Object, required: false }
|
|
10
11
|
});
|
|
12
|
+
if (!props.apiEndpoint || props.apiEndpoint === "/_scripts/embed/x")
|
|
13
|
+
requireRegistryEndpoint("ScriptXEmbed", "xEmbed");
|
|
11
14
|
const cacheKey = computed(() => `x-embed-${props.tweetId}`);
|
|
12
15
|
const { data: tweet, status, error } = useAsyncData(
|
|
13
16
|
cacheKey,
|
|
@@ -7,12 +7,12 @@ type __VLS_Props = {
|
|
|
7
7
|
tweetId: string;
|
|
8
8
|
/**
|
|
9
9
|
* Custom API endpoint for fetching tweet data
|
|
10
|
-
* @default '/_scripts/x
|
|
10
|
+
* @default '/_scripts/embed/x'
|
|
11
11
|
*/
|
|
12
12
|
apiEndpoint?: string;
|
|
13
13
|
/**
|
|
14
14
|
* Custom image proxy endpoint
|
|
15
|
-
* @default '/_scripts/x-
|
|
15
|
+
* @default '/_scripts/embed/x-image'
|
|
16
16
|
*/
|
|
17
17
|
imageProxyEndpoint?: string;
|
|
18
18
|
/**
|
|
@@ -61,12 +61,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
61
61
|
trigger: ElementScriptTrigger;
|
|
62
62
|
width: number;
|
|
63
63
|
height: number;
|
|
64
|
-
playerVars: YT.PlayerVars;
|
|
65
64
|
ratio: string;
|
|
65
|
+
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
66
|
+
playerVars: YT.PlayerVars;
|
|
66
67
|
cookies: boolean;
|
|
67
68
|
thumbnailSize: YoutubeThumbnailSize;
|
|
68
69
|
webp: boolean;
|
|
69
|
-
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
70
70
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
71
71
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
72
72
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
3
2
|
import { defu } from "defu";
|
|
4
3
|
import { useHead } from "nuxt/app";
|
|
4
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
|
5
5
|
import { useScriptTriggerElement } from "../composables/useScriptTriggerElement";
|
|
6
6
|
import { useScriptYouTubePlayer } from "../registry/youtube-player";
|
|
7
7
|
import ScriptAriaLoadingIndicator from "./ScriptAriaLoadingIndicator.vue";
|
|
@@ -30,6 +30,7 @@ const events = [
|
|
|
30
30
|
"onError",
|
|
31
31
|
"onApiChange"
|
|
32
32
|
];
|
|
33
|
+
const CAMEL_CASE_RE = /([A-Z])/g;
|
|
33
34
|
const rootEl = ref();
|
|
34
35
|
const youtubeEl = ref();
|
|
35
36
|
const ready = ref(false);
|
|
@@ -70,9 +71,11 @@ onMounted(() => {
|
|
|
70
71
|
onLoaded(async (instance) => {
|
|
71
72
|
if (!isTriggered.value && trigger instanceof Promise) {
|
|
72
73
|
const triggered = await trigger;
|
|
73
|
-
if (!triggered)
|
|
74
|
+
if (!triggered)
|
|
75
|
+
return;
|
|
74
76
|
}
|
|
75
|
-
if (!youtubeEl.value)
|
|
77
|
+
if (!youtubeEl.value)
|
|
78
|
+
return;
|
|
76
79
|
const YouTube = instance.YT instanceof Promise ? await instance.YT : instance.YT;
|
|
77
80
|
await new Promise((resolve) => {
|
|
78
81
|
if (typeof YT.Player === "undefined")
|
|
@@ -80,7 +83,8 @@ onMounted(() => {
|
|
|
80
83
|
else
|
|
81
84
|
resolve();
|
|
82
85
|
});
|
|
83
|
-
if (!youtubeEl.value)
|
|
86
|
+
if (!youtubeEl.value)
|
|
87
|
+
return;
|
|
84
88
|
player.value = new YT.Player(youtubeEl.value, {
|
|
85
89
|
host: !props.cookies ? "https://www.youtube-nocookie.com" : "https://www.youtube.com",
|
|
86
90
|
videoId: props.videoId,
|
|
@@ -89,7 +93,7 @@ onMounted(() => {
|
|
|
89
93
|
playerVars: props.playerVars,
|
|
90
94
|
...props.playerOptions,
|
|
91
95
|
events: Object.fromEntries(events.map((event) => [event, (e) => {
|
|
92
|
-
const emitEventName = event.replace(
|
|
96
|
+
const emitEventName = event.replace(CAMEL_CASE_RE, "-$1").replace("on-", "").toLowerCase();
|
|
93
97
|
emits(emitEventName, e);
|
|
94
98
|
if (event === "onReady") {
|
|
95
99
|
ready.value = true;
|
|
@@ -151,6 +155,8 @@ const placeholderAttrs = computed(() => {
|
|
|
151
155
|
src: isFallbackPlaceHolder.value ? fallbackPlaceHolder.value : placeholder.value,
|
|
152
156
|
alt: "",
|
|
153
157
|
loading: props.aboveTheFold ? "eager" : "lazy",
|
|
158
|
+
// @ts-expect-error untyped
|
|
159
|
+
fetchpriority: props.aboveTheFold ? "high" : void 0,
|
|
154
160
|
style: {
|
|
155
161
|
width: "100%",
|
|
156
162
|
objectFit: props.placeholderObjectFit,
|
|
@@ -61,12 +61,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
|
61
61
|
trigger: ElementScriptTrigger;
|
|
62
62
|
width: number;
|
|
63
63
|
height: number;
|
|
64
|
-
playerVars: YT.PlayerVars;
|
|
65
64
|
ratio: string;
|
|
65
|
+
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
66
|
+
playerVars: YT.PlayerVars;
|
|
66
67
|
cookies: boolean;
|
|
67
68
|
thumbnailSize: YoutubeThumbnailSize;
|
|
68
69
|
webp: boolean;
|
|
69
|
-
placeholderObjectFit: "cover" | "contain" | "fill" | "none" | "scale-down";
|
|
70
70
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
71
71
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
72
72
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveTrigger } from "#build/nuxt-scripts-trigger-resolver";
|
|
2
2
|
import { useScript as _useScript } from "@unhead/vue/scripts";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { defu } from "defu";
|
|
4
|
+
import { injectHead, onNuxtReady, useHead, useNuxtApp, useRuntimeConfig } from "nuxt/app";
|
|
5
|
+
import { markRaw, ref } from "vue";
|
|
5
6
|
import { logger } from "../logger.js";
|
|
6
|
-
|
|
7
|
+
function ensureScripts(nuxtApp) {
|
|
8
|
+
if (!nuxtApp.$scripts) {
|
|
9
|
+
nuxtApp.$scripts = {};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
7
12
|
function useNuxtScriptRuntimeConfig() {
|
|
8
13
|
return useRuntimeConfig().public["nuxt-scripts"];
|
|
9
14
|
}
|
|
@@ -22,7 +27,7 @@ export function useScript(input, options) {
|
|
|
22
27
|
script: [{ src, type: "text/partytown" }]
|
|
23
28
|
});
|
|
24
29
|
const nuxtApp2 = useNuxtApp();
|
|
25
|
-
nuxtApp2
|
|
30
|
+
ensureScripts(nuxtApp2);
|
|
26
31
|
const status = ref("loaded");
|
|
27
32
|
const stub = {
|
|
28
33
|
id: src,
|
|
@@ -50,7 +55,7 @@ export function useScript(input, options) {
|
|
|
50
55
|
if (!options.head) {
|
|
51
56
|
throw new Error("useScript() has been called without Nuxt context.");
|
|
52
57
|
}
|
|
53
|
-
nuxtApp
|
|
58
|
+
ensureScripts(nuxtApp);
|
|
54
59
|
const exists = !!nuxtApp.$scripts?.[id];
|
|
55
60
|
const err = options._validate?.();
|
|
56
61
|
if (import.meta.dev && import.meta.client && err) {
|
|
@@ -152,5 +157,7 @@ export function useScript(input, options) {
|
|
|
152
157
|
syncScripts();
|
|
153
158
|
}
|
|
154
159
|
}
|
|
160
|
+
markRaw(instance);
|
|
161
|
+
instance.toJSON = () => ({ id: instance.id, status: instance.status.value });
|
|
155
162
|
return instance;
|
|
156
163
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useNuxtApp, useRoute
|
|
2
|
-
import {
|
|
1
|
+
import { injectHead, useNuxtApp, useRoute } from "nuxt/app";
|
|
2
|
+
import { onScopeDispose, ref } from "vue";
|
|
3
3
|
export function useScriptEventPage(onChange) {
|
|
4
4
|
const nuxt = useNuxtApp();
|
|
5
5
|
const route = useRoute();
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
1
2
|
import type { ConsentScriptTriggerOptions } from '../types.js';
|
|
2
3
|
interface UseConsentScriptTriggerApi extends Promise<void> {
|
|
3
4
|
/**
|
|
4
5
|
* A function that can be called to accept the consent and load the script.
|
|
5
6
|
*/
|
|
6
7
|
accept: () => void;
|
|
8
|
+
/**
|
|
9
|
+
* A function that can be called to revoke consent and signal the script should be unloaded.
|
|
10
|
+
*/
|
|
11
|
+
revoke: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Reactive reference to the consent state
|
|
14
|
+
*/
|
|
15
|
+
consented: Ref<boolean>;
|
|
7
16
|
}
|
|
8
17
|
/**
|
|
9
18
|
* Load a script once consent has been provided either through a resolvable `consent` or calling the `accept` method.
|
|
19
|
+
* Supports revoking consent via the reactive `consented` ref. Consumers should watch `consented` to react to revocation.
|
|
10
20
|
* @param options
|
|
11
21
|
*/
|
|
12
22
|
export declare function useScriptTriggerConsent(options?: ConsentScriptTriggerOptions): UseConsentScriptTriggerApi;
|
|
@@ -1,14 +1,37 @@
|
|
|
1
|
+
import { onNuxtReady, requestIdleCallback, tryUseNuxtApp } from "nuxt/app";
|
|
1
2
|
import { isRef, ref, toValue, watch } from "vue";
|
|
2
|
-
import { tryUseNuxtApp, onNuxtReady, requestIdleCallback } from "nuxt/app";
|
|
3
3
|
export function useScriptTriggerConsent(options) {
|
|
4
|
-
if (import.meta.server)
|
|
5
|
-
|
|
4
|
+
if (import.meta.server) {
|
|
5
|
+
const p = new Promise(() => {
|
|
6
6
|
});
|
|
7
|
+
p.accept = () => {
|
|
8
|
+
};
|
|
9
|
+
p.revoke = () => {
|
|
10
|
+
};
|
|
11
|
+
p.consented = ref(false);
|
|
12
|
+
return p;
|
|
13
|
+
}
|
|
7
14
|
const consented = ref(false);
|
|
8
15
|
const nuxtApp = tryUseNuxtApp();
|
|
16
|
+
if (options?.consent) {
|
|
17
|
+
if (isRef(options?.consent)) {
|
|
18
|
+
watch(options.consent, (_val) => {
|
|
19
|
+
const val = toValue(_val);
|
|
20
|
+
consented.value = Boolean(val);
|
|
21
|
+
}, { immediate: true });
|
|
22
|
+
} else if (typeof options?.consent === "boolean") {
|
|
23
|
+
consented.value = options?.consent;
|
|
24
|
+
} else if (options?.consent instanceof Promise) {
|
|
25
|
+
options.consent.then((res) => {
|
|
26
|
+
consented.value = typeof res === "boolean" ? res : true;
|
|
27
|
+
}).catch(() => {
|
|
28
|
+
consented.value = false;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
9
32
|
const promise = new Promise((resolve) => {
|
|
10
|
-
watch(consented, (
|
|
11
|
-
if (
|
|
33
|
+
watch(consented, (newValue, oldValue) => {
|
|
34
|
+
if (newValue && !oldValue) {
|
|
12
35
|
const runner = nuxtApp?.runWithContext || ((cb) => cb());
|
|
13
36
|
if (options?.postConsentTrigger instanceof Promise) {
|
|
14
37
|
options.postConsentTrigger.then(() => runner(resolve));
|
|
@@ -32,24 +55,14 @@ export function useScriptTriggerConsent(options) {
|
|
|
32
55
|
}
|
|
33
56
|
runner(resolve);
|
|
34
57
|
}
|
|
35
|
-
});
|
|
36
|
-
if (options?.consent) {
|
|
37
|
-
if (isRef(options?.consent)) {
|
|
38
|
-
watch(options.consent, (_val) => {
|
|
39
|
-
const val = toValue(_val);
|
|
40
|
-
consented.value = Boolean(val);
|
|
41
|
-
}, { immediate: true });
|
|
42
|
-
} else if (typeof options?.consent === "boolean") {
|
|
43
|
-
consented.value = options?.consent;
|
|
44
|
-
} else if (options?.consent instanceof Promise) {
|
|
45
|
-
options?.consent.then((res) => {
|
|
46
|
-
consented.value = typeof res === "boolean" ? res : true;
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
58
|
+
}, { immediate: true });
|
|
50
59
|
});
|
|
51
60
|
promise.accept = () => {
|
|
52
61
|
consented.value = true;
|
|
53
62
|
};
|
|
63
|
+
promise.revoke = () => {
|
|
64
|
+
consented.value = false;
|
|
65
|
+
};
|
|
66
|
+
promise.consented = consented;
|
|
54
67
|
return promise;
|
|
55
68
|
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
useEventListener,
|
|
3
3
|
useIntersectionObserver
|
|
4
4
|
} from "@vueuse/core";
|
|
5
|
-
import {
|
|
5
|
+
import { tryOnMounted, tryOnScopeDispose } from "@vueuse/shared";
|
|
6
6
|
import { watch } from "vue";
|
|
7
7
|
function useElementVisibilityPromise(element) {
|
|
8
8
|
let observer;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { tryOnScopeDispose } from "@vueuse/shared";
|
|
2
1
|
import { useTimeoutFn } from "@vueuse/core";
|
|
2
|
+
import { tryOnScopeDispose } from "@vueuse/shared";
|
|
3
3
|
import { onNuxtReady } from "nuxt/app";
|
|
4
4
|
export function useScriptTriggerIdleTimeout(options) {
|
|
5
5
|
if (import.meta.server) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RegistryScriptInput } from '#nuxt-scripts/types';
|
|
2
|
+
import { BingUetOptions } from './schemas.js';
|
|
3
|
+
export { BingUetOptions };
|
|
4
|
+
export type BingUetInput = RegistryScriptInput<typeof BingUetOptions, true, false>;
|
|
5
|
+
export interface BingUetApi {
|
|
6
|
+
uetq: {
|
|
7
|
+
push: (event: string | Record<string, any>) => void;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
declare global {
|
|
11
|
+
interface Window {
|
|
12
|
+
UET: new (options: {
|
|
13
|
+
ti: string;
|
|
14
|
+
enableAutoSpaTracking?: boolean;
|
|
15
|
+
q?: any[];
|
|
16
|
+
}) => BingUetApi['uetq'];
|
|
17
|
+
uetq: any[] | BingUetApi['uetq'];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export declare function useScriptBingUet<T extends BingUetApi>(_options?: BingUetInput): import("#nuxt-scripts/types").UseScriptContext<T>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useRegistryScript } from "../utils.js";
|
|
2
|
+
import { BingUetOptions } from "./schemas.js";
|
|
3
|
+
export { BingUetOptions };
|
|
4
|
+
export function useScriptBingUet(_options) {
|
|
5
|
+
return useRegistryScript("bingUet", (options) => ({
|
|
6
|
+
scriptInput: {
|
|
7
|
+
src: "https://bat.bing.com/bat.js",
|
|
8
|
+
crossorigin: false
|
|
9
|
+
},
|
|
10
|
+
schema: import.meta.dev ? BingUetOptions : void 0,
|
|
11
|
+
scriptOptions: {
|
|
12
|
+
use() {
|
|
13
|
+
if (options?.id && typeof window.UET === "function" && Array.isArray(window.uetq)) {
|
|
14
|
+
const uetOptions = {
|
|
15
|
+
ti: options.id,
|
|
16
|
+
enableAutoSpaTracking: options.enableAutoSpaTracking ?? true,
|
|
17
|
+
q: window.uetq
|
|
18
|
+
};
|
|
19
|
+
window.uetq = new window.UET(uetOptions);
|
|
20
|
+
window.uetq.push("pageLoad");
|
|
21
|
+
}
|
|
22
|
+
return { uetq: window.uetq };
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
clientInit: import.meta.server ? void 0 : () => {
|
|
26
|
+
window.uetq = window.uetq || [];
|
|
27
|
+
}
|
|
28
|
+
}), _options);
|
|
29
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { RegistryScriptInput } from '#nuxt-scripts/types';
|
|
2
|
+
import { BlueskyEmbedOptions } from './schemas.js';
|
|
3
|
+
export { BlueskyEmbedOptions };
|
|
4
|
+
export interface BlueskyEmbedPostData {
|
|
5
|
+
uri: string;
|
|
6
|
+
cid: string;
|
|
7
|
+
author: {
|
|
8
|
+
did: string;
|
|
9
|
+
handle: string;
|
|
10
|
+
displayName: string;
|
|
11
|
+
avatar: string;
|
|
12
|
+
labels: Array<{
|
|
13
|
+
val: string;
|
|
14
|
+
}>;
|
|
15
|
+
verification?: {
|
|
16
|
+
verifiedStatus: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
record: {
|
|
20
|
+
$type: string;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
text: string;
|
|
23
|
+
langs?: string[];
|
|
24
|
+
facets?: Array<{
|
|
25
|
+
features: Array<{
|
|
26
|
+
$type: string;
|
|
27
|
+
uri?: string;
|
|
28
|
+
did?: string;
|
|
29
|
+
tag?: string;
|
|
30
|
+
}>;
|
|
31
|
+
index: {
|
|
32
|
+
byteStart: number;
|
|
33
|
+
byteEnd: number;
|
|
34
|
+
};
|
|
35
|
+
}>;
|
|
36
|
+
embed?: {
|
|
37
|
+
$type: string;
|
|
38
|
+
images?: Array<{
|
|
39
|
+
alt: string;
|
|
40
|
+
image: {
|
|
41
|
+
ref: {
|
|
42
|
+
$link: string;
|
|
43
|
+
};
|
|
44
|
+
mimeType: string;
|
|
45
|
+
size: number;
|
|
46
|
+
};
|
|
47
|
+
aspectRatio?: {
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
};
|
|
51
|
+
}>;
|
|
52
|
+
external?: {
|
|
53
|
+
uri: string;
|
|
54
|
+
title: string;
|
|
55
|
+
description: string;
|
|
56
|
+
thumb?: {
|
|
57
|
+
ref: {
|
|
58
|
+
$link: string;
|
|
59
|
+
};
|
|
60
|
+
mimeType: string;
|
|
61
|
+
size: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
embed?: {
|
|
67
|
+
$type: string;
|
|
68
|
+
images?: Array<{
|
|
69
|
+
thumb: string;
|
|
70
|
+
fullsize: string;
|
|
71
|
+
alt: string;
|
|
72
|
+
aspectRatio?: {
|
|
73
|
+
width: number;
|
|
74
|
+
height: number;
|
|
75
|
+
};
|
|
76
|
+
}>;
|
|
77
|
+
external?: {
|
|
78
|
+
uri: string;
|
|
79
|
+
title: string;
|
|
80
|
+
description: string;
|
|
81
|
+
thumb?: string;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
likeCount: number;
|
|
85
|
+
repostCount: number;
|
|
86
|
+
replyCount: number;
|
|
87
|
+
quoteCount: number;
|
|
88
|
+
indexedAt: string;
|
|
89
|
+
labels: Array<{
|
|
90
|
+
val: string;
|
|
91
|
+
}>;
|
|
92
|
+
}
|
|
93
|
+
export type BlueskyEmbedInput = RegistryScriptInput<typeof BlueskyEmbedOptions, false, false>;
|
|
94
|
+
/**
|
|
95
|
+
* Extract the handle/DID and post rkey from a Bluesky post URL
|
|
96
|
+
*/
|
|
97
|
+
export declare function extractBlueskyPostId(url: string): {
|
|
98
|
+
actor: string;
|
|
99
|
+
rkey: string;
|
|
100
|
+
} | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Proxy a Bluesky image URL through the server
|
|
103
|
+
*/
|
|
104
|
+
export declare function proxyBlueskyImageUrl(url: string, proxyEndpoint?: string): string;
|
|
105
|
+
/**
|
|
106
|
+
* Format a Bluesky post date for display
|
|
107
|
+
*/
|
|
108
|
+
export declare function formatBlueskyDate(dateString: string): string;
|
|
109
|
+
/**
|
|
110
|
+
* Format a number for display (e.g., 1234 -> 1.2K)
|
|
111
|
+
*/
|
|
112
|
+
export declare function formatCount(count: number): string;
|
|
113
|
+
/**
|
|
114
|
+
* Convert Bluesky facets (byte-range rich text annotations) to HTML
|
|
115
|
+
*/
|
|
116
|
+
export declare function facetsToHtml(text: string, facets?: BlueskyEmbedPostData['record']['facets']): string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { BlueskyEmbedOptions } from "./schemas.js";
|
|
2
|
+
export { BlueskyEmbedOptions };
|
|
3
|
+
const BSKY_POST_URL_RE = /bsky\.app\/profile\/([^/]+)\/post\/([^/?]+)/;
|
|
4
|
+
export function extractBlueskyPostId(url) {
|
|
5
|
+
const match = url.match(BSKY_POST_URL_RE);
|
|
6
|
+
if (!match)
|
|
7
|
+
return void 0;
|
|
8
|
+
return { actor: match[1], rkey: match[2] };
|
|
9
|
+
}
|
|
10
|
+
export function proxyBlueskyImageUrl(url, proxyEndpoint = "/_scripts/embed/bluesky-image") {
|
|
11
|
+
const separator = proxyEndpoint.includes("?") ? "&" : "?";
|
|
12
|
+
return `${proxyEndpoint}${separator}url=${encodeURIComponent(url)}`;
|
|
13
|
+
}
|
|
14
|
+
export function formatBlueskyDate(dateString) {
|
|
15
|
+
const date = new Date(dateString);
|
|
16
|
+
const time = date.toLocaleString("en-US", {
|
|
17
|
+
hour: "numeric",
|
|
18
|
+
minute: "numeric",
|
|
19
|
+
hour12: true,
|
|
20
|
+
timeZone: "UTC"
|
|
21
|
+
});
|
|
22
|
+
const month = date.toLocaleString("en-US", { month: "short", timeZone: "UTC" });
|
|
23
|
+
return `${time} \xB7 ${month} ${date.getUTCDate()}, ${date.getUTCFullYear()}`;
|
|
24
|
+
}
|
|
25
|
+
export function formatCount(count) {
|
|
26
|
+
if (count >= 1e6) {
|
|
27
|
+
return `${(count / 1e6).toFixed(1)}M`;
|
|
28
|
+
}
|
|
29
|
+
if (count >= 1e3) {
|
|
30
|
+
return `${(count / 1e3).toFixed(1)}K`;
|
|
31
|
+
}
|
|
32
|
+
return count.toString();
|
|
33
|
+
}
|
|
34
|
+
export function facetsToHtml(text, facets) {
|
|
35
|
+
if (!facets?.length)
|
|
36
|
+
return escapeHtml(text);
|
|
37
|
+
const encoder = new TextEncoder();
|
|
38
|
+
const decoder = new TextDecoder();
|
|
39
|
+
const bytes = encoder.encode(text);
|
|
40
|
+
const sorted = facets.toSorted((a, b) => a.index.byteStart - b.index.byteStart);
|
|
41
|
+
const parts = [];
|
|
42
|
+
let lastEnd = 0;
|
|
43
|
+
for (const facet of sorted) {
|
|
44
|
+
if (facet.index.byteStart > lastEnd) {
|
|
45
|
+
parts.push(escapeHtml(decoder.decode(bytes.slice(lastEnd, facet.index.byteStart))));
|
|
46
|
+
}
|
|
47
|
+
const facetText = escapeHtml(decoder.decode(bytes.slice(facet.index.byteStart, facet.index.byteEnd)));
|
|
48
|
+
for (const feature of facet.features) {
|
|
49
|
+
if (feature.$type === "app.bsky.richtext.facet#link" && feature.uri) {
|
|
50
|
+
parts.push(`<a href="${escapeHtml(feature.uri)}" target="_blank" rel="noopener noreferrer">${facetText}</a>`);
|
|
51
|
+
} else if (feature.$type === "app.bsky.richtext.facet#mention" && feature.did) {
|
|
52
|
+
parts.push(`<a href="https://bsky.app/profile/${escapeHtml(feature.did)}" target="_blank" rel="noopener noreferrer">${facetText}</a>`);
|
|
53
|
+
} else if (feature.$type === "app.bsky.richtext.facet#tag" && feature.tag) {
|
|
54
|
+
parts.push(`<a href="https://bsky.app/hashtag/${escapeHtml(feature.tag)}" target="_blank" rel="noopener noreferrer">${facetText}</a>`);
|
|
55
|
+
} else {
|
|
56
|
+
parts.push(facetText);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
lastEnd = facet.index.byteEnd;
|
|
60
|
+
}
|
|
61
|
+
if (lastEnd < bytes.length) {
|
|
62
|
+
parts.push(escapeHtml(decoder.decode(bytes.slice(lastEnd))));
|
|
63
|
+
}
|
|
64
|
+
return parts.join("");
|
|
65
|
+
}
|
|
66
|
+
const AMP_RE = /&/g;
|
|
67
|
+
const LT_RE = /</g;
|
|
68
|
+
const GT_RE = />/g;
|
|
69
|
+
const QUOT_RE = /"/g;
|
|
70
|
+
function escapeHtml(str) {
|
|
71
|
+
return str.replace(AMP_RE, "&").replace(LT_RE, "<").replace(GT_RE, ">").replace(QUOT_RE, """);
|
|
72
|
+
}
|