OLD | NEW |
(Empty) | |
| 1 <h1>Overview</h1> |
| 2 |
| 3 |
| 4 <p> |
| 5 Once you've finished this page |
| 6 and the |
| 7 <a href="getstarted.html">Getting Started</a> tutorial, |
| 8 you'll be all set to start writing extensions and packaged apps. |
| 9 </p> |
| 10 |
| 11 <p class="caution"> |
| 12 <strong>Note:</strong> |
| 13 <em>Packaged apps</em> are implemented as extensions, |
| 14 so unless otherwise stated, |
| 15 everything in this page applies to packaged apps. |
| 16 </p> |
| 17 |
| 18 <h2 id="what">The basics</h2> |
| 19 |
| 20 <p> |
| 21 An extension is a zipped bundle of files—HTML, |
| 22 CSS, JavaScript, images, and anything else you need—that |
| 23 adds functionality to the Google Chrome browser. |
| 24 Extensions are essentially web pages, |
| 25 and they can use all the |
| 26 <a href="api_other.html">APIs that the browser provides to web pages</a>, |
| 27 from XMLHttpRequest to JSON to HTML5. |
| 28 </p> |
| 29 |
| 30 <p> |
| 31 Extensions can interact with web pages or servers using |
| 32 <a href="content_scripts.html">content scripts</a> or |
| 33 <a href="xhr.html">cross-origin XMLHttpRequests</a>. |
| 34 Extensions can also interact programmatically |
| 35 with browser features such as |
| 36 <a href="bookmarks.html">bookmarks</a> |
| 37 and <a href="tabs.html">tabs</a>. |
| 38 </p> |
| 39 |
| 40 <h3 id="extension-ui">Extension UIs</h3> |
| 41 |
| 42 <p> |
| 43 Many extensions—but not packaged apps—add |
| 44 UI to Google Chrome in the form of |
| 45 <a href="browserAction.html">browser actions</a> |
| 46 or <a href="pageAction.html">page actions</a>. |
| 47 Each extension can have at most one browser action or page action. |
| 48 Choose a <b>browser action</b> when the extension is relevant to most pages. |
| 49 Choose a <b>page action</b> when the extension's icon |
| 50 should appear or disappear, |
| 51 depending on the page. |
| 52 </p> |
| 53 |
| 54 <table class="columns"> |
| 55 <tr> |
| 56 <td width="33%"> |
| 57 <img src="{{static}}/images/overview/browser-action.png" |
| 58 width="147" height="100" |
| 59 alt="screenshot" /> |
| 60 </td> |
| 61 <td width="33%"> |
| 62 <img src="{{static}}/images/overview/page-action.png" |
| 63 width="147" height="100" |
| 64 alt="screenshot" /> |
| 65 </td> |
| 66 <td> |
| 67 <img src="{{static}}/images/overview/browser-action-with-popup.png" |
| 68 width="147" height="100" |
| 69 alt="screenshot" /> |
| 70 </td> |
| 71 </tr> |
| 72 |
| 73 <tr> |
| 74 <td> |
| 75 This <a href="samples.html#gmail">mail extension</a> |
| 76 uses a <em>browser action</em> |
| 77 (icon in the toolbar). |
| 78 </td> |
| 79 <td> |
| 80 This <a href="samples.html#mappy">map extension</a> |
| 81 uses a <em>page action</em> |
| 82 (icon in the address bar) |
| 83 and <em>content script</em> |
| 84 (code injected into a web page). |
| 85 </td> |
| 86 <td> |
| 87 This <a href="samples.html#news">news extension</a> |
| 88 features a browser action that, |
| 89 when clicked, |
| 90 shows a <em>popup</em>. |
| 91 </td> |
| 92 </tr> |
| 93 </table> |
| 94 |
| 95 <p> |
| 96 Extensions (and packaged apps) can also present a UI in other ways, |
| 97 such as adding to the Chrome context menu, |
| 98 providing an options page, |
| 99 or using a content script that changes how pages look. |
| 100 See the <a href="devguide.html">Developer's Guide</a> |
| 101 for a complete list of extension features, |
| 102 with links to implementation details |
| 103 for each one. |
| 104 </p> |
| 105 |
| 106 |
| 107 <h3 id="packagedapp-ui">Packaged app UIs</h3> |
| 108 |
| 109 <p> |
| 110 A packaged app usually presents its main functionality using |
| 111 an HTML page that's bundled into the app. |
| 112 For example, the following packaged app |
| 113 displays a Flash file within an HTML page. |
| 114 </p> |
| 115 |
| 116 <img src="{{static}}/images/overview/flash-app.png" |
| 117 width="372" height="300" |
| 118 alt="screenshot" /> |
| 119 |
| 120 <p> |
| 121 For more information, |
| 122 see <a href="apps.html">Packaged Apps</a>. |
| 123 </p> |
| 124 |
| 125 <h2 id="files">Files</h2> |
| 126 <p> |
| 127 Each extension has the following files: |
| 128 |
| 129 </p> |
| 130 |
| 131 <ul> |
| 132 <li>A <b>manifest file</b></li> |
| 133 <li>One or more <b>HTML files</b> (unless the extension is a theme)</li> |
| 134 <li><em>Optional:</em> One or more <b>JavaScript files</b></li> |
| 135 <li><em>Optional:</em> Any other files your extension needs—for |
| 136 example, image files</li> |
| 137 </ul> |
| 138 |
| 139 <p> |
| 140 While you're working on your extension, |
| 141 you put all these files into a single folder. |
| 142 When you distribute your extension, |
| 143 the contents of the folder are packaged into a special ZIP file |
| 144 that has a <code>.crx</code> suffix. |
| 145 If you upload your extension using the |
| 146 <a href="https://chrome.google.com/webstore/developer/dashboard">Chrome Develope
r Dashboard</a>, |
| 147 the <code>.crx</code> file is created for you. |
| 148 For details on distributing extensions, |
| 149 see <a href="hosting.html">Hosting</a>. |
| 150 </p> |
| 151 |
| 152 |
| 153 <h3 id="relative-urls">Referring to files</h3> |
| 154 |
| 155 <p> |
| 156 You can put any file you like into an extension, |
| 157 but how do you use it? |
| 158 Usually, |
| 159 you can refer to the file using a relative URL, |
| 160 just as you would in an ordinary HTML page. |
| 161 Here's an example of referring to |
| 162 a file named <code>myimage.png</code> |
| 163 that's in a subfolder named <code>images</code>. |
| 164 </p> |
| 165 |
| 166 <pre> |
| 167 <img <b>src="images/myimage.png"</b>> |
| 168 </pre> |
| 169 |
| 170 <p> |
| 171 As you might notice while you use the Google Chrome debugger, |
| 172 every file in an extension is also accessible by an absolute URL like this: |
| 173 </p> |
| 174 |
| 175 <blockquote> |
| 176 <b>chrome-extension://</b><em><extensionID></em><b>/</b><em><pathToFile></
em> |
| 177 </blockquote> |
| 178 |
| 179 <p> |
| 180 In that URL, the <em><extensionID></em> is a unique identifier |
| 181 that the extension system generates for each extension. |
| 182 You can see the IDs for all your loaded extensions |
| 183 by going to the URL <b>chrome://extensions</b>. |
| 184 The <em><pathToFile></em> is the location of the file |
| 185 under the extension's top folder; |
| 186 it's the same as the relative URL. |
| 187 </p> |
| 188 |
| 189 <p> |
| 190 While you're working on an extension |
| 191 (before it's packaged), |
| 192 the extension ID can change. |
| 193 Specifically, the ID of an unpacked extension will change |
| 194 if you load the extension from a different directory; |
| 195 the ID will change again when you package the extension. |
| 196 If your extension's code |
| 197 needs to specify the full path to a file within the extension, |
| 198 you can use the <code>@@extension_id</code> |
| 199 <a href="i18n.html#overview-predefined">predefined message</a> |
| 200 to avoid hardcoding the ID during development. |
| 201 </p> |
| 202 |
| 203 <p> |
| 204 When you package an extension |
| 205 (typically, by uploading it with the dashboard), |
| 206 the extension gets a permanent ID, |
| 207 which remains the same even after you update the extension. |
| 208 Once the extension ID is permanent, |
| 209 you can change all occurrences of |
| 210 <code>@@extension_id</code> to use the real ID. |
| 211 </p> |
| 212 |
| 213 |
| 214 <h3>The manifest file</h3> |
| 215 |
| 216 <p> |
| 217 The manifest file, called <code>manifest.json</code>, |
| 218 gives information about the extension, |
| 219 such as the most important files |
| 220 and the capabilities that the extension might use. |
| 221 Here's a typical manifest file for a browser action |
| 222 that uses information from google.com: |
| 223 </p> |
| 224 |
| 225 <pre> |
| 226 { |
| 227 "name": "My Extension", |
| 228 "version": "2.1", |
| 229 "description": "Gets information from Google.", |
| 230 "icons": { "128": "icon_128.png" }, |
| 231 "background": { |
| 232 "scripts": ["bg.js"] |
| 233 }, |
| 234 "permissions": ["http://*.google.com/", "https://*.google.com/"], |
| 235 "browser_action": { |
| 236 "default_title": "", |
| 237 "default_icon": "icon_19.png", |
| 238 "default_popup": "popup.html" |
| 239 } |
| 240 }</pre> |
| 241 |
| 242 <p> |
| 243 For details, see |
| 244 <a href="manifest.html">Manifest Files</a>. |
| 245 </p> |
| 246 |
| 247 <h2 id="arch">Architecture</h2> |
| 248 |
| 249 <p> |
| 250 Many extensions have a <em>background page</em>, |
| 251 an invisible page |
| 252 that holds the main logic of the extension. |
| 253 An extension can also contain other pages |
| 254 that present the extension's UI. |
| 255 If an extension needs to interact with web pages that the user loads |
| 256 (as opposed to pages that are included in the extension), |
| 257 then the extension must use a content script. |
| 258 </p> |
| 259 |
| 260 |
| 261 <h3 id="background_page">The background page</h3> |
| 262 |
| 263 <p> |
| 264 The following figure shows a browser |
| 265 that has at least two extensions installed: |
| 266 a browser action (yellow icon) |
| 267 and a page action (blue icon). |
| 268 Both the browser action and the page action |
| 269 have background pages. |
| 270 This figure shows the browser action's background page, |
| 271 which is defined by <code>background.html</code> |
| 272 and has JavaScript code that controls |
| 273 the behavior of the browser action in both windows. |
| 274 </p> |
| 275 |
| 276 <img src="{{static}}/images/overview/arch-1.gif" |
| 277 width="232" height="168" |
| 278 alt="Two windows and a box representing a background page (background.html). On
e window has a yellow icon; the other has both a yellow icon and a blue icon. Th
e yellow icons are connected to the background page." /> |
| 279 |
| 280 <p> |
| 281 Although background pages can be useful, |
| 282 don't use one if you don't need it. |
| 283 Background pages are always open, |
| 284 so when a user installs many extensions that have background pages, |
| 285 Chrome's performance can suffer. |
| 286 </p> |
| 287 |
| 288 <!-- PENDING: Perhaps show a picture of many background page processes. |
| 289 This could build on a figure that shows the process architecture, |
| 290 and perhaps the differences between packaged apps and extensions. --> |
| 291 |
| 292 <p> |
| 293 Here are some examples of extensions that usually |
| 294 <em>do not need</em> a background page: |
| 295 </p> |
| 296 |
| 297 <ul> |
| 298 <li> An extension with a browser action that |
| 299 presents its UI solely through a popup |
| 300 (and perhaps an options page). |
| 301 </li> |
| 302 <li> |
| 303 An extension that provides an <em>override page</em>—a |
| 304 page that replaces a standard Chrome page. |
| 305 </li> |
| 306 <li> |
| 307 An extension with a content script |
| 308 that <em>doesn't use</em> localStorage or |
| 309 <a href="#apis">extension APIs</a>. |
| 310 </li> |
| 311 <li> |
| 312 An extension that has no UI except for an options page. |
| 313 </li> |
| 314 </ul> |
| 315 |
| 316 <p> |
| 317 See <a href="background_pages.html">Background Pages</a> |
| 318 for more details. |
| 319 </p> |
| 320 |
| 321 <h3 id="pages">UI pages</h3> |
| 322 |
| 323 <p> |
| 324 Extensions can contain ordinary HTML pages that display the extension's UI. |
| 325 For example, a browser action can have a popup, |
| 326 which is implemented by an HTML file. |
| 327 Any extension can have an options page, |
| 328 which lets users customize how the extension works. |
| 329 Another type of special page is the override page. |
| 330 And finally, you can |
| 331 use <a href="tabs.html#method-create">chrome.tabs.create()</a> |
| 332 or <code>window.open()</code> |
| 333 to display any other HTML files that are in the extension. |
| 334 </p> |
| 335 |
| 336 <p> |
| 337 The HTML pages inside an extension |
| 338 have complete access to each other's DOMs, |
| 339 and they can invoke functions on each other. |
| 340 </p> |
| 341 |
| 342 <!-- PENDING: Change the following example and figure |
| 343 to use something that's not a popup? |
| 344 (It might lead people to think that popups need background pages.) --> |
| 345 |
| 346 <p> |
| 347 The following figure shows the architecture |
| 348 of a browser action's popup. |
| 349 The popup's contents are a web page |
| 350 defined by an HTML file |
| 351 (<code>popup.html</code>). |
| 352 This extension also happens to have a background page |
| 353 (<code>background.html</code>). |
| 354 The popup doesn't need to duplicate code |
| 355 that's in the background page |
| 356 because the popup can invoke functions on the background page. |
| 357 </p> |
| 358 |
| 359 <img src="{{static}}/images/overview/arch-2.gif" |
| 360 width="256" height="168" |
| 361 alt="A browser window containing a browser action that's displaying a popup. Th
e popup's HTML file (popup.html) can communicate with the extension's background
page (background.html)." /> |
| 362 |
| 363 <p> |
| 364 See <a href="browserAction.html">Browser Actions</a>, |
| 365 <a href="options.html">Options</a>, |
| 366 <a href="override.html">Override Pages</a>, |
| 367 and the <a href="#pageComm">Communication between pages</a> section |
| 368 for more details. |
| 369 </p> |
| 370 |
| 371 |
| 372 <h3 id="contentScripts">Content scripts</h3> |
| 373 |
| 374 <p> |
| 375 If your extension needs to interact with web pages, |
| 376 then it needs a <em>content script</em>. |
| 377 A content script is some JavaScript |
| 378 that executes in the context of a page |
| 379 that's been loaded into the browser. |
| 380 Think of a content script as part of that loaded page, |
| 381 not as part of the extension it was packaged with |
| 382 (its <em>parent extension</em>). |
| 383 </p> |
| 384 |
| 385 <!-- [PENDING: Consider explaining that the reason content scripts are separated
from the extension is due to chrome's multiprocess design. Something like: |
| 386 |
| 387 Each extension runs in its own process. |
| 388 To have rich interaction with a web page, however, |
| 389 the extension must be able to |
| 390 run some code in the web page's process. |
| 391 Extensions accomplish this with content scripts.] |
| 392 --> |
| 393 |
| 394 <p> |
| 395 Content scripts can read details of the web pages the browser visits, |
| 396 and they can make changes to the pages. |
| 397 In the following figure, |
| 398 the content script |
| 399 can read and modify |
| 400 the DOM for the displayed web page. |
| 401 It cannot, however, modify the DOM of its parent extension's background page. |
| 402 </p> |
| 403 |
| 404 <img src="{{static}}/images/overview/arch-3.gif" |
| 405 width="238" height="169" |
| 406 alt="A browser window with a browser action (controlled by background.html) and
a content script (controlled by contentscript.js)." /> |
| 407 |
| 408 <p> |
| 409 Content scripts aren't completely cut off from their parent extensions. |
| 410 A content script can exchange messages with its parent extension, |
| 411 as the arrows in the following figure show. |
| 412 For example, a content script might send a message |
| 413 whenever it finds an RSS feed in a browser page. |
| 414 Or a background page might send a message |
| 415 asking a content script to change the appearance of its browser page. |
| 416 </p> |
| 417 |
| 418 <img src="{{static}}/images/overview/arch-cs.gif" |
| 419 width="238" height="194" |
| 420 alt="Like the previous figure, but showing more of the parent extension's files
, as well as a communication path between the content script and the parent exte
nsion." /> |
| 421 |
| 422 |
| 423 |
| 424 <p> |
| 425 For more information, |
| 426 see <a href="content_scripts.html">Content Scripts</a>. |
| 427 </p> |
| 428 |
| 429 |
| 430 <h2 id="apis"> Using the chrome.* APIs </h2> |
| 431 |
| 432 <p> |
| 433 In addition to having access to all the APIs that web pages and apps can use, |
| 434 extensions can also use Chrome-only APIs |
| 435 (often called <em>chrome.* APIs</em>) |
| 436 that allow tight integration with the browser. |
| 437 For example, any extension or web app can use the |
| 438 standard <code>window.open()</code> method to open a URL. |
| 439 But if you want to specify which window that URL should be displayed in, |
| 440 your extension can use the Chrome-only |
| 441 <a href="tabs.html#method-create">chrome.tabs.create()</a> |
| 442 method instead. |
| 443 </p> |
| 444 |
| 445 <h3 id="sync"> Asynchronous vs. synchronous methods </h3> |
| 446 <p> |
| 447 Most methods in the chrome.* APIs are <b>asynchronous</b>: |
| 448 they return immediately, without waiting for the operation to finish. |
| 449 If you need to know the outcome of that operation, |
| 450 then you pass a callback function into the method. |
| 451 That callback is executed later (potentially <em>much</em> later), |
| 452 sometime after the method returns. |
| 453 Here's an example of the signature for an asynchronous method: |
| 454 </p> |
| 455 |
| 456 <p> |
| 457 <code> |
| 458 chrome.tabs.create(object <em>createProperties</em>, function <em>callback</em>) |
| 459 </code> |
| 460 </p> |
| 461 |
| 462 <p> |
| 463 Other chrome.* methods are <b>synchronous</b>. |
| 464 Synchronous methods never have a callback |
| 465 because they don't return until they've completed all their work. |
| 466 Often, synchronous methods have a return type. |
| 467 Consider the |
| 468 <a href="extension.html#method-getBackgroundPage">chrome.extensions.getBackgroun
dPage()</a> method: |
| 469 </p> |
| 470 |
| 471 <p> |
| 472 <code> |
| 473 Window chrome.extension.getBackgroundPage() |
| 474 </code> |
| 475 </p> |
| 476 |
| 477 <p> |
| 478 This method has no callback and a return type of <code>Window</code> |
| 479 because it synchronously returns the background page |
| 480 and performs no other, asynchronous work. |
| 481 </p> |
| 482 |
| 483 |
| 484 <h3 id="sync-example"> Example: Using a callback </h3> |
| 485 |
| 486 <p> |
| 487 Say you want to navigate |
| 488 the user's currently selected tab to a new URL. |
| 489 To do this, you need to get the current tab's ID |
| 490 (using <a href="tabs.html#method-getSelected">chrome.tabs.getSelected()</a>) |
| 491 and then make that tab go to the new URL |
| 492 (using <a href="tabs.html#method-update">chrome.tabs.update()</a>). |
| 493 </p> |
| 494 |
| 495 <p> |
| 496 If <code>getSelected()</code> were synchronous, |
| 497 you might write code like this: |
| 498 </p> |
| 499 |
| 500 <pre> |
| 501 <b>//THIS CODE DOESN'T WORK</b> |
| 502 <span class="linenumber">1: </span>var tab = chrome.tabs.getSelected(null); <b>/
/WRONG!!!</b> |
| 503 <span class="linenumber">2: </span>chrome.tabs.update(tab.id, {url:newUrl}); |
| 504 <span class="linenumber">3: </span>someOtherFunction(); |
| 505 </pre> |
| 506 |
| 507 <p> |
| 508 That approach fails |
| 509 because <code>getSelected()</code> is asynchronous. |
| 510 It returns without waiting for its work to complete, |
| 511 and it doesn't even return a value |
| 512 (although some asynchronous methods do). |
| 513 You can tell that <code>getSelected()</code> is asynchronous |
| 514 by the <em>callback</em> parameter in its signature: |
| 515 |
| 516 <p> |
| 517 <code> |
| 518 chrome.tabs.getSelected(integer <em>windowId</em>, function <em>callback</em>) |
| 519 </code> |
| 520 </p> |
| 521 |
| 522 <p> |
| 523 To fix the preceding code, |
| 524 you must use that callback parameter. |
| 525 The following code shows |
| 526 how to define a callback function |
| 527 that gets the results from <code>getSelected()</code> |
| 528 (as a parameter named <code>tab</code>) |
| 529 and calls <code>update()</code>. |
| 530 </p> |
| 531 |
| 532 <pre> |
| 533 <b>//THIS CODE WORKS</b> |
| 534 <span class="linenumber">1: </span>chrome.tabs.getSelected(null, <b>function(tab
) {</b> |
| 535 <span class="linenumber">2: </span> chrome.tabs.update(tab.id, {url:newUrl}); |
| 536 <span class="linenumber">3: </span><b>}</b>); |
| 537 <span class="linenumber">4: </span>someOtherFunction(); |
| 538 </pre> |
| 539 |
| 540 <p> |
| 541 In this example, the lines are executed in the following order: 1, 4, 2. |
| 542 The callback function specified to <code>getSelected</code> is called |
| 543 (and line 2 executed) |
| 544 only after information about the currently selected tab is available, |
| 545 which is sometime after <code>getSelected()</code> returns. |
| 546 Although <code>update()</code> is asynchronous, |
| 547 this example doesn't use its callback parameter, |
| 548 since we don't do anything about the results of the update. |
| 549 </p> |
| 550 |
| 551 |
| 552 <h3 id="chrome-more"> More details </h3> |
| 553 |
| 554 <p> |
| 555 For more information, see the |
| 556 <a href="api_index.html">chrome.* API docs</a> |
| 557 and watch this video: |
| 558 </p> |
| 559 |
| 560 <p> |
| 561 <iframe title="YouTube video player" width="640" height="390" src="http://www.yo
utube.com/embed/bmxr75CV36A?rel=0" frameborder="0" allowfullscreen></iframe> |
| 562 </p> |
| 563 |
| 564 <h2 id="pageComm">Communication between pages </h2> |
| 565 |
| 566 <p> |
| 567 The HTML pages within an extension often need to communicate. |
| 568 |
| 569 Because all of an extension's pages |
| 570 execute in same process on the same thread, |
| 571 the pages can make direct function calls to each other. |
| 572 </p> |
| 573 |
| 574 <p> |
| 575 To find pages in the extension, use |
| 576 <a href="extension.html"><code>chrome.extension</code></a> |
| 577 methods such as |
| 578 <code>getViews()</code> and |
| 579 <code>getBackgroundPage()</code>. |
| 580 Once a page has a reference to other pages within the extension, |
| 581 the first page can invoke functions on the other pages, |
| 582 and it can manipulate their DOMs. |
| 583 </p> |
| 584 |
| 585 |
| 586 |
| 587 |
| 588 <h2 id="incognito"> Saving data and incognito mode </h2> |
| 589 |
| 590 <p> |
| 591 Extensions can save data using |
| 592 the HTML5 <a href="http://dev.w3.org/html5/webstorage/">web storage API</a> |
| 593 (such as <code>localStorage</code>) |
| 594 or by making server requests that result in saving data. |
| 595 Whenever you want to save something, |
| 596 first consider whether it's |
| 597 from a window that's in incognito mode. |
| 598 By default, extensions don't run in incognito windows, |
| 599 and packaged apps <em>do</em>. |
| 600 You need to consider what a user expects |
| 601 from your extension or packaged app |
| 602 when the browser is incognito. |
| 603 </p> |
| 604 |
| 605 <p> |
| 606 <em>Incognito mode</em> promises that the window will leave no tracks. |
| 607 When dealing with data from incognito windows, |
| 608 do your best to honor this promise. |
| 609 For example, if your extension normally |
| 610 saves browsing history to the cloud, |
| 611 don't save history from incognito windows. |
| 612 On the other hand, you can store |
| 613 your extension's settings from any window, |
| 614 incognito or not. |
| 615 </p> |
| 616 |
| 617 <p class="note"> |
| 618 <b>Rule of thumb:</b> |
| 619 If a piece of data might show where a user |
| 620 has been on the web or what the user has done, |
| 621 don't store it if it's from an incognito window. |
| 622 </p> |
| 623 |
| 624 <p> |
| 625 To detect whether a window is in incognito mode, |
| 626 check the <code>incognito</code> property of the relevant |
| 627 <a href="tabs.html#type-tabs.Tab">Tab</a> or |
| 628 <a href="windows.html#type-windows.Window">Window</a> object. |
| 629 For example: |
| 630 </p> |
| 631 |
| 632 <pre> |
| 633 var bgPage = chrome.extension.getBackgroundPage(); |
| 634 |
| 635 function saveTabData(tab, data) { |
| 636 if (tab.incognito) { |
| 637 bgPage[tab.url] = data; // Persist data ONLY in memory |
| 638 } else { |
| 639 localStorage[tab.url] = data; // OK to store data |
| 640 } |
| 641 </pre> |
| 642 |
| 643 |
| 644 <h2 id="now-what"> Now what? </h2> |
| 645 |
| 646 <p> |
| 647 Now that you've been introduced to extensions, |
| 648 you should be ready to write your own. |
| 649 Here are some ideas for where to go next: |
| 650 </p> |
| 651 |
| 652 <ul> |
| 653 <li> <a href="getstarted.html">Tutorial: Getting Started</a> </li> |
| 654 <li> <a href="tut_debugging.html">Tutorial: Debugging</a> </li> |
| 655 <li> <a href="devguide.html">Developer's Guide</a> </li> |
| 656 <li> <a href="http://dev.chromium.org/developers/design-documents/extensions/s
amples">Samples</a> </li> |
| 657 <li> <a href="http://www.youtube.com/view_play_list?p=CA101D6A85FE9D4B">Videos
</a>, |
| 658 such as |
| 659 <a href="http://www.youtube.com/watch?v=B4M_a7xejYI&feature=PlayList&p=CA101
D6A85FE9D4B&index=6">Extension Message Passing</a> |
| 660 </li> |
| 661 </ul> |
OLD | NEW |