UNPKG

@phensley/cldr-core

Version:
256 lines 9.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var languagetag_1 = require("./languagetag"); var parser_1 = require("./parser"); var util_1 = require("./util"); var string_1 = require("../utils/string"); var autogen_aliases_1 = require("./autogen.aliases"); var subtags = require("./autogen.subtags"); /** * Put a nested map into the given map. */ var putMap = function (map, key) { var val = map[key]; if (val === undefined) { val = []; map[key] = val; } return val; }; /** * Since a lot of comparisons will be done, we need fast access to * core fields of LanguageTag without exposing the raw fields. */ var fastTag = function (real) { // Hack to get fast access to internal core fields without exposing them. var fake = real; // The fast tag is used for indexing purposes. Since a field may be // undefined, and we don't want to use its string representation of // the undefined value (e.g. 'und', 'Zzzz', etc), we use the field's // index number to represent undefined. var language = fake.core[0 /* LANGUAGE */]; var script = fake.core[1 /* SCRIPT */]; var region = fake.core[2 /* REGION */]; return [ language || 0 /* LANGUAGE */, script || 1 /* SCRIPT */, region || 2 /* REGION */ ]; }; var parseFastTag = function (raw) { return fastTag(parser_1.parseLanguageTag(raw)); }; /** * Index holding likely subtags matches. */ var LikelySubtagsMap = /** @class */ (function () { function LikelySubtagsMap(likely) { var _this = this; // Hack to be able to index using numbers and strings. this.index = []; Object.keys(likely).forEach(function (k) { var key = parseFastTag(k); var val = parseFastTag(likely[k]); // Add the fast tag into the index. var map = putMap(putMap(_this.index, key[0 /* LANGUAGE */]), key[1 /* SCRIPT */]); map[key[2 /* REGION */]] = val; }); } /** * Lookup the FastTag in the index. */ LikelySubtagsMap.prototype.get = function (query) { var language = query[0 /* LANGUAGE */]; var node1 = this.index[language]; if (node1 !== undefined) { var script = query[1 /* SCRIPT */]; var node2 = node1[script]; if (node2 !== undefined) { var region = query[2 /* REGION */]; return node2[region] || undefined; } } return undefined; }; return LikelySubtagsMap; }()); // Flags for subtag permutations var F_LANGUAGE = 1; var F_SCRIPT = 2; var F_REGION = 4; var MATCH_ORDER = [ F_LANGUAGE | F_SCRIPT | F_REGION, F_LANGUAGE | F_REGION, F_LANGUAGE | F_SCRIPT, F_LANGUAGE, F_SCRIPT ]; /** * Clear or copy fields from src to dst depending on flags. */ var setFields = function (src, dst, flags) { dst[0 /* LANGUAGE */] = (flags & F_LANGUAGE) === 0 ? 0 /* LANGUAGE */ : src[0 /* LANGUAGE */]; dst[1 /* SCRIPT */] = (flags & F_SCRIPT) === 0 ? 1 /* SCRIPT */ : src[1 /* SCRIPT */]; dst[2 /* REGION */] = (flags & F_REGION) === 0 ? 2 /* REGION */ : src[2 /* REGION */]; }; /** * Lookup any aliases that match this tag, and replace any undefined subtags. */ var substituteLanguageAliases = function (dst) { var aliases = LANGUAGE_ALIAS_MAP[dst[0 /* LANGUAGE */]]; if (aliases === undefined) { return; } for (var i = 0; i < aliases.length; i++) { var _a = aliases[i], type = _a.type, repl = _a.repl; var exact = (type[0 /* LANGUAGE */] === dst[0 /* LANGUAGE */] && type[1 /* SCRIPT */] === dst[1 /* SCRIPT */] && type[2 /* REGION */] === dst[2 /* REGION */]); if ((type[1 /* SCRIPT */] === 1 /* SCRIPT */ && type[2 /* REGION */] === 2 /* REGION */) || exact) { dst[0 /* LANGUAGE */] = repl[0 /* LANGUAGE */]; if (dst[1 /* SCRIPT */] === 1 /* SCRIPT */) { dst[1 /* SCRIPT */] = repl[1 /* SCRIPT */]; } if (dst[2 /* REGION */] === 2 /* REGION */) { dst[2 /* REGION */] = repl[2 /* REGION */]; } break; } } }; /** * Add any missing subtags using the likely subtags mapping. For example, * this would convert "en" to "en-Latn-US". */ var addLikelySubtags = function (dst) { var tmp = dst.slice(0); for (var i = 0; i < MATCH_ORDER.length; i++) { var flags = MATCH_ORDER[i]; setFields(dst, tmp, flags); var match = LIKELY_SUBTAGS_MAP.get(tmp); if (match !== undefined) { if (dst[0 /* LANGUAGE */] === 0 /* LANGUAGE */) { dst[0 /* LANGUAGE */] = match[0 /* LANGUAGE */]; } if (dst[1 /* SCRIPT */] === 1 /* SCRIPT */) { dst[1 /* SCRIPT */] = match[1 /* SCRIPT */]; } if (dst[2 /* REGION */] === 2 /* REGION */) { dst[2 /* REGION */] = match[2 /* REGION */]; } break; } } }; /** * Return a language tag, combining the fast tag's core subtags with the * original's additional subtags. */ var returnTag = function (real, fast) { var language = fast[0 /* LANGUAGE */]; var script = fast[1 /* SCRIPT */]; var region = fast[2 /* REGION */]; return new languagetag_1.LanguageTag(typeof language === 'number' ? undefined : language, typeof script === 'number' ? undefined : script, typeof region === 'number' ? undefined : region, real.variant(), real.extensions(), real.privateUse()); }; // Undefined tag to be copied for use in resolution below. var UNDEFINED = [0 /* LANGUAGE */, 1 /* SCRIPT */, 2 /* REGION */]; /** * Compare two fast tags for equality. These always have identical length. */ var fastTagEquals = function (a, b) { var len = a.length; for (var i = 0; i < len; i++) { if (a[i] !== b[i]) { return false; } } return true; }; var languageAlias = string_1.stringToObject(autogen_aliases_1.languageAliasRaw, '|', ':'); var buildLanguageAliasMap = function () { return Object.keys(languageAlias).reduce(function (o, k) { var type = parseFastTag(k); var repl = parseFastTag(languageAlias[k]); var language = type[0 /* LANGUAGE */]; var aliases = o[language]; if (aliases === undefined) { aliases = []; o[language] = aliases; } aliases.push({ type: type, repl: repl }); return o; }, {}); }; var likelySubtags = string_1.stringToObject(subtags.likelyRaw, '|', ':'); // Singleton maps. var LANGUAGE_ALIAS_MAP = buildLanguageAliasMap(); var LIKELY_SUBTAGS_MAP = new LikelySubtagsMap(likelySubtags); /** * Methods for substituting language and region aliases, adding likely subtags, etc. * * @alpha */ var LanguageResolver = /** @class */ (function () { function LanguageResolver() { } /** * Substitute all relevant aliases, and then add likely subtags. */ LanguageResolver.resolve = function (real) { var tag = typeof real === 'string' ? parser_1.parseLanguageTag(real) : real; var fast = fastTag(tag); substituteLanguageAliases(fast); util_1.substituteRegionAliases(fast); addLikelySubtags(fast); return returnTag(tag, fast); }; /** * Add any missing subtags using the likely subtags mapping. For example, * this would convert "en" to "en-Latn-US". */ LanguageResolver.addLikelySubtags = function (real) { var tag = typeof real === 'string' ? parser_1.parseLanguageTag(real) : real; var fast = fastTag(tag); addLikelySubtags(fast); return returnTag(tag, fast); }; /** * Remove any subtags that would be added by addLikelySubtags() above. For example, * this would convert "en-Latn-US" to "en". */ LanguageResolver.removeLikelySubtags = function (real) { var tag = typeof real === 'string' ? parser_1.parseLanguageTag(real) : real; var max = fastTag(tag); if (max[0 /* LANGUAGE */] === 0 /* LANGUAGE */ || max[1 /* SCRIPT */] === 1 /* SCRIPT */ || max[2 /* REGION */] === 2 /* REGION */) { addLikelySubtags(max); } var tmp = UNDEFINED.slice(0); // Using "en-Latn-US" as an example... // 1. Match "en-Zzzz-ZZ" tmp[0 /* LANGUAGE */] = max[0 /* LANGUAGE */]; var match = tmp.slice(0); addLikelySubtags(match); if (fastTagEquals(match, max)) { return returnTag(tag, tmp); } // 2. Match "en-Zzzz-US" tmp[2 /* REGION */] = max[2 /* REGION */]; match = tmp.slice(0); addLikelySubtags(match); if (fastTagEquals(match, max)) { tmp[0 /* LANGUAGE */] = max[0 /* LANGUAGE */]; return returnTag(tag, tmp); } // 3. Match "en-Latn-ZZ" tmp[2 /* REGION */] = 2 /* REGION */; tmp[1 /* SCRIPT */] = max[1 /* SCRIPT */]; match = tmp.slice(0); addLikelySubtags(match); if (fastTagEquals(match, max)) { return returnTag(tag, tmp); } // 4. Nothing matched, so return a copy of the original tag. return returnTag(tag, max); }; return LanguageResolver; }()); exports.LanguageResolver = LanguageResolver; //# sourceMappingURL=resolver.js.map