blob: 65057285d5286fe71fddb5e0af361961098e6624 [file] [log] [blame]
[email protected]fa84b0d2014-08-07 07:06:181// 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'use strict';
6
7/**
8 * Constructor for the Nacl bridge to the whispernet wrapper.
9 * @param {string} nmf The relative path to the nmf containing the location of
10 * the whispernet Nacl wrapper.
11 * @param {function()} readyCallback Callback to be called once we've loaded the
12 * whispernet wrapper.
13 */
14function NaclBridge(nmf, readyCallback) {
15 this.readyCallback_ = readyCallback;
16 this.callbacks_ = [];
17 this.isEnabled_ = false;
18 this.naclId_ = this.loadNacl_(nmf);
19}
20
21/**
22 * Method to send generic byte data to the whispernet wrapper.
23 * @param {string} data Raw data to send to the whispernet wrapper.
24 */
25NaclBridge.prototype.send = function(data) {
26 if (this.isEnabled_) {
27 this.embed_.postMessage(data);
28 } else {
29 console.error('Whisper Nacl Bridge not initialized!');
30 }
31};
32
33/**
34 * Method to add a listener to Nacl messages received by this bridge.
35 * @param {function(Event)} messageCallback Callback to receive the messsage.
36 */
37NaclBridge.prototype.addListener = function(messageCallback) {
38 this.callbacks_.push(messageCallback);
39};
40
41/**
42 * Method that receives Nacl messages and forwards them to registered
43 * callbacks.
44 * @param {Event} e Event from the whispernet wrapper.
45 * @private
46 */
47NaclBridge.prototype.onMessage_ = function(e) {
48 if (this.isEnabled_) {
49 this.callbacks_.forEach(function(callback) {
50 callback(e);
51 });
52 }
53};
54
55/**
56 * Injects the <embed> for this nacl manifest URL, generating a unique ID.
57 * @param {string} manifestUrl Url to the nacl manifest to load.
58 * @return {number} generated ID.
59 * @private
60 */
61NaclBridge.prototype.loadNacl_ = function(manifestUrl) {
62 var id = 'nacl-' + Math.floor(Math.random() * 10000);
63 this.embed_ = document.createElement('embed');
64 this.embed_.name = 'nacl_module';
65 this.embed_.width = 1;
66 this.embed_.height = 1;
67 this.embed_.src = manifestUrl;
68 this.embed_.id = id;
69 this.embed_.type = 'application/x-pnacl';
70
71 // Wait for the element to load and callback.
72 this.embed_.addEventListener('load', this.onNaclReady_.bind(this));
73 this.embed_.addEventListener('error', this.onNaclError_.bind(this));
74
75 // Inject the embed string into the page.
76 document.body.appendChild(this.embed_);
77
78 // Listen for messages from the NaCl module.
79 window.addEventListener('message', this.onMessage_.bind(this), true);
80 return id;
81};
82
83/**
84 * Callback that is called when the Whispernet wrapper is loaded and forward
85 * that status to the callback registered with us in the constructor.
86 * @private
87 */
88NaclBridge.prototype.onNaclReady_ = function() {
89 if (this.readyCallback_)
90 this.readyCallback_();
91 this.isEnabled_ = true;
92};
93
94/**
95 * Callback that handles Nacl errors.
96 * @param {string} msg Error string.
97 * @private
98 */
99NaclBridge.prototype.onNaclError_ = function(msg) {
100 // TODO(rkc): Handle error from NaCl better.
101 console.error('NaCl error', msg);
102};