- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / devguide / coding / progress-events.rst
1 .. _devcycle-progress-events:
2
3 ###############
4 Progress Events
5 ###############
6
7 .. contents::
8   :local:
9   :backlinks: none
10   :depth: 2
11
12 There are five types of events that developers can respond to in Native Client:
13 progress, message, view change, focus, and input events (each described in the
14 glossary below). This chapter describes how to monitor progress events (events
15 that occur during the loading and execution of a Native Client module). This
16 chapter assumes you are familiar with the material presented in the
17 :doc:`Technical Overview <../../overview>`.
18
19 .. Note::
20   :class: note
21
22   The load_progress example illustrates progress event handling. You can find
23   this code in the ``/examples/tutorial/load_progress/`` directory in the Native
24   Client SDK download.
25
26 Module loading and progress events
27 ==================================
28
29 The Native Client runtime reports a set of state changes during the module
30 loading process by means of DOM progress events. This set of events is a direct
31 port of the proposed W3C `Progress Events
32 <http://www.w3.org/TR/progress-events/>`_ standard (except for the ``crash``
33 event which is an extension of the W3C standard). The following table lists the
34 events types reported by the Native Client runtime:
35
36 +-------------+--------------------+-----------+---------------+---------------+
37 | Event       | Description        | Number of | When event is | How you might |
38 |             |                    | times     | triggered     | react to      |
39 |             |                    | triggered |               | event         |
40 +=============+====================+===========+===============+===============+
41 |``loadstart``| Native Client has  | once      | This is the   | Display a     |
42 |             | started to load a  |           | first         | status        |
43 |             | Native Client      |           | progress      | message, such |
44 |             | module.            |           | event         | as            |
45 |             |                    |           | triggered     | "Loading..."  |
46 |             |                    |           | after the     |               |
47 |             |                    |           | Native Client |               |
48 |             |                    |           | module is     |               |
49 |             |                    |           | instantiated  |               |
50 |             |                    |           | and           |               |
51 |             |                    |           | initialized.  |               |
52 +-------------+--------------------+-----------+---------------+---------------+
53 |``progress`` | Part of the module | zero or   | After         | Display a     |
54 |             | has been loaded.   | more      | ``loadstart`` | progress bar. |
55 |             |                    |           | has been      |               |
56 |             |                    |           | dispatched.   |               |
57 +-------------+--------------------+-----------+---------------+---------------+
58 |``error``    | The Native Client  | zero or   | After the     | Inform user   |
59 |             | module failed to   | once      | last          | that the      |
60 |             | start execution    |           | ``progress``  | application   |
61 |             | (includes any      |           | event has     | failed to     |
62 |             | error before or    |           | been          | load.         |
63 |             | during             |           | dispatched,   |               |
64 |             | initialization of  |           | or after      |               |
65 |             | the module). The   |           | ``loadstart`` |               |
66 |             | ``lastError``      |           | if no         |               |
67 |             | attribute          |           | ``progress``  |               |
68 |             | (mentioned later)  |           | event was     |               |
69 |             | provides details   |           | dispatched.   |               |
70 |             | on the error       |           |               |               |
71 |             | (initialization    |           |               |               |
72 |             | failed, sel_ldr    |           |               |               |
73 |             | did not start,     |           |               |               |
74 |             | and so on).        |           |               |               |
75 +-------------+--------------------+-----------+---------------+---------------+
76 |``abort``    | Loading of the     | zero or   | After the     | It's not      |
77 |             | Native Client      | once      | last          | likely you    |
78 |             | module was         |           | ``progress``  | will want to  |
79 |             | aborted by the     |           | event has     | respond to    |
80 |             | user.              |           | been          | this event.   |
81 |             |                    |           | dispatched,   |               |
82 |             |                    |           | or after      |               |
83 |             |                    |           | ``loadstart`` |               |
84 |             |                    |           | if no         |               |
85 |             |                    |           | ``progress``  |               |
86 |             |                    |           | event was     |               |
87 |             |                    |           | dispatched.   |               |
88 +-------------+--------------------+-----------+---------------+---------------+
89 |``load``     | The Native Client  | zero or   | After the     | Remove the    |
90 |             | module was         | once      | last          | progress bar. |
91 |             | successfully       |           | ``progress``  |               |
92 |             | loaded, and        |           | event has     |               |
93 |             | execution was      |           | been          |               |
94 |             | started. (The      |           | dispatched,   |               |
95 |             | module was         |           | or after      |               |
96 |             | initialized        |           | ``loadstart`` |               |
97 |             | successfully.)     |           | if no         |               |
98 |             |                    |           | ``progress``  |               |
99 |             |                    |           | event was     |               |
100 |             |                    |           | dispatched.   |               |
101 +-------------+--------------------+-----------+---------------+---------------+
102 |``loadend``  | Loading of the     | once      | After an      | Indicate      |
103 |             | Native Client      |           | ``error``,    | loading is    |
104 |             | module has         |           | ``abort``, or | over          |
105 |             | stopped. Load      |           | ``load``      | (regardless   |
106 |             | succeeded          |           | event was     | of failure or |
107 |             | (``load``),        |           | dispatched.   | not).         |
108 |             | failed             |           |               |               |
109 |             | (``error``), or    |           |               |               |
110 |             | was aborted        |           |               |               |
111 |             | (``abort``).       |           |               |               |
112 +-------------+--------------------+-----------+---------------+---------------+
113 |``crash``    | The Native Client  | zero or   | After a       | Notify user   |
114 |             | module is not      | once      | ``loadend``.  | that the      |
115 |             | responding (died   |           |               | module did    |
116 |             | on an              |           |               | something     |
117 |             | ``assert()`` or    |           |               | illegal.      |
118 |             | ``exit()``) after  |           |               |               |
119 |             | a successful       |           |               |               |
120 |             | load. This event   |           |               |               |
121 |             | is unique to       |           |               |               |
122 |             | Native Client and  |           |               |               |
123 |             | is not part of     |           |               |               |
124 |             | the W3C Progress   |           |               |               |
125 |             | Events standard.   |           |               |               |
126 +-------------+--------------------+-----------+---------------+---------------+
127
128 The sequence of events for a successful module load is as follows:
129
130 =============================== ===============================
131 Event is dispatched             ... then this task is attempted
132 =============================== ===============================
133 ``loadstart``                   load the manifest file
134 ``progress`` (first time)       load the module
135 ``progress`` (subsequent times)
136 ``load``                        start executing the module
137 ``loadend``
138 =============================== ===============================
139
140 Errors that occur during loading are logged to the JavaScript console in Google
141 Chrome (select the menu icon |menu-icon| > Tools > JavaScript console).
142
143 .. |menu-icon| image:: /images/menu-icon.png
144
145 Handling progress events
146 ========================
147
148 You should add event listeners in a ``<script>`` element to listen for these
149 events before the ``<embed>`` element is parsed. For example, the following code
150 adds a listener for the ``load`` event to a parent ``<div>`` element that also
151 contains the Native Client ``<embed>`` element. First, the listener is
152 attached. Then, when the listener ``<div>`` receives the ``load`` event, the
153 JavaScript ``moduleDidLoad()`` function is called. The following code is
154 excerpted from the example in ``getting_started/part1/``:
155
156 .. naclcode::
157
158   <!--
159   Load the published pexe.
160   Note: Since this module does not use any real-estate in the browser, its
161   width and height are set to 0.
162
163   Note: The <embed> element is wrapped inside a <div>, which has both a 'load'
164   and a 'message' event listener attached.  This wrapping method is used
165   instead of attaching the event listeners directly to the <embed> element to
166   ensure that the listeners are active before the NaCl module 'load' event
167   fires.  This also allows you to use PPB_Messaging.PostMessage() (in C) or
168   pp::Instance.PostMessage() (in C++) from within the initialization code in
169   your module.
170   -->
171   <div id="listener">
172     <script type="text/javascript">
173       var listener = document.getElementById('listener');
174       listener.addEventListener('load', moduleDidLoad, true);
175       listener.addEventListener('message', handleMessage, true);
176     </script>
177
178     <embed id="hello_tutorial"
179            width=0 height=0
180            src="hello_tutorial.nmf"
181            type="application/x-pnacl" />
182   </div>
183
184 Event listeners can be added to any DOM object. Since listeners set at the
185 outermost scope capture events for their contained elements, you can set
186 listeners on outer elements (including the ``<body>`` element) to handle events
187 from inner elements. For more information, see the W3 specifications for `event
188 flow capture
189 <http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow-capture>`_ and
190 `event listener registration
191 <http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration>`_.
192
193 Displaying load status
194 ======================
195
196 One common response to progress events is to display the percentage of the
197 module that has been loaded. In the load_progress example, when the ``progress``
198 event is triggered the ``moduleLoadProgress`` function is called. This function
199 uses the ``lengthComputable``, ``loaded``, and ``total`` attributes (described
200 in the proposed W3C `Progress Events <http://www.w3.org/TR/progress-events/>`_
201 standard) of the event to calculate the percentage of the module that has
202 loaded.
203
204 .. naclcode::
205
206   function moduleLoadProgress(event) {
207     var loadPercent = 0.0;
208     var loadPercentString;
209     if (event.lengthComputable && event.total > 0) {
210       loadPercent = event.loaded / event.total * 100.0;
211       loadPercentString = loadPercent + '%';
212       common.logMessage('progress: ' + event.url + ' ' + loadPercentString +
213                        ' (' + event.loaded + ' of ' + event.total + ' bytes)');
214     } else {
215       // The total length is not yet known.
216       common.logMessage('progress: Computing...');
217     }
218   }
219
220 The ``lastError`` attribute
221 ===========================
222
223 The ``<embed>`` element has a ``lastError`` attribute that is set to an
224 informative string whenever a load failure (an ``error`` or ``abort`` event)
225 occurs.
226
227 The following code adds an event listener before the ``<embed>`` element to
228 capture and handle an error in loading the Native Client module. The
229 ``handleError()`` function listens for an ``error`` event. When an error occurs,
230 this function prints the contents of the ``lastError`` attribute
231 (``embed_element.lastError``) as an alert.
232
233 .. naclcode::
234
235   function domContentLoaded(name, tc, config, width, height) {
236     var listener = document.getElementById('listener');
237     ...
238     listener.addEventListener('error', moduleLoadError, true);
239     ...
240     common.createNaClModule(name, tc, config, width, height);
241   }
242
243   function moduleLoadError() {
244     common.logMessage('error: ' + common.naclModule.lastError);
245   }
246
247 The ``readyState`` attribute
248 ============================
249
250 You can use the ``readyState`` attribute to monitor the loading process. This
251 attribute is particularly useful if you don't care about the details of
252 individual progress events or when you want to poll for current load state
253 without registering listeners. The value of ``readyState`` progresses as follows
254 for a successful load:
255
256 ===================     ====================
257 Event                   ``readyState`` value
258 ===================     ====================
259 (before any events)     ``undefined``
260 ``loadstart``           1
261 ``progress``            3
262 ``load``                4
263 ``loadend``             4
264 ===================     ====================
265
266 The following code demonstrates how to monitor the loading process using the
267 ``readyState`` attribute. As before, the script that adds the event listeners
268 precedes the ``<embed>`` element so that the event listeners are in place before
269 the progress events are generated.
270
271 .. naclcode::
272
273   <html>
274   ...
275     <body id="body">
276       <div id="status_div">
277       </div>
278       <div id="listener_div">
279         <script type="text/javascript">
280            var stat = document.getElementById('status_div');
281            function handleEvent(e) {
282              var embed_element = document.getElementById('my_embed');
283              stat.innerHTML +=
284              '<br>' + e.type + ': readyState = ' + embed_element.readyState;
285            }
286            var listener_element = document.getElementById('listener_div');
287            listener_element.addEventListener('loadstart', handleEvent, true);
288            listener_element.addEventListener('progress', handleEvent, true);
289            listener_element.addEventListener('load', handleEvent, true);
290            listener_element.addEventListener('loadend', handleEvent, true);
291         </script>
292         <embed
293           name="naclModule"
294           id="my_embed"
295           width=0 height=0
296           src="my_example.nmf"
297           type="application/x-pnacl" />
298       </div>
299     </body>
300   </html>