| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview An interface definition of a speech rule. | 6 * @fileoverview An interface definition of a speech rule. |
| 7 * | 7 * |
| 8 * A speech rule is a data structure along with supporting methods that | 8 * A speech rule is a data structure along with supporting methods that |
| 9 * stipulates how to transform a tree structure such as XML, a browser DOM, or | 9 * stipulates how to transform a tree structure such as XML, a browser DOM, or |
| 10 * HTML into a format (usually strings) suitable for rendering by a | 10 * HTML into a format (usually strings) suitable for rendering by a |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 /** | 47 /** |
| 48 * | 48 * |
| 49 * @override | 49 * @override |
| 50 */ | 50 */ |
| 51 cvox.SpeechRule.prototype.toString = function() { | 51 cvox.SpeechRule.prototype.toString = function() { |
| 52 var cstrStrings = []; | 52 var cstrStrings = []; |
| 53 for (var key in this.dynamicCstr) { | 53 for (var key in this.dynamicCstr) { |
| 54 cstrStrings.push(this.dynamicCstr[key]); | 54 cstrStrings.push(this.dynamicCstr[key]); |
| 55 } | 55 } |
| 56 return this.name + ' | ' + cstrStrings.join('.') + ' | ' + | 56 return this.name + ' | ' + cstrStrings.join('.') + ' | ' + |
| 57 this.precondition.toString() + ' ==> ' + | 57 this.precondition.toString() + ' ==> ' + this.action.toString(); |
| 58 this.action.toString(); | |
| 59 }; | 58 }; |
| 60 | 59 |
| 61 | 60 |
| 62 /** | 61 /** |
| 63 * Mapping for types of speech rule components. | 62 * Mapping for types of speech rule components. |
| 64 * @enum {string} | 63 * @enum {string} |
| 65 */ | 64 */ |
| 66 cvox.SpeechRule.Type = { | 65 cvox.SpeechRule.Type = { |
| 67 NODE: 'NODE', | 66 NODE: 'NODE', |
| 68 MULTI: 'MULTI', | 67 MULTI: 'MULTI', |
| 69 TEXT: 'TEXT', | 68 TEXT: 'TEXT', |
| 70 PERSONALITY: 'PERSONALITY' | 69 PERSONALITY: 'PERSONALITY' |
| 71 }; | 70 }; |
| 72 | 71 |
| 73 | 72 |
| 74 /** | 73 /** |
| 75 * Maps a string to a valid speech rule type. | 74 * Maps a string to a valid speech rule type. |
| 76 * @param {string} str Input string. | 75 * @param {string} str Input string. |
| 77 * @return {cvox.SpeechRule.Type} | 76 * @return {cvox.SpeechRule.Type} |
| 78 */ | 77 */ |
| 79 cvox.SpeechRule.Type.fromString = function(str) { | 78 cvox.SpeechRule.Type.fromString = function(str) { |
| 80 switch (str) { | 79 switch (str) { |
| 81 case '[n]': return cvox.SpeechRule.Type.NODE; | 80 case '[n]': |
| 82 case '[m]': return cvox.SpeechRule.Type.MULTI; | 81 return cvox.SpeechRule.Type.NODE; |
| 83 case '[t]': return cvox.SpeechRule.Type.TEXT; | 82 case '[m]': |
| 84 case '[p]': return cvox.SpeechRule.Type.PERSONALITY; | 83 return cvox.SpeechRule.Type.MULTI; |
| 85 default: throw 'Parse error: ' + str; | 84 case '[t]': |
| 85 return cvox.SpeechRule.Type.TEXT; |
| 86 case '[p]': |
| 87 return cvox.SpeechRule.Type.PERSONALITY; |
| 88 default: |
| 89 throw 'Parse error: ' + str; |
| 86 } | 90 } |
| 87 }; | 91 }; |
| 88 | 92 |
| 89 | 93 |
| 90 /** | 94 /** |
| 91 * Maps a speech rule type to a human-readable string. | 95 * Maps a speech rule type to a human-readable string. |
| 92 * @param {cvox.SpeechRule.Type} speechType | 96 * @param {cvox.SpeechRule.Type} speechType |
| 93 * @return {string} Output string. | 97 * @return {string} Output string. |
| 94 */ | 98 */ |
| 95 cvox.SpeechRule.Type.toString = function(speechType) { | 99 cvox.SpeechRule.Type.toString = function(speechType) { |
| 96 switch (speechType) { | 100 switch (speechType) { |
| 97 case cvox.SpeechRule.Type.NODE: return '[n]'; | 101 case cvox.SpeechRule.Type.NODE: |
| 98 case cvox.SpeechRule.Type.MULTI: return '[m]'; | 102 return '[n]'; |
| 99 case cvox.SpeechRule.Type.TEXT: return '[t]'; | 103 case cvox.SpeechRule.Type.MULTI: |
| 100 case cvox.SpeechRule.Type.PERSONALITY: return '[p]'; | 104 return '[m]'; |
| 101 default: throw 'Unknown type error: ' + speechType; | 105 case cvox.SpeechRule.Type.TEXT: |
| 106 return '[t]'; |
| 107 case cvox.SpeechRule.Type.PERSONALITY: |
| 108 return '[p]'; |
| 109 default: |
| 110 throw 'Unknown type error: ' + speechType; |
| 102 } | 111 } |
| 103 }; | 112 }; |
| 104 | 113 |
| 105 | 114 |
| 106 /** | 115 /** |
| 107 * Defines a component within a speech rule. | 116 * Defines a component within a speech rule. |
| 108 * @param {{type: cvox.SpeechRule.Type, content: string}} kwargs The input | 117 * @param {{type: cvox.SpeechRule.Type, content: string}} kwargs The input |
| 109 * component in JSON format. | 118 * component in JSON format. |
| 110 * @constructor | 119 * @constructor |
| 111 */ | 120 */ |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 case cvox.SpeechRule.Type.NODE: | 165 case cvox.SpeechRule.Type.NODE: |
| 157 case cvox.SpeechRule.Type.MULTI: | 166 case cvox.SpeechRule.Type.MULTI: |
| 158 var bracket = rest.indexOf(' ('); | 167 var bracket = rest.indexOf(' ('); |
| 159 if (bracket == -1) { | 168 if (bracket == -1) { |
| 160 output.content = rest.trim(); | 169 output.content = rest.trim(); |
| 161 rest = ''; | 170 rest = ''; |
| 162 break; | 171 break; |
| 163 } | 172 } |
| 164 output.content = rest.substring(0, bracket).trim(); | 173 output.content = rest.substring(0, bracket).trim(); |
| 165 rest = rest.slice(bracket).trimLeft(); | 174 rest = rest.slice(bracket).trimLeft(); |
| 166 break; | 175 break; |
| 167 } | 176 } |
| 168 output = new cvox.SpeechRule.Component(output); | 177 output = new cvox.SpeechRule.Component(output); |
| 169 if (rest) { | 178 if (rest) { |
| 170 output.addAttributes(rest); | 179 output.addAttributes(rest); |
| 171 } | 180 } |
| 172 return output; | 181 return output; |
| 173 }; | 182 }; |
| 174 | 183 |
| 175 | 184 |
| 176 /** | 185 /** |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 }; | 253 }; |
| 245 | 254 |
| 246 | 255 |
| 247 /** | 256 /** |
| 248 * Parses an input string into a speech rule class object. | 257 * Parses an input string into a speech rule class object. |
| 249 * @param {string} input The input string. | 258 * @param {string} input The input string. |
| 250 * @return {cvox.SpeechRule.Action} The resulting object. | 259 * @return {cvox.SpeechRule.Action} The resulting object. |
| 251 */ | 260 */ |
| 252 cvox.SpeechRule.Action.fromString = function(input) { | 261 cvox.SpeechRule.Action.fromString = function(input) { |
| 253 var comps = cvox.SpeechRule.splitString_(input, ';') | 262 var comps = cvox.SpeechRule.splitString_(input, ';') |
| 254 .filter(function(x) {return x.match(/\S/);}) | 263 .filter(function(x) { |
| 255 .map(function(x) {return x.trim();}); | 264 return x.match(/\S/); |
| 265 }) |
| 266 .map(function(x) { |
| 267 return x.trim(); |
| 268 }); |
| 256 var newComps = []; | 269 var newComps = []; |
| 257 for (var i = 0; i < comps.length; i++) { | 270 for (var i = 0; i < comps.length; i++) { |
| 258 var comp = cvox.SpeechRule.Component.fromString(comps[i]); | 271 var comp = cvox.SpeechRule.Component.fromString(comps[i]); |
| 259 if (comp) { | 272 if (comp) { |
| 260 newComps.push(comp); | 273 newComps.push(comp); |
| 261 } | 274 } |
| 262 } | 275 } |
| 263 return new cvox.SpeechRule.Action(newComps); | 276 return new cvox.SpeechRule.Action(newComps); |
| 264 }; | 277 }; |
| 265 | 278 |
| 266 | 279 |
| 267 /** | 280 /** |
| 268 * @override | 281 * @override |
| 269 */ | 282 */ |
| 270 cvox.SpeechRule.Action.prototype.toString = function() { | 283 cvox.SpeechRule.Action.prototype.toString = function() { |
| 271 var comps = this.components.map(function(c) { return c.toString(); }); | 284 var comps = this.components.map(function(c) { |
| 285 return c.toString(); |
| 286 }); |
| 272 return comps.join('; '); | 287 return comps.join('; '); |
| 273 }; | 288 }; |
| 274 | 289 |
| 275 | 290 |
| 276 // TODO (sorge) Separatation of xpath expressions and custom functions. | 291 // TODO (sorge) Separatation of xpath expressions and custom functions. |
| 277 // Also test validity of xpath expressions. | 292 // Also test validity of xpath expressions. |
| 278 /** | 293 /** |
| 279 * Constructs a valid precondition for a speech rule. | 294 * Constructs a valid precondition for a speech rule. |
| 280 * @param {string} query A node selector function or xpath expression. | 295 * @param {string} query A node selector function or xpath expression. |
| 281 * @param {Array<string>=} opt_constraints A list of constraint functions. | 296 * @param {Array<string>=} opt_constraints A list of constraint functions. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 while (str != '') { | 331 while (str != '') { |
| 317 var sepPos = str.search(sep); | 332 var sepPos = str.search(sep); |
| 318 if (sepPos == -1) { | 333 if (sepPos == -1) { |
| 319 if ((str.match(/"/g) || []).length % 2 != 0) { | 334 if ((str.match(/"/g) || []).length % 2 != 0) { |
| 320 throw new cvox.SpeechRule.OutputError( | 335 throw new cvox.SpeechRule.OutputError( |
| 321 'Invalid string in expression: ' + str); | 336 'Invalid string in expression: ' + str); |
| 322 } | 337 } |
| 323 strList.push(prefix + str); | 338 strList.push(prefix + str); |
| 324 prefix = ''; | 339 prefix = ''; |
| 325 str = ''; | 340 str = ''; |
| 326 } else if ( | 341 } else if ((str.substring(0, sepPos).match(/"/g) || []).length % 2 == 0) { |
| 327 (str.substring(0, sepPos).match(/"/g) || []).length % 2 == 0) { | |
| 328 strList.push(prefix + str.substring(0, sepPos)); | 342 strList.push(prefix + str.substring(0, sepPos)); |
| 329 prefix = ''; | 343 prefix = ''; |
| 330 str = str.substring(sepPos + 1); | 344 str = str.substring(sepPos + 1); |
| 331 } else { | 345 } else { |
| 332 var nextQuot = str.substring(sepPos).search('"'); | 346 var nextQuot = str.substring(sepPos).search('"'); |
| 333 if (nextQuot == -1) { | 347 if (nextQuot == -1) { |
| 334 throw new cvox.SpeechRule.OutputError( | 348 throw new cvox.SpeechRule.OutputError( |
| 335 'Invalid string in expression: ' + str); | 349 'Invalid string in expression: ' + str); |
| 336 } else { | 350 } else { |
| 337 prefix = prefix + str.substring(0, sepPos + nextQuot + 1); | 351 prefix = prefix + str.substring(0, sepPos + nextQuot + 1); |
| 338 str = str.substring(sepPos + nextQuot + 1); | 352 str = str.substring(sepPos + nextQuot + 1); |
| 339 } | 353 } |
| 340 } | 354 } |
| 341 } | 355 } |
| 342 if (prefix) { | 356 if (prefix) { |
| 343 strList.push(prefix); | 357 strList.push(prefix); |
| 344 } | 358 } |
| 345 return strList; | 359 return strList; |
| 346 }; | 360 }; |
| 347 | 361 |
| 348 | 362 |
| 349 /** | 363 /** |
| 350 * Attributes for dynamic constraints. | 364 * Attributes for dynamic constraints. |
| 351 * We define one default attribute as style. Speech rule stores can add other | 365 * We define one default attribute as style. Speech rule stores can add other |
| 352 * attributes later. | 366 * attributes later. |
| 353 * @enum {string} | 367 * @enum {string} |
| 354 */ | 368 */ |
| 355 cvox.SpeechRule.DynamicCstrAttrib = | 369 cvox.SpeechRule.DynamicCstrAttrib = { |
| 356 { | |
| 357 STYLE: 'style' | 370 STYLE: 'style' |
| 358 }; | 371 }; |
| 359 | 372 |
| 360 | 373 |
| 361 /** | 374 /** |
| 362 * Dynamic constraints are a means to specialize rules that can be changed | 375 * Dynamic constraints are a means to specialize rules that can be changed |
| 363 * dynamically by the user, for example by choosing different styles, etc. | 376 * dynamically by the user, for example by choosing different styles, etc. |
| 364 * @typedef {!Object<cvox.SpeechRule.DynamicCstrAttrib, string>} | 377 * @typedef {!Object<cvox.SpeechRule.DynamicCstrAttrib, string>} |
| 365 */ | 378 */ |
| 366 cvox.SpeechRule.DynamicCstr; | 379 cvox.SpeechRule.DynamicCstr; |
| 367 | 380 |
| 368 | 381 |
| 369 /** | 382 /** |
| 370 * Error object for signaling parsing errors. | 383 * Error object for signaling parsing errors. |
| 371 * @param {string} msg The error message. | 384 * @param {string} msg The error message. |
| 372 * @constructor | 385 * @constructor |
| 373 * @extends {Error} | 386 * @extends {Error} |
| 374 */ | 387 */ |
| 375 cvox.SpeechRule.OutputError = function(msg) { | 388 cvox.SpeechRule.OutputError = function(msg) { |
| 376 this.name = 'RuleError'; | 389 this.name = 'RuleError'; |
| 377 this.message = msg || ''; | 390 this.message = msg || ''; |
| 378 }; | 391 }; |
| 379 goog.inherits(cvox.SpeechRule.OutputError, Error); | 392 goog.inherits(cvox.SpeechRule.OutputError, Error); |
| OLD | NEW |