Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

August 05 2011


Omnibar brings Google Chrome’s smart address bar to Safari

One major reason for my browser of choice being Google Chrome is the smart address bar for searching and direct URLs. Now the gap has been bridged and is a download away! Go, go, go…

October 07 2010


How to Create a Safari Extension from Scratch

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.


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 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 16×16 pixels, but can be as large as 18×18; images that are too large will be cropped to fit. We will use a small, 16×16 “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

var newTab = safari.application.activeBrowserWindow.openTab();
newTab.url = "";

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:

// 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 = ""; // Set tab URL to nettuts

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 32×32 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.


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!

Sponsored post

June 09 2010


Safari 5 Extensions

A handy list of available Safari extensions to tide you over until Apple opens their gallery.

June 08 2010


5 Excellent New Features in Safari 5

On June 7th, Apple released an update to their web browser, Safari 5. It includes a plethora of new features for web developers, including a faster JavaScript engine, better HTML5 support, extension support, and a great Web Inspector update. We will explore what these new features mean for web developers.

1. Improved Web Inspector

A good web inspector is extremely important to most web developers. Many people still prefer Firebug, which is an extension for Firefox, but the Webkit inspector has improved dramatically in the last few years.

CSS Inspector

In Safari 5, the web inspector has an improved CSS inspector panel, which lets you jump directly to a rule definition in the source file.

DOM Inspector

The DOM inspector is much improved, now allowing you to add attributes to DOM nodes in your document, remove nodes, and edit nodes as HTML, which lets you edit the entire tag as if it was a source file.

Resource Panel

The Resources panel is also improved, letting you see all HTTP redirects, along with full header information, including the HTTP status code.

JavaScript Inspector

The JavaScript inspector now lets you disable all breakpoints with a single click, and if you hover over an element while on a breakpoint, you can see the actual object values of what you are hovering over. This will be extremely useful for debugging purposes!

Timeline Panel

Safari 5 now has a new Timeline Panel, which provides information about everything that the browser is doing while you browse. This includes loading data, parsing it, laying it out on screen, and rendering it. Very cool for working on the performance of your website or application.

Audits Panel

Another added panel is the Audits panel, which much like the popular YSlow and Google Page Speed extensions for Firebug, suggests ways for you to improve the performance and compatibility of your site.


The last change to the Web Inspector is that a separate panel for the JavaScript console has been created. This is nice because it allows the console to take up the entire height of the Web Inspector rather that the small part that it used to. It is still available in the old location, however, for convienent access while looking at another panel. For more information about the updates to the Web Inspector, check out this post on the Webkit blog.

2. Better HTML5 Support

Apple touts seventeen new HTML5 features in Safari 5, and you might have heard of their HTML5 showcase that they launched last week (it really contains more CSS3 than anything else, but that seems to be getting lumped under HTML5 as well!). Apple really seems to be pushing HTML5, and Safari 5 now has a score of 136 on which is up from 113 in the previous release. Some of the new HTML5 features contained in Safari 5 include:

  • support for fullscreen video with closed captioning
  • geolocation
  • HTML5 AJAX History
  • drag and drop
  • nearly all of the HTML5 input types
  • official support for the new HTML5 elements such as <article>, <header> and <footer>.

Check out the complete list below.

Features For Realtime Webapps

Safari 5 includes two new HTML5 features for realtime webapps, like Friendfeed and Twitter. WebSocket is the first, and EventSource is the second. Now that three of the major browsers, Firefox, Chrome and Safari have implemented the WebSocket spec, writing realtime webapps using something like Node.js for a backend is becoming much more feasable.

WebSocket is essentially a two-way communication channel between your webapp in the browser and the server.

Since it is two way, you could write something like a Twitter client using it, and have new Twitter messages automatically appear as they are pushed from the server, and also push new tweets up as they are written. EventSource is a one way communication mechanism which allows the server to send events to the client but not the other way around. If you want to learn more about EventSource, check out this tutorial.

3. Extension Support

Because it is written using these technologies, it will be possible for someone to write a cross platform extension development library that works across Firefox (Jetpack), Chrome, and Safari 5.

There is now extension support in Safari, and, thanks to a new tool called Extension Builder in the already useful Develop menu, you can write your own. The extensions are written using standard web technologies, including HTML, CSS, and JavaScript and the Extensions API provided by Apple. Because it is written using these technologies, it will be possible for someone to write a cross platform extension development library that works across Firefox (Jetpack), Chrome, and Safari 5. All of them use web technologies to build extensions for their browsers. For security, all extensions for Safari 5 must be cryptographically signed by Apple through their Safari Dev Center.

Later this summer, Apple will open the Safari Extensions Gallery which will give users an easy place to find an install extensions. Panic is already showing off their extension called Code Notes, which, when it comes out, will allow you to add annotations to web pages by drawing and writing text notes directly on the site. The extension will then allow you to share your annotations via email. A very cool example of what the Safari 5 extensions API is capable of.

4. Faster JavaScript Engine

It wouldn’t be a complete browser upgrade if Apple didn’t tout their 30% faster JavaScript Engine. In the SunSpider JavaScript performance test, Safari ranks similarly to Google Chrome, and is still far ahead of the latest version of Firefox. While JavaScript performance is important, the real performance bottlenecks for web applications do not lie in the raw JavaScript language performance, but in the DOM API, which is notoriously slow in all browsers. I hope more attention is payed to DOM performance in the future.

5. Safari Reader

While not specifically a web developer feature, I’m sure you read a lot of articles like this one around the web. Safari Reader is essentally a way to get all of the destractions out of your way while you read just the article. Much like the Readability bookmarklet, Safari Reader auctomatically recognizes pages with an article in them, and presents a button in the toolbar that extracts the text and images from just the article section of the page and displays them in a nice readable font. It is also very nice that you can easily email and print just the article while you are looking at the Reader view. I’m sure that I will use this a lot!

While not a major release in terms of user features, Safari 5 is a very nice release for developers. With much better HTML5 support, increased JavaScript performance, and a better Web Inspector, Safari is now my development browser of choice. What about you?

April 15 2010


WebKit Inspector Improves Again: Timeline, Audits and Dedicated Console

Pavel Feldman has introduced some great improvements to the WebKit inspector.

There are some great new panels available:

Timeline Panel

The Timeline Panel provides you with a detailed view of what’s happening inside your browser as you surf. It allows you to zoom into the areas of interest, expand the nested records and investigate their details. The Timeline organizes nesting based on event causation. So, if a mouse down event handler sets a timer, which upon firing loads a resource using XHR, which later evaluates the result when the resource becomes available; then all the events caused by the mouse down will be placed under the mouse down umbrella. Solid parts of the bars show synchronous time spent on the operation, while the semi-transparent part shows the time consumed by everything this event caused (not necessarily synchronously).

Audits Panel

Audit results provide you with hints on unused resources, caching optimizations, the number of resources to load per domain, image tag parameters and many other suggestions. We’d like to make the audits framework extensible so that everyone can contribute checks for various categories such as mobile browsing, security, and static code analysis.

Dedicated Console Panel

You can now enjoy a large and powerful inspector console in a dedicated panel. Note that you can use panel switching shortcuts such as Command-[ and Command-] as mentioned in one of the previous posts.

To go along with these great new panels, there are also a ton of improvement to the other views that you know and love. My favorite is that you can now finally “Edit as HTML” in the DOM inspector. No more node ugliness.

Read the full post for all of the goodness.

April 09 2010


WebKit 2: Baking split process model into the renderer

Anders Carlsson and Sam Weinig announced that Apple has been working on “WebKit2″ for awhile, and it bakes in a split process model a la Chrome:

This is a heads-up that we will shortly start landing patches for a new WebKit framework that we at Apple have been working on for a while. We currently call this new framework “WebKit2″.

WebKit2 is designed from the ground up to support a split process model, where the web content (JavaScript, HTML, layout, etc) lives in a separate process. This model is similar to what Google Chrome offers, with the major difference being that we have built the process split model directly into the framework, allowing other clients to use it.

The documentation lists out the high level API:

