1 {{+bindTo:partials.standard_nacl_api}}
3 <section id="progress-events">
4 <h1 id="progress-events">Progress Events</h1>
5 <div class="contents local" id="contents" style="display: none">
7 <li><a class="reference internal" href="#module-loading-and-progress-events" id="id3">Module loading and progress events</a></li>
8 <li><a class="reference internal" href="#handling-progress-events" id="id4">Handling progress events</a></li>
9 <li><a class="reference internal" href="#displaying-load-status" id="id5">Displaying load status</a></li>
10 <li><a class="reference internal" href="#the-lasterror-attribute" id="id6">The <code>lastError</code> attribute</a></li>
11 <li><a class="reference internal" href="#the-readystate-attribute" id="id7">The <code>readyState</code> attribute</a></li>
12 <li><a class="reference internal" href="#the-exitstatus-attribute" id="id8">The <code>exitStatus</code> attribute</a></li>
15 </div><p>There are five types of events that developers can respond to in Native Client:
16 progress, message, view change, focus, and input events (each described in the
17 glossary below). This chapter describes how to monitor progress events (events
18 that occur during the loading and execution of a Native Client module). This
19 chapter assumes you are familiar with the material presented in the
20 <a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a>.</p>
22 The load_progress example illustrates progress event handling. You can find
23 this code in the <code>/examples/tutorial/load_progress/</code> directory in the Native
26 <h2 id="module-loading-and-progress-events">Module loading and progress events</h2>
27 <p>The Native Client runtime reports a set of state changes during the module
28 loading process by means of DOM progress events. This set of events is a direct
29 port of the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a> standard (except for the <code>crash</code>
30 event which is an extension of the W3C standard). The following table lists the
31 events types reported by the Native Client runtime:</p>
32 <table border="1" class="docutils">
35 <thead valign="bottom">
36 <tr class="row-odd"><th class="head">Event</th>
37 <th class="head">Description</th>
38 <th class="head">Number of
41 <th class="head">When event is
43 <th class="head">How you might
49 <tr class="row-even"><td><code>loadstart</code></td>
70 “Loading...”</td>
72 <tr class="row-odd"><td><code>progress</code></td>
73 <td>Part of the module
78 <code>loadstart</code>
84 <tr class="row-even"><td><code>error</code></td>
93 <code>lastError</code>
106 <code>progress</code>
111 <code>loadstart</code>
113 <code>progress</code>
122 <tr class="row-odd"><td><code>abort</code></td>
132 <code>progress</code>
137 <code>loadstart</code>
139 <code>progress</code>
148 <tr class="row-even"><td><code>load</code></td>
149 <td>The Native Client
162 <code>progress</code>
167 <code>loadstart</code>
169 <code>progress</code>
175 <tr class="row-odd"><td><code>loadend</code></td>
183 (<code>error</code>), or
185 (<code>abort</code>).</td>
189 <code>abort</code>, or
200 <tr class="row-even"><td><code>crash</code></td>
201 <td>The Native Client
205 <code>assert()</code> or
206 <code>exit()</code>) after
214 The <code>exitStatus</code>
221 <code>loadend</code>.</td>
230 <p>The sequence of events for a successful module load is as follows:</p>
231 <table border="1" class="docutils">
234 <thead valign="bottom">
235 <tr class="row-odd"><th class="head">Event is dispatched</th>
236 <th class="head">... then this task is attempted</th>
240 <tr class="row-even"><td><code>loadstart</code></td>
241 <td>load the manifest file</td>
243 <tr class="row-odd"><td><code>progress</code> (first time)</td>
244 <td>load the module</td>
246 <tr class="row-even"><td><code>progress</code> (subsequent times)</td>
249 <tr class="row-odd"><td><code>load</code></td>
250 <td>start executing the module</td>
252 <tr class="row-even"><td><code>loadend</code></td>
257 <p>Errors that occur during loading are logged to the JavaScript console in Google
258 Chrome (select the menu icon <img alt="menu-icon" src="/native-client/images/menu-icon.png" /> > Tools > JavaScript console).</p>
259 <h2 id="handling-progress-events">Handling progress events</h2>
260 <p>You should add event listeners in a <code><script></code> element to listen for these
261 events before the <code><embed></code> element is parsed. For example, the following code
262 adds a listener for the <code>load</code> event to a parent <code><div></code> element that also
263 contains the Native Client <code><embed></code> element. First, the listener is
264 attached. Then, when the listener <code><div></code> receives the <code>load</code> event, the
265 JavaScript <code>moduleDidLoad()</code> function is called. The following code is
266 excerpted from the example in <code>getting_started/part1/</code>:</p>
267 <pre class="prettyprint">
269 Load the published pexe.
270 Note: Since this module does not use any real-estate in the browser, its
271 width and height are set to 0.
273 Note: The <embed> element is wrapped inside a <div>, which has both a 'load'
274 and a 'message' event listener attached. This wrapping method is used
275 instead of attaching the event listeners directly to the <embed> element to
276 ensure that the listeners are active before the NaCl module 'load' event
277 fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
278 pp::Instance.PostMessage() (in C++) from within the initialization code in
281 <div id="listener">
282 <script type="text/javascript">
283 var listener = document.getElementById('listener');
284 listener.addEventListener('load', moduleDidLoad, true);
285 listener.addEventListener('message', handleMessage, true);
288 <embed id="hello_tutorial"
290 src="hello_tutorial.nmf"
291 type="application/x-pnacl" />
294 <p>Event listeners can be added to any DOM object. Since listeners set at the
295 outermost scope capture events for their contained elements, you can set
296 listeners on outer elements (including the <code><body></code> element) to handle events
297 from inner elements. For more information, see the W3 specifications for <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture">event
299 <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">event listener registration</a>.</p>
300 <h2 id="displaying-load-status">Displaying load status</h2>
301 <p>One common response to progress events is to display the percentage of the
302 module that has been loaded. In the load_progress example, when the <code>progress</code>
303 event is triggered the <code>moduleLoadProgress</code> function is called. This function
304 uses the <code>lengthComputable</code>, <code>loaded</code>, and <code>total</code> attributes (described
305 in the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a>
306 standard) of the event to calculate the percentage of the module that has
308 <pre class="prettyprint">
309 function moduleLoadProgress(event) {
310 var loadPercent = 0.0;
311 var loadPercentString;
312 if (event.lengthComputable && event.total > 0) {
313 loadPercent = event.loaded / event.total * 100.0;
314 loadPercentString = loadPercent + '%';
315 common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
316 ' (' + event.loaded + ' of ' + event.total + ' bytes)');
318 // The total length is not yet known.
319 common.logMessage('progress: Computing...');
323 <h2 id="the-lasterror-attribute">The <code>lastError</code> attribute</h2>
324 <p>The <code><embed></code> element has a <code>lastError</code> attribute that is set to an
325 informative string whenever a load failure (an <code>error</code> or <code>abort</code> event)
327 <p>The following code adds an event listener before the <code><embed></code> element to
328 capture and handle an error in loading the Native Client module. The
329 <code>handleError()</code> function listens for an <code>error</code> event. When an error occurs,
330 this function prints the contents of the <code>lastError</code> attribute
331 (<code>embed_element.lastError</code>) as an alert.</p>
332 <pre class="prettyprint">
333 function domContentLoaded(name, tc, config, width, height) {
334 var listener = document.getElementById('listener');
336 listener.addEventListener('error', moduleLoadError, true);
338 common.createNaClModule(name, tc, config, width, height);
341 function moduleLoadError() {
342 common.logMessage('error: ' + common.naclModule.lastError);
345 <h2 id="the-readystate-attribute">The <code>readyState</code> attribute</h2>
346 <p>You can use the <code>readyState</code> attribute to monitor the loading process. This
347 attribute is particularly useful if you don’t care about the details of
348 individual progress events or when you want to poll for current load state
349 without registering listeners. The value of <code>readyState</code> progresses as follows
350 for a successful load:</p>
351 <table border="1" class="docutils">
354 <thead valign="bottom">
355 <tr class="row-odd"><th class="head">Event</th>
356 <th class="head"><code>readyState</code> value</th>
360 <tr class="row-even"><td>(before any events)</td>
361 <td><code>undefined</code></td>
363 <tr class="row-odd"><td><code>loadstart</code></td>
366 <tr class="row-even"><td><code>progress</code></td>
369 <tr class="row-odd"><td><code>load</code></td>
372 <tr class="row-even"><td><code>loadend</code></td>
377 <p>The following code demonstrates how to monitor the loading process using the
378 <code>readyState</code> attribute. As before, the script that adds the event listeners
379 precedes the <code><embed></code> element so that the event listeners are in place before
380 the progress events are generated.</p>
381 <pre class="prettyprint">
384 <body id="body">
385 <div id="status_div">
387 <div id="listener_div">
388 <script type="text/javascript">
389 var stat = document.getElementById('status_div');
390 function handleEvent(e) {
391 var embed_element = document.getElementById('my_embed');
393 '<br>' + e.type + ': readyState = ' + embed_element.readyState;
395 var listener_element = document.getElementById('listener_div');
396 listener_element.addEventListener('loadstart', handleEvent, true);
397 listener_element.addEventListener('progress', handleEvent, true);
398 listener_element.addEventListener('load', handleEvent, true);
399 listener_element.addEventListener('loadend', handleEvent, true);
402 name="naclModule"
403 id="my_embed"
405 src="my_example.nmf"
406 type="application/x-pnacl" />
411 <h2 id="the-exitstatus-attribute">The <code>exitStatus</code> attribute</h2>
412 <p>This read-only attribute is set if the application calls <code>exit(n)</code>,
413 <code>abort()</code>, or crashes. Since NaCl modules are event handlers, there is no
414 need to call <code>exit(n)</code> in normal execution. If the module does exit or
415 crash, the <code>crash</code> progress event is issued and the <code>exitStatus</code> attribute
416 will contain the numeric value of the exit status:</p>
417 <ul class="small-gap">
418 <li>In the case of explicit calls to <code>exit(n)</code>, the numeric value will be
419 <code>n</code> (between 0 and 255).</li>
420 <li>In the case of crashes and calls to <code>abort()</code>, the numeric value will
421 be non-zero, but the exact value will depend on the chosen libc and the
422 target architecture, and may change in the future. Applications should not
423 rely on the <code>exitStatus</code> value being stable in these cases, but the value
424 may nevertheless be useful for temporary debugging.</li>
428 {{/partials.standard_nacl_api}}