langsys-js-typescript 0.6.1 → 0.6.3

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/index.mjs CHANGED
@@ -1074,8 +1074,14 @@ var TRANSLATABLE_ATTRIBUTES = [
1074
1074
  "placeholder",
1075
1075
  "alt",
1076
1076
  "title",
1077
+ "label",
1078
+ // <option>, <optgroup>, <track> — the text a user reads in the picker
1077
1079
  "aria-label",
1078
1080
  "aria-placeholder",
1081
+ "aria-description",
1082
+ "aria-valuetext",
1083
+ // the spoken value of a slider/meter
1084
+ "aria-roledescription",
1079
1085
  "data-error",
1080
1086
  "data-error-message",
1081
1087
  "data-validation-message",
@@ -1084,10 +1090,16 @@ var TRANSLATABLE_ATTRIBUTES = [
1084
1090
  "data-pattern-message"
1085
1091
  ];
1086
1092
  var PHRASE_MARKER_ATTRS = ["data-ls-phrase", "data-langsys-phrase"];
1093
+ function isTranslationExcluded(element) {
1094
+ if ((element.getAttribute("translate") ?? "").toLowerCase() === "no") return true;
1095
+ if (!element.hasAttribute("data-notrans")) return false;
1096
+ const value = (element.getAttribute("data-notrans") ?? "").trim().toLowerCase();
1097
+ return value !== "false" && value !== "0";
1098
+ }
1087
1099
  function isPhraseMarked(element) {
1088
1100
  return PHRASE_MARKER_ATTRS.some((attr) => {
1089
1101
  if (!element.hasAttribute(attr)) return false;
1090
- const value = (element.getAttribute(attr) ?? "").toLowerCase();
1102
+ const value = (element.getAttribute(attr) ?? "").trim().toLowerCase();
1091
1103
  return value !== "false" && value !== "0";
1092
1104
  });
1093
1105
  }
@@ -1186,9 +1198,15 @@ async function registerContentBlock(contentBlock) {
1186
1198
  function tokenizeElement(element) {
1187
1199
  const tokens = [];
1188
1200
  const clone = element.cloneNode(true);
1189
- _walkForTokens(element, Array.from(clone.childNodes), tokens, []);
1201
+ _walkForTokens(element, Array.from(clone.childNodes), tokens, [], false, true);
1190
1202
  return { tokens, content: normalizeMarkupPlaceholders(clone.outerHTML) };
1191
1203
  }
1204
+ function legacyTokenizeElement(element) {
1205
+ const tokens = [];
1206
+ const clone = element.cloneNode(true);
1207
+ _walkForTokens(element, Array.from(clone.childNodes), tokens, [], true, false);
1208
+ return tokens;
1209
+ }
1192
1210
  function _writeKnownContentBlockToCache(category, customId) {
1193
1211
  const lookupCat = category || "__uncategorized__";
1194
1212
  sTranslations.update((current) => {
@@ -1202,18 +1220,18 @@ function _writeKnownContentBlockToCache(category, customId) {
1202
1220
  return { ...current };
1203
1221
  });
1204
1222
  }
1205
- function _walkForTokens(liveRoot, cloneNodes, tokens, indices) {
1223
+ function _walkForTokens(liveRoot, cloneNodes, tokens, indices, duplicateSelectOptions, applyStyles) {
1206
1224
  cloneNodes.forEach((node, index) => {
1207
1225
  if (node.nodeType === Node.ELEMENT_NODE) {
1208
1226
  const el = node;
1209
- if (el.getAttribute("translate") === "no") return;
1227
+ if (isTranslationExcluded(el)) return;
1210
1228
  if (isPhraseMarked(el)) return;
1211
1229
  }
1212
- if (node.hasChildNodes()) {
1230
+ if (applyStyles && node.hasChildNodes()) {
1213
1231
  _applyStylesToClone(liveRoot, node, [...indices, index]);
1214
1232
  }
1215
1233
  if (node.nodeType === Node.ELEMENT_NODE) {
1216
- _tokenizeAttributes(node, tokens);
1234
+ _tokenizeAttributes(node, tokens, duplicateSelectOptions);
1217
1235
  }
1218
1236
  const contentToken = node.nodeValue?.replace(/\s+/g, " ").trim();
1219
1237
  if (node.nodeType === Node.TEXT_NODE && contentToken) {
@@ -1221,10 +1239,10 @@ function _walkForTokens(liveRoot, cloneNodes, tokens, indices) {
1221
1239
  return;
1222
1240
  }
1223
1241
  if (!node.hasChildNodes()) return;
1224
- _walkForTokens(liveRoot, Array.from(node.childNodes), tokens, [...indices, index]);
1242
+ _walkForTokens(liveRoot, Array.from(node.childNodes), tokens, [...indices, index], duplicateSelectOptions, applyStyles);
1225
1243
  });
1226
1244
  }
1227
- function _tokenizeAttributes(element, tokens) {
1245
+ function _tokenizeAttributes(element, tokens, duplicateSelectOptions) {
1228
1246
  const tagName = element.tagName.toLowerCase();
1229
1247
  if (tagName === "img") {
1230
1248
  const img = element;
@@ -1245,7 +1263,7 @@ function _tokenizeAttributes(element, tokens) {
1245
1263
  if (value) tokens.push(normalizeMarkupPlaceholders(value));
1246
1264
  }
1247
1265
  }
1248
- if (tagName === "select") {
1266
+ if (duplicateSelectOptions && tagName === "select") {
1249
1267
  const options = element.querySelectorAll("option");
1250
1268
  options.forEach((option) => {
1251
1269
  const optionText = option.textContent?.trim();
@@ -1371,9 +1389,15 @@ var Translate = class {
1371
1389
  return;
1372
1390
  }
1373
1391
  if (derivedId) {
1374
- const legacyId = generateLegacyCustomId(contentBlock.category, contentBlock.tokens);
1375
- if (legacyId !== this.custom_id && isContentBlockKnown(contentBlock.category, legacyId)) {
1376
- this.custom_id = legacyId;
1392
+ const legacyTokens = legacyTokenizeElement(this.element);
1393
+ const candidates = [
1394
+ generateCustomId(contentBlock.category, legacyTokens),
1395
+ generateLegacyCustomId(contentBlock.category, legacyTokens)
1396
+ ];
1397
+ for (const candidate of candidates) {
1398
+ if (candidate === this.custom_id) continue;
1399
+ if (!isContentBlockKnown(contentBlock.category, candidate)) continue;
1400
+ this.custom_id = candidate;
1377
1401
  if (this.tokens.length > 1 && this.element) {
1378
1402
  this.translate(Array.from(this.element.childNodes));
1379
1403
  this.lastTranslatedLocale = currentlyLoadedLocale.get();
@@ -1395,7 +1419,7 @@ var Translate = class {
1395
1419
  nodes.forEach((node) => {
1396
1420
  if (node?.nodeType === Node.ELEMENT_NODE) {
1397
1421
  const element = node;
1398
- if (element.getAttribute("translate") === "no") return;
1422
+ if (isTranslationExcluded(element)) return;
1399
1423
  if (isPhraseMarked(element)) return;
1400
1424
  this.translateAttributes(node);
1401
1425
  }
@@ -1637,6 +1661,6 @@ var t = ((phrase, ...rest) => {
1637
1661
  });
1638
1662
  var tSignal = LangsysApp.Translations.tSignal;
1639
1663
 
1640
- export { LangsysApp, LangsysAppAPI, Logger, PHRASE_MARKER_ATTR, PHRASE_MARKER_ATTRS, Phrase, Translate, Translations, canonicalizeLocale, createSignal, currentlyLoadedLocale, encodeRichText, findUnusedParamKeys, generateCustomId, generateLegacyCustomId, getValue, interpolate, isContentBlockKnown, isEmpty, isICU, isPhraseMarked, logger, markupTokenValues, md5, md5Legacy, normalizeMarkupPlaceholders, persist, reconstitute, registerContentBlock, sTranslations, stripSentinels, t, tSignal, tokenizeElement };
1664
+ export { LangsysApp, LangsysAppAPI, Logger, PHRASE_MARKER_ATTR, PHRASE_MARKER_ATTRS, Phrase, Translate, Translations, canonicalizeLocale, createSignal, currentlyLoadedLocale, encodeRichText, findUnusedParamKeys, generateCustomId, generateLegacyCustomId, getValue, interpolate, isContentBlockKnown, isEmpty, isICU, isPhraseMarked, isTranslationExcluded, legacyTokenizeElement, logger, markupTokenValues, md5, md5Legacy, normalizeMarkupPlaceholders, persist, reconstitute, registerContentBlock, sTranslations, stripSentinels, t, tSignal, tokenizeElement };
1641
1665
  //# sourceMappingURL=index.mjs.map
1642
1666
  //# sourceMappingURL=index.mjs.map