Flying With Mozilla Jetpack

We’re going to be working with Mozilla’s Jetpack today to create a slick color palette add-on using the Colourlover’s API. For those of you who don’t know, Jetpack is one of Mozilla’s newer lab experiments that allows web developers to use their pre-existing knowledge about building websites to create Firefox add-ons. So if you’re comfortable with CSS and jQuery Jetpack will be a breeze to learn! To read more about Jetpack explore the Jetpack homepage.

The add-on we’ll be building today is going to be a color palette generator that will rest in a slide bar on the left side of our browser. The color palette generator will create as many new palettes as we want by requesting them at random from the Colourlovers api, and when we like a specific color we can simply click it and Jetpack will copy the hex value to our clipboard for use in a style sheet or in Photoshop.

To see the completed project view the video below, and when you’re ready we’ll be going through the following steps to create the same add-on:

  1. First is to wireframe and style the add-on with HTML and CSS
  2. Second we’ll script with jQuery to add the interaction and make requests to the Colourlovers API.

Before We Begin…

To create this add-on you’re going to need the latest version of Firefox, version 3.5 or above. Also you’ll need to download the actual Jetpack add-on, which can be found at the bottom of the Jetpack homepage.

Click the big black button to download Jetpack

Once you have everything setup type “about:jetpack” into your address bar to access your local Jetpack homepage. This page is where you can manage your add-ons, develop new add-ons and reference the Jetpack API. Before we begin make sure you do the Jetpack tutorial under the tutorial tab. The tutorial is simple, fun and will get you comfortable with Jetpack in no time!

1. Access your Jetpack page by typing ‘about:jetpack’ in your address bar 2. The develop tab is where you’ll create your add-ons 3. The tutorial tab provides a quick tutorial to get you comfortable with Jetpack 4. Go to the API reference to learn more about what Jetpack can do

Adding HTML & CSS

Let’s begin by fleshing out the add-on so when it comes time to script it, we’ll be able to see were things fit. So go into the Develop tab and write the following inside the text box:

jetpack.future.import("slideBar");

jetpack.slideBar.append({
   persist: true,
   width: 290,
   html: <></>
});

First we use jetpack.future.import() to import Jetpack’s features that are still being tested. In this case we want to use the slideBar feature which will allow our add-on to rest in a slide bar.

After that we add our slide bar by appending it with jetpack.slideBar.append(). The slideBar takes a number of arguments, in this case we set width, persist and html. Width will determine the width of the slide bar in pixels which we set to 290px. Persist, when set to true, allows for the slide bar to stay open even when the user moves away from it. Last we add an area for html. With the html section we first open and close with <> </> tags, this will allow us to write our HTML. Remember you have the Jetpack API close by your develop tab, so reference it whenever you want to learn more about a feature!

Go ahead and press try out this code to test your code out. An empty gray slide bar should be created for you. Next we’ll add some HTML and CSS to make this look more like an add-on.

The gray slide bar with no styling, it’s just waiting for the magic touch of some HTML & CSS

So let’s continue and add our HTML within the tags I mentioned, add the following in-between the html: <> and </>:

