知らないうちにMacがシステム標準でJavaScriptで操作できるようになってた (JXA)



知ってる人には今更と思いますが、今まで知らなかったのでメモメモ。
AppleScriptの代わりにJavaScriptを使えるようになってました。

Yosemiteからの新機能だそうです。
JXAとも呼ばれています。宇宙航空研究開発機構とは無関係です。

(追記：JXAは公式の略称です →[Introduction to JavaScript for Automation Release Notes](https://developer.apple.com/library/prerelease/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/Articles/Introduction.html#//apple_ref/doc/uid/TP40014508-CH111-SW1))

詳しくは [Appleの公式ドキュメント](https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/) か、「参考」にあるリンクへどうぞ。

もう一つ記事を書いたのでこちらもよかったらどぞ。
[Macのキーボード入力、マウスクリックをJavaScriptで (JXA)](http://qiita.com/zakuroishikuro/items/afab0e33ad2030ba2f92)

# Script Editorで使う方法

まずScript Editorを使う方法を説明します。
好きなテキストエディタを使いたい場合は飛ばしてください。
(でも「用語説明」の表示の仕方は覚えておいてください。)

おもむろにScript Editorを立ち上げて「JavaScript」を選択します。

![スクリーンショット 2015-02-08 22.44.53.png](https://qiita-image-store.s3.amazonaws.com/0/18902/663d5c21-5345-9ff4-fe10-1651d8ad3d1a.png "スクリーンショット 2015-02-08 22.44.53.png")

## 実行

実行は三角ボタンか`command + r`です。

ログを表示してみましょう。
普通に`console.log`でいけます。
ただし、ログは左下のボタンの3つ目を選択していないと表示されません。

![スクリーンショット 2015-02-08 22.48.47.png](https://qiita-image-store.s3.amazonaws.com/0/18902/20997113-9e85-f860-f3b1-8b99af80c0de.png "スクリーンショット 2015-02-08 22.48.47.png")

ちなみに、赤丸ボタンは操作をスクリプトとして記録するボタンですが、JXAでは使えません。
(man osalangを参照)

## 環境設定

環境設定でJavaScriptをデフォルトにしましょう。(Apple Script好きは別)
ついでに「スクリプトメニュー」も表示しておいたほうが便利です。
「コンピュータスクリプト」は情報古くて動かないのあるしApple Scriptだし不要と思います。

![スクリーンショット 2015-02-08 22.25.55.png](https://qiita-image-store.s3.amazonaws.com/0/18902/7aee8cd3-d779-ee4f-32ed-6c3eac05355f.png "スクリーンショット 2015-02-08 22.25.55.png")

## 用語説明

用語説明もApple Scriptのものでなく、ちゃんとJavaScriptのものが読めます。
`command + shift + o`から選択できます。

![スクリーンショット 2015-02-08 22.40.43.png](https://qiita-image-store.s3.amazonaws.com/0/18902/2c4fe6db-93e4-5c8c-5a15-e9ce5cb89018.png "スクリーンショット 2015-02-08 22.40.43.png")

## Automator

Automatorでも利用できます。Script Editor関係ないですが。

![スクリーンショット 2015-02-12 15.54.55.png](https://qiita-image-store.s3.amazonaws.com/0/18902/61c778f6-064d-4b08-79ea-ab21acc3f4f0.png)

# Script Editorを使わない方法 (osascriptコマンド)

ターミナルから`osascript`コマンドで実行できます。
Script Editorを使わず、好きなテキストエディタを使えます。
デフォルトはApple Scriptなので`-l`オプションでJavaScriptを指定します。

## ファイルから実行
`.js`ファイルを実行してみます。

```js:sample.js
console.log('ふぁいるから実行')
```

```
$ osascript -l JavaScript sample.js
```

>ふぁいるから実行

## 文字列から実行 (-e)

`-e`オプションをつけると文字列をJavaScriptとして実行します。

```
$ osascript -l JavaScript -e "console.log('えばりゅえーと')"
```

>えばりゅえーと

ちなみに、JXAでは最後に評価された値が自動で出力されるので、console.logを書く必要はないです。

```
osascript -l JavaScript -e "1 + 1"
```
>2

出力させたくない場合は空文字列かundefinedを最後に評価させると改行のみ出力されます。
どうしても改行も出力させたくない場合、ObjCオブジェクトからstdlibをインポートしてステータスコード0を返します。
参考: [Exotic Recipes · dtinth/JXA-Cookbook Wiki](https://github.com/dtinth/JXA-Cookbook/wiki/Exotic-Recipes#suppressing-osascripts-last-statement-result)

```js:何も出力せず終了
ObjC.import('stdlib');
$.exit(0);
```

## パイプから実行

パイプで渡された文字列もJavaScriptとして実行されます。

```
$ echo "new Date()" | osascript -l JavaScript
```
>Sat Feb 14 2015 07:00:18 GMT+0900 (JST)

## コマンドライン引数の使用

コマンドライン引数も使えます。
`run`という名前の関数を作るだけ。かんたん！
C言語のmain関数のようなものです。

```js:sample.js
function run(argv){ 
  console.log(argv.length + "つ引数が渡されました。");
  console.log(JSON.stringify(argv));
}
```

```
$ osascript -l JavaScript sample.js one two
```

>2つ引数が渡されました。
>["one","two"]

↓run関数を作らなくても、ObjCからもやろうと思えばできます。
[Shell and CLI Interactions · dtinth/JXA-Cookbook Wiki](https://github.com/dtinth/JXA-Cookbook/wiki/Shell-and-CLI-Interactions#arguments)

## インタラクティブモード (-i)

`-i`をつけるとREPLになります。(Rubyのirbのようなもの)
`control + c`で終了です。

```
$ osascript -l JavaScript -i
>> console.log("いんたらくてぃぶ もーど")
いんたらくてぃぶ もーど
=> undefined
>> 1 + 1
=> 2
>> 
```

いちいちこんな長いの入力してられないのでalias貼りましょう。

```
echo 'alias jxa="osascript -l JavaScript"' >> .bash_profile
```

# Macを操作してみる

`Application("アプリケーション名とか")`でアプリケーションを参照してMacを操作できます。
Apple Scriptにおける`tell application`の部分です。

ダイアログを表示します。
アプリケーションはFinderでも何でもいいです。
(Appleのドキュメントではvarとセミコロンを省略していますが、何となくつける派です)

```js:だいあろぐ
var app = Application("System Events");

app.includeStandardAdditions = true;
app.displayDialog("える・ぷさい・こんぐるう");
```

![スクリーンショット 2015-02-08 23.14.37.png](https://qiita-image-store.s3.amazonaws.com/0/18902/d80d0875-5448-8a32-f6cd-f5d80513bd33.png "スクリーンショット 2015-02-08 23.14.37.png")

アラートを表示するには`includeStandardAdditions`をtrueにする必要があります。
これをすると、Standard Additionという機能拡張が有効になります。

ここ見れば基本はだいたい分かります。

- [鳶嶋工房 / AppleScript / JavaScript for Automation (JXA)](http://tonbi.jp/AppleScript/JavaScript/)
- [Home · dtinth/JXA-Cookbook Wiki](https://github.com/dtinth/JXA-Cookbook/wiki)

何が出来るのか、具体例を見たいなら以下のページおすすめ。

- [Javascrript for OSX Automation アドベントカレンダー - それマグで！](http://takuya-1st.hatenablog.jp/entry/2014/12/01/000000)
- [Macのキーボード入力、マウスクリックをJavaScriptで](http://qiita.com/zakuroishikuro/items/afab0e33ad2030ba2f92) (←自作)

# 疑問

Script Editorで`shift + command + l`を押すとライブラリウィンドウを表示できます。
アプリケーションを選択して、メニューバーのスクリプトアイコンを押すとそのアプリケーションを対象にしたスクリプトの下書きを開けますが、以下のようにnewとvarがついてます。

```
var Finder = new Application("Finder")

Finder.
```

Appleのドキュメントではついてません。
JXAではどちらが好ましいんでしょう。統一してほしい。

```
TextEdit = Application('TextEdit')
path = Path('/Users/username/Desktop/foo.rtf')
TextEdit.open(path)
```

# 参考

- [JavaScript for Automation Release Notes](https://developer.apple.com/library/mac/releasenotes/InterapplicationCommunication/RN-JavaScriptForAutomation/)
- [鳶嶋工房 / AppleScript / JavaScript for Automation (JXA)](http://tonbi.jp/AppleScript/JavaScript/)
- [Home · dtinth/JXA-Cookbook Wiki](https://github.com/dtinth/JXA-Cookbook/wiki)
- [Mac : JavaScript for Automation (JXA) 例文辞典](http://www.openspc2.org/reibun/JXA/Yosemite/)
- [Javascrript for OSX Automation アドベントカレンダー - それマグで！](http://takuya-1st.hatenablog.jp/entry/2014/12/01/000000)
- [Getting Started with JavaScript for Automation on Yosemite – MacStories](http://www.macstories.net/tutorials/getting-started-with-javascript-for-automation-on-yosemite/)
- [【Yosemiteの新機能】JavaScriptでアプリケーションを操作し、面倒な作業を自動化してみた | MEMOPATCH](http://memo.goodpatch.co/2014/07/javascript-in-yosemite/)
- [OS X YosemiteからJSでMacアプリを作れるようになったって！？と聞いてみたものの | mah365](http://blog.mah-lab.com/2014/10/04/os-x-yosemite-app-with-javascript/)

Apple Scriptの予備知識も頭に入れておくと役に立つかもしれません。
- [鳶嶋工房 / AppleScript / 入門(Introduction)](http://tonbi.jp/AppleScript/Introduction/)
- [Applescriptサンプル](http://www.asahi-net.or.jp/~va5n-okmt/factory/applescript/sample_code/)
- [Script factory : AppleScript ことはじめ](http://www.script-factory.net/monologue/AppleScriptIntroduction/index.xhtml)