最終更新日:2013/11/06

説明は書きかけです。書くだけ書いて全く整理されていません。また、開発中の機能が書いてある場合があります。

MenuBarAppleScript - AppleScriptでメニューバーにメニュー項目とWebView付きのウインドウを作れるアプリケーション

MenuBarAppleScriptとは?

MenuBarAppleScriptはメニューバー右側のステータスバーにメニュー項目を作れるAppleScriptです。自分はメニューバーアプリケーションは15インチのMacを使ってて画面が狭いこともあってあまり好きじゃないのですが、AppleScriptで自由に作成できたら面白いことができるかもしれないということで作ってみました。

WebView付きのウインドウはデスクトップに表示してクリックを無効にすれば、よくあるデスクトップに何か情報を表示するアプリケーションのように使えます。WebViewなので指定したURL、HTML、画像ファイル等を表示できるので何かを表示したい場合に使えると思います。

メニューを作るには何かシステムの情報が必要だろうということで、NSWorkspace、NSDistributedNotificationCenter、AXNotificationの通知を受け取って処理できるようにしました。具体的には、アプリケーションが起動した、切り替わった、iTunesの曲が変わった、ダウンロードが完了した、などの通知を受けて処理ができます。システムから通知が来るので、定期的に監視する等のCPUパワーの消費がありません。

MenuBarAppleScriptに正規表現やハッシュなどの独自の命令を追加してあるので、それらを使うとスクリプトを書くのが便利になると思います。

スクリプトが結構ややこしいので、タイプ別のサンプルを見て、それを変更しながら自作アプリケーションにして下さい。でも、AppleScriptObjCで同等のスクリプトを書くよりは簡単だと思います。

MenuBarAppleScriptでできることを実際にできたもので確認する

MenuBarAppleScriptで作ったアプリケーションにMenuBarAppleScriptで作ったものが置いてあります。とりあえず、どんなことができるか確認したい場合は下の長い説明より実際にできたものを見るのをお勧めします。

MenuBarAppleScriptについて詳しく

MenuBarAppleScriptはAppleScript StudioやAppleScriptObjCのようなAppleScriptを使っている新しい環境です。覚えることもたくさんありますが、同じことをAppleScriptObjCでやるよりはMenuBarAppleScriptの方が簡単ではないかと思います。

MenuBarAppleScriptを使う主な利点、欠点は下記のようになります。

利点

GUIとして、メニューバーアイテムとWebView付きウインドウを作成できる

通常のAppleScriptではGUIは簡単なダイアログしか作れませんが、MenuBarAppleScriptではメニューバーアイテムとWebView付きウインドウを作成できます。

メニューバーアイテムからメニューで選択してスクリプトの各種機能を実行したり、状態を表示したりできます。AppleScriptObjCで0からメニューバーアイテムを作るのよりはMenuBarAppleScriptの方が簡単だと思います。

WebView付きウインドウには画像を表示したり、フォームでダイアログを作って表示したりと、いろいろと応用できると思います。クリックを受け取らない半透明のウインドウなども作れるので、画面の隅っこに常時何か表示したい場合にも使えます。これも、AppleScriptObjCで0からWebView付きウインドウよりMenuBarAppleScriptの方が簡単だと思います。

この2つしかありませんがスクリプトから完全に制御できるのでいろいろとできるようになります。

OSの各種通知を受け取れる

OSにはアプリケーションが起動したとき、切り替わったとき、iTunesの曲が変わったとき、Safariでダウンロードが完了したとき、ネットワークの接続状況が変わったとき、などに通知が送られますが、その通知を受け取ることができます。通常のAppleScriptではこれらの通知は受け取れないのでiTunesの曲が変わった時にしても、一定間隔でチェックする必要がありますが、そういう無駄がなくなります。

AXNotificationの通知は、かなり奥が深くて面白いのですが、これをAppleScriptで使えるものはあまりないと思います。AXNotificationでは、ウインドウのスクロールバーをスクロールした、リストの選択した項目が変わった、選択したテキストが変わった、メニューを選択した、などの通知を受け取ることができます。これらを使うと、かなり特殊なことができるようになります。通常のGUIスクリプティングでは取得できない(と思う)、フォーカスが当たっているGUIパーツを取得できるので、応用範囲が格段に広がります。

AppleScriptを書くのに便利な命令がMenuBarAppleScriptにある

MenuBarAppleScriptに自分がAppleScriptを書いていて欲しいなと思った命令をいくつか追加しました。よくありそうなところではハッシュ関係の命令があります。使い方はちょっと癖がありますが、今までMenuBarAppleScriptでいろいろとスクリプトを書いてきましたがこれがあるとスクリプトを書く効率が格段に上がります。

また、リスト操作、パス関係など、通常それを処理するハンドラを書いている処理も命令を追加して、MenuBarAppleScriptを書く時にそれらのハンドラをコピペしなくていいようにしました。

命令の数は結構多いですが、AppleScriptEditorHelperでメニューから選んで挿入できるので、うろ覚えでも大丈夫です。

欠点

覚えることが多い

最初ははシンプルだったのですが、自分がAppleScriptで欲しい機能をなんでも追加して行ったら、自分でも全機能を把握できないぐらいになってきました。

ただ、覚えたら通常のAppleScriptではできないことができますし、MenuBarAppleScriptの命令も開発効率が上がるものがあると思います。

ただし、MenuBarAppleScriptの命令、キーワードはAppleScriptEditorHelperで挿入できるのでうろ覚えでもだいたい対処できます。

メニューバーアイテム、ウインドウを複雑にコントロールするにはGUIアプリケーションのイベントハンドリングの知識が必要

メニューバーアイテムやウインドウを操作する場合は、特定の処理をした場合に特定のハンドラが実行されます。どのハンドラがどういう時に実行されるかの知識が必要になります。

メニューアイテムにアプリケーションの状態に応じてチェックを付ける等もちょっとこつが必要です。

デバッグしづらい

アプリケーション実行に起きたスクリプトのエラーは原因がコンソールに表示されますが、エラーの行が表示されないので、どこが原因かわかりにくいです。

デバッグ方法を使用してAppleScriptエディタでスクリプトを実行することにより、特定のハンドラのイベントログを確認しながらデバッグすることはできます。

まとめ

自分はMenuBarAppleScriptを作ってから書いたスクリプトはほとんどMenuBarAppleScriptを使っています。自分のAppleScript作成環境がMenuBarAppleScriptで一つ新しいレベルに移行した感じです。もちろん、これは自分が欲しい機能をひたすら追加していったからですが、他の人でも有用に使えるのではないかと思います。MenuBarAppleScriptで作ったアプリケーションを見て、興味が有るものがあったら使ってみて、スクリプトも見てみて、便利そうだと思ったら是非使ってみて下さい。

スクリーンショット

LyricsStarTunes.app : iTunesの曲情報を表示。メニューのテキストをHTMLを使って装飾できます。

開発・動作環境

10.6.8で作ってます。

10.8でちょっとだけ動作確認しました。

MenuBarAppleScriptで作ったアプリケーションの配布について

MenuBarAppleScriptで作ったアプリケーションは自由に配布することができます。許可や連絡等は必要ありません。

同梱している物や、ここで公開しているアプリケーションを改造した物も自由に配布することができます。

新しいMenuBarAppleScriptアプリケーションの作り方

  1. アプリケーションをアプリケーションフォルダに入れます。サブフォルダでも大丈夫です。
  2. MenuBarAppleScript製アプリケーションを複製します。
  3. 複製したアプリケーションを「MenuBarAppleScript初期設定.app」で開きます。ドラッグドロップか実行したら表示されるダイアログで選択して下さい。
  4. アプリケーション名などを付けるダイアログが表示されるので入力すると、設定されます。
  5. アプリケーションをAppleScript エディタにドラッグドロップします。 「スクリプトに対応していないので、以下略」といったダイアログが出ますが、OKを押すとスクリプトが表示されます。 これが実行するスクリプトになりますので編集、保存します。

スクリプトの書き方

通知の種類等でCocoaの知識が必要だったり、結構ややこしいです。アプリケーションのタイプ別にサンプルをいくつか用意したのでそれを参考にどうなってるか見て下さい。

基本的には処理したいイベントや通知を設定すると、そのイベントや通知を処理するハンドラが実行されるので、そのハンドラでアプリケーションに結果をレコードで返して、メニューを作成したり、ウインドウを作成したりします。doInitでどのイベントや通知を処理するか設定しますが設定しないとdoInit以外のハンドラは何も実行されないので注意して下さい。また、設定自体はいつでもできるのでユーザーの命令が来てから、特定の通知をオンにする等もできます。

作ってみたもの・サンプルをダウンロードして参考にして下さい。

MenuBarCounter.app
メニューバーに表示されるテキストをクリックした時に処理をするアプリケーション
YouTubePlayerSample.app
WebViewのウインドウを作成。WebViewに表示したフォームの結果をAppleScriptで処理。
ImageViewer.app
Finderで選択したファイルをWebViewウインドウで表示。
DeskTopWindowTest.app
デスクトップにWebViewWindowを作成して、定期的に表示内容を更新。

実行するハンドラ名

実行するハンドラ名は下記イベント名や通知名の最初にdoを付けたものになります。

例:イベント selectMenuItem の場合
on doSelectMenuItem(theTitle, theTag, theActiveAppRecord, theThisAppRecord)
ハンドラの大文字を小文字は区別されないので上記のようにSを大文字にすることができます。
例:通知 com.apple.iTunes.playerInfo の場合
on docom_apple_iTunes_playerInfo(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord)
.など半角英数_以外の文字はすべて_に置換されます。
例:ウインドウ関係のイベント:windowWillClose
on doWindowWillClose(theWindowName, theActiveAppRecord, theThisAppRecord)

theActiveAppRecord, theThisAppRecordはすべての実行されるハンドラの最後の引数になります。

theActiveAppRecordのキーはアプリケーションの情報のtheUserInfoのキー / theActiveAppRecordを見て下さい。

ハンドラで返すレコードのキー

すべてのハンドラで同じ書式のレコードを返します。このレコードに設定したい値を入れます。

下記のようにして返します。

return {|AutoAddQuitMenuItem|:1, |NSDistributedNotificationList|:{"com.apple.DownloadFileFinished"}, |EventList|:{"selectMenuItem", "menuDidClose"}}

下記スクリプトのように«event MBASHndl»命令でレコードをアプリケーションに処理させることもできます。

«event MBASHndl» {|WebViewWindow|:{|Name|:"YT", |URL|:"http://youtube.com/"}}

キー一覧(順番整理前)