<style><![CDATA[
      body { background:#4A4A4B; font-family:Tahoma, Arial, "sans serif"; font-size:67.5%; }
      h1 { cursor:pointer; color:#FFF; padding:5px 0px; text-shadow:1px 1px 0px #343435; font-size:2em; text-align:center; }
      h1:hover { background:#393939; }
      .palette { position:relative; border-bottom:1px solid #363637; border-right:1px solid #363637; height:100px; width:250px; padding:10px; background:#FFF; }
      .color { background:#333; cursor:pointer; height:100px; width:50px; float:left; text-indent:-1000px; overflow:hidden; }
      .alert { background:#FCDD4D; border-bottom:1px solid #363637; border-right:1px solid #363637; color:#5e500d; font-size:1em; text-align:center; width:270px; margin-top:10px; padding:6px 0; }
]]></style>

<body>
  <h1>NEW PALETTE</h1>
  <div class="palette">
      <div class="color">Color</div>
      <div class="color">Color</div>
      <div class="color">Color</div>
      <div class="color">Color</div>
      <div class="color">Color</div>
   </div>
  <div class="alert">COPIED TO CLIPBOARD!</div>
</body>

The HTML looks like a standard HTML page with inline styling. If you notice though in between the <style> tags we have <![CDATA[ … ]> wrapping our style sheet. In JavaScript CDATA means character data, which basically allows us to write html as a string with multiple lines (so we don’t need to concatenate or use line-breaks).

As for the styles they’re mostly eye candy to make the add-on look similar to the Colourlovers site.

For our HTML we have a h1 tag that will serve as our button to request a new palette. We also have a .palette div which will contain the individual .color div’s. Each .color div will be a 50 by 100px block containing 1 of 5 colors from the chosen palette. Last we have our .alert box which will notify the user that the color has been copied to their clipboard.

Now click “try out this code” and you should see the makings for a pretty slick add-on.

With some CSS our add-on is beginning to take shape

Scripting The Add-On

To finish this add-on all we have to do is script it with some jQuery which is built into Jetpack. We’re going to be doing three things with jQuery: we’ll create a function to request a palette of colors from the colourlovers API, display those colors and then allow for copying the hex value to the users clipboard.

So let’s begin creating the function, place the bolded code into your Jetpack:

jetpack.future.import("slideBar");

jetpack.slideBar.append({
  onReady: function(slide) {
	jQuery.fn.newColors = function() {
		$.getJSON("http://www.colourlovers.com/api/palettes/random?jsonCallback=?", { numResults: 1},
	                function(palette) {
		        var i = 0;
		        $('.color', slide.contentDocument).each(function() {
		           	$(this).css('background-color', '#'+palette[0].colors[i]);
			        $(this).attr('id', palette[0].colors[i]);
			        i++;
		        });
	        }); // end getJSON
        }

       $().newColors();

  },
  persist: true,
  width: 290,
  html: <>
    <style><![CDATA[
      body { background:#4A4A4B; font-family:Tahoma, Arial, "sans serif"; font-size:67.5%; }
      h1 { cursor:pointer; color:#FFF; padding:5px 0px; text-shadow:1px 1px 0px #343435; font-size:2em; text-align:center; }
      h1:hover { background:#393939; }
      .palette { position:relative; border-bottom:1px solid #363637; border-right:1px solid #363637; height:100px; width:250px; padding:10px; background:#FFF; }
      .color { background:#333; cursor:pointer; height:100px; width:50px; float:left; text-indent:-1000px; overflow:hidden; }
      .alert { background:#FCDD4D; border-bottom:1px solid #363637; border-right:1px solid #363637; color:#5e500d; font-size:1em; text-align:center; width:270px; margin-top:10px; padding:6px 0; }
    ]]></style>
    <body>
      <h1>NEW PALETTE</h1>
      <div class="palette">
          <div class="color">Color</div>
          <div class="color">Color</div>
          <div class="color">Color</div>
          <div class="color">Color</div>
          <div class="color">Color</div>
      </div>
      <div class="alert">COPIED TO CLIPBOARD!</div>
    </body>
  </>
});

We add a new setting to our slideBar, onReady. The onReady setting allows us to trigger a function when the slide bar is loaded, so for this reason we’re going to put all of our scripts inside this function. Inside the onReady function we create another function to request palettes, jQuery.fn.newColors = function() { … } . Nested within the newColors function we send a request to the colourlovers api for json data using $.getJSON(); method. The parameters are the api’s url, how many palettes we want (one), and a function to trigger when the request is successfully made.

Our success function is going to pass the JSON data we retrieved as palette. We then set a new variable i to zero, this will track how many times we iterated through our loop, which is coming next. We are going to loop through each .color div and give them the corresponding color from our palette. So the first div will get color[0], the second will get color[1] and so on. Last we set the id of the color div’s to their hexadecimal color so we can reference the value later.

After we create our function we call it by using it on our whole slideBar, $().newColors();. Now press try out this code and you should have a randomly selected palette from Colourlovers appearing in your slide bar!

Now that the add-on can access the Colourlovers API we get our first random palette!

To get new ones on the fly though we need to add a little more code, add the following to your Jetpack directly under the $().newColors():

$('h1', slide.contentDocument).click(function() {
	$().newColors();
});

This snippet adds a click event to our h1 tag so that every time it’s triggered a new palette will be generated. Note that we add slide.contentDocument as the context for our h1 or else we wouldn’t be able to select the right one.

We can easily retrieve a new palette by clicking the “NEW PALETTE” button

Now our final addition is to add the clipboard feature which Jetpack makes a breeze to do. First import the clipboard by adding the following right below jetpack.future.import(’slideBar’):

jetpack.future.import('clipboard');

This gives us access to the clipboard feature which is still being developed, just like the slide bar. To use the clipboard to copy a chosen colors hex value add the following to the end of your onReady function:

$('.alert', slide.contentDocument).fadeOut(10);	

$('.color', slide.contentDocument).click(function() {
	var curColor = $(this).attr('id');
	jetpack.clipboard.set('#'+curColor);
        $('.alert', slide.contentDocument).fadeIn('fast').animate({opacity: 1}, 1000).fadeOut('medium');
});

We first hide our .alert so it’ll only be visible when it’s needed. Next we add a click event to each .color div within the palette. When the event is triggered we set a variable curColor which will contain the selected color’s hex value, remember we stored this as the divs id. We then use jetpack.clipboard.set() to store the curColor hex in the users clipboard. When that’s all done we notify the user that the color was successfully copied to their clipboard by fading in the .alert div temporarily.

Now we can copy a color when we click it, and the alert box will fade in to confirm it

There you have it, test your Jetpack for the last time and it should be fully functional. Here’s how you whole Jetpack script should look now that it’s complete:

jetpack.future.import("slideBar");
jetpack.future.import("clipboard");

jetpack.slideBar.append({
  onReady: function(slide) {
	jQuery.fn.newColors = function() {
		$.getJSON("http://www.colourlovers.com/api/palettes/random?jsonCallback=?", { numResults: 1},
	        function(palette) {
		   var i = 0;
		   $('.color', slide.contentDocument).each(function() {
			$(this).css('background-color', palette[0].colors[i]);
			$(this).attr('id', palette[0].colors[i]);
			i++;
		   });
	        }); // end getJSON
           }

          $().newColors();

          $('h1', slide.contentDocument).click(function() {
             $().newColors();
          });

          $('.alert', slide.contentDocument).fadeOut(10);	

          $('.color', slide.contentDocument).click(function() {
	     var curColor = $(this).attr('id');
	     jetpack.clipboard.set(curColor);
             $('.alert', slide.contentDocument).fadeIn('fast').animate({opacity: 1}, 1000).fadeOut('medium');
          });
   },
   persist: true,
   width: 290,
   html: <><style><![CDATA[
      body { background:#4A4A4B; font-family:Tahoma, Arial, "sans serif"; font-size:67.5%; }
      h1 { cursor:pointer; color:#FFF; padding:5px 0px; text-shadow:1px 1px 0px #343435; font-size:2em; text-align:center; }
      h1:hover { background:#393939; }
      .palette { position:relative; border-bottom:1px solid #363637; border-right:1px solid #363637; height:100px; width:250px; padding:10px; background:#FFF; }
      .color { background:#333; cursor:pointer; height:100px; width:50px; float:left; text-indent:-1000px; overflow:hidden; }
      .alert { background:#FCDD4D; border-bottom:1px solid #363637; border-right:1px solid #363637; color:#5e500d; font-size:1em; text-align:center; width:270px; margin-top:10px; padding:6px 0; }
]]></style>
<body>
  <h1>NEW PALETTE</h1>
  <div class="palette">
      <div class="color">Color</div>
      <div class="color">Color</div>
      <div class="color">Color</div>
      <div class="color">Color</div>
      <div class="color">Color</div>
   </div>
  <div class="alert">COPIED TO CLIPBOARD!</div>
</body></>

});

Conclusion

I hope this tutorial has given you a good introduction to Jetpack and what can be accomplished with the skills you already have as a web developer. This add-on also has a lot more room for improvement, for example why not try storing palettes you like using Jetpack’s simple persistent storage feature. You could also play around with the JSON request sent to Colourlovers to get only the most popular palettes, check out the API reference here.

If you’re running into any trouble feel free to leave a comment and I’ll try to sort your problem out, you could also contact me directly.