One goal of WebKit2 is to provide a stable C-based non-blocking API. In order to achieve the goal of a non-blocking API, several techniques are used to make the API usable while still providing a comprehensive set of features to the embedder. These techniques include:

  • Notification style client callbacks (e.g. didFinishLoadForFrame) These inform the embedder that something has happened, but do not give them the chance to do anything about it.
  • Policy style clients callbacks (e.g. decidePolicyForNavigationAction) These allow the embedder to decide on an action at their leisure, notifying the page through a listener object.
  • Policy settings (e.g. WKContextSetCacheModel, WKContextSetPopupPolicy) These allow the embedder to opt into a predefined policy without any callbacks into the UIProcess. These can either be an enumerated set of specific policies, or something more fine-grained, such as a list of strings with wildcards.
  • Injected code (e.g. WebBundle) Code can be loaded into the WebProcess for cases where all the other options fail. This can useful when access to the DOM is required. [Planned, but not currently implemented]

There have been a few comments here and there that the Apple folk haven’t been as vocal and people wondered what they were hacking on…. maybe now we know!

December 01 2009


Star Wars HTML and CSS: A NEW HOPE

There are a lot of CSS transitions experiments going on right now. Yesterday I discovered another HTML and CSS experiment which went "far far away", compared with my simple CSS gallery.

Guillermo Esteves presented a piece of history translated for tomorrows browsers:  the Star Wars Episode IV opening crawl in HTML and CSS:

Unfortunately, the live experiment is not suitable for all browsers and the ideal target seems to be only OSX 10.6 and its latest Safari browser but it partially worked via Google Chrome as well.

Something To Learn About

We are moving complex computations into our favorite "decoration layer": CSS
We also want as much control as possible, and the above concept is brilliant to understand how to tame CSS transitions.
This example includes new and different techniques. Here is what I found interesting:


OK, this is not new at all, but in this case I could not find a single valid reason to avoid the original font: a must! The only point here is that the author could have saved a bit of bandwidth via pre-deflated or gzipped fonts rather than serving them without any apparent optimization.

  2. @font-face {
  3.    font-family: FGB;
  4.    src: url("/experiments/frabk.ttf") format("truetype");
  5. }

It's a shame there is not the real STAR WARS font as well but just an image ... anyway, let's move into more concrete stuff ...


  2. #stage {
  3.   height:600px;
  4.   width:1000px;
  5.   overflow:hidden;
  6.   margin: 0 auto;
  7.   -webkit-perspective:800;
  8.   -webkit-perspective-origin:center 300px;
  9. }

The stage is the block element where the magic happens. The perspective property is able to give us a "deep space" 3D feeling making closer objects look larger than further ones. Via origin modification we can decide where things should disappear, in this case a bit higher point than a central 400px, to create a similar atmosphere respecting the movie choice (and I guess to make content readable as well).

Iteration-count and Custom transitions

  2. #far-far-away {
  3.   color:rgb(75,213,238);
  4.   font-family:FGB, sans-serif;
  5.   font-size:48px;
  6.   line-height:1.5;
  7.   position:absolute;
  8.   top:200px;
  9.   left:190px;
  10.   opacity:0;
  11.   -webkit-animation:fade-in-out 6s linear;
  12.   -webkit-animation-iteration-count: 1;
  13.   -webkit-animation-delay:5s;
  14. }

Far far away is the initial text. As we can see with other browsers as well this appears and disappear in 6 seconds.
This fade-in-out happens just once, so at the end of the effect, unless we won't modify the node class, the element won't be displayed anymore. This is what the animation-iteration-count property does while next snippet is the fade-in-out customization:

  2. @-webkit-keyframes fade-in-out {
  3.   0% { opacity:0; }
  4.   16%   { opacity:1; }
  5.   84%   { opacity:1; }
  6.   100%   { opacity:0; }
  7. }

Via keyframes <transition_name> we can blend FX linearity deciding the amount of opacity, or other properties, at certain moments.
A generic normal linear fade-in-out would be visible 100% only in the middle of the transition while in this case it is forced to be visible for 68% of the time, making fade in and out still homogeneous but controlling the full opacity for longer.
We could have used an ease-in-out effect over opacity property to obtain a similar result but I find definitively more interesting this kind of approach.

