messaging.html revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
1<!DOCTYPE html><!-- This page is a placeholder for generated extensions api doc. Note:
2    1) The <head> information in this page is significant, should be uniform
3       across api docs and should be edited only with knowledge of the
4       templating mechanism.
5    3) All <body>.innerHTML is genereated as an rendering step. If viewed in a
6       browser, it will be re-generated from the template, json schema and
7       authored overview content.
8    4) The <body>.innerHTML is also generated by an offline step so that this
9       page may easily be indexed by search engines.
10--><html xmlns="http://www.w3.org/1999/xhtml"><head>
11    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
12    <link href="css/ApiRefStyles.css" rel="stylesheet" type="text/css">
13    <link href="css/print.css" rel="stylesheet" type="text/css" media="print">
14    <script type="text/javascript" src="/third_party/jstemplate/jstemplate_compiled.js">
15    </script>
16    <script type="text/javascript" src="js/api_page_generator.js"></script>
17    <script type="text/javascript" src="js/bootstrap.js"></script>
18    <script type="text/javascript" src="js/sidebar.js"></script>
19  <title>Message Passing - Google Chrome Extensions - Google Code</title></head>
20  <body>  <div id="gc-container" class="labs">
21      <div id="devModeWarning">
22        You are viewing extension docs in chrome via the 'file:' scheme: are you expecting to see local changes when you refresh? You'll need run chrome with --allow-file-access-from-files.
23      </div>
24      <!-- SUBTEMPLATES: DO NOT MOVE FROM THIS LOCATION -->
25      <!-- In particular, sub-templates that recurse, must be used by allowing
26           jstemplate to make a copy of the template in this section which
27           are not operated on by way of the jsskip="true" -->
28      <div style="display:none">
29
30        <!-- VALUE -->
31        <div id="valueTemplate">
32          <dt>
33            <var>paramName</var>
34              <em>
35
36                <!-- TYPE -->
37                <div style="display:inline">
38                  (
39                    <span class="optional">optional</span>
40                    <span class="enum">enumerated</span>
41                    <span id="typeTemplate">
42                      <span>
43                        <a> Type</a>
44                      </span>
45                      <span>
46                        <span>
47                          array of <span><span></span></span>
48                        </span>
49                        <span>paramType</span>
50                        <span></span>
51                      </span>
52                    </span>
53                  )
54                </div>
55
56              </em>
57          </dt>
58          <dd class="todo">
59            Undocumented.
60          </dd>
61          <dd>
62            Description of this parameter from the json schema.
63          </dd>
64          <dd>
65            This parameter was added in version
66            <b><span></span></b>.
67            You must omit this parameter in earlier versions,
68            and you may omit it in any version.  If you require this
69            parameter, the manifest key
70            <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
71            can ensure that your extension won't be run in an earlier browser version.
72          </dd>
73
74          <!-- OBJECT PROPERTIES -->
75          <dd>
76            <dl>
77              <div>
78                <div>
79                </div>
80              </div>
81            </dl>
82          </dd>
83
84          <!-- FUNCTION PARAMETERS -->
85          <dd>
86            <div></div>
87          </dd>
88
89        </div> <!-- /VALUE -->
90
91        <div id="functionParametersTemplate">
92          <h5>Parameters</h5>
93          <dl>
94            <div>
95              <div>
96              </div>
97            </div>
98          </dl>
99        </div>
100      </div> <!-- /SUBTEMPLATES -->
101
102  <a id="top"></a>
103    <div id="skipto">
104      <a href="#gc-pagecontent">Skip to page content</a>
105      <a href="#gc-toc">Skip to main navigation</a>
106    </div>
107    <!-- API HEADER -->
108    <table id="header" width="100%" cellspacing="0" border="0">
109      <tbody><tr>
110        <td valign="middle"><a href="http://code.google.com/"><img src="images/code_labs_logo.gif" height="43" width="161" alt="Google Code Labs" style="border:0; margin:0;"></a></td>
111        <td valign="middle" width="100%" style="padding-left:0.6em;">
112          <form action="http://www.google.com/cse" id="cse" style="margin-top:0.5em">
113            <div id="gsc-search-box">
114              <input type="hidden" name="cx" value="002967670403910741006:61_cvzfqtno">
115              <input type="hidden" name="ie" value="UTF-8">
116              <input type="text" name="q" value="" size="55">
117              <input class="gsc-search-button" type="submit" name="sa" value="Search">
118              <br>
119              <span class="greytext">e.g. "page action" or "tabs"</span>
120            </div>
121          </form>
122
123          <script type="text/javascript" src="http://www.google.com/jsapi"></script>
124          <script type="text/javascript">google.load("elements", "1", {packages: "transliteration"});</script>
125          <script type="text/javascript" src="http://www.google.com/coop/cse/t13n?form=cse&t13n_langs=en"></script>
126          <script type="text/javascript" src="http://www.google.com/coop/cse/brand?form=cse&lang=en"></script>
127        </td>
128      </tr>
129    </tbody></table>
130
131    <div id="codesiteContent" class="">
132
133      <a id="gc-topnav-anchor"></a>
134      <div id="gc-topnav">
135        <h1>Google Chrome Extensions (<a href="http://code.google.com/labs/">Labs</a>)</h1>
136        <ul id="home" class="gc-topnav-tabs">
137          <li id="home_link">
138            <a href="index.html" title="Google Chrome Extensions home page">Home</a>
139          </li>
140          <li id="docs_link">
141            <a href="docs.html" title="Official Google Chrome Extensions documentation">Docs</a>
142          </li>
143          <li id="faq_link">
144            <a href="faq.html" title="Answers to frequently asked questions about Google Chrome Extensions">FAQ</a>
145          </li>
146          <li id="samples_link">
147            <a href="samples.html" title="Sample extensions (with source code)">Samples</a>
148          </li>
149          <li id="group_link">
150            <a href="http://groups.google.com/a/chromium.org/group/chromium-extensions" title="Google Chrome Extensions developer forum">Group</a>
151          </li>
152        </ul>
153      </div> <!-- end gc-topnav -->
154
155    <div class="g-section g-tpl-170">
156      <!-- SIDENAV -->
157      <div class="g-unit g-first" id="gc-toc">
158        <ul>
159          <li><a href="getstarted.html">Getting Started</a></li>
160          <li><a href="overview.html">Overview</a></li>
161          <li><a href="whats_new.html">What's New?</a></li>
162          <li><h2><a href="devguide.html">Developer's Guide</a></h2>
163            <ul>
164              <li>Browser UI
165                <ul>
166                  <li><a href="browserAction.html">Browser Actions</a></li>
167                  <li><a href="contextMenus.html">Context Menus</a></li>
168                  <li><a href="notifications.html">Desktop Notifications</a></li>
169                  <li><a href="options.html">Options Pages</a></li>
170                  <li><a href="override.html">Override Pages</a></li>
171                  <li><a href="pageAction.html">Page Actions</a></li>
172                  <li><a href="themes.html">Themes</a></li>
173                </ul>
174              </li>
175              <li>Browser Interaction
176                <ul>
177                  <li><a href="bookmarks.html">Bookmarks</a></li>
178                  <li><a href="cookies.html">Cookies</a></li>
179                  <li><a href="events.html">Events</a></li>
180                  <li><a href="history.html">History</a></li>
181                  <li><a href="management.html">Management</a></li>
182                  <li><a href="tabs.html">Tabs</a></li>
183                  <li><a href="windows.html">Windows</a></li>
184                </ul>
185              </li>
186              <li>Implementation
187                <ul>
188                  <li><a href="a11y.html">Accessibility</a></li>
189                  <li><a href="background_pages.html">Background Pages</a></li>
190                  <li><a href="content_scripts.html">Content Scripts</a></li>
191                  <li><a href="xhr.html">Cross-Origin XHR</a></li>
192                  <li><a href="idle.html">Idle</a></li>
193                  <li><a href="i18n.html">Internationalization</a></li>
194                  <li class="leftNavSelected">Message Passing</li>
195                  <li><a href="npapi.html">NPAPI Plugins</a></li>
196                </ul>
197              </li>
198              <li>Finishing
199                <ul>
200                  <li><a href="hosting.html">Hosting</a></li>
201                  <li><a href="external_extensions.html">Other Deployment Options</a></li>
202                </ul>
203              </li>
204            </ul>
205          </li>
206          <li><h2><a href="tutorials.html">Tutorials</a></h2>
207            <ul>
208              <li><a href="tut_debugging.html">Debugging</a></li>
209              <li><a href="tut_analytics.html">Google Analytics</a></li>
210              <li><a href="tut_oauth.html">OAuth</a></li>
211            </ul>
212          </li>
213          <li><h2>Reference</h2>
214            <ul>
215              <li>Formats
216                <ul>
217                  <li><a href="manifest.html">Manifest Files</a></li>
218                  <li><a href="match_patterns.html">Match Patterns</a></li>
219                  <!-- <li>Packages (.crx)</li> -->
220                </ul>
221              </li>
222              <li><a href="api_index.html">chrome.* APIs</a></li>
223              <li><a href="api_other.html">Other APIs</a></li>
224            </ul>
225          </li>
226          <li><h2><a href="samples.html">Samples</a></h2></li>
227          <div class="line"> </div>
228          <li><h2>More</h2>
229            <ul>
230              <li><a href="http://code.google.com/chrome/webstore/docs/index.html">Chrome Web Store</a></li>
231              <li><a href="http://code.google.com/chrome/apps/docs/developers_guide.html">Installable Web Apps</a></li>
232              <li><a href="themes.html">Themes</a></li>
233            </ul>
234          </li>
235        </ul>
236      </div>
237      <script>
238        initToggles();
239      </script>
240
241    <div class="g-unit" id="gc-pagecontent">
242      <div id="pageTitle">
243        <h1 class="page_title">Message Passing</h1>
244      </div>
245        <!-- TABLE OF CONTENTS -->
246        <div id="toc">
247          <h2>Contents</h2>
248          <ol>
249            <li>
250              <a href="#simple">Simple one-time requests</a>
251              <ol>
252                <li style="display: none; ">
253                  <a>h3Name</a>
254                </li>
255              </ol>
256            </li><li>
257              <a href="#connect">Long-lived connections</a>
258              <ol>
259                <li style="display: none; ">
260                  <a>h3Name</a>
261                </li>
262              </ol>
263            </li><li>
264              <a href="#external">Cross-extension messaging</a>
265              <ol>
266                <li style="display: none; ">
267                  <a>h3Name</a>
268                </li>
269              </ol>
270            </li><li>
271              <a href="#security-considerations">Security considerations</a>
272              <ol>
273                <li style="display: none; ">
274                  <a>h3Name</a>
275                </li>
276              </ol>
277            </li><li>
278              <a href="#examples">Examples</a>
279              <ol>
280                <li style="display: none; ">
281                  <a>h3Name</a>
282                </li>
283              </ol>
284            </li>
285              <li style="display: none; ">
286                <a href="#apiReference">API reference</a>
287                <ol>
288                  <li>
289                    <a href="#properties">Properties</a>
290                    <ol>
291                      <li>
292                        <a href="#property-anchor">propertyName</a>
293                      </li>
294                    </ol>
295                  </li>
296                  <li>
297                    <a href="#methods">Methods</a>
298                    <ol>
299                      <li>
300                        <a href="#method-anchor">methodName</a>
301                      </li>
302                    </ol>
303                  </li>
304                  <li>
305                    <a href="#events">Events</a>
306                    <ol>
307                      <li>
308                        <a href="#event-anchor">eventName</a>
309                      </li>
310                    </ol>
311                  </li>
312                  <li>
313                    <a href="#types">Types</a>
314                    <ol>
315                      <li>
316                        <a href="#id-anchor">id</a>
317                      </li>
318                    </ol>
319                  </li>
320                </ol>
321              </li>
322          </ol>
323        </div>
324        <!-- /TABLE OF CONTENTS -->
325
326        <!-- Standard content lead-in for experimental API pages -->
327        <p id="classSummary" style="display: none; ">
328          For information on how to use experimental APIs, see the <a href="experimental.html">chrome.experimental.* APIs</a> page.
329        </p>
330
331        <!-- STATIC CONTENT PLACEHOLDER -->
332        <div id="static"><div id="pageData-name" class="pageData">Message Passing</div>
333<div id="pageData-showTOC" class="pageData">true</div>
334
335<p>
336Since content scripts run in the context of a web page and not the extension,
337they often need some way of communicating with the rest of the extension. For
338example, an RSS reader extension might use content scripts to detect the
339presence of an RSS feed on a page, then notify the background page in order to
340display a page action icon for that page.
341
342</p><p>
343Communication between extensions and their content scripts works by using
344message passing. Either side can listen for messages sent from the other end,
345and respond on the same channel. A message can contain any valid JSON object
346(null, boolean, number, string, array, or object). There is a simple API for
347<a href="#simple">one-time requests</a>
348and a more complex API that allows you to have
349<a href="#connect">long-lived connections</a>
350for exchanging multiple messages with a shared context. It is also possible to
351send a message to another extension if you know its ID, which is covered in
352the
353<a href="#external">cross-extension messages</a>
354section.
355
356
357</p><h2 id="simple">Simple one-time requests</h2>
358<p>
359If you only need to send a single message to another part of your extension
360(and optionally get a response back), you should use the simplified
361<a href="extension.html#method-sendRequest">chrome.extension.sendRequest()</a>
362or
363<a href="tabs.html#method-sendRequest">chrome.tabs.sendRequest()</a>
364methods. This lets you send a one-time JSON-serializable message from a
365content script to extension, or vice versa, respectively. An optional
366callback parameter allows you handle the response from the other side, if
367there is one.
368
369</p><p>
370Sending a request from a content script looks like this:
371</p><pre>contentscript.js
372================
373chrome.extension.sendRequest({greeting: "hello"}, function(response) {
374  console.log(response.farewell);
375});
376</pre>
377
378<p>
379Sending a request from the extension to a content script looks very similar,
380except that you need to specify which tab to send it to. This example
381demonstrates sending a message to the content script in the selected tab.
382</p><pre>background.html
383===============
384chrome.tabs.getSelected(null, function(tab) {
385  chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
386    console.log(response.farewell);
387  });
388});
389</pre>
390
391<p>
392On the receiving end, you need to set up an
393<a href="extension.html#event-onRequest">chrome.extension.onRequest</a>
394event listener to handle the message. This looks the same from a content
395script or extension page. The request will remain open until you call
396sendResponse, so it is good practice to call sendResponse with an empty
397object to allow the request to be cleaned up.
398</p><pre>chrome.extension.onRequest.addListener(
399  function(request, sender, sendResponse) {
400    console.log(sender.tab ?
401                "from a content script:" + sender.tab.url :
402                "from the extension");
403    if (request.greeting == "hello")
404      sendResponse({farewell: "goodbye"});
405    else
406      sendResponse({}); // snub them.
407  });
408</pre>
409
410<p class="note">
411<b>Note:</b> If multiple pages are listening for onRequest events, only the
412first to call sendResponse() for a particular event will succeed in sending the
413response. All other responses to that event will be ignored.
414</p>
415
416
417<h2 id="connect">Long-lived connections</h2>
418<p>
419Sometimes it's useful to have a conversation that lasts longer than a single
420request and response. In this case, you can open a long-lived channel from
421your content script to an extension page, or vice versa, using
422<a href="extension.html#method-connect">chrome.extension.connect()</a>
423or
424<a href="tabs.html#method-connect">chrome.tabs.connect()</a> respectively. The
425channel can optionally have a name, allowing you to distinguish between
426different types of connections.
427
428</p><p>
429One use case might be an automatic form fill extension. The content script
430could open a channel to the extension page for a particular login, and send a
431message to the extension for each input element on the page to request the
432form data to fill in. The shared connection allows the extension to keep
433shared state linking the several messages coming from the content script.
434
435</p><p>
436When establishing a connection, each end is given a
437<a href="extension.html#type-Port">Port</a>
438object which is used for sending and receiving messages through that
439connection.
440
441</p><p>
442Here is how you open a channel from a content script, and send and listen for
443messages:
444</p><pre>contentscript.js
445================
446var port = chrome.extension.connect({name: "knockknock"});
447port.postMessage({joke: "Knock knock"});
448port.onMessage.addListener(function(msg) {
449  if (msg.question == "Who's there?")
450    port.postMessage({answer: "Madame"});
451  else if (msg.question == "Madame who?")
452    port.postMessage({answer: "Madame... Bovary");
453});
454</pre>
455
456<p>
457Sending a request from the extension to a content script looks very similar,
458except that you need to specify which tab to connect to. Simply replace the
459call to connect in the above example with
460<a href="tabs.html#method-connect">chrome.tabs.connect(tabId, {name:
461"knockknock"})</a>.
462
463</p><p>
464In order to handle incoming connections, you need to set up a
465<a href="extension.html#event-onConnect">chrome.extension.onConnect</a>
466event listener. This looks the same from a content script or an extension
467page. When another part of your extension calls "connect()", this event is
468fired, along with the
469<a href="extension.html#type-Port">Port</a>
470object you can use to send and receive messages through the connection. Here's
471what it looks like to respond to incoming connections:
472</p><pre>chrome.extension.onConnect.addListener(function(port) {
473  console.assert(port.name == "knockknock");
474  port.onMessage.addListener(function(msg) {
475    if (msg.joke == "Knock knock")
476      port.postMessage({question: "Who's there?"});
477    else if (msg.answer == "Madame")
478      port.postMessage({question: "Madame who?"});
479    else if (msg.answer == "Madame... Bovary")
480      port.postMessage({question: "I don't get it."});
481  });
482});
483</pre>
484
485<p>
486You may want to find out when a connection is closed, for example if you are
487maintaining separate state for each open port. For this you can listen to the
488<a href="extension.html#type-Port">Port.onDisconnect</a>
489event. This event is fired either when the other side of the channel manually
490calls
491<a href="extension.html#type-Port">Port.disconnect()</a>, or when the page
492containing the port is unloaded (for example if the tab is navigated).
493onDisconnect is guaranteed to be fired only once for any given port.
494
495
496</p><h2 id="external">Cross-extension messaging</h2>
497<p>
498In addition to sending messages between different components in your
499extension, you can use the messaging API to communicate with other extensions.
500This lets you expose a public API that other extensions can take advantage of.
501
502</p><p>
503Listening for incoming requests and connections is similar to the internal
504case, except you use the
505<a href="extension.html#event-onRequestExternal">chrome.extension.onRequestExternal</a>
506or
507<a href="extension.html#event-onConnectExternal">chrome.extension.onConnectExternal</a>
508methods. Here's an example of each:
509</p><pre>// For simple requests:
510chrome.extension.onRequestExternal.addListener(
511  function(request, sender, sendResponse) {
512    if (sender.id == blacklistedExtension)
513      sendResponse({});  // don't allow this extension access
514    else if (request.getTargetData)
515      sendResponse({targetData: targetData});
516    else if (request.activateLasers) {
517      var success = activateLasers();
518      sendResponse({activateLasers: success});
519    }
520  });
521
522// For long-lived connections:
523chrome.extension.onConnectExternal.addListener(function(port) {
524  port.onMessage.addListener(function(msg) {
525    // See other examples for sample onMessage handlers.
526  });
527});
528</pre>
529
530<p>
531Likewise, sending a message to another extension is similar to sending one
532within your extension. The only difference is that you must pass the ID of the
533extension you want to communicate with. For example:
534</p><pre>// The ID of the extension we want to talk to.
535var laserExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";
536
537// Make a simple request:
538chrome.extension.sendRequest(laserExtensionId, {getTargetData: true},
539  function(response) {
540    if (targetInRange(response.targetData))
541      chrome.extension.sendRequest(laserExtensionId, {activateLasers: true});
542  });
543
544// Start a long-running conversation:
545var port = chrome.extension.connect(laserExtensionId);
546port.postMessage(...);
547</pre>
548
549<h2 id="security-considerations">Security considerations</h2>
550
551<p>
552When receiving a message from a content script or another extension, your
553background page should be careful not to fall victim to <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">cross-site
554scripting</a>.  Specifically, avoid using dangerous APIs such as the
555below:
556</p>
557<pre>background.html
558===============
559chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
560  // WARNING! Might be evaluating an evil script!
561  var resp = eval("(" + response.farewell + ")");
562});
563
564background.html
565===============
566chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
567  // WARNING! Might be injecting a malicious script!
568  document.getElementById("resp").innerHTML = response.farewell;
569});
570</pre>
571<p>
572Instead, prefer safer APIs that do not run scripts:
573</p>
574<pre>background.html
575===============
576chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
577  // JSON.parse does not evaluate the attacker's scripts.
578  var resp = JSON.parse(response.farewell);
579});
580
581background.html
582===============
583chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) {
584  // innerText does not let the attacker inject HTML elements.
585  document.getElementById("resp").innerText = response.farewell;
586});
587</pre>
588
589<h2 id="examples">Examples</h2>
590
591<p>
592You can find simple examples of communication via messages in the
593<a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/api/messaging/">examples/api/messaging</a>
594directory.
595Also see the
596<a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/howto/contentscript_xhr">contentscript_xhr</a> example,
597in which a content script and its parent extension exchange messages,
598so that the parent extension can perform
599cross-site requests on behalf of the content script.
600For more examples and for help in viewing the source code, see
601<a href="samples.html">Samples</a>.
602</p>
603</div>
604
605        <!-- API PAGE -->
606        <div class="apiPage" style="display: none; ">
607        <a name="apiReference"></a>
608        <h2>API reference: chrome.apiname </h2>
609
610          <!-- PROPERTIES -->
611          <div class="apiGroup">
612            <a name="properties"></a>
613            <h3 id="properties">Properties</h3>
614
615            <div>
616              <a></a>
617              <h4>getLastError</h4>
618              <div class="summary">
619                <!-- Note: intentionally longer 80 columns -->
620                <span>chrome.extension</span><span>lastError</span>
621              </div>
622              <div>
623              </div>
624            </div>
625
626          </div> <!-- /apiGroup -->
627
628          <!-- METHODS -->
629          <div class="apiGroup" id="methods">
630            <a name="methods"></a>
631            <h3>Methods</h3>
632
633            <!-- iterates over all functions -->
634            <div class="apiItem">
635              <a></a> <!-- method-anchor -->
636              <h4>method name</h4>
637
638              <div class="summary"><span>void</span>
639                  <!-- Note: intentionally longer 80 columns -->
640                  <span>chrome.module.methodName</span>(<span><span>, </span><span></span>
641                      <var><span></span></var></span>)</div>
642
643              <div class="description">
644                <p class="todo">Undocumented.</p>
645                <p>
646                  A description from the json schema def of the function goes here.
647                </p>
648
649                <!-- PARAMETERS -->
650                <h4>Parameters</h4>
651                <dl>
652                  <div>
653                    <div>
654                    </div>
655                  </div>
656                </dl>
657
658                <!-- RETURNS -->
659                <h4>Returns</h4>
660                <dl>
661                  <div>
662                    <div>
663                    </div>
664                  </div>
665                </dl>
666
667                <!-- CALLBACK -->
668                <div>
669                  <div>
670                  <h4>Callback function</h4>
671                  <p>
672                    The callback <em>parameter</em> should specify a function
673                    that looks like this:
674                  </p>
675                  <p>
676                    If you specify the <em>callback</em> parameter, it should
677                    specify a function that looks like this:
678                  </p>
679
680                  <!-- Note: intentionally longer 80 columns -->
681                  <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
682                  <dl>
683                    <div>
684                      <div>
685                      </div>
686                    </div>
687                  </dl>
688                  </div>
689                </div>
690
691                <!-- MIN_VERSION -->
692                <p>
693                  This function was added in version <b><span></span></b>.
694                  If you require this function, the manifest key
695                  <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
696                  can ensure that your extension won't be run in an earlier browser version.
697                </p>
698              </div> <!-- /description -->
699
700            </div>  <!-- /apiItem -->
701
702          </div>  <!-- /apiGroup -->
703
704          <!-- EVENTS -->
705          <div class="apiGroup">
706            <a name="events"></a>
707            <h3 id="events">Events</h3>
708
709            <!-- iterates over all events -->
710            <div class="apiItem">
711              <a></a>
712              <h4>event name</h4>
713
714              <div class="summary">
715                <!-- Note: intentionally longer 80 columns -->
716                <span class="subdued">chrome.bookmarks</span><span>onEvent</span><span class="subdued">.addListener</span>(function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>);
717              </div>
718
719              <div class="description">
720                <p class="todo">Undocumented.</p>
721                <p>
722                  A description from the json schema def of the event goes here.
723                </p>
724
725                <!-- PARAMETERS -->
726                <h4>Parameters</h4>
727                <dl>
728                  <div>
729                    <div>
730                    </div>
731                  </div>
732                </dl>
733
734              </div> <!-- /decription -->
735
736            </div> <!-- /apiItem -->
737
738          </div> <!-- /apiGroup -->
739
740          <!-- TYPES -->
741          <div class="apiGroup">
742            <a name="types"></a>
743            <h3 id="types">Types</h3>
744
745            <!-- iterates over all types -->
746            <div class="apiItem">
747              <a></a>
748              <h4>type name</h4>
749
750              <div>
751              </div>
752
753            </div> <!-- /apiItem -->
754
755          </div> <!-- /apiGroup -->
756
757        </div> <!-- /apiPage -->
758      </div> <!-- /gc-pagecontent -->
759    </div> <!-- /g-section -->
760  </div> <!-- /codesiteContent -->
761    <div id="gc-footer" --="">
762      <div class="text">
763  <p>
764  Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>,
765  the content of this page is licensed under the <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons
766  Attribution 3.0 License</a>, and code samples are licensed under the
767  <a rel="license" href="http://code.google.com/google_bsd_license.html">BSD License</a>.
768  </p>
769  <p>
770  ©2010 Google
771  </p>
772
773<!-- begin analytics -->
774<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
775<script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>
776
777<script type="text/javascript">
778  // chrome doc tracking
779  try {
780    var engdocs = _gat._getTracker("YT-10763712-2");
781    engdocs._trackPageview();
782  } catch(err) {}
783
784  // code.google.com site-wide tracking
785  try {
786    _uacct="UA-18071-1";
787    _uanchor=1;
788    _uff=0;
789    urchinTracker();
790  }
791  catch(e) {/* urchinTracker not available. */}
792</script>
793<!-- end analytics -->
794      </div>
795    </div> <!-- /gc-footer -->
796  </div> <!-- /gc-container -->
797</body></html>
798