Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / speech_rules / math_store.js
blob4c33452b6b869712d6cc7e2e552420c313bdb195
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 /**
6  * @fileoverview Rule store for math syntax tree nodes.
7  */
9 goog.provide('cvox.MathStore');
11 goog.require('cvox.AbstractTts');
12 goog.require('cvox.BaseRuleStore');
13 goog.require('cvox.ChromeVox');
14 goog.require('cvox.NavMathDescription');
15 goog.require('cvox.SpeechRule');
16 goog.require('cvox.TraverseMath');
19 /**
20  * A store for Math rules.
21  * @constructor
22  * @extends {cvox.BaseRuleStore}
23  */
24 cvox.MathStore = function() {
25   goog.base(this);
27   /**
28    * @override
29    */
30   this.dynamicCstrAttribs = [
31     cvox.SpeechRule.DynamicCstrAttrib.DOMAIN,
32     cvox.SpeechRule.DynamicCstrAttrib.STYLE
33     ];
35   /**
36    * @override
37    */
38   this.defaultTtsProps = [cvox.AbstractTts.PITCH];
40 goog.inherits(cvox.MathStore, cvox.BaseRuleStore);
42 /** This adds domain to dynamic constraint annotation. */
43 cvox.SpeechRule.DynamicCstrAttrib.DOMAIN = 'domain';
46 /**
47  * @override
48  */
49 cvox.MathStore.prototype.defineRule = function(
50     name, dynamic, action, query, cstr) {
51   var dynamicCstr = this.parseDynamicConstraint(dynamic);
52   var cstrList = Array.prototype.slice.call(arguments, 4);
53   // We can not use goog.base due to variable number of constraint arguments.
54   var rule = cvox.MathStore.superClass_.defineRule.apply(
55       this, [name, dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.STYLE],
56              action, query].concat(cstrList));
57   // In the superclass the dynamic constraint only contains style annotations.
58   // We now set the proper dynamic constraint that contains in addition a
59   // a domain attribute/value pair.
60   rule.dynamicCstr = dynamicCstr;
61   this.removeDuplicates(rule);
62   return rule;
66 /**
67  * Parses the dynamic constraint for math rules, consisting of a domain and
68  * style information, given as 'domain.style'.
69  * @param {string} cstr A string representation of the dynamic constraint.
70  * @return {!cvox.SpeechRule.DynamicCstr} The dynamic constraint.
71  */
72 cvox.MathStore.prototype.parseDynamicConstraint = function(cstr) {
73   var domainStyle = cstr.split('.');
74   if (!domainStyle[0] || !domainStyle[1]) {
75     throw new cvox.SpeechRule.OutputError('Invalid domain assignment:' + cstr);
76   }
77   return cvox.MathStore.createDynamicConstraint(domainStyle[0], domainStyle[1]);
81 /**
82  * Creates a dynamic constraint annotation for math rules from domain and style
83  * values.
84  * @param {string} domain Domain annotation.
85  * @param {string} style Style annotation.
86  * @return {!cvox.SpeechRule.DynamicCstr}
87  */
88 cvox.MathStore.createDynamicConstraint = function(domain, style) {
89   var dynamicCstr = {};
90   dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.DOMAIN] = domain;
91   dynamicCstr[cvox.SpeechRule.DynamicCstrAttrib.STYLE] = style;
92   return dynamicCstr;
96 /**
97  * Adds an alias for an existing rule.
98  * @param {string} name The name of the rule.
99  * @param {string} dynamic A math domain and style assignment.
100  * @param {string} query Precondition query of the rule.
101  * @param {...string} cstr Additional static precondition constraints.
102  */
103 cvox.MathStore.prototype.defineUniqueRuleAlias = function(
104     name, dynamic, query, cstr) {
105   var dynamicCstr = this.parseDynamicConstraint(dynamic);
106   var rule = this.findRule(
107     goog.bind(
108       function(rule) {
109         return rule.name == name &&
110           this.testDynamicConstraints(dynamicCstr, rule);},
111       this));
112   if (!rule) {
113     throw new cvox.SpeechRule.OutputError(
114         'Rule named ' + name + ' with style ' + dynamic + ' does not exist.');
115   }
116   this.addAlias_(rule, query, Array.prototype.slice.call(arguments, 3));
121  * Adds an alias for an existing rule.
122  * @param {string} name The name of the rule.
123  * @param {string} query Precondition query of the rule.
124  * @param {...string} cstr Additional static precondition constraints.
125  */
126 cvox.MathStore.prototype.defineRuleAlias = function(name, query, cstr) {
127   var rule = this.findRule(function(rule) {
128     return rule.name == name;});
129   if (!rule) {
130     throw new cvox.SpeechRule.OutputError(
131       'Rule with named ' + name + ' does not exist.');
132     }
133   this.addAlias_(rule, query, Array.prototype.slice.call(arguments, 2));
138  * Adds an alias for an existing rule.
139  * @param {string} name The name of the rule.
140  * @param {string} query Precondition query of the rule.
141  * @param {...string} cstr Additional static precondition constraints.
142  */
143 cvox.MathStore.prototype.defineRulesAlias = function(name, query, cstr) {
144   var rules = this.findAllRules(function(rule) {return rule.name == name;});
145   if (rules.length == 0) {
146     throw new cvox.SpeechRule.OutputError(
147         'Rule with name ' + name + ' does not exist.');
148   }
149   var cstrList = Array.prototype.slice.call(arguments, 2);
150   rules.forEach(goog.bind(
151                   function(rule) {
152                     this.addAlias_(rule, query, cstrList);
153                   },
154                   this));
159  * Adds a new speech rule as alias of the given rule.
160  * @param {cvox.SpeechRule} rule The existing rule.
161  * @param {string} query Precondition query of the rule.
162  * @param {Array<string>} cstrList List of additional constraints.
163  * @private
164  */
165 cvox.MathStore.prototype.addAlias_ = function(rule, query, cstrList) {
166   var prec = new cvox.SpeechRule.Precondition(query, cstrList);
167   var newRule = new cvox.SpeechRule(
168       rule.name, rule.dynamicCstr, prec, rule.action);
169   newRule.name = rule.name;
170   this.addRule(newRule);
174 // Evaluator
176  * @override
177  */
178 cvox.MathStore.prototype.evaluateDefault = function(node) {
179   return this.evaluateString_(node.textContent);
184  * Evaluates a single string of a math expressions. The method splits the given
185  * string into components such as single characters, function names or words,
186  * numbers, etc. and creates the appropriate navigation descriptions.
187  * @param {string} str A string.
188  * @return {!Array<cvox.NavDescription>} Messages for the math expression.
189  * @private
190  */
191 cvox.MathStore.prototype.evaluateString_ = function(str) {
192   var descs = new Array();
193   if (str.match(/^\s+$/)) {
194     // Nothing but whitespace: Ignore.
195     return descs;
196   }
197   var split = cvox.MathStore.removeEmpty_(str.replace(/\s/g, ' ').split(' '));
198   for (var i = 0, s; s = split[i]; i++) {
199     if (s.length == 1) {
200       descs.push(this.evaluate_(s));
201     } else if (s.match(/^[a-zA-Z]+$/)) {
202       descs.push(this.evaluate_(s));
203     } else {
204       // Break up string even further wrt. symbols vs alphanum substrings.
205       var rest = s;
206       var count = 0;
207       while (rest) {
208         var num = rest.match(/^\d+/);
209         var alpha = rest.match(/^[a-zA-Z]+/);
210         if (num) {
211           descs.push(this.evaluate_(num[0]));
212           rest = rest.substring(num[0].length);
213         } else if (alpha) {
214           descs.push(this.evaluate_(alpha[0]));
215           rest = rest.substring(alpha[0].length);
216         } else {
217           // Dealing with surrogate pairs.
218           var chr = rest[0];
219           var code = chr.charCodeAt(0);
220           if (0xD800 <= code && code <= 0xDBFF &&
221               rest.length > 1 && !isNaN(rest.charCodeAt(1))) {
222             descs.push(this.evaluate_(rest.slice(0, 2)));
223             rest = rest.substring(2);
224           } else {
225             descs.push(this.evaluate_(rest[0]));
226             rest = rest.substring(1);
227             }
228         }
229       }
230     }
231   }
232   return descs;
237  * Creates a new Navigation Description for a math expression that be used by
238  * the background tts.
239  * @param {string} text to be translated.
240  * @return {cvox.NavDescription} Navigation description for the
241  *     math expression.
242  * @private
243  */
244 cvox.MathStore.prototype.evaluate_ = function(text) {
245   if (cvox.ChromeVox.host['mathMap']) {
246     // VS: Change this for android!
247     return cvox.ChromeVox.host['mathMap'].evaluate(
248         text,
249         cvox.TraverseMath.getInstance().domain,
250         cvox.TraverseMath.getInstance().style);
251   }
252   return new cvox.NavMathDescription(
253       {'text': text,
254        'domain': cvox.TraverseMath.getInstance().domain,
255        'style': cvox.TraverseMath.getInstance().style
256       });
261  * Removes all empty strings from an array of strings.
262  * @param {Array<string>} strs An array of strings.
263  * @return {Array<string>} The cleaned array.
264  * @private
265  */
266 cvox.MathStore.removeEmpty_ = function(strs) {
267   return strs.filter(function(str) {return str;});