langsys-js-typescript 0.6.2 → 0.6.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.
- package/CHANGELOG.md +48 -0
- package/dist/index.d.mts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +95 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -287,14 +287,76 @@ function warnUnmatchedParams(source, texts, params, context) {
|
|
|
287
287
|
}
|
|
288
288
|
function interpolate(template, params, locale) {
|
|
289
289
|
if (isICU(template)) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
290
|
+
const resolved = locale || "en";
|
|
291
|
+
const hasNullParam = !!params && Object.values(params).some((value) => value === null);
|
|
292
|
+
if (!hasNullParam) {
|
|
293
|
+
try {
|
|
294
|
+
return new IntlMessageFormat(template, resolved).format(params);
|
|
295
|
+
} catch {
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
{
|
|
299
|
+
try {
|
|
300
|
+
const ast = new IntlMessageFormat(template, resolved).ast;
|
|
301
|
+
if (!Array.isArray(ast)) return simpleInterpolate(template, params, locale);
|
|
302
|
+
const recovered = _recoverMissingArgs(JSON.parse(JSON.stringify(ast)), params);
|
|
303
|
+
return new IntlMessageFormat(recovered, resolved).format(params);
|
|
304
|
+
} catch {
|
|
305
|
+
return simpleInterpolate(template, params, locale);
|
|
306
|
+
}
|
|
294
307
|
}
|
|
295
308
|
}
|
|
296
309
|
return simpleInterpolate(template, params, locale);
|
|
297
310
|
}
|
|
311
|
+
var ICU_LITERAL = 0;
|
|
312
|
+
var ICU_ARGUMENT = 1;
|
|
313
|
+
var ICU_NUMBER = 2;
|
|
314
|
+
var ICU_DATE = 3;
|
|
315
|
+
var ICU_TIME = 4;
|
|
316
|
+
var ICU_SELECT = 5;
|
|
317
|
+
var ICU_PLURAL = 6;
|
|
318
|
+
var ICU_POUND = 7;
|
|
319
|
+
var ICU_TAG = 8;
|
|
320
|
+
function _recoverMissingArgs(nodes, params) {
|
|
321
|
+
const out = [];
|
|
322
|
+
for (const node of nodes) {
|
|
323
|
+
const name = node.value;
|
|
324
|
+
const value = name !== void 0 && name in params ? params[name] : void 0;
|
|
325
|
+
const supplied = value !== void 0 && value !== null;
|
|
326
|
+
if (node.type === ICU_TAG) {
|
|
327
|
+
out.push({ ...node, children: _recoverMissingArgs(node.children ?? [], params) });
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (node.type === ICU_SELECT || node.type === ICU_PLURAL) {
|
|
331
|
+
if (supplied) {
|
|
332
|
+
const options = {};
|
|
333
|
+
for (const [key, branch2] of Object.entries(node.options ?? {})) {
|
|
334
|
+
options[key] = { value: _recoverMissingArgs(branch2.value, params) };
|
|
335
|
+
}
|
|
336
|
+
out.push({ ...node, options });
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
const other = node.options?.other;
|
|
340
|
+
if (!other) {
|
|
341
|
+
out.push(node);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
const branch = _recoverMissingArgs(other.value, params);
|
|
345
|
+
out.push(
|
|
346
|
+
...branch.map(
|
|
347
|
+
(child) => child.type === ICU_POUND ? { type: ICU_LITERAL, value: `{${name}}` } : child
|
|
348
|
+
)
|
|
349
|
+
);
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
if (!supplied && (node.type === ICU_ARGUMENT || node.type === ICU_NUMBER || node.type === ICU_DATE || node.type === ICU_TIME)) {
|
|
353
|
+
out.push({ type: ICU_LITERAL, value: `{${name}}` });
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
out.push(node);
|
|
357
|
+
}
|
|
358
|
+
return out;
|
|
359
|
+
}
|
|
298
360
|
function simpleInterpolate(template, params, locale) {
|
|
299
361
|
return template.replace(/\{([^{},]+)\}/g, (match, rawKey) => {
|
|
300
362
|
const key = rawKey.trim();
|
|
@@ -1074,8 +1136,14 @@ var TRANSLATABLE_ATTRIBUTES = [
|
|
|
1074
1136
|
"placeholder",
|
|
1075
1137
|
"alt",
|
|
1076
1138
|
"title",
|
|
1139
|
+
"label",
|
|
1140
|
+
// <option>, <optgroup>, <track> — the text a user reads in the picker
|
|
1077
1141
|
"aria-label",
|
|
1078
1142
|
"aria-placeholder",
|
|
1143
|
+
"aria-description",
|
|
1144
|
+
"aria-valuetext",
|
|
1145
|
+
// the spoken value of a slider/meter
|
|
1146
|
+
"aria-roledescription",
|
|
1079
1147
|
"data-error",
|
|
1080
1148
|
"data-error-message",
|
|
1081
1149
|
"data-validation-message",
|
|
@@ -1192,9 +1260,15 @@ async function registerContentBlock(contentBlock) {
|
|
|
1192
1260
|
function tokenizeElement(element) {
|
|
1193
1261
|
const tokens = [];
|
|
1194
1262
|
const clone = element.cloneNode(true);
|
|
1195
|
-
_walkForTokens(element, Array.from(clone.childNodes), tokens, []);
|
|
1263
|
+
_walkForTokens(element, Array.from(clone.childNodes), tokens, [], false, true);
|
|
1196
1264
|
return { tokens, content: normalizeMarkupPlaceholders(clone.outerHTML) };
|
|
1197
1265
|
}
|
|
1266
|
+
function legacyTokenizeElement(element) {
|
|
1267
|
+
const tokens = [];
|
|
1268
|
+
const clone = element.cloneNode(true);
|
|
1269
|
+
_walkForTokens(element, Array.from(clone.childNodes), tokens, [], true, false);
|
|
1270
|
+
return tokens;
|
|
1271
|
+
}
|
|
1198
1272
|
function _writeKnownContentBlockToCache(category, customId) {
|
|
1199
1273
|
const lookupCat = category || "__uncategorized__";
|
|
1200
1274
|
sTranslations.update((current) => {
|
|
@@ -1208,18 +1282,18 @@ function _writeKnownContentBlockToCache(category, customId) {
|
|
|
1208
1282
|
return { ...current };
|
|
1209
1283
|
});
|
|
1210
1284
|
}
|
|
1211
|
-
function _walkForTokens(liveRoot, cloneNodes, tokens, indices) {
|
|
1285
|
+
function _walkForTokens(liveRoot, cloneNodes, tokens, indices, duplicateSelectOptions, applyStyles) {
|
|
1212
1286
|
cloneNodes.forEach((node, index) => {
|
|
1213
1287
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
1214
1288
|
const el = node;
|
|
1215
1289
|
if (isTranslationExcluded(el)) return;
|
|
1216
1290
|
if (isPhraseMarked(el)) return;
|
|
1217
1291
|
}
|
|
1218
|
-
if (node.hasChildNodes()) {
|
|
1292
|
+
if (applyStyles && node.hasChildNodes()) {
|
|
1219
1293
|
_applyStylesToClone(liveRoot, node, [...indices, index]);
|
|
1220
1294
|
}
|
|
1221
1295
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
1222
|
-
_tokenizeAttributes(node, tokens);
|
|
1296
|
+
_tokenizeAttributes(node, tokens, duplicateSelectOptions);
|
|
1223
1297
|
}
|
|
1224
1298
|
const contentToken = node.nodeValue?.replace(/\s+/g, " ").trim();
|
|
1225
1299
|
if (node.nodeType === Node.TEXT_NODE && contentToken) {
|
|
@@ -1227,10 +1301,10 @@ function _walkForTokens(liveRoot, cloneNodes, tokens, indices) {
|
|
|
1227
1301
|
return;
|
|
1228
1302
|
}
|
|
1229
1303
|
if (!node.hasChildNodes()) return;
|
|
1230
|
-
_walkForTokens(liveRoot, Array.from(node.childNodes), tokens, [...indices, index]);
|
|
1304
|
+
_walkForTokens(liveRoot, Array.from(node.childNodes), tokens, [...indices, index], duplicateSelectOptions, applyStyles);
|
|
1231
1305
|
});
|
|
1232
1306
|
}
|
|
1233
|
-
function _tokenizeAttributes(element, tokens) {
|
|
1307
|
+
function _tokenizeAttributes(element, tokens, duplicateSelectOptions) {
|
|
1234
1308
|
const tagName = element.tagName.toLowerCase();
|
|
1235
1309
|
if (tagName === "img") {
|
|
1236
1310
|
const img = element;
|
|
@@ -1251,7 +1325,7 @@ function _tokenizeAttributes(element, tokens) {
|
|
|
1251
1325
|
if (value) tokens.push(normalizeMarkupPlaceholders(value));
|
|
1252
1326
|
}
|
|
1253
1327
|
}
|
|
1254
|
-
if (tagName === "select") {
|
|
1328
|
+
if (duplicateSelectOptions && tagName === "select") {
|
|
1255
1329
|
const options = element.querySelectorAll("option");
|
|
1256
1330
|
options.forEach((option) => {
|
|
1257
1331
|
const optionText = option.textContent?.trim();
|
|
@@ -1377,9 +1451,15 @@ var Translate = class {
|
|
|
1377
1451
|
return;
|
|
1378
1452
|
}
|
|
1379
1453
|
if (derivedId) {
|
|
1380
|
-
const
|
|
1381
|
-
|
|
1382
|
-
|
|
1454
|
+
const legacyTokens = legacyTokenizeElement(this.element);
|
|
1455
|
+
const candidates = [
|
|
1456
|
+
generateCustomId(contentBlock.category, legacyTokens),
|
|
1457
|
+
generateLegacyCustomId(contentBlock.category, legacyTokens)
|
|
1458
|
+
];
|
|
1459
|
+
for (const candidate of candidates) {
|
|
1460
|
+
if (candidate === this.custom_id) continue;
|
|
1461
|
+
if (!isContentBlockKnown(contentBlock.category, candidate)) continue;
|
|
1462
|
+
this.custom_id = candidate;
|
|
1383
1463
|
if (this.tokens.length > 1 && this.element) {
|
|
1384
1464
|
this.translate(Array.from(this.element.childNodes));
|
|
1385
1465
|
this.lastTranslatedLocale = currentlyLoadedLocale.get();
|
|
@@ -1643,6 +1723,6 @@ var t = ((phrase, ...rest) => {
|
|
|
1643
1723
|
});
|
|
1644
1724
|
var tSignal = LangsysApp.Translations.tSignal;
|
|
1645
1725
|
|
|
1646
|
-
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, logger, markupTokenValues, md5, md5Legacy, normalizeMarkupPlaceholders, persist, reconstitute, registerContentBlock, sTranslations, stripSentinels, t, tSignal, tokenizeElement };
|
|
1726
|
+
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 };
|
|
1647
1727
|
//# sourceMappingURL=index.mjs.map
|
|
1648
1728
|
//# sourceMappingURL=index.mjs.map
|