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 JavaScript shim for the liblouis Native Client wrapper. | 6 * @fileoverview JavaScript shim for the liblouis Native Client wrapper. |
7 */ | 7 */ |
8 | 8 |
9 goog.provide('cvox.LibLouis'); | 9 goog.provide('cvox.LibLouis'); |
10 | 10 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 } | 67 } |
68 | 68 |
69 var embed = document.createElement('embed'); | 69 var embed = document.createElement('embed'); |
70 embed.src = this.nmfPath_; | 70 embed.src = this.nmfPath_; |
71 embed.type = 'application/x-nacl'; | 71 embed.type = 'application/x-nacl'; |
72 embed.width = 0; | 72 embed.width = 0; |
73 embed.height = 0; | 73 embed.height = 0; |
74 if (!goog.isNull(this.tablesDir_)) { | 74 if (!goog.isNull(this.tablesDir_)) { |
75 embed.setAttribute('tablesdir', this.tablesDir_); | 75 embed.setAttribute('tablesdir', this.tablesDir_); |
76 } | 76 } |
77 embed.addEventListener('load', goog.bind(this.onInstanceLoad_, this), | 77 embed.addEventListener( |
78 false /* useCapture */); | 78 'load', goog.bind(this.onInstanceLoad_, this), false /* useCapture */); |
79 embed.addEventListener('error', goog.bind(this.onInstanceError_, this), | 79 embed.addEventListener( |
80 false /* useCapture */); | 80 'error', goog.bind(this.onInstanceError_, this), false /* useCapture */); |
81 embed.addEventListener('message', goog.bind(this.onInstanceMessage_, this), | 81 embed.addEventListener( |
| 82 'message', goog.bind(this.onInstanceMessage_, this), |
82 false /* useCapture */); | 83 false /* useCapture */); |
83 elem.appendChild(embed); | 84 elem.appendChild(embed); |
84 this.embedElement_ = /** @type {!HTMLEmbedElement} */ (embed); | 85 this.embedElement_ = /** @type {!HTMLEmbedElement} */ (embed); |
85 }; | 86 }; |
86 | 87 |
87 | 88 |
88 /** | 89 /** |
89 * Detaches the Native Client instance from the DOM. | 90 * Detaches the Native Client instance from the DOM. |
90 */ | 91 */ |
91 cvox.LibLouis.prototype.detach = function() { | 92 cvox.LibLouis.prototype.detach = function() { |
(...skipping 25 matching lines...) Expand all Loading... |
117 * @param {string} tableNames Comma separated list of braille table names for | 118 * @param {string} tableNames Comma separated list of braille table names for |
118 * liblouis. | 119 * liblouis. |
119 * @param {function(cvox.LibLouis.Translator)} callback | 120 * @param {function(cvox.LibLouis.Translator)} callback |
120 * Callback which will receive the translator, or {@code null} on failure. | 121 * Callback which will receive the translator, or {@code null} on failure. |
121 */ | 122 */ |
122 cvox.LibLouis.prototype.getTranslator = function(tableNames, callback) { | 123 cvox.LibLouis.prototype.getTranslator = function(tableNames, callback) { |
123 if (!this.isAttached()) { | 124 if (!this.isAttached()) { |
124 callback(null /* translator */); | 125 callback(null /* translator */); |
125 return; | 126 return; |
126 } | 127 } |
127 this.rpc_('CheckTable', { 'table_names': tableNames }, function(reply) { | 128 this.rpc_('CheckTable', {'table_names': tableNames}, function(reply) { |
128 if (reply['success']) { | 129 if (reply['success']) { |
129 var translator = new cvox.LibLouis.Translator(this, tableNames); | 130 var translator = new cvox.LibLouis.Translator(this, tableNames); |
130 callback(translator); | 131 callback(translator); |
131 } else { | 132 } else { |
132 callback(null /* translator */); | 133 callback(null /* translator */); |
133 } | 134 } |
134 }.bind(this)); | 135 }.bind(this)); |
135 }; | 136 }; |
136 | 137 |
137 | 138 |
138 /** | 139 /** |
139 * Dispatches a message to the remote end and returns the reply asynchronously. | 140 * Dispatches a message to the remote end and returns the reply asynchronously. |
140 * A message ID will be automatically assigned (as a side-effect). | 141 * A message ID will be automatically assigned (as a side-effect). |
141 * @param {string} command Command name to be sent. | 142 * @param {string} command Command name to be sent. |
142 * @param {!Object} message JSONable message to be sent. | 143 * @param {!Object} message JSONable message to be sent. |
143 * @param {function(!Object)} callback Callback to receive the reply. | 144 * @param {function(!Object)} callback Callback to receive the reply. |
144 * @private | 145 * @private |
145 */ | 146 */ |
146 cvox.LibLouis.prototype.rpc_ = | 147 cvox.LibLouis.prototype.rpc_ = function(command, message, callback) { |
147 function(command, message, callback) { | |
148 if (!this.isAttached()) { | 148 if (!this.isAttached()) { |
149 throw Error('Cannot send RPC: liblouis instance not loaded'); | 149 throw Error('Cannot send RPC: liblouis instance not loaded'); |
150 } | 150 } |
151 var messageId = '' + this.nextMessageId_++; | 151 var messageId = '' + this.nextMessageId_++; |
152 message['message_id'] = messageId; | 152 message['message_id'] = messageId; |
153 message['command'] = command; | 153 message['command'] = command; |
154 var json = JSON.stringify(message); | 154 var json = JSON.stringify(message); |
155 if (cvox.LibLouis.DEBUG) { | 155 if (cvox.LibLouis.DEBUG) { |
156 window.console.debug('RPC -> ' + json); | 156 window.console.debug('RPC -> ' + json); |
157 } | 157 } |
(...skipping 28 matching lines...) Expand all Loading... |
186 * @param {Event} e Event dispatched after the message was posted. | 186 * @param {Event} e Event dispatched after the message was posted. |
187 * @private | 187 * @private |
188 */ | 188 */ |
189 cvox.LibLouis.prototype.onInstanceMessage_ = function(e) { | 189 cvox.LibLouis.prototype.onInstanceMessage_ = function(e) { |
190 if (cvox.LibLouis.DEBUG) { | 190 if (cvox.LibLouis.DEBUG) { |
191 window.console.debug('RPC <- ' + e.data); | 191 window.console.debug('RPC <- ' + e.data); |
192 } | 192 } |
193 var message = /** @type {!Object} */ (JSON.parse(e.data)); | 193 var message = /** @type {!Object} */ (JSON.parse(e.data)); |
194 var messageId = message['in_reply_to']; | 194 var messageId = message['in_reply_to']; |
195 if (!goog.isDef(messageId)) { | 195 if (!goog.isDef(messageId)) { |
196 window.console.warn('liblouis Native Client module sent message with no ID', | 196 window.console.warn( |
197 message); | 197 'liblouis Native Client module sent message with no ID', message); |
198 return; | 198 return; |
199 } | 199 } |
200 if (goog.isDef(message['error'])) { | 200 if (goog.isDef(message['error'])) { |
201 window.console.error('liblouis Native Client error', message['error']); | 201 window.console.error('liblouis Native Client error', message['error']); |
202 } | 202 } |
203 var callback = this.pendingRpcCallbacks_[messageId]; | 203 var callback = this.pendingRpcCallbacks_[messageId]; |
204 if (goog.isDef(callback)) { | 204 if (goog.isDef(callback)) { |
205 delete this.pendingRpcCallbacks_[messageId]; | 205 delete this.pendingRpcCallbacks_[messageId]; |
206 callback(message); | 206 callback(message); |
207 } | 207 } |
(...skipping 29 matching lines...) Expand all Loading... |
237 * Callback for result. Takes 3 parameters: the resulting cells, | 237 * Callback for result. Takes 3 parameters: the resulting cells, |
238 * mapping from text to braille positions and mapping from braille to | 238 * mapping from text to braille positions and mapping from braille to |
239 * text positions. If translation fails for any reason, all parameters are | 239 * text positions. If translation fails for any reason, all parameters are |
240 * {@code null}. | 240 * {@code null}. |
241 */ | 241 */ |
242 cvox.LibLouis.Translator.prototype.translate = function(text, callback) { | 242 cvox.LibLouis.Translator.prototype.translate = function(text, callback) { |
243 if (!this.instance_.isAttached()) { | 243 if (!this.instance_.isAttached()) { |
244 callback(null /*cells*/, null /*textToBraille*/, null /*brailleToText*/); | 244 callback(null /*cells*/, null /*textToBraille*/, null /*brailleToText*/); |
245 return; | 245 return; |
246 } | 246 } |
247 var message = { 'table_names': this.tableNames_, 'text': text }; | 247 var message = {'table_names': this.tableNames_, 'text': text}; |
248 this.instance_.rpc_('Translate', message, function(reply) { | 248 this.instance_.rpc_('Translate', message, function(reply) { |
249 var cells = null; | 249 var cells = null; |
250 var textToBraille = null; | 250 var textToBraille = null; |
251 var brailleToText = null; | 251 var brailleToText = null; |
252 if (reply['success'] && goog.isString(reply['cells'])) { | 252 if (reply['success'] && goog.isString(reply['cells'])) { |
253 cells = cvox.LibLouis.Translator.decodeHexString_(reply['cells']); | 253 cells = cvox.LibLouis.Translator.decodeHexString_(reply['cells']); |
254 if (goog.isDef(reply['text_to_braille'])) { | 254 if (goog.isDef(reply['text_to_braille'])) { |
255 textToBraille = reply['text_to_braille']; | 255 textToBraille = reply['text_to_braille']; |
256 } | 256 } |
257 if (goog.isDef(reply['braille_to_text'])) { | 257 if (goog.isDef(reply['braille_to_text'])) { |
258 brailleToText = reply['braille_to_text']; | 258 brailleToText = reply['braille_to_text']; |
259 } | 259 } |
260 } else if (text.length > 0) { | 260 } else if (text.length > 0) { |
261 // TODO(plundblad): The nacl wrapper currently returns an error | 261 // TODO(plundblad): The nacl wrapper currently returns an error |
262 // when translating an empty string. Address that and always log here. | 262 // when translating an empty string. Address that and always log here. |
263 console.error('Braille translation error for ' + JSON.stringify(message)); | 263 console.error('Braille translation error for ' + JSON.stringify(message)); |
264 } | 264 } |
265 callback(cells, textToBraille, brailleToText); | 265 callback(cells, textToBraille, brailleToText); |
266 }); | 266 }); |
267 }; | 267 }; |
268 | 268 |
269 | 269 |
270 /** | 270 /** |
271 * Translates braille cells into text. | 271 * Translates braille cells into text. |
272 * @param {!ArrayBuffer} cells Cells to be translated. | 272 * @param {!ArrayBuffer} cells Cells to be translated. |
273 * @param {function(?string)} callback Callback for result. | 273 * @param {function(?string)} callback Callback for result. |
274 */ | 274 */ |
275 cvox.LibLouis.Translator.prototype.backTranslate = | 275 cvox.LibLouis.Translator.prototype.backTranslate = function(cells, callback) { |
276 function(cells, callback) { | |
277 if (!this.instance_.isAttached()) { | 276 if (!this.instance_.isAttached()) { |
278 callback(null /*text*/); | 277 callback(null /*text*/); |
279 return; | 278 return; |
280 } | 279 } |
281 if (cells.byteLength == 0) { | 280 if (cells.byteLength == 0) { |
282 // liblouis doesn't handle empty input, so handle that trivially | 281 // liblouis doesn't handle empty input, so handle that trivially |
283 // here. | 282 // here. |
284 callback(''); | 283 callback(''); |
285 return; | 284 return; |
286 } | 285 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 */ | 324 */ |
326 cvox.LibLouis.Translator.encodeHexString_ = function(arrayBuffer) { | 325 cvox.LibLouis.Translator.encodeHexString_ = function(arrayBuffer) { |
327 var array = new Uint8Array(arrayBuffer); | 326 var array = new Uint8Array(arrayBuffer); |
328 var hex = ''; | 327 var hex = ''; |
329 for (var i = 0; i < array.length; i++) { | 328 for (var i = 0; i < array.length; i++) { |
330 var b = array[i]; | 329 var b = array[i]; |
331 hex += (b < 0x10 ? '0' : '') + b.toString(16); | 330 hex += (b < 0x10 ? '0' : '') + b.toString(16); |
332 } | 331 } |
333 return hex; | 332 return hex; |
334 }; | 333 }; |
OLD | NEW |