Advertisement

How to Create a Safari Extension from Scratch

by

Safari 5, the latest version of Apple's web browser, introduces extensions. Safari extensions are small add-ons that you can use to expand Safari's capabilities, built using simple HTML, CSS and JavaScript. In this tutorial, you will learn the basics of extension development by creating a simple extension using Safari 5's Extension Builder.


Introduction

In this tutorial we will build a simple extension that adds a button to the main Safari toolbar, and opens up Nettuts+ in a new tab when clicked. In the process, you will learn the basics of extension development and Extension Builder in Safari 5.

Developing an extension is very different from regular web development; it allows you to break out of the confines of a normal browser window, and change the browser itself for a unique experience. Fortunately, Safari 5 lets us do this using simple web technologies such as HTML, CSS and JavaScript; and it fully supports the powerful new features of HTML5 and CSS3.

Safari extensions can do five main things:

  1. Add toolbar items: An extension can add a button to the default Safari toolbar. In addition to performing some action when clicked, a numbered badge can be added to this button (to show, for example, a number of unread messages.)
  2. Add extension bars: Extension bars are simply HTML pages in the form of a toolbar which are added above the tab bar in Safari. They are extremely versatile and can be used for many things. The downside is that they take a lot of space and can become annoying.
  3. Add tabs & windows: Tabs and windows can be easily modified and added from within an extension. You can change a URL or load custom HTML content to a tab.
  4. Modify web content with script and style sheet injection: Easily change the appearance or behavior of a single webpage or the whole web using scripts and CSS files.
  5. Add context menu items: An extension can add a custom item to the contextual (right-click) menu that performs a certain command when selected.

In addition, Safari Extensions provide a very simple way to create a user-defined settings panel inside the built-in Safari Preferences window.


Step 0: Sign Up as a Safari Developer

The first thing to do is sign up as a Safari developer on apple.com. This will allow you to make a Safari Developer Certificate which is needed in order to use Extension Builder. Register over here and then go to the Safari Extension Certificate Utility and follow the instructions.

Once you have your certificate properly installed, it's time to get started!


Step 1: Meet Extension Builder

Extension Builder is the main tool used to create extensions.

If you've never developed for Safari before, you need to turn on the Develop menu. To do this, go to the Advanced tab in Safari Preferences and check the box next to "Show Develop in the menu bar". The menu should now appear; it contains many useful development tools, but for now, just select "Show Extension Builder." Make sure you have the latest version of Safari installed.

Extension Builder is made up of a sidebar on the left that lists the extensions you currently have in development and a panel on the right that lets you inspect an extension, edit its properties and settings, install it, and more.

To create a new extension, click the '+' icon in the lower left corner and select "New Extension." Name the extension whatever you like and save it somewhere. This will create a folder with a name extension ".safariextension". Go ahead and open this folder.

The extension folder contains all the files and resources for the extension. This is where we put the HTML, CSS, images and scripts that will make up our extension. By default, the folder will contain a file called Info.plist, which is essentially where all the info set in Extension Builder is saved to, in XML form. There is no reason to change this file manually.


Step 2: Set Up the Extension Settings

Many settings are self-explanatory, such as Name, Author and Description. There is no need to change anything for now, just scroll down to the "Extension Chrome" category. These are the user interfaces of the extension that will actually be shown. As mentioned before, you can add extension bars ("Bars"), context menu items and toolbar button. Only a button is needed for our extension, so click "New Toolbar Item". Toolbar Item 1 should appear with the following properties:

  • "Label" is the name of the button that will be shown if the toolbar overflows. "Palette Label" will be shown under the button in the "customize toolbar" dialog, and "Tool Tip" is the text that will appear after hovering on the button for a while. We will set the label to "Nettuts", and, by leaving the other two properties empty, they will take their values from the Label and be the same.
  • The "Image" property is the icon that will appear on the button itself. The image should just be an alpha channel, or a black image with a transparent background, in .png format. The size of the icon ideally should be 16x16 pixels, but can be as large as 18x18; images that are too large will be cropped to fit. We will use a small, 16x16 "plus" icon (icon.png) to indicate Nettuts+.

    To apply the image you want to use, first put it in the extension folder, then select it from the dropdown menu in Extension Builder.
  • "Identifier" can be used to identify the button from a script; we will set it simply to "nettuts".
  • "Command" is the name of the command that will be sent when clicking the button. Set it to "open-nettuts". We will later use this to detect when the button is clicked.
  • "Include by Default" Indicates whether or not the button appears on the user's toolbar immediately after installing the extension. Since the button is our extensions only feature, keep the setting checked.

