4020ad62c5
- Implemented `resolveApiAssetUrl` function to normalize asset URLs based on API base. - Updated `MedialibImage` component to utilize new asset URL resolution and added support for alt text and class properties. - Enhanced image loading behavior with improved width measurement and focal point handling. - Added placeholder image handling and improved accessibility with alt text. - Introduced new test script for auditing broken links in skill documentation. - Expanded seeded test content to include medialib entries and updated related tests for pagebuilder previews. - Improved global setup and teardown logging for clarity on seeded content management.
92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
import { get } from "svelte/store"
|
|
import { apiBaseURL } from "../config"
|
|
import { apiBaseOverride } from "./store"
|
|
|
|
function isAbsoluteUrl(url: string | undefined): boolean {
|
|
return !!url && (/^(?:https?:)?\/\//.test(url) || url.startsWith("data:") || url.startsWith("blob:"))
|
|
}
|
|
|
|
function normalizeBase(base: string | null | undefined): string | null {
|
|
return base ? base.replace(/\/+$/, "") + "/" : null
|
|
}
|
|
|
|
export function resolveApiAssetUrl(
|
|
url: string | null | undefined,
|
|
apiBase: string | null | undefined = get(apiBaseOverride) || apiBaseURL
|
|
): string | null | undefined {
|
|
if (!url || isAbsoluteUrl(url) || !url.startsWith("/assets/")) {
|
|
return url
|
|
}
|
|
|
|
const normalizedApiBase = normalizeBase(apiBase)
|
|
|
|
if (!normalizedApiBase) {
|
|
return url
|
|
}
|
|
|
|
return normalizedApiBase + "_/assets/" + url.replace(/^\/+/, "")
|
|
}
|
|
|
|
export function debounce<T extends (...args: never[]) => void>(
|
|
func: T,
|
|
wait: number
|
|
): (...args: Parameters<T>) => void {
|
|
let timeout: ReturnType<typeof setTimeout> | null = null
|
|
|
|
return (...args: Parameters<T>) => {
|
|
if (timeout) {
|
|
clearTimeout(timeout)
|
|
}
|
|
timeout = setTimeout(() => func(...args), wait)
|
|
}
|
|
}
|
|
|
|
export function formatNumber(number: number, decimals = 2): string {
|
|
return number.toFixed(decimals)
|
|
}
|
|
|
|
export function formatCurrency(amount: number, currency = "EUR", locale = "de-DE"): string {
|
|
// goja (tibi-server SSR runtime) does not provide Intl
|
|
if (typeof Intl === "undefined") {
|
|
const fixed = amount.toFixed(2).replace(".", ",")
|
|
return `${fixed}\u00A0${currency === "EUR" ? "€" : currency}`
|
|
}
|
|
return new Intl.NumberFormat(locale, {
|
|
style: "currency",
|
|
currency: currency,
|
|
}).format(amount)
|
|
}
|
|
|
|
export function generateMockImage(seed: string): string {
|
|
// Generate a consistent color based on the seed
|
|
const colors = [
|
|
"bg-red-200",
|
|
"bg-blue-200",
|
|
"bg-green-200",
|
|
"bg-yellow-200",
|
|
"bg-purple-200",
|
|
"bg-pink-200",
|
|
"bg-indigo-200",
|
|
"bg-teal-200",
|
|
]
|
|
|
|
const colorIndex = seed.split("").reduce((acc, char) => acc + char.charCodeAt(0), 0) % colors.length
|
|
return colors[colorIndex]
|
|
}
|
|
|
|
export function highlightSearchTerm(text: string, searchTerm: string): string {
|
|
if (!searchTerm.trim()) return text
|
|
|
|
const regex = new RegExp(`(${searchTerm})`, "gi")
|
|
return text.replace(regex, '<mark class="bg-yellow-200">$1</mark>')
|
|
}
|
|
|
|
export function slugify(value: string): string {
|
|
return value
|
|
.normalize("NFD")
|
|
.replace(/[\u0300-\u036f]/g, "")
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, "-")
|
|
.replace(/(^-|-$)/g, "")
|
|
}
|