LoginSignup
49
40

More than 5 years have passed since last update.

JXAでSafari, Chrome, Firefoxを操作する際の違い

Last updated at Posted at 2015-02-23

まとめ

Safari: Apple謹製だけど機能少ない
Chrome: なぜか異常に充実
Firefox: ほぼ何もできない


気が向いたときにちょっとずつ更新中

Safari Chrome Firefox
参照 Application( "Safari" ) Application( "Chrome" ) Application( "Firefox" )
ウィンドウ
(全て)
app.windows() app.windows() app.windows()
ウィンドウ
(最前面)
app.windows[0] app.windows[0] app.windows[0]
ウィンドウ
作成
app .Document().make() app .Window().make() -
タブ
(全て)
win.tabs() win.tabs() -
タブ
(表示中)
win .currentTab() win .activeTab() -
タブ
切り替え
win .currentTab = tab win .activeTabIndex = index -
URL移動 tab.url = "http://qiita.com" tab.url = "http://qiita.com" -
JS実行 app .doJavaScript("alert('hi.'),{in: tab}) app .execute(tab, {javascript:"alert('hi.')"}) -
ページ更新 tab.url = tab.url() tab.reload() -
読込中止 - tab.stop() -
戻る & 進む (やろうと思えばdoJavaScriptで) tab.goBack();
tab.goForward();
-
ブックマーク - 参照可(長いので省略) -
履歴 - - -

Chromeの新規ウィンドウ作成は戻り値でそのままWindowを得られる。
SafariはDocumentが返ってくるからURL移動したいときとか困る。
(app.Window().make()できればいいのに・・・)

Windowを得る場合は以下のようにするといいのかもしれない・・・

var Safari = Application("Safari");
var doc = Safari.Document().make();
var win = Safari.windows[doc.name()];

//URL移動
win.currentTab.url = "http://qiita.com"

使ってみる

以下の記事と同じことをするコードを書いてみました。

JXAを知らない方はこちら。

やること

下準備

  • 待ち秒数を指定 (DELAY)
  • アプリケーションの参照を取得
  • 最前面のウィンドウを取得

ループ

  • タブを切り替えてDELAY秒だけ待つ
  • ページを更新してDELAY秒だけ待つ

試すには30秒は長いので3秒にしました。

Safari

autoreload_safari.js
const DELAY = 3;

var Safari = Application("Safari");
var window = Safari.windows[0]; //最前面のウィンドウを取得

while(window.exists()) { //無限ループ (ウィンドウが開いてなければ実行しない)
  window.tabs().forEach(function(tab){

    // タブ切り替え
    window.currentTab = tab;
    delay(DELAY);

    // 更新
    tab.url = tab.url();
    delay(DELAY);
  });
};

ウィンドウから全タブを取得できます。
タブの切り替えは現在のタブ(currentTab)に任意のタブをセットすることで行います。

Safariには表示中のページを更新する関数がありません。
ページの更新は表示中のurlをタブのurlプロパティに再セットすることで可能です。

またはdoJavaScriptによってページ内でJavaScriptを実行して更新します。

JavaScriptで更新(doJavaScript関数)
Safari.doJavaScript("location.reload()", {in:tab});

doJavaScriptはページ内での実行結果を戻り値として返します。
ページから簡単に情報を得たい場合に便利かもです。
同じJavaScriptで書けますし。

メモ:

ブックマークにアクセスすることが出来ません。
ブックマークを整理するスクリプト書きたかったのに無理でした・・・。

リーディングリストに追加する機能はあるのですが、その一覧を取得する機能も無いです。
ビビりました。

Chrome

autoreload_chrome.js
const DELAY = 3;

var Chrome = Application("Google Chrome");
var window = Chrome.windows[0]; //最前面のウィンドウを取得

while(window.exists()){ //無限ループ (ウィンドウが開いてなければ実行しない)
  window.tabs().forEach(function(tab, i){

    // タブ切り替え
    window.activeTabIndex = i + 1;
    delay(DELAY);

    // 更新
    tab.reload();
    delay(DELAY);
  });
};

ウィンドウから全タブを取得できます。
タブの切り替えはウィンドウのactiveTabIndexにインデックスをセットすることで行います。
インデックスは1から始まることに注意。

タブからはインデックスを取得できません。
そのためforEachのカウンタを利用する必要があります。

アクティブなタブを取得する関数は.activeTab()です。
これは読み取り専用なのでSafariのように他のタブをセットすることはできません。

Chromeには表示中のページを更新する機能(.reload())があります。
更新キャンセルや「進む」「戻る」の機能もあります。

もちろんページ内でJavaScriptを実行することも可能です。

JavaScriptで更新(execute関数)
Chrome.execute(tab, {javascript:"location.reload()"});

Safariと同じようにexecuteもページ内での実行結果が戻り値になります。

メモ:

今回のブラウザの中で、スクリプト向けに用意された機能はChromeがダントツで充実してました!

ブックマークにアクセスすることもできます。
ブックマークを整理するスクリプトを書くことも可能でしょう。
やってませんが。

Firefox

autoreload_firefox.js
const DELAY = 3;

var Firefox = Application("Firefox");
var window = Firefox.windows[0]; //最前面のウィンドウを取得

SystemEvents = Application("System Events");

while(window.exists()){ //無限ループ (ウィンドウが開いてなければ実行しない)

  // タブ切り替え
  Firefox.activate();
  delay(0.3); //アクティブになるまで少し待つ
  SystemEvents.keystroke("]", {using:["command down", "shift down"]});
  delay(DELAY);

  // 更新
  Firefox.activate();
  delay(0.3); //アクティブになるまで少し待つ
  SystemEvents.keystroke("r", {using:"command down"});
  delay(DELAY);
};

ウィンドウからタブを取得できません。
ってことはApplication.documents()でページの内容を見れるのかな?

>> Firefox = Application("Firefox")
=> Application("Firefox")
>> Firefox.windows.length
=> 10
>> Firefox.documents()
=> []
>> 

!?
空の配列が返ってきました。
どうやら用語説明はテンプレそのまま使っていて、機能は何もなさそうです。多分。
ウィンドウを取得する以外、ほぼ何も出来なさそうです。

こういう場合はSystem Eventsからキーボードを押したりして操作するしかありません。
キーボードやマウス操作をする方法はこちらに書きました。

Application("Firefox")の部分を変えるだけでSafariでもChromeでも動きます。
いちいち.activate()する必要があるので他の作業中に動作させるのは無理です。

メモ:

ページの内容すら取得できないんじゃ・・・?
スクリプトで操作するなら別のブラウザを使いましょう。

追記:
windowにもdocumentプロパティがあることに気付きましたが、nullでした。

varFirefox = Application("Firefox");

Firefox.windows[0].document();
//=> undefined

Firefox.windows[0].properties();
//=> {"document":null, "closeable":true, "zoomed":true, "class":"window", "index":1, "visible":true, "name":"Yahoo! JAPAN", "modal":false, "miniaturizable":true, "titled":true, "id":6188, "miniaturized":false, "floating":false, "resizable":true, "bounds":{"x":0, "y":23, "width":1280, "height":709}, "zoomable":true}

ウィンドウからページのタイトルだけ取得できるようです。
上の例だとYahooを開いていることがnameプロパティで分かります。
ページ内容を取得する方法が存在するなら、知ってる方教えてください。

蛇足

ぜんぜん関係ないけど、Terminalでシェルスクリプトを実行するdoScriptもSafariのdoJavaScriptと同じ構文
ただし戻り値はタブの参照です。タブを指定しない場合は新しいウィンドウを開くので。

Terminal
var Terminal = Application("Terminal");
var tab = Terminal.windows[0].selectedTab(); // SafariはcurrentTab。名前統一してくれ

Terminal.doScript("echo 'hi.'", {in:tab});
var newTab = Terminal.doScript("echo 'hi new window.'");

コマンド実行の戻り値を得たい場合はdoShellScriptを使います
これはTerminalじゃなくても使えます

doShellScript
var app = Application.currentApplication();
app.includeStandardAdditions = true;

var date = app.doShellScript("date");
49
40
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
49
40