Step 3: Create the Global Page

To control our button, we need to have a script, and for that, we need to have an HTML file to load the script. That file is the global HTML page.

The global page is a place to put scripts, data and resources that require no user interface. It is simply a HTML page that is not displayed anywhere. The global page is loaded once per Safari session, and that makes it good for controlling our toolbar button.

Using your preferred text editor, make a new empty HTML file and call it "global.html". Save this file to the extension folder. In Extension Builder, find the "Global Page File" setting and select the file you created from the dropdown menu.

Open the global page. First, make a script tag in the file. You can also use an external .js file, but since our page contains nothing else but the script, there is no need.

When our button is clicked, safari sends a "command" event, which is called "open-nettuts", as we set in Extension Builder. In order to respond to this event, we need to install a listener in our global HTML page, like this:

safari.application.addEventListener("command", performCommand, false);

The first parameter is "type" - the type of event the target should listen to. In our case, it's a command. The second parameter is the function to call when the event occurs; we will simply call it "performCommand". The last parameter is Boolean - "useCapture", but it is not important for our needs; set it to false.

Our global page is now listening to commands that Safari sends. Now we need to implement the function "performCommand" to respond appropriately when our button is clicked:

// Function to perform when event is received
Function performCommand(event) {
	// Make sure event comes from the button
	if (event.command == "open-nettuts") {
		// This is where we finally respond to the click
	}
}

Our function will receive any command event sent from Safari, so we need to make sure which one it is and respond accordingly. The command property of the event object we receive should be the same as what we set in Extension Builder, so we check that it is indeed "open-nettuts".

Finally, when we know our button was clicked by the user, we want to perform two things: open a new tab, and set its URL to http://net.tutsplus.com.

var newTab = safari.application.activeBrowserWindow.openTab();
newTab.url = "http://net.tutsplus.com/";

The first line is rather self-explanatory: it finds the current active browser window and opens a new tab in it. This tab is returned and saved in a variable, which is used in the second line to change the URL to nettuts.

Your global page should look like this now:

<script>
// Set up the Listener
safari.application.addEventListener("command", performCommand, false);

// Function to perform when event is received
function performCommand(event) {
	// Make sure event comes from the button
	if (event.command == "open-nettuts") {
		var newTab = safari.application.activeBrowserWindow.openTab(); // Open a new tab
		newTab.url = "http://net.tutsplus.com/"; // Set tab URL to nettuts
	}
}
</script>

That's it! our global page now recognizes a click, opens a new tab and directs it to Nettuts. Switch back to Extension Builder, and click "Install" in the top right corner. A button should appear on the toolbar. Click it to make sure it works!


Step 4: Add the Extension Icon

As a final touch, you might want to add an icon to your extension. To do that, all you need to do is add three .png images of an icon to the extension folder: Icon-32.png, Icon-48.png and Icon-64.png. Each file needs to be the size that its name suggests, so Icon-32.png will be 32x32 pixels, and so forth.

As a bonus, the source files for this tutorial include a Photoshop template for creating your own extension icons!


Step 5: Build the Package

Our extension is now finished! To export it, click the "Build Package..." button in Extension Builder and save it somewhere. The extension can be installed by opening the file or dragging it to Safari. You can now send this file, publish it on the internet or try submitting to Apple's Safari extension gallery.


Conclusion

This tutorial should have provided you with a basic idea of how to create a Safari Extension. Now you can start making you own - browse the Safari extension Gallery for inspiration, or check out my own Widgets Bar extension. For more information about developing extensions, Apple's Safari Dev Center has a development guide, sample code and documentation. Have fun, and let us know if you'd like more tutorials on this topic!