1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Copyright (c) 2013 The Chromium Authors. All rights reserved.
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * found in the LICENSE file.
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)'use strict';
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)lib.rtdep('lib.f',
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          'hterm');
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// CSP means that we can't kick off the initialization from the html file,
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// so we do it like this instead.
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)window.onload = function() {
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lib.init(function() {
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NaClTerm.init();
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  });
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * The hterm-powered terminal command.
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * This class defines a command that can be run in an hterm.Terminal instance.
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @param {Object} argv The argument object passed in from the Terminal.
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)function NaClTerm(argv) {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io = argv.io.push();
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.argv_ = argv;
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)var ansiCyan = '\x1b[36m';
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)var ansiReset = '\x1b[0m';
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Static initialier called from index.html.
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * This constructs a new Terminal instance and instructs it to run the NaClTerm
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * command.
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.init = function() {
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var profileName = lib.f.parseQuery(document.location.search)['profile'];
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var terminal = new hterm.Terminal(profileName);
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  terminal.decorate(document.querySelector('#terminal'));
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Useful for console debugging.
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window.term_ = terminal;
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  terminal.runCommandClass(NaClTerm, document.location.hash.substr(1));
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.updateStatus = function(message) {
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  document.getElementById('statusField').textContent = message;
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print(message + '\n');
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handle messages sent to us from NaCl.
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * @private
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.handleMessage_ = function(e) {
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (e.data.indexOf(NaClTerm.prefix) == 0) {
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var msg = e.data.substring(NaClTerm.prefix.length);
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!this.loaded) {
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.bufferedOutput += msg;
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else {
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.io.print(msg);
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else if (e.data.indexOf('exited') == 0) {
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var exitCode = e.data.split(':', 2)[1]
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (exitCode === undefined)
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      exitCode = 0;
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.exit(exitCode);
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    console.log('unexpected message: ' + e.data);
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handle load error event from NaCl.
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.handleLoadAbort_ = function(e) {
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.updateStatus('Load aborted.');
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handle load abort event from NaCl.
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.handleLoadError_ = function(e) {
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.updateStatus(embed.lastError);
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.doneLoadingUrl = function() {
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var width = this.io.terminal_.screenSize.width;
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print('\r' + Array(width+1).join(' '));
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var message = '\rLoaded ' + this.lastUrl;
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.lastTotal) {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var kbsize = Math.round(this.lastTotal/1024)
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    message += ' ['+ kbsize + ' KiB]';
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print(message.slice(0, width) + '\n')
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handle load end event from NaCl.
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.handleLoad_ = function(e) {
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.lastUrl)
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.doneLoadingUrl();
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  else
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.io.print('Loaded.\n');
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delete this.lastUrl
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  document.getElementById('loading-cover').style.display = 'none';
118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print(ansiReset);
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Now that have completed loading and displaying
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // loading messages we output any messages from the
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NaCl module that were buffered up unto this point
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.loaded = true;
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print(this.bufferedOutput);
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.sendMessage(this.bufferedInput);
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.bufferedOutput = ''
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.bufferedInput = ''
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handle load progress event from NaCl.
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.handleProgress_ = function(e) {
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var url = e.url.substring(e.url.lastIndexOf('/') + 1);
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.lastUrl && this.lastUrl != url)
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.doneLoadingUrl()
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!url)
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var percent = 10;
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var message = 'Loading ' + url;
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (e.lengthComputable && e.total > 0) {
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    percent = Math.round(e.loaded * 100 / e.total);
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var kbloaded = Math.round(e.loaded / 1024);
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var kbtotal = Math.round(e.total / 1024);
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    message += ' [' + kbloaded + ' KiB/' + kbtotal + ' KiB ' + percent + '%]';
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  document.getElementById('progress-bar').style.width = percent + "%";
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var width = this.io.terminal_.screenSize.width;
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print('\r' + message.slice(-width));
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.lastUrl = url;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.lastTotal = e.total;
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Handle crash event from NaCl.
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.handleCrash_ = function(e) {
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this.exit(this.embed.exitStatus);
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Exit the command.
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.exit = function(code) {
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this.io.print(ansiCyan)
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (code == -1) {
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   this.io.print('Program crashed (exit status -1)\n')
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else {
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)   this.io.print('Program exited (status=' + code + ')\n');
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) }
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) this.loaded = false;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.restartNaCl = function() {
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.embed !== undefined) {
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    document.getElementById("listener").removeChild(this.embed);
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delete this.embed;
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.terminal_.reset();
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.startCommand();
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.createEmbed(this.io.terminal_.screenSize.width, this.io.terminal_.screenSize.height);
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/**
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * Create the NaCl embed element.
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * We delay this until the first terminal resize event so that we start
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * with the correct size.
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.createEmbed = function(width, height) {
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var mimetype = 'application/x-pnacl';
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (navigator.mimeTypes[mimetype] === undefined) {
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (mimetype.indexOf('pnacl') != -1)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.updateStatus('Browser does not support PNaCl or PNaCl is disabled');
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    else
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      this.updateStatus('Browser does not support NaCl or NaCl is disabled');
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var embed = document.createElement('object');
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.width = 0;
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.height = 0;
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.data = NaClTerm.nmf;
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.type = mimetype;
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.addEventListener('message', this.handleMessage_.bind(this));
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.addEventListener('progress', this.handleProgress_.bind(this));
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.addEventListener('load', this.handleLoad_.bind(this));
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.addEventListener('error', this.handleLoadError_.bind(this));
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.addEventListener('abort', this.handleLoadAbort_.bind(this));
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  embed.addEventListener('crash', this.handleCrash_.bind(this));
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  function addParam(name, value) {
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var param = document.createElement('param');
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    param.name = name;
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    param.value = value;
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    embed.appendChild(param);
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_TTY_PREFIX', NaClTerm.prefix);
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_TTY_RESIZE', 'tty_resize');
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_TTY_COLS', width);
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_TTY_ROWS', height);
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_STDIN', '/dev/tty');
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_STDOUT', '/dev/tty');
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_STDERR', '/dev/tty');
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_VERBOSITY', '2');
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('PS_EXIT_MESSAGE', 'exited');
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  addParam('TERM', 'xterm-256color');
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  addParam('LUA_DATA_URL', 'http://storage.googleapis.com/gonacl/demos/publish/234230_dev/lua');
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Add ARGV arguments from query parameters.
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var args = lib.f.parseQuery(document.location.search);
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (var argname in args) {
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    addParam(argname, args[argname]);
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the application has set NaClTerm.argv and there were
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // no arguments set in the query parameters then add the default
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NaClTerm.argv arguments.
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (args['arg1'] === undefined && NaClTerm.argv) {
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    var argn = 1
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NaClTerm.argv.forEach(function(arg) {
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      var argname = 'arg' + argn;
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      addParam(argname, arg);
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      argn = argn + 1
252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    })
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.updateStatus('Loading...');
256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print('Loading NaCl module.\n')
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  document.getElementById("listener").appendChild(embed);
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.embed = embed;
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.onTerminalResize_ = function(width, height) {
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (this.embed === undefined)
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.createEmbed(width, height);
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  else
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.embed.postMessage({'tty_resize': [ width, height ]});
266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Require at least 80 columns, otherwise some of the demos look
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // very wrong.
269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var width = this.io.terminal_.scrollPort_.characterSize.width * 80;
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  document.getElementById("terminal").style.minWidth = width + 'px';
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.sendMessage = function(msg) {
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!this.loaded) {
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    this.bufferedInput += msg;
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  var message = {};
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  message[NaClTerm.prefix] = msg;
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.embed.postMessage(message);
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.onVTKeystroke_ = function(str) {
284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.sendMessage(str)
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.startCommand = function() {
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // We don't properly support the hterm bell sound, so we need to disable it.
289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.terminal_.prefs_.definePreference('audible-bell-sound', '');
290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.terminal_.setAutoCarriageReturn(true);
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.terminal_.setCursorPosition(0, 0);
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.terminal_.setCursorVisible(true);
293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.bufferedOutput = '';
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.bufferedInput = '';
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.loaded = false;
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.print(ansiCyan);
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/*
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * This is invoked by the terminal as a result of terminal.runCommandClass().
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)NaClTerm.prototype.run = function() {
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.startCommand();
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.onVTKeystroke = this.onVTKeystroke_.bind(this);
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  this.io.onTerminalResize = this.onTerminalResize_.bind(this);
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
308