accessify-widget 0.3.3 → 0.3.4

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-B8sAE1Po.js";
1
+ import { d, i } from "./index-DcqLuguC.js";
2
2
  export {
3
3
  d as destroy,
4
4
  i as init
@@ -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-SGx_nXud.js"),
6436
+ "keyboard-nav": () => import("./keyboard-nav-BYCst88Y.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-BfD6Mw28.js"),
6443
+ "page-structure": () => import("./page-structure-MGMdSnYw.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)
@@ -7984,258 +7984,16 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
7984
7984
  const siteKey = serverConfig?.siteKey || "";
7985
7985
  const proxyUrl = serverConfig?.proxyUrl || "";
7986
7986
  let enabled = false;
7987
- let styleEl = null;
7988
- let tooltipEl = null;
7989
7987
  let domObserver = null;
7990
7988
  let autoGenerating = false;
7991
7989
  let missingAltImages = [];
7992
7990
  const processedImages = /* @__PURE__ */ new Map();
7993
- let describeClickHandler = null;
7994
- let describeEscHandler = null;
7995
- const describeButtons = /* @__PURE__ */ new Map();
7996
7991
  function lang() {
7997
7992
  return getCurrentWidgetLang() || initialLang;
7998
7993
  }
7999
7994
  function isDE() {
8000
7995
  return lang().startsWith("de");
8001
7996
  }
8002
- const STYLE_ID = "accessify-alt-text-styles";
8003
- function getStyles() {
8004
- return `
8005
- img[data-a11y-describable="true"]:not([data-a11y-is-link="true"]) {
8006
- cursor: help !important;
8007
- }
8008
-
8009
- .accessify-describe-btn {
8010
- position: absolute;
8011
- top: 6px;
8012
- right: 6px;
8013
- z-index: 10;
8014
- width: 26px;
8015
- height: 26px;
8016
- padding: 0;
8017
- border: none;
8018
- border-radius: 50%;
8019
- background: rgba(0, 0, 0, 0.55);
8020
- color: #fff;
8021
- font-family: system-ui, -apple-system, sans-serif;
8022
- font-size: 14px;
8023
- font-weight: 700;
8024
- line-height: 26px;
8025
- text-align: center;
8026
- cursor: help;
8027
- opacity: 0;
8028
- transition: opacity 0.15s ease;
8029
- backdrop-filter: blur(4px);
8030
- }
8031
- img[data-a11y-is-link="true"]:hover ~ .accessify-describe-btn,
8032
- .accessify-describe-btn:hover {
8033
- opacity: 1;
8034
- }
8035
- .accessify-describe-btn:hover {
8036
- background: rgba(0, 0, 0, 0.75);
8037
- }
8038
-
8039
- .accessify-describe-tooltip {
8040
- position: fixed;
8041
- z-index: 2147483647;
8042
- max-width: 320px;
8043
- padding: 10px 14px;
8044
- background: rgba(0, 0, 0, 0.75);
8045
- color: #fff;
8046
- border-radius: 8px;
8047
- backdrop-filter: blur(8px);
8048
- font-family: system-ui, -apple-system, sans-serif;
8049
- font-size: 13px;
8050
- line-height: 1.5;
8051
- word-break: break-word;
8052
- animation: accessify-fade-in 0.12s ease;
8053
- pointer-events: auto;
8054
- }
8055
- .accessify-describe-loading {
8056
- display: flex;
8057
- align-items: center;
8058
- gap: 8px;
8059
- color: #ddd;
8060
- font-style: italic;
8061
- }
8062
- .accessify-describe-loading::before {
8063
- content: '';
8064
- width: 12px;
8065
- height: 12px;
8066
- border: 2px solid rgba(255,255,255,0.3);
8067
- border-top-color: #fff;
8068
- border-radius: 50%;
8069
- animation: accessify-spin 0.8s linear infinite;
8070
- }
8071
- @keyframes accessify-spin {
8072
- to { transform: rotate(360deg); }
8073
- }
8074
- @keyframes accessify-fade-in {
8075
- from { opacity: 0; transform: translateY(4px); }
8076
- to { opacity: 1; transform: translateY(0); }
8077
- }
8078
- `;
8079
- }
8080
- function injectStyles() {
8081
- if (document.getElementById(STYLE_ID)) return;
8082
- styleEl = document.createElement("style");
8083
- styleEl.id = STYLE_ID;
8084
- styleEl.textContent = getStyles();
8085
- document.head.appendChild(styleEl);
8086
- }
8087
- function removeStyles() {
8088
- styleEl?.remove();
8089
- styleEl = null;
8090
- document.getElementById(STYLE_ID)?.remove();
8091
- }
8092
- function showDescribeTooltip(text, rect, loading = false) {
8093
- hideDescribeTooltip();
8094
- const tip = document.createElement("div");
8095
- tip.className = "accessify-describe-tooltip";
8096
- if (loading) {
8097
- const loadingEl = document.createElement("div");
8098
- loadingEl.className = "accessify-describe-loading";
8099
- loadingEl.textContent = isDE() ? "Bild wird analysiert…" : "Analyzing image…";
8100
- tip.appendChild(loadingEl);
8101
- } else {
8102
- const textEl = document.createElement("div");
8103
- textEl.textContent = text;
8104
- tip.appendChild(textEl);
8105
- }
8106
- document.body.appendChild(tip);
8107
- tooltipEl = tip;
8108
- const tipRect = tip.getBoundingClientRect();
8109
- let top = rect.bottom + 8;
8110
- if (top + tipRect.height > window.innerHeight - 8) {
8111
- top = rect.top - tipRect.height - 8;
8112
- }
8113
- if (top < 4) top = 4;
8114
- let left = rect.left + (rect.width - tipRect.width) / 2;
8115
- left = Math.max(8, Math.min(left, window.innerWidth - tipRect.width - 8));
8116
- tip.style.top = `${top}px`;
8117
- tip.style.left = `${left}px`;
8118
- }
8119
- function hideDescribeTooltip() {
8120
- tooltipEl?.remove();
8121
- tooltipEl = null;
8122
- }
8123
- async function handleImageClick(img) {
8124
- const rect = img.getBoundingClientRect();
8125
- const cached = img.dataset.accessifyDescription;
8126
- if (cached) {
8127
- showDescribeTooltip(cached, rect);
8128
- return;
8129
- }
8130
- const existingAlt = img.getAttribute("alt");
8131
- showDescribeTooltip("", rect, true);
8132
- try {
8133
- if (!aiService) {
8134
- showDescribeTooltip(
8135
- existingAlt || (isDE() ? "Kein API-Key konfiguriert" : "No API key configured"),
8136
- rect
8137
- );
8138
- return;
8139
- }
8140
- const src = getImageSrc(img);
8141
- const description = await aiService.describeImage(src, lang());
8142
- if (!enabled) return;
8143
- img.dataset.accessifyDescription = description;
8144
- showDescribeTooltip(description, rect);
8145
- const currentAlt = img.getAttribute("alt");
8146
- if (!currentAlt || !currentAlt.trim()) {
8147
- try {
8148
- const ctx = gatherImageContext(img);
8149
- const altText2 = await aiService.generateAltText(src, ctx, lang());
8150
- if (altText2) {
8151
- img.setAttribute("alt", altText2);
8152
- img.setAttribute("title", altText2);
8153
- setCachedAltText(src, altText2, lang()).catch(() => {
8154
- });
8155
- if (siteKey) persistAltTextToServer(siteKey, proxyUrl, src, altText2, lang());
8156
- }
8157
- } catch {
8158
- }
8159
- }
8160
- } catch (err) {
8161
- console.warn("[Accessify] Image description failed:", err);
8162
- showDescribeTooltip(
8163
- existingAlt || (isDE() ? "Beschreibung konnte nicht geladen werden" : "Could not load description"),
8164
- rect
8165
- );
8166
- }
8167
- }
8168
- function isLinkedImage(img) {
8169
- return !!img.closest("a[href]");
8170
- }
8171
- function addDescribeButton(img) {
8172
- if (describeButtons.has(img)) return;
8173
- const parent = img.parentElement;
8174
- if (!parent) return;
8175
- const pos = getComputedStyle(parent).position;
8176
- if (pos === "static") parent.style.position = "relative";
8177
- const btn = document.createElement("button");
8178
- btn.className = "accessify-describe-btn";
8179
- btn.textContent = "i";
8180
- btn.setAttribute("aria-label", isDE() ? "Bildbeschreibung anzeigen" : "Show image description");
8181
- btn.addEventListener("click", (e) => {
8182
- e.preventDefault();
8183
- e.stopPropagation();
8184
- handleImageClick(img);
8185
- });
8186
- img.insertAdjacentElement("afterend", btn);
8187
- describeButtons.set(img, btn);
8188
- }
8189
- function removeDescribeButtons() {
8190
- describeButtons.forEach((btn) => btn.remove());
8191
- describeButtons.clear();
8192
- }
8193
- function markImageDescribable(img) {
8194
- if (img.closest("#accessify-root") || img.closest("accessify-widget")) return;
8195
- if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return;
8196
- img.dataset.a11yDescribable = "true";
8197
- if (isLinkedImage(img)) {
8198
- img.dataset.a11yIsLink = "true";
8199
- addDescribeButton(img);
8200
- }
8201
- }
8202
- function enableClickToDescribe() {
8203
- document.querySelectorAll("img").forEach(markImageDescribable);
8204
- describeClickHandler = (e) => {
8205
- if (e.target.closest(".accessify-describe-tooltip")) return;
8206
- if (e.target.closest(".accessify-describe-btn")) return;
8207
- const img = e.target.closest("img[data-a11y-describable]");
8208
- if (!img) {
8209
- if (tooltipEl) hideDescribeTooltip();
8210
- return;
8211
- }
8212
- if (isLinkedImage(img)) return;
8213
- e.preventDefault();
8214
- e.stopPropagation();
8215
- handleImageClick(img);
8216
- };
8217
- document.addEventListener("click", describeClickHandler, true);
8218
- describeEscHandler = (e) => {
8219
- if (e.key === "Escape") hideDescribeTooltip();
8220
- };
8221
- document.addEventListener("keydown", describeEscHandler);
8222
- }
8223
- function disableClickToDescribe() {
8224
- if (describeClickHandler) {
8225
- document.removeEventListener("click", describeClickHandler, true);
8226
- describeClickHandler = null;
8227
- }
8228
- if (describeEscHandler) {
8229
- document.removeEventListener("keydown", describeEscHandler);
8230
- describeEscHandler = null;
8231
- }
8232
- hideDescribeTooltip();
8233
- removeDescribeButtons();
8234
- document.querySelectorAll("img[data-a11y-describable]").forEach((img) => {
8235
- delete img.dataset.a11yDescribable;
8236
- delete img.dataset.a11yIsLink;
8237
- });
8238
- }
8239
7997
  function isGenericAlt(alt) {
8240
7998
  if (!alt.trim()) return true;
8241
7999
  if (/^(image|img|photo|bild|foto|untitled|placeholder)/i.test(alt)) return true;
@@ -8249,9 +8007,13 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8249
8007
  if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 50 || img.naturalHeight < 50)) return true;
8250
8008
  return false;
8251
8009
  }
