accessify-widget 0.3.4 → 0.3.6
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-DcqLuguC.js → index-DDv0soH8.js} +164 -11
- package/dist/{index-DcqLuguC.js.map → index-DDv0soH8.js.map} +1 -1
- package/dist/{keyboard-nav-BYCst88Y.js → keyboard-nav-DYBrrE4b.js} +2 -2
- package/dist/{keyboard-nav-BYCst88Y.js.map → keyboard-nav-DYBrrE4b.js.map} +1 -1
- package/dist/{page-structure-MGMdSnYw.js → page-structure-BTemvR2X.js} +2 -2
- package/dist/{page-structure-MGMdSnYw.js.map → page-structure-BTemvR2X.js.map} +1 -1
- package/dist/widget.js +1 -1
- package/dist/widget.js.map +1 -1
- package/package.json +1 -1
package/dist/accessify.mjs
CHANGED
|
@@ -4779,7 +4779,7 @@ const deJson = {
|
|
|
4779
4779
|
"feature.textSimplify": "Text vereinfachen",
|
|
4780
4780
|
"feature.textSimplify.desc": "Text in Einfache Sprache umwandeln",
|
|
4781
4781
|
"feature.altText": "Bildbeschreibung",
|
|
4782
|
-
"feature.altText.desc": "
|
|
4782
|
+
"feature.altText.desc": "Bildbeschreibungen per Hover anzeigen und fehlende automatisch erzeugen",
|
|
4783
4783
|
"feature.autoScan": "WCAG-Prüfung",
|
|
4784
4784
|
"feature.autoScan.desc": "Seite auf Barrierefreiheit prüfen",
|
|
4785
4785
|
"feature.saturation": "Sättigung",
|
|
@@ -4868,7 +4868,7 @@ const enJson = {
|
|
|
4868
4868
|
"feature.textSimplify": "Simplify Text",
|
|
4869
4869
|
"feature.textSimplify.desc": "Simplify text for easier understanding",
|
|
4870
4870
|
"feature.altText": "Image Description",
|
|
4871
|
-
"feature.altText.desc": "
|
|
4871
|
+
"feature.altText.desc": "Show image descriptions on hover and auto-generate missing ones",
|
|
4872
4872
|
"feature.autoScan": "WCAG Scan",
|
|
4873
4873
|
"feature.autoScan.desc": "Scan page for accessibility issues",
|
|
4874
4874
|
"feature.saturation": "Saturation",
|
|
@@ -6433,14 +6433,14 @@ function FeatureGrid($$anchor, $$props) {
|
|
|
6433
6433
|
const FEATURE_LOADERS = {
|
|
6434
6434
|
contrast: () => import("./contrast-CqsICAkU.js"),
|
|
6435
6435
|
"text-size": () => import("./text-size-C6OFhCGi.js"),
|
|
6436
|
-
"keyboard-nav": () => import("./keyboard-nav-
|
|
6436
|
+
"keyboard-nav": () => import("./keyboard-nav-DYBrrE4b.js"),
|
|
6437
6437
|
"link-highlight": () => import("./link-highlight-DBGm067Y.js"),
|
|
6438
6438
|
"reading-guide": () => import("./reading-guide-VT8NciIL.js"),
|
|
6439
6439
|
"reading-mask": () => import("./reading-mask-BABChuCz.js"),
|
|
6440
6440
|
"animation-stop": () => import("./animation-stop-C0MwseK0.js"),
|
|
6441
6441
|
"hide-images": () => import("./hide-images-B_LeCBcd.js"),
|
|
6442
6442
|
"big-cursor": () => import("./big-cursor-B2UKu9dQ.js"),
|
|
6443
|
-
"page-structure": () => import("./page-structure-
|
|
6443
|
+
"page-structure": () => import("./page-structure-BTemvR2X.js"),
|
|
6444
6444
|
tts: () => import("./tts-CjszLRnb.js"),
|
|
6445
6445
|
"text-simplify": () => import("./text-simplify-Cvhpio7g.js"),
|
|
6446
6446
|
"alt-text": () => Promise.resolve().then(() => altText)
|
|
@@ -6866,6 +6866,74 @@ function getTranslatableAttributes(root2 = document.body) {
|
|
|
6866
6866
|
}
|
|
6867
6867
|
return attrs;
|
|
6868
6868
|
}
|
|
6869
|
+
const BLOCK_TAGS = /* @__PURE__ */ new Set(["H1", "H2", "H3", "H4", "H5", "H6", "P", "LI", "TD", "TH", "CAPTION", "FIGCAPTION", "BLOCKQUOTE", "DT", "DD"]);
|
|
6870
|
+
function groupTextNodes(textNodes) {
|
|
6871
|
+
const groups = [];
|
|
6872
|
+
const assigned = /* @__PURE__ */ new Set();
|
|
6873
|
+
for (const node of textNodes) {
|
|
6874
|
+
if (assigned.has(node)) continue;
|
|
6875
|
+
const block2 = findBlockAncestor(node);
|
|
6876
|
+
if (block2 && BLOCK_TAGS.has(block2.tagName)) {
|
|
6877
|
+
const siblings = textNodes.filter((n) => !assigned.has(n) && findBlockAncestor(n) === block2);
|
|
6878
|
+
if (siblings.length > 1) {
|
|
6879
|
+
for (const s of siblings) assigned.add(s);
|
|
6880
|
+
const fullText = (block2.textContent?.trim() || "").replace(/\s+/g, " ");
|
|
6881
|
+
const shortNodes = siblings.filter((n) => n.data.trim().length <= 2).length;
|
|
6882
|
+
const charPerNode = shortNodes > siblings.length * 0.5;
|
|
6883
|
+
groups.push({ nodes: siblings, fullText, singleNode: false, charPerNode });
|
|
6884
|
+
continue;
|
|
6885
|
+
}
|
|
6886
|
+
}
|
|
6887
|
+
assigned.add(node);
|
|
6888
|
+
groups.push({ nodes: [node], fullText: node.data.trim(), singleNode: true, charPerNode: false });
|
|
6889
|
+
}
|
|
6890
|
+
return groups;
|
|
6891
|
+
}
|
|
6892
|
+
function distributeCharsToNodes(nodes, translated) {
|
|
6893
|
+
const origLengths = nodes.map((n) => n.data.trim().length);
|
|
6894
|
+
const origWhitespace = nodes.map((n) => ({
|
|
6895
|
+
leading: n.data.match(/^\s*/)?.[0] || "",
|
|
6896
|
+
trailing: n.data.match(/\s*$/)?.[0] || ""
|
|
6897
|
+
}));
|
|
6898
|
+
let charIdx = 0;
|
|
6899
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
6900
|
+
const origLen = origLengths[i];
|
|
6901
|
+
if (origLen === 0) {
|
|
6902
|
+
continue;
|
|
6903
|
+
}
|
|
6904
|
+
const chunk = translated.slice(charIdx, charIdx + origLen);
|
|
6905
|
+
charIdx += origLen;
|
|
6906
|
+
nodes[i].data = origWhitespace[i].leading + chunk + origWhitespace[i].trailing;
|
|
6907
|
+
}
|
|
6908
|
+
if (charIdx < translated.length) {
|
|
6909
|
+
const overflow = translated.slice(charIdx);
|
|
6910
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
6911
|
+
if (origLengths[i] > 0) {
|
|
6912
|
+
nodes[i].data = nodes[i].data.trimEnd() + overflow + origWhitespace[i].trailing;
|
|
6913
|
+
break;
|
|
6914
|
+
}
|
|
6915
|
+
}
|
|
6916
|
+
}
|
|
6917
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
6918
|
+
if (origLengths[i] > 0) {
|
|
6919
|
+
const assigned = translated.slice(
|
|
6920
|
+
origLengths.slice(0, i).reduce((a, b) => a + b, 0),
|
|
6921
|
+
origLengths.slice(0, i + 1).reduce((a, b) => a + b, 0)
|
|
6922
|
+
);
|
|
6923
|
+
if (!assigned) {
|
|
6924
|
+
nodes[i].data = origWhitespace[i].leading + origWhitespace[i].trailing;
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
}
|
|
6928
|
+
}
|
|
6929
|
+
function findBlockAncestor(node) {
|
|
6930
|
+
let el = node.parentElement;
|
|
6931
|
+
while (el && el !== document.body) {
|
|
6932
|
+
if (BLOCK_TAGS.has(el.tagName)) return el;
|
|
6933
|
+
el = el.parentElement;
|
|
6934
|
+
}
|
|
6935
|
+
return null;
|
|
6936
|
+
}
|
|
6869
6937
|
async function translatePage(targetLang) {
|
|
6870
6938
|
const pageLang = document.documentElement.lang?.split("-")[0] || "auto";
|
|
6871
6939
|
const textNodes = getTranslatableTextNodes();
|
|
@@ -6883,8 +6951,9 @@ async function translatePage(targetLang) {
|
|
|
6883
6951
|
savedAttrs.push(entry);
|
|
6884
6952
|
}
|
|
6885
6953
|
}
|
|
6954
|
+
const nodeGroups = groupTextNodes(textNodes);
|
|
6886
6955
|
const allTexts = [
|
|
6887
|
-
...
|
|
6956
|
+
...nodeGroups.map((g) => g.fullText),
|
|
6888
6957
|
...attrEntries.map((a) => a.original.trim())
|
|
6889
6958
|
].filter(Boolean);
|
|
6890
6959
|
const uniqueTexts = [...new Set(allTexts)];
|
|
@@ -6897,13 +6966,23 @@ async function translatePage(targetLang) {
|
|
|
6897
6966
|
}
|
|
6898
6967
|
});
|
|
6899
6968
|
observerPaused = true;
|
|
6900
|
-
for (const
|
|
6901
|
-
const
|
|
6902
|
-
|
|
6903
|
-
if (
|
|
6969
|
+
for (const group of nodeGroups) {
|
|
6970
|
+
const replacement = lookup.get(group.fullText);
|
|
6971
|
+
if (!replacement) continue;
|
|
6972
|
+
if (group.singleNode) {
|
|
6973
|
+
const node = group.nodes[0];
|
|
6904
6974
|
const leading = node.data.match(/^\s*/)?.[0] || "";
|
|
6905
6975
|
const trailing = node.data.match(/\s*$/)?.[0] || "";
|
|
6906
6976
|
node.data = leading + replacement + trailing;
|
|
6977
|
+
} else if (group.charPerNode) {
|
|
6978
|
+
distributeCharsToNodes(group.nodes, replacement);
|
|
6979
|
+
} else {
|
|
6980
|
+
const firstNode = group.nodes[0];
|
|
6981
|
+
const leading = firstNode.data.match(/^\s*/)?.[0] || "";
|
|
6982
|
+
firstNode.data = leading + replacement;
|
|
6983
|
+
for (let i = 1; i < group.nodes.length; i++) {
|
|
6984
|
+
group.nodes[i].data = "";
|
|
6985
|
+
}
|
|
6907
6986
|
}
|
|
6908
6987
|
}
|
|
6909
6988
|
for (const entry of attrEntries) {
|
|
@@ -8075,6 +8154,79 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8075
8154
|
img.removeAttribute("title");
|
|
8076
8155
|
img.removeAttribute("data-accessify-title");
|
|
8077
8156
|
});
|
|
8157
|
+
document.querySelectorAll("[data-accessify-bg-alt]").forEach((el) => {
|
|
8158
|
+
el.removeAttribute("role");
|
|
8159
|
+
el.removeAttribute("aria-label");
|
|
8160
|
+
el.removeAttribute("title");
|
|
8161
|
+
el.removeAttribute("data-accessify-bg-alt");
|
|
8162
|
+
});
|
|
8163
|
+
}
|
|
8164
|
+
function scanForBackgroundImages() {
|
|
8165
|
+
const found = [];
|
|
8166
|
+
const candidates = document.querySelectorAll(
|
|
8167
|
+
'header, [class*="hero"], [class*="banner"], [class*="header"], [class*="bg-"], [class*="background"], [style*="background"]'
|
|
8168
|
+
);
|
|
8169
|
+
for (const el of candidates) {
|
|
8170
|
+
if (el.closest("#accessify-root") || el.closest("accessify-widget")) continue;
|
|
8171
|
+
if (el.getAttribute("data-accessify-bg-alt")) continue;
|
|
8172
|
+
const style = getComputedStyle(el);
|
|
8173
|
+
const bg = style.backgroundImage;
|
|
8174
|
+
if (!bg || bg === "none") continue;
|
|
8175
|
+
const urlMatch = bg.match(/url\(["']?([^"')]+)["']?\)/);
|
|
8176
|
+
if (!urlMatch) continue;
|
|
8177
|
+
const rect = el.getBoundingClientRect();
|
|
8178
|
+
if (rect.width < 100 || rect.height < 100) continue;
|
|
8179
|
+
if (el.getAttribute("role") === "img" && el.getAttribute("aria-label")) continue;
|
|
8180
|
+
found.push(el);
|
|
8181
|
+
}
|
|
8182
|
+
return found;
|
|
8183
|
+
}
|
|
8184
|
+
function getBackgroundImageUrl(el) {
|
|
8185
|
+
const bg = getComputedStyle(el).backgroundImage;
|
|
8186
|
+
const match = bg?.match(/url\(["']?([^"')]+)["']?\)/);
|
|
8187
|
+
return match ? match[1] : null;
|
|
8188
|
+
}
|
|
8189
|
+
function applyBgAlt(el, altText2) {
|
|
8190
|
+
el.setAttribute("role", "img");
|
|
8191
|
+
el.setAttribute("aria-label", altText2);
|
|
8192
|
+
el.setAttribute("title", altText2);
|
|
8193
|
+
el.setAttribute("data-accessify-bg-alt", "auto");
|
|
8194
|
+
}
|
|
8195
|
+
async function generateBgAlts() {
|
|
8196
|
+
if (!aiService || !enabled) return;
|
|
8197
|
+
const bgElements = scanForBackgroundImages();
|
|
8198
|
+
for (const el of bgElements) {
|
|
8199
|
+
if (!enabled) break;
|
|
8200
|
+
const src = getBackgroundImageUrl(el);
|
|
8201
|
+
if (!src) continue;
|
|
8202
|
+
const cached = await getCachedAltText(src);
|
|
8203
|
+
if (cached) {
|
|
8204
|
+
applyBgAlt(el, cached);
|
|
8205
|
+
continue;
|
|
8206
|
+
}
|
|
8207
|
+
try {
|
|
8208
|
+
const ctx = gatherBgContext(el);
|
|
8209
|
+
const alt = await aiService.generateAltText(src, ctx, lang());
|
|
8210
|
+
if (alt && enabled) {
|
|
8211
|
+
applyBgAlt(el, alt);
|
|
8212
|
+
setCachedAltText(src, alt, lang()).catch(() => {
|
|
8213
|
+
});
|
|
8214
|
+
if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, alt, lang());
|
|
8215
|
+
}
|
|
8216
|
+
} catch (err) {
|
|
8217
|
+
console.warn("[Accessify] Bg alt-text generation failed:", src, err);
|
|
8218
|
+
}
|
|
8219
|
+
}
|
|
8220
|
+
}
|
|
8221
|
+
function gatherBgContext(el) {
|
|
8222
|
+
const parts = [];
|
|
8223
|
+
parts.push(`Element: <${el.tagName.toLowerCase()}>`);
|
|
8224
|
+
if (el.className) parts.push(`Class: ${el.className}`);
|
|
8225
|
+
const text = el.textContent?.trim().slice(0, 100);
|
|
8226
|
+
if (text) parts.push(`Overlay text: ${text}`);
|
|
8227
|
+
const heading = el.querySelector("h1, h2, h3");
|
|
8228
|
+
if (heading?.textContent?.trim()) parts.push(`Heading: ${heading.textContent.trim()}`);
|
|
8229
|
+
return parts.join(". ");
|
|
8078
8230
|
}
|
|
8079
8231
|
async function generateAll() {
|
|
8080
8232
|
if (autoGenerating || !enabled || !aiService) return;
|
|
@@ -8176,6 +8328,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8176
8328
|
}
|
|
8177
8329
|
}
|
|
8178
8330
|
generateAll();
|
|
8331
|
+
generateBgAlts();
|
|
8179
8332
|
applyTitlesToAllImages();
|
|
8180
8333
|
document.querySelectorAll("img").forEach((img) => {
|
|
8181
8334
|
if (!img.complete) tryRegisterImage(img);
|
|
@@ -8211,7 +8364,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
|
|
|
8211
8364
|
return {
|
|
8212
8365
|
id: "alt-text",
|
|
8213
8366
|
name: () => isDE() ? "Bildbeschreibung" : "Image Description",
|
|
8214
|
-
description: isDE() ? "
|
|
8367
|
+
description: isDE() ? "Bildbeschreibungen per Hover anzeigen und fehlende automatisch erzeugen" : "Show image descriptions on hover and auto-generate missing ones",
|
|
8215
8368
|
icon: "alt-text",
|
|
8216
8369
|
category: "ai",
|
|
8217
8370
|
activate,
|
|
@@ -8417,4 +8570,4 @@ export {
|
|
|
8417
8570
|
init as i,
|
|
8418
8571
|
t
|
|
8419
8572
|
};
|
|
8420
|
-
//# sourceMappingURL=index-
|
|
8573
|
+
//# sourceMappingURL=index-DDv0soH8.js.map
|