Warp Speed: Action!

Thanks to Z axis transitions the initial STAR WARS image can appear and disappear using again a customized FX:

  2. @-webkit-keyframes logo {
  3.   0% { -webkit-transform: translateZ(0); opacity:1;}
  4.   50% { -webkit-transform: translateZ(-50000px); opacity:1; }
  5.   60% { -webkit-transform: translateZ(-60000px); opacity:0; }
  6.   100%   { -webkit-transform: translateZ(-100000px); opacity:0;}
  7. }
  9. /* few lines after, img is the only logo image */
  10. img {
  11.   opacity:0;
  12.   position:absolute;
  13.   top:100px;
  14.   width:1000px;
  15.   -webkit-transform-origin:center center;
  16.   /* above custom logo animation */
  17.   -webkit-animation:logo 25s linear;
  18.   -webkit-animation-iteration-count: 1;
  19.   /* suspance before the logo ... */
  20.   -webkit-animation-delay: 12s;
  21.   /* logo appears slower and fly away faster */
  22.   -webkit-animation-timing-function: ease-in;
  23. }

Above mix of webkit properties suggests me that new JavaScript libraries will use run-time actions to CSS transformations soon, rather than hard and manual JS computations over computed styles or similar expensive operations.
We can control delays, we can stop FXs removing classes or simply overwriting existent directives and, moreover, we can split the CSS itself into logical parts as the same @gesteves did, putting custom animations all together: good hint!

The Crawl

Last piece to check out is the text plus its title.

  2. /* custom crawl FX */
  3. @-webkit-keyframes crawl {
  4.   /* axis management until it disappears */
  5.   0% { -webkit-transform:rotateX(80deg) translateZ(300px) translateY(1100px);opacity:1;}
  6.   40% { -webkit-transform:rotateX(80deg) translateZ(300px) translateY(-340px);opacity:1;}
  7.   80% { -webkit-transform:rotateX(80deg) translateZ(300px) translateY(-1780px);opacity:0;}
  8.   100% { -webkit-transform:rotateX(80deg) translateZ(300px) translateY(-2500px);opacity:0;}
  9. }
  11. #crawl {
  12.   color:rgb(252,223,43);
  13.   font-family:FGD, sans-serif;
  14.   text-align:center;
  15.   font-size:36px;
  16.   opacity:0;
  17.   /* long animation */
  18.   -webkit-animation:crawl 120s linear;
  19.   /* again just once */
  20.   -webkit-animation-iteration-count: 1;
  21.   /* starting while the logo is still there */
  22.   -webkit-animation-delay:16s;
  23.   /* preserving 3D aspect for the entire animation */
  24.   -webkit-transform-style:preserve-3d;
  25. }
  27. #crawl p.title {
  28.   font-family:FGDC, sans-serif;
  29.   /* it's a title */
  30.   text-transform:uppercase;
  31.   /* it's massive */
  32.   font-size:96px;
  33.   /* but scaled to fit inside margins */
  34.   -webkit-transform:scaleX(0.6);
  35. }
  37. #crawl p {
  38.   /* preserve spaces */
  39.   white-space:pre;
  40. }

The Mythical Song

Well, this demo could not miss a proper audio element:

  2. <audio src="/experiments/starwars.m4a" id="audio" autobuffer="autobuffer" />

Apparently the used compression is truly good and the sound loud and clear. But who is in charge to start above song?


Quite hilarious all this demo does not basically need JavaScript at all except for an audio delay forced via interval:

  2. setTimeout("document.getElementById('audio').play()", 12000);

If we have a good broadband connection and we are sure in 12 seconds we have buffered enough audio, the synchronization between JavaScript and the transition delay is almost perfect and the demo experience unique.

It is great to see this work, and I look forward to seeing what he comes up with next. It feels that with HTML5, CSS3, and the Web.Next we will be able to be much more creative. Finally, it's December, I can already imagine a CSS3 based snow effect for our pages ... no?

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
No Soup for you

Don't be the product, buy the product!

YES, I want to SOUP ●UP for ...