If you’re trying to automate tests of your SproutCore application with Selenium, for example, you’ll realise that the HTML element ids are automatically generated. They change every now and then and break all your tests.
To get rid of this problem, you can override the layerId method of certain view classes to generate a stable, and human readable, id.
The following code takes the view hierarchy, and generates an id based on the parents’ names. For example, the mainPage.mainView.someOtherView.theTargetView view will be given the mmsome.theTargetView id.
You can add or overwrite a class property using the mixin method on the class prototype. The following example dynamically adds a keyForParentView method on the SC.View class without modifying SproutCore’s source code:
SC.View.prototype.mixin({
keyForParentView: function() {
var parentView = this.get('parentView'),
key;
for (key in parentView) {
if (this === parentView[key]) return key;
}
return null;
}
});
SproutCore’s SC.Response was recently rewritten and I patched it to avoid an exception to be thrown when a malformed JSON string was parsed. The standard way to write your data source didFetch method is now:
didFetch: function(response, params) {
var results, query = params.query;
if (SC.ok(response) && SC.ok(results = response.get('body'))) {
...
} else {
store.dataSourceDidErrorQuery(query);
}
}
This post will show you how to create a SproutCore ListView with alternate row colors.
Let’s add alternate row colors to the Todos tutorial’s list view. Clone the source code, then switch to the step-5 branch. It should look like this:

The code that’s actually responsible for the ListView is in main_page.js:46:
middleView: SC.ScrollView.design({
hasHorizontalScroller: NO,
layout: { top: 36, bottom: 32, left: 0, right: 0 },
backgroundColor: 'white',
contentView: SC.ListView.design({
contentBinding: 'Todos.tasksController.arrangedObjects',
selectionBinding: 'Todos.tasksController.selection',
contentValueKey: "description",
contentCheckboxKey: "isDone",
canEditContent: YES,
canReorderContent: YES,
canDeleteContent: YES,
destroyOnRemoval: YES,
rowHeight: 21
})
}),
This creates a standard list view whose rows are instances of the SC.ListItemView class. We want to customize the appearance of these rows, so we are going to subclass the SC.ListItemView class and override the render method:
Todos.ListItemView = SC.ListItemView.extend({
render: function(context, firstTime) {
if (this.get('contentIndex') % 2 === 0) {
context.addClass('even');
} else {
context.addClass('odd');
}
return sc_super();
}
});
Let go through this code snippet step by step:
Todos.ListItemView is the subclass’ nameSC.ListItemView.extend is the SproutCore syntax for subclassingrender: function(context, firstTime) is the method defined in view.js that we need to override to customize the view’s appearancecontentIndex property, which is exactly the row’s index. The property is obtained by calling the get method.context object, instance of SC.RenderContext. It has an addClass which adds a css class name to the current HTML element.sc_super().Now, we need to tell the contentView that it should use the Todos.ListItemView class for rows. This is done by adding the following line to the contentView’s parameters:
exampleView: Todos.ListItemView,
Finally, we need to add some css code to style the odd and even rows. Create a list_item.css file in your english.lproj folder:
.sc-list-item-view.even {
background-color: #E4E4E4;
}
Reload your browser, it should look like that:

EDIT: As nexneo points out, there is a simpler way to get the current row index. I’ve replaced this.owner.contentIndexForLayerId(this.layerId) by this.get('contentIndex'). Thanks!
Safari AdBlock 0.4.0 RC3 now works on Snow Leopard.
To make it work, though, you have to run Safari in 32-bit mode. To do so, select Safari.app in the Applications folder, hit ⌘-I to show the “Get Info” window, and check the “Open in 32-bit mode” checkbox:

I’m looking into an alternative solution to allow Safari to run in 64-bit with AdBlock (and any InputManager) enabled.
I installed lighttpd with MacPorts using the usual command
sudo port install lighttpd
But when I try to start it with a custom configuration file, I get the following error:
(plugin.c.213) mod_magnet plugin init failed
(server.c.614) loading plugins finally failed
It looks like the default MacPorts installation didn’t install everything needed for mod_magnet to work. Ports actually come in different flavours called variants. You can either do
port variants lighttpd
to see the different variants of a port, or directly read lighttpd’s portfile which has more info in it. You see on line 85 that the cml variant builds lighttpd with lua, which is the scripting language used by mod_magnet:
variant cml {
depends_lib-append port:lua \
port:libmemcache \
port:memcached \
port:pkgconfig
configure.args-append --with-lua \
--with-memcache
}
The cml variant is probably just what we need. While we’re at it, we are also going to add ssl support to our lighttpd installation.
Now, we first need to remove the previous installation
sudo port uninstall lighttpd
then do the new installation with the cml and ssl variants:
sudo port install lighttpd +cml +ssl
Lighttpd now starts without any error.