Home | History | Annotate | Download | only in messages
      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 Useful abstraction when  speaking messages.
      7  *
      8  * Usage:
      9  * $m('aria_role_link').withCount(document.links.length)
     10  * .andPause()
     11  * .andMessage('aria_role_forms')
     12  * .withCount(document.forms.length)
     13  * .andEnd()
     14  * .speakFlush();
     15  *
     16  */
     17 
     18 goog.provide('cvox.SpokenMessages');
     19 
     20 goog.require('cvox.AbstractTts');
     21 goog.require('cvox.ChromeVox');
     22 goog.require('cvox.SpokenMessage');
     23 
     24 /**
     25  * @type {Array}
     26  */
     27 cvox.SpokenMessages.messages = [];
     28 
     29 /**
     30  * Speaks the message chain and interrupts any on-going speech.
     31  */
     32 cvox.SpokenMessages.speakFlush = function() {
     33   cvox.SpokenMessages.speak(cvox.AbstractTts.QUEUE_MODE_FLUSH);
     34 };
     35 
     36 /**
     37  * Speaks the message chain after on-going speech finishes.
     38  */
     39 cvox.SpokenMessages.speakQueued = function() {
     40   cvox.SpokenMessages.speak(cvox.AbstractTts.QUEUE_MODE_QUEUE);
     41 };
     42 
     43 /**
     44  * Speak the message chain.
     45  * @param {number} mode The speech queue mode.
     46  */
     47 cvox.SpokenMessages.speak = function(mode) {
     48   for (var i = 0; i < cvox.SpokenMessages.messages.length; ++i) {
     49     var message = cvox.SpokenMessages.messages[i];
     50 
     51     // An invalid message format.
     52     if (!message || (!message.id && !message.raw))
     53       throw 'Invalid message received.';
     54 
     55     var finalText = '';
     56     if (message.count != null) {
     57       if (message.count <= 0) {
     58         try {
     59           finalText +=
     60               cvox.ChromeVox.msgs.getMsg(message.id[0] + '_optional_default');
     61         } catch(e) {
     62           // The message doesn't exist.
     63           continue;
     64         }
     65       } else if (message.count == 1) {
     66         finalText += cvox.ChromeVox.msgs.getMsg(message.id[0] + '_singular');
     67       } else {
     68         finalText += cvox.ChromeVox.msgs.getMsg(message.id[0] + '_plural',
     69                                                 [message.count]);
     70       }
     71     } else {
     72       if (message.raw) {
     73         finalText += message.raw;
     74       } else {
     75         finalText +=
     76             cvox.ChromeVox.msgs.getMsg.apply(cvox.ChromeVox.msgs, message.id);
     77       }
     78     }
     79 
     80     cvox.ChromeVox.tts.speak(finalText, mode,
     81                              cvox.AbstractTts.PERSONALITY_ANNOUNCEMENT);
     82 
     83     // Always queue after the first message.
     84     mode = cvox.AbstractTts.QUEUE_MODE_QUEUE;
     85   }
     86 
     87   cvox.SpokenMessages.messages = [];
     88 }
     89 
     90   /**
     91    * The newest message.
     92    * @return {cvox.SpokenMessage} The newest (current) message.
     93    */
     94 cvox.SpokenMessages.currentMessage = function() {
     95   if (cvox.SpokenMessages.messages.length == 0)
     96     throw 'Invalid usage of SpokenMessages; start the chain using $m()';
     97   return cvox.SpokenMessages.messages[cvox.SpokenMessages.messages.length - 1];
     98 };
     99 
    100 /**
    101  * Quantifies the current message.
    102  * This will modify the way the message gets read.
    103  * For example, if the count is 2, the message becomes pluralized according
    104  * to our i18n resources. The message "2 links" is a possible output.
    105  * @param {Number} count Quantifies current message.
    106  * @return {Object} This object, useful for chaining.
    107  */
    108 cvox.SpokenMessages.withCount = function(count) {
    109   cvox.SpokenMessages.currentMessage().count = count;
    110   return cvox.SpokenMessages;
    111 }
    112 
    113 /**
    114  * Quantifies the current message.
    115  * Modifies the message with a current index/total description (commonly seen
    116  * in lists).
    117  * @param {number} index The current item.
    118  * @param {number} total The total number of items.
    119  * @return {Object} This object, useful for chaining.
    120  */
    121 cvox.SpokenMessages.andIndexTotal = function(index, total) {
    122   var newMessage = new cvox.SpokenMessage();
    123   newMessage.raw = cvox.ChromeVox.msgs.getMsg('index_total', [index, total]);
    124   cvox.SpokenMessages.messages.push(newMessage);
    125   return cvox.SpokenMessages;
    126 }
    127 
    128 /**
    129  * Ends a message. with an appropriate marker.
    130  * @return {Object} This object, useful for chaining.
    131  */
    132 cvox.SpokenMessages.andEnd = function() {
    133   return cvox.SpokenMessages.andMessage('end');
    134 };
    135 
    136 /**
    137  * Adds a message.
    138  * @param {string|Array} messageId The id of the message.
    139  * @return {Object} This object, useful for chaining.
    140  */
    141 cvox.SpokenMessages.andMessage = function(messageId) {
    142   var newMessage = new cvox.SpokenMessage();
    143   newMessage.id = typeof(messageId) == 'string' ? [messageId] : messageId;
    144   cvox.SpokenMessages.messages.push(newMessage);
    145   return cvox.SpokenMessages;
    146 };
    147 
    148 
    149 /**
    150  * Adds a string as a message.
    151  * @param {string} message An already localized string.
    152  * @return {Object} This object, useful for chaining.
    153  */
    154 cvox.SpokenMessages.andRawMessage = function(message) {
    155   var newMessage = new cvox.SpokenMessage();
    156   newMessage.raw = message;
    157   cvox.SpokenMessages.messages.push(newMessage);
    158   return cvox.SpokenMessages;
    159 }
    160 
    161 /**
    162  * Pauses after the message, with an appropriate marker.
    163  * @return {Object} This object, useful for chaining.
    164  */
    165 cvox.SpokenMessages.andPause = function() {
    166   return cvox.SpokenMessages.andMessage('pause');
    167 };
    168 
    169 cvox.$m = cvox.SpokenMessages.andMessage;
    170