Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / braille / braille_translator_manager.js
blob2a152b228372ae2e03701b77057e5dd1556c14f2
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 Keeps track of the current braille translators.
7  */
9 goog.provide('cvox.BrailleTranslatorManager');
11 goog.require('cvox.BrailleTable');
12 goog.require('cvox.ExpandingBrailleTranslator');
13 goog.require('cvox.LibLouis');
15 /**
16  * @param {cvox.LibLouis=} opt_liblouisForTest Liblouis instance to use
17  *     for testing.
18  * @constructor
19  */
20 cvox.BrailleTranslatorManager = function(opt_liblouisForTest) {
21   /**
22    * @type {!cvox.LibLouis}
23    * @private
24    */
25   this.liblouis_ = opt_liblouisForTest || new cvox.LibLouis(
26       chrome.extension.getURL('braille/liblouis_nacl.nmf'),
27       chrome.extension.getURL('braille/tables'));
28   /**
29    * @type {!Array<function()>}
30    * @private
31    */
32   this.changeListeners_ = [];
33   /**
34    * @type {!Array<cvox.BrailleTable.Table>}
35    * @private
36    */
37   this.tables_ = [];
38   /**
39    * @type {cvox.ExpandingBrailleTranslator}
40    * @private
41    */
42   this.expandingTranslator_ = null;
43   /**
44    * @type {cvox.LibLouis.Translator}
45    * @private
46    */
47   this.defaultTranslator_ = null;
48   /**
49    * @type {string?}
50    * @private
51    */
52   this.defaultTableId_ = null;
53   /**
54    * @type {cvox.LibLouis.Translator}
55    * @private
56    */
57   this.uncontractedTranslator_ = null;
58   /**
59    * @type {string?}
60    * @private
61    */
62   this.uncontractedTableId_ = null;
64   if (!opt_liblouisForTest) {
65     document.addEventListener('DOMContentLoaded',
66                               this.loadLiblouis_.bind(this),
67                               false);
68   }
71 cvox.BrailleTranslatorManager.prototype = {
72   /**
73    * Adds a listener to be called whenever there is a change in the
74    * translator(s) returned by other methods of this instance.
75    * @param {function()} listener The listener.
76    */
77   addChangeListener: function(listener) {
78     this.changeListeners_.push(listener);
79   },
81   /**
82    * Refreshes the braille translator(s) used for input and output.  This
83    * should be called when something has changed (such as a preference) to
84    * make sure that the correct translator is used.
85    */
86   refresh: function() {
87     var tables = this.tables_;
88     if (tables.length == 0)
89       return;
91     // First, see if we have a braille table set previously.
92     var table = cvox.BrailleTable.forId(tables, localStorage['brailleTable']);
93     if (!table) {
94       // Match table against current locale.
95       var currentLocale = chrome.i18n.getMessage('@@ui_locale').split(/[_-]/);
96       var major = currentLocale[0];
97       var minor = currentLocale[1];
98       var firstPass = tables.filter(function(table) {
99         return table.locale.split(/[_-]/)[0] == major;
100       });
101       if (firstPass.length > 0) {
102         table = firstPass[0];
103         if (minor) {
104           var secondPass = firstPass.filter(function(table) {
105             return table.locale.split(/[_-]/)[1] == minor;
106           });
107           if (secondPass.length > 0)
108             table = secondPass[0];
109         }
110       }
111     }
112     if (!table)
113       table = cvox.BrailleTable.forId(tables, 'en-US-comp8');
115     // TODO(plundblad): Only update when user explicitly selects a table
116     // so that switching locales changes table by default.  crbug.com/441206.
117     localStorage['brailleTable'] = table.id;
118     if (!localStorage['brailleTable6'])
119       localStorage['brailleTable6'] = 'en-US-g1';
120     if (!localStorage['brailleTable8'])
121       localStorage['brailleTable8'] = 'en-US-comp8';
123     if (table.dots == '6') {
124       localStorage['brailleTableType'] = 'brailleTable6';
125       localStorage['brailleTable6'] = table.id;
126     } else {
127       localStorage['brailleTableType'] = 'brailleTable8';
128       localStorage['brailleTable8'] = table.id;
129     }
131     // If the user explicitly set an 8 dot table, use that when looking
132     // for an uncontracted table.  Otherwise, use the current table and let
133     // getUncontracted find an appropriate corresponding table.
134     var table8Dot = cvox.BrailleTable.forId(tables,
135                                             localStorage['brailleTable8']);
136     var uncontractedTable = cvox.BrailleTable.getUncontracted(
137         tables, table8Dot || table);
139     var newDefaultTableId = table.id;
140     var newUncontractedTableId = table.id === uncontractedTable.id ?
141         null : uncontractedTable.id;
142     if (newDefaultTableId === this.defaultTableId_ &&
143         newUncontractedTableId === this.uncontractedTableId_) {
144       return;
145     }
147     var finishRefresh = function(defaultTranslator, uncontractedTranslator) {
148       this.defaultTableId_ = newDefaultTableId;
149       this.uncontractedTableId_ = newUncontractedTableId;
150       this.expandingTranslator_ = new cvox.ExpandingBrailleTranslator(
151           defaultTranslator, uncontractedTranslator);
152       this.defaultTranslator_ = defaultTranslator;
153       this.uncontractedTranslator_ = uncontractedTranslator;
154       this.changeListeners_.forEach(function(listener) { listener(); });
155     }.bind(this);
157     this.liblouis_.getTranslator(table.fileNames, function(translator) {
158       if (!newUncontractedTableId) {
159         finishRefresh(translator, null);
160       } else {
161         this.liblouis_.getTranslator(
162             uncontractedTable.fileNames,
163             function(uncontractedTranslator) {
164               finishRefresh(translator, uncontractedTranslator);
165             });
166           }
167     }.bind(this));
168   },
170   /**
171    * @return {cvox.ExpandingBrailleTranslator} The current expanding braille
172    *     translator, or {@code null} if none is available.
173    */
174   getExpandingTranslator: function() {
175     return this.expandingTranslator_;
176   },
178   /**
179    * @return {cvox.LibLouis.Translator} The current braille translator to use
180    *     by default, or {@code null} if none is available.
181    */
182   getDefaultTranslator: function() {
183     return this.defaultTranslator_;
184   },
186   /**
187    * @return {cvox.LibLouis.Translator} The current uncontracted braille
188    *     translator, or {@code null} if it is the same as the default
189    *     translator.
190    */
191   getUncontractedTranslator: function() {
192     return this.uncontractedTranslator_;
193   },
195   /**
196    * Asynchronously fetches the list of braille tables and refreshes the
197    * translators when done.
198    * @private
199    */
200   fetchTables_: function() {
201     cvox.BrailleTable.getAll(function(tables) {
202       this.tables_ = tables;
203       this.refresh();
204     }.bind(this));
205   },
207   /**
208    * Loads the liblouis instance by attaching it to the document.
209    * @private
210    */
211   loadLiblouis_: function() {
212     // Cast away nullability.  When the document is loaded, it will always
213     // have a body.
214     this.liblouis_.attachToElement(
215         /** @type {!HTMLBodyElement} */ (document.body));
216     this.fetchTables_();
217   },
219   /**
220    * @return {!cvox.LibLouis} The liblouis instance used by this object.
221    */
222   getLibLouisForTest: function() {
223     return this.liblouis_;
224   },
226   /**
227    * @return {!Array<cvox.BrailleTable.Table>} The currently loaded braille
228    *     tables, or an empty array if they are not yet loaded.
229    */
230   getTablesForTest: function() {
231     return this.tables_;
232   }