Yosemiteから出来るようになったらしいので作ってみます。
早速ソースです。
// Generated by CoffeeScript 1.9.0
(function() {
var win;
ObjC["import"]('Cocoa');
win = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer($.NSMakeRect(0, 0, 160, 90), $.NSTitledWindowMask | $.NSMiniaturizableWindowMask | $.NSClosableWindowMask, $.NSBackingStoreBuffered, false);
win.title = 'my win';
win.center;
win.makeKeyAndOrderFront(win);
}).call(this);
ObjC["import"]('Cocoa');
でCocoaフレームワークをインポートして$.NSWindow
でウインドウを作ってます。
osacompile -s -l JavaScript -o win.app win.js
とコマンドをうてばwin.appが作られるのでopen win.appで実行出来ます。
上の例ではosacompileに-sを渡すことでウインドウを作るだけで完結した、実行できるアプリケーションを生成してます。ところが
osascript win.js
として実行した場合、実行はされるものの、プログラムはすぐに終了してしまいます。
そこで次の例ではosascriptコマンドでも動くよう改善をしました。
// Generated by CoffeeScript 1.9.0
(function() {
var app, win;
ObjC["import"]('Cocoa');
ObjC.registerSubclass({
name: 'WinDelegate',
superclass: 'NSObject',
protocols: ['NSWindowDelegate'],
methods: {
'windowWillClose:': {
types: ['void', ['id']],
implementation: function(notification) {
return app.terminate(0);
}
}
}
});
win = $.NSWindow.alloc.initWithContentRectStyleMaskBackingDefer($.NSMakeRect(0, 0, 160, 90), $.NSTitledWindowMask | $.NSMiniaturizableWindowMask | $.NSClosableWindowMask, $.NSBackingStoreBuffered, false);
win.delegate = $.WinDelegate.alloc.init;
win.title = 'my win2';
win.center;
win.makeKeyAndOrderFront(win);
app = $.NSApplication.sharedApplication;
app.setActivationPolicy($.NSApplicationActivationPolicyRegular);
app.activateIgnoringOtherApps(true);
app.run();
}).call(this);
$.NSApplicationを自前で用意して、ウインドウのクローズに合わせてterminateするようにしています。この際のwindowWillCloseメッセージを取り扱うために、ObjC.registerSubclassを使っています。
osascript win2.js
とすれば先ほどのようなウインドウが現れ、クローズボタンでの終了が確認できると思います。
ソース一式:
https://github.com/ymmtmdk/osx-app-js
参考:
https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/index.html
http://tylergaw.com/articles/building-osx-apps-with-js
http://qiita.com/zakuroishikuro/items/1b02378bf9e940602d87