Hacker News new | past | comments | ask | show | jobs | submit login
Backbone.js and Chrome Extensions (zapier.com)
35 points by mikeknoop on Feb 24, 2012 | hide | past | favorite | 21 comments



Instead of caching the model in LocalStorage, couldn't you also just store it in the extension's background page? You would simply store the data that you would otherwise put in LocalStorage within a variable on the background page. From the popup, you can access background page variables as members of the object returned by calling chrome.extension.getBackgroundPage().

The extension would still need to recompute it once every time it is starts up, but since it is computable I don't think it belongs in LocalStorage. (You wouldn't store something like this in the registry if you were writing a Windows program; you'd just keep it in memory.)

Also, the article could use a bit of improvement in terminology. When it talks about 'loading the extension', it really means displaying the popup. I think of loading the extension as in starting up the background page via the extensions window.


Good point I'll see if I can clear up that terminology in the post.

You are also correct that you could use the background page as an alternative persistance layer instead of LocalStorage. LocalStorage is obviously more applicable in non-extension environments. Is there a big benefit to using background pages in a Chrome Extension over LocalStorage simply for storage?

One thought for future work: load the Backbone app into the background page when the browser starts. Whenever the popup loads, simply update the Viewport view's element with Viewport.setElement() to be the root popup body element. This might allow persistance between popup loads.


The benefit isn't that big.

From the standpoint of writing quality code, I think it is better to use the background page instead of LocalStorage in that it lets you avoid writing to disk (which requires space and has worse performance than using memory, although at this scale the difference is trivial) and doesn't pollute your LocalStorage namespace as much.

An advantage of the LocalStorage approach is your readers can write code in a way similar to how they would if you were not writing an extension and it makes the material more accessible in that it requires less understanding of how Chrome extensions work.


two points

-localStorage works on the background.html page

-when content scripts access localStorage, they do so at the domain level of the url


I don't understand the purpose of your points here.

* localStorage also works from the popup (using the same storage as the background; that's how the tutorial was able to work).

* We're trying to get data working in the popup here, so how localStorage works in the contentscripts is irrelevant for solving this problem.


Nice post! For anyone interested in seeing another sample, I wrote a chrome extension that leverages backbone as well a few months back: https://github.com/jeffreyiacono/penalty-blox


Very well done, it seems I was beat to the punch (updating the article now...).

I'm curious, did you do anything special to work around fresh API hits each time the popup is loaded (ie. LocalStorage)?


All data (account names and hash tags to remove) are stored client side in localstorage, so the extension doesn't query / load data from an external API like yours does. As a result, I haven't bumped into that "gotcha" yet. I do use a background page to bridge the popup's stored data with the content script that does all the heavy lifting (from what I remember). Just fyi on the localstorage adapter: leveraging the one from the Todo example on the backbone website. Thanks for giving me a shout out in your article, very kind of you.


I have another comment on this thread with an idea for future work (http://news.ycombinator.com/item?id=3631097). I'd be curious to know if leveraging background pages for containing the Backbone instance would be a clean way to handle persistence (of the entire app, not just data).

Have you ever looked at something like this?


Author here, happy to answer any questions about the approach or code!


I think Backbone JS might be useful for facilitating communication between the different components that Chrome uses (ie. contentscript <-> browser button). I can't see anything in the Gists you provided that highlight this. Did you do any work on this at all, where you could shed any light?


I can explain a little more clearly on how Chrome generates the popup which is shown in the screenshot (you may know this already).

When you define a browser_action inside your manifest.json file:

   "browser_action": {
      "default_icon": "icon_16.png",
      "popup": "popup.html"
   },
Chrome automatically places an icon in the top bar, and when clicked, loads popup.html into a generated bubble.

Now, our foray into Chrome Extensions pretty much ends there. We load all our Backbone code via popup.html and let it do its thing. We did not look at any other of the mechanisms Chrome provides to extensions such as contentscripts.

With that said, I also see a lot of value in leveraging Backbone's Model and Bindings within contentscripts and it would be something worth exploring -- but it wasn't directly applicable to understanding how Backbone could work for us in overhauling our frontend.


I was just reading through the docs and am getting ready to write my first extension and think I'm going to try and get backbone running in the content script where I believe it's state will be persisted through open/close of the popup.

Thanks for your post!


It sounds like you want to use backbone in the background then. It could also be used in the contentscript, but that would be specific to a particular tab and you'd have to send a message from the background (preferred) or popup to request that data to make it accessible to the popup.


To be clear, a contentscript is a script which runs only on a specific website or domain (for example, if I specified my contentscript to run on zapier.com, it would get loaded every time I access that page).

Popups, on the other hand, get their scripts loaded into a brand new document when the icon is clicked and rendered into the popup bubble.

Backbone makes model/collection caching very easy so my preferred method would be to override Backbone.sync to store data inside LocalStorage.

There are a few blog posts out there with tricks on how to persist state between popup loads (unloading the popup DOM into the background page...). I think these strategies would break a Backbone app due to how view bindings work. I'd be curious to know any other ideas on how to persist the actual state (and not just model/collection data) between popup loads.

EDIT: To answer my own question a little bit, you could probably get fancy with http://code.google.com/chrome/extensions/background_pages.ht... but I'd need to do more research on the relation between background pages and popups.


If you find a way to persist the popup please share, I spent the last 9 hours in all out battle. Basically chrome shit cans the window object on blur, the closest I came was pushing the popup body into the background page for resurrection later, but it's clunky around the edges as your dealing with a new window/document context so stuff like js context, scroll position, etc.

I've tabled it for now. I'm 99% sure the way to go is to put a popout link on the popup, setPopup to null and then bind the click listener for the popup icon to focus the popup. If the user closes the popped out popup reset setPopup and the process starts anew. I'll still be overring backbone sync and keeping all the data in the background.


Nice, can you say a bit more about the purpose of the app. And did you consider creating it for mobile or other browser platforms.

Loaded question - I'm a co-founder of Trigger.io :-D


As it exists now, the extension shows what Zaps (web app to web app syncs) you have set up and lets you pause or run them manually. There is a ton more we could build into the extension. Practically our entire site could be run through an extension if you came up with a design which made sense. This is the beauty of an exposed backend API system -- it doesn't care how you represent the data coming out of it and Backbone.js is great lightweight framework for rendering all that data.

Eventually, I think we will have "frontend" views across many devices and machines (alluded to in the article, it's just to easy to create another view). We haven't tested the performance on any mobile clients yet but I would definitely look into a solution like Trigger.io when we get to it.


Oh, I've got an idea: now that we're approaching a world where cross-browser shit works, let's take the tech that is designed to build on top of that and use it to build shit that doesn't work cross-browser.


maybe the world is big enough now for multiple internets


I believe https://github.com/oo7ph/Trello-Clone another chrome extension, uses backbone as well. But I haven't studied this one (yet).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: