engine.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import * as Dcstr from '../rule_engine/dynamic_cstr.js';
  2. import * as EngineConst from './engine_const.js';
  3. import { Debugger } from './debugger.js';
  4. import { Variables } from './variables.js';
  5. export class SREError extends Error {
  6. constructor(message = '') {
  7. super();
  8. this.message = message;
  9. this.name = 'SRE Error';
  10. }
  11. }
  12. export class Engine {
  13. set defaultLocale(loc) {
  14. this._defaultLocale = Variables.ensureLocale(loc, this._defaultLocale);
  15. }
  16. get defaultLocale() {
  17. return this._defaultLocale;
  18. }
  19. static getInstance() {
  20. Engine.instance = Engine.instance || new Engine();
  21. return Engine.instance;
  22. }
  23. static defaultEvaluator(str, _cstr) {
  24. return str;
  25. }
  26. static evaluateNode(node) {
  27. return Engine.nodeEvaluator(node);
  28. }
  29. getRate() {
  30. const numeric = parseInt(this.rate, 10);
  31. return isNaN(numeric) ? 100 : numeric;
  32. }
  33. setDynamicCstr(opt_dynamic) {
  34. if (this.defaultLocale) {
  35. Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.LOCALE] = this.defaultLocale;
  36. }
  37. if (opt_dynamic) {
  38. const keys = Object.keys(opt_dynamic);
  39. for (let i = 0; i < keys.length; i++) {
  40. const feature = keys[i];
  41. if (Dcstr.DynamicCstr.DEFAULT_ORDER.indexOf(feature) !== -1) {
  42. const value = opt_dynamic[feature];
  43. this[feature] = value;
  44. }
  45. }
  46. }
  47. EngineConst.DOMAIN_TO_STYLES[this.domain] = this.style;
  48. const dynamic = [this.locale, this.modality, this.domain, this.style].join('.');
  49. const fallback = Dcstr.DynamicProperties.createProp([Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.LOCALE]], [Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.MODALITY]], [Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.DOMAIN]], [Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.STYLE]]);
  50. const comparator = this.comparators[this.domain];
  51. const parser = this.parsers[this.domain];
  52. this.parser = parser ? parser : this.defaultParser;
  53. this.dynamicCstr = this.parser.parse(dynamic);
  54. this.dynamicCstr.updateProperties(fallback.getProperties());
  55. this.comparator = comparator
  56. ? comparator()
  57. : new Dcstr.DefaultComparator(this.dynamicCstr);
  58. }
  59. constructor() {
  60. this.customLoader = null;
  61. this.parsers = {};
  62. this.comparator = null;
  63. this.mode = EngineConst.Mode.SYNC;
  64. this.init = true;
  65. this.delay = false;
  66. this.comparators = {};
  67. this.domain = 'mathspeak';
  68. this.style = Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.STYLE];
  69. this._defaultLocale = Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.LOCALE];
  70. this.locale = Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.LOCALE];
  71. this.subiso = '';
  72. this.modality = Dcstr.DynamicCstr.DEFAULT_VALUES[Dcstr.Axis.MODALITY];
  73. this.speech = EngineConst.Speech.NONE;
  74. this.markup = EngineConst.Markup.NONE;
  75. this.mark = true;
  76. this.automark = false;
  77. this.character = true;
  78. this.cleanpause = true;
  79. this.cayleyshort = true;
  80. this.linebreaks = false;
  81. this.rate = '100';
  82. this.walker = 'Table';
  83. this.structure = false;
  84. this.aria = false;
  85. this.ruleSets = [];
  86. this.strict = false;
  87. this.isIE = false;
  88. this.isEdge = false;
  89. this.pprint = false;
  90. this.config = false;
  91. this.rules = '';
  92. this.prune = '';
  93. this.locale = this.defaultLocale;
  94. this.evaluator = Engine.defaultEvaluator;
  95. this.defaultParser = new Dcstr.DynamicCstrParser(Dcstr.DynamicCstr.DEFAULT_ORDER);
  96. this.parser = this.defaultParser;
  97. this.dynamicCstr = Dcstr.DynamicCstr.defaultCstr();
  98. }
  99. configurate(feature) {
  100. if (this.mode === EngineConst.Mode.HTTP && !this.config) {
  101. configBlocks(feature);
  102. this.config = true;
  103. }
  104. configFeature(feature);
  105. }
  106. setCustomLoader(fn) {
  107. if (fn) {
  108. this.customLoader = fn;
  109. }
  110. }
  111. }
  112. Engine.BINARY_FEATURES = [
  113. 'automark',
  114. 'mark',
  115. 'character',
  116. 'cleanpause',
  117. 'strict',
  118. 'structure',
  119. 'aria',
  120. 'pprint',
  121. 'cayleyshort',
  122. 'linebreaks'
  123. ];
  124. Engine.STRING_FEATURES = [
  125. 'markup',
  126. 'style',
  127. 'domain',
  128. 'speech',
  129. 'walker',
  130. 'defaultLocale',
  131. 'locale',
  132. 'delay',
  133. 'modality',
  134. 'rate',
  135. 'rules',
  136. 'subiso',
  137. 'prune'
  138. ];
  139. Engine.nodeEvaluator = function (_node) {
  140. return [];
  141. };
  142. export default Engine;
  143. function configFeature(feature) {
  144. if (typeof SREfeature !== 'undefined') {
  145. for (const [name, feat] of Object.entries(SREfeature)) {
  146. feature[name] = feat;
  147. }
  148. }
  149. }
  150. function configBlocks(feature) {
  151. const scripts = document.documentElement.querySelectorAll('script[type="text/x-sre-config"]');
  152. for (let i = 0, m = scripts.length; i < m; i++) {
  153. let inner;
  154. try {
  155. inner = scripts[i].innerHTML;
  156. const config = JSON.parse(inner);
  157. for (const [key, val] of Object.entries(config)) {
  158. feature[key] = val;
  159. }
  160. }
  161. catch (_err) {
  162. Debugger.getInstance().output('Illegal configuration ', inner);
  163. }
  164. }
  165. }
  166. export class EnginePromise {
  167. static get(locale = Engine.getInstance().locale) {
  168. return EnginePromise.promises[locale] || Promise.resolve('');
  169. }
  170. static getall() {
  171. return Promise.all(Object.values(EnginePromise.promises));
  172. }
  173. }
  174. EnginePromise.loaded = {};
  175. EnginePromise.promises = {};