8252
- function needsAltText(img) {
8010
+ function isValidImage(img) {
8253
8011
  if (img.closest("#accessify-root") || img.closest("accessify-widget")) return false;
8254
8012
  if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return false;
8013
+ return true;
8014
+ }
8015
+ function needsAltText(img) {
8016
+ if (!isValidImage(img)) return false;
8255
8017
  const alt = img.getAttribute("alt");
8256
8018
  if (alt === null) return true;
8257
8019
  if (isGenericAlt(alt)) return true;
@@ -8297,6 +8059,23 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8297
8059
  img.setAttribute("title", altText2);
8298
8060
  processedImages.set(img, { generatedAlt: altText2 });
8299
8061
  }
8062
+ function applyTitlesToAllImages() {
8063
+ document.querySelectorAll("img").forEach((img) => {
8064
+ if (!isValidImage(img)) return;
8065
+ if (img.getAttribute("title")) return;
8066
+ const alt = img.getAttribute("alt");
8067
+ if (alt && alt.trim()) {
8068
+ img.setAttribute("title", alt);
8069
+ img.setAttribute("data-accessify-title", "auto");
8070
+ }
8071
+ });
8072
+ }
8073
+ function removeTitles() {
8074
+ document.querySelectorAll('img[data-accessify-title="auto"]').forEach((img) => {
8075
+ img.removeAttribute("title");
8076
+ img.removeAttribute("data-accessify-title");
8077
+ });
8078
+ }
8300
8079
  async function generateAll() {
8301
8080
  if (autoGenerating || !enabled || !aiService) return;
8302
8081
  autoGenerating = true;
@@ -8344,7 +8123,6 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8344
8123
  const cached = await getCachedAltText(src);
8345
8124
  if (cached) {
8346
8125
  applyAltText(img, cached);
8347
- updateBadge();
8348
8126
  return;
8349
8127
  }
8350
8128
  try {
@@ -8362,15 +8140,20 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8362
8140
  }
8363
8141
  function tryRegisterImage(img) {
8364
8142
  if (!enabled) return;
8365
- if (img.closest("#accessify-root")) return;
8143
+ if (!isValidImage(img)) return;
8366
8144
  if (missingAltImages.includes(img)) return;
8367
8145
  function addIfValid() {
8368
8146
  if (!enabled || missingAltImages.includes(img)) return;
8369
8147
  if (img.naturalWidth < 20 || img.naturalHeight < 20) return;
8370
- markImageDescribable(img);
8371
8148
  if (needsAltText(img)) {
8372
8149
  missingAltImages.push(img);
8373
8150
  generateSingle(img);
8151
+ } else {
8152
+ const alt = img.getAttribute("alt");
8153
+ if (alt && alt.trim() && !img.getAttribute("title")) {
8154
+ img.setAttribute("title", alt);
8155
+ img.setAttribute("data-accessify-title", "auto");
8156
+ }
8374
8157
  }
8375
8158
  }
8376
8159
  if (img.complete && img.naturalWidth > 0) addIfValid();
@@ -8379,9 +8162,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8379
8162
  function activate() {
8380
8163
  if (enabled) return;
8381
8164
  enabled = true;
8382
- injectStyles();
8383
- const alreadyApplied = document.querySelectorAll('img[data-accessify-alt="auto"]');
8384
- alreadyApplied.forEach((img) => {
8165
+ document.querySelectorAll('img[data-accessify-alt="auto"]').forEach((img) => {
8385
8166
  if (img.closest("#accessify-root")) return;
8386
8167
  if (!processedImages.has(img)) {
8387
8168
  processedImages.set(img, { generatedAlt: img.getAttribute("alt") || "" });
@@ -8395,21 +8176,14 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8395
8176
  }
8396
8177
  }
8397
8178
  generateAll();
8398
- document.querySelectorAll("img").forEach((img) => {
8399
- if (img.closest("#accessify-root") || img.closest("accessify-widget")) return;
8400
- const alt = img.getAttribute("alt");
8401
- if (alt && alt.trim() && !img.getAttribute("title")) {
8402
- img.setAttribute("title", alt);
8403
- img.setAttribute("data-accessify-title", "auto");
8404
- }
8405
- });
8406
- enableClickToDescribe();
8179
+ applyTitlesToAllImages();
8407
8180
  document.querySelectorAll("img").forEach((img) => {
8408
8181
  if (!img.complete) tryRegisterImage(img);
8409
8182
  });
8410
8183
  setTimeout(() => {
8411
8184
  if (enabled) {
8412
8185
  document.querySelectorAll("img").forEach(tryRegisterImage);
8186
+ applyTitlesToAllImages();
8413
8187
  }
8414
8188
  }, 2e3);
8415
8189
  domObserver = new MutationObserver((mutations) => {
@@ -8418,11 +8192,6 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8418
8192
  if (node instanceof HTMLImageElement) tryRegisterImage(node);
8419
8193
  else if (node instanceof HTMLElement) {
8420
8194
  node.querySelectorAll("img").forEach(tryRegisterImage);
8421
- node.querySelectorAll("img").forEach((img) => {
8422
- if (!img.closest("#accessify-root") && !img.closest("accessify-widget")) {
8423
- img.dataset.a11yDescribable = "true";
8424
- }
8425
- });
8426
8195
  }
8427
8196
  }
8428
8197
  }
@@ -8434,13 +8203,8 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8434
8203
  autoGenerating = false;
8435
8204
  domObserver?.disconnect();
8436
8205
  domObserver = null;
8437
- disableClickToDescribe();
8438
- document.querySelectorAll('img[data-accessify-title="auto"]').forEach((img) => {
8439
- img.removeAttribute("title");
8440
- img.removeAttribute("data-accessify-title");
8441
- });
8206
+ removeTitles();
8442
8207
  missingAltImages = [];
8443
- removeStyles();
8444
8208
  }
8445
8209
  autoApplyCachedAltTexts({ siteKey, proxyUrl, lang: initialLang }).catch(() => {
8446
8210
  });
@@ -8653,4 +8417,4 @@ export {
8653
8417
  init as i,
8654
8418
  t
8655
8419
  };
8656
- //# sourceMappingURL=index-B8sAE1Po.js.map
8420
+ //# sourceMappingURL=index-DcqLuguC.js.map