The Shape of Everything
A website mostly about Mac stuff, written by Gus Mueller
» Acorn
» Twitter
» Pizza Lab
» Code
» Archive
November 20, 2010

Here's a little update on what I've been doing with JSTalk lately ("All the power of Cocoa, wrapped up in JavaScript").

"Get Result of JSTalk" System Service

This works exactly like AppleScript's "Get Result of AppleScript". Just substitute JSTalk for AppleScript in there. It's kind of neat- you just highlight some code like "123+4*5" and you'll get 143 replaced in it. This is great for doing little bits of math in Interface Builder text fields.

Of course you also have the full power of Cocoa with this service, so you can highlight [[@"~" stringByExpandingTildeInPath] uppercaseString] and get back "/VOLUMES/SRV/USERS/GUS" in my case. Is this useful? Maybe not this example, but for some folks this service will be very useful. (You might need to turn this service on in your system preferences first for it to show up).

Triple Quoted Strings.

This is just what it sounds like, and is inspired from Python. If you have a multi-line string, you can wrap it up in """'s, and JSTalk will do the right thing.

Plugins for Image Processing

JSTImageTools is a plugin I've written which makes viewing various image formats a piece of cake. It also lets you rapidly build/prototype CIImage filters, which has been wonderful for me lately. Here's an example which just converts an image to grayscale:

var ciKernel = """kernel vec4 grayscale(sampler src) { vec4 p = sample(src, samplerCoord(src)); p.rgb = vec3(p.r0.3 + p.g0.59 + p.b*0.11); return premultiply(p); }"""; var filter = [JSTQuickCIFilter quickFilterWithKernel:ciKernel]; // this may take a second to download var url = [NSURL URLWithString:"http://images.apple.com/imac/images/overview_hero1_20100727.png"]; var img = [CIImage imageWithContentsOfURL:url]; // add the first and only argumet, our ciimage [filter addKernelArgument:img]; [JSTImageTools viewCIImage:[filter outputImage] inWindowNamed:"test" extent:[img extent]];

That's a simple example, but you can write much more complicated scripts using multiple images and filters and whatever. Acorn 2.6's Tilt Shift filter was first prototyped in JSTalk.

The Future?

I've been adding little bits of code to the editor here and there, which hopefully makes it a nicer environment to write your scripts in. For instance, if you type a '(' it'll automatically insert the ending ')' for you. Same with [ and {. I know I need to turn this into a pref, so that'll happen eventually as well.

What about packaging standard JSTalk plugins into the editor? If you want to use the database or image tools plugins you have to manually install them. This is possibly dumb since a brand new user might try and run my example script and the editor will bark at you about the JSTImageTools class not being available. If I bundled those in the editor, then this wouldn't be a problem.

I've also been hacking away on a new bridge for JSTalk (currently JSTalk uses JSCocoa from Patrick Geiller). Why a new bridge if the current one works? This is mostly out of curiosity on my part, in an attempt to really understand just what the heck goes on with the Objective-C runtime. Writing my own bridge has also allowed me to try out some ideas I've had in mind, such as having the preprocessor turn your Objective-C method calls directly into calls to objc_msgSend. Right now, here's what happens with JSTalk:

1) You write [NSURL URLWithString:foo]; 2) JSTalk's preprocessor turns this into NSURL.URLWithString(foo), which is the format JSCocoa needs for ObjC method calls. 3) Internally JSCocoa will convert URLWithString into a selector, and then call objc_msgSend(NSURL, "URLWithString", foo);

It seems to me it'd be easier to skip a couple of steps if the preprocessor just wrote out 'objc_msgSend(NSURL, "URLWithString", foo);' and that was called to the new bridge.

Anyway, it's just an idea and it has been fun hacking on the code and playing with libffi. I'd say the chances of JSTalk ever using the new bridge are pretty slim since I'm lazy and I'm hitting the harder parts of the bridge- but who knows.

If you use JSTalk- what else would you want to see in it?