Add a Notification Settings Button to all web notifications behind the web platform...
[chromium-blink-merge.git] / native_client_sdk / doc_generated / devguide / coding / progress-events.html
blob70adb6cf8dda165c8bdb5ac85f801a8f8acedf3f
1 {{+bindTo:partials.standard_nacl_article}}
3 <section id="progress-events">
4 <span id="devcycle-progress-events"></span><h1 id="progress-events"><span id="devcycle-progress-events"></span>Progress Events</h1>
5 <div class="contents local" id="contents" style="display: none">
6 <ul class="small-gap">
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>
13 </ul>
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 section describes how to monitor progress events (events
18 that occur during the loading and execution of a Native Client module). This
19 section 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>
21 <aside class="note">
22 The load_progress example illustrates progress event handling. You can find
23 this code in the <code>/pepper_&lt;version&gt;/examples/tutorial/load_progress/</code>
24 directory in the Native Client SDK download.
25 </aside>
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">
33 <colgroup>
34 </colgroup>
35 <thead valign="bottom">
36 <tr class="row-odd"><th class="head">Event</th>
37 <th class="head">Times
38 triggered</th>
39 <th class="head">When
40 triggered</th>
41 <th class="head">How you might
42 respond</th>
43 </tr>
44 </thead>
45 <tbody valign="top">
46 <tr class="row-even"><td><dl class="first last docutils">
47 <dt><code>loadstart</code></dt>
48 <dd>Native Client has started to
49 load a Native Client module.</dd>
50 </dl>
51 </td>
52 <td>once</td>
53 <td>The
54 first
55 progress
56 event
57 after the
58 Native Client
59 module is
60 instantiated
61 and
62 initialized.</td>
63 <td>Display a
64 status
65 message, such
67 &#8220;Loading...&#8221;</td>
68 </tr>
69 <tr class="row-odd"><td><dl class="first last docutils">
70 <dt><code>progress</code></dt>
71 <dd>Part of the module has been
72 loaded.</dd>
73 </dl>
74 </td>
75 <td>zero or
76 more</td>
77 <td>After
78 <code>loadstart</code>
79 has been
80 dispatched.</td>
81 <td>Display a
82 progress bar.</td>
83 </tr>
84 <tr class="row-even"><td><dl class="first last docutils">
85 <dt><code>error</code></dt>
86 <dd>The Native Client module failed
87 to start execution (includes any
88 error before or during
89 initialization of the module).
90 The <code>lastError</code> attribute
91 (mentioned later) provides
92 details on the error
93 (initialization failed, sel_ldr
94 did not start, and so on).</dd>
95 </dl>
96 </td>
97 <td>zero or
98 once</td>
99 <td>After the last
100 <code>progress</code>
101 event has been
102 dispatched,
103 or after
104 <code>loadstart</code>
105 if no
106 <code>progress</code>
107 event was
108 dispatched.</td>
109 <td>Inform user
110 that the
111 application
112 failed to
113 load.</td>
114 </tr>
115 <tr class="row-odd"><td><dl class="first last docutils">
116 <dt><code>abort</code></dt>
117 <dd>Loading of the NativeClient
118 module was aborted by the user.</dd>
119 </dl>
120 </td>
121 <td>zero or
122 once</td>
123 <td>After the last
124 <code>progress</code>
125 event has been
126 dispatched, or
127 after
128 <code>loadstart</code>
129 if no
130 <code>progress</code>
131 event was
132 dispatched.</td>
133 <td>It&#8217;s not
134 likely you
135 will want to
136 respond to
137 this event.</td>
138 </tr>
139 <tr class="row-even"><td><dl class="first last docutils">
140 <dt><code>load</code></dt>
141 <dd>The Native Client module was
142 successfully loaded, and
143 execution was started.
144 (The module was initialized
145 successfully.)</dd>
146 </dl>
147 </td>
148 <td>zero or
149 once</td>
150 <td>After the
151 last
152 <code>progress</code>
153 event has been
154 dispatched, or
155 after
156 <code>loadstart</code>
157 if no
158 <code>progress</code>
159 event was
160 dispatched.</td>
161 <td>Remove the
162 progress bar.</td>
163 </tr>
164 <tr class="row-odd"><td><dl class="first last docutils">
165 <dt><code>loadend</code></dt>
166 <dd>Loading of the Native Client
167 module has stopped. Load
168 succeeded (<code>load</code>), failed
169 (<code>error</code>), or was aborted
170 (<code>abort</code>).</dd>
171 </dl>
172 </td>
173 <td>once</td>
174 <td>After an
175 <code>error</code>,
176 <code>abort</code>, or
177 <code>load</code>
178 event was
179 dispatched.</td>
180 <td>Indicate
181 loading is
182 over
183 (regardless of
184 failure or
185 not).</td>
186 </tr>
187 <tr class="row-even"><td><dl class="first last docutils">
188 <dt><code>crash</code></dt>
189 <dd>The Native Client module is not
190 responding (died on an
191 <code>assert()</code> or <code>exit()</code>)
192 after a successful load. This
193 event is unique to Native Client
194 and is not part of the W3C
195 Progress Events standard. The
196 <code>exitStatus</code> attribute
197 provides the numeric exit
198 status.</dd>
199 </dl>
200 </td>
201 <td>zero or
202 once</td>
203 <td>After a
204 <code>loadend</code>.</td>
205 <td>Notify user
206 that the
207 module did
208 something
209 illegal.</td>
210 </tr>
211 </tbody>
212 </table>
213 <p>The sequence of events for a successful module load is as follows:</p>
214 <table border="1" class="docutils">
215 <colgroup>
216 </colgroup>
217 <thead valign="bottom">
218 <tr class="row-odd"><th class="head">Event is dispatched</th>
219 <th class="head">... then this task is attempted</th>
220 </tr>
221 </thead>
222 <tbody valign="top">
223 <tr class="row-even"><td><code>loadstart</code></td>
224 <td>load the manifest file</td>
225 </tr>
226 <tr class="row-odd"><td><code>progress</code> (first time)</td>
227 <td>load the module</td>
228 </tr>
229 <tr class="row-even"><td><code>progress</code> (subsequent times)</td>
230 <td>&nbsp;</td>
231 </tr>
232 <tr class="row-odd"><td><code>load</code></td>
233 <td>start executing the module</td>
234 </tr>
235 <tr class="row-even"><td><code>loadend</code></td>
236 <td>&nbsp;</td>
237 </tr>
238 </tbody>
239 </table>
240 <p>Errors that occur during loading are logged to the JavaScript console in Google
241 Chrome (select the menu icon <img alt="menu-icon" src="/native-client/images/menu-icon.png" /> &gt; Tools &gt; JavaScript console).</p>
242 <h2 id="handling-progress-events">Handling progress events</h2>
243 <p>You should add event listeners in a <code>&lt;script&gt;</code> element to listen for these
244 events before the <code>&lt;embed&gt;</code> element is parsed. For example, the following code
245 adds a listener for the <code>load</code> event to a parent <code>&lt;div&gt;</code> element that also
246 contains the Native Client <code>&lt;embed&gt;</code> element. First, the listener is
247 attached. Then, when the listener <code>&lt;div&gt;</code> receives the <code>load</code> event, the
248 JavaScript <code>moduleDidLoad()</code> function is called. The following code is
249 excerpted from the example in <code>getting_started/part1/</code>:</p>
250 <pre class="prettyprint">
251 &lt;!--
252 Load the published pexe.
253 Note: Since this module does not use any real-estate in the browser, its
254 width and height are set to 0.
256 Note: The &lt;embed&gt; element is wrapped inside a &lt;div&gt;, which has both a 'load'
257 and a 'message' event listener attached. This wrapping method is used
258 instead of attaching the event listeners directly to the &lt;embed&gt; element to
259 ensure that the listeners are active before the NaCl module 'load' event
260 fires. This also allows you to use PPB_Messaging.PostMessage() (in C) or
261 pp::Instance.PostMessage() (in C++) from within the initialization code in
262 your module.
263 --&gt;
264 &lt;div id=&quot;listener&quot;&gt;
265 &lt;script type=&quot;text/javascript&quot;&gt;
266 var listener = document.getElementById('listener');
267 listener.addEventListener('load', moduleDidLoad, true);
268 listener.addEventListener('message', handleMessage, true);
269 &lt;/script&gt;
271 &lt;embed id=&quot;hello_tutorial&quot;
272 width=0 height=0
273 src=&quot;hello_tutorial.nmf&quot;
274 type=&quot;application/x-pnacl&quot; /&gt;
275 &lt;/div&gt;
276 </pre>
277 <p>Event listeners can be added to any DOM object. Since listeners set at the
278 outermost scope capture events for their contained elements, you can set
279 listeners on outer elements (including the <code>&lt;body&gt;</code> element) to handle events
280 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
281 flow capture</a> and
282 <a class="reference external" href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">event listener registration</a>.</p>
283 <h2 id="displaying-load-status">Displaying load status</h2>
284 <p>One common response to progress events is to display the percentage of the
285 module that has been loaded. In the load_progress example, when the <code>progress</code>
286 event is triggered the <code>moduleLoadProgress</code> function is called. This function
287 uses the <code>lengthComputable</code>, <code>loaded</code>, and <code>total</code> attributes (described
288 in the proposed W3C <a class="reference external" href="http://www.w3.org/TR/progress-events/">Progress Events</a>
289 standard) of the event to calculate the percentage of the module that has
290 loaded.</p>
291 <pre class="prettyprint">
292 function moduleLoadProgress(event) {
293 var loadPercent = 0.0;
294 var loadPercentString;
295 if (event.lengthComputable &amp;&amp; event.total &gt; 0) {
296 loadPercent = event.loaded / event.total * 100.0;
297 loadPercentString = loadPercent + '%';
298 common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
299 ' (' + event.loaded + ' of ' + event.total + ' bytes)');
300 } else {
301 // The total length is not yet known.
302 common.logMessage('progress: Computing...');
305 </pre>
306 <h2 id="the-lasterror-attribute">The <code>lastError</code> attribute</h2>
307 <p>The <code>&lt;embed&gt;</code> element has a <code>lastError</code> attribute that is set to an
308 informative string whenever a load failure (an <code>error</code> or <code>abort</code> event)
309 occurs.</p>
310 <p>The following code adds an event listener before the <code>&lt;embed&gt;</code> element to
311 capture and handle an error in loading the Native Client module. The
312 <code>handleError()</code> function listens for an <code>error</code> event. When an error occurs,
313 this function prints the contents of the <code>lastError</code> attribute
314 (<code>embed_element.lastError</code>) as an alert.</p>
315 <pre class="prettyprint">
316 function domContentLoaded(name, tc, config, width, height) {
317 var listener = document.getElementById('listener');
319 listener.addEventListener('error', moduleLoadError, true);
321 common.createNaClModule(name, tc, config, width, height);
324 function moduleLoadError() {
325 common.logMessage('error: ' + common.naclModule.lastError);
327 </pre>
328 <h2 id="the-readystate-attribute">The <code>readyState</code> attribute</h2>
329 <p>You can use the <code>readyState</code> attribute to monitor the loading process. This
330 attribute is particularly useful if you don&#8217;t care about the details of
331 individual progress events or when you want to poll for current load state
332 without registering listeners. The value of <code>readyState</code> progresses as follows
333 for a successful load:</p>
334 <table border="1" class="docutils">
335 <colgroup>
336 </colgroup>
337 <thead valign="bottom">
338 <tr class="row-odd"><th class="head">Event</th>
339 <th class="head"><code>readyState</code> value</th>
340 </tr>
341 </thead>
342 <tbody valign="top">
343 <tr class="row-even"><td>(before any events)</td>
344 <td><code>undefined</code></td>
345 </tr>
346 <tr class="row-odd"><td><code>loadstart</code></td>
347 <td>1</td>
348 </tr>
349 <tr class="row-even"><td><code>progress</code></td>
350 <td>3</td>
351 </tr>
352 <tr class="row-odd"><td><code>load</code></td>
353 <td>4</td>
354 </tr>
355 <tr class="row-even"><td><code>loadend</code></td>
356 <td>4</td>
357 </tr>
358 </tbody>
359 </table>
360 <p>The following code demonstrates how to monitor the loading process using the
361 <code>readyState</code> attribute. As before, the script that adds the event listeners
362 precedes the <code>&lt;embed&gt;</code> element so that the event listeners are in place before
363 the progress events are generated.</p>
364 <pre class="prettyprint">
365 &lt;html&gt;
367 &lt;body id=&quot;body&quot;&gt;
368 &lt;div id=&quot;status_div&quot;&gt;
369 &lt;/div&gt;
370 &lt;div id=&quot;listener_div&quot;&gt;
371 &lt;script type=&quot;text/javascript&quot;&gt;
372 var stat = document.getElementById('status_div');
373 function handleEvent(e) {
374 var embed_element = document.getElementById('my_embed');
375 stat.innerHTML +=
376 '&lt;br&gt;' + e.type + ': readyState = ' + embed_element.readyState;
378 var listener_element = document.getElementById('listener_div');
379 listener_element.addEventListener('loadstart', handleEvent, true);
380 listener_element.addEventListener('progress', handleEvent, true);
381 listener_element.addEventListener('load', handleEvent, true);
382 listener_element.addEventListener('loadend', handleEvent, true);
383 &lt;/script&gt;
384 &lt;embed
385 name=&quot;naclModule&quot;
386 id=&quot;my_embed&quot;
387 width=0 height=0
388 src=&quot;my_example.nmf&quot;
389 type=&quot;application/x-pnacl&quot; /&gt;
390 &lt;/div&gt;
391 &lt;/body&gt;
392 &lt;/html&gt;
393 </pre>
394 <h2 id="the-exitstatus-attribute">The <code>exitStatus</code> attribute</h2>
395 <p>This read-only attribute is set if the application calls <code>exit(n)</code>,
396 <code>abort()</code>, or crashes. Since NaCl modules are event handlers, there is no
397 need to call <code>exit(n)</code> in normal execution. If the module does exit or
398 crash, the <code>crash</code> progress event is issued and the <code>exitStatus</code> attribute
399 will contain the numeric value of the exit status:</p>
400 <ul class="small-gap">
401 <li>In the case of explicit calls to <code>exit(n)</code>, the numeric value will be
402 <code>n</code> (between 0 and 255).</li>
403 <li>In the case of crashes and calls to <code>abort()</code>, the numeric value will
404 be non-zero, but the exact value will depend on the chosen libc and the
405 target architecture, and may change in the future. Applications should not
406 rely on the <code>exitStatus</code> value being stable in these cases, but the value
407 may nevertheless be useful for temporary debugging.</li>
408 </ul>
409 </section>
411 {{/partials.standard_nacl_article}}