New Tutorial on Writing Widgets

As the release of Coherent looms nearer, I’ve been encouraged to start writing some documentation. My first effort is up: Writing a Widget. This tutorial takes you through creating a widget using Coherent starting with raw mark up and ending with a functional (if simple) widget. Thanks to some great feedback (and encouragement) from Neil Mix of Pandora, this tutorial doesn’t suck.

Oh, and if you haven’t tried Pandora yet, what the heck are you waiting for? This is one of the coolest things I’ve run across in ages. Of course, now my wallet is going to be completely empty because I’ve been turned onto a half dozen musicians I’d never heard of before…

Writing a Widget

Coherent strives to present a sane Model View Controller paradigm for client-side Web development. So writing a Widget using the Coherent library may be a bit different from what your accustomed to. However, if you’ve ever written desktop software, this should feel right at home.

For this tutorial, we’re going to build a simple photo gallery to display a static list of images with captions. In a future tutorial, we’ll see how we can expand this sample to pull image information from Flickr or other sources. Read More

Pitting JavaScript Against Objective-C

In many ways, the API of Coherent is drawn from various Cocoa APIs: NSKeyValueCoding, NSKeyValueObserving, NSKeyValueBindingCreation, NSArrayController and others. Of course, some allowances have to be made for the syntax differences between Objective-C and JavaScript. So methods like setValue: forKey: from NSKeyValueCoding become setValueForKey on coherent.KVO. But where possible, I’ve tried to adhere to the same or similar API.

I’m not certain that’s such a great idea. After all, the target market for Coherent is JavaScript programmers not Objective-C programmers. So just how important is it to mimic the API that Objective-C programmers will feel comfortable with?

Getters & Setters

In Cocoa, classes declare getters and setters to access instance properties. The property getter is named the same as property, while the setter is prefixed with set. You might have the following code to access the name property of a class:

-(NSString*) name;
-(void) setName: (NSString*)newName;

These methods are invoked as follows:

NSString* theName= [someObject name];
[someObject setName: aNewName];

On the other hand, the idiom in JavaScript is to mimic the Java Beans style of getter and setter methods: the getter is prefixed with get and the setter with set. The same code might be written in JavaScript as:

getName: function()
{
    ...
},

setName: function()
{
    ...
}

(Presuming this is inside an Object literal…) And these methods would be invoked as follows:

var theName= someObject.getName();
someObject.setName(aNewName);

Prior to r146, Coherent required getters to follow the Objective-C idiom. However, now Coherent will check first for a getter with the get prefix before looking for a getter with the same name as the property.

Ultimately, it would be nice if every browser supported JavaScript properties, but until Microsoft catches up with FireFox and Safari, we’ll have to make do with explicit getters & setters.

Deviation from the Spec

As I’m writing the documentation for various parts of the library, I’ve come across several places where I’m not adhering to the Cocoa spec exactly. In some cases, I think my implementation makes better sense for JavaScript. But in others, it’s clear in hind sight why Apple chose to design the API the way it did. Read More

Automatic Change Notifications in Coherent

I’ve written a little bit about an exciting new feature in the Coherent library: automatic change notifications. In short, this reduces the amount of code you need to write and if your application only needs to support a Class A browser (like Safari 3 or Firefox), you can rely on JavaScript’s support for property getter/setter methods to further reduce your work.

Now if I can only figure out what I’m going to do about Arrays and change notifications, then I could wrap up the changes needed for 1.0.