nav_description.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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.
4
5/**
6 * @fileoverview A simple container object for the description of a
7 * navigation from one object to another.
8 *
9 */
10
11
12goog.provide('cvox.NavDescription');
13
14goog.require('cvox.AbstractTts');
15goog.require('cvox.ChromeVox');
16goog.require('cvox.CursorSelection');
17
18/**
19 * A class representing the description of navigation from one object to
20 * another.
21 * @param {{context: (undefined|string),
22 *          text: (string),
23 *          userValue: (undefined|string),
24 *          annotation: (undefined|string),
25 *          earcons: (undefined|Array.<number>),
26 *          personality: (undefined|Object),
27 *          hint: (undefined|string)}} kwargs The arguments for this
28 *  description.
29 *  context The context, for example descriptions of objects
30 *     that were crossed into, like "Toolbar" or "Menu Bar" or "List with
31 *     5 items". This is all spoken with an annotation voice.
32 *  text The text of the object itself, including text from
33 *     titles, labels, etc.
34 *  userValue The text that the user has entered.
35 *  annotation The role and state of the object.
36 *  earcons A list of the earcon ids to play along
37 *     with the spoken description of this object.
38 *  personality Optional TTS personality to use for the text.
39 *  hint Optional Hint text (.e.g. aria-describedby).
40 * @constructor
41 */
42cvox.NavDescription = function(kwargs) {
43  this.context = kwargs.context ? kwargs.context : '';
44  this.text = kwargs.text ? kwargs.text : '';
45  this.userValue = kwargs.userValue ? kwargs.userValue : '';
46  this.annotation = kwargs.annotation ? kwargs.annotation : '';
47  this.earcons = kwargs.earcons ? kwargs.earcons : [];
48  this.personality = kwargs.personality;
49  this.hint = kwargs.hint ? kwargs.hint : '';
50};
51
52
53/**
54 * @return {boolean} true if this description is empty.
55 */
56cvox.NavDescription.prototype.isEmpty = function() {
57  return (this.context.length == 0 &&
58          this.earcons.length == 0 &&
59          this.text.length == 0 &&
60          this.userValue.length == 0 &&
61          this.annotation.length == 0);
62};
63
64
65/**
66 * @return {string} A string representation of this object.
67 */
68cvox.NavDescription.prototype.toString = function() {
69  return 'NavDescription(context="' + this.context + '" ' +
70         ' text="' + this.text + '" ' +
71         ' userValue="' + this.userValue + '" ' +
72         ' annotation="' + this.annotation + '")';
73};
74
75
76/**
77 * Modifies the earcon to play along with the spoken description of the object.
78 * @param {number} earconId An earcon id to be pushed on to the list of earcon
79 * ids to play along with the spoken description of this object.
80 */
81cvox.NavDescription.prototype.pushEarcon = function(earconId) {
82  this.earcons.push(earconId);
83};
84
85
86/**
87 * Speak this nav description with the given queue mode.
88 * @param {number=} queueMode The queue mode: cvox.AbstractTts.QUEUE_MODE_FLUSH
89 *     for flush, cvox.AbstractTts.QUEUE_MODE_QUEUE for adding to queue.
90 * @param {function()=} startCallback Function called when this starts speaking.
91 * @param {function()=} endCallback Function called when this ends speaking.
92 */
93cvox.NavDescription.prototype.speak = function(
94    queueMode, startCallback, endCallback) {
95  /**
96   * Return a deep copy of PERSONALITY_ANNOTATION for modifying.
97   * @return {Object} The newly created properties object.
98   */
99  function makeAnnotationProps() {
100    var properties = {};
101    var src = cvox.AbstractTts.PERSONALITY_ANNOTATION;
102    for (var key in src) {
103      properties[key] = src[key];
104    }
105    return properties;
106  }
107
108  var speakArgs = new Array();
109  if (this.context) {
110    speakArgs.push([this.context, queueMode, makeAnnotationProps()]);
111    queueMode = 1;
112  }
113
114  speakArgs.push([this.text,
115                  queueMode,
116                  this.personality ? this.personality : {}]);
117  queueMode = 1;
118
119  if (this.userValue) {
120    speakArgs.push([this.userValue, queueMode, {}]);
121  }
122
123  if (this.annotation) {
124    speakArgs.push([this.annotation, queueMode, makeAnnotationProps()]);
125  }
126
127  if (this.hint) {
128    speakArgs.push([this.hint, queueMode, makeAnnotationProps()]);
129  }
130
131  var length = speakArgs.length;
132  for (var i = 0; i < length; i++) {
133    if (i == 0 && startCallback) {
134      speakArgs[i][2]['startCallback'] = startCallback;
135    }
136    if (i == length - 1 && endCallback) {
137      speakArgs[i][2]['endCallback'] = endCallback;
138    }
139    cvox.ChromeVox.tts.speak.apply(cvox.ChromeVox.tts, speakArgs[i]);
140  }
141};
142
143
144/**
145 * Compares two NavDescriptions.
146 * @param {cvox.NavDescription} that A NavDescription.
147 * @return {boolean} True if equal.
148 */
149cvox.NavDescription.prototype.equals = function(that) {
150  return this.context == that.context &&
151      this.text == that.text &&
152      this.userValue == that.userValue &&
153      this.annotation == that.annotation;
154};
155