diff --git a/MN.L10n.Javascript/Javascript/L10n.js b/MN.L10n.Javascript/Javascript/L10n.js index 9b73355..8750dbc 100644 --- a/MN.L10n.Javascript/Javascript/L10n.js +++ b/MN.L10n.Javascript/Javascript/L10n.js @@ -1,2 +1,2 @@ -(function(){function l(){var n=null;return typeof window!="undefined"?n=window:typeof global!="undefined"&&(n=global),n}function u(){var n=l();if(n==null)return null;var e=n.l10n;return typeof e=="undefined"?null:e}function f(n,e){typeof e=="undefined"&&(e={});var t=u();if(t==null)return n;var r=t.Phrases[n],i;return typeof e.__count!="undefined"&&(i=t.ruleEvaluator(e.__count).toString()),typeof r!="undefined"&&(typeof i!="undefined"&&typeof r.r[i]!="undefined"?n=r.r[i]:n=r.r["0"]),n}function a(n,e){var r,i;if(typeof e=="undefined")return n;for(var t in e)e.hasOwnProperty(t)&&(n=n.split("$"+t+"$").join((i=(r=e[t])==null?void 0:r.toString())!=null?i:""));return n}function o(n,e){return a(f(n,e),e)}typeof window!="undefined"&&(window._s=o);typeof global!="undefined"&&(global._s=o);})(); +"use strict";(function(){function u(){var n=null;return typeof window!="undefined"?n=window:typeof global!="undefined"&&(n=global),n}function f(){var n=u();if(n==null)return null;var t=n.l10n;return typeof t=="undefined"?null:t}var g=" !ctx=";function l(n){if(n==null)return"";if(typeof n!="string")return n;var t=n.toLowerCase().indexOf(g);return t<0?n:n.substring(0,t)}function a(n,t){typeof t=="undefined"&&(t={});var e=f();if(e==null)return n;var r=e.Phrases[n],i;return typeof t.__count!="undefined"&&(i=e.ruleEvaluator(t.__count).toString()),typeof r!="undefined"&&(typeof i!="undefined"&&typeof r.r[i]!="undefined"?n=r.r[i]:n=r.r[0]),l(n)}function d(n,t){var r,i;if(typeof t=="undefined")return n;for(var e in t)t.hasOwnProperty(e)&&(n=n.split("$"+e+"$").join((i=(r=t[e])==null?void 0:r.toString())!=null?i:""));return n}function o(n,t){return d(a(n,t),t)}typeof window!="undefined"&&(window._s=o);typeof global!="undefined"&&(global._s=o);})(); //# sourceMappingURL=L10n.js.map diff --git a/MN.L10n.Javascript/Javascript/L10n.js.map b/MN.L10n.Javascript/Javascript/L10n.js.map index 04fddae..d095ece 100644 --- a/MN.L10n.Javascript/Javascript/L10n.js.map +++ b/MN.L10n.Javascript/Javascript/L10n.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../src/internal/GetGlobal.ts", "../src/internal/GetL10n.ts", "../src/internal/GetPhrase.ts", "../src/internal/ReplaceKeywords.ts", "../src/_s.ts", "../src/L10n.ts"], - "sourcesContent": ["export function getGlobal(): any {\r\n var target: any = null;\r\n if (typeof window !== \"undefined\") {\r\n target = window;\r\n } else if (typeof global !== \"undefined\") {\r\n target = global;\r\n }\r\n\r\n return target;\r\n}\r\n", "import { getGlobal } from \"./GetGlobal\";\r\n\r\ntype GlobalL10n = {\r\n Phrases: {\r\n [phrase: string]: {\r\n r: {\r\n \"0\": string;\r\n [ruleIndex: string]: string | undefined;\r\n };\r\n };\r\n };\r\n ruleEvaluator: (count: number) => number;\r\n};\r\n\r\nexport function getL10n(): GlobalL10n | null {\r\n var global = getGlobal();\r\n if (global == null) {\r\n return null;\r\n }\r\n\r\n var l10n = global.l10n;\r\n if (\"undefined\" === typeof l10n) {\r\n return null;\r\n }\r\n\r\n return l10n as GlobalL10n;\r\n}\r\n", "import { getL10n } from \"./GetL10n\";\r\n\r\n/**\r\n * Fetches the phrase from the internal list of phrases, and evaluates potential count-rules\r\n */\r\nexport function getPhrase(\r\n phrase: string,\r\n args?: {\r\n __count?: number;\r\n }\r\n) {\r\n if (\"undefined\" === typeof args) args = {};\r\n var l10n = getL10n();\r\n if (l10n == null) {\r\n return phrase;\r\n }\r\n\r\n var _p = l10n.Phrases[phrase];\r\n var _ri: string | undefined;\r\n if (\"undefined\" !== typeof args.__count) {\r\n _ri = l10n.ruleEvaluator(args.__count).toString();\r\n }\r\n if (\"undefined\" !== typeof _p) {\r\n if (\"undefined\" !== typeof _ri && \"undefined\" !== typeof _p.r[_ri]) {\r\n phrase = _p.r[_ri]!;\r\n } else {\r\n phrase = _p.r[\"0\"];\r\n }\r\n }\r\n return phrase;\r\n}\r\n", "export function replaceKeywords(\r\n phrase: string,\r\n args?: {\r\n [key: string]: string | number;\r\n }\r\n) {\r\n if (\"undefined\" === typeof args) {\r\n return phrase;\r\n }\r\n\r\n for (var p in args) {\r\n if (args.hasOwnProperty(p)) {\r\n phrase = phrase.split(\"$\" + p + \"$\").join(args[p]?.toString() ?? \"\");\r\n }\r\n }\r\n return phrase;\r\n}\r\n", "import { getPhrase } from \"./internal/GetPhrase\";\r\nimport { replaceKeywords } from \"./internal/ReplaceKeywords\";\r\nimport { ExtractL10nParameter, TranslatedString } from \"./publicTypes\";\r\n\r\nexport function _s(\r\n l10nString: T,\r\n formatParameters?: {\r\n [key in ExtractL10nParameter]: string | number;\r\n }\r\n): TranslatedString {\r\n return replaceKeywords(\r\n getPhrase(l10nString, formatParameters),\r\n formatParameters\r\n ) as unknown as TranslatedString;\r\n}\r\n", "import { _s } from \"./_s\";\r\n\r\nif (\"undefined\" !== typeof window) {\r\n (window as any)._s = _s;\r\n}\r\n\r\nif (\"undefined\" !== typeof global) {\r\n (global as any)._s = _s;\r\n}\r\n"], - "mappings": "YAAO,YAA0B,CAC/B,GAAI,GAAc,KAClB,MAAI,OAAO,SAAW,YACpB,EAAS,OACA,MAAO,SAAW,aAC3B,GAAS,QAGJ,ECMF,YAAsC,CAC3C,GAAI,GAAS,IACb,GAAI,GAAU,KACZ,MAAO,MAGT,GAAI,GAAO,EAAO,KAClB,MAAI,AAAgB,OAAO,IAAvB,YACK,KAGF,ECpBF,WACL,EACA,EAGA,CACA,AAAI,AAAgB,MAAO,IAAvB,aAA6B,GAAO,IACxC,GAAI,GAAO,IACX,GAAI,GAAQ,KACV,MAAO,GAGT,GAAI,GAAK,EAAK,QAAQ,GAClB,EACJ,MAAI,AAAgB,OAAO,GAAK,SAA5B,aACF,GAAM,EAAK,cAAc,EAAK,SAAS,YAErC,AAAgB,MAAO,IAAvB,aACF,CAAI,AAAgB,MAAO,IAAvB,aAA8B,AAAgB,MAAO,GAAG,EAAE,IAA5B,YAChC,EAAS,EAAG,EAAE,GAEd,EAAS,EAAG,EAAE,MAGX,EC7BF,WACL,EACA,EAGA,CALF,QAME,GAAI,AAAgB,MAAO,IAAvB,YACF,MAAO,GAGT,OAAS,KAAK,GACZ,AAAI,EAAK,eAAe,IACtB,GAAS,EAAO,MAAM,IAAM,EAAI,KAAK,KAAK,QAAK,KAAL,cAAS,aAAT,OAAuB,KAGrE,MAAO,GCXF,WACL,EACA,EAGkB,CAClB,MAAO,GACL,EAAU,EAAY,GACtB,GCVJ,AAAI,AAAgB,MAAO,SAAvB,aACD,QAAe,GAAK,GAGvB,AAAI,AAAgB,MAAO,SAAvB,aACD,QAAe,GAAK", - "names": [] + "sources": ["../src/internal/GetGlobal.ts", "../src/internal/GetL10n.ts", "../src/internal/MetadataReplacer.ts", "../src/internal/GetPhrase.ts", "../src/internal/ReplaceKeywords.ts", "../src/_s.ts", "../src/L10n.ts"], + "sourcesContent": ["export function getGlobal(): any {\r\n var target: any = null;\r\n if (typeof window !== \"undefined\") {\r\n target = window;\r\n } else if (typeof global !== \"undefined\") {\r\n target = global;\r\n }\r\n\r\n return target;\r\n}\r\n", "import { getGlobal } from \"./GetGlobal\";\r\n\r\ntype GlobalL10n = {\r\n Phrases: {\r\n [phrase: string]: {\r\n r: {\r\n \"0\": string;\r\n [ruleIndex: string]: string | undefined;\r\n };\r\n };\r\n };\r\n ruleEvaluator: (count: number) => number;\r\n};\r\n\r\nexport function getL10n(): GlobalL10n | null {\r\n var global = getGlobal();\r\n if (global == null) {\r\n return null;\r\n }\r\n\r\n var l10n = global.l10n;\r\n if (\"undefined\" === typeof l10n) {\r\n return null;\r\n }\r\n\r\n return l10n as GlobalL10n;\r\n}\r\n", "var metaDataStartToken = \" !ctx=\";\r\n\r\nexport function replaceMetadata(phrase: string | null): string {\r\n\tif (phrase == null) {\r\n\t\treturn \"\";\r\n\t}\r\n\r\n\tif (typeof phrase != \"string\") {\r\n\t\treturn phrase;\r\n\t}\r\n\r\n\tvar ioMetaStart = phrase.toLowerCase().indexOf(metaDataStartToken);\r\n\tif (ioMetaStart < 0) {\r\n\t\treturn phrase;\r\n\t}\r\n\r\n\treturn phrase.substring(0, ioMetaStart);\r\n}\r\n", "import { getL10n } from \"./GetL10n\";\r\nimport { replaceMetadata } from \"./MetadataReplacer\";\r\n\r\n/**\r\n * Fetches the phrase from the internal list of phrases, and evaluates potential count-rules\r\n */\r\nexport function getPhrase(\r\n\tphrase: string,\r\n\targs?: {\r\n\t\t__count?: number;\r\n\t}\r\n) {\r\n\tif (\"undefined\" === typeof args) args = {};\r\n\tvar l10n = getL10n();\r\n\tif (l10n == null) {\r\n\t\treturn phrase;\r\n\t}\r\n\r\n\tvar _p = l10n.Phrases[phrase];\r\n\tvar _ri: string | undefined;\r\n\tif (\"undefined\" !== typeof args.__count) {\r\n\t\t_ri = l10n.ruleEvaluator(args.__count).toString();\r\n\t}\r\n\tif (\"undefined\" !== typeof _p) {\r\n\t\tif (\"undefined\" !== typeof _ri && \"undefined\" !== typeof _p.r[_ri]) {\r\n\t\t\tphrase = _p.r[_ri]!;\r\n\t\t} else {\r\n\t\t\tphrase = _p.r[\"0\"];\r\n\t\t}\r\n\t}\r\n\r\n\treturn replaceMetadata(phrase);\r\n}\r\n", "export function replaceKeywords(\r\n phrase: string,\r\n args?: {\r\n [key: string]: string | number;\r\n }\r\n) {\r\n if (\"undefined\" === typeof args) {\r\n return phrase;\r\n }\r\n\r\n for (var p in args) {\r\n if (args.hasOwnProperty(p)) {\r\n phrase = phrase.split(\"$\" + p + \"$\").join(args[p]?.toString() ?? \"\");\r\n }\r\n }\r\n return phrase;\r\n}\r\n", "import { getPhrase } from \"./internal/GetPhrase\";\r\nimport { replaceKeywords } from \"./internal/ReplaceKeywords\";\r\nimport { ExtractL10nParameter, TranslatedString } from \"./publicTypes\";\r\n\r\nexport function _s(\r\n l10nString: T,\r\n formatParameters?: {\r\n [key in ExtractL10nParameter]: string | number;\r\n }\r\n): TranslatedString {\r\n return replaceKeywords(\r\n getPhrase(l10nString, formatParameters),\r\n formatParameters\r\n ) as unknown as TranslatedString;\r\n}\r\n", "import { _s } from \"./_s\";\r\n\r\nif (\"undefined\" !== typeof window) {\r\n (window as any)._s = _s;\r\n}\r\n\r\nif (\"undefined\" !== typeof global) {\r\n (global as any)._s = _s;\r\n}\r\n"], + "mappings": "yBAAO,SAASA,GAAiB,CAC/B,IAAIC,EAAc,KAClB,OAAI,OAAO,QAAW,YACpBA,EAAS,OACA,OAAO,QAAW,cAC3BA,EAAS,QAGJA,CACT,CCKO,SAASC,GAA6B,CAC3C,IAAIC,EAASC,EAAU,EACvB,GAAID,GAAU,KACZ,OAAO,KAGT,IAAIE,EAAOF,EAAO,KAClB,OAAoB,OAAOE,GAAvB,YACK,KAGFA,CACT,CC1BA,IAAIC,EAAqB,SAElB,SAASC,EAAgBC,EAA+B,CAC9D,GAAIA,GAAU,KACb,MAAO,GAGR,GAAI,OAAOA,GAAU,SACpB,OAAOA,EAGR,IAAIC,EAAcD,EAAO,YAAY,EAAE,QAAQF,CAAkB,EACjE,OAAIG,EAAc,EACVD,EAGDA,EAAO,UAAU,EAAGC,CAAW,CACvC,CCXO,SAASC,EACfC,EACAC,EAGC,CACmB,OAAOA,GAAvB,cAA6BA,EAAO,CAAC,GACzC,IAAIC,EAAOC,EAAQ,EACnB,GAAID,GAAQ,KACX,OAAOF,EAGR,IAAII,EAAKF,EAAK,QAAQF,GAClBK,EACJ,OAAoB,OAAOJ,EAAK,SAA5B,cACHI,EAAMH,EAAK,cAAcD,EAAK,OAAO,EAAE,SAAS,GAE7B,OAAOG,GAAvB,cACiB,OAAOC,GAAvB,aAA8C,OAAOD,EAAG,EAAEC,IAA5B,YACjCL,EAASI,EAAG,EAAEC,GAEdL,EAASI,EAAG,EAAE,IAITE,EAAgBN,CAAM,CAC9B,CChCO,SAASO,EACdC,EACAC,EAGA,CALF,IAAAC,EAAAC,EAME,GAAoB,OAAOF,GAAvB,YACF,OAAOD,EAGT,QAASI,KAAKH,EACRA,EAAK,eAAeG,CAAC,IACvBJ,EAASA,EAAO,MAAM,IAAMI,EAAI,GAAG,EAAE,MAAKD,GAAAD,EAAAD,EAAKG,KAAL,YAAAF,EAAS,aAAT,KAAAC,EAAuB,EAAE,GAGvE,OAAOH,CACT,CCZO,SAASK,EACdC,EACAC,EAGkB,CAClB,OAAOC,EACLC,EAAUH,EAAYC,CAAgB,EACtCA,CACF,CACF,CCZoB,OAAO,QAAvB,cACD,OAAe,GAAKG,GAGH,OAAO,QAAvB,cACD,OAAe,GAAKA", + "names": ["getGlobal", "target", "getL10n", "global", "getGlobal", "l10n", "metaDataStartToken", "replaceMetadata", "phrase", "ioMetaStart", "getPhrase", "phrase", "args", "l10n", "getL10n", "_p", "_ri", "replaceMetadata", "replaceKeywords", "phrase", "args", "_a", "_b", "p", "_s", "l10nString", "formatParameters", "replaceKeywords", "getPhrase", "_s"] } diff --git a/MN.L10n.Javascript/Javascript/package.json b/MN.L10n.Javascript/Javascript/package.json index 6ea65b7..1e59d93 100644 --- a/MN.L10n.Javascript/Javascript/package.json +++ b/MN.L10n.Javascript/Javascript/package.json @@ -1,37 +1,37 @@ { - "name": "@multinet/mn-l10n", - "version": "3.0.2", - "description": "Multinet translation library", - "main": "dist/L10n.js", - "types": "dist/types", - "files": [ - "src", - "dist" - ], - "publishConfig": { - "registry": "https://www.myget.org/F/multinet/npm/" - }, - "repository": "https://github.com/MultinetInteractive/MN.L10n", - "author": "Chris Gårdenberg, Linus Centerström", - "license": "GPL-3.0", - "sideEffects": true, - "devDependencies": { - "@babel/core": "^7.19.6", - "@types/jest": "^29.2.1", - "@types/node": "^18.11.9", - "esbuild": "^0.15.13", - "esbuild-plugin-babel": "^0.2.3", - "jest": "^29.2.2", - "ts-jest": "^29.0.3", - "typescript": "^4.8.4" - }, - "scripts": { - "build": "tsc && node scripts/build.mjs", - "buildAndMinify": "tsc && node scripts/build.mjs --min", - "test": "node node_modules/jest/bin/jest.js", - "test-watch": "node node_modules/jest/bin/jest.js --watch", - "test-debug": "node --inspect-brk node_modules/jest/bin/jest.js --runInBand", - "test-coverage": "node node_modules/jest/bin/jest.js --collect-coverage", - "buildAndPublish": "yarn buildAndMinify && npm publish" - } + "name": "@multinet/mn-l10n", + "version": "3.1.0", + "description": "Multinet translation library", + "main": "dist/L10n.js", + "types": "dist/types", + "files": [ + "src", + "dist" + ], + "publishConfig": { + "registry": "https://www.myget.org/F/multinet/npm/" + }, + "repository": "https://github.com/MultinetInteractive/MN.L10n", + "author": "Chris Gårdenberg, Linus Centerström", + "license": "GPL-3.0", + "sideEffects": true, + "devDependencies": { + "@babel/core": "^7.19.6", + "@types/jest": "^29.2.1", + "@types/node": "^18.11.9", + "esbuild": "^0.15.13", + "esbuild-plugin-babel": "^0.2.3", + "jest": "^29.2.2", + "ts-jest": "^29.0.3", + "typescript": "^4.8.4" + }, + "scripts": { + "build": "tsc && node scripts/build.mjs", + "buildAndMinify": "tsc && node scripts/build.mjs --min", + "test": "node node_modules/jest/bin/jest.js", + "test-watch": "node node_modules/jest/bin/jest.js --watch", + "test-debug": "node --inspect-brk node_modules/jest/bin/jest.js --runInBand", + "test-coverage": "node node_modules/jest/bin/jest.js --collect-coverage", + "buildAndPublish": "yarn buildAndMinify && npm publish" + } } diff --git a/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.test.ts b/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.test.ts index 00fec00..91385d0 100644 --- a/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.test.ts +++ b/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.test.ts @@ -3,118 +3,142 @@ import { getPhrase } from "./GetPhrase"; import * as getL10nModule from "./GetL10n"; jest.mock("./GetL10n"); -const getL10nMock = (getL10nModule.getL10n as any) as MockedFunction< - typeof getL10nModule.getL10n +const getL10nMock = getL10nModule.getL10n as any as MockedFunction< + typeof getL10nModule.getL10n >; beforeEach(() => getL10nMock.mockReset()); describe("GetPhrase", () => { - it("returns the phrase if l10n is unavailable", () => { - getL10nMock.mockImplementation(() => null); - const phrase = getPhrase("Testar $__count$", { - __count: 1, - }); - expect(phrase).toBe("Testar $__count$"); - }); - it("returns the phrase if it is unavailable", () => { - getL10nMock.mockImplementation(() => ({ - Phrases: {}, - ruleEvaluator: (c) => c, - })); - const phrase = getPhrase("Testar $__count$", { - __count: 1, - }); - expect(phrase).toBe("Testar $__count$"); - }); - it("uses the correct phrase if available", () => { - getL10nMock.mockImplementation(() => ({ - ruleEvaluator: (c) => c, - Phrases: { - ["test"]: { - r: { - "0": "test2", - }, - }, - ["test2"]: { - r: { - "0": "test3", - }, - }, - }, - })); + it("returns the phrase if l10n is unavailable", () => { + getL10nMock.mockImplementation(() => null); + const phrase = getPhrase("Testar $__count$", { + __count: 1 + }); + expect(phrase).toBe("Testar $__count$"); + }); + it("returns the phrase if it is unavailable", () => { + getL10nMock.mockImplementation(() => ({ + Phrases: {}, + ruleEvaluator: (c) => c + })); + const phrase = getPhrase("Testar $__count$", { + __count: 1 + }); + expect(phrase).toBe("Testar $__count$"); + }); + it("uses the correct phrase if available", () => { + getL10nMock.mockImplementation(() => ({ + ruleEvaluator: (c) => c, + Phrases: { + ["test"]: { + r: { + "0": "test2" + } + }, + ["test2"]: { + r: { + "0": "test3" + } + } + } + })); - const phrase = getPhrase("test"); - expect(phrase).toBe("test2"); - }); - it("uses the 0 phrase if no other is available", () => { - getL10nMock.mockImplementation(() => ({ - ruleEvaluator: (c) => c, - Phrases: { - ["test"]: { - r: { - "0": "test2", - }, - }, - ["test2"]: { - r: { - "0": "test3", - }, - }, - }, - })); + const phrase = getPhrase("test"); + expect(phrase).toBe("test2"); + }); + it("uses the 0 phrase if no other is available", () => { + getL10nMock.mockImplementation(() => ({ + ruleEvaluator: (c) => c, + Phrases: { + ["test"]: { + r: { + "0": "test2" + } + }, + ["test2"]: { + r: { + "0": "test3" + } + } + } + })); - const phrase = getPhrase("test", { - __count: 3, - }); - expect(phrase).toBe("test2"); - }); + const phrase = getPhrase("test", { + __count: 3 + }); + expect(phrase).toBe("test2"); + }); - it("uses the correct counted phrase if available", () => { - getL10nMock.mockImplementation(() => ({ - ruleEvaluator: (c) => c, - Phrases: { - ["test"]: { - r: { - "0": "test2", - "1": "test4", - }, - }, - ["test2"]: { - r: { - "0": "test3", - }, - }, - }, - })); + it("uses the correct counted phrase if available", () => { + getL10nMock.mockImplementation(() => ({ + ruleEvaluator: (c) => c, + Phrases: { + ["test"]: { + r: { + "0": "test2", + "1": "test4" + } + }, + ["test2"]: { + r: { + "0": "test3" + } + } + } + })); - const phrase = getPhrase("test", { - __count: 1, - }); - expect(phrase).toBe("test4"); - }); + const phrase = getPhrase("test", { + __count: 1 + }); + expect(phrase).toBe("test4"); + }); - it("uses the correct counted phrase if available 2", () => { - getL10nMock.mockImplementation(() => ({ - ruleEvaluator: (c) => (c === 1 ? 6 : c), - Phrases: { - ["test"]: { - r: { - "0": "test2", - "6": "test4", - }, - }, - ["test2"]: { - r: { - "0": "test3", - }, - }, - }, - })); + it("uses the correct counted phrase if available 2", () => { + getL10nMock.mockImplementation(() => ({ + ruleEvaluator: (c) => (c === 1 ? 6 : c), + Phrases: { + ["test"]: { + r: { + "0": "test2", + "6": "test4" + } + }, + ["test2"]: { + r: { + "0": "test3" + } + } + } + })); - const phrase = getPhrase("test", { - __count: 1, - }); - expect(phrase).toBe("test4"); - }); + const phrase = getPhrase("test", { + __count: 1 + }); + expect(phrase).toBe("test4"); + }); + + it("uses replaces metadata if needed", () => { + getL10nMock.mockImplementation(() => ({ + ruleEvaluator: (c) => (c === 1 ? 6 : c), + Phrases: { + ["test !ctx=my test data"]: { + r: { + "0": "test2 !ctx=my test data", + "6": "test4 !ctx=my test data" + } + }, + ["test2"]: { + r: { + "0": "test3" + } + } + } + })); + + const phrase = getPhrase("test !ctx=my test data", { + __count: 1 + }); + expect(phrase).toBe("test4"); + }); }); diff --git a/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.ts b/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.ts index 3d5d13d..83e25ae 100644 --- a/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.ts +++ b/MN.L10n.Javascript/Javascript/src/internal/GetPhrase.ts @@ -1,31 +1,33 @@ import { getL10n } from "./GetL10n"; +import { replaceMetadata } from "./MetadataReplacer"; /** * Fetches the phrase from the internal list of phrases, and evaluates potential count-rules */ export function getPhrase( - phrase: string, - args?: { - __count?: number; - } + phrase: string, + args?: { + __count?: number; + } ) { - if ("undefined" === typeof args) args = {}; - var l10n = getL10n(); - if (l10n == null) { - return phrase; - } + if ("undefined" === typeof args) args = {}; + var l10n = getL10n(); + if (l10n == null) { + return phrase; + } - var _p = l10n.Phrases[phrase]; - var _ri: string | undefined; - if ("undefined" !== typeof args.__count) { - _ri = l10n.ruleEvaluator(args.__count).toString(); - } - if ("undefined" !== typeof _p) { - if ("undefined" !== typeof _ri && "undefined" !== typeof _p.r[_ri]) { - phrase = _p.r[_ri]!; - } else { - phrase = _p.r["0"]; - } - } - return phrase; + var _p = l10n.Phrases[phrase]; + var _ri: string | undefined; + if ("undefined" !== typeof args.__count) { + _ri = l10n.ruleEvaluator(args.__count).toString(); + } + if ("undefined" !== typeof _p) { + if ("undefined" !== typeof _ri && "undefined" !== typeof _p.r[_ri]) { + phrase = _p.r[_ri]!; + } else { + phrase = _p.r["0"]; + } + } + + return replaceMetadata(phrase); } diff --git a/MN.L10n.Javascript/Javascript/src/internal/MetadataReplacer.test.ts b/MN.L10n.Javascript/Javascript/src/internal/MetadataReplacer.test.ts new file mode 100644 index 0000000..035bd19 --- /dev/null +++ b/MN.L10n.Javascript/Javascript/src/internal/MetadataReplacer.test.ts @@ -0,0 +1,20 @@ +import { replaceMetadata } from "./MetadataReplacer"; +describe("it replaces metadata correctly", () => { + const testData: [string, string][] = [ + ["Deltagare", "Deltagare"], + ["Deltagare !ctx=1", "Deltagare"], + ["Deltagare !Ctx=1", "Deltagare"], + ["Deltagare!ctx=1", "Deltagare!ctx=1"], + [ + "Det finns en massa deltagare !ctx=1 all this text is meta", + "Det finns en massa deltagare" + ] + ]; + + for (const [input, expected] of testData) { + it(`replaces metadata in "${input}" correctly`, () => { + const result = replaceMetadata(input); + expect(result).toBe(expected); + }); + } +}); diff --git a/MN.L10n.Javascript/Javascript/src/internal/MetadataReplacer.ts b/MN.L10n.Javascript/Javascript/src/internal/MetadataReplacer.ts new file mode 100644 index 0000000..9a95afc --- /dev/null +++ b/MN.L10n.Javascript/Javascript/src/internal/MetadataReplacer.ts @@ -0,0 +1,18 @@ +var metaDataStartToken = " !ctx="; + +export function replaceMetadata(phrase: string | null): string { + if (phrase == null) { + return ""; + } + + if (typeof phrase != "string") { + return phrase; + } + + var ioMetaStart = phrase.toLowerCase().indexOf(metaDataStartToken); + if (ioMetaStart < 0) { + return phrase; + } + + return phrase.substring(0, ioMetaStart); +}