accessify-widget 0.2.18 → 0.2.20

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-DvpENReS.js";
1
+ import { d, i } from "./index-DwxnT3JK.js";
2
2
  export {
3
3
  d as destroy,
4
4
  i as init
@@ -1673,7 +1673,7 @@ function derived(fn) {
1673
1673
  return signal;
1674
1674
  }
1675
1675
  // @__NO_SIDE_EFFECTS__
1676
- function async_derived(fn, label, location) {
1676
+ function async_derived(fn, label, location2) {
1677
1677
  let parent = (
1678
1678
  /** @type {Effect | null} */
1679
1679
  active_effect
@@ -6310,14 +6310,14 @@ function FeatureGrid($$anchor, $$props) {
6310
6310
  const FEATURE_LOADERS = {
6311
6311
  contrast: () => import("./contrast-CqsICAkU.js"),
6312
6312
  "text-size": () => import("./text-size-C6OFhCGi.js"),
6313
- "keyboard-nav": () => import("./keyboard-nav-BLkj3Uzc.js"),
6313
+ "keyboard-nav": () => import("./keyboard-nav-BtZsDcZQ.js"),
6314
6314
  "link-highlight": () => import("./link-highlight-DBGm067Y.js"),
6315
6315
  "reading-guide": () => import("./reading-guide-VT8NciIL.js"),
6316
6316
  "reading-mask": () => import("./reading-mask-BABChuCz.js"),
6317
6317
  "animation-stop": () => import("./animation-stop-C0MwseK0.js"),
6318
6318
  "hide-images": () => import("./hide-images-B_LeCBcd.js"),
6319
6319
  "big-cursor": () => import("./big-cursor-B2UKu9dQ.js"),
6320
- "page-structure": () => import("./page-structure-D88y-Y7V.js"),
6320
+ "page-structure": () => import("./page-structure-DTKpsB5y.js"),
6321
6321
  tts: () => import("./tts-CjszLRnb.js"),
6322
6322
  "text-simplify": () => import("./text-simplify-Cvhpio7g.js"),
6323
6323
  "alt-text": () => Promise.resolve().then(() => altText)
@@ -6630,6 +6630,8 @@ let currentTranslateLang = null;
6630
6630
  let translating = false;
6631
6631
  let observer = null;
6632
6632
  let observerPaused = false;
6633
+ let navigationHandler = null;
6634
+ let lastUrl = "";
6633
6635
  const TRANSLATABLE_ATTRS = [
6634
6636
  "aria-label",
6635
6637
  "aria-description",
@@ -6773,10 +6775,23 @@ async function translatePage(targetLang) {
6773
6775
  }
6774
6776
  function setupObserver(targetLang) {
6775
6777
  if (observer) observer.disconnect();
6778
+ lastUrl = location.href;
6776
6779
  const debouncedTranslate = debounce(() => {
6777
6780
  if (!currentTranslateLang || observerPaused) return;
6778
6781
  translatePage(currentTranslateLang);
6779
6782
  }, 300);
6783
+ const onNavigation = () => {
6784
+ if (!currentTranslateLang || observerPaused) return;
6785
+ const newUrl = location.href;
6786
+ if (newUrl !== lastUrl) {
6787
+ lastUrl = newUrl;
6788
+ savedTextNodes = [];
6789
+ savedAttrs = [];
6790
+ setTimeout(() => {
6791
+ if (currentTranslateLang) translatePage(currentTranslateLang);
6792
+ }, 500);
6793
+ }
6794
+ };
6780
6795
  observer = new MutationObserver((mutations) => {
6781
6796
  if (observerPaused || !currentTranslateLang) return;
6782
6797
  let hasRelevantChange = false;
@@ -6790,17 +6805,36 @@ function setupObserver(targetLang) {
6790
6805
  break;
6791
6806
  }
6792
6807
  }
6793
- if (hasRelevantChange) debouncedTranslate();
6808
+ if (hasRelevantChange) {
6809
+ onNavigation();
6810
+ debouncedTranslate();
6811
+ }
6794
6812
  });
6795
6813
  observer.observe(document.body, {
6796
6814
  childList: true,
6797
6815
  subtree: true,
6798
6816
  characterData: true
6799
6817
  });
6818
+ navigationHandler = onNavigation;
6819
+ window.addEventListener("popstate", navigationHandler);
6820
+ const origPush = history.pushState;
6821
+ const origReplace = history.replaceState;
6822
+ history.pushState = function(...args) {
6823
+ origPush.apply(this, args);
6824
+ onNavigation();
6825
+ };
6826
+ history.replaceState = function(...args) {
6827
+ origReplace.apply(this, args);
6828
+ onNavigation();
6829
+ };
6800
6830
  }
6801
6831
  function teardownObserver() {
6802
6832
  observer?.disconnect();
6803
6833
  observer = null;
6834
+ if (navigationHandler) {
6835
+ window.removeEventListener("popstate", navigationHandler);
6836
+ navigationHandler = null;
6837
+ }
6804
6838
  }
6805
6839
  function getElId(el) {
6806
6840
  return el.id || el.getAttribute("data-a11y-id") || (el.setAttribute("data-a11y-id", Math.random().toString(36).substr(2, 9)), el.getAttribute("data-a11y-id"));
@@ -7787,6 +7821,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
7787
7821
  let styleEl = null;
7788
7822
  let badgeEl = null;
7789
7823
  let missingAltImages = [];
7824
+ let existingAltImages = [];
7790
7825
  const processedImages = /* @__PURE__ */ new Map();
7791
7826
  let autoGenerating = false;
7792
7827
  let tooltipEl = null;
@@ -7800,6 +7835,7 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
7800
7835
  }
7801
7836
  const STYLE_ID = "accessify-alt-text-styles";
7802
7837
  const HIGHLIGHT_CLASS = "accessify-alt-missing";
7838
+ const HAS_ALT_CLASS = "accessify-alt-existing";
7803
7839
  const BADGE_CLASS = "accessify-alt-badge";
7804
7840
  function getStyles() {
7805
7841
  return `
@@ -7833,6 +7869,12 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
7833
7869
  content: none;
7834
7870
  }
7835
7871
 
7872
+ .${HAS_ALT_CLASS} {
7873
+ outline: 3px solid #2a9d8f !important;
7874
+ outline-offset: 3px !important;
7875
+ position: relative !important;
7876
+ }
7877
+
7836
7878
  .accessify-alt-tooltip {
7837
7879
  position: fixed;
7838
7880
  z-index: 2147483647;
@@ -8071,7 +8113,13 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8071
8113
  if (img.closest("#accessify-root") || img.closest("accessify-widget")) return;
8072
8114
  if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return;
8073
8115
  const alt = img.getAttribute("alt");
8074
- if (alt === "") return;
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
+ }
8075
8123
  if (alt === null || isGenericAlt(alt)) missing.push(img);
8076
8124
  });
8077
8125
  document.querySelectorAll("picture").forEach((picture) => {
@@ -8098,6 +8146,20 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8098
8146
  });
8099
8147
  return missing;
8100
8148
  }
8149
+ function scanWithExistingAlt(excludeMissing) {
8150
+ const existing = [];
8151
+ const missingSet = new Set(excludeMissing);
8152
+ document.querySelectorAll("img").forEach((img) => {
8153
+ if (img.closest("#accessify-root") || img.closest("accessify-widget")) return;
8154
+ if (missingSet.has(img)) return;
8155
+ if (img.complete && img.naturalWidth > 0 && (img.naturalWidth < 20 || img.naturalHeight < 20)) return;
8156
+ const alt = img.getAttribute("alt");
8157
+ if (alt && alt.trim() && !isGenericAlt(alt)) {
8158
+ existing.push(img);
8159
+ }
8160
+ });
8161
+ return existing;
8162
+ }
8101
8163
  function scanAutoApplied() {
8102
8164
  const images = document.querySelectorAll('img[data-accessify-alt="auto"]');
8103
8165
  const applied = [];
@@ -8192,16 +8254,28 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8192
8254
  removeBadge();
8193
8255
  const remaining = missingAltImages.filter((img) => !processedImages.has(img)).length;
8194
8256
  const generating = missingAltImages.filter((img) => img.classList.contains("accessify-alt-generating")).length;
8195
- if (remaining === 0 && missingAltImages.length > 0) {
8196
- showBadge(isDE() ? `✓ ${missingAltImages.length} Alt-Texte gesetzt` : `✓ ${missingAltImages.length} alt texts applied`, "#2a9d8f", 0);
8197
- setTimeout(() => removeBadge(), 5e3);
8198
- return;
8199
- }
8200
- if (remaining === 0) return;
8257
+ const generated = processedImages.size;
8258
+ const withExisting = existingAltImages.length;
8259
+ const totalImages = missingAltImages.length + withExisting;
8201
8260
  if (generating > 0) {
8202
8261
  showBadge(isDE() ? `${generating} Bilder werden analysiert…` : `Analyzing ${generating} images…`, "#f77f00", generating);
8203
- } else {
8204
- showBadge(isDE() ? `${remaining} Bilder ohne Alt-Text` : `${remaining} images missing alt text`, "#e63946", remaining);
8262
+ return;
8263
+ }
8264
+ if (remaining === 0 && totalImages > 0) {
8265
+ const parts = [];
8266
+ if (withExisting > 0) parts.push(isDE() ? `${withExisting} ✓` : `${withExisting} ✓`);
8267
+ if (generated > 0) parts.push(isDE() ? `${generated} erzeugt` : `${generated} generated`);
8268
+ const summary = `${totalImages} ${isDE() ? "Bilder" : "images"}: ${parts.join(", ")}`;
8269
+ showBadge(summary, "#2a9d8f", 0);
8270
+ setTimeout(() => removeBadge(), 8e3);
8271
+ return;
8272
+ }
8273
+ if (remaining > 0) {
8274
+ const statusParts = [];
8275
+ if (withExisting > 0) statusParts.push(`${withExisting} ✓`);
8276
+ statusParts.push(isDE() ? `${remaining} ohne Alt-Text` : `${remaining} missing`);
8277
+ const text = `${totalImages} ${isDE() ? "Bilder" : "images"}: ${statusParts.join(", ")}`;
8278
+ showBadge(text, "#e63946", remaining);
8205
8279
  }
8206
8280
  }
8207
8281
  function showBadge(text, color, count) {
@@ -8255,21 +8329,36 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8255
8329
  function tryRegisterImage(img) {
8256
8330
  if (!enabled) return;
8257
8331
  if (img.closest("#accessify-root")) return;
8258
- if (missingAltImages.includes(img)) return;
8259
- const alt = img.getAttribute("alt");
8260
- if (alt !== null && alt.trim() !== "") return;
8332
+ if (missingAltImages.includes(img) || existingAltImages.includes(img)) return;
8261
8333
  function addIfValid() {
8262
- if (!enabled || missingAltImages.includes(img)) return;
8263
- if (img.naturalWidth >= 20 && img.naturalHeight >= 20) {
8334
+ if (!enabled || missingAltImages.includes(img) || existingAltImages.includes(img)) return;
8335
+ if (img.naturalWidth < 20 || img.naturalHeight < 20) return;
8336
+ const alt = img.getAttribute("alt");
8337
+ const isMissing = alt === null || isGenericAlt(alt) || alt === "" && !isDecorativeImage(img);
8338
+ if (isMissing) {
8264
8339
  img.classList.add(HIGHLIGHT_CLASS);
8265
8340
  missingAltImages.push(img);
8266
8341
  updateBadge();
8267
8342
  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();
8268
8351
  }
8269
8352
  }
8270
8353
  if (img.complete && img.naturalWidth > 0) addIfValid();
8271
8354
  else img.addEventListener("load", addIfValid, { once: true });
8272
8355
  }
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
+ }
8273
8362
  function activate() {
8274
8363
  if (enabled) return;
8275
8364
  enabled = true;
@@ -8291,6 +8380,15 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8291
8380
  missingAltImages.push(img);
8292
8381
  img.classList.add(HIGHLIGHT_CLASS);
8293
8382
  }
8383
+ const withAlt = scanWithExistingAlt(missingAltImages);
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);
8391
+ }
8294
8392
  updateBadge();
8295
8393
  generateAll();
8296
8394
  document.querySelectorAll("img").forEach((img) => {
@@ -8322,6 +8420,10 @@ function createAltTextModule(aiService, initialLang = "de", serverConfig) {
8322
8420
  img.classList.remove(HIGHLIGHT_CLASS, "accessify-alt-done", "accessify-alt-generating");
8323
8421
  });
8324
8422
  missingAltImages = [];
8423
+ existingAltImages.forEach((img) => {
8424
+ img.classList.remove(HAS_ALT_CLASS);
8425
+ });
8426
+ existingAltImages = [];
8325
8427
  removeStyles();
8326
8428
  }
8327
8429
  autoApplyCachedAltTexts({ siteKey, proxyUrl, lang: initialLang }).catch(() => {
@@ -8535,4 +8637,4 @@ export {
8535
8637
  init as i,
8536
8638
  t
8537
8639
  };
8538
- //# sourceMappingURL=index-DvpENReS.js.map
8640
+ //# sourceMappingURL=index-DwxnT3JK.js.map