ddribin / jscocoa forked from parmanoir/jscocoa

Write Cocoa applications in Javascript

This URL has Read+Write access

name age message
directory GC ObjC JSCocoa/ Fri Mar 20 04:12:03 -0700 2009 CHECK - removed tests 11 12 15 30 32 - works wi... [parmanoir]
directory GUIConsole/ Sat Jul 04 15:46:50 -0700 2009 Added JSCocoa.JSFunctionNamed [parmanoir]
directory JSCocoa/ Loading commit data...
directory JSCocoaLauncher OLD/ Fri Apr 03 07:22:28 -0700 2009 starting new launcher [parmanoir]
directory JSCocoaLauncher/ Sat Jul 04 15:46:50 -0700 2009 Added JSCocoa.JSFunctionNamed [parmanoir]
directory JSLocalizedString/ Tue Mar 10 09:41:15 -0700 2009 Made loading class.js optional [parmanoir]
file License Thu Feb 12 13:33:29 -0800 2009 Added license [parmanoir]
directory Multiple JSCocoa instances/ Fri Mar 20 04:12:03 -0700 2009 CHECK - removed tests 11 12 15 30 32 - works wi... [parmanoir]
directory NSLogConsole from JSCocoa/ Tue Dec 30 17:06:02 -0800 2008 first commit [parmanoir]
directory ProcessViewer/ Sat Jul 04 15:46:50 -0700 2009 Added JSCocoa.JSFunctionNamed [parmanoir]
file README.markdown Sat Jul 18 15:49:19 -0700 2009 Readme update : GC [parmanoir]
directory Samples/ Tue Dec 30 17:06:02 -0800 2008 first commit [parmanoir]
directory Tests/ Thu Apr 23 02:15:16 -0700 2009 Added allKeys method to Object.prototype with d... [parmanoir]
directory TestsRunner/
directory XCode Templates/ Tue Dec 30 17:06:02 -0800 2008 first commit [parmanoir]
directory iPhoneTest2/ Thu Feb 12 07:14:08 -0800 2009 memory buffer working [parmanoir]
README.markdown

JSCocoa, a bridge from Javascript to Cocoa

JSCocoa lets you use Cocoa in Javascript. You can write Cocoa applications (almost) entirely in Javascript, or use it as a Plugin engine, like Acorn does. JSCocoa uses WebKit's Javascript framework, JavascriptCore.

JSCocoa is a way to use Cocoa from a Mac desktop app or from the iPhone simulator. (iPhone coming up after I implement Tim Burk's method pool to sidestep iPhone's disabled mprotect). It works just like other bridges :

JSCocoa isn't a Javascript framework to use on the Web. For that, check out :

  • Cappuccino an open source framework that makes it easy to build desktop-caliber applications that run in a web browser
  • SproutCore makes building javascript applications fun and easy

Contribute and discuss

  • Discussion group Questions ? Join the Google group and ask away !
  • Twitter Tweet me questions and comments
  • Github fork JSCocoa from Github, add changes, and notify me with a pull request
  • Documentation on Google Code

Who uses it ?

Are you missing on that list ? Send me a mail !

What does it look like ?

Use straight Javascript syntax to call Cocoa.

// Get current application name
var appName = NSWorkspace.sharedWorkspace.activeApplication.NSApplicationName

// Alloc an object (need to release)
var button = NSButton.alloc.initWithFrame(NSMakeRect(0, 0, 100, 40))
// Alloc an object (no need to release)
var button = NSButton.instance({ withFrame:NSMakeRect(0, 0, 100, 40) }) 

// Setting
var window = NSWorkspace.sharedWorkspace.activeApplication.keyWindow
// Instead of calling setTitle ...
window.setTitle('new title')
// ... set the 'title' property
window.title = 'new title'

// Call methods with jQuery-like syntax
obj.call({ withParam1:'Hello', andParam2:'World' }) 
obj['callWithParam1:andParam2:']('Hello', 'World') 
obj.callWithParam1_andParam2('Hello', 'World' )

// Unicode identifiers !
function    追加する(最初の, 次の) {   return 最初の+ 次の }
var 結果 = 追加する('こんにちは', '世界')
NSApplication.sharedApplication.keyWindow.title = 結果

// Define a new Javascript class usable by Cocoa (inspired by Cappucino)
class MyClass < NSObject
{
    // Custom drawing, calling parent method
    - (void)drawRect:(NSRect)rect
    {
        // do some drawing here
        ...
        // Call parent method
        this.Super(arguments)           
    }
    // Class method
    + (float)addFloatX:(float)x andFloatY:(float)y
    {
        return x + y
    }
}

// Manipulate an existing class
class NSButton
{
    // Add a method to an existing class
    - (void)someNewMethod:(NSString*)name
    {
        ...
    }

    // Swizzle an instance method of an existing class
    Swizzle- (void)drawRect:(NSRect)rect
    {
        // Draw something behind the button
        ...
        // Call original swizzled method
        this.Original(arguments)
        // Draw something in front of the button
        NSBezierPath.bezierPathWithOvalInRect(rect).stroke
    }
}

Starting up

This will start a controller, eval a file, call a Javascript method and get an ObjC object out of it. You can start multiple interpreters, e.g. one for each document.

// Start
JSCocoa* jsc = [JSCocoa new];

// Eval a file
[jsc evalJSFile:@"path to a file"];
// Eval a string
[jsc evalJSString:@"log(NSWorkspace.sharedWorkspace.activeApplication.NSApplicationName)"];

// Add an object of ours to the Javascript context
[jsc setObject:self withName:@"controller"];

// Call a Javascript method - we can use any object we added with setObject
JSValueRef returnValue = [jsc callJSFunctionNamed:@"myJavascriptFunction" withArguments:self, nil];
// The return value might be a raw Javascript value (null, true, false, a number) or an ObjC object
// To get an ObjC object
id resultingObject = [jsc unboxJSValueRef:returnValue];

// (Cleanup : only needed if you don't use ObjC's Garbage Collection)
// Remove all existing references to ObjC objects in the Javascript context
[jsc unlinkAllReferences];
[jsc garbageCollect];
// Destroy
[jsc release];

Add it to your project

Going the framework route :

  • Build JSCocoa/JSCocoa.xcodeproj
  • Add built JSCocoa.framework to your project
  • import <JSCocoa/JSCocoa.h>

No framework, adding JSCocoa files into your project :

  • Drag the JSCocoa folder in your project
  • Delete irrelevant files (Info.plist, JSCocoa_Prefix.pch, English.lproj, project files)
  • Add the JavascriptCore framework
  • In 'Build' project settings, add -lffi to 'Other linker flags'
  • import "JSCocoa.h"

Thanks !

  • Gus Mueller — Distant Object code
  • Jonathan 'Wolf' Rentzsch — JRSwizzle

Questions, comments, patches

Send me a mail !

Patrick Geiller
parmanoir@gmail.com