Home | History | Annotate | Download | only in docs
      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>Tutorial: OAuth - 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&t13n_langs=en"></script>
    136           <script type="text/javascript" src="http://www.google.com/coop/cse/brand?form=cse&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><a href="messaging.html">Message Passing</a></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 class="leftNavSelected">OAuth</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">Tutorial: OAuth</h1>
    255       </div>
    256         <!-- TABLE OF CONTENTS -->
    257         <div id="toc">
    258           <h2>Contents</h2>
    259           <ol>
    260             <li>
    261               <a href="#requirements">Requirements</a>
    262               <ol>
    263                 <li style="display: none; ">
    264                   <a>h3Name</a>
    265                 </li>
    266               </ol>
    267             </li><li>
    268               <a href="#getting-started">Getting started</a>
    269               <ol>
    270                 <li style="display: none; ">
    271                   <a>h3Name</a>
    272                 </li>
    273               </ol>
    274             </li><li>
    275               <a href="#oauth-dance">The OAuth dance in an extension</a>
    276               <ol>
    277                 <li>
    278                   <a href="#set-code">Setup code</a>
    279                 </li><li>
    280                   <a href="#request-token">Fetching and authorizing a request token</a>
    281                 </li><li>
    282                   <a href="#signed-requests">Sending signed API requests</a>
    283                 </li>
    284               </ol>
    285             </li><li>
    286               <a href="#sample-code">Sample code</a>
    287               <ol>
    288                 <li style="display: none; ">
    289                   <a>h3Name</a>
    290                 </li>
    291               </ol>
    292             </li>
    293               <li style="display: none; ">
    294                 <a href="#apiReference">API reference</a>
    295                 <ol>
    296                   <li>
    297                     <a href="#properties">Properties</a>
    298                     <ol>
    299                       <li>
    300                         <a href="#property-anchor">propertyName</a>
    301                       </li>
    302                     </ol>
    303                   </li>
    304                   <li>
    305                     <a>Methods</a>
    306                     <ol>
    307                       <li>
    308                         <a href="#method-anchor">methodName</a>
    309                       </li>
    310                     </ol>
    311                   </li>
    312                   <li>
    313                     <a>Events</a>
    314                     <ol>
    315                       <li>
    316                         <a href="#event-anchor">eventName</a>
    317                       </li>
    318                     </ol>
    319                   </li>
    320                   <li>
    321                     <a href="#types">Types</a>
    322                     <ol>
    323                       <li>
    324                         <a href="#id-anchor">id</a>
    325                       </li>
    326                     </ol>
    327                   </li>
    328                 </ol>
    329               </li>
    330           </ol>
    331         </div>
    332         <!-- /TABLE OF CONTENTS -->
    333 
    334         <!-- Standard content lead-in for experimental API pages -->
    335         <p id="classSummary" style="display: none; ">
    336           For information on how to use experimental APIs, see the <a href="experimental.html">chrome.experimental.* APIs</a> page.
    337         </p>
    338 
    339         <!-- STATIC CONTENT PLACEHOLDER -->
    340         <div id="static"><div id="pageData-name" class="pageData">Tutorial: OAuth</div>
    341 <div id="pageData-showTOC" class="pageData">true</div>
    342 
    343 <p>
    344 <a href="http://oauth.net/">OAuth</a> is an open protocol that aims to standardize the way desktop and web applications access a user's private data. OAuth provides a mechanism for users to grant access to private data without sharing their private credentials (username/password). Many sites have started enabling APIs to use OAuth because of its security and standard set of libraries.
    345 </p>
    346 <p>
    347 This tutorial will walk you through the necessary steps for creating a Google Chrome Extension that uses OAuth to access an API. It leverages a library that you can reuse in your extensions.
    348 </p>
    349 <p>
    350 This tutorial uses the <a href="http://code.google.com/apis/documents/">Google Documents List Data API</a> as an example OAuth-enabled API endpoint.
    351 </p>
    352 
    353 <h2 id="requirements">Requirements</h2>
    354 
    355 <p>
    356 This tutorial expects that you have some experience writing extensions for Google Chrome and some familiarity with the <a href="http://code.google.com/apis/accounts/docs/OAuth.html">3-legged OAuth</a> flow. Although you dont need a background in the <a href="http://code.google.com/apis/documents/">Google Documents List Data API</a> (or the other <a href="http://code.google.com/apis/gdata/">Google Data APIs</a> for that matter), having a understanding of the protocol may be helpful.
    357 </p>
    358 
    359 <h2 id="getting-started">Getting started</h2>
    360 
    361 <p>
    362 First, copy over the three library files from the Chromium source tree at <a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/oauth_contacts/">.../examples/extensions/oauth_contacts/</a>:
    363 </p>
    364 <ul>
    365 <li><strong><a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.html?revision=34725&content-type=text/plain">chrome_ex_oauth.html</a></strong> - interstitial page for the oauth_callback URL</li>
    366 <li><strong><a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauth.js?content-type=text/plain">chrome_ex_oauth.js</a></strong> - core OAuth library</li>
    367 <li><strong><a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/oauth_contacts/chrome_ex_oauthsimple.js?content-type=text/plain">chrome_ex_oauthsimple.js</a></strong> - helpful wrapper for chrome_ex_oauth.js</li>
    368 </ul>
    369 
    370 <p>Place the three library files in the root of your extension directory (or wherever your JavaScript is stored). Then include both .js files in your background page in the following order:</p>
    371 
    372 <pre>&lt;script type="text/javascript" src="chrome_ex_oauthsimple.js"&gt;&lt;/script&gt;
    373 &lt;script type="text/javascript" src="chrome_ex_oauth.js"&gt;&lt;/script&gt;
    374 </pre>
    375 
    376 <p>Your background page will manage the OAuth flow.</p>
    377 
    378 <h2 id="oauth-dance">The OAuth dance in an extension</h2>
    379 
    380 <p>
    381 If you are familiar with the OAuth protocol, you'll recall that the OAuth dance consists of three steps:
    382 </p>
    383 
    384 <ol>
    385 <li>fetching an initial request token</li>
    386 <li>having the user authorize the request token</li>
    387 <li>fetching an access token</li>
    388 </ol>
    389 
    390 <p>In the context of an extension, this flow gets a bit tricky. Namely, there is no established consumer key/secret between the service provider and the application. That is, there is no web application URL for the user to be redirected to after the approval process.
    391 </p>
    392 
    393 <p>
    394 Luckily, Google and a few other companies have been working on an <a href="http://code.google.com/apis/accounts/docs/OAuthForInstalledApps.html">OAuth for installed applications</a> solution that you can use from an extension environment. In the installed applications OAuth dance, the consumer key/secret are anonymous/anonymous and you provide an <em>application name</em> for the user to grant access to (instead of an application URL). The end result is the same: your background page requests the initial token, opens a new tab to the approval page, and finally makes the asynchronous call for the access token.
    395 </p>
    396 
    397 <h3 id="set-code">Setup code</h3>
    398 
    399 <p>To initialize the library, create a <code>ChromeExOAuth</code> object in the background page:</p>
    400 
    401 <pre>var oauth = ChromeExOAuth.initBackgroundPage({
    402   'request_url': &lt;OAuth request URL&gt;,
    403   'authorize_url': &lt;OAuth authorize URL&gt;,
    404   'access_url': &lt;OAuth access token URL&gt;,
    405   'consumer_key': &lt;OAuth consumer key&gt;,
    406   'consumer_secret': &lt;OAuth consumer secret&gt;,
    407   'scope': &lt;scope of data access, not used by all OAuth providers&gt;,
    408   'app_name': &lt;application name, not used by all OAuth providers&gt;
    409 });
    410 </pre>
    411 
    412 <p>In the case of the Documents List API and Googles OAuth endpoints, a possible initialization may be:</p>
    413 
    414 <pre>var oauth = ChromeExOAuth.initBackgroundPage({
    415   'request_url': 'https://www.google.com/accounts/OAuthGetRequestToken',
    416   'authorize_url': 'https://www.google.com/accounts/OAuthAuthorizeToken',
    417   'access_url': 'https://www.google.com/accounts/OAuthGetAccessToken',
    418   'consumer_key': 'anonymous',
    419   'consumer_secret': 'anonymous',
    420   'scope': 'https://docs.google.com/feeds/',
    421   'app_name': 'My Google Docs Extension'
    422 });
    423 </pre>
    424 
    425 <h3 id="request-token">Fetching and authorizing a request token</h3>
    426 
    427 <p>
    428 Once you have your background page set up, call the <code>authorize()</code> function to begin the OAuth dance and redirect the user to the OAuth provider. The client library abstracts most of this process, so all you need to do is pass a callback to the <code>authorize()</code> function, and a new tab will open and redirect the user.
    429 </p>
    430 
    431 <pre>oauth.authorize(function() {
    432   // ... Ready to fetch private data ...
    433 });
    434 </pre>
    435 
    436 <p>
    437 You don't need to provide any additional logic for storing the token and secret, as this library already stores these values in the browsers <code>localStorage</code>. If the library already has an access token stored for the current scope, then no tab will be opened. In either case, the callback will be called.
    438 </p>
    439 
    440 <h3 id="signed-requests">Sending signed API requests</h3>
    441 
    442 <p>
    443 Once your specified callback is executed, call the <code>sendSignedRequest()</code> function to send signed requests to your API endpoint(s). <code>sendSignedRequest()</code> takes three arguments: a URI, a callback function, and an optional parameter object. The callback is passed two arguments: the response text and the <code>XMLHttpRequest</code> object that was used to make the request.
    444 </p>
    445 
    446 <p>This example sends an HTTP <code>GET</code>:</p>
    447 
    448 <pre>function callback(resp, xhr) {
    449   // ... Process text response ...
    450 };
    451 
    452 function onAuthorized() {
    453   var url = 'https://docs.google.com/feeds/default/private/full';
    454   var request = {
    455     'method': 'GET',
    456     'parameters': {'alt': 'json'}
    457   };
    458 
    459   // Send: GET https://docs.google.com/feeds/default/private/full?alt=json
    460   oauth.sendSignedRequest(url, callback, request);
    461 };
    462 
    463 oauth.authorize(onAuthorized);
    464 </pre>
    465 
    466 <p>A more complex example using an HTTP <code>POST</code> might look like this:</p>
    467 
    468 <pre>function onAuthorized() {
    469   var url = 'https://docs.google.com/feeds/default/private/full';
    470   var request = {
    471     'method': 'POST',
    472     'headers': {
    473       'GData-Version': '3.0',
    474       'Content-Type': 'application/atom+xml'
    475     },
    476     'parameters': {
    477       'alt': 'json'
    478     },
    479     'body': 'Data to send'
    480   };
    481 
    482   // Send: POST https://docs.google.com/feeds/default/private/full?alt=json
    483   oauth.sendSignedRequest(url, callback, request);
    484 };
    485 </pre>
    486 
    487 <p>
    488 By default, the <code>sendSignedRequest()</code> function sends the <code>oauth_*</code> parameters in the URL (by calling <code>oauth.signURL()</code>). If you prefer to send the <code>oauth_*</code> parameters in the <code>Authorization</code> header (or need direct access to the generated header), use <code>getAuthorizationHeader()</code>. Its arguments are a URI, an HTTP method, and an optional object of URL query parameters as key/value pairs.
    489 </p>
    490 
    491 <p>Here is the example above using <code>getAuthorizationHeader()</code> and an <code>XMLHttpRequest</code> object:</p>
    492 
    493 <pre>function stringify(parameters) {
    494   var params = [];
    495   for(var p in parameters) {
    496     params.push(encodeURIComponent(p) + '=' +
    497                 encodeURIComponent(parameters[p]));
    498   }
    499   return params.join('&amp;');
    500 };
    501 
    502 function onAuthorized() {
    503   var method = 'POST';
    504   var url = 'https://docs.google.com/feeds/default/private/full';
    505   var params = {'alt': 'json'};
    506 
    507   var xhr = new XMLHttpRequest();
    508   xhr.onreadystatechange = function(data) {
    509     callback(xhr, data);
    510   };
    511   xhr.setRequestHeader('GData-Version', '3.0');
    512   xhr.setRequestHeader('Content-Type', 'application/atom+xml');
    513   xhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
    514   xhr.open(method, url + '?' + stringify(params), true);
    515 
    516   xhr.send('Data to send');
    517 };
    518 </pre>
    519 
    520 <h2 id="sample-code">Sample code</h2>
    521 
    522 <p>
    523 Sample extensions that use these techniques are available in the Chromium source tree:
    524 </p>
    525 
    526 <ul>
    527 <li><a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/gdocs/">.../examples/extensions/gdocs/</a></li>
    528 <li><a href="http://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/extensions/docs/examples/extensions/oauth_contacts/">.../examples/extensions/oauth_contacts/</a></li>
    529 </ul>
    530 
    531 </div>
    532 
    533         <!-- API PAGE -->
    534         <div class="apiPage" style="display: none; ">
    535         <a name="apiReference"></a>
    536         <h2>API reference: chrome.apiname </h2>
    537 
    538           <!-- PROPERTIES -->
    539           <div class="apiGroup">
    540             <a name="properties"></a>
    541             <h3 id="properties">Properties</h3>
    542 
    543             <div>
    544               <a></a>
    545               <h4>getLastError</h4>
    546               <div class="summary">
    547                 <!-- Note: intentionally longer 80 columns -->
    548                 <span>chrome.extension</span><span>lastError</span>
    549               </div>
    550               <div>
    551               </div>
    552             </div>
    553 
    554           </div> <!-- /apiGroup -->
    555 
    556           <!-- METHODS -->
    557           <div id="methodsTemplate" class="apiGroup">
    558             <a></a>
    559             <h3>Methods</h3>
    560 
    561             <!-- iterates over all functions -->
    562             <div class="apiItem">
    563               <a></a> <!-- method-anchor -->
    564               <h4>method name</h4>
    565 
    566               <div class="summary"><span>void</span>
    567                   <!-- Note: intentionally longer 80 columns -->
    568                   <span>chrome.module.methodName</span>(<span><span>, </span><span></span>
    569                       <var><span></span></var></span>)</div>
    570 
    571               <div class="description">
    572                 <p class="todo">Undocumented.</p>
    573                 <p>
    574                   A description from the json schema def of the function goes here.
    575                 </p>
    576 
    577                 <!-- PARAMETERS -->
    578                 <h4>Parameters</h4>
    579                 <dl>
    580                   <div>
    581                     <div>
    582                     </div>
    583                   </div>
    584                 </dl>
    585 
    586                 <!-- RETURNS -->
    587                 <h4>Returns</h4>
    588                 <dl>
    589                   <div>
    590                     <div>
    591                     </div>
    592                   </div>
    593                 </dl>
    594 
    595                 <!-- CALLBACK -->
    596                 <div>
    597                   <div>
    598                   <h4>Callback function</h4>
    599                   <p>
    600                     The callback <em>parameter</em> should specify a function
    601                     that looks like this:
    602                   </p>
    603                   <p>
    604                     If you specify the <em>callback</em> parameter, it should
    605                     specify a function that looks like this:
    606                   </p>
    607 
    608                   <!-- Note: intentionally longer 80 columns -->
    609                   <pre>function(<span>Type param1, Type param2</span>) <span class="subdued">{...}</span>;</pre>
    610                   <dl>
    611                     <div>
    612                       <div>
    613                       </div>
    614                     </div>
    615                   </dl>
    616                   </div>
    617                 </div>
    618 
    619                 <!-- MIN_VERSION -->
    620                 <p>
    621                   This function was added in version <b><span></span></b>.
    622                   If you require this function, the manifest key
    623                   <a href="manifest.html#minimum_chrome_version">minimum_chrome_version</a>
    624                   can ensure that your extension won't be run in an earlier browser version.
    625                 </p>
    626               </div> <!-- /description -->
    627 
    628             </div>  <!-- /apiItem -->
    629 
    630           </div>  <!-- /apiGroup -->
    631 
    632           <!-- EVENTS -->
    633           <div id="eventsTemplate" class="apiGroup">
    634             <a></a>
    635             <h3>Events</h3>
    636             <!-- iterates over all events -->
    637             <div class="apiItem">
    638               <a></a>
    639               <h4>event name</h4>
    640 
    641               <div class="summary">
    642                 <!-- Note: intentionally longer 80 columns -->
    643                 <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>);
    644               </div>
    645 
    646               <div class="description">
    647                 <p class="todo">Undocumented.</p>
    648                 <p>
    649                   A description from the json schema def of the event goes here.
    650                 </p>
    651 
    652                 <!-- PARAMETERS -->
    653                 <div>
    654                   <h4>Parameters</h4>
    655                   <dl>
    656                     <div>
    657                       <div>
    658                       </div>
    659                     </div>
    660                   </dl>
    661                 </div>
    662               </div> <!-- /decription -->
    663 
    664             </div> <!-- /apiItem -->
    665 
    666           </div> <!-- /apiGroup -->
    667 
    668           <!-- TYPES -->
    669           <div class="apiGroup">
    670             <a name="types"></a>
    671             <h3 id="types">Types</h3>
    672 
    673             <!-- iterates over all types -->
    674             <div class="apiItem">
    675               <a></a>
    676               <h4>type name</h4>
    677 
    678               <div>
    679               </div>
    680 
    681             </div> <!-- /apiItem -->
    682 
    683           </div> <!-- /apiGroup -->
    684 
    685         </div> <!-- /apiPage -->
    686       </div> <!-- /gc-pagecontent -->
    687     </div> <!-- /g-section -->
    688   </div> <!-- /codesiteContent -->
    689     <div id="gc-footer" --="">
    690       <div class="text">
    691   <p>
    692   Except as otherwise <a href="http://code.google.com/policies.html#restrictions">noted</a>,
    693   the content of this page is licensed under the <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons
    694   Attribution 3.0 License</a>, and code samples are licensed under the
    695   <a rel="license" href="http://code.google.com/google_bsd_license.html">BSD License</a>.
    696   </p>
    697   <p>
    698   2011 Google
    699   </p>
    700 
    701 <!-- begin analytics -->
    702 <script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>
    703 <script src="http://www.google-analytics.com/ga.js" type="text/javascript"></script>
    704 
    705 <script type="text/javascript">
    706   // chrome doc tracking
    707   try {
    708     var engdocs = _gat._getTracker("YT-10763712-2");
    709     engdocs._trackPageview();
    710   } catch(err) {}
    711 
    712   // code.google.com site-wide tracking
    713   try {
    714     _uacct="UA-18071-1";
    715     _uanchor=1;
    716     _uff=0;
    717     urchinTracker();
    718   }
    719   catch(e) {/* urchinTracker not available. */}
    720 </script>
    721 <!-- end analytics -->
    722       </div>
    723     </div> <!-- /gc-footer -->
    724   </div> <!-- /gc-container -->
    725 </body></html>
    726