LogAppleScriptError
1を返すと、スクリプトのエラーがConsoleに表示されるようになります。
デフォルト:1
DebugLog
0を返すと、«event DebugLog»の出力をしなくなります。
デフォルト:1
DebugJavaScript
1を返すとJavaScriptの構文エラーと実行時エラーをコンソールに出力します。ただし、エラー内容はわかりにくいです。
デフォルト:0
ネットにあるサイトを表示すると結構エラーがあります。そのような場合は必要な時のみ1にするといいと思います。
SaveDict
1で辞書(ハッシュ)関係の命令の値を初期設定ファイルに保存する。
~/Library/Preferences/com.yourcompany.MenuBarAppleScript.AppName.plist
保存した値は次回起動時に自動的に読み込みます。
propertyみたいなものですが、propertyはスクリプトを編集保存すると値が初期化されますが、これは値を保持したままになります。
SaveDictNow
1で辞書の内容をファイルに保存する
tmpキーは削除しません。
実行中に不慮の事故でアプリケーションが強制終了してデータが消えたら困るときに、これで必要なときに保存出来ます。
MenuBarItemImage
メニューバーに表示する画像
"icon Finder"の様に"icon "の後にアプリケーション名やファイル、フォルダのパスを書くとアイコンになります。
MenuBarItemAlternateImage
メニューバークリック時のハイライトされている時に表示される画像
MenuBarItemImageと同じ書式です。
PriorityToMenuBarItemImage
1の場合、MenuBarItemImageとMenuBarItemTitleが同時に指定されている場合にMenuBarItemImageだけを表示する
一度設定したら値を記憶します。
MenuBarItemImageがあるか無いかわからない場合に1を指定しておくとどちらかを自動的に表示できるように出来ます。
MenuBarItemTitle
メニューバーに表示するタイトル
画像と同時に表示可能
MenuBarItemHTMLTitle
メニューバーに表示するタイトルをHTMLで指定
MenuBarItemHTMLTitleBaseURL
MenuBarItemHTMLTitleを作る時のBaseURL
MenuBarItemToolTip
メニューバーの上にマウスをしばらく置いていると表示するToolTipのテキスト
EventList
メニューバーをクリックしたり、メニューを選択した等のイベントでアプリケーションで利用する物のリスト
{ "*" }ですべてのイベントのハンドラを実行します。ハンドラがスクリプト中に無い場合のエラーは表示されません。
デフォルトは{ "*" }です。
詳しくは通常のイベント
NSWorkspaceNotificationList
NSWorkspaceの通知のリスト
NSDistributedNotificationList
NSDistributedNotificationCenterの通知のリスト
SCNotificationList
SCNotificationの通知のリスト
注意:現在のバージョンでは最初の一回目だけ指定可能で、あとから値を変更したり、削除したりすることはできません。
SCNotificationIgnoreKeyList
SCNotificationは値に変化があった時に実行されるが、辞書の特定のキーの値に変化があった時は処理を実行したくない場合にそのキーを指定する
当然AppleScriptで判定しても良いですが、値が頻繁に変わる場合はAppleScriptを実行して処理するより負荷が少なくなることが期待できます
RunSCNotificationHandler
現在の状態でSCNotificationのハンドラを実行
アプリケーション起動時に実行して現在値を確認する為等に
AXNotificationList
AXNotificationの通知のリスト
ReplaceString
サービスで置換するテキスト
QuitAfterSec
指定した秒後にアプリケーションを終了する
Quit
1でアプリケーションを終了する
Init
アプリケーションの名前やサービスを設定するスクリプトを実行する
RemoveMenuBarItem
1でメニューバーからメニューを取り除く
MenuBarItemLength
幅をピクセルで指定
"Variable"を指定すると動的に設定した値の幅になる。デフォルト値はこれになります。
MenuBarItemImageMaxWidth
MenuBarItemImageMaxHeight
MenuBarItemAlternateImageMaxWidth
MenuBarItemAlternateImageMaxHeight
画像の最大サイズ。縦横比を維持してリサイズします。
MaxHeightのデフォルト値は22です。0でリサイズしません。
一度設定したら値を覚えます。変更しないならdoInitで一度設定しておけばOKです。
MenuItemList
メニューに表示するアイテムのリスト
showContextMenuと同じ書式
"---title タイトル"が追加されています。
PopUpMenuItemList
メニューに表示するアイテムのリスト。すぐにポップアップして表示する。
クリック時に動的にメニューを作りたい場合に使用する。参考:MoveFileMenu.app
showContextMenuと同じ書式
ContextMenuItemList
マウスの位置にコンテキストメニューを表示する。
showContextMenuと同じ書式
下記メニューアイテムで位置を変更できます
"---contextMenuPositionX center" -- left/center/right/mouse/#x
"---contextMenuPositionY top" -- top/center/bottom/mouse/#y
AutoAddQuitMenuItem
1でメニューの一番下に自動的にQuitメニューアイテムを追加する
一度設定したら値を覚えます
デフォルトは1
AutoAddQuitMenuItemMenuTypeList
AutoAddQuitMenuItemを適用するメニューの種類のリスト
デフォルトはすべてです
Menu : MenuItemListで設定するメニュー
PopUpMenu : PopUpMenuItemListで設定するメニュー
ContextMenu : ContextMenuItemListで設定するメニュー
AutoAddLaunchOnLoginMenuItem
1でログイン時に自動的に起動するように設定できるメニューアイテムを追加します。
一度設定したら値を覚えます
デフォルトは1
AutoAddLaunchOnLoginMenuItemMenuTypeList
AutoAddLaunchOnLoginMenuItemを適用するメニューの種類のリスト
デフォルトはすべてです
Menu : MenuItemListで設定するメニュー
PopUpMenu : PopUpMenuItemListで設定するメニュー
ContextMenu : ContextMenuItemListで設定するメニュー
AutoAddVersionMenuItem
1でメニューにMenuBarAppleScriptのバージョンを追加します。
一度設定したら値を覚えます
デフォルトは1
何故表示しているかというと、自分はMenuBarAppleScriptでいろいろ作っていてバージョン違いのものがたくさんあり簡単に確認したいからです。
AutoAddVersionMenuItemMenuTypeList
AutoAddVersionMenuItemを適用するメニューの種類のリスト
デフォルトはすべてです
Menu : MenuItemListで設定するメニュー
PopUpMenu : PopUpMenuItemListで設定するメニュー
ContextMenu : ContextMenuItemListで設定するメニュー
IdleSec
指定した秒後にdoIdle()ハンドラを実行する。繰り返しはしないので連続して実行したい場合はdoIdleで毎回この値を返して下さい。
新しい値を返すと、タイマーはキャンセルされ新しい指定秒後にdoIdleが実行されます。
DoAfterSec
{|Handler|:"Test", |Sec|:3, |UserInfo|:"hoge" }on DoAfterSecTest(theUserInfo,theActiveAppRecord, theThisAppRecord)ハンドラを3秒後に実行する。
Secに0を指定するとキャンセルできます。同じハンドラを実行前に再度指定すると、現在のタイマーをキャンセルして新しくタイマーをセットします。
UserInfoは未指定の場合はmissing valueになります。
DoAtTime
|DoAtTime|:{|Handler|:"22Century", |Time|:{|Year|:2101, |Month|:1, |Day|:1, |Hour|:0, |Minute|:0, |Second|:0}}
|DoAtTime|:{|Handler|:"NewYear", |Time|:{|Month|:1, |Day|:1, |Hour|:0, |Minute|:0, |Second|:0}}
|DoAtTime|:{|Handler|:"NyaaNyaaDayTime", |Time|:{|Day|:2, |Hour|:2, |Minute|:2, |Second|:2}}
|DoAtTime|:{|Handler|:"WBS", |Time|:{|Hour|:23, |Minute|:0, |Second|:0}}
|DoAtTime|:{|Handler|:"Every30Min", |Time|:{|Minute|:30, |Second|:0}}
|DoAtTime|:{|Handler|:"Every15Sec", |Time|:{|Second|:15}}
|DoAtTime|:{|Handler|:"NewYear", |Time|:{|Month|:1, |Day|:1, |Hour|:0, |Minute|:0, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:1}
|DoAtTime|:{|Handler|:"NyaaNyaaDayTime", |Time|:{|Day|:2, |Hour|:2, |Minute|:2, |Second|:2}, |Repeat|:1, |DoOnlyFirstRun|:1}
|DoAtTime|:{|Handler|:"WBS", |Time|:{|Hour|:23, |Minute|:0, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:1}
|DoAtTime|:{|Handler|:"Every30Min", |Time|:{|Minute|:30, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:1}
|DoAtTime|:{|Handler|:"Every15Sec", |Time|:{|Second|:15}, |Repeat|:1, |DoOnlyFirstRun|:1}
指定した時間に下記ハンドラが実行されます。
Repeat : 繰り返します
DoOnlyFirstRun : ハンドラのtheIsFirstRunが1の時のみハンドラを実行します。
on doAtTimeTest(theFireTimeDifference, theIsWake, theIsFirstRun, theSettingRecord, theActiveAppRecord, theThisAppRecord)
theFireTimeDifference : 指定した時間と現在時間の差の秒数。正数。
theIsWake : スリープから起きた時に予定時間を過ぎていた場合に実行される時に1。
theIsFirstRun : 上記スリープから起きた時にはDoAtTimeを複数登録していると複数回同じハンドラが実行される場合がありますが、その名前のハンドラが最初に実行される場合1。theIsWakeが0の場合は常に1。DoOnlyFirstRunが1の場合、これが1の時しかハンドラは実行されません。
theSettingRecord : |DoAtTime|に渡したレコード(キーが小文字になっていますが登録に影響はありません)。Repeatで繰り返すように出来ますが、«event MBASHndl» {|DoAtTime|:theSettingRecord}を実行することによって再度DoAtTimeを同じ設定で登録して手動で繰り返すことができます。
例:{ |Time|:{|Minute|:30, |Second|:0} }で時間指定すると、次の30分にハンドラを実行します。秒や時間指定も同じです。
例:{ |Time|:{|Minute|:30, |Second|:0}, |Repeat| : 1 }で時間指定すると、毎時30分にハンドラを実行します。秒や時間指定も同じです。
Macをスリープしても指定した時間にハンドラが実行されます。スリープ中に指定した時間が過ぎた場合は、起きた時にすぐにハンドラを実行します。スリープ中に予定時間が過ぎたかどうかは上記ハンドラの引数で確認して下さい。
スリープから復帰時の動作はあまり検証していないので、なにか不具合があるかもしれません。
DoAtTimeの使用例
CancelDoAtTime
|CancelDoAtTime| : theSettingRecord
DoAtTimeで渡したレコードを渡すとそのDoAtTimeをキャンセルする
SendActionOn
clickMenuBarItemを実行するマウスイベントの種類
下記4種類あります。デフォルトはLeftMouseUpでマウスアップ時に実行します。
{ "LeftMouseUp", "LeftMouseDown", "LeftMouseDragged", "Periodic" }
HotKeyList
システム全体で有効なホットキー
登録するホットキーのリスト
{|HotKeyList|:{{|Name|:"RateUp", |KeyChar|:"up", |ModifierKeyList|:{"shift", "option"}, |Enable|:1 }}}
Nameがホットキーの名前。doHotKey + ホットキーの名前のハンドラがホットキーを押した時に実行されます。この場合、doHotKeyRateUp( theActiveAppRecord, theThisAppRecord )というハンドラが実行されます。
KeyCharはキーもしくはキーの名前。tab,space,up,down,left,right,delete,return,F1,F2...など一部特殊キーをテキストで指定できます。KeyCodeでキーコードで指定できます。
ModifierKeyListで修飾キーを指定します。command,option,shift,controlの種類あります。
Enableで有効、無効を指定できます。1で有効、0で無効になります。0はRemoveHotKeyNameListと同じような物です。スクリプト中にはとりあえず、設定を書いておき、オン、オフを切り替えたい場合に使用します。デフォルトは1です。
RemoveHotKeyNameList
ホットキーを解除するホットキーの名前のリスト
AppHotKeyList
アプリケーションのみで有効なホットキー。設定方法はHotKeyListとほぼ同じです。
登録するホットキーのリスト
{|HotKeyList|:{{|Name|:"RateUp", |KeyChar|:"up", |ModifierKeyList|:{"shift", "option"}, |Enable|:1 }}}
Nameがホットキーの名前。doAppHotKey + ホットキーの名前のハンドラがホットキーを押した時に実行されます。この場合、doAppHotKeyRateUp( theActiveAppRecord, theThisAppRecord )というハンドラが実行されます。
KeyCharはキーもしくはキーの名前。tab,up,down,left,right,delete,return,F1,F2...など一部特殊キーをテキストで指定できます。"W"の場合は小文字の"w"を指定します。大文字だとシフトキーが必要になります。
ModifierKeyListで修飾キーを指定します。command,option,shift,controlが種類あります。
Enableで有効、無効を指定できます。1で有効、0で無効になりす。0はRemoveAppHotKeyNameListと同じような物です。スクリプト中にはとりあえず、設定を書いておき、オン、オフを切り替えたい場合に使用します。デフォルトは1です。
ホットキーはメニューのショートカットキーとしてアプリケーションの登録されます。ちゃんと登録されているか確認したい場合は、アプリケーションの実行タイプを「通常」にしてメニューを見えるようにして、メニューを表示すると確認できます。Cmd + Cなど最初からあるものを上書きすることはできないので注意して下さい。
メニューのショートカットキーなのでテキスト入力中には修飾キーが無いホットキーは動作しないなどの制限があります。
サンプル
RemoveAppHotKeyNameList
ホットキーを解除するAppホットキーの名前のリスト
WebViewWindow
WebView付きのウインドウ。WebViewで表示できる物が表示できます。
WebViewWindowについてを見て下さい
WebViewWindowList
WebViewWindowのリスト。一度に複数のウインドウを作成したい場合に。
didFinishLoadForFrameDelay
WebViewの読み込み完了からdoDidFinishLoadForFrameが実行されるまでの遅延秒数。
JavaScriptを使っているサイトは読み込み完了直後はまだページが完成していない場合があります。
デフォルト値:0.5
AutoSaveAndRestoreWindowFrameByName
ウインドウ名でウインドウの位置を自動的に保存、新規作成時にウインドウの位置を保存した位置にします。
位置やサイズが指定してある場合は、そちらが適用されます。
ClearWebViewCache
1でWebViewのキャッシュをクリアする。
同じパス名で保存した画像を更新した場合、キャッシュをクリアしないと、キャッシュから表示されるので画像が更新されません。
FSEventFolderList
FSEventで調べるフォルダのリスト。再設定すると以前のフォルダは調べなくなります。空のリストを渡すと調べなくなります。
下記ハンドラが実行されます。theEventPathListは変更があったフォルダのリストです。サブフォルダで変更があるとサブフォルダのパスが入ります。どのファイルで変更があったかは自分で調べて下さい。
on doFSEvent(theEventPathList, theActiveAppRecord, theThisAppRecord)
サブフォルダの通知も来るので気をつけて下さい。ホームフォルダ等上の方のフォルダを指定すると、キャッシュ等で頻繁に変更があるので、常時ハンドラが実行されることになります。
NotificationPriority
Growlを指定するとGrowlで通知するようになる。
WebViewNavigationAction
doWebViewNavigationActionの結果
return {|WebViewNavigationAction|:{|URL|:theURL, |Action|:0}}
0を返すとWebView内でリンクを開かなくなる。Safariでリンクを開きたい場合等に。
VersionCheck
新しいバージョンのアプリケーションがあるかチェックする
return { |VersionCheck| : { |URL|:theVersionJSONURL, |Interval|: days * 7 } }
インターネット上に最新バージョンを記録したファイルを置いて、それとアプリケーションのバージョンを比較します。
新しいバージョンの有無はバージョン文字列の違いで判断します。数値の意味は理解してません。アプリケーションのバージョンが1.2、ネット上の最新バージョン情報が1.1でも新しいバージョンがあると判断されます(通常このようなことはないと思いますが)。
ウインドウは一定時間で自動的に閉じます。
使い方例
KanaEisuuKeyDown
1を返すと「英数」キーか「かな」キーを押している状態の時にキーを押した時に下記ハンドラが実行されるようになります
on doKanaEisuuKeyUp(theKeyInfoRecord, theActiveAppRecord, theThisAppRecord)
on doKanaEisuuKeyDown(theKeyInfoRecord, theActiveAppRecord, theThisAppRecord)
theKeyInfoRecordのキーはAppleScriptEditorHelperで確認してください。
キー入力を取得出来ますが、「英数」か「かな」キーを押している状態のキーのみスクリプト中で取得でき、通常そのキーを押しながら文字入力をしないのでMenuBarAppleScriptでキーロガーを作ることはできないと考えています。
KanaEisuuKeyDownSpaceIsNormalChar
通常KanaEisuuKeyDownではスペースは特殊文字としてlastCharが"space"となり、inputStringに含まれませんがこれを1にするとinputStringにスペース" "が含まれるようになります。
RequireRegistraionMenuItemList
{"MenuItemRegex1", "MenuItemRegex2"}
このタイトルのメニューアイテムは選択不可にしてRequireRegistraionMenuItemPrefixを追加する
RequireRegistraionMenuItemTagList
{10001, 10002}
このタグのメニューアイテムは選択不可にしてRequireRegistraionMenuItemPrefixを追加する
RequireRegistraionMenuItemPrefix
"[Locked] "
RequireRegistraionMenuItemListとRequireRegistraionMenuItemTagListのメニューアイテムに付ける文字列
RequireRegistraionMessageMenuItemList
{"---separatorItem", "Lockされたメニューアイテムを使用するには登録(有料)が必要です","登録ページを開く","---tag " & theOpenRegistURLTag }
未登録時にメニュー末尾に自動的に追加するメニューアイテムのリスト
RegisteredMessageMenuItemList
{"---separatorItem", "登録ありがとうございます", "---disable" }
登録済みの時にメニュー末尾に自動的に追加するメニューアイテムのリスト
ASBMExecLoop
return { |ASBMExecLoop| : {{theVal1, theVal2, theSleepSec}} }
return { |ASBMExecLoop| : {{1, 1, 1.4}} }
return { |ASBMExecLoop| : "stop" }
«event ASBMExec»{theVal1, theVal2}をスレッドを作成してループしてずっと実行する
配列なので複数の命令を実行させることも可能
"stop"を渡すとスレッドを終了して処理を終了する

WebViewWindowについて

WebView付きのウインドウを作成できます。

WebViewではいろいろ表示できるので、何かを表示したい時に使えると思います。

WebViewそのままなのでSafariにある機能がすべて使える訳ではありません。デフォルト設定で表示できるだけです。

クローズボタンを押して閉じると、YouTubeの再生が止まりました。|Visible|:0で隠した場合は止まりませんでした。

Yahooを表示
return {|WebViewWindow|:{|Name|:"Yahoo", |Visible|:1, |Width|:windowWidth, |Height|:windowHeight, |URL|:"http://www.yahoo.co.jp/"}}
いろいろ指定する例
return {|WebViewWindow|:{|HTML|:theHTML, |Name|:"YT", |Visible|:1, |Width|:windowWidth, |Height|:windowHeight, |Delete|:0, |AllowsScrolling|:0, |Title|:defaultTitle, |Activate|:1, |Alpha|:0.5, |Opaque|:0}}

WebViewWindowで設定する値のキー

Name
処理対象のウインドウの名前。名前が空文字の場合、ウインドウは作成されません。
ウインドウを作ったり、作らなかったりする場合は、常に、WebViewWindowを返して、Nameを、作らない時は""、作る時は"hoge"のようにするとちょっと楽かもしれません。
タイトルバーに表示するものはTitleで設定します。
Title
タイトルバーに表示するタイトル
Width
ウインドウの幅
screenListで現在のスクリーンの情報が得られるので、位置やサイズ指定をしたい場合に使って下さい
Height
ウインドウの高さ
X
ウインドウのX座標
値が"mouse"でカーソルの位置
Y
ウインドウのY座標
値が"mouse"でカーソルの位置
InitialWidth
FrameAutosaveName、AutoSaveAndRestoreWindowFrameByNameを使用する時のウインドウの初期幅を指定
初めてウインドウが作られる場合のみ、この値が使用されます。ユーザーがドラッグ等で位置、サイズを指定して、その値が保存された場合は、その値が使用されます。
InitialHeight
FrameAutosaveName、AutoSaveAndRestoreWindowFrameByNameを使用する時のウインドウの初期高さを指定
初めてウインドウが作られる場合のみ、この値が使用されます。ユーザーがドラッグ等で位置、サイズを指定して、その値が保存された場合は、その値が使用されます。
InitialX
FrameAutosaveName、AutoSaveAndRestoreWindowFrameByNameを使用する時のウインドウの初期X座標を指定
初めてウインドウが作られる場合のみ、この値が使用されます。ユーザーがドラッグ等で位置、サイズを指定して、その値が保存された場合は、その値が使用されます。
InitialY
FrameAutosaveName、AutoSaveAndRestoreWindowFrameByNameを使用する時のウインドウの初期Y座標を指定
初めてウインドウが作られる場合のみ、この値が使用されます。ユーザーがドラッグ等で位置、サイズを指定して、その値が保存された場合は、その値が使用されます。
MaxWidth
MaxHeight
ウインドウの最大の大きさ。
MinWidth
MinHeight
ウインドウの最小の大きさ。
AspectratioWidth
AspectratioHeight
ウインドウの縦横比。
ResizeIncrementとは同時に設定出来ません
ResizeIncrementWidth
ResizeIncrementHeight
ウインドウのリサイズ幅の増加数。
デフォルトは1
Aspectratioを設定すると1になります。
Delete
1ならウインドウを削除
URL
表示するURL。パスでもOK
HTML
表示するHTML
BaseURL
HTMLのBaseURL
JavaScript
指定したJavaScriptを実行する。HTMLやURLと同時に指定してもページの読み込みが完了していないので期待通りにならない場合があります。その場合はOnloadJavasScriptを使って下さい。
結果はハンドラJavaScriptResultで処理をします。
設定するイベント名は"JavaScriptResult"になります。
その場でJavaScriptを実行して返り値を取得したい場合は«event WebVJS__»を使います。
OnloadJavaScript
ページの読み込み完了時に実行するJavaScript
結果はハンドラJavaScriptResultで処理をします。
設定するイベント名は"JavaScriptResult"になります。
その場でJavaScriptを実行して返り値を取得したい場合は«event WebVJS__»を使います。
OnloadJavaScriptDelay
デフォルト:0.5
OnloadJavaScriptを読み込み完了から指定した秒数後に実行するようにする
JavaScriptを使っていろいろしているページは読み込み完了直後にはまたページが不完全な場合があります。その場合、ここで実行までの時間を調整して下さい。
JavaScriptHandler
"JavaScript"、"OnloadJavaScript"で実行するハンドラは通常"doJavaScriptResult"ですが、ここで指定すると指定した文字列を追加したハンドラを実行します。
"Hage"を設定すると"doJavaScriptResultHage"が実行されるようになります。
Visible
1で表示、0で隠す
Activate
ウインドウをアクティブにする。アプリケーションもアクティブになります。
StyleList
ウインドウのスタイルの属性のリスト。属性は下記値があります。
Titled : タイトルバーを付ける
Utility : タイトルバーが細いウインドウ
Borderless : タイトルバー無し
Closable : クローズボタン
Resizable : リサイズできるようにする
HUD : HUD
Default : Utility + Closable + Resizable + Titled
HasShadow
1で陰を付ける
Opaque
0を指定するとalphaで透明、半透明なウインドウにできる。
AlphaValue
ウインドウの透明度。1で不透明、0で透明
Opaqueで透明ウインドウにしておく必要がありますが、1以外を指定すると自動的にOpaqueが0になります。
IgnoresMouseEvents
1でクリックを無効。クリックはウインドウの下のアプリケーションに伝わります。
HidesOnDeactivate
アプリケーションがアクティブじゃなくなったらウインドウを隠す
デフォルトは0
AcceptsFirstMouse
通常ウインドウがアクティブじゃない時の最初のクリックはウインドウをアクティブにするだけだが、1を指定するとウインドウをアクティブにして、ウインドウ内のクリックも有効になる。
デフォルトは0
MenuBarAppleScriptではパレットのように使うウインドウが多いと思われるのでデフォルトは1です。
CanHide
0でウインドウを隠せなくなる
デフォルトは0
効果がない模様
DrawsBackground
0でWebViewの背景を描かなくなる
AllowsScrolling
0でスクロールバーを表示しない
FrameAutosaveName
この名前でウインドウ位置とサイズを自動的に保存
FrameUsingNameで同じ名前を指定すると位置とサイズをロードできる
AutoSaveAndRestoreWindowFrameByNameでウインドウ名で自動的に行うようにできる。
FrameUsingName
指定した名前で保存した位置とサイズをロードして設定する
Level
ウインドウの表示レベル
StatusWindowLevel : 最前面
FloatingWindowLevel : フローティングウインドウ
NormalWindowLevel : 通常
DesktopWindowLevel : デスクトップ
DesktopIconWindowLevel : デスクトップアイコン
LevelPlus
指定した数値をLevelに足します。
LevelをDesktopIconWindowLevelにして、LevelPlusに1を指定するとデスクトップアイコンの手前にウインドウが表示され、よくあるデスクトップアイコンを隠すウインドウを表示できます(未確認です)。
LoadsImagesAutomatically
0で画像を読み込まなくなる
ページを読み込んでJavaScriptでテキストを取得するだけの場合は画像やプラグインを切っておくと軽くなると思います。
設定はplistに保存されるので一度設定したらずっと有効になります(未確認)。
PlugInsEnabled
0でプラグインを読み込まなくなる
設定はplistに保存されるので一度設定したらずっと有効になります(未確認)。
JavaEnabled
0でJavaを読み込まなくなる
設定はplistに保存されるので一度設定したらずっと有効になります(未確認)。
AllowsAnimatedImages
0で停止
AllowsAnimatedImageLooping
0で停止
UserAgent
Safariの様に見せる場合は次のようにする
|UserAgent|:"Version/6.0 Safari/536.25"
SafeCookie
通常CookieはSafariと共有だが1を指定すると共有しなくなる。
また、アプリケーション終了時にCookieの保存をしない。
UserInfo
任意の値をウインドウに保存
«event WebVUtil» {theWindowName, "getUserInfo"}で取得

WebViewWindowで表示しているHTMLからAppleScriptのハンドラを実行する

mbas:HandlerName?key=value
の様なmbasから始まるURLを開いた時には、HandlerNameにdoURLを付けた
on doURLHandlerName(theFormRecord, theActiveAppRecord, theThisAppRecord)を実行します。theFormRecordは{|key|:{"value"}}のレコードになります。

formで上記URLを作る場合は
<form action='mbas:ChooseMovie' method=get>
の様にactionを設定すればOKです。

|rawURL| of theFormRecordにURLがそのまま入っています。

rawmbasから始まるURLを開いた場合は、on doRawURL(mbasURL, theActiveAppRecord, theThisAppRecord)が実行されます。

ハンドラをいっぱい作りたくない場合はこちらをつかってください。

JavaScriptからAppleScriptのハンドラを実行して結果を取得する

次のJavaScriptで

var result = window.MenuBarAppleScript.runHandler("ハンドラ名","渡す値");

var result = window.MenuBarAppleScript.runHandler("bc",e.value);


var result = "";
if( window.MenuBarAppleScript )
{
	result = window.MenuBarAppleScript.runHandler("bc", e.value);
}
else
{
	result = "ブラウザでテスト実行した時の仮の値";
}

次のハンドラが実行されます。結果はレコードのキー |Result| に入れて返します。

on doHandlerFromJavaScriptbc(theValue, theActiveAppRecord, theThisAppRecord)
	--	«event DebugLog» {"doHandlerFromJavaScriptbc"}
	set theResult to do shell script "echo " & quoted form of theValue & " | bc "
	set theResult to «event TextRegx» {"replace", "(\\d)(?=(\\d\\d\\d)+(?!\\d))", theResult, "$1,"}
	return {|Result|:theResult}
end doHandlerFromJavaScriptbc

JavaScriptからコンソールにログを出力する

DebugJavaScriptが1の場合、通常のブラウザで使える下記命令を使うとをコンソールにログを出力します。

console.log("hoge");

通常のイベント

通知以外のアプリケーションの動作のイベントです。登録したイベントのハンドラのみ実行されます。

例:

return {|EventList|:{"selectMenuItem","menuDidClose","clickMenuBarItem","doubleClickMenuBarItem"}}

init
起動直後に一度実行される
on doInit(theActiveAppRecord, theThisAppRecord)
run
doInitの実行直後に一度実行される
on doRun(theActiveAppRecord, theThisAppRecord)
runWithNoServiceNoOpenFileNoOpenURL
doRunの直後にService,OpenFile,OpenURLが実行されなかったら実行される
サービスで起動したのか、普通にダブルクリックで開いたのかで処理を分けたい場合に。
on doRunWithNoServiceNoOpenFileNoOpenURL(theActiveAppRecord, theThisAppRecord)
quit
アプリケーション終了時に実行される
on doQuit(theActiveAppRecord, theThisAppRecord)
LSUIElementとLSBackgroundOnlyのバックグラウンドで実行されるアプリケーションの場合、時間がかかる処理をすると途中でも強制終了します。正確な時間は調べてませんが1秒かかるとダメです。
reOpen
アプリケーションをFinderやDockから再度開いた
on doReOpen(theActiveAppRecord, theThisAppRecord)
selectMenuItem
メニューアイテムを選択した
on doSelectMenuItem(theTitle, theTag, theActiveAppRecord, theThisAppRecord)
on doSelectMenuItemHandlerSuffix(theTitle, theTag, theUserInfo, theActiveAppRecord, theThisAppRecord)
HandlerSuffixの有無で引数のtheUserInfoが違ってきますので注意して下さい。theUserInfoが必要な場合はHandlerSuffixを指定して下さい。
menuDidClose
メニューを閉じた
on doMenuDidClose(theActiveAppRecord, theThisAppRecord)
clickMenuBarItem
メニューバーアイコンをクリックした
SendActionOnでマウスを上げた時じゃなくて押した時に実行するようにできます。
on doClickMenuBarItem(theActiveAppRecord, theThisAppRecord)
doubleClickMenuBarItem
メニューバーアイコンをダブルクリックした。
メニューバーアイテムのアイコンやテキストを連打しているとこれになるので、連打されることを考慮するならここでもclickMenuBarItemと同じ処理をしておいた方がいい場合があります。
on doDoubleClickMenuBarItem(theActiveAppRecord, theThisAppRecord)
rightClickMenuBarItem
メニューバーアイコンを右クリックした。正確にはSendActionOnの設定に関わらず押した時に実行されます。
下記のようにすると右クリックでメニューを表示できます。
on doRightClickMenuBarItem(theActiveAppRecord, theThisAppRecord)
	return {|PopUpMenuItemList|:theMenuItemList}
end doRightClickMenuBarItem
button3ClickMenuBarItem
メニューバーアイコンをミドルクリックした。正確にはSendActionOnの設定に関わらず押した時に実行されます。
ボタン4以降もあります。3をボタンの数字にして下さい。
on doButton3ClickMenuBarItem(theActiveAppRecord, theThisAppRecord)
scrollWheelMenuBarItemこの機能は1.3.1で無効になっています。
メニューバーアイコン上でスクロールイベントが起きた。マウスホイールを回した、二本指でトラックバッドをスワイプした時。
on doScrollWheelMenuBarItem(theDeltaX, theDeltaY, theActiveAppRecord, theThisAppRecord)
deltaが1以上の時のみ実行されます。
トラックパッドの場合、ハンドラが何度も実行されるのでDoAfterSecで遅延実行させてスクロールが終わったと思われるときに一回だけ実行するようにしたほうがいいと思います。下記リンク先のサンプルを参考にして下さい。
scrollWheelMenuBarItemの使用例
hotKeyHotKeyName
ホットキーを押した。
on doHotKeyHOTKEYNAME(theActiveAppRecord, theThisAppRecord)
HOTKEYNAMEは登録時に指定したホットキーの名前です。
windowWillClose
ウインドウを閉じる直前
on doClickMenuBarItem( theWindowName, theActiveAppRecord, theThisAppRecord)
windowDidMove
ウインドウを移動した
on doClickMenuBarItem( theWindowName, theActiveAppRecord, theThisAppRecord)
windowDidResize
ウインドウをリサイズした
on doClickMenuBarItem( theWindowName, theActiveAppRecord, theThisAppRecord)
OpenURL
URLを開いた
Safariで登録したスキームのURLを開かせることにより、SafariとMenuBarAppleScriptをリンクできたりします。
on doOpenURL(theURL, theActiveAppRecord, theThisAppRecord)
OpenFile
ファイルを開いた
on doOpenFile(thePathList, theActiveAppRecord, theThisAppRecord)
FileService
ファイルを選択してサービスメニューを実行した
on doFileService(thePathList, theActiveAppRecord, theThisAppRecord)
TextService
テキストを選択してサービスを実行した
on doTextService(theText, theActiveAppRecord, theThisAppRecord)
didFinishLoadForFrame
on doDidFinishLoadForFrame(theWindowName, theActiveAppRecord, theThisAppRecord)
WebViewのロードが完了した。フレームがある場合は複数回実行されます。
JavaScriptResult
on doJavaScriptResult(theWindowName, theJavaScriptResult, theActiveAppRecord, theThisAppRecord)
OnLoadJavaScript、JavaScriptで実行したJavaScriptの結果を受け取る
WebViewNavigationAction
on doWebViewNavigationAction(theURL, theActiveAppRecord, theThisAppRecord)
WebViewのリンクをクリックした時に実行される。リンクをWebViewで開かずにSafariで開くようにできる。
return {|WebViewNavigationAction|:{|URL|:theURL, |Action|:0}}
上記のようなレコードで返す。Actionで0を返すとWebView内でリンクを開かなくなる。Safariでリンクを開きたい場合等に。
NewWindowURL
on doNewWindowURL(theURL, theActiveAppRecord, theThisAppRecord)
JavaScriptやtargetを指定したリンクなどで新規ウインドウを表示する場合に実行される。
return {|NewWindowURL|:{|URL|:theURL, |Action|:0}}
上記のレコードを返す。Actionで0を返すと、URLを現在のWebViewで表示しない。1を返すと現在のWebViewでURLを表示する。
ハンドラが無いなど上記のレコードを返さない場合は1と同じで現在のWebViewでURLを表示する。
リンクをブラウザで開きたい場合は0を返して、次のスクリプトを実行する
do shell script "open " & quoted form of theURL
FileURL
WebViewでfile:のURLを開いた時に次のハンドラを実行する
on doFileURL(theURL,theActiveAppRecord, theThisAppRecord)

アプリケーションの情報 - theActiveAppRecord / theThisAppRecord / theUserInfoがAppの場合

bundleIdentifierなど値が無いキーもあります。nameが使いやすいかなと思います。

name
拡張子無しのファイル名
localizedName
ローカライズされた名前
無ければname
fileName
ファイル名
bundleIdentifier
bundleIdentifier
processIdentifier
processIdentifier
path
Unix Path
mouseX
mouseY
カーソルの座標
theActiveAppRecordの値は現在値、theThisAppRecordの値はアプリケーション起動時の値になります。
screenList
スクリーンの情報のリスト
例:screenList:{{x:0, height:900, y:0, visibleWidth:1436, width:1440, visibleY:22, visibleX:0, visibleHeight:878}, {x:262, height:1200, y:900, visibleWidth:1920, width:1920, visibleY:900, visibleX:262, visibleHeight:1200}}
visibleと付くのがメニューバーやドックを除いたサイズです。
theActiveAppRecordの値は現在値、theThisAppRecordの値はアプリケーション起動時の値になります。
modifierKeyList
押している修飾キーとボタンのリスト
control, command, shift, option, fn, caps, eisuu, kana
mouseButtonLeft, mouseButtonRight, mouseButtonCenter, mouseButton4, mouseButton5, mouseButton6, mouseButton7, mouseButton8
theActiveAppRecordの値は現在値、theThisAppRecordの値はアプリケーション起動時の値になります。

theThisAppRecordにあるキー

パスなどは起動時の値で起動後に動かしても値は変わりません。

resourcesFolderPath
MenuBarAppleScript内部のリソースフォルダのフルパス
resourcesFolderURL
MenuBarAppleScript内部のリソースフォルダのURL
リソースにあるHTMLなどをWebViewに表示させる場合はPathよりURLで指定するとURLに"#hoge"などを付けることができる。
scriptsFolderPath
MenuBarAppleScript内部のスクリプトフォルダのフルパス
URLSchemeList
アプリケーションに設定されているURLスキームのリスト
processorCount
CPUのコア数(スレッド数)
疑似スレッドで実行するスレッドを決める参考等に
physicalMemory
物理メモリサイズ
単位はバイト
menuBarItemVisible
MenuBarItemを表示しているなら1
mainWindowName
main window name
keyWindowName
key window name
アクティブなウインドウ名です
allWebViewWindowRecord
ウインドウの位置、サイズが入ったレーコード
キーはウインドウ名で、値はレコードで、そのレコードのキーはx,y,width,height,name,visibleです。
allWebViewWindowNameList
ウインドウの名前のレコード

通知

NSWorkspaceとNSDistributedNotificationCenterの通知を受けることができます。

通知のハンドラの引数

(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord)になります。

theNotificationName
通知の名前
NSWorkspaceDidLaunchApplicationNotificationやcom.apple.iTunes.playerInfo
theObject
通知に渡されたobject
値の種類が文字列か数値以外の場合、値は空になります。
theUserInfo
通知に渡されたuserInfo
レコードになります
値の種類が文字列か数値以外の場合、レコードから取り除きます。
theActiveAppRecord
アクティブなアプリケーションの情報
theThisAppRecord
実行しているMenuBarAppleScriptアプリケーションの情報

ハンドラ名の例

NSWorkspaceの通知

NSWorkspaceの通知を受けて処理をすることができます。

たくさんあるのですが、一部を紹介します。

使いそうな通知

NSWorkspaceDidLaunchApplicationNotification
アプリケーションが起動した
theUserInfoはアプリケーションの情報
NSWorkspaceDidTerminateApplicationNotification
アプリケーションが終了した
theUserInfoはアプリケーションの情報
NSWorkspaceDidActivateApplicationNotification
アプリケーションがアクティブになった
theUserInfoはアプリケーションの情報
NSWorkspaceDidDeactivateApplicationNotification
アプリケーションがアクティブじゃなくなった
theUserInfoはアプリケーションの情報
NSWorkspaceDidWakeNotification
スリープから復帰した
NSWorkspaceWillSleepNotification
もうすぐスリープする

上記以外の通知は下記URLの「Notifications」の所を見て下さい。

下の方に「NSWorkspaceDidLaunchApplicationNotification」等がありますが、これが通知名です。

NSDistributedNotificationCenterの通知

同梱の「NSDistributedNotificationCenterTest.app」でシステムで飛び交ってる通知を表示できますので、これで面白いことができる通知が無いか調べることができます。

{}で囲まれているのがレコードで()で囲まれているのがリストです。

com.apple.securityagent.InputPrefsChangedのAppleSelectedInputSourcesの"Input Mode"を取得するには次のようになります。

set AppleSelectedInputSourcesRecord to item 1 of AppleSelectedInputSources of theUserInfo
set theInputMode to |Input Mode| of AppleSelectedInputSourcesRecord

AXNotificationの通知

この通知は上の二つの通知とは違って、下記設定が必要です。

「ユニバーサルアクセス」環境設定で「補助装置にアクセスできるようにする」にチェックを入れます。

現在のバージョンでは設定した通知を削除することはできません。アプリケーションを終了したりUI Elementが無くなると指定した通知は無くなるのかは分かりませんが、実行されなくなり、影響は無くなります。

通知の種類

下記リンクを先に書いてあります。

kAXWindowCreatedNotificationの場合、下記のように書いてありますが、CFSTR内のAXWindowCreatedが通知で指定する値になりますので注意して下さい。

#define kAXWindowCreatedNotification CFSTR("AXWindowCreated")

AXNotificationではどのアプリケーションのどのElementを調べるか指定する必要があります。*ですべてのアプリケーションやElementを対象にできますが、通知の種類によっては頻繁に実行されるものがありますので注意して下さい。

指定方法は下記のようになります。指定する値がリストなので括弧が多くなりますので注意して下さい。

{|AXNotificationList|:{{|AppName|:"Finder", |NotificationList|:{{|name|:"AXSelectedRowsChanged", target:"*"}, {|name|:"AXSelectedChildrenChanged", target:"*"}, {|name|:"AXValueChanged", targetList:{"AXWindows", "", "AXRole", "AXSplitGroup", "AXRole", "AXScrollArea", "AXOrientation", "AXVerticalOrientation"}}}}}}

AppName:対象のアプリケーション名。英語名で指定。*ですべて。"AppleScrit エディタ"の場合、"AppleScript Editor"となります。

Name:通知名

Target:対象のElement。*ですべて指定可能。

TargetList:対象のElementを指定する属性と値のリスト。上から順番に属性と値で指定して行きます。値は正規表現で指定可能です。AXApplicationから指定します。最初の属性を"CreatedWindow"にすると(値は"")作成されたウインドウを対象にElementを探すようになります。通知で実行されるハンドラ内で"AXEL"にすると(値は"")、通知の対象になったUI Elementが対象になります。«event UIElSetE»で指定したUI Elementを対象とする"UIEl"もあります。

通知の種類によっては*ですべてのElementを対象にすると、対象が多くて通知が来る頻度が非常に高くなる場合がありますので注意して下さい。

実行されるハンドラ

on doAXValueChanged(theAXAppRecord, theActiveAppRecord, theThisAppRecord)

SCNotificationの通知

下記リンク先に書いてあるSystemConfigurationの機能を使ってネットワーク設定などに変化があったときにハンドラを実行できます。

正式にはSCNotificationとは言いませんが、MenuBarAppleScriptではSCNotificationとして設定します。

設定する通知名はSystemConfiguration.framework でネットワークの情報を得る | ishwt::trackingに書いてある方法で調べられます。

例:State:/Network/Global/IPv4

値が変わった時に実行されるハンドラは記号を_に置換した下記になります。

on doState__Network_Global_IPv4(theValue, theActiveAppRecord, theThisAppRecord)

変化があった時に実行されますが、アプリケーション起動直後に現在値を知っておきたい場合は、{ |RunSCNotificationHandler|:1 }をSCNotificationListの設定と同時に返しておくと、上記ハンドラに現在値が渡されて実行されます。

例:ネットワークのオンオフをチェック

注意:Macがルータまで繋がっているか確認できますが、ルータがインターネットに繋がっているかどうかはわかりません。

doInitで次のレコードを返します。

{ |SCNotificationList|:{"State:/Network/Global/IPv4"}, |RunSCNotificationHandler|:1 }

次のハンドラが実行されるのでtheValueをチェックします。ネットワークに接続していない場合はtheValueがmissing valueになります。

on doState__Network_Global_IPv4(theValue, theActiveAppRecord, theThisAppRecord)
	-- ネットに繋がっているかチェックして記憶
	-- «event DebugLog» {"doState__Network_Global_IPv4", theValue}
	if theValue is not missing value then
		set theNetworkStatus to true -- 繋がっている
	else
		set theNetworkStatus to false -- 繋がっていない
	end if
end doState__Network_Global_IPv4

MenuBarAppleScriptのコマンド

あったらいいな、と思ったのをいくつか入れてみました。命令はAppleEventのコードで指定します。

一般

«event MBASHndl» theRecord
渡したレコードをハンドラから返したように処理をする
«event MBASRunH» {|Handler|:"MyHandlerName", |Key|:theValue}
MenuBarAppleScriptのハンドラを実行。上の命令の場合、doHandler + MyHandlerNameの下記ハンドラが実行されます。
on doHandlerMyHandlerName(theRecord, theActiveAppRecord, theThisAppRecord)
theRecordは命令で渡したレコードです。
他のアプリケーションから命令をさせたい場合に使えます。
«event DebugLog» theValue_Text_Number_List_Record
コンソールに値を出力
return {|DebugLog|:0}のように0を設定すると出力しなくなります。
«event InfoAApp»
theActiveAppRecordを返す
疑似スレッドで取得したい場合等に
«event InfoTApp»
theThisAppRecordを返す
«event MBASHndl»で処理をした後の値を取得したい場合や、疑似スレッドで取得したい場合等に
«event PlaySnd_» { |Sound| : theSoundName }
theSoundNameのサウンドを再生する。
名前を指定するとシステムサウンド、パスを指定するとそのパスのサウンドファイルになります。
同じサウンドを再生中に再度再生させた場合は再生中のものは停止して、新しく最初から再生します。
|Loops| : 1でループ再生
|Volume| : 0〜1.0で音量指定
|CurrentTime| : 再生位置を秒数で指定
|Stop| : 1で再生を停止する
|Command| : "Pause"/"Resume"/"Play"/"Stop"
Pauseで一時停止して、Resumeで再生開始。指定しなかったらPlay。
|Release| : 1で再生終了時にサウンドをメモリから解放する
«event ASBMExec»{theVal1, theVal2}
AppleSmartBatteryManagerに命令を送ります
詳しくは下記ページを読んで、実行にあたっては自己責任で最新の注意を持って行って下さい
AutoChargeInhibit - MacBook Pro 15 early 2011のバッテリーの充電をソフトウェア制御でオン・オフする
«event ChckRegi»{theLicenseName, theLicenseKey}
«event ChckRegi»
cocoafobで作成したライセンスキーが正しいかチェックして正しければ1を返します。間違っている場合は0を返します。
キー(pubkey.pem)は名前を"LicensePubKey.pem"として"MenuBarAppleScript.app/Contents/Resources/"フォルダに入れて下さい。キーはここに書いてあるコマンドを3つ実行すると作ることができます:cocoafob : generating-keys
MenuBarAppleScriptで使うファイル名で作る場合は次のようになります
$ openssl dsaparam -out dsaparam.pem 512; openssl gendsa -out LicensePrivKey.pem dsaparam.pem; openssl dsa -in LicensePrivKey.pem -pubout -out LicensePubKey.pem
theLicenseNameはチェック時に先頭にアプリケーションのLocalizedNameかBundleIdentifier、複数のアプリケーションで共通の場合に使用する"master"を付加した値を使用します。逆に言えばアプリケーションのLocalizedNameかBundleIdentifierを偽装した場合、そのアプリケーションを同じLicensePubKey.pemを使った別のアプリケーションのtheLicenseNameとtheLicenseKeyで登録できることになります。対策としては、theThisAppRecordのlocalizedNamebundleIdentifierをチェックして、変わっていたら«event ChckRegi»は実行しない、アプリケーションを終了する、などが考えられます。
上記仕様はtheLicenseName、theLicenseKeyを初期設定ファイルにそのまま保存し隠さない状態でそれなりの対策が出来る方法として採用しました。
MenuBarAppleScriptで、theLicenseNameがme@example.comの場合、次のどれかのtheLicenseNameでキーを作成します。
MenuBarAppleScript,me@example.com
com.yourcompany.MenuBarAppleScript.MenuBarAppleScript,me@example.com
master,me@example.com
license_generator.phpのmake_lincese$stringDataは上記値になるようにしておいてください。
例:$stringData = $product_code.",".$name;
値を指定しなくて«event ChckRegi»を実行した場合、前回チェックした時の名前とキーでチェックして値を返します。登録成功時に自動的に名前とキーを保存します。保存場所は辞書ではないのでスクリプトからは操作できません。
想定している使い方としてはユーザー登録の時だけ名前とキーを指定して実行、登録済みか未登録かで処理を分ける時は値を指定しなくて実行、となっています。
メニューアイテムを自動的に選択可能、不可にする場合はRequireRegistraionMenuItemListなどを最初に設定すると自動的に行うことができます。
登録、未登録時でメニューアイテムの表示、非表示を切り替えたい場合は、メニューアイテムに"---hide registered"か"---hide notregistered"を追加してください。
MenuBarAppleScriptにサンプルコードが入っているので参考にして下さい。
MenuBarAppleScript登録サンプルメールアドレス:me@example.com
MenuBarAppleScript登録サンプルライセンスキー:GAWQE-FA2GB-UKA4Q-GUWGT-D39QH-2EEGN-KHUAH-FSMAC-CUAJT-A6M6D-ZKZNH-7CM7J-G6QFW-NHQJM-RWU5Z-A
アクティベートするサンプルリンク:Click and Activate MenuBarAppleScript

WebView関係

«event WebVJS__» {theWindowName, "location.href"}
JavaScriptを実行して結果を返す
結果をその場で取得したい場合はこれを使います。ただし、ウインドウ作成直後にすぐ実行するとページ読み込みが完了してい場合がありますので注意して下さい。
«event WebVFind» {theWindowName, theText}
theTextを検索
«event SW2PsPDF» {theSavePath, "screen", "printbackgrounds", theWindowName}
«event SW2PsPDF» {"mbas:theName", "screen", "printbackgrounds", theWindowName}
theWindowNameのウインドウをpdfやpngで保存する。
{"保存するパス", "media", "printbackgrounds", theWindowName, "Max Width", "Max Height 倍率"}
-- "保存するパス" -- 保存するpdfのパス。ファイルの拡張子をjpg、pngにすると画像で保存することも可能。"mbas:"から始まる文字列でMenuBarAppleScript内部に保存して、その文字列でMenuBarItemImageやMenuBarItemAlternateImage、Menu Itemに画像を指定できます。
-- "media" -- 適用するCSSのmedia。空文字で変更しない。通常"screen"。"window"を指定するとウインドウをキャプチャした画像を保存します。ウインドウのタイトルバーなどもキャプチャされます。pdfでは保存出来ません。
-- "printbackgrounds" -- "printbackgrounds"で背景を印刷する。それ以外で印刷しない
-- theWindowName -- 保存するウインドウ名。
-- "Max Width" -- 画像にするエリアの最大幅。未指定で全体。文字列で指定するのに注意
-- "Max Height 倍率" -- 画像にするエリアの高さの横幅に対する倍率。未指定で全体。"1"にすると正方形になります。文字列で指定するのに注意
-- 後ろの設定はオプションで省略可能です
例:HTMLで作成した画像をメニューバーアイコンに設定する
例:set theResult to «event SW2PsPDF» {theSavePath, "screen", "printbackgrounds", theWindowName}
下記のように保存するRectを指定することができます。
«event SW2PsPDF» {theSavePath, "screen", "printbackgrounds", |keyWindowName| of theThisAppRecord, "{{106, 11}, {400, 400}}"}
{{x,y}, {width,height}}
SafariWebView2Pdf - SafariのアクティブなタブをPDFで保存するSIMBLプラグインのWebViewを画像で保存するコードを移植したので、同じようにして画像で保存できます。SafariWebView2Pdfとの違いは"URL"にウインドウのNameを指定するところであとは同じです。
注意点&FAQ:"printbackgrounds"を指定しないと"background-color"などが表示されません!。divなどに背景色を付けて作ったのが真っ白な場合はこれです。

WebViewウインドウ関係:WebVUtil

«event WebVUtil» {theWindowName, "doJavaScript", theScript }
JavaScriptを実行
«event WebVUtil» {theWindowName, "isLoading" }
読込中なら1
«event WebVUtil» {theWindowName, "stopLoading" }
読み込み停止
«event WebVUtil» {theWindowName, "reload" }
リロード
«event WebVUtil» {theWindowName, "findText", theText }
テキスト検索
«event WebVUtil» {missing value, "clearSafeCookie"}}
SafeCookieモード時のCookieを削除。
全て削除します。ウインドウごとに個別に削除はできません。
«event WebVUtil» {theWindowName, "setUserInfo", hoge}
ウインドウに任意の値を保存
«event WebVUtil» {theWindowName, "getUserInfo"}
setUserInfoで設定した値を取得

Unixコマンド関係

«event Cmd_Run_» {|CommandPath|:"/bin/ls", |ArgvList|:{"-la"}, |Handler|:"LS", |Name|:"LS" }
コマンドを非同期で実行。
コマンドが終了したら名前が doCommandResult + Handler のハンドラに結果を渡して実行します。
on doCommandResultLS(theOutputText, theErrorText, theTerminationStatus, theCommandRecord, theActiveAppRecord, theThisAppRecord)
値はArgvListに一つずつ書きます。文字列を""で囲む必要はありません。
一つのコマンドであってシェルスクリプトではありません。
コマンドの出力はテキストのみで、文字コードはUTF-8の必要があります。
«event Cmd_Run_» {|CommandPath|:"/usr/bin/tw", |ArgvList|:{"--stream:filter=" & theWord & ""}, |Handler|:"GetLiveTwitter", |Interval|:3.0, |OutputType|:"Standard", |Word|:theWord, |Index|:theTDIndex, |WindowName|:"RealTimeWindow", |Activate|:0, |TryCount|:0}
|Interval|を付けるとコマンドを非同期で実行。
コマンドを出力をInterval間隔で取りに行き上と同じハンドラを実行します。取りに行った時に出力が無ければ出力されるまで待ちますのでハンドラはInterval間隔で実行されるとは限りません。
取りに行く出力の種類はOutputTypeでStandardかErrorを指定し、指定した値のみハンドラの引数に渡されます。
curlやffmpegなど時間がかかるコマンドの進行状況等を表示する場合に使えます。
コマンドが終了しているか実行しているかはtheTerminationStatusで分かります。実行中の場合missing valueになり、終了している場合は実行したコマンドのTerminationStatusになります。
上の例ではWord、TryCountなどコマンドの実行に必須ではない値がありますが、結果を取得したハンドラで参考にしたい値がある場合は、このように自由にレコードに含めることができます。theCommandRecordは«event Cmd_Run_»に渡したレコードそのままなので、値を取得することができます。
«event Cmd_Quit» theCommandRecord
«event Cmd_Quit» {|Name|:theName }
コマンドを強制終了
Nameか、コマンドに渡したレコード全体で指定します。NameがNameが優先します。

通知関係(GrowlとUserNotification)

Growlと10.8の通知(UserNotification)に同じスクリプトの命令で通知を出すことができます。デフォルトでは、10.8で実行していてUserNotificationが使えるならUserNotificationを使い、10.6や10.7など使えない場合はGrowlで通知を出します。

NotificationPriorityで画像を表示したい場合等に常にGrowlで通知を出すようにもできます。

命令

«event PostNoti» {|Title|:theTitle, |SubTitle|:theSubTitle, |InformativeText|:theInformativeText, |ImagePriority|:"Image", |Icon|:theIcon, |Image|:theArtworkURL, |LaunchApp|:"iTunes", |Handler|:"Click", |SoundName|:"", |ActionButtonTitle|:"iTunes", |OtherButtonTitle|:"Close"}

DistributedNotificationに通知

DistributedNotificationを受ける側でなく通知をする命令です。

これで通知したものもNSDistributedNotificationCenterの通知で受けられるのでMenuBarAppleScriptのアプリケーション同士で連携したい場合に使用したりできると思います。

命令

«event PostDNti» { "Notification Name" , theObject, theUserInfoRecord }
theObject, theUserInfoRecordは省略可能です
theUserInfoはレコードで指定します
ダウンロード完了を通知する例:
«event PostDNti» { "com.apple.DownloadFileFinished" , "/Users/hoge/Downloads/MenuBarAppleScript1.4.5.zip" }
«event PostDNti» {"com.yourcompany.YoruNoQuake", "", {|url|:"http://www.yahoo.co.jp"}}

指定するレーコードのキー

Title
対象の通知:UserNotification、Growl
通知のタイトルです。
SubTitle
対象の通知:UserNotification、(Growl)
通知のサブタイトルです。
Growlにはサブタイトルは無いのでDescriptionに表示されます。
InformativeText
対象の通知:UserNotification、(Growl)
通知のInformativeTextです。
Growlにはサブタイトルは無いのでDescriptionに表示されます。SubTitleも指定されている場合は改行を挟んで繋ぎます。
Description
対象の通知:Growl、(UserNotification)
Descriptionです。UserNotificationにはDescriptionは無いのでInformativeTextに表示されます。
SoundName
対象の通知:UserNotification
サウンド名
""でサウンド無し
ActionButtonTitle
対象の通知:UserNotification
ActionButtonTitle
OtherButtonTitle
対象の通知:UserNotification
OtherButtonTitle
NotificationNameList
対象の通知:Growl
Growlで使用する全通知の名前のリスト
デフォルトでは{ "Message" }になります。
通知の種類ごとにスタイルや表示設定を変えたい場合に使用します。通知が1種類の場合や細かい設定が必要無い場合はデフォルトで大丈夫です。
この設定は一番最初にGrowlの通知を表示するときのみ使用されます。2回目以降に値を変えても無効です。
NotificationName
対象の通知:Growl
Growlで使用する通知の名前。
未指定の場合、"Message"になります。
指定する値は、NotificationNameListで設定した値になっている必要があります。なっていない場合は通知が表示されません。
Growlでは通知の名前ごとに設定を変えられます。
Image
対象の通知:Growl
Growlで表示する画像のパス or URL
Icon
対象の通知:Growl
Growlで表示する画像をアイコンにする場合のアイコンのファイルパスやアプリケーション名
ImagePriority
対象の通知:Growl
ImageとIconの両方を指定した時にどちらを表示するか
ImageでImage、IconでIconを表示する
Identifier
対象の通知:Growl
Growlの通知のIdentifier
同じIdentifierの通知は二つ同時に表示されません。すでに表示しているものがあればそこに新しい通知が表示されます。
Sticky
対象の通知:Growl
1でGrowlを通知を表示したままにする
LaunchApp
対象の通知:UserNotification、Growl
通知をクリックやActionButtonを押した時に下記動作をする
指定したアプリケーションを起動する。
OpenURL
対象の通知:UserNotification、Growl
通知をクリックやActionButtonを押した時に下記動作をする
指定したURLを開く。
OpenFile
対象の通知:UserNotification、Growl
通知をクリックやActionButtonを押した時に下記動作をする
指定したファイルを開く。
SelectFile
対象の通知:UserNotification、Growl
通知をクリックやActionButtonを押した時に下記動作をする
指定したファイルをFinderで選択する。
ActivateApp
対象の通知:UserNotification、Growl
通知をクリックやActionButtonを押した時に下記動作をする
指定したアプリケーションをアクティブにする。アプリケーションが起動していなければ何もしない。
Spotlight
対象の通知:UserNotification、Growl
通知をクリックやActionButtonを押した時に下記動作をする
Finderでスポットライト検索ウインドウを表示する。
Finderはアクティブにならないので、アティブにしたいならActivateAppを併用してください。
Handler
対象の通知:UserNotification、Growl
指定した値がHogeの場合、下記ハンドラを実行する。
my doNotificationHoge(theRecord, theActiveAppRecord, theThisAppRecord)
を実行する
theRecordは«event PostNoti»で渡したレコード。処理用に独自の値を追加しておいてもOK。ただし、UserNotificationではレコード全体でデータサイズが1KByte以下になるようにするのがお勧めらしいです。
PostNotificationType
この通知をUserNotification、Growlどちらで表示するか個別に指定します
UserNotificationでUserNotification通知、GrowlでGrowlで通知。

ウインドウ関係

«event Win_Visi» theWindowName
指定した名前のウインドウが表示されていたら1。表示されていない、存在しなければ0
«event Win_Hide»
«event Win_Hide» theWindowName
指定したウインドウもしくはすべてのウインドウを隠す
«event Win_DelA»
すべてのウインドウを削除
«event Win_Show»
«event Win_Show» theWindowName
«event Win_Show» theAllWebViewWindowRecord
指定したウインドウもしくはすべてのウインドウを表示する
«event Win_Show» theAllWebViewWindowRecord
WebViewウインドウをtheAllWebViewWindowRecordのvisibleが1なら表示する
アプリケーション切り替え時にウインドウを一時的に隠す場合、|allWebViewWindowRecord| of theThisAppRecordのレコードを保存しておくと、«event Win_Hide»で隠して、«event Win_Show» theAllWebViewWindowRecordで戻せます。

イベント関係

«event PostKeyE» {|app|:theAppNameOrBundleIdentifier, |keyChar|:"v", |modifierkeyList|:{"command"}}
指定したアプリケーションにキーイベントを送る
指定したアプリケーションがアクティブじゃなくても指定したアプリケーションにキーイベントを送れます。
重要:10.7以降のサンドボックス対応アプリケーションでは指定したアプリケーションに直接キーイベントを送れないので指定したアプリケーションをアクティブにして、システムに対してキーイベントを送るようになっています。システムに対してキーイベントを送ると通常アクティブなアプリケーションがキーイベントを処理します。これによって、バックグラウンドのアプリケーションを操作することができなくなっています。
«event PostSKey» {|key|:"SOUND_UP", |option|:"down", |shift|:"down" }
指定したアプリケーションに特殊キーイベントを送る
pressSpecialKey - 特殊キーを押すコマンドラインアプリケーションをそのまま組み込んでいます
例(元):pressSpecialKey -key sound_up -option down -shift down
例(MBAS):«event PostSKey» {|key|:"sound_up", |option|:"down", |shift|:"down" }
«event PostMove» { theX, theY }
x,yにマウスカーソルを移動
«event PostClck» { |Button| : "left", |X| : theX, |Y| : theY, |clickCount| : 1 }
クリックする

UI Element関係

«event UIElSetE» {"AppleScript Editor", {"Attr", "AXFocusedUIElement"}}
«event UIElSetE» {"AppleScript Editor", {"Attr", "AXFocusedUIElement", "Attr1", "Value1", "Attr2", "Value2" }}
«event UIElSetE» {"AppleScript Editor", {"Attr", "AXFocusedUIElement"}, "SaveName" }
«event UIElSetE» {"AppleScript Editor", { 100, 80 } } -- 座標(x,y)で調べる(指定したアプリケーションのみ対象)
«event UIElSetE» { missing value , { 100, 80 } } -- 座標(x,y)で調べる(すべてのアプリケーションが対象)
«event UIElGetV»«event UIElSetV»の処理対象のUI Elementを指定
値は"属性", "値" のペアを並べて書きます。対象のUI Elementの子(AXChildren)を探していきます。一番最初はAXApplicationが対象になっています。
値は文字列です。数値も文字列になります。
"値"は正規表現で書きます。部分マッチするので文字列と完全一致する場合には"^ねこ$"にします。正規表現のメタ文字も考慮して安全に書くなら"^\\Qねこ\\E$"にします。
"属性1 属性2"のように属性を半角スペースで区切って複数書くことができます。取得する値も"値1 値2"と半角スペースで区切ったものになります。
返り値は見つかったUI Elementの数です。ただし二つ以上見つかっても処理対象になるのは最初の一つです。
以下は特殊な属性値("Attr")です。
UIEl : UIElを対象とする。最初に指定可能
AXEl : AXElを対象とする。最初に指定可能
Attr : 属性を取得する。"Attr", "AXParent"で親を取得できます。
FindSelf : 通常は対象のUI Elementの子を調べますがこれを指定すると次に指定した属性と値の比較を現在のUI Elementと行います。"Attr"でUI Elementを取得して、その子ではなくそのUI Elementから探す場合に。
Index : 指定したindexの子を取得する
AnyRole : 指定したRoleの子調べて、AnyRoleの次に指定した属性と値のUI Elementが無ければ、再度AnyRoleに戻り子を探す。探しているUI ElementがどのAXScrollAreaやAXSplitGroupに入っているかわからない場合にこれを使うと探すことができます。
AnyRoleAll : 指定した子を全て調べて見つかったUI Elementを返します。AnyRoleは何か見つかった段階で終了します。
PerformAction : AXPressなどを実行できる。Setする命令だけどここに命令を追加したら楽だったので。対象のUI Elementが複数ある場合はすべてのUI Elementで命令を実行する。
上記キーで値がないものは""を指定して下さい。
実際の使い方は«event UIElSetE»のレシピ«event UIElSetE»でGUI操作ハンドラを見て下さい。
互換性のために、一番最初に指定する属性と値は値を""にすると属性値を取得します。{"Attr", "AXFocusedUIElement" }{"AXFocusedUIElement", "" }は同じになります。古いスクリプトでは後者のスクリプトがある場合がありますが、前者の"Attr"を使う方を推奨します。
無限ループ対策として数百回子を調べると調べるのを終了します。
値を2つの数値x,yを指定するとスクリーン上のx,y座標にあるUI Elementを対象とします。その際、アプリケーション名を指定するとそのアプリケーションのみ調べます。この時、アプリケーションが他のウインドウなどに隠れていても調べることができます。これは便利だったり不便だったりするので注意して下さい。アプリケーション名をmissing valueにすると座標にあるUI Elementをアプリケーションを限定せず取得します。
set {theRole, theVisibleCharacterRange, theValue} to «event UIElGetV» {"AXRole", "AXVisibleCharacterRange", "AXValue"}
«event UIElSetE»で指定したUI Elementの属性の値を取得。リストで指定で複数の属性を指定可能。
値が無い場合はmissing valueになります。
«event UIElSetV» {"AXVisibleCharacterRange", "pos=" & pos & " len=1"}
«event UIElSetE»で指定したUI Elementの属性の値を設定。リストで、属性、値を指定します。
UIElementInspectorで属性名の後ろに(W)と書いてあるものに、設定できます。Rangeなども取得した値の書き方でセットできます。
返り値は無く、値が設定されたかどうかは再度取得して確認する必要があります。
«event UIElSetV» {"AXSelectedTextMarkerRange", "Range", "SavedValue"}
3つ目の値を"SavedValue"にすると、値を«event UIElVal_»で保存した名前で指定できます。
«event AXElGetV» {"AXRole", "AXVisibleCharacterRange", "AXValue"}
event AXElSetV» {"AXVisibleCharacterRange", "pos=" & pos & " len=1"}
AXNotificationの通知のハンドラ実行時に通知を受けたUI Elementを対象に上と同じ処理をする命令
«event UIElIndx» { theIndex }
«event UIElIndx» { theIndex, theSaveName }
«event UIElSetE»で保存した複数のUI Elementをインデックスで切り替える
切り替えに成功すれば1、失敗すれば0を返す
theIndex : 指定するUI Elementのインデックス。«event UIElSetE»実行直後はは1。
theSaveName : どの保存したUI Elementのリストから取得するか。«event UIElSetE»で指定した名前、もしくは属性値のリスト。未指定の時は最後にUIElSetEした時のリスト。
«event UIElPAct» {"AXPress"}
«event AXElPAct» {"AXPress"}
«event UIElPAct» {"AXPress", {|modifierKeys|:"command option shift control"}}
«event AXElPAct» {"AXPress", {|modifierKeys|:"command option shift control"}}
指定した命令をPerformActionする。
二つ目の値にレコードで実行時に押す修飾キーを指定できる。
«event UIElVal_» {"Attr Name", "parameter", "SaveName"}
«event AXElVal_» {"Attr Name", "parameter", "SaveName"}
UIElの値を取得します。UIElGetVとの違いは、パラーメータを指定できる、取得した値を保存できる、です。
パラメータ("parameter")にはpositionなどを指定する場合"pos=1 len=10"のようなテキストで指定できます。
パラメータ("parameter")には"SaveName"で保存した名前を指定できます。また、"UIEl"、"AXEl"も指定できます。パラメータを空文字にするとパラーメータは指定しなくてUIElGetVと同じように値を取得します。"SaveName"で保存はできます。"SaveName"を空文字にすると値を保存しません。
例:AXWebAreaの選択しているテキストを取得する。UIElはAXWebAreaが指定されている必要があります。
«event UIElVal_» {"AXSelectedTextMarkerRange", "", "SelectedTextMarkerRange"} -- AXSelectedTextMarkerRangeをSelectedTextMarkerRangeに保存
set theSelectedText to «event UIElVal_» {"AXStringForTextMarkerRange", "SelectedTextMarkerRange", ""} -- AXStringForTextMarkerRangeを上で保存したSelectedTextMarkerRangeをパラメータにして取得
UIElementのテキストを可能な限り取得するgetUIElementTextも参考にして下さい。取得するならこれでだいたい行けると思います。

AXWebAreaで取得可能な属性@10.6.8:{"AXUIElementForTextMarker", "AXTextMarkerRangeForUIElement", "AXLineForTextMarker", "AXTextMarkerRangeForLine", "AXStringForTextMarkerRange", "AXTextMarkerForPosition", "AXBoundsForTextMarkerRange", "AXAttributedStringForTextMarkerRange", "AXTextMarkerRangeForUnorderedTextMarkers", "AXNextTextMarkerForTextMarker", "AXPreviousTextMarkerForTextMarker", "AXLeftWordTextMarkerRangeForTextMarker", "AXRightWordTextMarkerRangeForTextMarker", "AXLeftLineTextMarkerRangeForTextMarker", "AXRightLineTextMarkerRangeForTextMarker", "AXSentenceTextMarkerRangeForTextMarker", "AXParagraphTextMarkerRangeForTextMarker", "AXNextWordEndTextMarkerForTextMarker", "AXPreviousWordStartTextMarkerForTextMarker", "AXNextLineEndTextMarkerForTextMarker", "AXPreviousLineStartTextMarkerForTextMarker", "AXNextSentenceEndTextMarkerForTextMarker", "AXPreviousSentenceStartTextMarkerForTextMarker", "AXNextParagraphEndTextMarkerForTextMarker", "AXPreviousParagraphStartTextMarkerForTextMarker", "AXStyleTextMarkerRangeForTextMarker", "AXLengthForTextMarkerRange", "AXBoundsForRange", "AXStringForRange"}

AXTextArea、AXTextFieldで取得可能な属性@10.6.8:{"AXLineForIndex", "AXRangeForLine", "AXStringForRange", "AXRangeForPosition", "AXRangeForIndex", "AXBoundsForRange", "AXRTFForRange", "AXStyleRangeForIndex", "AXAttributedStringForRange"}
«event UIElPAtr»
«event UIElVal_»で指定可能なパラメータ付き属性の名前を取得します。
UIElementInspector.appでは確認できないのでこれで確認できます。
«event UIElAppI»
UIElで指定されているUIパーツを持つアプリケーション情報を取得
«event UIElAXEl»
UIElの値をAXElにする
«event UIElSave» {"name", "UIEl"/"AXEl" }
現在UIElかAXElに設定されている値を"name"に保存する
«event UIElLoad» {"name"}
«event UIElSave»で保存した値をロードする
ロードに成功したら1、失敗したら0を返す。
«event UIElFind» {"ParentAndSelf", {theAttr, theValue, theOpt}}
«event UIElFind» {"ParentAndSelf", {"AXRole", "(AXTextArea|AXTextField|AXStaticText)", "regex"}}
現在のUI Elementとその親要素から指定したtheAttrがtheValueの要素を探してUIElに設定する。
見つかれば1、見つからなければ0を返す。
theOpt : "regex" と "not"。両方指定する場合は "regex not" のようにします。
regexで比較が正規表現になります。通常は完全一致です。
notで一致しない物を探します。
AXFocusedUIElementで取得したUIElのAXScrollAreaを取得する時等に使います。
«event UIElFind» {"Parent", {theAttr, theValue, theOpt}}
"ParentAndSelf"の自分は含まないもの

HTTPサーバー機能

MenuBarAppleScriptのアプリケーションがHTTPサーバーになることができます。

何故この機能を追加したかというと、次の理由からです。

  1. Macの何かのデータをiPadに表示できるかもしれない ⇒ 一個だけ自分専用のスクリプトで使いましたが、汎用的で面白いものはアイデアが思いつきませんでした…
  2. UserScriptとAppleScriptの連携で、今は UserScriptからURLスキーム経由でAppleScriptを起動して、AppleScriptでブラウザのJavaScriptを実行して結果を反映させていますが、MenuBarAppleScriptがサーバーになって、AppleScriptの結果をJSONPで返してUserScriptで処理をすれば、ブラウザのAppleScriptに依存しなくて、Safari、Chrome、FirefoxどれでもUserScriptとAppleScriptの連携ができると考えたから。
«event HTTPSevr» { "start", {|Port|:21248, |DocumentRoot|:"~/Desktop", |User|:"", |Password|:""}}
«event HTTPSevr» { "stop" }
サーバーオプション
Port : ポート番号
DocumentRoot : ここで指定したフォルダを起点にファイルを探す
DirectoryIndexFileNames : DocumentRoot内のフォルダにアクセス時に表示するファイル
例:{"index.html", "index.htm"}
User, Password : ログインに必要なユーザー名とパスワード。""もしくはmissing valueでログイン無しでアクセス可能。パスワードのみ指定可能。
返り値:
1 : サーバ起動OK
1以外 : エラー内容の文字列
theThisAppRecordのHTTPServerURLにサーバのURL、HTTPServerPortにポートのみ、HTTPServerStatusにサーバの状態が入ります。0:未起動、1:起動OK、文字列:起動時のエラーメッセージ
サーバーのレスポンスの処理はon doHTTPResponse(theRequestPath, theDocumentFilePath, theMethod, theActiveAppRecord, theThisAppRecord)で行います。
theRequestPath : リクエストのパス。
theDocumentFilePath : リクエストのパスをDocumentRootフォルダのパスに変換したもの。フォルダの場合、末尾に/が付きます。
theMethod : "GET", "HEAD" など
theRequestPathはparseURLで調べることができます。
JSONPを返す場合はwriteJSONでレコードからJSONを作ることができます。
バグ : 大きなファイルを返したり、doHTTPResponseのAppleScriptの処理に時間がかかる場合、MenuBarAppleScriptのアプリケーションが落ちる場合があります。
サンプル:doHTTPResponseの使用例

Dictionary Services (辞書サービス)

Dictionary Services Referenceの命令です。

ハッシュではないです。

«event DicSShow» { theText, theTextOffset, { theShowWindowX, theShowWindowY } }
«event DicSShow» { theText, theTextOffset, { theShowWindowX, theShowWindowY }, theSavedAttributedStringName }
«event DicSShow» { "りんご", 1, { 20, 20 } }
辞書をポップアップウインドウで表示
theTextOffset : 単語の位置。1ベースのインデックスで指定。。missing valueを指定すると、指定したテキストをそのまま調べます。
単語は文字列中の位置で指定します。theTextをそのまま調べたい場合はtheTextOffsetをmissing valueにします。
{ theShowWindowX, theShowWindowY }はディスプレイの左上が{ 0 , 0 }の座標。
theSaveAttributedStringNameは«event UIElVal_»で保存したAttributedStringを指定する場合。
HIDictionaryWindowShow
«event DicSTerm» { theText, theTextOffset }
«event DicSTerm» {"海外旅行に行ってきたよ!", 1 }
theTextのtheTextOffsetの位置の単語と単語のRangeを返します。無ければ{ missing value, missing value }を返す。
例:{"海外旅行", "pos=0 len=4"}
theTextOffset : 単語の位置。1ベースのインデックス。
単語は文字列中の位置で指定します。単語だけならtheTextOffsetを1にして、theTextに表示したい単語を指定します。
"TextOffset"のようにくっついている文字列でも、"Text"や"Offset"を取得できます。日本語も"海外旅行に行く"の場合、"海外旅行"や"行く"を取得できます。
DCSGetTermRangeInString
«event DicSDef_» { theText, theTextOffset, theDictName }
«event DicSDef_» {"海外", 1, "国語辞典"}
«event DicSDef_» {"apple", 1, "英和/和英辞典"}
«event DicSDef_» {"りんご", 1, "英和/和英辞典"}
«event DicSDef_» {"感じ", 1, "類語辞典"}
«event DicSDef_» {"Finder", 1, "Apple"}
«event DicSDef_» {"犬", 1, "Wikipedia"}
theTextのtheTextOffsetの位置の単語の意味を返します。無けれればmissing value
theTextOffset : 単語の位置。1ベースのインデックス。missing valueを指定すると、指定したテキストをそのまま調べます。
theDictName : 辞書名。辞書.appの環境設定で確認できます。未指定もしくは無い場合はデフォルトの辞書で調べます。
単語は文字列中の位置で指定します。単語だけならtheTextOffsetを1にして、theTextに表示したい単語を指定します。
DCSCopyTextDefinition

テキスト 一般

詳しい説明はNSString Class Referenceを見て下さい。

«event TextUtil» {"lowercaseString", theText}
小文字にする
«event TextUtil» {"uppercaseString", theText}
大文字にする
«event TextUtil» {"capitalizedString", theText}
Abcのようにする
«event TextUtil» {"capitalizedString", theText}
Abcのようにする
«event TextUtil» {"printfInt", "%04d", 12}
printfで数値を整形する。値は一つだけなので%dは一つだけで、指定する数値も一つです。
«event TextUtil» {"printfFloat", "%.2f", 12.345678}
printfでfloat値を整形する。値は一つだけなので%fは一つだけで、指定する数値も一つです。
«event TextUtil» {"strtol", theText, theBase}
«event TextUtil» {"strtol", theText, { theBase1, theBase2, theBase3 } }
«event TextUtil» {"strtol", "AA", 16}
«event TextUtil» {"strtol", "AA 99 FF", { 16, 16, 16 } }
strtolでテキストを数値に変換します。
変換でエラーになった場合はmissing valueを返します。
theBaseをリストで複数渡すことができます。その場合の返り値は数値のリストになります。変換でエラーになった場合はリストのそのエラーに成った値からmissing valueになります。
実際には大きな数値でもいいようにstrtollを呼び出して変換しています。
«event TextUtil» {"parseJSON", theURLorText}
JSONのURL又はJSONのテキストを渡して、JSONのレコードを返す
parseに失敗した場合はmissing valueを返します
«event TextUtil» {"parseXML", theURLorText}
XMLのURL又はXMLのテキストを渡すしてそのXMLのレコードを返す
parseに失敗した場合はmissing valueを返します
参考:Simple XML to NSDictionary Converter
«event TextUtil» {"writeJSON", theRecord }
レコードをJSONのテキストに変換する
«event TextUtil» {"MGTemplateEngine", theTemplate, theValueRecord }
«event TextUtil» {"MGTemplateEngine", theTemplate, theValueRecord, thePersistentValueRecord }
«event TextUtil» {"MGTemplateEngine", theTemplate, theValueRecord, thePersistentValueRecord, {|OpenHTML|:1, |Browser|:"Safari", |OpenText|:0, |Editor|:"mi", |Activate|:0, |Name|:"UseCount"} }
MGTemplateEngineを使用する
theTemplate : テンプレートファイルのパス、もしくはテンプレートのテキスト
theValueRecord : テンプレートの値のレコード
thePersistentValueRecord : テンプレートの値のレコードその2。固定値をこのレコードに入れておくに感じでしょうか。
{|OpenHTML|:1, |Browser|:"Safari", |OpenText|:0, |Editor|:"mi", |Activate|:0, |Name|:"UseCount"} : テンプレートの結果をブラウザやテキストエディタで開く場合の設定
・フィルタ
uppercase
lowercase
capitalized
・MenuBarAppleScriptの追加フィルタ
html : テキストにhtmlspecialcharsを適用する。HTMLで表示するテキストの場合に使用
decodehtml : テキストにdecodeHtmlSpecialcharsを適用する。
encode : テキストにencodeURIComponentを適用する。
decode : テキストにdecodeURIComponentを適用する。
・テンプレート書き方
{% literal %}This text won't be {% now %} interpreted.{% /literal %}
{{ key }}
{{ key | html }}
{{ key | encode }}
{{ users.@count }}
{{ users.@lastObject }}
{% cycle a b c %} {{ value }} {% /cyble %}
{{ currentLoop.currentIndex }} {{ currentLoop.startIndex }} {{ currentLoop.endIndex }} {{ currentLoop.reversed }}
{{ currentLoop.parentLoop.currentIndex }} {{ currentLoop.parentLoop.startIndex }} {{ currentLoop.parentLoop.endIndex }} {{ currentLoop.parentLoop.reversed }}
{% for 1 to 5 %} {{ currentLoop.currentIndex }} {% /for %}
{% for 1 to 5 reversed %} {{ currentLoop.currentIndex }} {% /for %}
{% for path in paths %} {{ path }} {% /for %}
{% for path in paths reversed %} {{ currentLoop.currentIndex }} {{ path }} {% /for %}
{% for user in users %} {{ currentLoop.currentIndex }} {{ user.name }} {{ user.age }} {% /for %}
{% for user in users reversed %} {{ currentLoop.currentIndex }} {{ user.name }} {{ user.age }} {% /for %}
{%if item.usedcount >= hilightUsedCount %} TRUE {%/if%}
{%if item.usedcount >= hilightUsedCount %} TRUE {%else%} FALSE {%/if%}
{% if 'text1' equalsstring 'text1' %} same {% /if %}
{% if 'text1' notequalsstring 'text2' %} not same {% /if %}
{%if currentLoop.currentIndex % 2 %}odd{%else%}even{%/if%}
ifで使える演算子一覧 : and , %% , or , || , = , == , != ,<> , > , < , >= , <= , % , equalsstring , notequalsstring
メモ:上記演算子のandを使ってみたら使い方が悪いのか動きませんでした。ifを二重にしました。
{% cycle odd even %}
{% cycle 'odd a' 'even b' %}
http://mattgemmell.com/files/sample_template.txt
MGTemplateEngineのテンプレート例

テキスト URL関係

«event TextURL_» {"encodeURIComponent", theText [, mojiCode] }
encodeURIComponentする
mojiCodeは"UTF8","SJIS","EUC-JP"。"JIS"はエラーになります
«event TextURL_» {"decodeURIComponent", theText [, mojiCode] }
decodeURIComponentする
mojiCodeは"UTF8","SJIS","EUC-JP"。"JIS"はエラーになります
«event TextURL_» {"parseURL", theURL }
URLの属性のレコードを返します。特に使えそうなのはqueryをrecordにした|queryRecord|です。
レコードのキーは次の通りです。
|queryRecord|
|absoluteString|
|absoluteURL|
|baseURL|
|fragment|
|host|
|lastPathComponent|
|parameterString|
|password|
|path|
|pathComponents|
|pathExtension|
|port|
|query|
|relativePath|
|relativeString|
|resourceSpecifier|
|scheme|
|user|
AppleScriptEditorHelperで上記キーを挿入することができます。
Googleのqを取得するには次のようにします。qは複数回設定され場合もあるのでリストになるのでitem 1で指定します。
	set theURLRecord to «event TextURL_» {"parseURL", "http://www.google.co.jp/search?q=3ds"}
	«event DebugLog» (theURLRecord)
	«event DebugLog» (item 1 of q of |queryRecord| of theURLRecord)
«event TextURL_» {"htmlspecialchars", theText }
&, <, >, ", 'を&amp;などに置換する
«event TextURL_» {"decodeHtmlSpecialchars", theText }
htmlspecialcharsの逆の処理。

テキスト 正規表現関係(RE)

TextRegxは引数の順番がイマイチで気になるのでそれを直した新しい命令を作りました。

«event TextRE__» {"isMatched", "text", "pattern" }
パターンにマッチするなら1
«event TextRE__» {"capture", "abc 123 efg", "([0-9]+)", 1 }
«event TextRE__» {"capture", "abc 123 efg", "(\\w+) ([0-9]+)", {1,2} }
パターンの()で囲った物を取得する。()は1からの番号で指定する
リストで複数指定可能。返り値はリストになります。
«event TextRE__» {"matchedList", "123 abc 456 efg", "[0-9]+" }
結果:{ "123", "456" }
パターンにあう文字列をすべて抜き出しリストで返す
matchedListは()で囲った物を返すのではなくて、パターンにあう物を返す。特定の文字に囲まれた部分を取得するには次のようにする
例:hrefの値を取得:«event TextRE__» {"matchedList", theHTML, "(?<=<a href=\")(.*?)(?=\">)" }
«event TextRE__» {"split", "text", "pattern" }
パターンでテキストを分割してリストで返す
«event TextRE__» {"replace", "text", "pattern", "replaceText" }
パターンを"replaceText"で置換する

テキスト 正規表現関係

«event TextRegx» {"isMatched", "pattern", "text" }
パターンにマッチするなら1
«event TextRegx» {"capture", "([0-9]+)", "abc 123 efg", 1 }
«event TextRegx» {"capture", "(\\w+) ([0-9]+)", "abc 123 efg", {1,2} }
パターンの()で囲った物を取得する。()は1からの番号で指定する
リストで複数指定可能。返り値はリストになります。
«event TextRegx» {"matchedList", "[0-9]+", "123 abc 456 efg" }
結果:{ "123", "456" }
パターンにあう文字列をすべて抜き出しリストで返す
matchedListは()で囲った物を返すのではなくて、パターンにあう物を返す。特定の文字に囲まれた部分を取得するには次のようにする
例:hrefの値を取得:«event TextRegx» {"matchedList", "(?<=<a href=\")(.*?)(?=\">)", theHTML }
«event TextRegx» {"split", "pattern", "text" }
パターンでテキストを分割してリストで返す
«event TextRegx» {"replace", "pattern", "text", "replaceText" }
パターンを"replaceText"で置換する

テキスト パス関係

詳しい説明はNSString Class Referenceを見て下さい。

Finderでできるのに何故あるのかというとFinderでファイル操作をしているとエラーになることがたまにあってFinderを信用してないからです。

コマンドでもできますが、命令を用意したほうが処理が軽いかなと思い(未確認)機能を付けました。

«event TextPath» {"url", thePath}
thePathのURLを返す
«event TextPath» {"exists", thePath}
ファイルが存在すれば1、無ければ0
«event TextPath» {"isDirectory", thePath}
フォルダなら1、ファイルなら0
«event TextPath» {"stringByExpandingTildeInPath", thePath}
~/hogeのパスをフルパスに展開する
«event TextPath» {"lastPathComponent", thePath}
パスの最後の要素名(ファイル名、フォルダ名)を返す
«event TextPath» {"pathExtension", thePath}
拡張子を返す
«event TextPath» {"stringByDeletingLastPathComponent", thePath}
パスの最後の要素を削除したパスを返す
«event TextPath» {"stringByDeletingPathExtension", thePath}
拡張子を削除したパスを返す
«event TextPath» {"stringByAbbreviatingWithTildeInPath", thePath}
/Users/hoge/foo/a.txtを~/foo/a.txtにする。ユーザーが存在しない場合はそのままのパスを返す
«event TextPath» {"stringByAppendingPathComponent", thePath, "inu.zip"}
指定した値をパスに追加する
«event TextPath» {"stringsByAppendingPaths", thePath, {"mac", "wii"}}
指定したパスにリストで指定した値を追加したパスをリストで返す
«event TextPath» {"isAbsolutePath", thePath}
絶対パスなら1
«event TextPath» {"stringByResolvingSymlinksInPath", thePath}
シンボリックリンクの元パスを返す
«event TextPath» {"stringByStandardizingPath", thePath}
/hoge//hage/a.jpgの//を/に戻す等して通常のパスにしたものを返す
«event TextPath» {"move", theSrcPath, theDstPath }
ファイルを移動する
成功したら1を返す。
«event TextPath» {"copy", theSrcPath, theDstPath }
ファイルをコピーする
成功したら1を返す。
«event TextPath» {"remove", thePath}
ファイルを削除する
成功したら1を返す。
«event TextPath» {"createDirectory", thePath}
フォルダを作成する
成功したら1を返す。
«event TextPath» {"contentsOfDirectory", thePath }
«event TextPath» {"contentsOfDirectory", thePath, { "SkipsHiddenFiles", "folderOnly", "fileOnly", "AddSlashToFolder" } }
フォルダ内のファイルを取得する
SkipsHiddenFiles : 不可視ファイルは取得しない
folderOnly : フォルダのみ取得する
fileOnly : ファイルのみ取得する
AddSlashToFolder : フォルダ名の末尾に/を追加する
«event TextPath» {"moveToTrash", thePath}
ファイルをゴミ箱に移動する
返り値は無し
«event TextPath» {"duplicate", thePath}
ファイルを複製する
Finderで複製するのと同じ
返り値は無し
«event TextPath» {"setIcon", thePath, theImagePathOrURL }
アイコンを設定する
成功したら1を返す。
«event TextPath» {"getTag", thePath }
10.9のタグを取得する
成功したらタグをリストで返します。
無い場合は空のリストを返します。
失敗したらmissing valueを返します
«event TextPath» {"setTag", thePath, theTagStrOrTagList }
10.9のタグをファイルに設定する
成功したら1を返す。
既存のタグを全て消して設定したタグになります。追加したい場合はaddTagを使います。
theTagStrOrTagListは下記のように指定できるということです。
«event TextPath» {"setTag", thePath, "Apple" }
«event TextPath» {"setTag", thePath, { "Apple", "Store" } }
«event TextPath» {"addTag", thePath, theTagStrOrTagList }
10.9のタグをファイルに追加する
成功したら1を返す。
localizedCaseInsensitiveCompareで同じタグがあるかどうか調べ、すでにあれば追加しません
localizedCaseInsensitiveCompareは全角、半角とひらがな、カタカナを同じとして比較します。
«event TextPath» {"removeTag", thePath, theTagStrOrTagList }
10.9のタグをファイルから取り除く
localizedCaseInsensitiveCompareで同じタグかどうか比較します。
localizedCaseInsensitiveCompareは全角、半角とひらがな、カタカナを同じとして比較します。
成功したら取り除いたタグの数を返す。

日付関係

«event DateUtil» {"SecondsUntilDate", {|Year|:2101, |Month|:1, |Day|:1, |Hour|:0, |Minute|:0, |Second|:0}}
«event DateUtil» {"SecondsUntilDate", {|Month|:1, |Day|:1, |Hour|:0, |Minute|:0, |Second|:0}}
«event DateUtil» {"SecondsUntilDate", {|Day|:2, |Hour|:2, |Minute|:2, |Second|:2}}
«event DateUtil» {"SecondsUntilDate", {|Hour|:23, |Minute|:0, |Second|:0}}
«event DateUtil» {"SecondsUntilDate", {|Minute|:30, |Second|:0}}
«event DateUtil» {"SecondsUntilDate", {|Second|:30}}
«event DateUtil» {"SecondsUntilDate", "2013-04-12 15:30:45 +0900"}
指定した時間までの秒数を返す。
DoAtTimeで指定する時間と同じレコードです。何秒後にDoAtTimeのハンドラが実行されるのか確認したい場合などに

辞書(ハッシュ)関係

Cocoaで辞書、一般にはハッシュと呼ばれる、文字列をキーとして、データを参照する機能を実現する命令です。

あったら便利だと思うので付けてみました。

これを使う利点は辞書が便利だから以外に、ここに保存したデータはMenuBarAppleScriptのスクリプトを変更、保存してもMenuBarAppleScriptのアプリケーションが起動している限り保持されるので、ここに状態を保存すると、スクリプトを保存、更新しても、次の実行時に前回の状態のままスクリプトを実行できます。開発中のアプリケーションでスクリプトの一部分を変更した場合でも、propertyに保存するとスクリプトを保存した時に初期化されてしまいますが、これを使うと前回の状態を保持したまま実行できます。

また、return {|SaveDict|:1}を返すと、辞書の値をPreferenceのplistに保存するようになり、アプリケーションを終了、再起動しても値を保持できるようになります。デフォルト値も1です。なお、値の読み込みは起動時に自動的に行われます。

辞書のキーには文字列以外も指定できますが内部で文字列に変換されます。これはplistでは辞書のキーは文字列のみ有効だからです。その為、"1"と1は同じキーとなるので注意してください。

dictNameが次のものは保存前に削除します

実行中のみの一時データは下記名前にすると保存ません。

"^(?i)te?mp([-_ ]|$)"
上記正規表現にマッチする名前の辞書を削除します。
例:すべて大文字小文字は区別しません
"tmp"
"temp"
"tmp-"から始まるもの
"tmp_"から始まるもの
"tmp "から始まるもの
"temp-"から始まるもの
"temp_"から始まるもの
"temp "から始まるもの
«event DictSetV» {dictName, "theKey", "value" }
«event DictSetV» {dictName, "theKey", {"hoge", "hage" } }
dictNameという名前の辞書の"theKey"の値をリスト"value"{"hoge", "hage" }に設定。
設定できる値は、文字列、数値、リスト、レコードです。date型やアプリケーション独自の値は設定できません。
内部ではリストは配列(NSArray)、レコードは辞書(NSDictionary)になります。
dictName[theKey] = theValue;
«event DictSetD» {dictName, "theKey", "defaultValue" }
値の初期値を設定します。
«event DictGetV»をした時に、«event DictSetV»で値を設定していない場合にmissing valueでなく、これで設定した値を返します。
主に、アプリケーションの初期設定を指定するのに使います。
«event DictGetV» {dictName, "theKey"}
«event DictGetV» {dictName, "theKey", theDefaultValue }
dictNameという名前の辞書の"theKey"の値を取得
値が未設定の場合、missing valueを返します。メモ:missing valueはFourCC "msng"でした。
"DefaultValue"を指定すると値が未設定の場合、theDefaultValueを返します。値が設定されていないなら初期値を設定して実行する場合、ここで初期値を指定しておくと、ifで調べる必要が無くなります。
«event DictGetL» {dictName, "theKey"}
dictNameという名前の辞書の"theKey"の値を取得
値が未設定の場合、空のリストを返します。
リストを設定、取得する場合で、空のリストを初期値としていい場合、これを使うと、リストの値をすでに設定してあるか調べる必要がありません。
«event DictNotV» {dictName, "theKey"}
«event DictNotV» {dictName, "theKey", theDefaultValue }
値が0以外の数値の場合0に、0の場合1にして、その値を返します。
値が数値以外の場合は何もしません。
主に設定のオンオフをトグルするのに使います。
«event DictDelV» {dictName, "theKey"}
dictNameという名前の辞書の"theKey"のキーと値を削除
«event DictDelA» {dictName}
dictNameという名前の辞書のすべてのキーと値を削除
«event DictAKey» {dictName,"sort function"}
dictNameという名前の辞書のすべてのキーをリストで返す
"sort function"は次のものがあります。未指定でソートしません。
compare
caseInsensitiveCompare
localizedCaseInsensitiveCompare
localizedStandardCompare
«event DictAVal» {dictName,"sort function"}
dictNameという名前の辞書のすべての値をリストで返す
"sort function"は次のものがあります。未指定でソートしません。
compare
caseInsensitiveCompare
localizedCaseInsensitiveCompare
localizedStandardCompare
«event DictInit»
すべての辞書を削除する
«event DictList» {dictName,"listKey",actionName, "value1"}
辞書 dictName の"listKey"の値がリストの場合、actionNameの処理を実行する
«event DictList»の命令

«event DictList»の命令

リスト操作であれば便利そうなのを入れてみました。

この命令は対象のリストを変更します。

値を取得する物で、値を取得できなかった場合はmissing valueを返します。

直接リストを操作したい場合は下記のように«event HndlList»にして、theListで直接リストを指定します。命令の種類は下記«event DictList»と同じです。

返り値のtheListが処理済みのリストで、theResultは処理した時の値で無い場合はmissing valueになります。shiftやpopの場合等に値が入っています。

set {theList, theResult} to «event HndlList» {theList,"sort", "localizedStandardCompare" }

«event DictList» {dictName,listKey,"objectAtIndex", 1}
指定したindexの値を取得。indexはAppleScriptのリストと同じ1からカウントします。
«event DictList» {dictName,listKey,"indexOfObject", "hoge"}
指定した値のindexを取得。indexはAppleScriptのリストと同じ1からカウントします。見つからない場合は-1になります。
«event DictList» {dictName,listKey,"containsObject", "hoge"}
指定した値が含まれるなら1。無いなら0
«event DictList» {dictName,listKey,"count"}
要素の数を返す
«event DictList» {dictName,listKey,"reverse"}
順番を逆にする
«event DictList» {dictName,listKey,"pop"}
最後の要素を返して、最後の要素はリストから削除する
«event DictList» {dictName,listKey,"shift"}
最初の要素を返して、最初の要素はリストから削除する
«event DictList» {dictName,listKey,"addObject", "hoge"}
«event DictList» {dictName,listKey,"push", "hoge"}
値を最後に追加する
«event DictList» {dictName,listKey,"unshift", "hoge"}
値を先頭に追加する
«event DictList» {dictName,listKey,"addObjectsFromArray", { "hoge", "hage" } }
指定したリストの要素をリストに追加する
«event DictList» {dictName,listKey,"setArray", { "hoge", "hage" } }
リストの内容をを指定したリストの内容にする
«event DictList» {dictName,listKey,"trim", 10}
リストの要素数が指定した数値以上の場合、後ろから削除して指定した要素数にする。少ない場合は何もしない。
«event DictList» {dictName,listKey,"head", 10}
リストの最初から10個の要素を取り出す。少ない場合は無いにもしない。trimと同じ
«event DictList» {dictName,listKey,"tail", 10}
リストの後ろから10個の要素を取り出す。少ない場合は何もしない。
«event DictList» {dictName,listKey,"removeLastObject"}
最後の要素を削除する。リストが空の場合は何もしない
«event DictList» {dictName,listKey,"removeAllObjects"}
すべての要素を削除する
«event DictList» {dictName,listKey,"removeObject", "hoge"}
指定した要素を削除する。無い場合は何もしない。複数ある場合はすべて削除される。
«event DictList» {dictName,listKey,"removeObjectsInArray", { "hoge", "hage" } }
指定したリストに入っている要素を削除する。無い場合は何もしない。
«event DictList» {dictName,listKey,"sort", "sort function" }
リストをソートする
"sort function"は次のものがあります
compare
caseInsensitiveCompare
localizedCaseInsensitiveCompare
localizedStandardCompare
«event DictList» {dictName,listKey,"isEqualToArray", theList }
指定したリストと同じなら1
«event DictList» {dictName,listKey,"uniq"}
重複している要素を削除
«event DictList» {dictName,listKey,"grep", "pattern" }
指定した正規表現にマッチする物だけのリストにする
«event DictList» {dictName,listKey,"notgrep", "pattern" }
指定した正規表現にマッチしない物だけのリストにする
«event DictList» {dictName,listKey,"insertAfterEveryItem", "hoge" }
{1,2,3}{1,"hoge",2,"hoge",3,"hoge"}になります。
«event DictList» {dictName,listKey,"insertBeforeEveryItem", "hoge" }
{1,2,3}{"hoge",1,"hoge",2,"hoge",3}になります。
«event DictList» {dictName,listKey,"insertAfterTheItem", "find", "insert" }
{1,"find",3}{1,"find","insert",3}になります。
挿入した項目数を返します
MenuItemListの特定のメニュー項目に属性を追加するのに使えます。
«event DictList» {dictName,listKey,"insertBeforeTheItem", "find", "insert" }
{1,"find",3}{1,"insert","find",3}になります。
挿入した項目数を返します
«event DictList» {dictName,listKey,"insertListAfterEveryItem", theInserList }
«event DictList» {dictName,listKey,"insertListAfterEveryItem", {8,9} }
リストを展開して追加します
{1,2,3}{1,8,9,2,8,9,3,8,9}になります。
«event DictList» {dictName,listKey,"insertListBeforeEveryItem", theInserList }
«event DictList» {dictName,listKey,"insertListBeforeEveryItem", {8,9} }
リストを展開して追加します
{1,2,3}{8,9,1,8,9,2,8,9,3}になります。
«event DictList» {dictName,listKey,"insertListAfterTheItem", "find", theInserList }
«event DictList» {dictName,listKey,"insertListAfterTheItem", "find", {8,9} }
{1,"find",3}{1,"find",8,9,3}になります。
リストを展開して追加します
挿入した項目数を返します
MenuItemListの特定のメニュー項目に属性を追加するのに使えます。
«event DictList» {dictName,listKey,"insertListBeforeTheItem", "find", theInserList }
«event DictList» {dictName,listKey,"insertListBeforeTheItem", "find", {8,9} }
{1,"find",3}{1,8,9,"find",3}になります。
リストを展開して追加します
挿入した項目数を返します
«event DictList» {dictName,listKey,"prependTextToEveryItem", "hoge" }
すべての要素のテキストの前に指定したテキストを追加します。
{"a","b"}{"hogea","hogeb"}になります。
«event DictList» {dictName,listKey,"appendTextToEveryItem", "hoge" }
すべての要素のテキストの後ろに指定したテキストを追加します。
{"a","b"}{"ahoge","bhoge"}になります。
«event DictList» {dictName,listKey,"replaceTextToEveryItem", "pattern", "replaceText" }
すべての要素のテキストの指定した正規表現パターンにマッチする物を"replaceText"で置換します。
正規表現なので気をつけて下さい。
«event DictList» {dictName,listKey,"join", "text"}
リストを"text"で結合した文字列を返す

«event DictDict»の命令

辞書(レコード)操作であれば便利そうなのを入れてみました。

値を取得する物で、値を取得できなかった場合はmissing valueを返します。

直接レコードを操作したい場合は下記のように«event HndlDict»にして、theRecordで直接リストを指定します。命令は下記«event DictDict»と同じです。

返り値のtheRecordが処理済みのレコードで、theResultは処理した時の値で無い場合はmissing valueになります。

set {theRecord, theResult} to «event HndlDict» {theRecord,"setObjectForKey", theObject, theKey }

«event DictDict» {dictName,dictKey,"objectforkey", theKey }
theKeyの値を取得。無ければmissing value
«event DictDict» {dictName,dictKey,"setObjectForKey", theObject, theKey }
theKeyをtheObjectにする
«event DictDict» {dictName,dictKey,"removeObjectForKey", theKey }
theKeyの値を削除する
«event DictDict» {dictName,dictKey,"count" }
値の数を返す
«event DictDict» {dictName,dictKey,"removeAllObjects" }
すべての値を削除する
«event DictDict» {dictName,dictKey,"removeObjectsForKeys", { key1, key2 } }
指定したキーのリストの値を削除する
«event DictDict» {dictName,dictKey,"allKeys", "sort function" }
すべてのキーをリストで返す
"sort function"は次のものがあります。未指定でソートしません。
compare
caseInsensitiveCompare
localizedCaseInsensitiveCompare
localizedStandardCompare
«event DictDict» {dictName,dictKey,"allValues", "sort function" }
すべての値をリストで返す
"sort function"は次のものがあります。未指定でソートしません。
compare
caseInsensitiveCompare
localizedCaseInsensitiveCompare
localizedStandardCompare
«event DictDict» {dictName,dictKey,"isEqualToDictionary", theRecord }
指定したレコードと同じなら1
«event DictDict» {dictName,dictKey,"setDictionary", theRecord }
辞書を設定する
«event DictDict» {dictName,dictKey,"allKeysForObject", theObj }
値がtheObjのキーをリストで返す

«event DictNum_»の命令

辞書の指定したキーに値が無い場合は0を処理対象にする

«event DictNum_» {dictName,dictKey,"+", 1}
数値を足して、足した後の数を返す
- * /も使用できます。
«event DictNum_» {dictName,dictKey,"not"}
値が0かmissing valueなら1を、それ以外なら0を返す

«event DictText»の命令

辞書の指定したキーに値が無い場合は空文字列を処理対象にする

«event DictText» {dictName,dictKey,"append", "abc"}
テキストを末尾に追加して、追加後のテキストを返す
«event DictText» {dictName,dictKey,"compare", "abc", "compare"/"caseInsensitiveCompare"/"localizedCaseInsensitiveCompare"/"localizedStandardCompare"}
テキストを比較して結果を返す。結果は-1,0,1の数値。辞書文字列が大きい場合1。
最後の値は比較関数

URLスキーム

初期設定でURLスキームを設定するとそのURLを開いた時に下記ハンドラが実行されます。

on doOpenURL(theURL, theActiveAppRecord, theThisAppRecord)

URLの分析するにはparseURLを使うと便利かもしれません。

他のアプリケーションからURLを開くと、MenuBarAppleScriptアプリケーションがアクティブになり、現在アクティブなアプリケーションがアクティブじゃなくなります。バックグラウンドで、URLを使って命令をやり取りする場合には、結構気になります。それを回避するには、初期設定のアプリケーションの実行タイプをLSBackgroundOnlyにします。ただし、デフォルトのLSUIElementとGUIを利用する場合の細かい動作が違ってきます。

アプリケーション実行タイプ別特徴

通常
Dockに表示される普通のアプリケーション
doQuitの処理が確実にすべて実行される
LSUIElement
Dockに表示されないアプリケーション
サービスを実行した時はアクティブになる
doQuitで時間がかかる処理をしたら処理中でもアプリケーションが強制終了する
LSBackgroundOnly
Dockに表示されないアプリケーション
サービスを実行した時もアクティブにならない
Cmd + Cでテキストを選択できない
doQuitで時間がかかる処理をしたら処理中でもアプリケーションが強制終了する

起動直後のイベントの実行順書

  1. doInit
  2. doRun
  3. doService系、doOpenFile、doOpenURL
  4. 上のがなければ、doRunWithNoServiceNoOpenFileNoOpenURL

UIElementInspector

UI ElementはUIElementInspectorで調べることができます。「Download Sample Code」をダウンロードするとアプリケーションが入っています。

属性名の最後に(W)と書いてある物が設定可能になります。Position、Rangeなどを設定するには取得した属性と同じ形式のテキストを作成して渡すことにより設定可能です。

値によってはGUI Scriptingでは取得、設定できない物もありますので、いろいろ楽しめるのではないかと思います。

スクリプトレシピ

基本テンプレート

スクリプト

property theMenuBarItemImage : "icon Finder" --  -- メニューバーの画像。無い場合はmissing value
property theMenuBarTitle : "タイトル" -- メニューバーのタイトル 。無い場合はmissing value
property theMenuItemList : {"メニュー1", "メニュー2"}

on run
	-- デバッグ用
	-- tellするアプリケーションを編集中のMenuBarAppleScriptアプリケーションにしておく必要があります
	
	-- ハンドラをテスト実行
	-- theActiveAppRecord は «event InfoAApp»
	-- theThisAppRecord は «event InfoTApp» 
	-- になります
	my doSelectMenuItem("メニュー1", 1, «event InfoAApp», «event InfoTApp»)
end run

on doInit(theActiveAppRecord, theThisAppRecord)
	return {|SaveDict|:1, |LogAppleScriptError|:1, |DebugLog|:1, |DebugJavaScript|:0, |AutoAddQuitMenuItem|:1, |AutoAddLaunchOnLoginMenuItem|:1, |AutoAddVersionMenuItem|:1, |AutoSaveAndRestoreWindowFrameByName|:1, |MenuBarItemImage|:theMenuBarItemImage, |MenuBarItemTitle|:theMenuBarTitle, |MenuItemList|:my getMenuItemList(theActiveAppRecord, theThisAppRecord)}
end doInit

on doRun(theActiveAppRecord, theThisAppRecord)
	-- 起動直後に処理をするならここに記述
end doRun

on getMenuItemList(theActiveAppRecord, theThisAppRecord)
	set theWorkList to theMenuItemList
	
	-- ここでメニューアイテムにチェックを付けたりする

	set end of theWorkList to (current date) as text
	
	set theWorkList to {|name| of theThisAppRecord, "---separatorItem"} & theMenuItemList
	
	return theWorkList
end getMenuItemList

on setMenuItem(theActiveAppRecord, theThisAppRecord)
	«event MBASHndl» {|MenuItemList|:my getMenuItemList(theActiveAppRecord, theThisAppRecord)}
end setMenuItem

on doSelectMenuItem(theTitle, theTag, theActiveAppRecord, theThisAppRecord)
	-- メニュー選択時の処理
	if theTitle is "メニュー1" then
		beep
	end if
end doSelectMenuItem

サービス用アプリケーションテンプレート

サービスから実行するアプリケーションのテンプレートです。テキストとファイル、ついでにURLが書いてありますが、必要無いものは消して下さい。


on run
	-- デバッグ用
	-- tellするアプリケーションを編集中のMenuBarAppleScriptアプリケーションにしておく必要があります
	my doTextService("テキスト text TEXT", «event InfoAApp», «event InfoTApp»)
	my doFileService({"/hoge.txt"}, «event InfoAApp», «event InfoTApp»)
	my doOpenURL("http://memogakisouko.appspot.com/MenuBarAppleScript.html#download", «event InfoAApp», «event InfoTApp»)
end run

on doInit(theActiveAppRecord, theThisAppRecord)
	return {|LogAppleScriptError|:1, |DebugLog|:1, |SaveDict|:1}
end doInit

on doTextService(theText, theActiveAppRecord, theThisAppRecord)
	«event DebugLog» theText
	-- 処理をする
	set theText to «event TextUtil» {"lowercaseString", theText}
	-- 置換する場合ReplaceStringを返す
	return {|ReplaceString|:theText, |QuitAfterSec|:30.0}
end doTextService

on doFileService(thePathList, theActiveAppRecord, theThisAppRecord)
	«event DebugLog» thePathList
	repeat with thePath in thePathList
		-- thePath に処理をする
	end repeat
	
	return {|QuitAfterSec|:30.0}
end doFileService

on doOpenFile(thePathList, theActiveAppRecord, theThisAppRecord)
	my doFileService(thePathList, theActiveAppRecord, theThisAppRecord)
end doOpenFile

on doOpenURL(theURL, theActiveAppRecord, theThisAppRecord)
	set theURLRecord to «event TextURL_» {"parseURL", theURL}
	«event DebugLog» theURLRecord
	-- URLの処理をする
	
	return {|QuitAfterSec|:30.0}
end doOpenURL

特定のアプリケーションでのみメニューバーアイテムを表示

property

property theMenuBarItemImage : "icon Evernote" --  -- メニューバーの画像。無い場合はmissing value
property theMenuBarTitle : "履歴" -- メニューバーのタイトル 。無い場合はmissing value
property theMenuBarItemDisplayAppNameList : {"Evernote", "AppleScript Editor"} -- 表示するアプリケーション名

doInitで返すレコードの値

|NSWorkspaceNotificationList|:{"NSWorkspaceDidActivateApplicationNotification"},

ハンドラ

on doNSWorkspaceDidActivateApplicationNotification(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord)
	
	set activeAppName to |name| of theUserInfo
	
	if (theMenuBarItemDisplayAppNameList does not contain activeAppName) and (|name| of theThisAppRecord is not activeAppName) then
		-- 隠す
		return {RemoveMenuBarItem:1}
	end if
	
	-- 表示
	return {|MenuBarItemImage|:theMenuBarItemImage, |MenuBarItemTitle|:theMenuBarTitle, |MenuItemList|:my getMenuItemList(theActiveAppRecord, theThisAppRecord)}
end doNSWorkspaceDidActivateApplicationNotification

ウインドウも特定のアプリケーションでのみ表示する場合のハンドラ

on doNSWorkspaceDidActivateApplicationNotification(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord)
	set activeAppName to |name| of theUserInfo
	
	if (theMenuBarItemDisplayAppNameList does not contain activeAppName) and (|name| of theThisAppRecord is not activeAppName) then
		-- 隠す
		-- ウインドウのvisibleを保存して全部隠す
		if 1 is |menuBarItemVisible| of theThisAppRecord then -- まだ隠してない時のみ隠す
			«event DictSetV» {"Var", "allWebViewWindowRecord", |allWebViewWindowRecord| of theThisAppRecord}
			«event Win_Hide»
			return {RemoveMenuBarItem:1}
		else
			return
		end if
	end if
	
	-- 表示
	if 0 is |menuBarItemVisible| of theThisAppRecord then
		«event Win_Show» («event DictGetV» {"Var", "allWebViewWindowRecord"}) -- 非表示から表示した時のみ表示する
	end if
	return {|MenuBarItemImage|:theMenuBarItemImage, |MenuBarItemTitle|:theMenuBarTitle, |MenuItemList|:my getMenuItemList(theActiveAppRecord, theThisAppRecord)}
end doNSWorkspaceDidActivateApplicationNotification

メニューバーアイテムをクリックした時に動的にメニューを作成して表示する

注意点

|MenuItemList|で、メニューアイテムが設定されているとそのメニューが表示されdoClickMenuBarItemは実行されず、動的にメニューを作れません。

他のレシピと併用する場合は|MenuItemList|を削除して下さい。

doInitで返すレコードの値

|SendActionOn|:{"LeftMouseDown"},

ハンドラ

on doClickMenuBarItem(theActiveAppRecord, theThisAppRecord)
	return {|PopUpMenuItemList|:my getMenuItemList(theActiveAppRecord, theThisAppRecord)}
end doClickMenuBarItem

メニューバーアイテムを右クリックでコンテキストメニューを表示する

ハンドラ

on doRightClickMenuBarItem(theActiveAppRecord, theThisAppRecord)
	return {|PopUpMenuItemList|:theRightClickMenuItemList}
end doRightClickMenuBarItem

リストからメニューリストを作成

スクリプト

	-- 処理対象のリスト
	set theWorkList to |allWebViewWindowNameList| of theThisAppRecord
	
	-- ソートするなら
	set {theWorkList, theResult} to «event HndlList» {theWorkList, "sort", "localizedStandardCompare"}
	
	-- タイトル用のprefixを付ける。付けなくてもほぼ大丈夫だけど---tagなどで始まるタイトルは表示されない
	set {theWorkList, theResult} to «event HndlList» {theWorkList, "prependTextToEveryItem", "---title "}
	
	-- メニューを選択した時に実行する処理の種類をtagで指定。メニューが複雑になってくると、tagでの判別が必要になってきます。
	set {theWorkList, theResult} to «event HndlList» {theWorkList, "insertAfterEveryItem", "---tag " & theSelectWindowTag}
	
	-- 特定の項目にチェックを付ける
	set checkTitle to |keyWindowName| of theThisAppRecord -- チェックを付けるタイトル
	set {theWorkList, theResult} to «event HndlList» {theWorkList, "insertAfterTheItem", "---title " & checkTitle, "---state on"}
	
	-- 完成

メニューアイテムを選択して設定をオンオフする。メニューアイテムにオンのチェックを付ける。

スクリプトに追加するには、最初に下のスクリプトを全部コピペしてから、theHogeSettingを自分の好きな名前に一括置換すると速いです。

property

property theSettingDictName : "Setting" -- 設定を保存する辞書の名前
property theHogeSettingTagAndKey : 1 -- 設定のタグとキー。数字で指定
property theHogeSettingDefaultValue : 1 -- 設定の初期値。1がオン、0がオフ
property theMenuItemList : { "設定", "---disable", "Hogeの設定", "---tag " & theHogeSettingTagAndKey, "---indentationLevel 1"}

doInit


	-- 初期値を辞書に登録
	«event DictSetD» {theSettingDictName, theHogeSettingTagAndKey, theHogeSettingDefaultValue}

メニュー作成


on getMenuItemList(theActiveAppRecord, theThisAppRecord)
	set theWorkList to theMenuItemList
	
	-- メニューアイテムにオンの場合チェックを付ける
	set {theWorkList, theResult} to «event HndlList» {theWorkList, "insertAfterTheItem", "---tag " & theHogeSettingTagAndKey, "---state " & («event DictGetV» {theSettingDictName, theHogeSettingTagAndKey})}
	
	return theWorkList
end getMenuItemList

メニュー選択


on doSelectMenuItem(theTitle, theTag, theActiveAppRecord, theThisAppRecord)
	if theTag is theHogeSettingTagAndKey then
		-- 設定のトルグ
		«event DictNotV» {theSettingDictName, theHogeSettingTagAndKey }
		my setMenuItem(theActiveAppRecord, theThisAppRecord) -- メニュー更新
	end if
end doSelectMenuItem

設定のオンオフを判定して処理

if 1 is («event DictGetV» {theSettingDictName, theHogeSettingTagAndKey}) then
	-- 設定がオンなので処理をする
end if

いくつかの値から選択するメニューアイテムを表示。選択したメニューアイテムにオンのチェックを付ける。

上のサンプルと似ていますが、これはある値のオンオフじゃなくて、数種類の値から選ぶメニューになります。

property

property theThemeMenuItemTag : 9 -- メニューアイテムに付けるタグ。重複しない任意の数値
property theDefaultThemeName : "Cosmo" -- デフォルト値
property theSettingDictName : "Setting" -- 設定を保存する辞書名
property theThemeNameKey : "ThemeName" -- 設定を保存する辞書のキー

property theMenuItemList : {"HTML テーマ", "---submenu", "Amelia", "---tag " & theThemeMenuItemTag, "Cerulean", "---tag " & theThemeMenuItemTag, "Cosmo", "---tag " & theThemeMenuItemTag, "Cyborg", "---tag " & theThemeMenuItemTag, "Journal Readable", "---tag " & theThemeMenuItemTag, "Simplex", "---tag " & theThemeMenuItemTag, "Slate", "---tag " & theThemeMenuItemTag, "Spacelab", "---tag " & theThemeMenuItemTag, "Spruce", "---tag " & theThemeMenuItemTag, "Superhero", "---tag " & theThemeMenuItemTag, "United", "---tag " & theThemeMenuItemTag, "---end submenu"}

doInit


	-- 初期値を辞書に登録
	«event DictSetD» {theSettingDictName, theThemeNameKey, theDefaultThemeName}

ハンドラ

on getMenuItemList(theActiveAppRecord, theThisAppRecord)
	set theWorkList to theMenuItemList
	
	-- 現在の値のメニューアイテムにチェックを付ける
	set theThemeName to «event DictGetV» {theSettingDictName, theThemeNameKey}
	set {theWorkList, theResult} to «event HndlList» {theWorkList, "insertAfterTheItem", theThemeName, "---state 1"}
	
	
	return theWorkList
end getMenuItemList

on doSelectMenuItem(theTitle, theTag, theActiveAppRecord, theThisAppRecord)
	-- メニュー選択時の処理
	if theTag is theThemeMenuItemTag then
		-- メニューを選択したので値を保存して、メニューを更新
		«event DictSetV» {theSettingDictName, theThemeNameKey, theTitle}
		my setMenuItem(theActiveAppRecord, theThisAppRecord)
	end if
end doSelectMenuItem

on setMenuItem(theActiveAppRecord, theThisAppRecord)
	«event MBASHndl» {|MenuItemList|:my getMenuItemList(theActiveAppRecord, theThisAppRecord)}
end setMenuItem
	set theHTMLTheme to «event DictGetV» {theSettingDictName, theThemeNameKey}
-- theHTMLThemeに選択した値が入っているので処理をする

iTunesの曲が変わった時に処理をする

曲が変わった通知を受け取ります。

doInitで返すレコードの値

|NSDistributedNotificationList|:{"com.apple.iTunes.playerInfo"},

ハンドラ


on docom_apple_iTunes_playerInfo(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord)
	-- NSDistributedNotificationのcom.apple.iTunes.playerInfoの通知を受けた時に実行されます
	
	-- theUserInfoに曲の情報が入っています
	-- 次のようにして取り出します
	-- set theName to |Name| of theUserInfo
	
	-- 停止中はメニューバーから取り除く
	if |Player State| of theUserInfo is "Paused" then
		-- 停止した時の処理
		return {}
	end if
	
	-- Playing以外の場合はハンドラを終了
	-- PausedとPlaying以外あるかどかはわかりません
	if |Player State| of theUserInfo is not "Playing" then
		-- 再生していない時の処理
		return {}
	end if
	
	
	tell application "iTunes"
		-- theUserInfoから通知で受けた曲を取り出すには次のようにpersistent IDを使います
		-- current trackでもだいたいいいと思います
		set thePlaylistList to every playlist whose persistent ID is |Playlist PersistentID| of theUserInfo
		set thePlaylist to item 1 of thePlaylistList
		set theTrackList to every track of thePlaylist whose persistent ID is |PersistentID| of theUserInfo
		set theTrack to item 1 of theTrackList -- theTrackがtheUserInfoで受け取ったtrackになります
		
		-- 処理をする
		
	end tell
end docom_apple_iTunes_playerInfo

Safariのダウンロードが完了した時にハンドラを実行

doInitで返すレコードの値

|NSDistributedNotificationList|:{"com.apple.DownloadFileFinished"},

ハンドラ

on docom_apple_DownloadFileFinished(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord)
	-- theObjectにダウンロードしたファイルのパスが入っています
	
	set theDownloadFilePath to theObject
	
	-- 処理をする
	
end docom_apple_DownloadFileFinished

ネットの接続状態が変わった時にハンドラを実行

doInitで返すレコードの値

|SCNotificationList|:{"State:/Network/Global/IPv4"}, |RunSCNotificationHandler|:1, 

ハンドラ

on doState__Network_Global_IPv4(theValue, theActiveAppRecord, theThisAppRecord)
	-- ネットに繋がっているかチェックして記憶
	if theValue is not missing value then
		-- ネットに繋がっている
		set theNetworkStatus to true
	else
		-- ネットに繋がっていない
		set theNetworkStatus to false
	end if
end doState__Network_Global_IPv4

ホットキーを登録、押した時にスクリプトを実行:グローバル

doInitで返すレコードの値

|HotKeyList|:{{|Name|:"RateUp", |KeyChar|:"up", |ModifierKeyList|:{"shift", "option"}, |Enable|:1 }, {|Name|:"RateDown", |KeyChar|:"down", |ModifierKeyList|:{"shift", "option"}, |Enable|:1}}, 

propertyにホットキーの設定を書く場合

-- ホットキー設定 変更した場合は要アプリケーションの再起動
property theEnableHotKey : 0 -- ホットキーを有効にするなら1 無効なら 0
property theHotKeyKey : "right" -- ホットキーのキー
property theHotKeyModifierKeyList : {"command", "control"} -- ホットキーの修飾キー
|HotKeyList|:{{|Name|:"RateUp", |KeyChar|:theHotKeyKey, |ModifierKeyList|:theHotKeyModifierKeyList, |Enable|:theEnableHotKey}}, 

ハンドラ


on doHotKeyRateUp(theActiveAppRecord, theThisAppRecord)
	
	-- ホットキーを押した時の処理
	
end doHotKeyRateUp

ホットキーを登録、押した時にスクリプトを実行:アプリのみ

doInitで返すレコードの値

|AppHotKeyList|:{{|Name|:"RateUp", |KeyChar|:"up", |ModifierKeyList|:{"shift", "option"}, |Enable|:1 }, {|Name|:"RateDown", |KeyChar|:"down", |ModifierKeyList|:{"shift", "option"}, |Enable|:1}}, 

propertyにホットキーの設定を書く場合

-- ホットキー設定 変更した場合は要アプリケーションの再起動
property theEnableHotKey : 0 -- ホットキーを有効にするなら1 無効なら 0
property theHotKeyKey : "right" -- ホットキーのキー
property theHotKeyModifierKeyList : {"command", "control"} -- ホットキーの修飾キー
|AppHotKeyList|:{{|Name|:"RateUp", |KeyChar|:theHotKeyKey, |ModifierKeyList|:theHotKeyModifierKeyList, |Enable|:theEnableHotKey}}, 

ハンドラ


on doAppHotKeyRateUp(theActiveAppRecord, theThisAppRecord)
	
	-- ホットキーを押した時の処理
	
end doAppHotKeyRateUp

MenuBarAppleScriptでテスト用スクリプトを実行

可能ならデバッグ方法を使用したほうがイベントログが確認できます。

ハンドラ

on run
	set theApp to (path to me) as Unicode text
	tell application theApp
		«event MBASRunH» {|Handler|:"Test"}
	end tell
end run

on doHandlerTest(theRecord, theActiveAppRecord, theThisAppRecord)
	-- ここにテスト用スクリプトを書く
	-- MenuBarAppleScriptで実行されるので各種MenuBarAppleScriptの命令が使えます
	say "test"
end doHandlerTest

疑似スレッド

コマンドの非同期実行でosascriptを実行して、MenuBarAppleScriptのスクリプトのハンドラを実行して擬似的にスレッドを実現しているものです。

スレッド間での値の受け渡しは辞書(ハッシュ)関係の命令を使い、MenuBarAppleScriptを起点に行うことができます。MenuBarAppleScriptの命令はアプリケーションのメインスレッドで実行されるので、別のスレッドから同時に実行しても大丈夫です。

スレッドではpropertyは使えますが、初期値は保証されません。また、他のスレッド間でpropertyの値を共有することはできません。初期化してそのスクリプト中で使うことはできます。

MenuBarAppleScriptThread.scptは最新のMenuBarAppleScriptにはバンドルの中に入っています。

ハンドラ


	-- 新規スレッドで実行
	my detachNewThread("Test", {"hoge", "neko"})

on detachNewThread(theThreadHandler, theUserInfo)
	-- スレッド作成
	set appInfoRecord to «event InfoTApp»
	set theThreadNumber to «event DictNum_» {"ThreadUserInfo", "ThreadNumber", "+", 1}
	set theThreadNumberStr to theThreadNumber as text
	«event DictSetV» {"ThreadUserInfo", theThreadNumberStr, theUserInfo}
	
	set theThreadScriptPath to (|scriptsFolderPath| of appInfoRecord) & "MenuBarAppleScriptThread.scpt"
	«event Cmd_Run_» {|CommandPath|:"/usr/bin/osascript", |ArgvList|:{theThreadScriptPath, |bundleIdentifier| of appInfoRecord, theThreadHandler, theThreadNumberStr}, |Handler|:"FinishThread" & theThreadHandler, |ThreadNumber|:theThreadNumber, |UserInfo|:theUserInfo}
end detachNewThread

on doThreadTest(theBundleIdentifier, theThreadNumberStr)
	try
		-- スレッドで実行されるハンドラ
		tell application id theBundleIdentifier
			-- 元のアプリケーションにtell
			set theUserInfo to «event DictGetV» {"ThreadUserInfo", theThreadNumberStr}
			«event DebugLog» {"UserInfo", theUserInfo}
			
			-- 時間がかかる処理など
			
			
			«event DictDelV» {"ThreadUserInfo", theThreadNumberStr} -- UserInfoを削除しておく
		end tell
		return "abc"
	on error msg
		«event DebugLog» "Thread Error"
		«event DebugLog» msg
	end
end doThreadTest

on doCommandResultFinishThreadTest(theOutputText, theErrorText, theTerminationStatus, theCommandRecord, theActiveAppRecord, theThisAppRecord)
	-- スレッド終了時に実行されるハンドラ
	-- theOutputTextの末尾には改行が付加されているようです。
	«event DebugLog» {"ThreadResult", theOutputText}
	«event DebugLog» theCommandRecord
end doCommandResultFinishThreadTest

特定のメニューが選択された時にハンドラを実行

例:ファイルメニューの保存がCmd + Sやメニューアイテムを選択して実行された時にハンドラを実行します。

doInitで返すレコードの値

{|AXNotificationList|:{{|AppName|:"Evernote", |Enable|:1, |NotificationList|:{{|Name|:"AXMenuItemSelected", |Enable|:1, |TargetList|:{"AXMenuBar", "", "AXTitle", "ファイル", "AXRole", "AXMenu", "AXTitle", "保存"}}}}}}

ハンドラ

on doAXMenuItemSelected(theAXAppRecord, theActiveAppRecord, theThisAppRecord)
	-- メニューが選択された
end doAXMenuItemSelected

アプリケーションを再度開いた時にダイアログで確認して終了する

GUIが全く無いアプリケーションに書いておくと終了できるようになります。

ハンドラ : ダイアログ

on doReOpen(theActiveAppRecord, theThisAppRecord)
	set theName to |name| of theThisAppRecord
	activate
	display dialog theName & "を終了します" buttons {"Cancel", "OK"} default button 2
	if the button returned of the result is "OK" then
		quit
	end if
end doReOpen

アプリケーションを再度開いた時にコンテキストメニューを表示する

メニューに終了とログイン時に自動的に起動する設定を表示しておけば、終了したり、その設定ができるようになります。

property

|AutoAddQuitMenuItem|:1, |AutoAddLaunchOnLoginMenuItem|:1, |AutoAddVersionMenuItem|:1,

ハンドラ : コンテキストメニュー

on doReOpen(theActiveAppRecord, theThisAppRecord)
	set theName to |name| of theThisAppRecord
	«event MBASHndl» {|ContextMenuItemList|:{theName}}
end doReOpen

アクティブなアプリケーションのフォーカスが当たっているTextAreaを操作する

テキストの取得、選択しているテキストの取得、テキストの選択、選択しているテキストへスクロール、指定したテキストへスクロールができます。

ハンドラ


on getFocusedUIElementText(theActiveAppRecord)
	-- ver.2012.12.25.00
	-- フォーカスが当たっているAXTextFieldかAXTextAreaのテキストを取得
	«event UIElSetE» {|name| of theActiveAppRecord, {"AXFocusedUIElement", ""}}
	set {theRole, theValue} to «event UIElGetV» {"AXRole", "AXValue"}
	if {"AXTextField", "AXTextArea"} does not contain theRole then
		return ""
	end if
	return theValue
end getFocusedUIElementText

on getFocusedUIElementSelectedText(theActiveAppRecord)
	-- ver.2012.12.25.00
	-- フォーカスが当たっているAXTextFieldかAXTextAreaの選択しているテキストを取得
	«event UIElSetE» {|name| of theActiveAppRecord, {"AXFocusedUIElement", ""}}
	set {theRole, theSelectedText} to «event UIElGetV» {"AXRole", "AXSelectedText"}
	if {"AXTextField", "AXTextArea"} does not contain theRole then
		return ""
	end if
	
	return theSelectedText
end getFocusedUIElementSelectedText

on focusedUIElementSelectText(theActiveAppRecord, theSelectText)
	-- ver.2012.12.31.00
	-- フォーカスが当たっているAXTextField、AXTextAreaの指定したテキストを選択する
	«event UIElSetE» {|name| of theActiveAppRecord, {"AXFocusedUIElement", ""}}
	set {theRole, theValue} to «event UIElGetV» {"AXRole", "AXValue"}
	if {"AXTextField", "AXTextArea"} does not contain theRole then
		return false
	end if
	
	set pos to offset of theSelectText in theValue
	if pos is 0 then
		return false
	end if
	
	set theLen to (count of theSelectText)
	set pos to pos - 1
	«event UIElSetV» {"AXSelectedTextRange", "pos=" & pos & " len=" & theLen}
	«event UIElSetV» {"AXVisibleCharacterRange", "pos=" & pos & " len=" & theLen}
	return true
end focusedUIElementSelectText


on focusedUIElementScrollToSelection(theActiveAppRecord)
	-- ver.2012.12.25.00
	-- フォーカスが当たっているAXTextAreaを選択しているテキストかカーソルがある位置にスクロールする
	«event UIElSetE» {|name| of theActiveAppRecord, {"AXFocusedUIElement", ""}}
	set {theRole, theRange} to «event UIElGetV» {"AXRole", "AXSelectedTextRange"}
	if theRole is not "AXTextArea" then
		return
	end if
	
	«event UIElSetV» {"AXVisibleCharacterRange", theRange}
end focusedUIElementScrollToSelection

on focusedUIElementScrollToText(theActiveAppRecord, theSelectText)
	-- ver.2012.12.25.00
	-- AXTextAreaで指定したテキストを表示するようにスクロールする。
	-- テキストが複数ある場合は最初のものが対象になる
	«event UIElSetE» {|name| of theActiveAppRecord, {"AXFocusedUIElement", ""}}
	set {theRole, theVisibleCharacterRange, theValue} to «event UIElGetV» {"AXRole", "AXVisibleCharacterRange", "AXValue"}
	if theRole is not "AXTextArea" then
		return ""
	end if
	
	set pos to offset of theSelectText in theValue
	if pos is 0 then
		return "no text"
	end if
	
	set {theVPos, theVLen} to my rangeTextToList(theVisibleCharacterRange)
	
	if theVPos ≤ pos and pos ≤ (theVPos + theVLen) then
		-- すでに画面に表示されている場合はスクロールしない
		return "visible"
	end if
	
	«event UIElSetV» {"AXVisibleCharacterRange", "pos=" & pos & " len=1"}
	return "scroll"
end focusedUIElementScrollToText

on rangeTextToList(theRange)
	-- ver.2012.12.25.00
	set {thePos, theLen} to «event TextRegx» {"capture", "pos=([0-9]+) len=([0-9]+)", theRange, {1, 2}}
	set thePos to thePos + 1 -- AppleScriptは1ベースなので
	return {thePos, theLen}
end rangeTextToList

指定したアプリケーションのフォーカスが当たっているUIElementのテキストを可能な限り取得する

AXTextField,AXTextArea,AXWebAreaなどが取得できます。

クリップボード、サービスを使わずにかなりの状況でテキストを取得できると思います。


-- 指定したアプリケーションのフォーカスが当たっているUI Elementのテキストを取得
if 1 is «event UIElSetE» {"Evernote", {"Attr", "AXFocusedUIElement"}} then
	set {theRole, theAllText, theSelectedText, theSelectedRangeList, theInsertionWord, theInsertionLine, theTerm} to my getUIElementText("Evernote", "InsertionWord")
end


on getUIElementText(theGetOption)
	-- ver.2013.01.30.00	
	
	-- UIElの選択しているテキストなどを取得する
	-- "AXTextField", "AXTextArea", "AXWebArea" などから取得できる
	
	-- theAppName : 対象のアプリケーション名 英語名で指定
	
	-- theGetOption :
	-- "InsertionWord"で挿入部分の単語(同じ種類の文字の連続)と行を取得。対象が"GetOption"と繋がっている場合は"GetOption"を返します。
	-- "Term"で辞書サービスで単語を取得 。単語を取得します。対象が"GetOption"と繋がっていても"Get"や"Option"を返します。
	-- 複数指定する場合ははスペースで繋げる
	--  ""で未指定
	
	-- 注意
	-- AXWebAreaはテキストを選択している場合、theSelectedRangeListがちゃんと取得できない場合がある。
	-- その為、 theInsertionWord, theInsertionLineもちゃんと取得できない場合がある
	
	-- 使い方
	-- set {theRole, theAllText, theSelectedText, theSelectedRangeList, theInsertionWord, theInsertionLine, theTerm} to my getUIElementText("InsertionWord Term")
	
	-- theInsertionWordはカーソル位置の文字の英数字、ひらがな、カタカナ、漢字の連続した部分です。
	
	tell me
		try
			set theRole to missing value
			set theAllText to missing value
			set theSelectedText to missing value
			set theSelectedRangeList to missing value
			set theInsertionWord to ""
			set theInsertionLine to ""
			set theTerm to missing value
			
			set {theRole} to «event UIElGetV» {"AXRole"}
			
			if theRole is "AXWebArea" then
				«event UIElVal_» {"AXTextMarkerRangeForUIElement", "UIEl", "AllTextMarkerRange"}
				set theAllText to «event UIElVal_» {"AXStringForTextMarkerRange", "AllTextMarkerRange", ""}
				
				«event UIElVal_» {"AXSelectedTextMarkerRange", "", "SelectedTextMarkerRange"}
				set theSelectedText to «event UIElVal_» {"AXStringForTextMarkerRange", "SelectedTextMarkerRange", ""}
				
				set theBounds to «event UIElVal_» {"AXBoundsForTextMarkerRange", "SelectedTextMarkerRange", ""} -- ,
				if theBounds is not missing value then
					set {theX, theY, theWidth, theHeight} to «event TextRE__» {"capture", theBounds, "x=(-?\\d+) y=(-?\\d+) w=(-?\\d+) h=(=?\\d+)", {1, 2, 3, 4}}
					
					«event UIElVal_» {"AXTextMarkerForPosition", "x=" & theX & " y=" & theY, "StartSelectionTextMarker"}
					«event UIElVal_» {"AXStartTextMarker", "", "StartTextMarker"}
					«event UIElVal_» {"AXTextMarkerRangeForUnorderedTextMarkers", {"StartTextMarker", "StartSelectionTextMarker"}, "StartToStartSelectionMarkerRange"} -- ,
					
					set StartToStartSelectionText to «event UIElVal_» {"AXStringForTextMarkerRange", "StartToStartSelectionMarkerRange", ""}
					set theSelectedRangeList to {1 + (count of StartToStartSelectionText), count of theSelectedText}
				else
					set theSelectedRangeList to missing value
				end if
			else
				set {theAllText, theSelectedText, theSelectedTextRange} to «event UIElGetV» {"AXValue", "AXSelectedText", "AXSelectedTextRange"}
				
				if theSelectedTextRange is not missing value then
					set {thePos, theLen} to «event TextRE__» {"capture", theSelectedTextRange, "pos=(-?\\d+) len=(-?\\d+)", {1, 2}}
					set theSelectedRangeList to {thePos + 1, theLen}
				end if
			end if
			
			
			
			if ((theGetOption contains "Insertionword") or (theGetOption contains "Term")) and (theAllText is not missing value) and (theAllText is not "") and (theSelectedRangeList is not missing value) then
				set theAllTextLen to count of theAllText
				set theSelPos to (item 1 of theSelectedRangeList)
				
				if (item 2 of theSelectedRangeList) > 0 then
					set theSelPos to theSelPos + (item 2 of theSelectedRangeList) - 1
				end if
				
				if theSelPos < 1 then
					set theSelPos to 1
				end if
				
				if theSelPos > theAllTextLen then
					set theSelPos to theAllTextLen
				end if
				
				if (theGetOption contains "Term") then
					set {theTerm, theRange} to «event DicSTerm» {theAllText, theSelPos}
				end if
				
				
				if (theGetOption contains "insertionword") then
					set theInsertionWord to text theSelPos of theAllText
					
					set theGetLineRegex to "([^\\n\\r]+)"
					set theRegexList to {theGetLineRegex, "([-_A-Za-z0-9]+)", "(\\p{Hiragana}+)", "([\\p{Katakana}ー]+)", "(\\p{Han}+)"}
					repeat with theRegexItem in theRegexList
						set theRegex to contents of theRegexItem
						if (1 is («event TextRE__» {"isMatched", theInsertionWord, theRegex})) then
							
							if theSelPos > 1 then
								set theText to text 1 thru (theSelPos - 1) of theAllText
								set theText to «event TextRE__» {"capture", theText, theRegex & "\\z", 1}
								if theText is not missing value then
									set theInsertionWord to theText & theInsertionWord
								end if
							end if
							
							if theSelPos < theAllTextLen then
								set theText to text (theSelPos + 1) thru -1 of theAllText
								set theText to «event TextRE__» {"capture", theText, "^" & theRegex, 1}
								if theText is not missing value then
									set theInsertionWord to theInsertionWord & theText
								end if
							end if
							
							if theRegex is theGetLineRegex then
								set theInsertionLine to theInsertionWord
								set theInsertionWord to text theSelPos of theAllText
							else
								exit repeat
							end if
						else if theRegex is theGetLineRegex then
							-- 前の行を取得
							if theSelPos > 1 then
								set theText to text 1 thru (theSelPos - 1) of theAllText
								set theText to «event TextRE__» {"capture", theText, theRegex & "\\z", 1}
								if theText is not missing value then
									set theInsertionLine to theText
								end if
							end if
						end if
					end repeat
				end if
			end if
		on error
			set theRole to missing value
			set theAllText to missing value
			set theSelectedText to missing value
			set theSelectedRangeList to missing value
			set theInsertionWord to ""
			set theInsertionLine to ""
			set theTerm to missing value
		end try
		return {theRole, theAllText, theSelectedText, theSelectedRangeList, theInsertionWord, theInsertionLine, theTerm}
	end tell
	
end getUIElementText

Finderの選択している項目が変わった時に処理をする

選択しているものが変わったことはわかりますが、何を選択しているかは通知ではわからないのでselectionで調べて下さい。

property

|AXNotificationList|:{{|AppName|:"Finder", |NotificationList|:{{|Name|:"AXSelectedRowsChanged", |Target|:"*"}, {|Name|:"AXSelectedChildrenChanged", |Target|:"*"}}}}

ハンドラ


on doAXSelectedChildrenChanged(theAXAppRecord, theActiveAppRecord, theThisAppRecord)
	-- アイコン表示で選択した項目が変わった。選択したファイルはFinderのselectionで取得します。
	-- ファイル以外のものを選択した場合も実行されると思うので、選択したファイルが変わっているか調べる等して下さい
	my FinderSelectionChanged()
end doAXSelectedChildrenChanged

on doAXSelectedRowsChanged(theAXAppRecord, theActiveAppRecord, theThisAppRecord)
	-- リスト表示で選択した項目が変わった。選択したファイルはFinderのselectionで取得します。
	-- ファイル以外のものを選択した場合も実行されると思うので、選択したファイルが変わっているか調べる等して下さい
	my FinderSelectionChanged()
end doAXSelectedRowsChanged

on FinderSelectionChanged()
	try
		tell application "Finder"
			set theSelectionAliasList to selection as alias list
		end tell
	on error
		return
	end try
	
	repeat with theAlias in theSelectionAliasList
		-- 処理をする
	end repeat
end FinderSelectionChanged

FSEventでフォルダの変更を調べる

アプリケーションに返すレコードの値

doInit以外でもOK

|FSEventFolderList|:{"/path/to/check/folder/"}

ハンドラ


on doFSEvent(theEventPathList, theActiveAppRecord, theThisAppRecord)
 -- 変更があった
end

JavaScriptとの連携

"CalSearch"を好きな名前に変えて下さい。

JavaScriptからMenuBarAppleScriptのハンドラを実行

次のJavaScriptでブラウザで動作確認できます。

var result = "";
if( window.MenuBarAppleScript )
{
	result = window.MenuBarAppleScript.runHandler("CalSearch","MenuBarAppleScriptに渡す値");
	// 文字列、数値、リストを渡すことができます
	//result = window.MenuBarAppleScript.runHandler("Sample",[ 1, 2, [ "a", "b" ] ] );
	// AppleScript側ではtheValueが { 1, 2, { "a", "b" } } になります。
}
else
{
	result = "hoge";	// ブラウザで動作確認用のresult
}

// HTMLの状態はLocal Storageでセーブ、ロードできます。
var settingA =localStorage.getItem('settingA'); -- ロード
localStorage.setItem('settingA', $(this).val()); -- セーブ

JavaScriptから実行されたハンドラ

on doHandlerFromJavaScriptCalSearch(theValue, theActiveAppRecord, theThisAppRecord)
	--	«event DebugLog» {"doHandlerFromJavaScriptCalSearch"}

	-- 処理をする
	set theResult to "結果"
	
	return {|Result|:theResult} -- JavaScriptに返す値
	return {|Result|: { theResult, 1, 2 } } -- リストを返すとJavaScriptでは配列になります

end doHandlerFromJavaScriptCalSearch

WebViewWindowを表示、作るハンドラ


property theWindowName : "ウインドウ名"

on showWindow(theActiveAppRecord, theThisAppRecord)
	-- ウインドウが無ければ作成して表示、あればそれを表示
	if (|allWebViewWindowNameList| of theThisAppRecord) does not contain theWindowName then
		my makeWindow(theActiveAppRecord, theThisAppRecord)
	end if
	«event Win_Show» theWindowName
end showWindow

on hideWindow(theActiveAppRecord, theThisAppRecord)
	«event Win_Hide» theWindowName
end hideWindow

on makeWindow(theActiveAppRecord, theThisAppRecord)
	set theHTMLURL to (|resourcesFolderURL| of theThisAppRecord) & "datepicker/index.html"
	
	«event MBASHndl» {|WebViewWindow|:{|URL|:theHTMLURL, |Name|:theWindowName, |Title|:theWindowName, |Visible|:0, |Activate|:0, |Width|:228, |Height|:400, |Delete|:0, |AllowsScrolling|:0, |Alpha|:1.0, |Opaque|:0, |Level|:"FloatingWindowLevel", |StyleList|:{"Titled", "Utility", "Closable", "HUD"}, |CanHide|:1, |HasShadow|:1, |AcceptsFirstMouse|:1}}
end makeWindow

WebViewWindowでページの読み込み完了まで待ってJavaScriptを実行

doDidFinishLoadForFrameでページの読み込み完了時に処理をできますが、この場合処理が分離されるので、JavaScriptでページの値を取得してそれを処理をする場合などはすごい面倒になります。

そこで、ページの読み込み完了まで待ってJavaScriptを実行するサンプルです。


	set theTmpWindowName to "tmp"
	set theURL to "http://tv.yahoo.co.jp/listings/"
	-- 画像やプラグインをオフにしておくと読み込みがちょっと早いと思う
	-- ただし、一度オフにするとずっとオフになるので次にウインドウを作る時は
	-- |LoadsImagesAutomatically|:1, |PlugInsEnabled|:1, |JavaEnabled|:1
	-- を必要に応じてウインドウ作成時に指定して下さい。
	«event MBASHndl» {|WebViewWindow|:{|Name|:theTmpWindowName, |URL|:theURL, |Width|:512, |Height|:512, |Visible|:0, |LoadsImagesAutomatically|:0, |PlugInsEnabled|:0, |JavaEnabled|:0}}
	repeat 100 times
		delay 0.2
		if 0 is («event WebVUtil» {theTmpWindowName, "isLoading"}) then
			exit repeat
		end if
	end repeat
	
	set theJavaScript to "
	var text = '';
	var result = document.evaluate('id(\"ListingsHeader\")//td[@class=\"station\"]//a//text()', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for(var i=0;i<result.snapshotLength;i++){
	var node = result.snapshotItem(i);
	text += node.textContent + '<>';
}
return text;
"
	
	-- return で値を返せるように囲っておく
	set theJavaScript to "(function(){" & theJavaScript & ";})();"
	
	set theChannel to «event WebVUtil» {theTmpWindowName, "doJavaScript", theJavaScript}
	
	-- XPath 例2
	set theJavaScript to "
	var text = '';
	var result = document.evaluate('id(\"ListingsMargin\")/following-sibling::*[1][local-name()=\"table\"]/tbody/tr[1]//td', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for(var i=0;i<result.snapshotLength;i++){
	var node = result.snapshotItem(i);
	text += node.innerText + '<>';
}

return text;
"
	set theJavaScript to "(function(){" & theJavaScript & ";})();"
	
	set theInfo to «event WebVUtil» {theTmpWindowName, "doJavaScript", theJavaScript}


	«event MBASHndl» {|WebViewWindow|:{|Name|:theTmpWindowName, |Delete|:1 } } 

«event UIElSetE»のレシピ

«event UIElSetE»で処理対象を指定するサンプルです。

フォーカスが当たっているUI Elementを対象とする
«event UIElSetE» {"AppleScript Editor", {"Attr", "AXFocusedUIElement"}}
基本でよく使います
テキスト編集中ならAXTextArea、AXWebAreaなどになります。
アクティブなウインドウのAXWebAreaを探して対象とする
«event UIElSetE» {"Safari", {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXRole", "AXWebArea"}}
AnyRoleを使うとAXWebAreaがどのAXGroupのどのAXSplitGroupに入っているなどを知らなくてもAXWebAreaを取得できます。
普通にAppleScriptのGUIスクリプティングでAXWebViewを指定しようとすると、Safari,Evernote,Mail,Dictionaryなどすべて指定方法が違いますが、AnyRoleを使った上記記述法で書くとアプリケーション名を変えるだけでほぼすべてのアプリケーションで同じスクリプトでウインドウに表示されているAXWebAreaを指定できます。
アクティブなウインドウの"ノートリスト"という名前のAXTableを探して対象とする
«event UIElSetE» {"Evernote", {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXRole AXTitle", "^AXTable \\Qノートリスト\\E$"}}
上のAXWebAreaと同じですが、探しているタイプのUI Elementが複数あり、タイトルで指定したい場合。
タイトルを\\Qと\\Eで囲っているのは探しているタイトルに正規表現のメタ文字がある場合に備えてです。
UIElがテーブルの時に、AppleScriptというテキストを表示しているAXRowを探して対象とする
«event UIElSetE» {"Evernote", {"UIEl", "", "AXRole", "AXRow", "AXRole AXValue", "^AXTextField \\QAppleScript\\E$", "Attr", "AXParent"}}
AttrでAXParentを取得すると一度子まで調べてその親を対象に出来ます。
UIElがAXOutlineの時に閉じているフォルダを開く
«event UIElSetE» {"Evernote", {"UIEl", "", "AXRole", "AXRow", "AXRole", "AXGroup", "AXRole AXValue", "AXDisclosureTriangle 0", "PerformAction", "AXPress"}}
探した閉じているフォルダのAXRowに対してPerformActionでAXPressを送って展開させています。

«event UIElSetE»でGUI操作ハンドラ

«event UIElSetE»でGUIを操作するハンドラです。どのAXGroupやAXScrollAreaに入っているかなどは指定する必要がなくて、タイトルなどそのUI Elementの属性で指定できます。



set theAppName to "System Preferences"
my setSliderValue(theAppName, "AXDescription", "Dock のサイズつまみ", 0.1)
my clickMenuItem(theAppName, "アーカイブ")
my selectPopupButton(theAppName, "AXValue", "(スケール|ジニー)", "ジニーエフェクト")
my clickButton(theAppName, "プロファイルを開く")
my setCheckAndRadioButtonValue(System, "拡大:", 1)
my selectTab("System Preferences", "AXValue", ".*(設定|コマンド).*", "設定")
	
on selectTab(theAppName, theTargetTabAttr, theTargetTabValue, theSelectTabTitle)
	-- ver.2013.01.06.00
	tell me
		if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXRole " & theTargetTabAttr, "AXTabGroup " & theTargetTabValue & "", "Attr", "AXTabs", "FindSelf", "", "AXTitle", "^\\Q" & theSelectTabTitle & "\\E$", "PerformAction", "AXPress"}}) then
			return true
		end if
		return false
	end tell
end selectTab

on setSliderValue(theAppName, theTargetSliderAttr, theTargetSliderValue, theValue)
	-- ver.2013.01.09.00
	tell me
		if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXRole " & theTargetSliderAttr, "^AXSlider \\Q" & theTargetSliderValue & "\\E$"}}) then
			«event UIElSetV» {"AXValue", theValue}
			return true
		end if
		return false
	end tell
end setSliderValue

on setCheckAndRadioButtonValue(theAppName, theButtonTitle, theValue)
	-- ver.2013.01.06.00
	-- 1でオン、0でオフ
	tell me
		if theValue is 1 then
			set theCurrentValue to "0"
		else
			set theCurrentValue to "1"
		end if
		if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXRole AXValue AXTitle", "^(AXCheckBox|AXRadioButton) " & theCurrentValue & " \\Q" & theButtonTitle & "\\E$", "PerformAction", "AXPress"}}) then
			return true
		end if
		
		return false
	end tell
end setCheckAndRadioButtonValue

on clickButton(theAppName, theButtonTitle)
	if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXTitle", "^\\Q" & theButtonTitle & "\\E$", "PerformAction", "AXPress"}}) then
		return true
	end if
	
	return false
end clickButton

on selectPopupButton(theAppName, theTargetPopupAttr, theTargetPopupValue, theSelectTitle)
	-- ver.2013.01.06.00
	tell me
		if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXFocusedWindow", "AnyRole", "(AXSplitGroup|AXGroup|AXScrollArea|AXTabGroup)", "AXRole " & theTargetPopupAttr, "AXPopUpButton " & theTargetPopupValue & "", "PerformAction", "AXPress"}}) then
			if 0 is not («event UIElSetE» {theAppName, {"UIEl", "", "AnyRole", "(AXMenu|AXMenuItem)", "AXTitle", "^\\Q" & theSelectTitle & "\\E$", "PerformAction", "AXPress"}}) then
				return true
			end if
		end if
		return false
	end tell
end selectPopupButton

-- 下のより «event UIElPAct» を使ったほうが動作が安定するようです。
on clickMenuItem(theAppName, theMenuItemTitle)
	-- ver.2013.07.28.00
	tell application theAppName to activate
	tell me
		if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXMenuBar", "AnyRole", "(AXMenu|AXMenuItem)", "AXRole AXEnabled AXTitle", "^AXMenuItem 1 \\Q" & theMenuItemTitle & "\\E$"}}) then
			«event UIElPAct» {"AXPress"}
			return true
		end if
		return false
	end tell
end clickMenuItem


-- «event UIElSetE» 1行で書く場合。指定したメニュー実行後にメニューが表示されるケースが有りました。
on clickMenuItem_2(theAppName, theMenuItemTitle)
	-- ver.2013.04.19.00
	tell application theAppName to activate
	tell me
		if 0 is not («event UIElSetE» {theAppName, {"Attr", "AXMenuBar", "AnyRole", "(AXMenu|AXMenuItem)", "AXRole AXEnabled AXTitle", "^AXMenuItem 1 \\Q" & theMenuItemTitle & "\\E$", "PerformAction", "AXPress"}}) then
			return true
		end if
		return false
	end tell
end clickMenuItem

WebViewで実行したJavaScriptの結果を確実に返す

JavaScriptの途中でreturnで値を返すとその結果を取得できない場合があります。それの対策にはスクリプトを次のようにします。

-- 実行したいJavaScript
set theJavaScript to "hoge(); if( ! hage ){ return 'fusafusa';} katsura();"

-- これでスクリプトを囲む
set theJavaScript to "(function(){" & theJavaScript & ";})();"

-- 実行する
set theResult to «event WebVJS__» {theWindowName, theJavaScript}  

DoAtTimeで指定時間にハンドラを実行する:自動繰り返し

DoAtTimeのサンプルです。

スリープから復帰時がややこしいですが、下記サンプルで細かいところまで対処できていると思います。あまり動作テストはしてませんが…。

スリープからの復帰時に気をつけることは、予定時間を過ぎていた、複数指定して複数の予定時間を過ぎていたです。下の例では、複数の予定時間を過ぎていた場合でも1回だけ処理を実行します。すべての予定時間分の処理を行う場合はDoOnlyFirstRunを0にする必要があります。

doInit

-- 好きな時間を登録する。いくつでもOK
«event MBASHndl» {|DoAtTime|:{|Handler|:"Hoge", |Time|:{|Hour|:8, |Minute|:0, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:1}}
«event MBASHndl» {|DoAtTime|:{|Handler|:"Hoge", |Time|:{|Hour|:13, |Minute|:30, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:1}}
«event MBASHndl» {|DoAtTime|:{|Handler|:"Hoge", |Time|:{|Hour|:19, |Minute|:0, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:1}}

ハンドラ

on doAtTimeHoge(theFireTimeDifference, theIsWake, theIsFirstRun, theSettingRecord, theActiveAppRecord, theThisAppRecord)
	-- «event DebugLog» {"doAtTimeHoge", theFireTimeDifference, theIsWake, theIsFirstRun}
	
	-- 処理でネットワークに接続する場合、スリープ解除直後は
	-- ネットワークに繋がっていない場合があるので
	-- 下記のようにして10秒程度後に実行させると確実に繋がると思います。
	if theIsWake is 1 
		-- 起きた直後は10秒後に実行
		«event MBASHndl» {|DoAfterSec|:{|Handler|:"Hoge", |Sec|:10}}
	else
		-- 上の10秒待ちの間に指定時間が更に来た場合にハンドラを
		-- 直接実行しないでDoAfterSecですぐに実行するようにしておくと
		-- 10秒のはキャンセルされて0.01秒後に実行される。
		«event MBASHndl» {|DoAfterSec|:{|Handler|:"Hoge", |Sec|:0.01}}
	end if
	
	-- ネットに繋がない場合は上のようなめんどくさいことはしなくて
	-- したいことを直接書いてOK
	-- my hoge() 

end doAtTimeHoge

on doAfterSecHoge(theUserInfo, theActiveAppRecord, theThisAppRecord)
	-- スリープから復帰時の遅延実行用
	
	my hoge() -- したいこと
	
end doAfterSecHoge

DoAtTimeで指定時間にハンドラを実行する:手動繰り返し

DoAtTimeのサンプルです。

スリープから復帰時がややこしいですが、下記サンプルで細かいところまで対処できていると思います。動作テストはしてませんが…。

doInit

-- 好きな時間を登録する。いくつでもOK
«event MBASHndl» {|DoAtTime|:{|Handler|:"Hoge", |Time|:{|Hour|:8, |Minute|:0, |Second|:0}}}
«event MBASHndl» {|DoAtTime|:{|Handler|:"Hoge", |Time|:{|Hour|:13, |Minute|:30, |Second|:0}}}
«event MBASHndl» {|DoAtTime|:{|Handler|:"Hoge", |Time|:{|Hour|:19, |Minute|:0, |Second|:0}}}

ハンドラ

on doAtTimeHoge(theFireTimeDifference, theIsWake, theIsFirstRun, theSettingRecord, theActiveAppRecord, theThisAppRecord)
	-- «event DebugLog» {"doAtTimeHoge", theFireTimeDifference, theIsWake, theIsFirstRun}
	
	-- 繰り返すので再登録
	«event MBASHndl» {|DoAtTime|:theSettingRecord}
	
	-- 同じハンドラでDoAtTimeをいくつか登録した時にスリープして、
	-- 指定時間をいくつか過ぎた場合、
	-- スリープから起きた時に全部ハンドラが実行されるが1回だけ処理したい場合は
	-- 下記のように調べる。
	-- 起きている時に実行される時もtheIsFirstRunは1なので実行される。
	if theIsFirstRun is 1 then
		-- 処理でネットワークに接続する場合、スリープ解除直後は
		-- ネットワークに繋がっていない場合があるので
		-- 下記のようにして10秒程度後に実行させると確実に繋がると思います。
		if theIsWake is 1 
			-- 起きた時10秒後に実行
			«event MBASHndl» {|DoAfterSec|:{|Handler|:"Hoge", |Sec|:10}}
		else
			-- 上の10秒待ちの間に指定時間が更に来た場合にハンドラを
			-- 直接実行しないでDoAfterSecですぐに実行するようにしておくと
			-- 10秒のはキャンセルされて0.01秒後に実行される。
			«event MBASHndl» {|DoAfterSec|:{|Handler|:"Hoge", |Sec|:0.01}}
		end if
		
		-- ネットに繋がない場合は上のようなめんどくさいことはしなくて
		-- したいことを直接書いてOK
		-- my hoge() 

	end if
	
end doAtTimeHoge

on doAfterSecHoge(theUserInfo, theActiveAppRecord, theThisAppRecord)
	-- スリープから復帰時の遅延実行用
	
	my hoge() -- したいこと
	
end doAfterSecHoge

HTMLで作成した画像をメニューバーアイコンに設定する

アプリケーションアイコンの上に文字を重ねた画像をメニューバーアイコンにしたいと思ったのでやってみました。

下で使っているIconMaker.htmlの例:IconMaker.html

IconMaker.htmlを好きなように変更してMenuBarAppleScriptアプリケーション内部のResourcesフォルダに入れて下さい。

property

property theMenuBarItemImage : "mbas:icon" -- MenuBarAppleScript内部に保存するアイコン画像の名前。"mbas:"から始める必要があります。

doInit

-- "IconMaker.html"で表示した内容をアイコンにする
set theHTMLPath to (|resourcesFolderPath| of theThisAppRecord) & "IconMaker.html"
«event MBASHndl» {|WebViewWindow|:{|Name|:"IconMaker", |URL|:theHTMLPath, |Visible|:0, |DrawsBackground|:0}}

doInitで返すレコードの値

画像のみを表示する場合に必要

{|PriorityToMenuBarItemImage|:1}

ハンドラ

on doDidFinishLoadForFrame(theWindowName, theActiveAppRecord, theThisAppRecord)
	if theWindowName is "IconMaker" then
		-- 画像でMenuBarAppleScript内部に保存
		«event SW2PsPDF» {theMenuBarItemImage, "screen", "", theWindowName} 
		-- 保存した画像をメニューバーアイコンに設定して、ウインドウを削除
		«event MBASHndl» {|RemoveMenuBarItem|:1, |MenuBarItemImage|:theMenuBarItemImage, |WebViewWindow|:{|Name|:theWindowName, |Delete|:1}}
	end if
end doDidFinishLoadForFrame

アプリケーションにホットキー(ショートカットキー)を付ける

doInit

on doInit(theActiveAppRecord, theThisAppRecord)
	-- キーは小文字で指定する。shift + キーの場合、大文字で指定する。
	-- 修飾キー無しもできます
	return {|AppHotKeyList|:{{|Name|:"Save", |KeyChar|:"s", |ModifierKeyList|:{"command"}, |Enable|:1}, {|Name|:"Close", |KeyChar|:"w", |ModifierKeyList|:{"command"}, |Enable|:1}}}
end doInit

ハンドラ

on doAppHotKeySave(theActiveAppRecord, theThisAppRecord)
	-- 何か保存する処理
end doAppHotKeySave

on doAppHotKeyClose(theActiveAppRecord, theThisAppRecord)
	my hideWindow(theActiveAppRecord, theThisAppRecord)
end doAppHotKeyClose

scrollWheelMenuBarItemの使用例

この機能は1.3.1で無効になっています。

ハンドラ



on doScrollWheelMenuBarItem(theDeltaX, theDeltaY, theActiveAppRecord, theThisAppRecord)
	-- トラックパッドでスクロールした時にはイベントがたくさん来る
	-- イベントが終わったと思われるときに一回だけ実行するにはDoAfterSecで遅延実行を使うと簡単にできる
	--«event DebugLog» {"doScrollWheelMenuBarItem", theDeltaX, theDeltaY}
	-- Deltaは上、左が正の数、下、右が負の数	
	-- 遅延時間が多いと反応が遅くなるので適切な値に調整して下さい
	return {|DoAfterSec|:{|Handler|:"ScrollWheel", |Sec|:0.35, |UserInfo|:{theDeltaX, theDeltaY}}}
end doScrollWheelMenuBarItem

on doAfterSecScrollWheel(theUserInfo, theActiveAppRecord, theThisAppRecord)
	set theDeltaX to item 1 of theUserInfo
	set theDeltaY to item 2 of theUserInfo
	--«event DebugLog» {"doAfterSecScrollWheel", theDeltaX, theDeltaY}
	if theDeltaY ≥ 1 then
		-- 上
		say "up"
	else if theDeltaY ≤ -1 then
		-- 下
		say "down"
	else if theDeltaX ≥ 1 then
		-- 左
		say "left"
	else if theDeltaX ≤ -1 then
		-- 右
		say "right"
	end if
end doAfterSecScrollWheel

doHTTPResponseの使用例

フォルダ内のファイル一覧を返す例

ハンドラ


on startHTTPServer(theActiveAppRecord, theThisAppRecord)
	set theResult to «event HTTPSevr» {"start", {|Port|:50208, |DocumentRoot|:"~/", |DirectoryIndexFileNames|:{}, |User|:"", |Password|:""}}
	if theResult is not 1 then
		activate
		beep
		display alert "サーバーの起動に失敗しました。アプリケーションを終了します。" & return & theResult
		«event MBASHndl» {|Quit|:1}
	end if
	
	-- set theThisAppRecord to «event InfoTApp»
	-- do shell script "open " & quoted form of HTTPServerURL of theThisAppRecord
end startHTTPServer

on doHTTPResponse(theRequestPath, theDocumentFilePath, theMethod, theActiveAppRecord, theThisAppRecord)
	«event DebugLog» {theRequestPath, theDocumentFilePath, theMethod}
	
	if theDocumentFilePath ends with "/" then
		if theRequestPath does not end with "/" then
			set theRequestPath to theRequestPath & "/"
		end if
		
		-- パスに '' が含まれていると駄目です
		
		set theTemplate to "
	<html>
	<head>
	<title>{{ folder | html }}</title>
	</head>
	<body>

	<h1>{{ folder | html }}</h1>
	<a href='{{ parentFolder | html }}'>UP</a>
	<ol>
	{% for path in paths %}
	<li><a href='{{ parentPath }}{{ path }}'>{{ path | html }}</a></li>
	{% /for %}
	</ol>
	</body>
	</html>
"
		
		set theParentFolderPath to «event TextPath» {"stringByDeletingLastPathComponent", theRequestPath}
		
		set theList to «event TextPath» {"contentsOfDirectory", theDocumentFilePath, {"SkipsHiddenFiles", "AddSlashToFolder"}}
		
		if theRequestPath is "/" then
			set theParentPath to ""
		else
			set theParentPath to theRequestPath
		end if
		
		set theValue to {|folder|:theDocumentFilePath, |parentPath|:theParentPath, paths:theList, |parentFolder|:theParentFolderPath}
		set theHTML to «event TextUtil» {"MGTemplateEngine", theTemplate, theValue}
		
		return {|HTTPResponse|:{|HTML|:theHTML, cache:0}}
	else
		return {|HTTPResponse|:{|File|:theDocumentFilePath}}
	end if
end doHTTPResponse

MGTemplateEngineのテンプレート例


-- リスト
set theTemplate to "
	<h1>{{ title | html }}</h1>
	<p>{{ note | html }}</p>
	<ol>
	{% for item in items %}
		<li>{{ item | html }}</li>
	{% /for %}
	</ol>
"

set theTitle to "<リストのサンプル>"
set theNote to "リストをHTMLのリストに変換"

set theItemList to {}
set end of theItemList to "黒"
set end of theItemList to "猫"
set end of theItemList to "白"
set end of theItemList to "犬"

set theValueRecord to {|items|:theItemList, title:theTitle, |note|:theNote}

set theHTML to «event TextUtil» {"MGTemplateEngine", theTemplate, theValueRecord, {}, {|OpenHTML|:0, |Browser|:"Safari", |OpenText|:0, |Editor|:"mi", |Activate|:0, |Name|:"Test"}}


-- レコード
set theTemplate to "
	<h1>{{ title | html }}</h1>
	<p>{{ note | html }}</p>
	<table>
		<tr>
			<th>{{ label.Name | html }}</th>
			<th>{{ label.Kind | html }}</th>
			<th>{{ label.Age }}</th>
		</tr>
	{% for item in items %}
		<tr>
			<td>{{ item.Name | html }}</td>
			<td>{{ item.Kind | html }}</td>
			<td>{{ item.Age }}</td>
		</tr>
	{% /for %}
	</table>
"

set theTitle to "<テーブルのサンプル>"
set theNote to "レコードのリストをテーブルに変換。キーに'name'を使用したらMGTemplateEngineのキーワードのようで表示されませんでした。その為'Name'にしました。"

set theLabel to {|Name|:"名前", |Kind|:"種類", Age:"年齢"}

set theItemList to {}
set end of theItemList to {|Name|:"ミケ", |Kind|:"ねこ", Age:10}
set end of theItemList to {|Name|:"ポチ", |Kind|:"イヌ", Age:2}
set end of theItemList to {|Name|:"たまちゃん", |Kind|:"あざらし", Age:7}
set end of theItemList to {|Name|:"マイケル", |Kind|:"ねこ", Age:15}

set theValueRecord to {|items|:theItemList, label:theLabel, title:theTitle, |note|:theNote}

set theHTML to «event TextUtil» {"MGTemplateEngine", theTemplate, theValueRecord, {}, {|OpenHTML|:0, |Browser|:"Safari", |OpenText|:0, |Editor|:"mi", |Activate|:0, |Name|:"Test"}}

新しいバージョンのアプリケーションがリリースされているかチェックする

property

-- バージョンチェックの間隔
property theAppVersionCheckIntervalSec : days * 7
-- バージョン情報が記載されたJSONのURL
property theAppVersionJSONURL : "https://googledrive.com/host/0B7jmDxmCrfK0UUJub1p6NnAxcGc/version.js"

doInitで返すレコードの値

|VersionCheck|:{|URL|:theAppVersionJSONURL, |Interval|:theAppVersionCheckIntervalSec}},

バージョンを記載したJSONを作るAppleScript

theAppVersionJSONURLで参照するファイルを作るAppleScriptです。

MenuBarAppleScriptの機能で作っています。

ファイルの書き出しにdo shell scriptを使ったら、エスケープされた改行が解除されて動かなくなったので、AppleScriptの命令を使用しています。

commentdisplay dialogでそのまま表示されます。改行したい場合はreturnでつないで下さい。

property theHistoryJSPath : "/Users/hage/Sites/foo/version.js"

tell application "MenuBarAppleScript"
	«event DictDelV» {"tmp", "version"}
	
	-- ここにアプリケーション名とバージョン、URL、コメントを書いていく
	«event DictDict» {"tmp", "version", "setObjectForKey", {|version|:"1.4.1", |url|:"http://memogakisouko.appspot.com/MenuBarAppleScript.html", comment:"・いろいろ機能を追加"}, "MenuBarAppleScript"}
	
	«event DictDict» {"tmp", "version", "setObjectForKey", {|version|:"1.4.1", |url|:"http://memogakisouko.appspot.com/MenuBarAppleScript.html#AppleScriptEditorHelper", comment:"・MenuBarAppleScript1.4.1の用語に対応"}, "AppleScriptEditorHelper"}
	
	set theValue to «event DictGetV» {"tmp", "version"}
	
	set theJSONText to «event TextUtil» {"writeJSON", theValue}
	«event TextUtil» {"writeToFile", theHistoryJSPath, theJSONText}
	quit
end tell

指定時間、スリープ復帰時になどを考慮した一定間隔で処理をするサンプル

-- 指定時間、スリープ復帰時、一定時間間隔に処理をする -- いくつかハンドラがありますが処理自体はdoIdleで行いますのでdoIdleにしたい処理を書きます property theUpdateIntervalSec : hours * 2.0 -- 更新間隔。この秒数間隔で処理を定期的に実行 on doInit(theActiveAppRecord, theThisAppRecord) -- 例:0時5分に日が変わった時の処理をする «event MBASHndl» {|DoAtTime|:{|Handler|:"NextDay", |Time|:{|Hour|:0, |Minute|:5, |Second|:0}, |Repeat|:1, |DoOnlyFirstRun|:0}} -- idleとdidWakeを登録 return {|IdleSec|:theUpdateIntervalSec, |NSWorkspaceNotificationList|:{"NSWorkspaceDidWakeNotification"}} end doInit on doNSWorkspaceDidWakeNotification(theNotificationName, theObject, theUserInfo, theActiveAppRecord, theThisAppRecord) -- «event DebugLog» "NSWorkspaceDidWakeNotification" -- スリープから復帰後に更新したいけどwifi再接続に時間がかかる場合あるのでちょっと後に更新 -- IdleSecは上書き可能なのでこれでOK return {|IdleSec|:20} end doNSWorkspaceDidWakeNotification on doAtTimeNextDay(theFireTimeDifference, theIsWake, theIsFirstRun, theSettingRecord, theActiveAppRecord, theThisAppRecord) «event DebugLog» {"doAtTimeHoge", theFireTimeDifference, theIsWake, theIsFirstRun} if theIsWake is 1 then -- wake時はdidWakeで処理しているので何もしない else -- 直接実行しないでこれでdoIdleを呼ぶようにすると、 -- 通常のdoIdleやNSWorkspaceDidWakeNotificationがほぼ同時に実行される場合に -- それらをキャンセルして一回だけ実行されるようにできる。 return {|IdleSec|:20} -- チャイムを時間ピッタリに鳴らすなどの場合はここで直接実行するか0.01を返すなどにして下さい end if end doAtTimeNextDay on doIdle(theActiveAppRecord, theThisAppRecord) -- ここで一定間隔&ほぼ指定時間&スリープ復帰時にしたい処理を実行 my hoge() return {|IdleSec|:theUpdateIntervalSec} end doIdle

メモ

デバッグ方法

基本

AppleScriptエディタで実行してイベントログを確認する方法

通常のスクリプト同じようにイベントログを確認しながらデバッグするには次のようにします。

下記画像の設定をオンにします
MenuBarAppleScriptの名前等の初期設定をすると自動的にアプリケーションがライブラリに登録されるので登録されているか確認します。未登録の場合は、MenuBarAppleScriptが最新バージョンか確認して、再設定して下さい。
デバッグしたいスクリプトを下記スクリーンショットの様にします。このメニューにアプリケーションが表示されない場合は、一つ前のステップに戻って下さい。
ここまでで設定完了であとは実行すればMenuBarAppleScriptの機能を使ったり、実行中のアプリケーションの状態を取得、設定できるようになります。
10.8では実行時に下記ダイアログが表示されますが、「スクリプトを実行」を押して下さい。
実行した時のスクリーンショット

Tips

FAQ - スクリプトを書く時の注意点

バグ

今後する機能追加するかもしれないこと

コメント

1.4.2

何故、他のスクリプト言語やアプリケーションやOSAX、そしてAppleScript自体でできる命令を追加しているのかというと、主に次の2つの理由です。

一つは配布する時に、他のソフトのインストール無しでMenuBarAppleScriptのアプリケーションをダブルクリックするだけでアプリケーションが動作してすぐに試せる方がいいんじゃないか、というのがあります。その為、OS標準のコマンドやアプリケーション以外はできるだけ使わなくて済むように命令を追加してます。

もう一つは複数行のAppleScriptのハンドラやスクリプト言語で書くことができるけど、それらを書くのが面倒くさいので1行で書ける命令を追加してしまおう、ってのがあります。正規表現を数百回実行する場合などは、スクリプト言語を数百回起動させるよりMenuBarAppleScriptの命令のほうが実行速度も早かったので、そういう利点もあるかな、と思ってます。

1.0.0

長年謎だった、AXWebAreaのAXSelectedTextMarkerRangeの使い方がついに分かったので、MenuBarAppleScriptで使えるようにしてみました。これで、クリップボードやサービスを使わずにSafari、Evernote、MailなどAXWebAreaを使ったアプリケーションの選択しているテキストを同じスクリプトで取得できます!。

0.7.2

細かい機能だけどあればスクリプトの作成が楽になるものをいくつか追加。

AXNotificationは奥が深いけど、Cocoaだとちょっと試すのも結構めんどくさいのが、AppleScriptで手軽にいろいろ挑戦できるのがいい感じです。非常にとっつきにくいけど、通常できなさそうなことができたりする場合があるのでお勧めです。

0.7.0

アプリケーションを作るのにあたって欲しいと思った機能を追加しています。しかし、そろそろ完成が近づいているのではないでしょうか。メニューバーアイテムを二つ以上作れないのが気になってますが、結構大きな変更になりそうだし、メニューバーのスペースの関係もあり、なかなか手を出せないでいます。

0.5.1

以前から気になっていたEventListの指定とdoInitでエラーが表示されないのを改善してみました。これで結構作りやすくなったと思います。

YouTubePlaylistPlayerを作ってて思いましたが、独自の命令がいっぱいでAppleScriptだけど通常のAppleScriptとは全く違う物になってしまった感じです。しかし、ハッシュ、リスト、正規表現の命令があると開発効率がいいですね。

0.5.0

非同期でUnixコマンドを実行する命令を付けました。コマンドが実行中でも出力を取得して処理をできるので、curlやffmpegの途中経過を表示するのに使えると思います。 osascriptでスクリプトを非同期で実行させて擬似的にスレッドを実現できそうですが、いろいろ考えても必要な場面が思いつかなかったので、使ったことはありません。

その他いろいろと欲しい機能を追加しました。

0.4.1

今まで、Property List Editorで設定していた、URLスキームを初期設定で指定できるようにしました。ブラウザのUserScriptからURLスキームを使ってMenuBarAppleScriptに命令を飛ばして、いろいろ処理したり、結果をAppleScriptでブラウザに反映させる、ってのをやってますが、結構面白いです。

0.4.0

正規表現とパス関係とURLエンコードなど、自分がスクリプト書く時にdo shell scriptのお世話になっている機能をいくつか入れてみました。正規表現でテストしたところではdo shell scriptでperlより«event TextRegx» の方が速かったです。

0.3.0

AppleScriptEditorHelperを作っててハッシュ機能が欲しくなったので、似たようなことができるようにしましたが、有る無しで開発効率が全然違いますね。

0.2.2

AXNotificationをとりあえず、アプリケーション全体で設定できるようにしてみました。なかなか面白いネタは思いつきませんが、サンプルで作ったmdlsViewerはいい感じで今後mdls、mediainfoで調べる時はこれを使うと思います。サービスメニューを選択したりドラッグドロップでファイルをアプリケーションに渡す手間がないのは楽でいいですね。

0.2.1

他の人が作ったMenuBarAppleScriptのスクリプトを見て、スクリプトのオーナというのか実行主がアプリケーション本体だというのを今頃知りました。それで«event MBASHndl»命令を追加してみました。何かと使えるのではないでしょうか。

0.1.0

いろいろとMenuBarAppleScriptのネタが思いついてAppleScript魂が久しぶりに燃えています!。作った後に実用するかどうかは分からないけど・・・。

思ったよりややこしいので作り方で分からないことがあったらご連絡ください。

AppleScriptEditorHelper

AppleScript エディタでAppleScriptを書くのを補助するアプリケーションです。$200のエディタを使ってる人には必要無いと思いますが、AppleScript エディタを使ってる自分が欲しい機能をいくつか入れてみました。

MenuBarAppleScriptの命令、キーワードを挿入できるのでMenuBarAppleScriptのスクリプトを書くには必須アイテムです。

「ユニバーサルアクセス」環境設定で「補助装置にアクセスできるようにする」にチェックを入れる必要があります。[設定のスクリーンショット]

UI Element関係の命令を使ったサンプルで何かネタが無いかと思っていたのですが、前から思っていたAppleScriptエディタの不便なところを結構解消できるアプリケーションができました。

使い方:メニューバーのAppleScript エディタのアイコンのメニューから操作します。ToolbarAppleScriptと同梱のスクリプトを使用するとウインドウのツールバーから手軽に操作できるようになります。

ASEverHelperとあわせて自分のAppleScript制作環境がかなり良くなった感じです。

機能

ダウンロード

MBAS_AppleScriptEditorHelper1.4.5.zip
MenuBarAppleScript 1.4.5
MenuBarAppleScriptの命令挿入機能のキーワードを更新。

サンプル置き場

MenuBarAppleScriptで作ったアプリケーションに移動しました。

MenuBarAppleScriptで作られたアプリケーションや紹介記事

新しくメモした順

ダウンロード

MenuBarAppleScript2.0.0

«event RemvEvnt» {"TextPath", "TextUtil", "Cmd_Run_"}を追加。MenuBarAppleScriptの命令を実行できなくできます
ユーザー登録の認証ができるcocoafobを組み込みました。
«event ChckRegi»{theLicenseName, theLicenseKey}を追加
RequireRegistraionMenuItemListなどを追加。ユーザー登録されているかどうかでメニュー項目を自動的に変更できます。
メニューアイテムに"---hide registered"か"---hide notregistered"を追加。ユーザー登録されているかどうかでメニュー項目を自動的に表示するか、隠すかできます。
LetsMoveを組み込みました
«event ASBMExec»{theVal1, theVal2}を追加
ASBMExecLoopを追加
SCNotificationIgnoreKeyListを追加
«event PostSKey»を追加
«event PostDNti»を追加
KanaEisuuKeyDownSpaceIsNormalCharを追加
10.6.8でアプリケーションに直接送れなくなっていた«event PostKeyE»のバグを修正。
«event HndlList» {theList,"insertListAfterEveryItem", theInserList }を追加
«event HndlList» {theList,"insertListBeforeEveryItem", theInserList }を追加
«event HndlList» {theList,"insertListAfterTheItem", "find", theInserList }を追加
«event HndlList» {theList,"insertListBeforeTheItem", "find", theInserList }を追加
«event DictList» {dictName,listKey,"insertListAfterEveryItem", theInserList }を追加
«event DictList» {dictName,listKey,"insertListBeforeEveryItem", theInserList }を追加
«event DictList» {dictName,listKey,"insertListAfterTheItem", "find", theInserList }を追加
«event DictList» {dictName,listKey,"insertListBeforeTheItem", "find", theInserList }を追加
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.6に対応しています。

MenuBarAppleScript1.4.5

MenuBarAppleScript1.4.5.zip
10.9で「MenuBarAppleScript初期設定.app」で初期化する時にエラーになって初期設定できない問題を修正
初期設定スクリプトの修正のみで本体に機能追加はありません。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.5に対応しています。

MenuBarAppleScript1.4.4

MenuBarAppleScript1.4.4.zip
サーバー機能でアプリケーションが落ちる場合があるのをちょっと対処
カラーピッカーでグレースケールでカラーを選んだ時にエラーになる問題を修正
10.7以降のサンドボックス対応アプリケーションでは«event PostKeyE»で指定したアプリケーションに直接キーイベントを送れないので指定したアプリケーションをアクティブにして、システムに対してキーイベントを送るようにした。
10.9のタグを取得、設定できる命令を追加。«event TextPath» {"getTag", thePath }以降を参照。
スポットライトコメントに書いたタグを10.9のタグに設定するアプリケーションSpotlightCommentToMavericksTagも参考にしてみて下さい。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.4に対応しています。

MenuBarAppleScript1.4.3

MenuBarAppleScript1.4.3.zip
WebViewのデフォルトUserAgentの指定方法が間違っていたのを修正。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.3に対応しています。

MenuBarAppleScript1.4.2

MenuBarAppleScript1.4.2.zip
JavaScriptにwindow.MenuBarAppleScript.beep();を追加
MenuBarItemImageMaxHeightが1以下の場合、メニューバーの高さの割合で指定できるようになった。
«event UIElSetE»で座標で対象を指定できるようにした。
UIElの処理対象のアプリケーション情報を取得する«event InfoUApp»を追加
AutoAddVersionMenuItemMenuTypeList,AutoAddLaunchOnLoginMenuItemMenuTypeList,AutoAddQuitMenuItemMenuTypeListが設定できなかったのを修正。
WebViewWindowにUserAgentとSafeCookieを追加
«event WebVUtil» {missing value, "clearSafeCookie"}を追加
«event TextUtil» {"writeToFile", thePath, theText }を追加
«event TextUtil» {"readFile", thePath }を追加
«event WebVUtil» {theWindowName, "setUserInfo", hoge}を追加
«event WebVUtil» {theWindowName, "getUserInfo"}を追加
WebViewWindowのキーに|UserInfo|を追加。
以下の仕様の変更は1.4.1以前のスクリプトに互換性がありませんので注意して下さい。
メニューアイテムに"---userInfo hogehage"を追加。
メニューアイテムに"---handler HandlerSuffix"を追加した時のdoSelectMenuItemHandlerSuffixハンドラの引数を変更してtheUserInfoを追加。
on doSelectMenuItemHandlerSuffix(theTitle, theTag, theUserInfo, theActiveAppRecord, theThisAppRecord)
になります。
前からtitleとtag以外にもメニューアイテムの補助情報が欲しいと思っていたのですが、互換性を保ったまま実現するいい方法が浮かばなかったのでやってなかったです。しかし、HandlerSuffixを追加して、これはまだ全然使っていないので、今のうちならここだけ仕様を変えても修正するアプリケーションが少ないのでいいかなと思いやってみました。同じdoSelectMenuItemで引数が違うのがややこしいですけども…。リストなどをUserInfoに渡したい場合は、writeJSON、parseJSONを使えばできそうです。
«event UIElLoad»が成功したかどうか分かるように返り値を返すようになった
WebViewのUserAgentにデフォルトでSafariのUserAgentを設定するようにした。
KanaEisuuKeyDownの仕様を変更
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.2に対応しています。

MenuBarAppleScript1.4.1

MenuBarAppleScript1.4.1.zip
メニューアイテムに"---hide 1"を追加。メニューに表示されなくなります。
メニューアイテムに"---key c"を追加。ショートカットキーに表示されます。表示されるだけなので実際に動作させるにはスクリプトが必要です。
メニューアイテムに"---modifierKey command option"を追加。ショートカットキーに表示されます。表示されるだけなので実際に動作させるにはスクリプトが必要です。
メニューアイテムに"---indentationLevel 1"を追加。メニューアイテムを右にインデントします。
メニューアイテムに"---handler HandlerSuffix"を追加。この場合、"doSelectMenuItemHandlerSuffix()"が実行されるようになります。メニューの途中で値を変えることも可能。この値を指定した後のメニュー項目から適用されます。メニューアイテムの前に入れて下さい。"---handler"を指定するとデフォルトの動作に戻ります。
なお、メニューアイテムで指定できるすべての値はAppleScriptEditorHelperで確認できます。
«event Win_Show»、«event Win_Hide»のバグを修正
encodeURIComponentで「"」と「'」もエンコードするようにした
アプリケーションの初期設定時にバージョンを指定できるようにした。
新しいバージョンのアプリケーションがリリースされているかチェックの為のスクリプトを内蔵した
window.MenuBarAppleScript.runHandlerで配列をAppleScriptに渡せるようにした。
console.logで配列を表示できるようにした
Windowの設定に、MaxWidth、MaxHeight、MinWidth、MinHeight、AspectratioWidth、AspectratioHeight、ResizeIncrementWidth、ResizeIncrementHeightを追加
resourcesFolderURLの末尾が"//"になっていたのを修正
簡易バージョンチェック機能を追加
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.1に対応しています。

MenuBarAppleScript1.4.0

MenuBarAppleScript1.4.0.zip
AnyRoleAllを追加
UIElSetEで取得したすべてのElementを保存するようになった。デフォルト名は要素を指定する値。3つ目の値で好きな名前を指定できる
UIElSetEで取得した複数の値を切り替えるUIElIndxを追加
UIElSetVで保存済みの値を設定できないバグを修正
«event TextUtil»のparseJSON,parseXMLのnullがmissing valueになるようにした
«event TextUtil»にwriteJSONを追加
«event TextUtil»にMGTemplateEngineを追加
リスト操作のreverseが実装されていなかったのを追加
«event Win_DelA»を追加
«event UIElAppI»を追加
«event TextUtil»にstrtolを追加
サーバー機能を追加。仕様はまだ変更するかもしれません。ドキュメント作成中。
KanaEisuuKeyDown,KanaEisuuKeyUpを追加したけど、現在仕様を検討中
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.4.0に対応しています。

MenuBarAppleScript1.3.1

MenuBarAppleScript1.3.1.zip
«event TextUtil» {"parseJSON", theURLorText}を追加
«event TextUtil» {"parseXML", theURLorText}を追加
SaveDictNowを追加
DictNotVを追加
DictSetDを追加
scrollWheelMenuBarItemを削除
JavaScriptのconsole.log('hoge');がdidFinishLoadForFrameの実行前まではログ出力できていなかったのを修正。
スクリプトレシピをいろいろと修正
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.3.1に対応しています。

MenuBarAppleScript1.3.0

MenuBarAppleScript1.3.0.zip
アプリケーション内で使用出来るホットキー、AppHotKeyを追加。
DebugJavaScriptが1の場合、JavaScriptの構文エラーと実行時エラーがコンソールに出力されるようになった。デフォルトは0です。ただし、詳しいエラー状況はわかりません。しかし、エラーが起きていて、それが構文エラーか実行時エラーかがわかるだけでも参考になると思います。
DebugJavaScriptが1の場合、JavaScriptのconsole.log('hoge');でコンソールにログを出力するようになった。
WebViewが新規ウインドウを開く場合に実行されるハンドラNewWindowURLを追加。
«event TextPath» {"url", thePath}を追加
theThisAppRecord|resourcesFolderURL|を追加
«event SW2PsPDF»のmediaに"window"を指定するとウインドウをキャプチャした画像を保存するようになった。
«event Win_Hide»«event Win_Show»で指定したウインドウの表示を変更できるようにした。
button3ClickMenuBarItemを追加
scrollWheelMenuBarItemを追加
RunSCNotificationHandlerの実行タイミングを変更。すべての値の処理が終わってから実行するようにした。
まれにアプリケーションが落ちるのは治ってないようです。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.3.0に対応しています。

MenuBarAppleScript1.2.3

MenuBarAppleScript1.2.3.zip
指定した時間にハンドラを実行するDoAtTimeを追加。
日付関係の命令を追加。
SW2PsPDFで保存する画像をMenuBarAppleScript内部に保存してMenuBarItemImageやMenuBarItemAlternateImageに設定できるようになった。例:HTMLで作成した画像をメニューバーアイコンに設定する
PriorityToMenuBarItemImageを追加。
まれにアプリケーションが落ちるのが治っているかもしれません。治ってないかもしれません。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.2.3に対応しています。

MenuBarAppleScript1.2.2

MenuBarAppleScript1.2.2.zip
Dictionary Services (辞書サービス)の命令を少し変更。単語の位置にmissing valueを指定すると指定した文字列をそのまま調べるようにした。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.2.2に対応しています。

MenuBarAppleScript1.2.1

MenuBarAppleScript1.2.1.zip
MenuBarAppleScript1.2.0に日本語リソースを入れ忘れていたので追加。英語モードで起動しているためか、Dictionary Services (辞書サービス)の命令で日本語辞書が調べられませんでした。あと、WebViewのコンテキストメニューが英語になっていました。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.2.1に対応しています。

MenuBarAppleScript1.2.0

MenuBarAppleScript1.2.0.zip
Dictionary Services (辞書サービス)の命令を追加。単語の意味を調べることができます。
AutoAddLaunchAutomaticallyOnLoginMenuItemをAutoAddLaunchOnLoginMenuItemにAutoAddLaunchAutomaticallyOnLoginMenuItemMenuTypeListにAutoAddLaunchOnLoginMenuItemMenuTypeList変更。古い方も互換性のため認識します。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。最新版はMenuBarAppleScript1.2.0に対応しています。

MenuBarAppleScript1.1.0

MenuBarAppleScript1.1.0.zip
«event TextPath»に命令を追加。移動、削除、フォルダ内のファイルを取得、アイコンの設定などができるようになった。
«event UIElSetE»の命令に機能を追加。AnyRole、Index、PerformActionを追加。
dictNameが次のものは保存前に削除します
SaveDictはデフォルトで保存する1になりました。
AutoAddQuitMenuItem、AutoAddLaunchAutomaticallyOnLoginMenuItem、AutoAddVersionMenuItemのデフォルト値は1になりました。
メニューバーアイコンのデフォルトの高さをAPIで取得したメニューバーの高さにするようにした。
WebViewWindowの設定にAcceptsFirstMouseはデフォルトでは0のオフになりました。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript1.0.0

MenuBarAppleScript1.0.0.zip
いろいろ機能追加してバグも入ってるかもしれないけど、年明けで今年は1.0.0から始めようということでVer.1.0.0です
AXWebAreaの全体のテキスト、選択しているテキストなどを取得できる命令«event UIElVal_»を追加。«event UIElSetV»で«event UIElVal_»で保存した値を設定できるようになった。
«event UIElVal_»の使い方はレシピに書いてあるgetUIElementTextを参考にして下さい。AXWebAreaを含むかなりの状況で全体、選択しているテキストを取得できます。
指定した名前のウインドウが表示されていたら1を返す命令«event Win_Visi»を追加。
正規表現の引数の順番を変えた命令«event TextRE__»を追加
WebViewWindowの設定にAcceptsFirstMouseを追加。デフォルトで有効。
初期化スクリプトのバグを修正。設定によってはエラーになっていた。
WebViewのLocal Storageがファイルに保存されるようにした。
イベントにrunWithNoServiceNoOpenFileNoOpenURLを追加
LSUIElementとLSBackgroundOnlyのアプリケーションはシステム終了時にdoQuitが実行途中でも終了してしまう場合があるので通常のDockに表示されるアプリケーションも作れるように初期化スクリプトを更新。
GrowlのFrameworkを2.0.1に更新
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript0.8.0

AppleScriptEditorHelperが0.8.0なのでそれをダウンロードして下さい
微速度Desktopが0.8.0なのでそれをダウンロードして下さい
イベントのハンドラを実行時にハンドラが無いエラーになった時に、そのイベントがアプリケーションを再起動するまで実行されなくなるバグを修正
Cmd_Quitでnameで終了できないバグを修正
メニューバーのサービスメニューの「一般」に常に表示されるサービスメニュー項目を作れる様になった。
«event TextPath»に命令exists、isDirectoryを追加。
辞書のキーに文字列以外を設定できますが、ファイルに保存時にエラーになるので文字列以外のキーは内部で文字列に変換するようにした。内部的なことなのであまり気にしなくてもいいですが、"1"と1は同じキーになる点は注意が必要です。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript0.7.2

AppleScriptEditorHelperが0.7.2なのでそれをダウンロードして下さい
«event TextURL_»にdecodeHtmlSpecialcharsを追加。
«event Win_Hide»«event Win_Show»を追加。
«event DictText»にcompareを追加。
AXNotificationを登録時に対象が無い時のバグを修正
初期化スクリプトを更新。アプリケーションの変更日を設定した現在の時間にするようにした。作成日も現在の時間にできるようにした。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript0.7.1

|AXNotificationList|の設定のレコードに|Enable| : 0を追加するとその通知は有効にならなくなった。スクリプト作成中等に、一時的にオフにしたい場合等に。アプリケーション実行中に一度オンにしたものを実行中にオフにすることはできません。

MenuBarAppleScript0.7.0

MoveMouseToNextDisplayが0.7.0なのでそれをダウンロードして下さい
キーワード"cursor"を"mouse"に変更。"cursor"も認識します。
マウスを移動する命令、«event PostMove»を追加。サンプル:MoveMouseToNextDisplay
マウスクリックする命令、«event PostClck»を追加
音を再生する命令、«event PlaySnd_»を追加
JavaScriptからAppleScriptのハンドラを実行できるようになった。サンプル:bcDentaku
«event DictNum_»の命令にnotを追加
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript0.6.0

AppleScriptEditorHelperが0.6.0なのでそれをダウンロードして下さい
EventListの値に"*"を指定した時の問題を修正
DoAfterSecの引数の説明が間違っていたのを修正。自分も間違って使ってた・・・。
AXNotificationでエラーが出る問題が直ったかもしれません。
AutoAddVersionMenuItemでメニューにバージョンを表示できるようにした。
処理の最適化
スクリプトレシピによく使う処理を書きました。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript0.5.1

AppleScriptEditorHelperが0.5.1なのでそれをダウンロードして下さい
YouTubePlaylistPlayerが0.5.1なのでそれをダウンロードして下さい
EventListの値に"*"を指定するとすべてのイベントのハンドラを実行するようにした。デフォルトは{"*"}なので、EventListは設定しなくても動くようになりました。
LogAppleScriptErrorとDebugLogの初期値を1にした。これでdoInitでのスクリプトエラーが表示されdoInitのバグが分かりやすくなります。
リソースにJapanese.lprojフォルダを追加して、WebViewのコンテキストメニューが日本語になるようにした。
MenuBarItemTitle、MenuBarItemImageなどをmissing valueにすると値を設定しないようにするようにした。
Menu Itemの指定方法に"---title タイトル"を追加。キーワードを含む文字列をタイトルに設定したい場合に。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令、キーワード挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。自分はこれが無いと書けません。

MenuBarAppleScript0.5.0

AppleScriptEditorHelperが0.5.0なのでそれをダウンロードして下さい
AutoTextCounterが0.5.0なのでそれをダウンロードして下さい
ContextMenuの表示位置を指定できるようになった
run、reOpenイベントを追加
SCNotificationの通知を追加
Unixコマンドを非同期で実行できる命令を追加
«event DictText»の命令を追加
«event DictNum_»の命令を追加
«event DictDict»のレコードを直接処理をする版の«event HndlDict»を追加
«event DictList»のリストを直接処理をする版の«event HndlList»を追加
theThisAppRecordの値にscriptPath,resourcesFolderPath,scriptsFolderPath,URLSchemeList,processorCount,physicalMemoryを追加
doFileURLを通常のイベントと同じように指定するようにした。
AXNotification関係のバグ修正
AXNotificationListの|App|を|AppName|に変更
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。
AppleScriptEditorHelperにMenuBarAppleScriptの命令挿入機能があるので、MenuBarAppleScriptのスクリプトを書く時にお勧めです。

MenuBarAppleScript0.4.2

MenuBarAppleScript0.4.2.zip
rightClickMenuBarItemがエラーになっていたのを修正
OnLoadJavaScriptとdidFinishLoadForFrameの実行をWebViewのmainFrameが読み込み完了時の時にした。また、OnLoadJavaScriptはdidFinishLoadForFrame後から0.5秒後に実行するようにした。OnloadJavaScriptDelayで設定可能。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。

MenuBarAppleScript0.4.1

MenuBarAppleScript0.4.1.zip
初期設定のスクリプトを改良。サービスを無しにできるようにした。URLスキームを設定できるようにした。LSUIElementとLSBackgroundOnlyを選べるようにした。
WebViewのformから実行されるハンドラの引数のフォームのレコード値を変更。同じキーでも複数指定される場合もあるので値がリストになりました。値が一個の場合でもリストなので注意して下さい。
命令«event TextURL_»に新しい命令を追加
命令«event TextUtil»に新しい命令を追加
GrowlのImageでファイルパスを指定すると画像が表示されなかったのを修正
didFinishLoadForFrameを指定しないと、OnLoadJavaScriptでdoJavaScriptResultが実行されないのを実行されるように修正
サービスのテキストの置換ができなかったのを修正
アプリケーションが起動していない状態からURLを開いてdoOpenURLが呼び出される場合、エラーになっていたのを修正。サービスでも同様の問題があったかもしれません。
WebViewの設定にLoadsImagesAutomaticallyなどを追加。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。

MenuBarAppleScript0.4.0

MenuBarAppleScript0.4.0
AppleScriptEditorHelperが0.4.0なのでそっちからダウンロードして下さい
イベントにrightClickMenuBarItemを追加。
命令«event MBASRunH»を追加
命令«event TextPath»を追加
命令«event TextURL_»を追加
命令«event TextUtil»を追加
命令«event TextRegx»を追加
命令«event DictDict»を追加
命令«event DictList»の命令を追加
命令«event DictGetV»で初期値を指定できるようにした
実行ファイルとInfo.plistのアプリケーション名をMenuBarAppleScriptじゃなくて、指定したアプリケーション名にするようにした。初期設定時に英語名を聞かれる場合があります。"Quit All MenuBarAppleScript.app"が使えなくなりました。
return {|SaveDict|:1}で保存できなかったのを修正。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。

MenuBarAppleScript0.3.1

MenuBarAppleScript0.3.1
AppleScriptEditorHelperLyricsStarTunesが0.3.1なのでそっちからダウンロードして下さい
AppleEventのDic_をDictにした。スクリプトのDic_をDictで全置換してください
Growlと10.8の通知に対応した。通知関係を見て下さい。
使ってない機能は(ほとんど、もしくはぜんぜん)テストしてないのでおかしいと思ったら、ご連絡ください。使い方が分からない場合もどうぞ。

MenuBarAppleScript0.3.0

MenuBarAppleScript0.3.0
AppleScriptEditorHelperが0.3.0なのでそっちからダウンロードして下さい
MenuBarAppleScriptのコマンドを追加
AXNotificationの通知を更新
ウインドウをちゃんと削除できるようになった

MenuBarAppleScript0.2.2

MenuBarAppleScript0.2.2.zip
サービスの実行するハンドラ名をdoServiceからdoTextService等のように、値によって変えるようにした。
AXNotificationの通知に部分的に対応。
WebViewをpdf、画像として保存できるようになった。WebViewWindowのWebViewをpdfやjpg,pngで保存する
サンプル:mdlsViewer.app
アプリケーションのBundle Identifierの付け方を変更。半角英数字のある名前の場合はそれを使用するようにした。
ウインドウの初期位置、サイズを指定できるinitialWidthなどを追加。
スクリプトを毎回ロード、保存するのをやめて、保存はアプリケーション終了時のみ、ロードはファイルに変更があったときのみにした。
サンプルの中でそこそこ使えそうな物は同梱はやめて作ってみたもの・サンプルに移動。

MenuBarAppleScript0.2.1

MenuBarAppleScript0.2.1.zip
«event MBASHndl» {|WebViewWindow|:{|Name|:"YT", |URL|:"http://youtube.com/"}}
の様に«event MBASHndl»でスクリプト中で命令を随時処理できるようになった。
サンプル:YouTubePlayerSample.app
ウインドウのStyleListの設定のバグを修正。
FSEventに対応。ただし、MenuBarAppleScriptでは変更があったフォルダしか通知しないので、どのファイルが追加されたり、変更されたのかは自分で調べて下さい。
サブフォルダの通知も来るので気をつけて下さい。ホームフォルダ等上の方のフォルダを指定すると、キャッシュ等で頻繁に変更があるので、常時ハンドラが実行されることになります。
サンプル:SafariAutoReloadFileURL.app

MenuBarAppleScript0.2.0

MenuBarAppleScript0.2.0.zip
ハンドラの引数を変更しました。以前のスクリプトが動かなくなりました。変更点はtheModifierKeyListtheActiveAppRecordに入れました。modifierKeyList of theActiveAppRecordで参照して下さい。また、引数からtheModifierKeyListを削除して下さい。
WebViewWindow関連の修正
デスクトップに何か表示したい場合はDeskTopWindowTest.appを参考にして下さい。

MenuBarAppleScript0.1.5

MenuBarAppleScript0.1.5.zip
WebViewWindowのレベル(フローティングウインドウとか、デスクトップに表示するとか)を変更できるようにした。デスクトップに表示するウインドウが作成できます。
WebViewWindow関係の設定を追加、変更
以下が今回の変更点のサンプルになります
LyricsStarTunes.app : デスクトップに曲情報を表示するようになった
YouTubePlayerSample.app : ウインドウの位置を記録するようになった

MenuBarAppleScript0.1.4

MenuBarAppleScript0.1.4.zip
ハンドラで返すレーコードのキーは大文字小文字どっちでも書けるようにしました。注意点で書いたバグか仕様にはまると結構大変なので。
WebViewWindowを作れるようになった。いろいろ表示できるので何かと使えるのではないかと思います。サンプル:YouTubePlayer.app ImageViewer.app。サンプルで使用していない機能は全くテストしていません。
すべてのハンドラの引数の最後にtheThisAppRecordを追加。|name| of theThisAppRecordに動作しているMenuBarAppleScriptの名前が入っています。また、AppRecordにマウスの位置とスクリーンのサイズを追加。theThisAppRecordの情報はアプリケーション起動直後の値になります。現在値はtheActiveAppRecordを参照して下さい。WebViewWindowの位置やサイズ調整が必要な場合の情報として。

MenuBarAppleScript0.1.3

MenuBarAppleScript0.1.3.zip
アイコンを作成してみた。制作時間15分ぐらい・・・。

MenuBarAppleScript0.1.2

MenuBarAppleScript0.1.2.zip
スペルミスを修正・・・。間違ったスペルのスクリプトが動かなくなります。
ホットキーを付けられるようになった。使い方はLyricsStarTunes.appを見て下さい。
|LogAppleScriptError|:1を返すとでエラーをコンソールに出力できるようになった。デバッグが楽になると思います。
すべてのハンドラの引数の最後にtheActiveAppRecordを渡すようにした。

MenuBarAppleScript0.1.1

MenuBarAppleScript0.1.1.zip
ちょっと修正

MenuBarAppleScript0.1.0

MenuBarAppleScript0.1.0.zip
仕様は変更になる場合があります
サンプルで使っていない機能はテストしないものがあります
アイコンが使い回しです