ui: fix net-sim i18n — decode-entity key match + label coverage (v2.7.6)

The network-simulation description never switched to Russian: its
data-l10n attribute carries " (decoded to " by the browser), while the
LANG_RU key is raw text inside <script> and keeps the literal &quot;, so
translatePage()'s lookup missed and t() returned the English key.

- LANG_RU: the description key now carries real quotes, matching the
  decoded attribute value (RU value unchanged)
- add the missing RU entries for the net-sim labels AUTHENTICATE, MCC,
  MNC, LAC, Cell ID, TAC, RAC (acronyms map to themselves; Cell ID ->
  «Идентификатор соты»)
- html.test.js: strict cross-check that every data-l10n attribute
  (entity-decoded, as the browser does) is a LANG_RU key
- sw.js cache simple-v209; version trio 2.7.6
This commit is contained in:
2026-09-20 14:05:27 +03:00
parent 6131d34d28
commit a688c63919
5 changed files with 31 additions and 5 deletions
+19
View File
@@ -298,3 +298,22 @@ test('the network monitor labels its refresh timestamp and has no area line', ()
assert.match(html, /data-l10n="Last refresh">Last refresh<\/span>: <span id="netstate-read"><\/span>/);
assert.ok(!/id="netstate-area"/.test(html), 'the area line is gone; LAI/RAI/TAI live in the EF rows');
});
test('every data-l10n attribute resolves in LANG_RU after HTML decoding', () => {
// translatePage() looks up el.getAttribute('data-l10n') — the browser
// decodes entities in attribute values, but NOT inside the <script>
// block where LANG_RU lives. Mirror that lookup exactly: a key written
// as &quot; in the markup and &quot; in the dict never matches.
const dictMatch = html.match(/const LANG_RU = \{([\s\S]*?)\n\};/);
assert.ok(dictMatch, 'LANG_RU literal not found');
const dict = eval('({' + dictMatch[1] + '})');
const entities = {
quot: '"', '#34': '"', amp: '&', '#38': '&', apos: "'", '#39': "'",
lt: '<', '#60': '<', gt: '>', '#62': '>', nbsp: ' ',
};
const decode = s => s.replace(/&([a-z]+|#[0-9]+);/gi,
(m, e) => entities[e] !== undefined ? entities[e] : m);
const attrs = [...html.matchAll(/data-l10n="([^"]*)"/g)].map(m => decode(m[1]));
const missing = [...new Set(attrs.filter(k => !(k in dict)))];
assert.deepStrictEqual(missing, [], 'data-l10n keys with no LANG_RU entry:\n' + missing.join('\n'));
});