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