Add ICU message format support
[chromium-blink-merge.git] / native_client_sdk / src / gonacl_appengine / static / bullet / NaClAM.js
blobee59a5ea63d829d4db241223d2c896b197ea6b1f
1 // Copyright (c) 2013 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 function NaClAMMessage() {
6 this.header = {};
7 this.frames = new Array();
10 NaClAMMessage.prototype.reset = function() {
11 this.header = {};
12 this.frames = new Array();
15 function NaClAM(embedId) {
16 this.embedId = embedId;
17 this.requestId = 0;
18 this.message = new NaClAMMessage();
19 this.state = 0;
20 this.framesLeft = 0;
21 this.listeners_ = Object.create(null);
22 this.handleMesssage_ = this.handleMesssage_.bind(this);
25 NaClAM.prototype.enable = function() {
26 window.addEventListener('message', this.handleMesssage_, true);
29 NaClAM.prototype.disable = function() {
30 window.removeEventListener('message', this.handleMesssage_, true);
33 NaClAM.prototype.log_ = function(msg) {
34 console.log(msg);
37 NaClAM.prototype.handleMesssage_ = function(event) {
38 var STATE_WAITING_FOR_HEADER = 0;
39 var STATE_COLLECTING_FRAMES = 1;
40 if (this.state == STATE_WAITING_FOR_HEADER) {
41 var header;
42 try {
43 header = JSON.parse(String(event.data));
44 } catch (e) {
45 console.log(e);
46 console.log(event.data);
47 return;
49 // Special case our log print command
50 if (header['cmd'] == 'NaClAMPrint') {
51 this.log_(header['print'])
52 return;
54 if (typeof(header['request']) != "number") {
55 console.log('Header message requestId is not a number.');
56 return;
58 if (typeof(header['frames']) != "number") {
59 console.log('Header message frames is not a number.');
60 return;
62 this.framesLeft = header['frames'];
63 this.state = STATE_COLLECTING_FRAMES;
64 this.message.header = header;
65 } else if (this.state == STATE_COLLECTING_FRAMES) {
66 this.framesLeft--;
67 this.message.frames.push(event.data);
69 if (this.state == STATE_COLLECTING_FRAMES && this.framesLeft == 0) {
70 this.dispatchEvent(this.message);
71 this.message.reset();
72 this.state = STATE_WAITING_FOR_HEADER;
76 NaClAM.prototype.messageHeaderIsValid_ = function(header) {
77 if (header['cmd'] == undefined) {
78 console.log('NaClAM: Message header does not contain cmd.');
79 return false;
81 if (typeof(header['cmd']) != "string") {
82 console.log('NaClAm: Message cmd is not a string.');
83 return false;
85 if (header['frames'] == undefined) {
86 console.log('NaClAM: Message header does not contain frames.');
87 return false;
89 if (typeof(header['frames']) != "number") {
90 console.log('NaClAm: Message frames is not a number.');
91 return false;
93 if (header['request'] == undefined) {
94 console.log('NaClAM: Message header does not contain request.');
95 return false;
97 if (typeof(header['request']) != "number") {
98 console.log('NaClAm: Message request is not a number.');
99 return false;
101 return true;
104 NaClAM.prototype.framesIsValid_ = function(frames) {
105 var i;
106 if (!frames) {
107 // No frames.
108 return true;
110 if (Array.isArray(frames) == false) {
111 console.log('NaClAM: Frames must be an array.');
112 return false;
114 for (i = 0; i < frames.length; i++) {
115 var e = frames[i];
116 if (typeof(e) == "string") {
117 continue;
119 if ((e instanceof ArrayBuffer) == false) {
120 console.log('NaClAM: Frame is not a string or ArrayBuffer');
121 return false;
124 return true;
127 NaClAM.prototype.framesLength_ = function(frames) {
128 if (!frames) {
129 // No frames.
130 return 0;
132 return frames.length;
135 NaClAM.prototype.sendMessage = function(cmdName, arguments, frames) {
136 if (this.framesIsValid_(frames) == false) {
137 console.log('NaClAM: Not sending message because frames is invalid.');
138 return undefined;
140 var numFrames = this.framesLength_(frames);
141 this.requestId++;
142 var msgHeader = {
143 cmd: cmdName,
144 frames: numFrames,
145 request: this.requestId,
146 args: arguments
148 if (this.messageHeaderIsValid_(msgHeader) == false) {
149 console.log('NaClAM: Not sending message because header is invalid.');
150 return undefined;
152 var AM = document.getElementById(this.embedId);
153 if (!AM) {
154 console.log('NaClAM: Not sending message because Acceleration Module is not there.');
155 return undefined;
157 AM.postMessage(JSON.stringify(msgHeader));
158 var i;
159 for (i = 0; i < numFrames; i++) {
160 AM.postMessage(frames[i]);
162 return this.requestId;
166 * Adds an event listener to this Acceleration Module.
167 * @param {string} type The name of the command.
168 * @param handler The handler for the cmomand. This is called whenever the command is received.
170 NaClAM.prototype.addEventListener = function(type, handler) {
171 if (!this.listeners_) {
172 this.listeners_ = Object.create(null);
174 if (!(type in this.listeners_)) {
175 this.listeners_[type] = [handler];
176 } else {
177 var handlers = this.listeners_[type];
178 if (handlers.indexOf(handler) < 0) {
179 handlers.push(handler);
185 * Removes an event listener from this Acceleration Module.
186 * @param {string} type The name of the command.
187 * @param handler The handler for the cmomand. This is called whenever the command is received.
189 NaClAM.prototype.removeEventListener = function(type, handler) {
190 if (!this.listeners_) {
191 // No listeners
192 return;
194 if (type in this.listeners_) {
195 var handlers = this.listeners_[type];
196 var index = handlers.indexOf(handler);
197 if (index >= 0) {
198 if (handlers.length == 1) {
199 // Listeners list would be empty, delete it
200 delete this.listeners_[type];
201 } else {
202 // Remove the handler
203 handlers.splice(index, 1);
212 NaClAM.prototype.dispatchEvent = function(event) {
213 if (!this.listeners_) {
214 return true;
216 var type = event.header.cmd;
217 if (type in this.listeners_) {
218 // Make a copy to walk over
219 var handlers = this.listeners_[type].concat();
220 for (var i = 0, handler; handler = handlers[i]; i++) {
221 handler.call(this, event);