math_map.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  2. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  3. return new (P || (P = Promise))(function (resolve, reject) {
  4. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  5. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  6. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  7. step((generator = generator.apply(thisArg, _arguments || [])).next());
  8. });
  9. };
  10. import * as BrowserUtil from '../common/browser_util.js';
  11. import { Engine, EnginePromise } from '../common/engine.js';
  12. import * as EngineConst from '../common/engine_const.js';
  13. import * as FileUtil from '../common/file_util.js';
  14. import { SystemExternal } from '../common/system_external.js';
  15. import { DynamicCstr } from '../rule_engine/dynamic_cstr.js';
  16. import * as MathCompoundStore from '../rule_engine/math_compound_store.js';
  17. import { SpeechRuleEngine } from '../rule_engine/speech_rule_engine.js';
  18. import { completeLocale } from '../l10n/l10n.js';
  19. import * as AlphabetGenerator from './alphabet_generator.js';
  20. const addSymbols = {
  21. functions: MathCompoundStore.addFunctionRules,
  22. symbols: MathCompoundStore.addSymbolRules,
  23. units: MathCompoundStore.addUnitRules,
  24. si: (x) => x.forEach(MathCompoundStore.setSiPrefixes),
  25. messages: completeLocale,
  26. rules: SpeechRuleEngine.addStore,
  27. characters: MathCompoundStore.addCharacterRules
  28. };
  29. let _init = false;
  30. export function loadLocale() {
  31. return __awaiter(this, arguments, void 0, function* (locale = Engine.getInstance().locale) {
  32. if (!_init) {
  33. AlphabetGenerator.generateBase();
  34. _loadLocale(DynamicCstr.BASE_LOCALE);
  35. _init = true;
  36. }
  37. return EnginePromise.promises[DynamicCstr.BASE_LOCALE].then(() => __awaiter(this, void 0, void 0, function* () {
  38. const defLoc = Engine.getInstance().defaultLocale;
  39. if (defLoc) {
  40. _loadLocale(defLoc);
  41. return EnginePromise.promises[defLoc].then(() => __awaiter(this, void 0, void 0, function* () {
  42. _loadLocale(locale);
  43. return EnginePromise.promises[locale];
  44. }));
  45. }
  46. _loadLocale(locale);
  47. return EnginePromise.promises[locale];
  48. }));
  49. });
  50. }
  51. function _loadLocale(locale = Engine.getInstance().locale) {
  52. if (!EnginePromise.loaded[locale]) {
  53. EnginePromise.loaded[locale] = [false, false];
  54. MathCompoundStore.reset();
  55. retrieveMaps(locale);
  56. }
  57. }
  58. function loadMethod() {
  59. if (Engine.getInstance().customLoader) {
  60. return Engine.getInstance().customLoader;
  61. }
  62. return standardLoader();
  63. }
  64. export function standardLoader() {
  65. switch (Engine.getInstance().mode) {
  66. case EngineConst.Mode.ASYNC:
  67. return loadFile;
  68. case EngineConst.Mode.HTTP:
  69. return loadAjax;
  70. case EngineConst.Mode.SYNC:
  71. default:
  72. return loadFileSync;
  73. }
  74. }
  75. function retrieveFiles(locale) {
  76. const loader = loadMethod();
  77. const promise = new Promise((res) => {
  78. const inner = loader(locale);
  79. inner.then((str) => {
  80. parseMaps(str);
  81. EnginePromise.loaded[locale] = [true, true];
  82. res(locale);
  83. }, (_err) => {
  84. EnginePromise.loaded[locale] = [true, false];
  85. console.error(`Unable to load locale: ${locale}`);
  86. Engine.getInstance().locale = Engine.getInstance().defaultLocale;
  87. res(locale);
  88. });
  89. });
  90. EnginePromise.promises[locale] = promise;
  91. }
  92. function parseMaps(json) {
  93. const js = typeof json === 'string'
  94. ? JSON.parse(json)
  95. : json;
  96. addMaps(js);
  97. }
  98. function addMaps(json, opt_locale) {
  99. let generate = true;
  100. for (let i = 0, key; (key = Object.keys(json)[i]); i++) {
  101. const info = key.split('/');
  102. if (opt_locale && opt_locale !== info[0]) {
  103. continue;
  104. }
  105. if (generate && info[1] === 'symbols' && info[0] !== 'base') {
  106. AlphabetGenerator.generate(info[0]);
  107. generate = false;
  108. }
  109. addSymbols[info[1]](json[key]);
  110. }
  111. }
  112. function retrieveMaps(locale) {
  113. if (Engine.getInstance().isIE &&
  114. Engine.getInstance().mode === EngineConst.Mode.HTTP) {
  115. getJsonIE_(locale);
  116. return;
  117. }
  118. retrieveFiles(locale);
  119. }
  120. function getJsonIE_(locale, opt_count) {
  121. let count = opt_count || 1;
  122. if (!BrowserUtil.mapsForIE) {
  123. if (count <= 5) {
  124. setTimeout((() => getJsonIE_(locale, count++)).bind(this), 300);
  125. }
  126. return;
  127. }
  128. addMaps(BrowserUtil.mapsForIE, locale);
  129. }
  130. function loadFile(locale) {
  131. const file = FileUtil.localePath(locale);
  132. return new Promise((res, rej) => {
  133. SystemExternal.fs.readFile(file, 'utf8', (err, json) => {
  134. if (err) {
  135. return rej(err);
  136. }
  137. res(json);
  138. });
  139. });
  140. }
  141. function loadFileSync(locale) {
  142. const file = FileUtil.localePath(locale);
  143. return new Promise((res, rej) => {
  144. let str = '{}';
  145. try {
  146. str = SystemExternal.fs.readFileSync(file, 'utf8');
  147. }
  148. catch (err) {
  149. return rej(err);
  150. }
  151. res(str);
  152. });
  153. }
  154. function loadAjax(locale) {
  155. const file = FileUtil.localePath(locale);
  156. const httpRequest = new XMLHttpRequest();
  157. return new Promise((res, rej) => {
  158. httpRequest.onreadystatechange = function () {
  159. if (httpRequest.readyState === 4) {
  160. const status = httpRequest.status;
  161. if (status === 0 || (status >= 200 && status < 400)) {
  162. res(httpRequest.responseText);
  163. }
  164. else {
  165. rej(status);
  166. }
  167. }
  168. };
  169. httpRequest.open('GET', file, true);
  170. httpRequest.send();
  171. });
  172. }