1 // Copyright (c) 2012 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 moduleDidLoad() {
10 return document.getElementById(id);
13 // Called by the common.js module.
14 function domContentLoaded(name, tc, config, width, height) {
15 navigator.webkitPersistentStorage.requestQuota(1024 * 1024,
18 'Allocated ' + bytes + ' bytes of persistant storage.');
19 common.attachDefaultListeners();
20 common.createNaClModule(name, tc, config, width, height);
22 function(e) { alert('Failed to allocate space') });
25 // Called by the common.js module.
26 function attachListeners() {
27 var radioEls = document.querySelectorAll('input[type="radio"]');
28 for (var i = 0; i < radioEls.length; ++i) {
29 radioEls[i].addEventListener('click', onRadioClicked);
32 // Wire up the 'click' event for each function's button.
33 var functionEls = document.querySelectorAll('.function');
34 for (var i = 0; i < functionEls.length; ++i) {
35 var functionEl = functionEls[i];
36 var id = functionEl.getAttribute('id');
37 var buttonEl = functionEl.querySelector('button');
39 // The function name matches the element id.
40 var func = window[id];
41 buttonEl.addEventListener('click', func);
44 $('pipe_input_box').addEventListener('keypress', onPipeInput)
45 $('pipe_output').disabled = true;
47 $('pipe_name').addEventListener('change',
48 function() { $('pipe_output').value = ''; })
51 // Called with keypress events on the pipe input box
52 function onPipeInput(e) {
53 // Create an arraybuffer containing the 16-bit char code
54 // from the keypress event.
55 var buffer = new ArrayBuffer(1*2);
56 var bufferView = new Uint16Array(buffer);
57 bufferView[0] = e.charCode;
59 // Pass the buffer in a dictionary over the NaCl module
60 var pipeSelect = $('pipe_name');
61 var pipeName = pipeSelect[pipeSelect.selectedIndex].value;
67 nacl_module.postMessage(message);
72 function onRadioClicked(e) {
73 var divId = this.id.slice(5); // skip "radio"
74 var functionEls = document.querySelectorAll('.function');
75 for (var i = 0; i < functionEls.length; ++i) {
76 var visible = functionEls[i].id === divId;
77 if (functionEls[i].id === divId)
78 functionEls[i].removeAttribute('hidden');
80 functionEls[i].setAttribute('hidden', '');
84 function addNameToSelectElements(cssClass, handle, name) {
85 var text = '[' + handle + '] ' + name;
86 var selectEls = document.querySelectorAll(cssClass);
87 for (var i = 0; i < selectEls.length; ++i) {
88 var optionEl = document.createElement('option');
89 optionEl.setAttribute('value', handle);
90 optionEl.appendChild(document.createTextNode(text));
91 selectEls[i].appendChild(optionEl);
95 function removeNameFromSelectElements(cssClass, handle) {
96 var optionEls = document.querySelectorAll(cssClass + ' > option');
97 for (var i = 0; i < optionEls.length; ++i) {
98 var optionEl = optionEls[i];
99 if (optionEl.value == handle) {
100 var selectEl = optionEl.parentNode;
101 selectEl.removeChild(optionEl);
106 var filehandle_map = {};
107 var dirhandle_map = {};
110 var filename = $('fopenFilename').value;
111 var access = $('fopenMode').value;
112 postCall('fopen', filename, access, function(filename, filehandle) {
113 filehandle_map[filehandle] = filename;
115 addNameToSelectElements('.file-handle', filehandle, filename);
116 common.logMessage('File ' + filename + ' opened successfully.');
121 var filehandle = parseInt($('fcloseHandle').value, 10);
122 postCall('fclose', filehandle, function(filehandle) {
123 var filename = filehandle_map[filehandle];
124 removeNameFromSelectElements('.file-handle', filehandle, filename);
125 common.logMessage('File ' + filename + ' closed successfully.');
130 var filehandle = parseInt($('freadHandle').value, 10);
131 var numBytes = parseInt($('freadBytes').value, 10);
132 postCall('fread', filehandle, numBytes, function(filehandle, data) {
133 var filename = filehandle_map[filehandle];
134 common.logMessage('Read "' + data + '" from file ' + filename + '.');
139 var filehandle = parseInt($('fwriteHandle').value, 10);
140 var data = $('fwriteData').value;
141 postCall('fwrite', filehandle, data, function(filehandle, bytesWritten) {
142 var filename = filehandle_map[filehandle];
143 common.logMessage('Wrote ' + bytesWritten + ' bytes to file ' + filename +
149 var filehandle = parseInt($('fseekHandle').value, 10);
150 var offset = parseInt($('fseekOffset').value, 10);
151 var whence = parseInt($('fseekWhence').value, 10);
152 postCall('fseek', filehandle, offset, whence, function(filehandle, filepos) {
153 var filename = filehandle_map[filehandle];
154 common.logMessage('Seeked to location ' + filepos + ' in file ' + filename +
160 var filehandle = parseInt($('fflushHandle').value, 10);
161 postCall('fflush', filehandle, function(filehandle, filepos) {
162 var filename = filehandle_map[filehandle];
163 common.logMessage('flushed ' + filename + '.');
168 var filename = $('statFilename').value;
169 postCall('stat', filename, function(filename, size) {
170 common.logMessage('File ' + filename + ' has size ' + size + '.');
174 function opendir(e) {
175 var dirname = $('opendirDirname').value;
176 postCall('opendir', dirname, function(dirname, dirhandle) {
177 dirhandle_map[dirhandle] = dirname;
179 addNameToSelectElements('.dir-handle', dirhandle, dirname);
180 common.logMessage('Directory ' + dirname + ' opened successfully.');
184 function readdir(e) {
185 var dirhandle = parseInt($('readdirHandle').value, 10);
186 postCall('readdir', dirhandle, function(dirhandle, ino, name) {
187 var dirname = dirhandle_map[dirhandle];
188 if (ino === undefined) {
189 common.logMessage('End of directory.');
191 common.logMessage('Read entry ("' + name + '", ino = ' + ino +
192 ') from directory ' + dirname + '.');
197 function closedir(e) {
198 var dirhandle = parseInt($('closedirHandle').value, 10);
199 postCall('closedir', dirhandle, function(dirhandle) {
200 var dirname = dirhandle_map[dirhandle];
201 delete dirhandle_map[dirhandle];
203 removeNameFromSelectElements('.dir-handle', dirhandle, dirname);
204 common.logMessage('Directory ' + dirname + ' closed successfully.');
209 var dirname = $('mkdirDirname').value;
210 var mode = parseInt($('mkdirMode').value, 10);
211 postCall('mkdir', dirname, mode, function(dirname) {
212 common.logMessage('Directory ' + dirname + ' created successfully.');
217 var dirname = $('rmdirDirname').value;
218 postCall('rmdir', dirname, function(dirname) {
219 common.logMessage('Directory ' + dirname + ' removed successfully.');
224 var dirname = $('chdirDirname').value;
225 postCall('chdir', dirname, function(dirname) {
226 common.logMessage('Changed directory to: ' + dirname + '.');
231 postCall('getcwd', function(dirname) {
232 common.logMessage('getcwd: ' + dirname + '.');
236 function getaddrinfo(e) {
237 var name = $('getaddrinfoName').value;
238 var family = $('getaddrinfoFamily').value;
239 postCall('getaddrinfo', name, family, function(name, addrType) {
240 common.logMessage('getaddrinfo returned successfully');
241 common.logMessage('ai_cannonname = ' + name + '.');
243 for (var i = 1; i < arguments.length; i+=2) {
244 var msg = 'Address number ' + count + ' = ' + arguments[i] +
245 ' (' + arguments[i+1] + ')';
246 common.logMessage(msg);
252 function gethostbyname(e) {
253 var name = $('gethostbynameName').value;
254 postCall('gethostbyname', name, function(name, addrType) {
255 common.logMessage('gethostbyname returned successfully');
256 common.logMessage('h_name = ' + name + '.');
257 common.logMessage('h_addr_type = ' + addrType + '.');
258 for (var i = 2; i < arguments.length; i++) {
259 common.logMessage('Address number ' + (i-1) + ' = ' + arguments[i] + '.');
264 function connect(e) {
265 var host = $('connectHost').value;
266 var port = parseInt($('connectPort').value, 10);
267 postCall('connect', host, port, function(sockhandle) {
268 common.logMessage('connected');
269 addNameToSelectElements('.sock-handle', sockhandle, '[socket]');
274 var handle = parseInt($('recvHandle').value, 10);
275 var bufferSize = parseInt($('recvBufferSize').value, 10);
276 postCall('recv', handle, bufferSize, function(messageLen, message) {
277 common.logMessage("received " + messageLen + ' bytes: ' + message);
282 var handle = parseInt($('sendHandle').value, 10);
283 var message = $('sendMessage').value;
284 postCall('send', handle, message, function(sentBytes) {
285 common.logMessage("sent bytes: " + sentBytes);
290 var handle = parseInt($('closeHandle').value, 10);
291 postCall('close', handle, function(sock) {
292 removeNameFromSelectElements('.sock-handle', sock, "[socket]");
293 common.logMessage("closed socket: " + sock);
297 var funcToCallback = {};
299 function postCall(func) {
300 var callback = arguments[arguments.length - 1];
301 funcToCallback[func] = callback;
303 nacl_module.postMessage({
305 args: Array.prototype.slice.call(arguments, 1, -1)
309 function ArrayBufferToString(buf) {
310 return String.fromCharCode.apply(null, new Uint16Array(buf));
313 // Called by the common.js module.
314 function handleMessage(message_event) {
315 var data = message_event.data;
316 if ((typeof(data) === 'string' || data instanceof String)) {
317 common.logMessage(data);
318 } else if (data instanceof Object) {
319 var pipeName = data['pipe']
320 if (pipeName !== undefined) {
321 // Message for JavaScript I/O pipe
322 var operation = data['operation'];
323 if (operation == 'write') {
324 $('pipe_output').value += ArrayBufferToString(data['payload']);
325 } else if (operation == 'ack') {
326 common.logMessage(pipeName + ": ack:" + data['payload']);
328 common.logMessage('Got unexpected pipe operation: ' + operation);
331 // Result from a function call.
332 var params = data.args;
333 var funcName = data.cmd;
334 var callback = funcToCallback[funcName];
337 common.logMessage('Error: Bad message ' + funcName +
338 ' received from NaCl module.');
342 delete funcToCallback[funcName];
343 callback.apply(null, params);
346 common.logMessage('Error: Unknow message `' + data +
347 '` received from NaCl module.');