accessify-widget 0.3.79 → 0.3.80

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.
@@ -1,4 +1,4 @@
1
- import { d, i } from "./index-BUfTIuEG.js";
1
+ import { d, i } from "./index-CPFBQbTr.js";
2
2
  export {
3
3
  d as destroy,
4
4
  i as init
@@ -1,4 +1,4 @@
1
- import { g as getCurrentWidgetLang } from "./index-BUfTIuEG.js";
1
+ import { g as getCurrentWidgetLang } from "./index-CPFBQbTr.js";
2
2
  const IDB_NAME = "accessify-alt-text-cache";
3
3
  const IDB_STORE = "alt-texts";
4
4
  const IDB_VERSION = 2;
@@ -742,4 +742,4 @@ export {
742
742
  autoApplyCachedAltTexts,
743
743
  createAltTextModule as default
744
744
  };
745
- //# sourceMappingURL=alt-text-D_iJlJtX.js.map
745
+ //# sourceMappingURL=alt-text-BhMp9kbv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alt-text-D_iJlJtX.js","sources":["../src/features/alt-text.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// Accessify – Bildbeschreibung (Image Description) Feature\n// ---------------------------------------------------------------------------\n//\n// A) AUTO-APPLY (runs on widget init, no feature activation needed):\n// Loads alt texts from server manifest + IndexedDB cache and silently\n// applies them to images (alt + title). Ensures all visitors get\n// alt texts immediately.\n//\n// B) GENERATE (when user activates the feature toggle):\n// Scans for images without alt text → generates via AI → injects\n// alt + title into DOM. Title attribute provides native hover tooltip\n// on every image, consistently.\n//\n// Framer compatibility:\n// - Uses currentSrc || src (srcset-aware)\n// - Treats empty alt=\"\" on large images as \"missing\" (Framer sets alt=\"\" on all)\n// - Delayed re-scans for lazy-loaded images\n// - MutationObserver for dynamically added images\n// ---------------------------------------------------------------------------\n\nimport type { FeatureModule, FeatureState, AIService } from '../types';\nimport { RateLimitError } from '../services/ai-service';\nimport { getCurrentWidgetLang } from '../i18n/index';\n\n// ---------------------------------------------------------------------------\n// IndexedDB cache\n// ---------------------------------------------------------------------------\n\nconst IDB_NAME = 'accessify-alt-text-cache';\nconst IDB_STORE = 'alt-texts';\nconst IDB_VERSION = 2;\n\ninterface CachedAltText {\n key: string; src: string; altText: string; lang: string; createdAt: number;\n}\n\nfunction hashSrc(src: string): string {\n let hash = 5381;\n const n = src.toLowerCase().trim();\n for (let i = 0; i < n.length; i++) { hash = ((hash << 5) + hash) + n.charCodeAt(i); hash |= 0; }\n return Math.abs(hash).toString(36);\n}\n\n/** Normalize image URL: strip query params for cache matching (Framer adds ?width=&height=) */\nfunction normalizeImageUrl(url: string): string {\n try {\n const u = new URL(url);\n u.searchParams.delete('width');\n u.searchParams.delete('height');\n u.searchParams.delete('scale-down-to');\n return u.href;\n } catch {\n return url;\n }\n}\n\n/** Get the best available src for an image (Framer srcset aware) */\nfunction getImageSrc(img: HTMLImageElement): string {\n return img.currentSrc || img.src;\n}\n\nfunction openCache(): Promise<IDBDatabase | null> {\n return new Promise((resolve) => {\n try {\n const req = indexedDB.open(IDB_NAME, IDB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(IDB_STORE)) db.createObjectStore(IDB_STORE, { keyPath: 'key' });\n if (!db.objectStoreNames.contains('alt-text-reports')) db.createObjectStore('alt-text-reports', { keyPath: 'key' });\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => resolve(null);\n } catch { resolve(null); }\n });\n}\n\nasync function getAllCachedAltTexts(): Promise<Map<string, string>> {\n const db = await openCache();\n const map = new Map<string, string>();\n if (!db) return map;\n return new Promise((resolve) => {\n try {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const req = tx.objectStore(IDB_STORE).getAll();\n req.onsuccess = () => {\n for (const r of req.result as CachedAltText[]) { map.set(r.src, r.altText); }\n resolve(map);\n };\n req.onerror = () => resolve(map);\n } catch { resolve(map); }\n });\n}\n\nasync function getCachedAltText(src: string): Promise<string | null> {\n const db = await openCache();\n if (!db) return null;\n return new Promise((resolve) => {\n try {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const store = tx.objectStore(IDB_STORE);\n const req1 = store.get(hashSrc(src));\n req1.onsuccess = () => {\n if ((req1.result as CachedAltText | undefined)?.altText) {\n resolve(req1.result.altText);\n return;\n }\n const norm = normalizeImageUrl(src);\n if (norm !== src) {\n const req2 = store.get(hashSrc(norm));\n req2.onsuccess = () => resolve((req2.result as CachedAltText | undefined)?.altText || null);\n req2.onerror = () => resolve(null);\n } else {\n resolve(null);\n }\n };\n req1.onerror = () => resolve(null);\n } catch { resolve(null); }\n });\n}\n\nasync function setCachedAltText(src: string, altText: string, langCode: string): Promise<void> {\n const db = await openCache();\n if (!db) return;\n return new Promise((resolve) => {\n try {\n const tx = db.transaction(IDB_STORE, 'readwrite');\n tx.objectStore(IDB_STORE).put({ key: hashSrc(src), src, altText, lang: langCode, createdAt: Date.now() } as CachedAltText);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n } catch { resolve(); }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Server-side alt-text cache (cross-browser, cross-visitor)\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_API_BASE = 'https://accessify-api.accessify.workers.dev';\n\n// Module-wide mode tracking, set on every manifest fetch. 'manual' = default,\n// never run live AI for unknown images. 'auto' = live fallback + auto-persist OK.\ntype ResimplifyMode = 'manual' | 'auto';\nlet currentAltSiteMode: ResimplifyMode = 'manual';\n\nasync function fetchServerAltTexts(siteKey: string, proxyUrl: string, lang: string): Promise<Map<string, string>> {\n const map = new Map<string, string>();\n try {\n const base = proxyUrl || DEFAULT_API_BASE;\n const pageUrl = window.location.origin + window.location.pathname;\n const res = await fetch(`${base}/v1/manifest?siteKey=${encodeURIComponent(siteKey)}&url=${encodeURIComponent(pageUrl)}&feature=alt_text&variant=${encodeURIComponent(lang)}`, {\n headers: { 'Accept': 'application/json' },\n cache: 'no-cache',\n });\n if (!res.ok) return map;\n const data = await res.json() as { blocks?: Array<{ selector: string; result: string }>; siteMode?: ResimplifyMode };\n // Update authoritative mode from server on every fetch\n currentAltSiteMode = data.siteMode === 'auto' ? 'auto' : 'manual';\n if (data.blocks) {\n for (const block of data.blocks) {\n if (block.selector && block.result) map.set(block.selector, block.result);\n }\n }\n } catch { /* fall back to IndexedDB */ }\n return map;\n}\n\nfunction persistAltTextToServer(siteKey: string, proxyUrl: string, imageUrl: string, altText: string, lang: string): void {\n try {\n const base = proxyUrl || DEFAULT_API_BASE;\n const pageUrl = window.location.origin + window.location.pathname;\n fetch(`${base}/v1/cache/persist-alt-text`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ siteKey, pageUrl, imageUrl, altText, lang }),\n }).catch(() => {});\n } catch { /* fire-and-forget */ }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-apply: runs on widget init, no feature activation needed\n// ---------------------------------------------------------------------------\n\nlet autoApplied = false;\n\n/** Silently apply cached/manifest alt texts to all images on the page */\nexport async function autoApplyCachedAltTexts(\n widgetConfig?: { siteKey?: string; proxyUrl?: string; lang?: string },\n): Promise<number> {\n if (autoApplied) return 0;\n autoApplied = true;\n\n const cache = new Map<string, string>();\n const siteKey = widgetConfig?.siteKey;\n const proxyUrl = widgetConfig?.proxyUrl || '';\n const pageLang = widgetConfig?.lang?.split('-')[0] || document.documentElement.lang?.split('-')[0] || 'en';\n\n // 1. Server manifest (freshest, cross-browser)\n if (siteKey) {\n const serverCache = await fetchServerAltTexts(siteKey, proxyUrl, pageLang);\n for (const [url, alt] of serverCache) {\n // Store BOTH original URL and normalized URL (without width/height params)\n // so lookups by currentSrc (any size) will match\n cache.set(url, alt);\n const norm = normalizeImageUrl(url);\n if (norm !== url) cache.set(norm, alt);\n setCachedAltText(url, alt, pageLang).catch(() => {});\n }\n }\n\n // 2. IndexedDB (fills gaps)\n const localCache = await getAllCachedAltTexts();\n for (const [url, alt] of localCache) {\n if (!cache.has(url)) cache.set(url, alt);\n }\n\n if (cache.size === 0) return 0;\n\n function applyToImg(img: HTMLImageElement): boolean {\n if (img.closest('#accessify-root') || img.closest('accessify-widget')) return false;\n const src = getImageSrc(img);\n const norm = normalizeImageUrl(src);\n const imgSrcNorm = normalizeImageUrl(img.src);\n const cached = cache.get(src) || cache.get(norm) || cache.get(img.src) || cache.get(imgSrcNorm);\n if (!cached) return false;\n\n const alt = img.getAttribute('alt');\n if (alt === null || alt.trim() === '') {\n img.setAttribute('alt', cached);\n img.setAttribute('data-accessify-alt', 'auto');\n }\n // Always set title for native hover tooltip\n img.setAttribute('title', cached);\n return true;\n }\n\n let applied = 0;\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (applyToImg(img)) applied++;\n });\n\n // Watch for late-loading images (Framer SPA, lazy load)\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n for (const node of m.addedNodes) {\n const imgs = node instanceof HTMLImageElement ? [node] :\n node instanceof HTMLElement ? Array.from(node.querySelectorAll<HTMLImageElement>('img')) : [];\n for (const img of imgs) applyToImg(img);\n }\n }\n });\n observer.observe(document.body, { childList: true, subtree: true });\n setTimeout(() => observer.disconnect(), 30000);\n\n return applied;\n}\n\n// ---------------------------------------------------------------------------\n// Feature Module\n// ---------------------------------------------------------------------------\n\nexport default function createAltTextModule(\n aiService?: AIService,\n initialLang: string = 'de',\n serverConfig?: { siteKey?: string; proxyUrl?: string },\n): FeatureModule {\n const siteKey = serverConfig?.siteKey || '';\n const proxyUrl = serverConfig?.proxyUrl || '';\n let enabled = false;\n let domObserver: MutationObserver | null = null;\n let autoGenerating = false;\n\n // Tracked images\n let missingAltImages: HTMLImageElement[] = [];\n const processedImages = new Map<HTMLImageElement, { generatedAlt: string }>();\n\n function lang(): string { return getCurrentWidgetLang() || initialLang; }\n function isDE(): boolean { return lang().startsWith('de'); }\n\n // -------------------------------------------------------------------------\n // Helpers\n // -------------------------------------------------------------------------\n\n function isGenericAlt(alt: string): boolean {\n if (!alt.trim()) return true;\n if (/^(image|img|photo|bild|foto|untitled|placeholder)/i.test(alt)) return true;\n if (/^IMG_\\d+/i.test(alt)) return true;\n if (/\\.(jpg|jpeg|png|gif|webp|svg|avif)$/i.test(alt)) return true;\n return false;\n }\n\n function isDecorativeImage(img: HTMLImageElement): boolean {\n const role = img.getAttribute('role');\n if (role === 'presentation' || role === 'none') return true;\n if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return true;\n return false;\n }\n\n function isValidImage(img: HTMLImageElement): boolean {\n if (img.closest('#accessify-root') || img.closest('accessify-widget')) return false;\n // Skip tiny images (icons, tracking pixels, avatars)\n if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return false;\n // Skip images not rendered on-screen (display:none, visibility:hidden, etc.)\n const rect = img.getBoundingClientRect();\n if (rect.width < 40 || rect.height < 40) return false;\n // Skip images hidden via CSS (opacity:0, visibility:hidden)\n const style = getComputedStyle(img);\n if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false;\n // Skip images with role=\"presentation\" or aria-hidden\n if (img.getAttribute('role') === 'presentation' || img.getAttribute('aria-hidden') === 'true') return false;\n return true;\n }\n\n function needsAltText(img: HTMLImageElement): boolean {\n if (!isValidImage(img)) return false;\n const alt = img.getAttribute('alt');\n if (alt === null) return true;\n if (isGenericAlt(alt)) return true;\n if (alt === '' && !isDecorativeImage(img)) return true;\n return false;\n }\n\n function scanForMissingAlt(): HTMLImageElement[] {\n const missing: HTMLImageElement[] = [];\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (needsAltText(img)) missing.push(img);\n });\n document.querySelectorAll<HTMLElement>('picture').forEach((picture) => {\n if (picture.closest('#accessify-root') || picture.closest('accessify-widget')) return;\n const img = picture.querySelector('img');\n if (img && !missing.includes(img) && needsAltText(img)) {\n missing.push(img);\n }\n });\n return missing;\n }\n\n function gatherImageContext(img: HTMLImageElement): string {\n const parts: string[] = [];\n try {\n const url = new URL(getImageSrc(img), window.location.href);\n const filename = url.pathname.split('/').pop();\n if (filename) parts.push(`Filename: ${filename}`);\n } catch {}\n const figure = img.closest('figure');\n if (figure) {\n const caption = figure.querySelector('figcaption');\n if (caption?.textContent?.trim()) parts.push(`Caption: ${caption.textContent.trim()}`);\n }\n const container = img.parentElement?.parentElement || img.parentElement;\n if (container) {\n const heading = container.querySelector('h1, h2, h3, h4, h5, h6');\n if (heading?.textContent?.trim()) parts.push(`Nearby heading: ${heading.textContent.trim()}`);\n }\n return parts.join('. ');\n }\n\n // -------------------------------------------------------------------------\n // Apply + Generate (title = native hover tooltip on every image)\n // -------------------------------------------------------------------------\n\n function applyAltText(img: HTMLImageElement, altText: string) {\n img.setAttribute('alt', altText);\n img.setAttribute('title', altText);\n processedImages.set(img, { generatedAlt: altText });\n if (enabled) addInfoBadge(img, altText);\n }\n\n /** Set title on every visible image that has alt text but no title yet */\n function applyTitlesToAllImages() {\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (!isValidImage(img)) return;\n // Skip if already has a title\n if (img.getAttribute('title')) return;\n const alt = img.getAttribute('alt');\n if (alt && alt.trim()) {\n img.setAttribute('title', alt);\n img.setAttribute('data-accessify-title', 'auto');\n }\n });\n }\n\n // -------------------------------------------------------------------------\n // Info badge — small \"i\" icon on each image with alt text\n // -------------------------------------------------------------------------\n // Badges live in a single overlay container on document.body (position:fixed\n // would need scroll tracking, so we use position:absolute on the body).\n // This keeps them completely outside any overflow:hidden zoom containers.\n // -------------------------------------------------------------------------\n\n const BADGE_ATTR = 'data-accessify-badge';\n const WRAPPER_ATTR = 'data-accessify-badge-wrap';\n const OVERLAY_ID = 'accessify-badge-overlay';\n const BADGE_STYLE_ID = 'accessify-badge-styles';\n let badgePositionRAF: number | null = null;\n let trackedBadges: Array<{ target: HTMLElement; badge: HTMLElement; tooltip: HTMLElement }> = [];\n let outsideClickHandler: ((e: Event) => void) | null = null;\n\n function getOrCreateOverlay(): HTMLElement {\n let overlay = document.getElementById(OVERLAY_ID);\n if (!overlay) {\n overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n Object.assign(overlay.style, {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '0',\n height: '0',\n overflow: 'visible',\n pointerEvents: 'none',\n zIndex: '10000',\n });\n document.body.appendChild(overlay);\n }\n // Inject badge hover + coarse pointer styles once\n if (!document.getElementById(BADGE_STYLE_ID)) {\n const style = document.createElement('style');\n style.id = BADGE_STYLE_ID;\n style.textContent = `\n [${BADGE_ATTR}=\"badge\"]:hover + [${BADGE_ATTR}=\"tooltip\"] { display: block !important; }\n [${BADGE_ATTR}=\"badge\"]:hover { background: rgba(0,0,0,0.85) !important; }\n @media (pointer: coarse) {\n [${BADGE_ATTR}=\"badge\"] { width: 36px !important; height: 36px !important; line-height: 36px !important; font-size: 16px !important; }\n }\n `;\n document.head.appendChild(style);\n }\n return overlay;\n }\n\n function positionBadge(target: HTMLElement, badge: HTMLElement, tooltip: HTMLElement) {\n const rect = target.getBoundingClientRect();\n // Skip if element is not visible / too small / off-screen\n if (rect.width < 40 || rect.height < 40 ||\n rect.bottom < 0 || rect.top > window.innerHeight + 200 ||\n rect.right < 0 || rect.left > window.innerWidth + 200) {\n badge.style.display = 'none';\n tooltip.style.display = 'none';\n return;\n }\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n const top = rect.top + scrollY + 6;\n const left = rect.left + scrollX + 6;\n badge.style.display = '';\n badge.style.top = `${top}px`;\n badge.style.left = `${left}px`;\n // Tooltip positioned below badge\n tooltip.style.top = `${top + 26}px`;\n tooltip.style.left = `${left}px`;\n }\n\n function updateAllBadgePositions() {\n for (const { target, badge, tooltip } of trackedBadges) {\n if (!document.body.contains(target)) continue;\n positionBadge(target, badge, tooltip);\n }\n }\n\n function startBadgeTracking() {\n if (badgePositionRAF !== null) return;\n const tick = () => {\n updateAllBadgePositions();\n badgePositionRAF = requestAnimationFrame(tick);\n };\n badgePositionRAF = requestAnimationFrame(tick);\n\n // Outside-click handler to close all open tooltips\n if (!outsideClickHandler) {\n outsideClickHandler = (e: Event) => {\n const target = e.target as HTMLElement;\n if (target.getAttribute(BADGE_ATTR) === 'badge') return;\n for (const entry of trackedBadges) {\n entry.tooltip.style.display = 'none';\n entry.badge.style.background = 'rgba(0,0,0,0.6)';\n }\n };\n document.addEventListener('click', outsideClickHandler, { passive: true });\n }\n }\n\n function stopBadgeTracking() {\n if (badgePositionRAF !== null) {\n cancelAnimationFrame(badgePositionRAF);\n badgePositionRAF = null;\n }\n if (outsideClickHandler) {\n document.removeEventListener('click', outsideClickHandler);\n outsideClickHandler = null;\n }\n }\n\n function addInfoBadge(target: HTMLElement, altText: string) {\n if (target.getAttribute(BADGE_ATTR)) return;\n target.setAttribute(BADGE_ATTR, '1');\n\n const overlay = getOrCreateOverlay();\n\n // Badge \"i\" circle\n const badge = document.createElement('span');\n Object.assign(badge.style, {\n position: 'absolute',\n width: '22px',\n height: '22px',\n borderRadius: '50%',\n background: 'rgba(0,0,0,0.6)',\n color: '#fff',\n fontFamily: 'sans-serif',\n fontWeight: 'bold',\n fontSize: '13px',\n lineHeight: '22px',\n textAlign: 'center',\n cursor: 'default',\n pointerEvents: 'auto',\n boxShadow: '0 1px 4px rgba(0,0,0,0.4)',\n transition: 'background 0.15s',\n });\n badge.textContent = 'i';\n badge.setAttribute('aria-hidden', 'true');\n badge.setAttribute('translate', 'no');\n badge.classList.add('notranslate');\n badge.setAttribute(BADGE_ATTR, 'badge');\n\n // Tooltip\n const tooltip = document.createElement('span');\n Object.assign(tooltip.style, {\n display: 'none',\n position: 'absolute',\n minWidth: '150px',\n maxWidth: '280px',\n padding: '6px 10px',\n background: 'rgba(0,0,0,0.88)',\n color: '#fff',\n fontFamily: 'sans-serif',\n fontSize: '12px',\n lineHeight: '1.4',\n borderRadius: '6px',\n pointerEvents: 'none',\n wordWrap: 'break-word',\n boxShadow: '0 2px 8px rgba(0,0,0,0.3)',\n zIndex: '1',\n });\n tooltip.textContent = altText;\n tooltip.setAttribute('translate', 'no');\n tooltip.classList.add('notranslate');\n tooltip.setAttribute(BADGE_ATTR, 'tooltip');\n\n badge.addEventListener('click', () => {\n const isOpen = tooltip.style.display === 'block';\n // Close all other open tooltips first\n for (const entry of trackedBadges) {\n entry.tooltip.style.display = 'none';\n entry.badge.style.background = 'rgba(0,0,0,0.6)';\n }\n if (!isOpen) {\n badge.style.background = 'rgba(0,0,0,0.85)';\n tooltip.style.display = 'block';\n }\n });\n\n overlay.appendChild(badge);\n overlay.appendChild(tooltip);\n\n // Initial position\n positionBadge(target, badge, tooltip);\n\n // Track for continuous position updates\n trackedBadges.push({ target, badge, tooltip });\n }\n\n function removeAllBadges() {\n stopBadgeTracking();\n trackedBadges = [];\n // Remove overlay and badge styles\n document.getElementById(OVERLAY_ID)?.remove();\n document.getElementById(BADGE_STYLE_ID)?.remove();\n // Clear badge markers\n document.querySelectorAll(`[${BADGE_ATTR}]`).forEach(el => el.removeAttribute(BADGE_ATTR));\n // Legacy: unwrap any leftover wrappers from old version\n document.querySelectorAll<HTMLElement>(`[${WRAPPER_ATTR}]`).forEach(wrapper => {\n const img = wrapper.querySelector('img');\n if (img && wrapper.parentElement) {\n wrapper.parentElement.insertBefore(img, wrapper);\n wrapper.remove();\n }\n });\n }\n\n /** Add info badges to ALL visible images */\n function addBadgesToAllImages() {\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (!isValidImage(img)) return;\n const alt = img.getAttribute('alt') || img.getAttribute('title');\n if (alt && alt.trim()) {\n addInfoBadge(img, alt.trim());\n }\n });\n // Also for background images\n document.querySelectorAll<HTMLElement>('[data-accessify-bg-alt]').forEach((el) => {\n const alt = el.getAttribute('aria-label');\n if (alt && alt.trim()) {\n addInfoBadge(el, alt.trim());\n }\n });\n // Start tracking positions (handles scroll, resize, zoom)\n if (trackedBadges.length > 0) startBadgeTracking();\n }\n\n function removeTitles() {\n document.querySelectorAll<HTMLImageElement>('img[data-accessify-title=\"auto\"]').forEach((img) => {\n img.removeAttribute('title');\n img.removeAttribute('data-accessify-title');\n });\n // Clean up background image descriptions\n document.querySelectorAll<HTMLElement>('[data-accessify-bg-alt]').forEach((el) => {\n el.removeAttribute('role');\n el.removeAttribute('aria-label');\n el.removeAttribute('title');\n el.removeAttribute('data-accessify-bg-alt');\n });\n // Remove all info badges\n removeAllBadges();\n }\n\n // -------------------------------------------------------------------------\n // Background images (CSS background-image)\n // -------------------------------------------------------------------------\n\n /** Find significant elements with CSS background-image and no accessibility info */\n function scanForBackgroundImages(): HTMLElement[] {\n const found: HTMLElement[] = [];\n // Scan ALL elements — not just specific class patterns — for background-image\n const allElements = document.querySelectorAll<HTMLElement>('*');\n for (const el of allElements) {\n if (el.closest('#accessify-root') || el.closest('accessify-widget')) continue;\n if (el.getAttribute('data-accessify-bg-alt')) continue;\n // Skip tiny or invisible elements quickly via offsetHeight (avoids getComputedStyle)\n if (el.offsetWidth < 200 || el.offsetHeight < 150) continue;\n const style = getComputedStyle(el);\n const bg = style.backgroundImage;\n if (!bg || bg === 'none') continue;\n // Must have a url() reference (not just gradients)\n const urlMatch = bg.match(/url\\([\"']?([^\"')]+)[\"']?\\)/);\n if (!urlMatch) continue;\n // Skip SVG data URIs and tiny inline images\n if (urlMatch[1].startsWith('data:image/svg')) continue;\n // Skip if already has role=\"img\" with aria-label\n if (el.getAttribute('role') === 'img' && el.getAttribute('aria-label')) continue;\n found.push(el);\n }\n return found;\n }\n\n function getBackgroundImageUrl(el: HTMLElement): string | null {\n const bg = getComputedStyle(el).backgroundImage;\n const match = bg?.match(/url\\([\"']?([^\"')]+)[\"']?\\)/);\n return match ? match[1] : null;\n }\n\n function applyBgAlt(el: HTMLElement, altText: string) {\n el.setAttribute('role', 'img');\n el.setAttribute('aria-label', altText);\n el.setAttribute('title', altText);\n el.setAttribute('data-accessify-bg-alt', 'auto');\n if (enabled) addInfoBadge(el, altText);\n }\n\n async function generateBgAlts() {\n if (!aiService || !enabled) return;\n if (currentAltSiteMode !== 'auto') {\n if ((window as any).__ACCESSIFY_DEBUG) {\n console.info('[Accessify] alt-text: siteMode=manual — skipping live generation for background images');\n }\n return;\n }\n const bgElements = scanForBackgroundImages();\n for (const el of bgElements) {\n if (!enabled) break;\n const src = getBackgroundImageUrl(el);\n if (!src) continue;\n // Check cache first\n const cached = await getCachedAltText(src);\n if (cached) {\n applyBgAlt(el, cached);\n continue;\n }\n // Generate via AI\n try {\n const ctx = gatherBgContext(el);\n const alt = await aiService.generateAltText(src, ctx, lang());\n if (alt && enabled) {\n applyBgAlt(el, alt);\n setCachedAltText(src, alt, lang()).catch(() => {});\n if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());\n }\n } catch (err) {\n console.warn('[Accessify] Bg alt-text generation failed:', src, err);\n }\n }\n }\n\n function gatherBgContext(el: HTMLElement): string {\n const parts: string[] = [];\n // Tag and class hints\n parts.push(`Element: <${el.tagName.toLowerCase()}>`);\n if (el.className) parts.push(`Class: ${el.className}`);\n // Text inside\n const text = el.textContent?.trim().slice(0, 100);\n if (text) parts.push(`Overlay text: ${text}`);\n // Nearby heading\n const heading = el.querySelector('h1, h2, h3');\n if (heading?.textContent?.trim()) parts.push(`Heading: ${heading.textContent.trim()}`);\n return parts.join('. ');\n }\n\n async function generateAll() {\n if (autoGenerating || !enabled || !aiService) return;\n autoGenerating = true;\n const CONCURRENCY = 3;\n\n // Phase 1: apply from IndexedDB cache\n const uncached: HTMLImageElement[] = [];\n for (const img of missingAltImages) {\n if (!enabled) { autoGenerating = false; return; }\n if (processedImages.has(img)) continue;\n const src = getImageSrc(img);\n const cached = await getCachedAltText(src);\n if (cached) {\n applyAltText(img, cached);\n } else {\n uncached.push(img);\n }\n }\n\n if (!enabled) { autoGenerating = false; return; }\n if (!uncached.length) { autoGenerating = false; return; }\n\n // SAFETY GATE: only proceed with live AI if site is in 'auto' mode.\n // In 'manual' (default), leave images without generated alt text — the\n // owner must trigger a crawl or switch modes from the dashboard.\n if (currentAltSiteMode !== 'auto') {\n if ((window as any).__ACCESSIFY_DEBUG) {\n console.info(\n `[Accessify] alt-text: siteMode=manual — ${uncached.length} image(s) left untouched. ` +\n `Trigger a crawl from the dashboard or enable auto mode.`,\n );\n }\n autoGenerating = false;\n return;\n }\n\n // Phase 2: AI generation in parallel batches\n for (let i = 0; i < uncached.length; i += CONCURRENCY) {\n if (!enabled) { autoGenerating = false; return; }\n const batch = uncached.slice(i, i + CONCURRENCY);\n await Promise.all(batch.map(async (img) => {\n if (!enabled) return;\n try {\n const src = getImageSrc(img);\n const ctx = gatherImageContext(img);\n const alt = await aiService!.generateAltText(src, ctx, lang());\n if (alt && enabled) {\n applyAltText(img, alt);\n setCachedAltText(src, alt, lang()).catch(() => {});\n if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());\n }\n } catch (err) {\n console.warn('[Accessify] Alt-text generation failed:', getImageSrc(img), err);\n }\n }));\n }\n\n autoGenerating = false;\n }\n\n async function generateSingle(img: HTMLImageElement) {\n if (!aiService || !enabled) return;\n const src = getImageSrc(img);\n const cached = await getCachedAltText(src);\n if (cached) { applyAltText(img, cached); return; }\n\n // Mode gate — only live-generate when site is in 'auto' mode\n if (currentAltSiteMode !== 'auto') return;\n\n try {\n const ctx = gatherImageContext(img);\n const alt = await aiService.generateAltText(src, ctx, lang());\n if (alt && enabled) {\n applyAltText(img, alt);\n setCachedAltText(src, alt, lang()).catch(() => {});\n if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());\n }\n } catch (err) {\n console.warn('[Accessify] Alt-text generation failed:', src, err);\n }\n }\n\n // -------------------------------------------------------------------------\n // Dynamic image registration\n // -------------------------------------------------------------------------\n\n function tryRegisterImage(img: HTMLImageElement) {\n if (!enabled) return;\n if (!isValidImage(img)) return;\n if (missingAltImages.includes(img)) return;\n\n function addIfValid() {\n if (!enabled || missingAltImages.includes(img)) return;\n if (img.naturalWidth < 20 || img.naturalHeight < 20) return;\n\n if (needsAltText(img)) {\n missingAltImages.push(img);\n generateSingle(img);\n } else {\n // Image has alt but maybe no title/badge yet — add both\n const alt = img.getAttribute('alt');\n if (alt && alt.trim()) {\n if (!img.getAttribute('title')) {\n img.setAttribute('title', alt);\n img.setAttribute('data-accessify-title', 'auto');\n }\n addInfoBadge(img, alt.trim());\n }\n }\n }\n\n if (img.complete && img.naturalWidth > 0) addIfValid();\n else img.addEventListener('load', addIfValid, { once: true });\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n function activate() {\n if (enabled) return;\n enabled = true;\n\n // Recognize images that were auto-applied from cache/manifest\n document.querySelectorAll<HTMLImageElement>('img[data-accessify-alt=\"auto\"]').forEach((img) => {\n if (img.closest('#accessify-root')) return;\n if (!processedImages.has(img)) {\n processedImages.set(img, { generatedAlt: img.getAttribute('alt') || '' });\n missingAltImages.push(img);\n }\n });\n\n // Scan for truly missing alt texts\n const missing = scanForMissingAlt();\n for (const img of missing) {\n if (!missingAltImages.includes(img)) {\n missingAltImages.push(img);\n }\n }\n\n // Start AI generation in background (img + background images)\n generateAll();\n generateBgAlts();\n\n // Set title on ALL images (consistent hover tooltip everywhere)\n applyTitlesToAllImages();\n\n // Add info badges to show alt text is available\n addBadgesToAllImages();\n\n // Register not-yet-loaded images\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (!img.complete) tryRegisterImage(img);\n });\n\n // Delayed re-scans for late-loading images and AI-generated alt texts\n for (const delay of [2000, 5000, 10000]) {\n setTimeout(() => {\n if (enabled) {\n document.querySelectorAll<HTMLImageElement>('img').forEach(tryRegisterImage);\n applyTitlesToAllImages();\n addBadgesToAllImages();\n }\n }, delay);\n }\n\n // Watch for new images\n domObserver = new MutationObserver((mutations) => {\n for (const m of mutations) {\n for (const node of m.addedNodes) {\n if (node instanceof HTMLImageElement) tryRegisterImage(node);\n else if (node instanceof HTMLElement) {\n node.querySelectorAll<HTMLImageElement>('img').forEach(tryRegisterImage);\n }\n }\n }\n });\n domObserver.observe(document.body, { childList: true, subtree: true });\n }\n\n function deactivate() {\n enabled = false;\n autoGenerating = false;\n domObserver?.disconnect();\n domObserver = null;\n\n // Remove auto-added titles (but keep alt texts — those are useful)\n removeTitles();\n missingAltImages = [];\n }\n\n // Run auto-apply immediately when the module is created\n autoApplyCachedAltTexts({ siteKey, proxyUrl, lang: initialLang }).catch(() => {});\n\n return {\n id: 'alt-text',\n name: () => (isDE() ? 'Bildbeschreibung' : 'Image Description'),\n description: isDE() ? 'Bildbeschreibungen per Hover anzeigen und fehlende automatisch erzeugen' : 'Show image descriptions on hover and auto-generate missing ones',\n icon: 'alt-text',\n category: 'ai',\n activate,\n deactivate,\n getState: (): FeatureState => ({\n id: 'alt-text',\n enabled,\n value: {\n missingCount: missingAltImages.filter((img) => !processedImages.has(img)).length,\n processedCount: processedImages.size,\n },\n }),\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"alt-text-BhMp9kbv.js","sources":["../src/features/alt-text.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// Accessify – Bildbeschreibung (Image Description) Feature\n// ---------------------------------------------------------------------------\n//\n// A) AUTO-APPLY (runs on widget init, no feature activation needed):\n// Loads alt texts from server manifest + IndexedDB cache and silently\n// applies them to images (alt + title). Ensures all visitors get\n// alt texts immediately.\n//\n// B) GENERATE (when user activates the feature toggle):\n// Scans for images without alt text → generates via AI → injects\n// alt + title into DOM. Title attribute provides native hover tooltip\n// on every image, consistently.\n//\n// Framer compatibility:\n// - Uses currentSrc || src (srcset-aware)\n// - Treats empty alt=\"\" on large images as \"missing\" (Framer sets alt=\"\" on all)\n// - Delayed re-scans for lazy-loaded images\n// - MutationObserver for dynamically added images\n// ---------------------------------------------------------------------------\n\nimport type { FeatureModule, FeatureState, AIService } from '../types';\nimport { RateLimitError } from '../services/ai-service';\nimport { getCurrentWidgetLang } from '../i18n/index';\n\n// ---------------------------------------------------------------------------\n// IndexedDB cache\n// ---------------------------------------------------------------------------\n\nconst IDB_NAME = 'accessify-alt-text-cache';\nconst IDB_STORE = 'alt-texts';\nconst IDB_VERSION = 2;\n\ninterface CachedAltText {\n key: string; src: string; altText: string; lang: string; createdAt: number;\n}\n\nfunction hashSrc(src: string): string {\n let hash = 5381;\n const n = src.toLowerCase().trim();\n for (let i = 0; i < n.length; i++) { hash = ((hash << 5) + hash) + n.charCodeAt(i); hash |= 0; }\n return Math.abs(hash).toString(36);\n}\n\n/** Normalize image URL: strip query params for cache matching (Framer adds ?width=&height=) */\nfunction normalizeImageUrl(url: string): string {\n try {\n const u = new URL(url);\n u.searchParams.delete('width');\n u.searchParams.delete('height');\n u.searchParams.delete('scale-down-to');\n return u.href;\n } catch {\n return url;\n }\n}\n\n/** Get the best available src for an image (Framer srcset aware) */\nfunction getImageSrc(img: HTMLImageElement): string {\n return img.currentSrc || img.src;\n}\n\nfunction openCache(): Promise<IDBDatabase | null> {\n return new Promise((resolve) => {\n try {\n const req = indexedDB.open(IDB_NAME, IDB_VERSION);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(IDB_STORE)) db.createObjectStore(IDB_STORE, { keyPath: 'key' });\n if (!db.objectStoreNames.contains('alt-text-reports')) db.createObjectStore('alt-text-reports', { keyPath: 'key' });\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => resolve(null);\n } catch { resolve(null); }\n });\n}\n\nasync function getAllCachedAltTexts(): Promise<Map<string, string>> {\n const db = await openCache();\n const map = new Map<string, string>();\n if (!db) return map;\n return new Promise((resolve) => {\n try {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const req = tx.objectStore(IDB_STORE).getAll();\n req.onsuccess = () => {\n for (const r of req.result as CachedAltText[]) { map.set(r.src, r.altText); }\n resolve(map);\n };\n req.onerror = () => resolve(map);\n } catch { resolve(map); }\n });\n}\n\nasync function getCachedAltText(src: string): Promise<string | null> {\n const db = await openCache();\n if (!db) return null;\n return new Promise((resolve) => {\n try {\n const tx = db.transaction(IDB_STORE, 'readonly');\n const store = tx.objectStore(IDB_STORE);\n const req1 = store.get(hashSrc(src));\n req1.onsuccess = () => {\n if ((req1.result as CachedAltText | undefined)?.altText) {\n resolve(req1.result.altText);\n return;\n }\n const norm = normalizeImageUrl(src);\n if (norm !== src) {\n const req2 = store.get(hashSrc(norm));\n req2.onsuccess = () => resolve((req2.result as CachedAltText | undefined)?.altText || null);\n req2.onerror = () => resolve(null);\n } else {\n resolve(null);\n }\n };\n req1.onerror = () => resolve(null);\n } catch { resolve(null); }\n });\n}\n\nasync function setCachedAltText(src: string, altText: string, langCode: string): Promise<void> {\n const db = await openCache();\n if (!db) return;\n return new Promise((resolve) => {\n try {\n const tx = db.transaction(IDB_STORE, 'readwrite');\n tx.objectStore(IDB_STORE).put({ key: hashSrc(src), src, altText, lang: langCode, createdAt: Date.now() } as CachedAltText);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n } catch { resolve(); }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Server-side alt-text cache (cross-browser, cross-visitor)\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_API_BASE = 'https://accessify-api.accessify.workers.dev';\n\n// Module-wide mode tracking, set on every manifest fetch. 'manual' = default,\n// never run live AI for unknown images. 'auto' = live fallback + auto-persist OK.\ntype ResimplifyMode = 'manual' | 'auto';\nlet currentAltSiteMode: ResimplifyMode = 'manual';\n\nasync function fetchServerAltTexts(siteKey: string, proxyUrl: string, lang: string): Promise<Map<string, string>> {\n const map = new Map<string, string>();\n try {\n const base = proxyUrl || DEFAULT_API_BASE;\n const pageUrl = window.location.origin + window.location.pathname;\n const res = await fetch(`${base}/v1/manifest?siteKey=${encodeURIComponent(siteKey)}&url=${encodeURIComponent(pageUrl)}&feature=alt_text&variant=${encodeURIComponent(lang)}`, {\n headers: { 'Accept': 'application/json' },\n cache: 'no-cache',\n });\n if (!res.ok) return map;\n const data = await res.json() as { blocks?: Array<{ selector: string; result: string }>; siteMode?: ResimplifyMode };\n // Update authoritative mode from server on every fetch\n currentAltSiteMode = data.siteMode === 'auto' ? 'auto' : 'manual';\n if (data.blocks) {\n for (const block of data.blocks) {\n if (block.selector && block.result) map.set(block.selector, block.result);\n }\n }\n } catch { /* fall back to IndexedDB */ }\n return map;\n}\n\nfunction persistAltTextToServer(siteKey: string, proxyUrl: string, imageUrl: string, altText: string, lang: string): void {\n try {\n const base = proxyUrl || DEFAULT_API_BASE;\n const pageUrl = window.location.origin + window.location.pathname;\n fetch(`${base}/v1/cache/persist-alt-text`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ siteKey, pageUrl, imageUrl, altText, lang }),\n }).catch(() => {});\n } catch { /* fire-and-forget */ }\n}\n\n// ---------------------------------------------------------------------------\n// Auto-apply: runs on widget init, no feature activation needed\n// ---------------------------------------------------------------------------\n\nlet autoApplied = false;\n\n/** Silently apply cached/manifest alt texts to all images on the page */\nexport async function autoApplyCachedAltTexts(\n widgetConfig?: { siteKey?: string; proxyUrl?: string; lang?: string },\n): Promise<number> {\n if (autoApplied) return 0;\n autoApplied = true;\n\n const cache = new Map<string, string>();\n const siteKey = widgetConfig?.siteKey;\n const proxyUrl = widgetConfig?.proxyUrl || '';\n const pageLang = widgetConfig?.lang?.split('-')[0] || document.documentElement.lang?.split('-')[0] || 'en';\n\n // 1. Server manifest (freshest, cross-browser)\n if (siteKey) {\n const serverCache = await fetchServerAltTexts(siteKey, proxyUrl, pageLang);\n for (const [url, alt] of serverCache) {\n // Store BOTH original URL and normalized URL (without width/height params)\n // so lookups by currentSrc (any size) will match\n cache.set(url, alt);\n const norm = normalizeImageUrl(url);\n if (norm !== url) cache.set(norm, alt);\n setCachedAltText(url, alt, pageLang).catch(() => {});\n }\n }\n\n // 2. IndexedDB (fills gaps)\n const localCache = await getAllCachedAltTexts();\n for (const [url, alt] of localCache) {\n if (!cache.has(url)) cache.set(url, alt);\n }\n\n if (cache.size === 0) return 0;\n\n function applyToImg(img: HTMLImageElement): boolean {\n if (img.closest('#accessify-root') || img.closest('accessify-widget')) return false;\n const src = getImageSrc(img);\n const norm = normalizeImageUrl(src);\n const imgSrcNorm = normalizeImageUrl(img.src);\n const cached = cache.get(src) || cache.get(norm) || cache.get(img.src) || cache.get(imgSrcNorm);\n if (!cached) return false;\n\n const alt = img.getAttribute('alt');\n if (alt === null || alt.trim() === '') {\n img.setAttribute('alt', cached);\n img.setAttribute('data-accessify-alt', 'auto');\n }\n // Always set title for native hover tooltip\n img.setAttribute('title', cached);\n return true;\n }\n\n let applied = 0;\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (applyToImg(img)) applied++;\n });\n\n // Watch for late-loading images (Framer SPA, lazy load)\n const observer = new MutationObserver((mutations) => {\n for (const m of mutations) {\n for (const node of m.addedNodes) {\n const imgs = node instanceof HTMLImageElement ? [node] :\n node instanceof HTMLElement ? Array.from(node.querySelectorAll<HTMLImageElement>('img')) : [];\n for (const img of imgs) applyToImg(img);\n }\n }\n });\n observer.observe(document.body, { childList: true, subtree: true });\n setTimeout(() => observer.disconnect(), 30000);\n\n return applied;\n}\n\n// ---------------------------------------------------------------------------\n// Feature Module\n// ---------------------------------------------------------------------------\n\nexport default function createAltTextModule(\n aiService?: AIService,\n initialLang: string = 'de',\n serverConfig?: { siteKey?: string; proxyUrl?: string },\n): FeatureModule {\n const siteKey = serverConfig?.siteKey || '';\n const proxyUrl = serverConfig?.proxyUrl || '';\n let enabled = false;\n let domObserver: MutationObserver | null = null;\n let autoGenerating = false;\n\n // Tracked images\n let missingAltImages: HTMLImageElement[] = [];\n const processedImages = new Map<HTMLImageElement, { generatedAlt: string }>();\n\n function lang(): string { return getCurrentWidgetLang() || initialLang; }\n function isDE(): boolean { return lang().startsWith('de'); }\n\n // -------------------------------------------------------------------------\n // Helpers\n // -------------------------------------------------------------------------\n\n function isGenericAlt(alt: string): boolean {\n if (!alt.trim()) return true;\n if (/^(image|img|photo|bild|foto|untitled|placeholder)/i.test(alt)) return true;\n if (/^IMG_\\d+/i.test(alt)) return true;\n if (/\\.(jpg|jpeg|png|gif|webp|svg|avif)$/i.test(alt)) return true;\n return false;\n }\n\n function isDecorativeImage(img: HTMLImageElement): boolean {\n const role = img.getAttribute('role');\n if (role === 'presentation' || role === 'none') return true;\n if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return true;\n return false;\n }\n\n function isValidImage(img: HTMLImageElement): boolean {\n if (img.closest('#accessify-root') || img.closest('accessify-widget')) return false;\n // Skip tiny images (icons, tracking pixels, avatars)\n if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return false;\n // Skip images not rendered on-screen (display:none, visibility:hidden, etc.)\n const rect = img.getBoundingClientRect();\n if (rect.width < 40 || rect.height < 40) return false;\n // Skip images hidden via CSS (opacity:0, visibility:hidden)\n const style = getComputedStyle(img);\n if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false;\n // Skip images with role=\"presentation\" or aria-hidden\n if (img.getAttribute('role') === 'presentation' || img.getAttribute('aria-hidden') === 'true') return false;\n return true;\n }\n\n function needsAltText(img: HTMLImageElement): boolean {\n if (!isValidImage(img)) return false;\n const alt = img.getAttribute('alt');\n if (alt === null) return true;\n if (isGenericAlt(alt)) return true;\n if (alt === '' && !isDecorativeImage(img)) return true;\n return false;\n }\n\n function scanForMissingAlt(): HTMLImageElement[] {\n const missing: HTMLImageElement[] = [];\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (needsAltText(img)) missing.push(img);\n });\n document.querySelectorAll<HTMLElement>('picture').forEach((picture) => {\n if (picture.closest('#accessify-root') || picture.closest('accessify-widget')) return;\n const img = picture.querySelector('img');\n if (img && !missing.includes(img) && needsAltText(img)) {\n missing.push(img);\n }\n });\n return missing;\n }\n\n function gatherImageContext(img: HTMLImageElement): string {\n const parts: string[] = [];\n try {\n const url = new URL(getImageSrc(img), window.location.href);\n const filename = url.pathname.split('/').pop();\n if (filename) parts.push(`Filename: ${filename}`);\n } catch {}\n const figure = img.closest('figure');\n if (figure) {\n const caption = figure.querySelector('figcaption');\n if (caption?.textContent?.trim()) parts.push(`Caption: ${caption.textContent.trim()}`);\n }\n const container = img.parentElement?.parentElement || img.parentElement;\n if (container) {\n const heading = container.querySelector('h1, h2, h3, h4, h5, h6');\n if (heading?.textContent?.trim()) parts.push(`Nearby heading: ${heading.textContent.trim()}`);\n }\n return parts.join('. ');\n }\n\n // -------------------------------------------------------------------------\n // Apply + Generate (title = native hover tooltip on every image)\n // -------------------------------------------------------------------------\n\n function applyAltText(img: HTMLImageElement, altText: string) {\n img.setAttribute('alt', altText);\n img.setAttribute('title', altText);\n processedImages.set(img, { generatedAlt: altText });\n if (enabled) addInfoBadge(img, altText);\n }\n\n /** Set title on every visible image that has alt text but no title yet */\n function applyTitlesToAllImages() {\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (!isValidImage(img)) return;\n // Skip if already has a title\n if (img.getAttribute('title')) return;\n const alt = img.getAttribute('alt');\n if (alt && alt.trim()) {\n img.setAttribute('title', alt);\n img.setAttribute('data-accessify-title', 'auto');\n }\n });\n }\n\n // -------------------------------------------------------------------------\n // Info badge — small \"i\" icon on each image with alt text\n // -------------------------------------------------------------------------\n // Badges live in a single overlay container on document.body (position:fixed\n // would need scroll tracking, so we use position:absolute on the body).\n // This keeps them completely outside any overflow:hidden zoom containers.\n // -------------------------------------------------------------------------\n\n const BADGE_ATTR = 'data-accessify-badge';\n const WRAPPER_ATTR = 'data-accessify-badge-wrap';\n const OVERLAY_ID = 'accessify-badge-overlay';\n const BADGE_STYLE_ID = 'accessify-badge-styles';\n let badgePositionRAF: number | null = null;\n let trackedBadges: Array<{ target: HTMLElement; badge: HTMLElement; tooltip: HTMLElement }> = [];\n let outsideClickHandler: ((e: Event) => void) | null = null;\n\n function getOrCreateOverlay(): HTMLElement {\n let overlay = document.getElementById(OVERLAY_ID);\n if (!overlay) {\n overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n Object.assign(overlay.style, {\n position: 'absolute',\n top: '0',\n left: '0',\n width: '0',\n height: '0',\n overflow: 'visible',\n pointerEvents: 'none',\n zIndex: '10000',\n });\n document.body.appendChild(overlay);\n }\n // Inject badge hover + coarse pointer styles once\n if (!document.getElementById(BADGE_STYLE_ID)) {\n const style = document.createElement('style');\n style.id = BADGE_STYLE_ID;\n style.textContent = `\n [${BADGE_ATTR}=\"badge\"]:hover + [${BADGE_ATTR}=\"tooltip\"] { display: block !important; }\n [${BADGE_ATTR}=\"badge\"]:hover { background: rgba(0,0,0,0.85) !important; }\n @media (pointer: coarse) {\n [${BADGE_ATTR}=\"badge\"] { width: 36px !important; height: 36px !important; line-height: 36px !important; font-size: 16px !important; }\n }\n `;\n document.head.appendChild(style);\n }\n return overlay;\n }\n\n function positionBadge(target: HTMLElement, badge: HTMLElement, tooltip: HTMLElement) {\n const rect = target.getBoundingClientRect();\n // Skip if element is not visible / too small / off-screen\n if (rect.width < 40 || rect.height < 40 ||\n rect.bottom < 0 || rect.top > window.innerHeight + 200 ||\n rect.right < 0 || rect.left > window.innerWidth + 200) {\n badge.style.display = 'none';\n tooltip.style.display = 'none';\n return;\n }\n const scrollX = window.scrollX;\n const scrollY = window.scrollY;\n const top = rect.top + scrollY + 6;\n const left = rect.left + scrollX + 6;\n badge.style.display = '';\n badge.style.top = `${top}px`;\n badge.style.left = `${left}px`;\n // Tooltip positioned below badge\n tooltip.style.top = `${top + 26}px`;\n tooltip.style.left = `${left}px`;\n }\n\n function updateAllBadgePositions() {\n for (const { target, badge, tooltip } of trackedBadges) {\n if (!document.body.contains(target)) continue;\n positionBadge(target, badge, tooltip);\n }\n }\n\n function startBadgeTracking() {\n if (badgePositionRAF !== null) return;\n const tick = () => {\n updateAllBadgePositions();\n badgePositionRAF = requestAnimationFrame(tick);\n };\n badgePositionRAF = requestAnimationFrame(tick);\n\n // Outside-click handler to close all open tooltips\n if (!outsideClickHandler) {\n outsideClickHandler = (e: Event) => {\n const target = e.target as HTMLElement;\n if (target.getAttribute(BADGE_ATTR) === 'badge') return;\n for (const entry of trackedBadges) {\n entry.tooltip.style.display = 'none';\n entry.badge.style.background = 'rgba(0,0,0,0.6)';\n }\n };\n document.addEventListener('click', outsideClickHandler, { passive: true });\n }\n }\n\n function stopBadgeTracking() {\n if (badgePositionRAF !== null) {\n cancelAnimationFrame(badgePositionRAF);\n badgePositionRAF = null;\n }\n if (outsideClickHandler) {\n document.removeEventListener('click', outsideClickHandler);\n outsideClickHandler = null;\n }\n }\n\n function addInfoBadge(target: HTMLElement, altText: string) {\n if (target.getAttribute(BADGE_ATTR)) return;\n target.setAttribute(BADGE_ATTR, '1');\n\n const overlay = getOrCreateOverlay();\n\n // Badge \"i\" circle\n const badge = document.createElement('span');\n Object.assign(badge.style, {\n position: 'absolute',\n width: '22px',\n height: '22px',\n borderRadius: '50%',\n background: 'rgba(0,0,0,0.6)',\n color: '#fff',\n fontFamily: 'sans-serif',\n fontWeight: 'bold',\n fontSize: '13px',\n lineHeight: '22px',\n textAlign: 'center',\n cursor: 'default',\n pointerEvents: 'auto',\n boxShadow: '0 1px 4px rgba(0,0,0,0.4)',\n transition: 'background 0.15s',\n });\n badge.textContent = 'i';\n badge.setAttribute('aria-hidden', 'true');\n badge.setAttribute('translate', 'no');\n badge.classList.add('notranslate');\n badge.setAttribute(BADGE_ATTR, 'badge');\n\n // Tooltip\n const tooltip = document.createElement('span');\n Object.assign(tooltip.style, {\n display: 'none',\n position: 'absolute',\n minWidth: '150px',\n maxWidth: '280px',\n padding: '6px 10px',\n background: 'rgba(0,0,0,0.88)',\n color: '#fff',\n fontFamily: 'sans-serif',\n fontSize: '12px',\n lineHeight: '1.4',\n borderRadius: '6px',\n pointerEvents: 'none',\n wordWrap: 'break-word',\n boxShadow: '0 2px 8px rgba(0,0,0,0.3)',\n zIndex: '1',\n });\n tooltip.textContent = altText;\n tooltip.setAttribute('translate', 'no');\n tooltip.classList.add('notranslate');\n tooltip.setAttribute(BADGE_ATTR, 'tooltip');\n\n badge.addEventListener('click', () => {\n const isOpen = tooltip.style.display === 'block';\n // Close all other open tooltips first\n for (const entry of trackedBadges) {\n entry.tooltip.style.display = 'none';\n entry.badge.style.background = 'rgba(0,0,0,0.6)';\n }\n if (!isOpen) {\n badge.style.background = 'rgba(0,0,0,0.85)';\n tooltip.style.display = 'block';\n }\n });\n\n overlay.appendChild(badge);\n overlay.appendChild(tooltip);\n\n // Initial position\n positionBadge(target, badge, tooltip);\n\n // Track for continuous position updates\n trackedBadges.push({ target, badge, tooltip });\n }\n\n function removeAllBadges() {\n stopBadgeTracking();\n trackedBadges = [];\n // Remove overlay and badge styles\n document.getElementById(OVERLAY_ID)?.remove();\n document.getElementById(BADGE_STYLE_ID)?.remove();\n // Clear badge markers\n document.querySelectorAll(`[${BADGE_ATTR}]`).forEach(el => el.removeAttribute(BADGE_ATTR));\n // Legacy: unwrap any leftover wrappers from old version\n document.querySelectorAll<HTMLElement>(`[${WRAPPER_ATTR}]`).forEach(wrapper => {\n const img = wrapper.querySelector('img');\n if (img && wrapper.parentElement) {\n wrapper.parentElement.insertBefore(img, wrapper);\n wrapper.remove();\n }\n });\n }\n\n /** Add info badges to ALL visible images */\n function addBadgesToAllImages() {\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (!isValidImage(img)) return;\n const alt = img.getAttribute('alt') || img.getAttribute('title');\n if (alt && alt.trim()) {\n addInfoBadge(img, alt.trim());\n }\n });\n // Also for background images\n document.querySelectorAll<HTMLElement>('[data-accessify-bg-alt]').forEach((el) => {\n const alt = el.getAttribute('aria-label');\n if (alt && alt.trim()) {\n addInfoBadge(el, alt.trim());\n }\n });\n // Start tracking positions (handles scroll, resize, zoom)\n if (trackedBadges.length > 0) startBadgeTracking();\n }\n\n function removeTitles() {\n document.querySelectorAll<HTMLImageElement>('img[data-accessify-title=\"auto\"]').forEach((img) => {\n img.removeAttribute('title');\n img.removeAttribute('data-accessify-title');\n });\n // Clean up background image descriptions\n document.querySelectorAll<HTMLElement>('[data-accessify-bg-alt]').forEach((el) => {\n el.removeAttribute('role');\n el.removeAttribute('aria-label');\n el.removeAttribute('title');\n el.removeAttribute('data-accessify-bg-alt');\n });\n // Remove all info badges\n removeAllBadges();\n }\n\n // -------------------------------------------------------------------------\n // Background images (CSS background-image)\n // -------------------------------------------------------------------------\n\n /** Find significant elements with CSS background-image and no accessibility info */\n function scanForBackgroundImages(): HTMLElement[] {\n const found: HTMLElement[] = [];\n // Scan ALL elements — not just specific class patterns — for background-image\n const allElements = document.querySelectorAll<HTMLElement>('*');\n for (const el of allElements) {\n if (el.closest('#accessify-root') || el.closest('accessify-widget')) continue;\n if (el.getAttribute('data-accessify-bg-alt')) continue;\n // Skip tiny or invisible elements quickly via offsetHeight (avoids getComputedStyle)\n if (el.offsetWidth < 200 || el.offsetHeight < 150) continue;\n const style = getComputedStyle(el);\n const bg = style.backgroundImage;\n if (!bg || bg === 'none') continue;\n // Must have a url() reference (not just gradients)\n const urlMatch = bg.match(/url\\([\"']?([^\"')]+)[\"']?\\)/);\n if (!urlMatch) continue;\n // Skip SVG data URIs and tiny inline images\n if (urlMatch[1].startsWith('data:image/svg')) continue;\n // Skip if already has role=\"img\" with aria-label\n if (el.getAttribute('role') === 'img' && el.getAttribute('aria-label')) continue;\n found.push(el);\n }\n return found;\n }\n\n function getBackgroundImageUrl(el: HTMLElement): string | null {\n const bg = getComputedStyle(el).backgroundImage;\n const match = bg?.match(/url\\([\"']?([^\"')]+)[\"']?\\)/);\n return match ? match[1] : null;\n }\n\n function applyBgAlt(el: HTMLElement, altText: string) {\n el.setAttribute('role', 'img');\n el.setAttribute('aria-label', altText);\n el.setAttribute('title', altText);\n el.setAttribute('data-accessify-bg-alt', 'auto');\n if (enabled) addInfoBadge(el, altText);\n }\n\n async function generateBgAlts() {\n if (!aiService || !enabled) return;\n if (currentAltSiteMode !== 'auto') {\n if ((window as any).__ACCESSIFY_DEBUG) {\n console.info('[Accessify] alt-text: siteMode=manual — skipping live generation for background images');\n }\n return;\n }\n const bgElements = scanForBackgroundImages();\n for (const el of bgElements) {\n if (!enabled) break;\n const src = getBackgroundImageUrl(el);\n if (!src) continue;\n // Check cache first\n const cached = await getCachedAltText(src);\n if (cached) {\n applyBgAlt(el, cached);\n continue;\n }\n // Generate via AI\n try {\n const ctx = gatherBgContext(el);\n const alt = await aiService.generateAltText(src, ctx, lang());\n if (alt && enabled) {\n applyBgAlt(el, alt);\n setCachedAltText(src, alt, lang()).catch(() => {});\n if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());\n }\n } catch (err) {\n console.warn('[Accessify] Bg alt-text generation failed:', src, err);\n }\n }\n }\n\n function gatherBgContext(el: HTMLElement): string {\n const parts: string[] = [];\n // Tag and class hints\n parts.push(`Element: <${el.tagName.toLowerCase()}>`);\n if (el.className) parts.push(`Class: ${el.className}`);\n // Text inside\n const text = el.textContent?.trim().slice(0, 100);\n if (text) parts.push(`Overlay text: ${text}`);\n // Nearby heading\n const heading = el.querySelector('h1, h2, h3');\n if (heading?.textContent?.trim()) parts.push(`Heading: ${heading.textContent.trim()}`);\n return parts.join('. ');\n }\n\n async function generateAll() {\n if (autoGenerating || !enabled || !aiService) return;\n autoGenerating = true;\n const CONCURRENCY = 3;\n\n // Phase 1: apply from IndexedDB cache\n const uncached: HTMLImageElement[] = [];\n for (const img of missingAltImages) {\n if (!enabled) { autoGenerating = false; return; }\n if (processedImages.has(img)) continue;\n const src = getImageSrc(img);\n const cached = await getCachedAltText(src);\n if (cached) {\n applyAltText(img, cached);\n } else {\n uncached.push(img);\n }\n }\n\n if (!enabled) { autoGenerating = false; return; }\n if (!uncached.length) { autoGenerating = false; return; }\n\n // SAFETY GATE: only proceed with live AI if site is in 'auto' mode.\n // In 'manual' (default), leave images without generated alt text — the\n // owner must trigger a crawl or switch modes from the dashboard.\n if (currentAltSiteMode !== 'auto') {\n if ((window as any).__ACCESSIFY_DEBUG) {\n console.info(\n `[Accessify] alt-text: siteMode=manual — ${uncached.length} image(s) left untouched. ` +\n `Trigger a crawl from the dashboard or enable auto mode.`,\n );\n }\n autoGenerating = false;\n return;\n }\n\n // Phase 2: AI generation in parallel batches\n for (let i = 0; i < uncached.length; i += CONCURRENCY) {\n if (!enabled) { autoGenerating = false; return; }\n const batch = uncached.slice(i, i + CONCURRENCY);\n await Promise.all(batch.map(async (img) => {\n if (!enabled) return;\n try {\n const src = getImageSrc(img);\n const ctx = gatherImageContext(img);\n const alt = await aiService!.generateAltText(src, ctx, lang());\n if (alt && enabled) {\n applyAltText(img, alt);\n setCachedAltText(src, alt, lang()).catch(() => {});\n if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());\n }\n } catch (err) {\n console.warn('[Accessify] Alt-text generation failed:', getImageSrc(img), err);\n }\n }));\n }\n\n autoGenerating = false;\n }\n\n async function generateSingle(img: HTMLImageElement) {\n if (!aiService || !enabled) return;\n const src = getImageSrc(img);\n const cached = await getCachedAltText(src);\n if (cached) { applyAltText(img, cached); return; }\n\n // Mode gate — only live-generate when site is in 'auto' mode\n if (currentAltSiteMode !== 'auto') return;\n\n try {\n const ctx = gatherImageContext(img);\n const alt = await aiService.generateAltText(src, ctx, lang());\n if (alt && enabled) {\n applyAltText(img, alt);\n setCachedAltText(src, alt, lang()).catch(() => {});\n if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());\n }\n } catch (err) {\n console.warn('[Accessify] Alt-text generation failed:', src, err);\n }\n }\n\n // -------------------------------------------------------------------------\n // Dynamic image registration\n // -------------------------------------------------------------------------\n\n function tryRegisterImage(img: HTMLImageElement) {\n if (!enabled) return;\n if (!isValidImage(img)) return;\n if (missingAltImages.includes(img)) return;\n\n function addIfValid() {\n if (!enabled || missingAltImages.includes(img)) return;\n if (img.naturalWidth < 20 || img.naturalHeight < 20) return;\n\n if (needsAltText(img)) {\n missingAltImages.push(img);\n generateSingle(img);\n } else {\n // Image has alt but maybe no title/badge yet — add both\n const alt = img.getAttribute('alt');\n if (alt && alt.trim()) {\n if (!img.getAttribute('title')) {\n img.setAttribute('title', alt);\n img.setAttribute('data-accessify-title', 'auto');\n }\n addInfoBadge(img, alt.trim());\n }\n }\n }\n\n if (img.complete && img.naturalWidth > 0) addIfValid();\n else img.addEventListener('load', addIfValid, { once: true });\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n function activate() {\n if (enabled) return;\n enabled = true;\n\n // Recognize images that were auto-applied from cache/manifest\n document.querySelectorAll<HTMLImageElement>('img[data-accessify-alt=\"auto\"]').forEach((img) => {\n if (img.closest('#accessify-root')) return;\n if (!processedImages.has(img)) {\n processedImages.set(img, { generatedAlt: img.getAttribute('alt') || '' });\n missingAltImages.push(img);\n }\n });\n\n // Scan for truly missing alt texts\n const missing = scanForMissingAlt();\n for (const img of missing) {\n if (!missingAltImages.includes(img)) {\n missingAltImages.push(img);\n }\n }\n\n // Start AI generation in background (img + background images)\n generateAll();\n generateBgAlts();\n\n // Set title on ALL images (consistent hover tooltip everywhere)\n applyTitlesToAllImages();\n\n // Add info badges to show alt text is available\n addBadgesToAllImages();\n\n // Register not-yet-loaded images\n document.querySelectorAll<HTMLImageElement>('img').forEach((img) => {\n if (!img.complete) tryRegisterImage(img);\n });\n\n // Delayed re-scans for late-loading images and AI-generated alt texts\n for (const delay of [2000, 5000, 10000]) {\n setTimeout(() => {\n if (enabled) {\n document.querySelectorAll<HTMLImageElement>('img').forEach(tryRegisterImage);\n applyTitlesToAllImages();\n addBadgesToAllImages();\n }\n }, delay);\n }\n\n // Watch for new images\n domObserver = new MutationObserver((mutations) => {\n for (const m of mutations) {\n for (const node of m.addedNodes) {\n if (node instanceof HTMLImageElement) tryRegisterImage(node);\n else if (node instanceof HTMLElement) {\n node.querySelectorAll<HTMLImageElement>('img').forEach(tryRegisterImage);\n }\n }\n }\n });\n domObserver.observe(document.body, { childList: true, subtree: true });\n }\n\n function deactivate() {\n enabled = false;\n autoGenerating = false;\n domObserver?.disconnect();\n domObserver = null;\n\n // Remove auto-added titles (but keep alt texts — those are useful)\n removeTitles();\n missingAltImages = [];\n }\n\n // Run auto-apply immediately when the module is created\n autoApplyCachedAltTexts({ siteKey, proxyUrl, lang: initialLang }).catch(() => {});\n\n return {\n id: 'alt-text',\n name: () => (isDE() ? 'Bildbeschreibung' : 'Image Description'),\n description: isDE() ? 'Bildbeschreibungen per Hover anzeigen und fehlende automatisch erzeugen' : 'Show image descriptions on hover and auto-generate missing ones',\n icon: 'alt-text',\n category: 'ai',\n activate,\n deactivate,\n getState: (): FeatureState => ({\n id: 'alt-text',\n enabled,\n value: {\n missingCount: missingAltImages.filter((img) => !processedImages.has(img)).length,\n processedCount: processedImages.size,\n },\n }),\n };\n}\n"],"names":[],"mappings":"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"}