accessify-widget 0.2.20 → 0.2.22
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/dist/accessify.min.js +1 -1
- package/dist/accessify.min.js.map +1 -1
- package/dist/accessify.mjs +1 -1
- package/dist/{index-DwxnT3JK.js → index-B9BgMU66.js} +410 -417
- package/dist/{index-DwxnT3JK.js.map → index-B9BgMU66.js.map} +1 -1
- package/dist/{keyboard-nav-BtZsDcZQ.js → keyboard-nav-cvuhPLSY.js} +2 -2
- package/dist/{keyboard-nav-BtZsDcZQ.js.map → keyboard-nav-cvuhPLSY.js.map} +1 -1
- package/dist/{page-structure-DTKpsB5y.js → page-structure-XImoLRLq.js} +2 -2
- package/dist/{page-structure-DTKpsB5y.js.map → page-structure-XImoLRLq.js.map} +1 -1
- package/dist/widget.js +1 -1
- package/dist/widget.js.map +1 -1
- package/package.json +1 -1
|
@@ -4760,8 +4760,8 @@ const deJson = {
|
|
|
4760
4760
|
"feature.tts.desc": "Text per Klick vorlesen lassen",
|
|
4761
4761
|
"feature.textSimplify": "Text vereinfachen",
|
|
4762
4762
|
"feature.textSimplify.desc": "Text in Einfache Sprache umwandeln",
|
|
4763
|
-
"feature.altText": "
|
|
4764
|
-
"feature.altText.desc": "
|
|
4763
|
+
"feature.altText": "Bildbeschreibung",
|
|
4764
|
+
"feature.altText.desc": "Bilder per Klick beschreiben lassen",
|
|
4765
4765
|
"feature.autoScan": "WCAG-Prüfung",
|
|
4766
4766
|
"feature.autoScan.desc": "Seite auf Barrierefreiheit prüfen",
|
|
4767
4767
|
"feature.saturation": "Sättigung",
|
|
@@ -4849,8 +4849,8 @@ const enJson = {
|
|
|
4849
4849
|
"feature.tts.desc": "Click any text to hear it spoken",
|
|
4850
4850
|
"feature.textSimplify": "Simplify Text",
|
|
4851
4851
|
"feature.textSimplify.desc": "Simplify text for easier understanding",
|
|
4852
|
-
"feature.altText": "
|
|
4853
|
-
"feature.altText.desc": "
|
|
4852
|
+
"feature.altText": "Image Description",
|
|
4853
|
+
"feature.altText.desc": "Click images to get AI descriptions",
|
|
4854
4854
|
"feature.autoScan": "WCAG Scan",
|
|
4855
4855
|
"feature.autoScan.desc": "Scan page for accessibility issues",
|
|
4856
4856
|
"feature.saturation": "Saturation",
|
|
@@ -4997,7 +4997,7 @@ const locales = {
|
|
|
4997
4997
|
"feature.pageStructure": "页面结构",
|
|
4998
4998
|
"feature.tts": "朗读",
|
|
4999
4999
|
"feature.textSimplify": "简化文本",
|
|
5000
|
-
"feature.altText": "
|
|
5000
|
+
"feature.altText": "图片描述",
|
|
5001
5001
|
"feature.autoScan": "WCAG 扫描"
|
|
5002
5002
|
}),
|
|
5003
5003
|
hi: withEnglish({
|
|
@@ -5040,7 +5040,7 @@ const locales = {
|
|
|
5040
5040
|
"feature.pageStructure": "पेज संरचना",
|
|
5041
5041
|
"feature.tts": "जोर से पढ़ें",
|
|
5042
5042
|
"feature.textSimplify": "टेक्स्ट सरल करें",
|
|
5043
|
-
"feature.altText": "
|
|
5043
|
+
"feature.altText": "चित्र विवरण",
|
|
5044
5044
|
"feature.autoScan": "WCAG स्कैन"
|
|
5045
5045
|
}),
|
|
5046
5046
|
es: withEnglish({
|
|
@@ -5083,7 +5083,7 @@ const locales = {
|
|
|
5083
5083
|
"feature.pageStructure": "Estructura de pagina",
|
|
5084
5084
|
"feature.tts": "Lectura en voz alta",
|
|
5085
5085
|
"feature.textSimplify": "Simplificar texto",
|
|
5086
|
-
"feature.altText": "
|
|
5086
|
+
"feature.altText": "Descripcion de imagen",
|
|
5087
5087
|
"feature.autoScan": "Escaneo WCAG"
|
|
5088
5088
|
}),
|
|
5089
5089
|
fr: withEnglish({
|
|
@@ -5126,7 +5126,7 @@ const locales = {
|
|
|
5126
5126
|
"feature.pageStructure": "Structure de page",
|
|
5127
5127
|
"feature.tts": "Lecture audio",
|
|
5128
5128
|
"feature.textSimplify": "Simplifier le texte",
|
|
5129
|
-
"feature.altText": "
|
|
5129
|
+
"feature.altText": "Description d'image",
|
|
5130
5130
|
"feature.autoScan": "Analyse WCAG"
|
|
5131
5131
|
}),
|
|
5132
5132
|
ar: withEnglish({
|
|
@@ -5169,7 +5169,7 @@ const locales = {
|
|
|
5169
5169
|
"feature.pageStructure": "بنية الصفحة",
|
|
5170
5170
|
"feature.tts": "القراءة بصوت عالٍ",
|
|
5171
5171
|
"feature.textSimplify": "تبسيط النص",
|
|
5172
|
-
"feature.altText": "
|
|
5172
|
+
"feature.altText": "وصف الصورة",
|
|
5173
5173
|
"feature.autoScan": "فحص WCAG"
|
|
5174
5174
|
}),
|
|
5175
5175
|
bn: withEnglish({
|
|
@@ -5211,7 +5211,7 @@ const locales = {
|
|
|
5211
5211
|
"feature.pageStructure": "পেজ স্ট্রাকচার",
|
|
5212
5212
|
"feature.tts": "জোরে পড়া",
|
|
5213
5213
|
"feature.textSimplify": "টেক্সট সহজ করুন",
|
|
5214
|
-
"feature.altText": "
|
|
5214
|
+
"feature.altText": "ছবির বিবরণ",
|
|
5215
5215
|
"feature.autoScan": "WCAG স্ক্যান"
|
|
5216
5216
|
}),
|
|
5217
5217
|
pt: withEnglish({
|
|
@@ -5254,7 +5254,7 @@ const locales = {
|
|
|
5254
5254
|
"feature.pageStructure": "Estrutura da pagina",
|
|
5255
5255
|
"feature.tts": "Leitura em voz alta",
|
|
5256
5256
|
"feature.textSimplify": "Simplificar texto",
|
|
5257
|
-
"feature.altText": "
|
|
5257
|
+
"feature.altText": "Descricao da imagem",
|
|
5258
5258
|
"feature.autoScan": "Varredura WCAG"
|
|
5259
5259
|
}),
|
|
5260
5260
|
ru: withEnglish({
|
|
@@ -5297,7 +5297,7 @@ const locales = {
|
|
|
5297
5297
|
"feature.pageStructure": "Структура страницы",
|
|
5298
5298
|
"feature.tts": "Озвучивание",
|
|
5299
5299
|
"feature.textSimplify": "Упростить текст",
|
|
5300
|
-
"feature.altText": "
|
|
5300
|
+
"feature.altText": "Описание изображения",
|
|
5301
5301
|
"feature.autoScan": "Проверка WCAG"
|
|
5302
5302
|
}),
|
|
5303
5303
|
ur: withEnglish({
|
|
@@ -5339,7 +5339,7 @@ const locales = {
|
|
|
5339
5339
|
"feature.pageStructure": "صفحہ ساخت",
|
|
5340
5340
|
"feature.tts": "بلند آواز میں پڑھیں",
|
|
5341
5341
|
"feature.textSimplify": "متن آسان کریں",
|
|
5342
|
-
"feature.altText": "
|
|
5342
|
+
"feature.altText": "تصویر کی تفصیل",
|
|
5343
5343
|
"feature.autoScan": "WCAG اسکین"
|
|
5344
5344
|
}),
|
|
5345
5345
|
id: withEnglish({
|
|
@@ -5381,7 +5381,7 @@ const locales = {
|
|
|
5381
5381
|
"feature.pageStructure": "Struktur halaman",
|
|
5382
5382
|
"feature.tts": "Bacakan",
|
|
5383
5383
|
"feature.textSimplify": "Sederhanakan teks",
|
|
5384
|
-
"feature.altText": "
|
|
5384
|
+
"feature.altText": "Deskripsi gambar",
|
|
5385
5385
|
"feature.autoScan": "Pindai WCAG"
|
|
5386
5386
|
}),
|
|
5387
5387
|
ja: withEnglish({
|
|
@@ -5424,7 +5424,7 @@ const locales = {
|
|
|
5424
5424
|
"feature.pageStructure": "ページ構造",
|
|
5425
5425
|
"feature.tts": "読み上げ",
|
|
5426
5426
|
"feature.textSimplify": "文章を簡単にする",
|
|
5427
|
-
"feature.altText": "
|
|
5427
|
+
"feature.altText": "画像の説明",
|
|
5428
5428
|
"feature.autoScan": "WCAG スキャン"
|
|
5429
5429
|
}),
|
|
5430
5430
|
pcm: withEnglish({
|
|
@@ -5466,7 +5466,7 @@ const locales = {
|
|
|
5466
5466
|
"feature.pageStructure": "Page structure",
|
|
5467
5467
|
"feature.tts": "Read aloud",
|
|
5468
5468
|
"feature.textSimplify": "Simplify text",
|
|
5469
|
-
"feature.altText": "
|
|
5469
|
+
"feature.altText": "Image Description",
|
|
5470
5470
|
"feature.autoScan": "WCAG scan"
|
|
5471
5471
|
}),
|
|
5472
5472
|
mr: withEnglish({
|
|
@@ -5508,7 +5508,7 @@ const locales = {
|
|
|
5508
5508
|
"feature.pageStructure": "पृष्ठरचना",
|
|
5509
5509
|
"feature.tts": "मोठ्याने वाचा",
|
|
5510
5510
|
"feature.textSimplify": "मजकूर सोपा करा",
|
|
5511
|
-
"feature.altText": "
|
|
5511
|
+
"feature.altText": "चित्र वर्णन",
|
|
5512
5512
|
"feature.autoScan": "WCAG स्कॅन"
|
|
5513
5513
|
}),
|
|
5514
5514
|
te: withEnglish({
|
|
@@ -5550,7 +5550,7 @@ const locales = {
|
|
|
5550
5550
|
"feature.pageStructure": "పేజీ నిర్మాణం",
|
|
5551
5551
|
"feature.tts": "గట్టిగా చదవండి",
|
|
5552
5552
|
"feature.textSimplify": "టెక్స్ట్ సులభతరం చేయి",
|
|
5553
|
-
"feature.altText": "
|
|
5553
|
+
"feature.altText": "చిత్ర వివరణ",
|
|
5554
5554
|
"feature.autoScan": "WCAG స్కాన్"
|
|
5555
5555
|
}),
|
|
5556
5556
|
tr: withEnglish({
|
|
@@ -5593,7 +5593,7 @@ const locales = {
|
|
|
5593
5593
|
"feature.pageStructure": "Sayfa yapisi",
|
|
5594
5594
|
"feature.tts": "Sesli oku",
|
|
5595
5595
|
"feature.textSimplify": "Metni sadeletir",
|
|
5596
|
-
"feature.altText": "
|
|
5596
|
+
"feature.altText": "Resim aciklamasi",
|
|
5597
5597
|
"feature.autoScan": "WCAG taramasi"
|
|
5598
5598
|
}),
|
|
5599
5599
|
ta: withEnglish({
|
|
@@ -5635,7 +5635,7 @@ const locales = {
|
|
|
5635
5635
|
"feature.pageStructure": "பக்க அமைப்பு",
|
|
5636
5636
|
"feature.tts": "சத்தமாக வாசி",
|
|
5637
5637
|
"feature.textSimplify": "உரையை எளிமைப்படுத்து",
|
|
5638
|
-
"feature.altText": "
|
|
5638
|
+
"feature.altText": "பட விளக்கம்",
|
|
5639
5639
|
"feature.autoScan": "WCAG ஸ்கேன்"
|
|
5640
5640
|
}),
|
|
5641
5641
|
vi: withEnglish({
|
|
@@ -5677,7 +5677,7 @@ const locales = {
|
|
|
5677
5677
|
"feature.pageStructure": "Cau truc trang",
|
|
5678
5678
|
"feature.tts": "Doc thanh tieng",
|
|
5679
5679
|
"feature.textSimplify": "Don gian hoa van ban",
|
|
5680
|
-
"feature.altText": "
|
|
5680
|
+
"feature.altText": "Mo ta hinh anh",
|
|
5681
5681
|
"feature.autoScan": "Quet WCAG"
|
|
5682
5682
|
}),
|
|
5683
5683
|
ko: withEnglish({
|
|
@@ -5720,7 +5720,7 @@ const locales = {
|
|
|
5720
5720
|
"feature.pageStructure": "페이지 구조",
|
|
5721
5721
|
"feature.tts": "소리 내어 읽기",
|
|
5722
5722
|
"feature.textSimplify": "텍스트 단순화",
|
|
5723
|
-
"feature.altText": "
|
|
5723
|
+
"feature.altText": "이미지 설명",
|
|
5724
5724
|
"feature.autoScan": "WCAG 검사"
|
|
5725
5725
|
})
|
|
5726
5726
|
};
|
|
@@ -6078,6 +6078,20 @@ function createProxyService(siteKey, proxyUrl) {
|
|
|
6078
6078
|
}
|
|
6079
6079
|
const data = await res.json();
|
|
6080
6080
|
return data.result || "";
|
|
6081
|
+
},
|
|
6082
|
+
async describeImage(imageUrl, lang) {
|
|
6083
|
+
const res = await fetch(`${base}/v1/ai/describe-image`, {
|
|
6084
|
+
method: "POST",
|
|
6085
|
+
headers,
|
|
6086
|
+
body: JSON.stringify({ imageUrl, lang })
|
|
6087
|
+
});
|
|
6088
|
+
if (!res.ok) {
|
|
6089
|
+
const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
|
|
6090
|
+
if (res.status === 429) throw new RateLimitError(err.error || "Rate limit reached");
|
|
6091
|
+
throw new Error(err.error || `AI proxy error: ${res.status}`);
|
|
6092
|
+
}
|
|
6093
|
+
const data = await res.json();
|
|
6094
|
+
return data.result || "";
|
|
6081
6095
|
}
|
|
6082
6096
|
};
|
|
6083
6097
|
}
|
|
@@ -6156,6 +6170,33 @@ function createDirectService(config2) {
|
|
|
6156
6170
|
}
|
|
6157
6171
|
const data = await response.json();
|
|
6158
6172
|
return extractContent(data);
|
|
6173
|
+
},
|
|
6174
|
+
async describeImage(imageUrl, lang) {
|
|
6175
|
+
const langInstruction = lang && lang.startsWith("de") ? " Beschreibe auf Deutsch." : "";
|
|
6176
|
+
const response = await fetch(`${OPENROUTER_BASE}/chat/completions`, {
|
|
6177
|
+
method: "POST",
|
|
6178
|
+
headers,
|
|
6179
|
+
body: JSON.stringify({
|
|
6180
|
+
model: config2.visionModel || DEFAULTS.visionModel,
|
|
6181
|
+
messages: [{
|
|
6182
|
+
role: "user",
|
|
6183
|
+
content: [
|
|
6184
|
+
{
|
|
6185
|
+
type: "text",
|
|
6186
|
+
text: `Describe what is shown in this image. 2-3 sentences, easy to understand.${langInstruction} Return ONLY the description.`
|
|
6187
|
+
},
|
|
6188
|
+
{ type: "image_url", image_url: { url: imageUrl } }
|
|
6189
|
+
]
|
|
6190
|
+
}],
|
|
6191
|
+
max_tokens: 500
|
|
6192
|
+
})
|
|
6193
|
+
});
|
|
6194
|
+
if (!response.ok) {
|
|
6195
|
+
if (response.status === 429) throw new RateLimitError("Rate limit reached. Please try again later.");
|
|
6196
|
+
throw new Error(`AI vision error: ${response.status}`);
|
|
6197
|
+
}
|
|
6198
|
+
const data = await response.json();
|
|
6199
|
+
return extractContent(data);
|
|
6159
6200
|
}
|
|
6160
6201
|
};
|
|
6161
6202
|
}
|
|
@@ -6310,14 +6351,14 @@ function FeatureGrid($$anchor, $$props) {
|
|
|
6310
6351
|
const FEATURE_LOADERS = {
|
|
6311
6352
|
contrast: () => import("./contrast-CqsICAkU.js"),
|
|
6312
6353
|
"text-size": () => import("./text-size-C6OFhCGi.js"),
|
|
6313
|
-
"keyboard-nav": () => import("./keyboard-nav-
|
|
6354
|
+
"keyboard-nav": () => import("./keyboard-nav-cvuhPLSY.js"),
|
|
6314
6355
|
"link-highlight": () => import("./link-highlight-DBGm067Y.js"),
|
|
6315
6356
|
"reading-guide": () => import("./reading-guide-VT8NciIL.js"),
|
|
6316
6357
|
"reading-mask": () => import("./reading-mask-BABChuCz.js"),
|
|
6317
6358
|
"animation-stop": () => import("./animation-stop-C0MwseK0.js"),
|
|
6318
6359
|
"hide-images": () => import("./hide-images-B_LeCBcd.js"),
|
|
6319
6360
|
"big-cursor": () => import("./big-cursor-B2UKu9dQ.js"),
|
|
6320
|
-
"page-structure": () => import("./page-structure-
|
|
6361
|
+
"page-structure": () => import("./page-structure-XImoLRLq.js"),
|
|
6321
6362
|
tts: () => import("./tts-CjszLRnb.js"),
|
|
6322
6363
|
"text-simplify": () => import("./text-simplify-Cvhpio7g.js"),
|
|
6323
6364
|
"alt-text": () => Promise.resolve().then(() => altText)
|
|
@@ -7587,7 +7628,6 @@ function createWidgetStyles(config2) {
|
|
|
7587
7628
|
}
|
|
7588
7629
|
const IDB_NAME = "accessify-alt-text-cache";
|
|
7589
7630
|
const IDB_STORE = "alt-texts";
|
|
7590
|
-
const IDB_REPORT_STORE = "alt-text-reports";
|
|
7591
7631
|
const IDB_VERSION = 2;
|
|
7592
7632
|
function hashSrc(src) {
|
|
7593
7633
|
let hash = 5381;
|
|
@@ -7598,6 +7638,20 @@ function hashSrc(src) {
|
|
|
7598
7638
|
}
|
|
7599
7639
|
return Math.abs(hash).toString(36);
|
|
7600
7640
|
}
|
|
7641
|
+
function normalizeImageUrl(url) {
|
|
7642
|
+
try {
|
|
7643
|
+
const u = new URL(url);
|
|
7644
|
+
u.searchParams.delete("width");
|
|
7645
|
+
u.searchParams.delete("height");
|
|
7646
|
+
u.searchParams.delete("scale-down-to");
|
|
7647
|
+
return u.href;
|
|
7648
|
+
} catch {
|
|
7649
|
+
return url;
|
|
7650
|
+
}
|
|
7651
|
+
}
|
|
7652
|
+
function getImageSrc(img) {
|
|
7653
|
+
return img.currentSrc || img.src;
|
|
7654
|
+
}
|
|
7601
7655
|
function openCache() {
|
|
7602
7656
|
return new Promise((resolve) => {
|
|
7603
7657
|
try {
|
|
@@ -7605,7 +7659,7 @@ function openCache() {
|
|
|
7605
7659
|
req.onupgradeneeded = () => {
|
|
7606
7660
|
const db = req.result;
|
|
7607
7661
|
if (!db.objectStoreNames.contains(IDB_STORE)) db.createObjectStore(IDB_STORE, { keyPath: "key" });
|
|
7608
|
-
if (!db.objectStoreNames.contains(
|
|
7662
|
+
if (!db.objectStoreNames.contains("alt-text-reports")) db.createObjectStore("alt-text-reports", { keyPath: "key" });
|
|
7609
7663
|
};
|
|
7610
7664
|
req.onsuccess = () => resolve(req.result);
|
|
7611
7665
|
req.onerror = () => resolve(null);
|
|
@@ -7623,8 +7677,7 @@ async function getAllCachedAltTexts() {
|
|
|
7623
7677
|
const tx = db.transaction(IDB_STORE, "readonly");
|
|
7624
7678
|
const req = tx.objectStore(IDB_STORE).getAll();
|
|
7625
7679
|
req.onsuccess = () => {
|
|
7626
|
-
const
|
|
7627
|
-
for (const r of results) {
|
|
7680
|
+
for (const r of req.result) {
|
|
7628
7681
|
map.set(r.src, r.altText);
|
|
7629
7682
|
}
|
|
7630
7683
|
resolve(map);
|
|
@@ -7641,9 +7694,23 @@ async function getCachedAltText(src) {
|
|
|
7641
7694
|
return new Promise((resolve) => {
|
|
7642
7695
|
try {
|
|
7643
7696
|
const tx = db.transaction(IDB_STORE, "readonly");
|
|
7644
|
-
const
|
|
7645
|
-
|
|
7646
|
-
|
|
7697
|
+
const store = tx.objectStore(IDB_STORE);
|
|
7698
|
+
const req1 = store.get(hashSrc(src));
|
|
7699
|
+
req1.onsuccess = () => {
|
|
7700
|
+
if (req1.result?.altText) {
|
|
7701
|
+
resolve(req1.result.altText);
|
|
7702
|
+
return;
|
|
7703
|
+
}
|
|
7704
|
+
const norm = normalizeImageUrl(src);
|
|
7705
|
+
if (norm !== src) {
|
|
7706
|
+
const req2 = store.get(hashSrc(norm));
|
|
7707
|
+
req2.onsuccess = () => resolve(req2.result?.altText || null);
|
|
7708
|
+
req2.onerror = () => resolve(null);
|
|
7709
|
+
} else {
|
|
7710
|
+
resolve(null);
|
|
7711
|
+
}
|
|
7712
|
+
};
|
|
7713
|
+
req1.onerror = () => resolve(null);
|
|
7647
7714
|
} catch {
|
|
7648
7715
|
resolve(null);
|
|
7649
7716
|
}
|
|
@@ -7663,41 +7730,6 @@ async function setCachedAltText(src, altText2, langCode) {
|
|
|
7663
7730
|
}
|
|
7664
7731
|
});
|
|
7665
7732
|
}
|
|
7666
|
-
async function saveReport(src, altText2, langCode) {
|
|
7667
|
-
const db = await openCache();
|
|
7668
|
-
if (!db) return;
|
|
7669
|
-
return new Promise((resolve) => {
|
|
7670
|
-
try {
|
|
7671
|
-
const tx = db.transaction(IDB_REPORT_STORE, "readwrite");
|
|
7672
|
-
tx.objectStore(IDB_REPORT_STORE).put({
|
|
7673
|
-
key: hashSrc(src) + "_" + Date.now(),
|
|
7674
|
-
src,
|
|
7675
|
-
pageUrl: window.location.href,
|
|
7676
|
-
altText: altText2,
|
|
7677
|
-
lang: langCode,
|
|
7678
|
-
reportedAt: Date.now()
|
|
7679
|
-
});
|
|
7680
|
-
tx.oncomplete = () => resolve();
|
|
7681
|
-
tx.onerror = () => resolve();
|
|
7682
|
-
} catch {
|
|
7683
|
-
resolve();
|
|
7684
|
-
}
|
|
7685
|
-
});
|
|
7686
|
-
}
|
|
7687
|
-
async function removeCachedAltText(src) {
|
|
7688
|
-
const db = await openCache();
|
|
7689
|
-
if (!db) return;
|
|
7690
|
-
return new Promise((resolve) => {
|
|
7691
|
-
try {
|
|
7692
|
-
const tx = db.transaction(IDB_STORE, "readwrite");
|
|
7693
|
-
tx.objectStore(IDB_STORE).delete(hashSrc(src));
|
|
7694
|
-
tx.oncomplete = () => resolve();
|
|
7695
|
-
tx.onerror = () => resolve();
|
|
7696
|
-
} catch {
|
|
7697
|
-
resolve();
|
|
7698
|
-
}
|
|
7699
|
-
});
|
|
7700
|
-
}
|
|
7701
7733
|
const DEFAULT_API_BASE = "https://accessify-api.accessify.workers.dev";
|
|
7702
7734
|
async function fetchServerAltTexts(siteKey, proxyUrl, lang) {
|
|
7703
7735
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -7712,9 +7744,7 @@ async function fetchServerAltTexts(siteKey, proxyUrl, lang) {
|
|
|
7712
7744
|
const data = await res.json();
|
|
7713
7745
|
if (data.blocks) {
|
|
7714
7746
|
for (const block2 of data.blocks) {
|
|
7715
|
-
if (block2.selector && block2.result)
|
|
7716
|
-
map.set(block2.selector, block2.result);
|
|
7717
|
-
}
|
|
7747
|
+
if (block2.selector && block2.result) map.set(block2.selector, block2.result);
|
|
7718
7748
|
}
|
|
7719
7749
|
}
|
|
7720
7750
|
} catch {
|
|
@@ -7751,62 +7781,33 @@ async function autoApplyCachedAltTexts(widgetConfig) {
|
|
|
7751
7781
|
}
|
|
7752
7782
|
}
|
|
7753
7783
|
const localCache = await getAllCachedAltTexts();
|
|
7754
|
-
const localOnly = [];
|
|
7755
7784
|
for (const [url, alt] of localCache) {
|
|
7756
|
-
if (!cache.has(url))
|
|
7757
|
-
cache.set(url, alt);
|
|
7758
|
-
localOnly.push({ imageUrl: url, altText: alt });
|
|
7759
|
-
}
|
|
7760
|
-
}
|
|
7761
|
-
if (siteKey && localOnly.length > 0) {
|
|
7762
|
-
try {
|
|
7763
|
-
const base = proxyUrl || DEFAULT_API_BASE;
|
|
7764
|
-
const pageUrl = window.location.origin + window.location.pathname;
|
|
7765
|
-
fetch(`${base}/v1/cache/batch-persist-alt-text`, {
|
|
7766
|
-
method: "POST",
|
|
7767
|
-
headers: { "Content-Type": "application/json" },
|
|
7768
|
-
body: JSON.stringify({
|
|
7769
|
-
siteKey,
|
|
7770
|
-
pageUrl,
|
|
7771
|
-
entries: localOnly.map((e) => ({ ...e, lang: pageLang }))
|
|
7772
|
-
})
|
|
7773
|
-
}).catch(() => {
|
|
7774
|
-
});
|
|
7775
|
-
} catch {
|
|
7776
|
-
}
|
|
7785
|
+
if (!cache.has(url)) cache.set(url, alt);
|
|
7777
7786
|
}
|
|
7778
7787
|
if (cache.size === 0) return 0;
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
images.forEach((img) => {
|
|
7782
|
-
if (img.closest("#accessify-root") || img.closest("accessify-widget")) return;
|
|
7788
|
+
function applyToImg(img) {
|
|
7789
|
+
if (img.closest("#accessify-root") || img.closest("accessify-widget")) return false;
|
|
7783
7790
|
const alt = img.getAttribute("alt");
|
|
7784
|
-
if (alt !== null && alt.trim() !== "") return;
|
|
7785
|
-
const src = img
|
|
7786
|
-
const cached = cache.get(src) || cache.get(img.src);
|
|
7791
|
+
if (alt !== null && alt.trim() !== "") return false;
|
|
7792
|
+
const src = getImageSrc(img);
|
|
7793
|
+
const cached = cache.get(src) || cache.get(normalizeImageUrl(src)) || cache.get(img.src);
|
|
7787
7794
|
if (cached) {
|
|
7788
7795
|
img.setAttribute("alt", cached);
|
|
7789
7796
|
img.setAttribute("title", cached);
|
|
7790
7797
|
img.setAttribute("data-accessify-alt", "auto");
|
|
7791
|
-
|
|
7798
|
+
return true;
|
|
7792
7799
|
}
|
|
7800
|
+
return false;
|
|
7801
|
+
}
|
|
7802
|
+
let applied = 0;
|
|
7803
|
+
document.querySelectorAll("img").forEach((img) => {
|
|
7804
|
+
if (applyToImg(img)) applied++;
|
|
7793
7805
|
});
|
|
7794
7806
|
const observer2 = new MutationObserver((mutations) => {
|
|
7795
7807
|
for (const m of mutations) {
|
|
7796
7808
|
for (const node of m.addedNodes) {
|
|
7797
7809
|
const imgs = node instanceof HTMLImageElement ? [node] : node instanceof HTMLElement ? Array.from(node.querySelectorAll("img")) : [];
|
|
7798
|
-
for (const img of imgs)
|
|
7799
|
-
if (img.closest("#accessify-root") || img.closest("accessify-widget")) continue;
|
|
7800
|
-
const a = img.getAttribute("alt");
|
|
7801
|
-
if (a !== null && a.trim() !== "") continue;
|
|
7802
|
-
const src = img.currentSrc || img.src;
|
|
7803
|
-
const c = cache.get(src) || cache.get(img.src);
|
|
7804
|
-
if (c) {
|
|
7805
|
-
img.setAttribute("alt", c);
|
|
7806
|
-
img.setAttribute("title", c);
|
|
7807
|
-
img.setAttribute("data-accessify-alt", "auto");
|
|
7808
|
-
}
|
|
7809
|
-
}
|
|
7810
|
+
for (const img of imgs) applyToImg(img);
|
|
7810
7811
|
}
|
|
7811
7812
|
}
|
|
7812
7813
|
});
|
|
@@ -7820,13 +7821,14 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
7820
7821
|
let enabled = false;
|
|
7821
7822
|
let styleEl = null;
|
|
7822
7823
|
let badgeEl = null;
|
|
7824
|
+
let tooltipEl = null;
|
|
7825
|
+
let domObserver = null;
|
|
7826
|
+
let autoGenerating = false;
|
|
7823
7827
|
let missingAltImages = [];
|
|
7824
|
-
let existingAltImages = [];
|
|
7825
7828
|
const processedImages = /* @__PURE__ */ new Map();
|
|
7826
|
-
let
|
|
7827
|
-
let
|
|
7828
|
-
const
|
|
7829
|
-
let reportPanelEl = null;
|
|
7829
|
+
let describeClickHandler = null;
|
|
7830
|
+
let describeEscHandler = null;
|
|
7831
|
+
const describeButtons = /* @__PURE__ */ new Map();
|
|
7830
7832
|
function lang() {
|
|
7831
7833
|
return getCurrentWidgetLang() || initialLang;
|
|
7832
7834
|
}
|
|
@@ -7835,15 +7837,12 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
7835
7837
|
}
|
|
7836
7838
|
const STYLE_ID = "accessify-alt-text-styles";
|
|
7837
7839
|
const HIGHLIGHT_CLASS = "accessify-alt-missing";
|
|
7838
|
-
const HAS_ALT_CLASS = "accessify-alt-existing";
|
|
7839
|
-
const BADGE_CLASS = "accessify-alt-badge";
|
|
7840
7840
|
function getStyles() {
|
|
7841
7841
|
return `
|
|
7842
7842
|
.${HIGHLIGHT_CLASS} {
|
|
7843
7843
|
outline: 3px dashed #e63946 !important;
|
|
7844
7844
|
outline-offset: 3px !important;
|
|
7845
7845
|
position: relative !important;
|
|
7846
|
-
transition: outline-color 0.2s ease !important;
|
|
7847
7846
|
}
|
|
7848
7847
|
.${HIGHLIGHT_CLASS}.accessify-alt-generating::after {
|
|
7849
7848
|
content: '\\2026';
|
|
@@ -7869,99 +7868,97 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
7869
7868
|
content: none;
|
|
7870
7869
|
}
|
|
7871
7870
|
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
outline-offset: 3px !important;
|
|
7875
|
-
position: relative !important;
|
|
7876
|
-
}
|
|
7877
|
-
|
|
7878
|
-
.accessify-alt-tooltip {
|
|
7879
|
-
position: fixed;
|
|
7880
|
-
z-index: 2147483647;
|
|
7881
|
-
max-width: 320px;
|
|
7882
|
-
padding: 8px 12px;
|
|
7883
|
-
background: #1a1a2e;
|
|
7884
|
-
color: #e0e0e0;
|
|
7885
|
-
border-radius: 8px;
|
|
7886
|
-
box-shadow: 0 4px 20px rgba(0,0,0,0.4);
|
|
7887
|
-
font-family: system-ui, -apple-system, sans-serif;
|
|
7888
|
-
font-size: 13px;
|
|
7889
|
-
line-height: 1.5;
|
|
7890
|
-
pointer-events: none;
|
|
7891
|
-
word-break: break-word;
|
|
7892
|
-
opacity: 1;
|
|
7871
|
+
img[data-a11y-describable="true"]:not([data-a11y-is-link="true"]) {
|
|
7872
|
+
cursor: help !important;
|
|
7893
7873
|
}
|
|
7894
7874
|
|
|
7895
|
-
.accessify-
|
|
7875
|
+
.accessify-describe-btn {
|
|
7896
7876
|
position: absolute;
|
|
7897
7877
|
top: 6px;
|
|
7898
7878
|
right: 6px;
|
|
7899
7879
|
z-index: 10;
|
|
7900
|
-
width:
|
|
7901
|
-
height:
|
|
7880
|
+
width: 26px;
|
|
7881
|
+
height: 26px;
|
|
7902
7882
|
padding: 0;
|
|
7903
7883
|
border: none;
|
|
7904
7884
|
border-radius: 50%;
|
|
7905
|
-
background: rgba(
|
|
7906
|
-
color: #
|
|
7885
|
+
background: rgba(26, 26, 46, 0.85);
|
|
7886
|
+
color: #e0e0e0;
|
|
7907
7887
|
font-family: system-ui, -apple-system, sans-serif;
|
|
7908
|
-
font-size:
|
|
7909
|
-
font-weight:
|
|
7910
|
-
line-height:
|
|
7888
|
+
font-size: 14px;
|
|
7889
|
+
font-weight: 700;
|
|
7890
|
+
line-height: 26px;
|
|
7911
7891
|
text-align: center;
|
|
7912
|
-
cursor:
|
|
7892
|
+
cursor: help;
|
|
7913
7893
|
opacity: 0;
|
|
7914
7894
|
transition: opacity 0.15s ease;
|
|
7915
7895
|
backdrop-filter: blur(4px);
|
|
7896
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
7916
7897
|
}
|
|
7917
|
-
|
|
7918
|
-
.accessify-
|
|
7898
|
+
img[data-a11y-is-link="true"]:hover ~ .accessify-describe-btn,
|
|
7899
|
+
.accessify-describe-btn:hover {
|
|
7919
7900
|
opacity: 1;
|
|
7920
7901
|
}
|
|
7921
|
-
.accessify-
|
|
7922
|
-
background: rgba(
|
|
7902
|
+
.accessify-describe-btn:hover {
|
|
7903
|
+
background: rgba(26, 26, 46, 0.95);
|
|
7923
7904
|
color: #fff;
|
|
7924
7905
|
}
|
|
7925
7906
|
|
|
7926
|
-
.accessify-
|
|
7907
|
+
.accessify-describe-tooltip {
|
|
7927
7908
|
position: fixed;
|
|
7928
|
-
z-index:
|
|
7929
|
-
width:
|
|
7930
|
-
padding:
|
|
7909
|
+
z-index: 2147483647;
|
|
7910
|
+
max-width: 340px;
|
|
7911
|
+
padding: 14px 18px;
|
|
7931
7912
|
background: #1a1a2e;
|
|
7932
|
-
color: #
|
|
7913
|
+
color: #e0e0e0;
|
|
7933
7914
|
border-radius: 10px;
|
|
7934
|
-
box-shadow: 0
|
|
7915
|
+
box-shadow: 0 6px 24px rgba(0,0,0,0.45);
|
|
7935
7916
|
font-family: system-ui, -apple-system, sans-serif;
|
|
7936
|
-
font-size:
|
|
7937
|
-
line-height: 1.
|
|
7917
|
+
font-size: 14px;
|
|
7918
|
+
line-height: 1.6;
|
|
7919
|
+
word-break: break-word;
|
|
7920
|
+
animation: accessify-fade-in 0.15s ease;
|
|
7938
7921
|
}
|
|
7939
|
-
.accessify-
|
|
7940
|
-
|
|
7941
|
-
|
|
7922
|
+
.accessify-describe-tooltip .accessify-describe-close {
|
|
7923
|
+
position: absolute;
|
|
7924
|
+
top: 6px;
|
|
7925
|
+
right: 8px;
|
|
7926
|
+
background: none;
|
|
7927
|
+
border: none;
|
|
7928
|
+
color: #888;
|
|
7929
|
+
font-size: 16px;
|
|
7930
|
+
cursor: pointer;
|
|
7931
|
+
padding: 2px 6px;
|
|
7932
|
+
line-height: 1;
|
|
7942
7933
|
}
|
|
7943
|
-
.accessify-
|
|
7944
|
-
|
|
7934
|
+
.accessify-describe-tooltip .accessify-describe-close:hover {
|
|
7935
|
+
color: #fff;
|
|
7936
|
+
}
|
|
7937
|
+
.accessify-describe-loading {
|
|
7938
|
+
display: flex;
|
|
7945
7939
|
align-items: center;
|
|
7946
|
-
gap:
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7940
|
+
gap: 8px;
|
|
7941
|
+
color: #aaa;
|
|
7942
|
+
font-style: italic;
|
|
7943
|
+
}
|
|
7944
|
+
.accessify-describe-loading::before {
|
|
7945
|
+
content: '';
|
|
7946
|
+
width: 14px;
|
|
7947
|
+
height: 14px;
|
|
7948
|
+
border: 2px solid #555;
|
|
7949
|
+
border-top-color: #aaa;
|
|
7950
|
+
border-radius: 50%;
|
|
7951
|
+
animation: accessify-spin 0.8s linear infinite;
|
|
7952
|
+
}
|
|
7953
|
+
@keyframes accessify-spin {
|
|
7954
|
+
to { transform: rotate(360deg); }
|
|
7955
7955
|
}
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
background: rgba(42,157,143,0.1);
|
|
7960
|
-
color: #2a9d8f;
|
|
7961
|
-
cursor: default;
|
|
7956
|
+
@keyframes accessify-fade-in {
|
|
7957
|
+
from { opacity: 0; transform: translateY(4px); }
|
|
7958
|
+
to { opacity: 1; transform: translateY(0); }
|
|
7962
7959
|
}
|
|
7963
7960
|
|
|
7964
|
-
|
|
7961
|
+
.accessify-alt-badge {
|
|
7965
7962
|
position: fixed;
|
|
7966
7963
|
top: 12px;
|
|
7967
7964
|
right: 12px;
|
|
@@ -7978,7 +7975,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
7978
7975
|
font-size: 13px;
|
|
7979
7976
|
user-select: none;
|
|
7980
7977
|
}
|
|
7981
|
-
|
|
7978
|
+
.accessify-alt-badge-count {
|
|
7982
7979
|
display: inline-flex;
|
|
7983
7980
|
align-items: center;
|
|
7984
7981
|
justify-content: center;
|
|
@@ -8005,100 +8002,161 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8005
8002
|
styleEl = null;
|
|
8006
8003
|
document.getElementById(STYLE_ID)?.remove();
|
|
8007
8004
|
}
|
|
8008
|
-
function
|
|
8009
|
-
|
|
8010
|
-
if (!text) return;
|
|
8011
|
-
hideTooltip();
|
|
8005
|
+
function showDescribeTooltip(text, rect, loading = false) {
|
|
8006
|
+
hideDescribeTooltip();
|
|
8012
8007
|
const tip = document.createElement("div");
|
|
8013
|
-
tip.className = "accessify-
|
|
8014
|
-
|
|
8008
|
+
tip.className = "accessify-describe-tooltip";
|
|
8009
|
+
const closeBtn = document.createElement("button");
|
|
8010
|
+
closeBtn.className = "accessify-describe-close";
|
|
8011
|
+
closeBtn.textContent = "×";
|
|
8012
|
+
closeBtn.setAttribute("aria-label", "Close");
|
|
8013
|
+
closeBtn.addEventListener("click", (e) => {
|
|
8014
|
+
e.stopPropagation();
|
|
8015
|
+
hideDescribeTooltip();
|
|
8016
|
+
});
|
|
8017
|
+
tip.appendChild(closeBtn);
|
|
8018
|
+
if (loading) {
|
|
8019
|
+
const loadingEl = document.createElement("div");
|
|
8020
|
+
loadingEl.className = "accessify-describe-loading";
|
|
8021
|
+
loadingEl.textContent = isDE() ? "Bild wird analysiert…" : "Analyzing image…";
|
|
8022
|
+
tip.appendChild(loadingEl);
|
|
8023
|
+
} else {
|
|
8024
|
+
const textEl = document.createElement("div");
|
|
8025
|
+
textEl.textContent = text;
|
|
8026
|
+
tip.appendChild(textEl);
|
|
8027
|
+
}
|
|
8015
8028
|
document.body.appendChild(tip);
|
|
8016
8029
|
tooltipEl = tip;
|
|
8017
|
-
const rect = img.getBoundingClientRect();
|
|
8018
8030
|
const tipRect = tip.getBoundingClientRect();
|
|
8019
|
-
let top = rect.
|
|
8020
|
-
if (top
|
|
8031
|
+
let top = rect.bottom + 8;
|
|
8032
|
+
if (top + tipRect.height > window.innerHeight - 8) {
|
|
8033
|
+
top = rect.top - tipRect.height - 8;
|
|
8034
|
+
}
|
|
8035
|
+
if (top < 4) top = 4;
|
|
8021
8036
|
let left = rect.left + (rect.width - tipRect.width) / 2;
|
|
8022
|
-
left = Math.max(
|
|
8037
|
+
left = Math.max(8, Math.min(left, window.innerWidth - tipRect.width - 8));
|
|
8023
8038
|
tip.style.top = `${top}px`;
|
|
8024
8039
|
tip.style.left = `${left}px`;
|
|
8025
8040
|
}
|
|
8026
|
-
function
|
|
8041
|
+
function hideDescribeTooltip() {
|
|
8027
8042
|
tooltipEl?.remove();
|
|
8028
8043
|
tooltipEl = null;
|
|
8029
8044
|
}
|
|
8030
|
-
function
|
|
8031
|
-
|
|
8045
|
+
async function handleImageClick(img) {
|
|
8046
|
+
const rect = img.getBoundingClientRect();
|
|
8047
|
+
const cached = img.dataset.accessifyDescription;
|
|
8048
|
+
if (cached) {
|
|
8049
|
+
showDescribeTooltip(cached, rect);
|
|
8050
|
+
return;
|
|
8051
|
+
}
|
|
8052
|
+
const existingAlt = img.getAttribute("alt");
|
|
8053
|
+
showDescribeTooltip("", rect, true);
|
|
8054
|
+
try {
|
|
8055
|
+
if (!aiService) {
|
|
8056
|
+
showDescribeTooltip(
|
|
8057
|
+
existingAlt || (isDE() ? "Kein API-Key konfiguriert" : "No API key configured"),
|
|
8058
|
+
rect
|
|
8059
|
+
);
|
|
8060
|
+
return;
|
|
8061
|
+
}
|
|
8062
|
+
const src = getImageSrc(img);
|
|
8063
|
+
const description = await aiService.describeImage(src, lang());
|
|
8064
|
+
if (!enabled) return;
|
|
8065
|
+
img.dataset.accessifyDescription = description;
|
|
8066
|
+
showDescribeTooltip(description, rect);
|
|
8067
|
+
const currentAlt = img.getAttribute("alt");
|
|
8068
|
+
if (!currentAlt || !currentAlt.trim()) {
|
|
8069
|
+
try {
|
|
8070
|
+
const ctx = gatherImageContext(img);
|
|
8071
|
+
const altText2 = await aiService.generateAltText(src, ctx, lang());
|
|
8072
|
+
if (altText2) {
|
|
8073
|
+
img.setAttribute("alt", altText2);
|
|
8074
|
+
img.setAttribute("title", altText2);
|
|
8075
|
+
setCachedAltText(src, altText2, lang()).catch(() => {
|
|
8076
|
+
});
|
|
8077
|
+
if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, altText2, lang());
|
|
8078
|
+
}
|
|
8079
|
+
} catch {
|
|
8080
|
+
}
|
|
8081
|
+
}
|
|
8082
|
+
} catch (err) {
|
|
8083
|
+
console.warn("[Accessify] Image description failed:", err);
|
|
8084
|
+
showDescribeTooltip(
|
|
8085
|
+
existingAlt || (isDE() ? "Beschreibung konnte nicht geladen werden" : "Could not load description"),
|
|
8086
|
+
rect
|
|
8087
|
+
);
|
|
8088
|
+
}
|
|
8032
8089
|
}
|
|
8033
|
-
function
|
|
8034
|
-
|
|
8090
|
+
function isLinkedImage(img) {
|
|
8091
|
+
return !!img.closest("a[href]");
|
|
8035
8092
|
}
|
|
8036
|
-
function
|
|
8037
|
-
if (
|
|
8093
|
+
function addDescribeButton(img) {
|
|
8094
|
+
if (describeButtons.has(img)) return;
|
|
8038
8095
|
const parent = img.parentElement;
|
|
8039
|
-
if (parent)
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
}
|
|
8096
|
+
if (!parent) return;
|
|
8097
|
+
const pos = getComputedStyle(parent).position;
|
|
8098
|
+
if (pos === "static") parent.style.position = "relative";
|
|
8043
8099
|
const btn = document.createElement("button");
|
|
8044
|
-
btn.className = "accessify-
|
|
8100
|
+
btn.className = "accessify-describe-btn";
|
|
8045
8101
|
btn.textContent = "i";
|
|
8046
|
-
btn.setAttribute("aria-label", isDE() ? "
|
|
8102
|
+
btn.setAttribute("aria-label", isDE() ? "Bildbeschreibung anzeigen" : "Show image description");
|
|
8047
8103
|
btn.addEventListener("click", (e) => {
|
|
8048
8104
|
e.preventDefault();
|
|
8049
8105
|
e.stopPropagation();
|
|
8050
|
-
|
|
8106
|
+
handleImageClick(img);
|
|
8051
8107
|
});
|
|
8052
8108
|
img.insertAdjacentElement("afterend", btn);
|
|
8053
|
-
|
|
8054
|
-
}
|
|
8055
|
-
function
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
}
|
|
8059
|
-
function
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
reportBtn.classList.add("reported");
|
|
8078
|
-
});
|
|
8079
|
-
panel.appendChild(reportBtn);
|
|
8080
|
-
document.body.appendChild(panel);
|
|
8081
|
-
reportPanelEl = panel;
|
|
8082
|
-
setTimeout(() => {
|
|
8083
|
-
const handleOutside = (e) => {
|
|
8084
|
-
if (!panel.contains(e.target) && e.target !== anchor) {
|
|
8085
|
-
closeReportPanel();
|
|
8086
|
-
document.removeEventListener("click", handleOutside);
|
|
8087
|
-
}
|
|
8088
|
-
};
|
|
8089
|
-
document.addEventListener("click", handleOutside);
|
|
8090
|
-
}, 50);
|
|
8091
|
-
const handleEsc = (e) => {
|
|
8092
|
-
if (e.key === "Escape") {
|
|
8093
|
-
closeReportPanel();
|
|
8094
|
-
document.removeEventListener("keydown", handleEsc);
|
|
8109
|
+
describeButtons.set(img, btn);
|
|
8110
|
+
}
|
|
8111
|
+
function removeDescribeButtons() {
|
|
8112
|
+
describeButtons.forEach((btn) => btn.remove());
|
|
8113
|
+
describeButtons.clear();
|
|
8114
|
+
}
|
|
8115
|
+
function markImageDescribable(img) {
|
|
8116
|
+
if (img.closest("#accessify-root") || img.closest("accessify-widget")) return;
|
|
8117
|
+
if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return;
|
|
8118
|
+
img.dataset.a11yDescribable = "true";
|
|
8119
|
+
if (isLinkedImage(img)) {
|
|
8120
|
+
img.dataset.a11yIsLink = "true";
|
|
8121
|
+
addDescribeButton(img);
|
|
8122
|
+
}
|
|
8123
|
+
}
|
|
8124
|
+
function enableClickToDescribe() {
|
|
8125
|
+
document.querySelectorAll("img").forEach(markImageDescribable);
|
|
8126
|
+
describeClickHandler = (e) => {
|
|
8127
|
+
if (e.target.closest(".accessify-describe-tooltip")) return;
|
|
8128
|
+
if (e.target.closest(".accessify-describe-btn")) return;
|
|
8129
|
+
const img = e.target.closest("img[data-a11y-describable]");
|
|
8130
|
+
if (!img) {
|
|
8131
|
+
if (tooltipEl) hideDescribeTooltip();
|
|
8132
|
+
return;
|
|
8095
8133
|
}
|
|
8134
|
+
if (isLinkedImage(img)) return;
|
|
8135
|
+
e.preventDefault();
|
|
8136
|
+
e.stopPropagation();
|
|
8137
|
+
handleImageClick(img);
|
|
8096
8138
|
};
|
|
8097
|
-
document.addEventListener("
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8139
|
+
document.addEventListener("click", describeClickHandler, true);
|
|
8140
|
+
describeEscHandler = (e) => {
|
|
8141
|
+
if (e.key === "Escape") hideDescribeTooltip();
|
|
8142
|
+
};
|
|
8143
|
+
document.addEventListener("keydown", describeEscHandler);
|
|
8144
|
+
}
|
|
8145
|
+
function disableClickToDescribe() {
|
|
8146
|
+
if (describeClickHandler) {
|
|
8147
|
+
document.removeEventListener("click", describeClickHandler, true);
|
|
8148
|
+
describeClickHandler = null;
|
|
8149
|
+
}
|
|
8150
|
+
if (describeEscHandler) {
|
|
8151
|
+
document.removeEventListener("keydown", describeEscHandler);
|
|
8152
|
+
describeEscHandler = null;
|
|
8153
|
+
}
|
|
8154
|
+
hideDescribeTooltip();
|
|
8155
|
+
removeDescribeButtons();
|
|
8156
|
+
document.querySelectorAll("img[data-a11y-describable]").forEach((img) => {
|
|
8157
|
+
delete img.dataset.a11yDescribable;
|
|
8158
|
+
delete img.dataset.a11yIsLink;
|
|
8159
|
+
});
|
|
8102
8160
|
}
|
|
8103
8161
|
function isGenericAlt(alt) {
|
|
8104
8162
|
if (!alt.trim()) return true;
|
|
@@ -8107,67 +8165,54 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8107
8165
|
if (/\.(jpg|jpeg|png|gif|webp|svg|avif)$/i.test(alt)) return true;
|
|
8108
8166
|
return false;
|
|
8109
8167
|
}
|
|
8168
|
+
function isDecorativeImage(img) {
|
|
8169
|
+
const role = img.getAttribute("role");
|
|
8170
|
+
if (role === "presentation" || role === "none") return true;
|
|
8171
|
+
if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return true;
|
|
8172
|
+
return false;
|
|
8173
|
+
}
|
|
8174
|
+
function needsAltText(img) {
|
|
8175
|
+
if (img.closest("#accessify-root") || img.closest("accessify-widget")) return false;
|
|
8176
|
+
if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return false;
|
|
8177
|
+
const alt = img.getAttribute("alt");
|
|
8178
|
+
if (alt === null) return true;
|
|
8179
|
+
if (isGenericAlt(alt)) return true;
|
|
8180
|
+
if (alt === "" && !isDecorativeImage(img)) return true;
|
|
8181
|
+
return false;
|
|
8182
|
+
}
|
|
8110
8183
|
function scanForMissingAlt() {
|
|
8111
8184
|
const missing = [];
|
|
8112
8185
|
document.querySelectorAll("img").forEach((img) => {
|
|
8113
|
-
if (img
|
|
8114
|
-
if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return;
|
|
8115
|
-
const alt = img.getAttribute("alt");
|
|
8116
|
-
if (alt === "") {
|
|
8117
|
-
const role = img.getAttribute("role");
|
|
8118
|
-
if (role === "presentation" || role === "none") return;
|
|
8119
|
-
if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return;
|
|
8120
|
-
missing.push(img);
|
|
8121
|
-
return;
|
|
8122
|
-
}
|
|
8123
|
-
if (alt === null || isGenericAlt(alt)) missing.push(img);
|
|
8186
|
+
if (needsAltText(img)) missing.push(img);
|
|
8124
8187
|
});
|
|
8125
8188
|
document.querySelectorAll("picture").forEach((picture) => {
|
|
8126
8189
|
if (picture.closest("#accessify-root") || picture.closest("accessify-widget")) return;
|
|
8127
8190
|
const img = picture.querySelector("img");
|
|
8128
|
-
if (img && !missing.includes(img)) {
|
|
8129
|
-
|
|
8130
|
-
if (alt === null || isGenericAlt(alt)) {
|
|
8131
|
-
missing.push(img);
|
|
8132
|
-
}
|
|
8133
|
-
}
|
|
8134
|
-
});
|
|
8135
|
-
document.querySelectorAll("*").forEach((el) => {
|
|
8136
|
-
if (el.closest("#accessify-root") || el.closest("accessify-widget")) return;
|
|
8137
|
-
if (el.tagName === "SCRIPT" || el.tagName === "STYLE") return;
|
|
8138
|
-
const bg = window.getComputedStyle(el).backgroundImage;
|
|
8139
|
-
if (!bg || bg === "none" || !bg.startsWith("url(")) return;
|
|
8140
|
-
const src = bg.match(/url\(["']?(.+?)["']?\)/)?.[1];
|
|
8141
|
-
if (!src || src.includes("data:") || src.includes("gradient")) return;
|
|
8142
|
-
if (el.textContent?.trim() || el.getAttribute("aria-label")) return;
|
|
8143
|
-
if (!el.dataset.accessifyBgSrc) {
|
|
8144
|
-
el.dataset.accessifyBgSrc = src;
|
|
8191
|
+
if (img && !missing.includes(img) && needsAltText(img)) {
|
|
8192
|
+
missing.push(img);
|
|
8145
8193
|
}
|
|
8146
8194
|
});
|
|
8147
8195
|
return missing;
|
|
8148
8196
|
}
|
|
8149
|
-
function
|
|
8150
|
-
const
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
if (
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8168
|
-
if (!processedImages.has(img)) applied.push(img);
|
|
8169
|
-
});
|
|
8170
|
-
return applied;
|
|
8197
|
+
function gatherImageContext(img) {
|
|
8198
|
+
const parts = [];
|
|
8199
|
+
try {
|
|
8200
|
+
const url = new URL(getImageSrc(img), window.location.href);
|
|
8201
|
+
const filename = url.pathname.split("/").pop();
|
|
8202
|
+
if (filename) parts.push(`Filename: ${filename}`);
|
|
8203
|
+
} catch {
|
|
8204
|
+
}
|
|
8205
|
+
const figure = img.closest("figure");
|
|
8206
|
+
if (figure) {
|
|
8207
|
+
const caption = figure.querySelector("figcaption");
|
|
8208
|
+
if (caption?.textContent?.trim()) parts.push(`Caption: ${caption.textContent.trim()}`);
|
|
8209
|
+
}
|
|
8210
|
+
const container = img.parentElement?.parentElement || img.parentElement;
|
|
8211
|
+
if (container) {
|
|
8212
|
+
const heading = container.querySelector("h1, h2, h3, h4, h5, h6");
|
|
8213
|
+
if (heading?.textContent?.trim()) parts.push(`Nearby heading: ${heading.textContent.trim()}`);
|
|
8214
|
+
}
|
|
8215
|
+
return parts.join(". ");
|
|
8171
8216
|
}
|
|
8172
8217
|
function applyAltText(img, altText2) {
|
|
8173
8218
|
img.setAttribute("alt", altText2);
|
|
@@ -8176,12 +8221,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8176
8221
|
if (enabled) {
|
|
8177
8222
|
img.classList.add("accessify-alt-done");
|
|
8178
8223
|
img.classList.remove("accessify-alt-generating");
|
|
8179
|
-
addInfoButton(img);
|
|
8180
8224
|
}
|
|
8181
|
-
img.removeEventListener("mouseenter", onMouseEnter);
|
|
8182
|
-
img.removeEventListener("mouseleave", onMouseLeave);
|
|
8183
|
-
img.addEventListener("mouseenter", onMouseEnter);
|
|
8184
|
-
img.addEventListener("mouseleave", onMouseLeave);
|
|
8185
8225
|
}
|
|
8186
8226
|
async function generateAll() {
|
|
8187
8227
|
if (autoGenerating || !enabled || !aiService) return;
|
|
@@ -8190,7 +8230,8 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8190
8230
|
const uncached = [];
|
|
8191
8231
|
for (const img of missingAltImages) {
|
|
8192
8232
|
if (processedImages.has(img)) continue;
|
|
8193
|
-
const
|
|
8233
|
+
const src = getImageSrc(img);
|
|
8234
|
+
const cached = await getCachedAltText(src);
|
|
8194
8235
|
if (cached) {
|
|
8195
8236
|
applyAltText(img, cached);
|
|
8196
8237
|
} else {
|
|
@@ -8209,16 +8250,17 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8209
8250
|
await Promise.all(batch.map(async (img) => {
|
|
8210
8251
|
if (!enabled) return;
|
|
8211
8252
|
try {
|
|
8253
|
+
const src = getImageSrc(img);
|
|
8212
8254
|
const ctx = gatherImageContext(img);
|
|
8213
|
-
const alt = await aiService.generateAltText(
|
|
8255
|
+
const alt = await aiService.generateAltText(src, ctx, lang());
|
|
8214
8256
|
if (alt && enabled) {
|
|
8215
8257
|
applyAltText(img, alt);
|
|
8216
|
-
setCachedAltText(
|
|
8258
|
+
setCachedAltText(src, alt, lang()).catch(() => {
|
|
8217
8259
|
});
|
|
8218
|
-
if (siteKey) persistAltTextToServer(siteKey, proxyUrl,
|
|
8260
|
+
if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());
|
|
8219
8261
|
}
|
|
8220
8262
|
} catch (err) {
|
|
8221
|
-
console.warn("[Accessify] Alt-text generation failed:", img
|
|
8263
|
+
console.warn("[Accessify] Alt-text generation failed:", getImageSrc(img), err);
|
|
8222
8264
|
img.classList.remove("accessify-alt-generating");
|
|
8223
8265
|
}
|
|
8224
8266
|
}));
|
|
@@ -8228,7 +8270,8 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8228
8270
|
}
|
|
8229
8271
|
async function generateSingle(img) {
|
|
8230
8272
|
if (!aiService || !enabled) return;
|
|
8231
|
-
const
|
|
8273
|
+
const src = getImageSrc(img);
|
|
8274
|
+
const cached = await getCachedAltText(src);
|
|
8232
8275
|
if (cached) {
|
|
8233
8276
|
applyAltText(img, cached);
|
|
8234
8277
|
updateBadge();
|
|
@@ -8237,16 +8280,16 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8237
8280
|
img.classList.add("accessify-alt-generating");
|
|
8238
8281
|
try {
|
|
8239
8282
|
const ctx = gatherImageContext(img);
|
|
8240
|
-
const alt = await aiService.generateAltText(
|
|
8283
|
+
const alt = await aiService.generateAltText(src, ctx, lang());
|
|
8241
8284
|
if (alt && enabled) {
|
|
8242
8285
|
applyAltText(img, alt);
|
|
8243
|
-
setCachedAltText(
|
|
8286
|
+
setCachedAltText(src, alt, lang()).catch(() => {
|
|
8244
8287
|
});
|
|
8245
|
-
if (siteKey) persistAltTextToServer(siteKey, proxyUrl,
|
|
8288
|
+
if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());
|
|
8246
8289
|
updateBadge();
|
|
8247
8290
|
}
|
|
8248
8291
|
} catch (err) {
|
|
8249
|
-
console.warn("[Accessify] Alt-text generation failed:",
|
|
8292
|
+
console.warn("[Accessify] Alt-text generation failed:", src, err);
|
|
8250
8293
|
img.classList.remove("accessify-alt-generating");
|
|
8251
8294
|
}
|
|
8252
8295
|
}
|
|
@@ -8254,38 +8297,35 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8254
8297
|
removeBadge();
|
|
8255
8298
|
const remaining = missingAltImages.filter((img) => !processedImages.has(img)).length;
|
|
8256
8299
|
const generating = missingAltImages.filter((img) => img.classList.contains("accessify-alt-generating")).length;
|
|
8257
|
-
const generated = processedImages.size;
|
|
8258
|
-
const withExisting = existingAltImages.length;
|
|
8259
|
-
const totalImages = missingAltImages.length + withExisting;
|
|
8260
8300
|
if (generating > 0) {
|
|
8261
8301
|
showBadge(isDE() ? `${generating} Bilder werden analysiert…` : `Analyzing ${generating} images…`, "#f77f00", generating);
|
|
8262
8302
|
return;
|
|
8263
8303
|
}
|
|
8264
|
-
if (remaining === 0 &&
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
setTimeout(() => removeBadge(),
|
|
8304
|
+
if (remaining === 0 && processedImages.size > 0) {
|
|
8305
|
+
showBadge(
|
|
8306
|
+
isDE() ? `✓ ${processedImages.size} Bildbeschreibungen erstellt` : `✓ ${processedImages.size} descriptions generated`,
|
|
8307
|
+
"#2a9d8f",
|
|
8308
|
+
0
|
|
8309
|
+
);
|
|
8310
|
+
setTimeout(() => removeBadge(), 6e3);
|
|
8271
8311
|
return;
|
|
8272
8312
|
}
|
|
8273
8313
|
if (remaining > 0) {
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8314
|
+
showBadge(
|
|
8315
|
+
isDE() ? `${remaining} Bilder ohne Beschreibung` : `${remaining} images without description`,
|
|
8316
|
+
"#e63946",
|
|
8317
|
+
remaining
|
|
8318
|
+
);
|
|
8279
8319
|
}
|
|
8280
8320
|
}
|
|
8281
8321
|
function showBadge(text, color, count) {
|
|
8282
8322
|
const badge = document.createElement("div");
|
|
8283
|
-
badge.className =
|
|
8323
|
+
badge.className = "accessify-alt-badge";
|
|
8284
8324
|
badge.setAttribute("role", "status");
|
|
8285
8325
|
badge.setAttribute("aria-live", "polite");
|
|
8286
8326
|
if (count > 0) {
|
|
8287
8327
|
const c = document.createElement("span");
|
|
8288
|
-
c.className =
|
|
8328
|
+
c.className = "accessify-alt-badge-count";
|
|
8289
8329
|
c.style.background = color;
|
|
8290
8330
|
c.textContent = String(count);
|
|
8291
8331
|
badge.appendChild(c);
|
|
@@ -8300,108 +8340,67 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8300
8340
|
badgeEl?.remove();
|
|
8301
8341
|
badgeEl = null;
|
|
8302
8342
|
}
|
|
8303
|
-
function gatherImageContext(img) {
|
|
8304
|
-
const parts = [];
|
|
8305
|
-
try {
|
|
8306
|
-
const url = new URL(img.src, window.location.href);
|
|
8307
|
-
const filename = url.pathname.split("/").pop();
|
|
8308
|
-
if (filename) parts.push(`Filename: ${filename}`);
|
|
8309
|
-
} catch {
|
|
8310
|
-
}
|
|
8311
|
-
const figure = img.closest("figure");
|
|
8312
|
-
if (figure) {
|
|
8313
|
-
const caption = figure.querySelector("figcaption");
|
|
8314
|
-
if (caption?.textContent?.trim()) parts.push(`Caption: ${caption.textContent.trim()}`);
|
|
8315
|
-
}
|
|
8316
|
-
const parent = img.parentElement;
|
|
8317
|
-
if (parent) {
|
|
8318
|
-
const heading = parent.querySelector("h1, h2, h3, h4, h5, h6");
|
|
8319
|
-
if (heading?.textContent?.trim()) parts.push(`Nearby heading: ${heading.textContent.trim()}`);
|
|
8320
|
-
}
|
|
8321
|
-
const describedBy = img.getAttribute("aria-describedby");
|
|
8322
|
-
if (describedBy) {
|
|
8323
|
-
const descEl = document.getElementById(describedBy);
|
|
8324
|
-
if (descEl?.textContent?.trim()) parts.push(`Description: ${descEl.textContent.trim()}`);
|
|
8325
|
-
}
|
|
8326
|
-
return parts.join(". ");
|
|
8327
|
-
}
|
|
8328
|
-
let domObserver = null;
|
|
8329
8343
|
function tryRegisterImage(img) {
|
|
8330
8344
|
if (!enabled) return;
|
|
8331
8345
|
if (img.closest("#accessify-root")) return;
|
|
8332
|
-
if (missingAltImages.includes(img)
|
|
8346
|
+
if (missingAltImages.includes(img)) return;
|
|
8333
8347
|
function addIfValid() {
|
|
8334
|
-
if (!enabled || missingAltImages.includes(img)
|
|
8348
|
+
if (!enabled || missingAltImages.includes(img)) return;
|
|
8335
8349
|
if (img.naturalWidth < 20 || img.naturalHeight < 20) return;
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
if (isMissing) {
|
|
8350
|
+
markImageDescribable(img);
|
|
8351
|
+
if (needsAltText(img)) {
|
|
8339
8352
|
img.classList.add(HIGHLIGHT_CLASS);
|
|
8340
8353
|
missingAltImages.push(img);
|
|
8341
8354
|
updateBadge();
|
|
8342
8355
|
generateSingle(img);
|
|
8343
|
-
} else if (alt && alt.trim()) {
|
|
8344
|
-
existingAltImages.push(img);
|
|
8345
|
-
img.classList.add(HAS_ALT_CLASS);
|
|
8346
|
-
img.removeEventListener("mouseenter", onMouseEnter);
|
|
8347
|
-
img.removeEventListener("mouseleave", onMouseLeave);
|
|
8348
|
-
img.addEventListener("mouseenter", onMouseEnter);
|
|
8349
|
-
img.addEventListener("mouseleave", onMouseLeave);
|
|
8350
|
-
updateBadge();
|
|
8351
8356
|
}
|
|
8352
8357
|
}
|
|
8353
8358
|
if (img.complete && img.naturalWidth > 0) addIfValid();
|
|
8354
8359
|
else img.addEventListener("load", addIfValid, { once: true });
|
|
8355
8360
|
}
|
|
8356
|
-
function isDecorativeImage(img) {
|
|
8357
|
-
const role = img.getAttribute("role");
|
|
8358
|
-
if (role === "presentation" || role === "none") return true;
|
|
8359
|
-
if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return true;
|
|
8360
|
-
return false;
|
|
8361
|
-
}
|
|
8362
8361
|
function activate() {
|
|
8363
8362
|
if (enabled) return;
|
|
8364
8363
|
enabled = true;
|
|
8365
8364
|
injectStyles();
|
|
8366
|
-
const alreadyApplied =
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
processedImages.
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
img.addEventListener("mouseenter", onMouseEnter);
|
|
8376
|
-
img.addEventListener("mouseleave", onMouseLeave);
|
|
8377
|
-
}
|
|
8365
|
+
const alreadyApplied = document.querySelectorAll('img[data-accessify-alt="auto"]');
|
|
8366
|
+
alreadyApplied.forEach((img) => {
|
|
8367
|
+
if (img.closest("#accessify-root")) return;
|
|
8368
|
+
if (!processedImages.has(img)) {
|
|
8369
|
+
processedImages.set(img, { generatedAlt: img.getAttribute("alt") || "" });
|
|
8370
|
+
missingAltImages.push(img);
|
|
8371
|
+
img.classList.add(HIGHLIGHT_CLASS, "accessify-alt-done");
|
|
8372
|
+
}
|
|
8373
|
+
});
|
|
8378
8374
|
const missing = scanForMissingAlt();
|
|
8379
8375
|
for (const img of missing) {
|
|
8380
|
-
missingAltImages.
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
for (const img of withAlt) {
|
|
8385
|
-
existingAltImages.push(img);
|
|
8386
|
-
img.classList.add(HAS_ALT_CLASS);
|
|
8387
|
-
img.removeEventListener("mouseenter", onMouseEnter);
|
|
8388
|
-
img.removeEventListener("mouseleave", onMouseLeave);
|
|
8389
|
-
img.addEventListener("mouseenter", onMouseEnter);
|
|
8390
|
-
img.addEventListener("mouseleave", onMouseLeave);
|
|
8376
|
+
if (!missingAltImages.includes(img)) {
|
|
8377
|
+
missingAltImages.push(img);
|
|
8378
|
+
img.classList.add(HIGHLIGHT_CLASS);
|
|
8379
|
+
}
|
|
8391
8380
|
}
|
|
8392
8381
|
updateBadge();
|
|
8393
8382
|
generateAll();
|
|
8383
|
+
enableClickToDescribe();
|
|
8394
8384
|
document.querySelectorAll("img").forEach((img) => {
|
|
8395
8385
|
if (!img.complete) tryRegisterImage(img);
|
|
8396
8386
|
});
|
|
8397
8387
|
setTimeout(() => {
|
|
8398
|
-
if (enabled)
|
|
8388
|
+
if (enabled) {
|
|
8389
|
+
document.querySelectorAll("img").forEach(tryRegisterImage);
|
|
8390
|
+
}
|
|
8399
8391
|
}, 2e3);
|
|
8400
8392
|
domObserver = new MutationObserver((mutations) => {
|
|
8401
8393
|
for (const m of mutations) {
|
|
8402
8394
|
for (const node of m.addedNodes) {
|
|
8403
8395
|
if (node instanceof HTMLImageElement) tryRegisterImage(node);
|
|
8404
|
-
else if (node instanceof HTMLElement)
|
|
8396
|
+
else if (node instanceof HTMLElement) {
|
|
8397
|
+
node.querySelectorAll("img").forEach(tryRegisterImage);
|
|
8398
|
+
node.querySelectorAll("img").forEach((img) => {
|
|
8399
|
+
if (!img.closest("#accessify-root") && !img.closest("accessify-widget")) {
|
|
8400
|
+
img.dataset.a11yDescribable = "true";
|
|
8401
|
+
}
|
|
8402
|
+
});
|
|
8403
|
+
}
|
|
8405
8404
|
}
|
|
8406
8405
|
}
|
|
8407
8406
|
});
|
|
@@ -8412,26 +8411,20 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8412
8411
|
autoGenerating = false;
|
|
8413
8412
|
domObserver?.disconnect();
|
|
8414
8413
|
domObserver = null;
|
|
8415
|
-
|
|
8416
|
-
closeReportPanel();
|
|
8417
|
-
removeInfoButtons();
|
|
8414
|
+
disableClickToDescribe();
|
|
8418
8415
|
removeBadge();
|
|
8419
8416
|
missingAltImages.forEach((img) => {
|
|
8420
8417
|
img.classList.remove(HIGHLIGHT_CLASS, "accessify-alt-done", "accessify-alt-generating");
|
|
8421
8418
|
});
|
|
8422
8419
|
missingAltImages = [];
|
|
8423
|
-
existingAltImages.forEach((img) => {
|
|
8424
|
-
img.classList.remove(HAS_ALT_CLASS);
|
|
8425
|
-
});
|
|
8426
|
-
existingAltImages = [];
|
|
8427
8420
|
removeStyles();
|
|
8428
8421
|
}
|
|
8429
8422
|
autoApplyCachedAltTexts({ siteKey, proxyUrl, lang: initialLang }).catch(() => {
|
|
8430
8423
|
});
|
|
8431
8424
|
return {
|
|
8432
8425
|
id: "alt-text",
|
|
8433
|
-
name: () => isDE() ? "
|
|
8434
|
-
description: isDE() ? "
|
|
8426
|
+
name: () => isDE() ? "Bildbeschreibung" : "Image Description",
|
|
8427
|
+
description: isDE() ? "Bilder per Klick beschreiben lassen" : "Click images to get AI descriptions",
|
|
8435
8428
|
icon: "alt-text",
|
|
8436
8429
|
category: "ai",
|
|
8437
8430
|
activate,
|
|
@@ -8440,7 +8433,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8440
8433
|
id: "alt-text",
|
|
8441
8434
|
enabled,
|
|
8442
8435
|
value: {
|
|
8443
|
-
missingCount: missingAltImages.length,
|
|
8436
|
+
missingCount: missingAltImages.filter((img) => !processedImages.has(img)).length,
|
|
8444
8437
|
processedCount: processedImages.size
|
|
8445
8438
|
}
|
|
8446
8439
|
})
|
|
@@ -8637,4 +8630,4 @@ export {
|
|
|
8637
8630
|
init as i,
|
|
8638
8631
|
t
|
|
8639
8632
|
};
|
|
8640
|
-
//# sourceMappingURL=index-
|
|
8633
|
+
//# sourceMappingURL=index-B9BgMU66.js.map
|