ファイルパスをURLに置換してSafariで検証するAppleScript

最近の GUI アプリは AppleScript を呼び出すメニューを持っているので、例えばエディタアプリで書いているコードを Safari で検証したいという時にブラウザでリンクの遷移を辿ったり URL バーに入力する手間が必要なく表示することができます。High Sierra の対応の問題から TextWrangler から CotEditor に乗り換えたことから先に使っていた AppleScript を編集したので紹介します。

今回はユーザディレクトリのサイトフォルダの中にあるファイルを対象にしましたが、MAMP やサイトルートにあるファイルを編集している環境では先頭二行のプロパティを編集してください(もちろんユーザディレクトリ名も)。後半では開発メニューのコンソールを同時に開くようにしていますので最初に使いたいもののショートカットキーにすると良いでしょう。

Coda にも Safari.scpt が同梱されているので、これを改編すれば file:/// スキームでの受け渡しを変更することができるのでお試しください。また Google Chrome を呼び出だす事へ流用する事も容易かと思いますので是非。

参考:

Safari 8のリセット

Safari 8 の読み込みが遅くなって、確かブラウザのコマンドとしてリセット機能があったような気がしたのだけど見当たらず「Safari メニュー>履歴と Web サイトデータを消去…」という項目になっていて選択すると iCloud データ管理だったので、環境設定の「プライバシー>すべての Web サイトデータを削除…」をして再度 Safari を起動すると軽快に動作するようになりましたとさ。

http://hkitago.tumblr.com/post/108117496951


ここで覚悟しないといけないのは認証情報の再入力ということになりますが、同じ症状が二度目だったの(とタンブラーの投稿埋め込み機能を使ってみたかったの)で Chrome を経由して記事にしました。

結局リセットコマンドは v8 で無くなっているようなので、iPhoto などのように起動時にキーコマンドでリセットできれば嬉しいところです。

Safari の余談で便利なところ。

P.S. 埋め込みだらけ

参考:

The bug of animation-play-state on Webkit for iOS

具体的には HTML に記述されるノードの並び順によって keyframe が影響を受け挙動が変ってしまうという問題を見つけました。こちらのデモを参考まで。
animation play state bug (同じボタンを押す度に上下の円が順に回ります)

現時点でMac OS と iOS 版の Safari (7.0.1 9537.73.11 && 7.0 Mobile/11D5134c Safari 9537.5)、iOS 版の Google Chrome (32.0.1700.20) で影響を確認しています。そこで同じような問題が WebKit Bugzilla に投稿されているにも関わらず、未確認のまま一年が過ぎようとしているのに若干不安を持ちつつも、Android 並びに PC 版の Chrome ブラウザは正しく実装されているため Apple のバグレポートを使って報告しました。

iOS4 の時には既に製品として公開している中、バグレポートで大変な目に遭ったのですが、Google のモノはトリッキーにこちら側で手直しや対応することができる問題が多いのに比べ、Apple のは向こうの対応を待つしかないという箱庭で遊ぶ危険さみたいなものを感じて止みません。

P.S. さっき新たなβ版が出ていたのだけど、次のiOS 7.1に間に合ってほしいなー(棒読み)。

参考:

ChromeからSafariで開くサービスメニュー

Google リーダーの終了に伴って Feedly へ移行することにしたのだけど、元々このサービスは Google Chrome の機能拡張を主に構築されていたことや、OS X のアップグレードを前に Safari が大分もっさりしていることなどから、開発用途でもあるデフォルトブラウザを Safari にしつつもニュースリーダーとして Google Chrome を使う事にした。ところがページロールがあり広告だらけな長めの読み物を見る時にはどうしても Safari のリーダー機能を使いたくなる時があって、いちいちアドレスバーの文字列をコピペして移動するのは面倒なので表題のものを Automator で作る事にした。

作るのは至って簡単な数分の作業です。

  1. Automator を起動し、ファイル>新規>サービス というメニューコマンドをクリックしたら選択ボタンを押します。
  2. “サービス”は、次の項目を受け取ります:入力なし/検索対象:Google Chrome.app とします。
  3. 左側のパネルにある “AppleScript を実行” というアクションを右側のパネルにドロップし gist:5575774 をコピペします。
  4. “Safariで開く”というような適当な名前を付けて保存します。(保存先と拡張子は Automator にお任せ)

そうすると、Google Chrome を前面に持ってきた際に「Chrome>サービス>Safariで開く」というメニューコマンドが確認できるようになります。(本来は副クリックでも表示できれば良いのですが、Google Chrome がその機能を書き換えてしまっているのでちょっと不便ですねえ。)

加えて参考リンクにも解説されているように、各サービスには独自のショートカットキーを割り当てられるので「>システム環境設定>キーボード>サービス」と進み、スクロール下方の一般カテゴリに先ほど作成したサービス名が見えると思うので他と衝突しないキーの組み合わせを割り当てます。例では「コマンド+シフト+O」としていますが、ドックにウィンドウが入ってた場合に隠し機能でもあるゆっくりとしたアニメーション効果がイラッとする場合があるのでシフトキーを使わないようにすると良いかと思います。(このスローアニメーションをオフにする方法は現在無いようで…)

スクリーンショット 2013-06-29 4.39.44

そうしてる内にもこんな知らせを受けて、ジェスチャーにもキーにも対応している Reeder へ戻る羽目になりそうな予感です。

参考:

SafariでCSSの表示確認

JavaScript で動的にノードを追加しても描画してくれるので、いちいちファイルを編集→ブラウザ切り替え→リロードという手間コンボが必要ありませんよー、という映像です。

最近メタディスクリプションの内容を書き換えるという難解!な要件があって活躍したとかしないとか。

参考:HTML and CSS Debugging Tools | Design Shack

P.S. 連投で恐縮ですが iPad で何か書かせてください。;-)

Tumblrタグ検索ブックマークレット

最近タンブラーで過去の投稿を引き出したいことが多くなってきたので、まずタグから絞り込むことができるようにブックマークレットを作って Safari のツールバーの左から5番目に置いた。
TUMbrTAG

javascript:(function()%7BQr=(window.getSelection?window.getSelection():document.getSelection?document.getSelection():document.selection.createRange().text);if(!Qr%7C%7CQr=='')%7Bvoid(Qr=prompt('Tumblr%20Tagged%20search%20word:',''))%7Dif(Qr)window.open('http://hkitago.tumblr.com/tagged/'+encodeURI(Qr));%7D)();


アドレスのアカウント名は適宜変更してお使いください。もちろんショートカットは⌘5!

で思い出したけど、Lion になってから Safari の ⌘+SFT+L ショートカットがリーディングリストに置き換わってしまったので同じように三番目(GOOG)に登録した。

P.S. 仕事用の Local ディレクトリ表示がまた後ろに行ってしまった… 🙁

LionのSafariが重い

昨年末に作業環境を刷新して一月ほど経とうとしてるんだけど、iOS というか WebKit のウェブアプリ開発で Safari を主に使っていると時折、従来に見受けられた JavaScript の無限ループみたいな感じの高い負荷で動かなくなってしまうことがあったのでその回避方法を公式のフォーラムから。

– Quit Safari
– Turn off bookmark syncing in the iCloud System Preference pane (under the Apple Menu)
– Select the Finder, under the GO menu, select “Go to Folder…”
– Enter in “~/Library/ ” (no quotes, first character is a tilde)
– Renamed the files “Bookmarks.plist” and “Bookmarks.sprt” to “Bookmarks-old.plist” and “Bookmark-old.sprt”
(.sprt appears to be a legacy file on my system not being used anymore, so you may not have it.)
– Go back into the Systems Preferences and turn on iCloud Bookmark settings
– Start Safari, give it some time to resync your bookmarks from the cloud.

引用元: What is SafariDAVclient?: Apple Support Communities.

ここではリネームしていますが、デスクトップに置いたりゴミ箱にいれてしまっても大丈夫かと。ちなみに .sprt ファイルは存在しませんでした。

原因と方法を簡単に言うと、iCloud でブックマークの同期を使っている場合に起きる事が多いので、Lion から不可視となったライブラリ>Safariフォルダにある Bookmarks.plist を再構築すると直りますよ、ということらしいです。

ところがどっこい、「SafariDAVclient taking 100% of CPU on Mac OS X 10.7.2 | Dave on Macs」によると、ブックマーク同期サービスを利用していなくてもこの問題が起きる場合があるそうで、こちらではまた違うやり方が紹介されています。

いずれにせよアクティビティモニタで確認すると SafariDAVclient というプロセスが悪さをしていることに変わりはなく、同期サービスを利用しているので前者の方法を使い一先ず処理速度が復帰したこともあり押さえているだけなのですが、もし今後問題が復活した場合は iCloud によるブックマークの同期サービスを控えて後者について試してみようと思います。(リーディングリストなんてサードパーティのサービスでも十分賄えますしね。)

iOS用お絵描きソフト

iPad の Safari で動作するマルチタッチ対応お絵描きソフトを作ってみた” からコードを拝借し、フルスクリーンで起動するように次のタグを追加してローカル上にある Mac OS のサイトディレクトリに配置した。

"apple-touch-icon"を指定しない場合のホームアイコンはページのスクリーンショットになるので、何か描いた後に “ホーム画面に追加” ボタンを実行すると良い。

デモ (リンクは予告無く削除する事があります)

フルスクリーン表示ではアドレスバーの表示が無いので、白紙に戻す時に使う “再読み込み” は “ホーム>アイコン” とタップ数が多くなってしまう事に注意。

P.S. 子供に遊ばせてみる事にする。

更新: "apple-touch-icon"を指定したウェブアプリは iOS4 のマルチタスクに対応する様だ。

更新2(7/22):子供とお絵描きをして遊んだ。彼は飽きたらホームボタンを押すので同時にスリープボタンを押してキャプチャを撮る事に成功。

Safari 5の新機能

Mac|Life が Safari 5にある注目すべき17個の新機能を紹介する記事 “17 Cool Safari 5.0 Features and Tips Revealed” を公開していた。

ウェブ開発者としては2ページ目の後半に書かれているユーザエージェントを変更して Apple の公式文書を見ると iPad 用に最適化されたページ設計を垣間見ることができるのを最近とても重宝しているが、コマンド+数字キーというショートカットによるブックマークレットの呼び出しが9つ以上になってきたこともあって、Extension を使った Youtube 動画の保存やタブセッションの保存ボタンを追加することができるのも便利だと思う。(ツールバーに再読み込みボタンを復活させる Extension なんてのもある。)

更に Safari 4 ではキャレットブラウジングという地味な機能が、ウェブ上に公開されているコードをコピペしたり Evernote やメモへ保存するためにテキストを選択する場合に有益だったが、Safari 5 ではコマンド+Zという文字入力のやり直しを行うショートカットが拡張されていて、タブをうっかり閉じてしまった時に実行すると復元する(その後、コマンド+シフト+Zでまた閉じる)という機能が今回の地味なお気に入り機能になっている。

ヘルプ>謝辞からも分かる様にリーダー機能は Arc90 が Apache License で公開している Readability のコードを利用しているそうで、アドレスバー右端(再読み込みボタンの左)に表示されているが、押しっぱなしにすると従来あった RSS を登録するためのプルダウンメニューが表示されるというのも利用者の混乱を最小限に抑える措置として気が利いている。

SQLiteデータベースのバージョンを変更する

iPhone アプリで利用している SQLite のスキーマを変更する必要に迫られ開発中に予期せぬ出来事があった。具体的にはテーブルに一列追加する changeVersion という関数を利用する際に必ずバージョンがマッチしないというエラーを出力するというものだ。

success callback である第五引数内でもoj.versionがoldVersionを返すのが気になります、、、。リロードするとようやくnewVersionに変わるんですけれど、これで良いのかなぁ。

引用元: JavaScript++かも日記: 【iPhone】iPhone用 JavaScriptデータベースプログラミング入門 (6).

Safari の JavaScript のデバッガでこの問題を確認し回避策を模索していたところ、Apple の文書に次のような回答を見つけた。

Unfortunately, the only way for your code to see the new version number is by closing the browser window. If you get an error code 2 (see “Error Codes”) and the database version you passed in for the old version matches the version in db.version, you should either assume that the version change already happened or display an alert instructing the user to close and reopen the browser window.

引用元: Safari Dev Center: Safari Client-Side Storage and Offline Applications Programming Guide: Using the JavaScript Database.

結局のところ挙動は問題ないのだけど、ブラウザを閉じるか再読み込みしないと利用者に反映されないということで、次のようなコードにして iPhone の UIWebView 用に移植する前段階として一旦作業を終えることにした。

try {
  if (window.openDatabase) {
  // db = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000); /* 現行バージョンの記述 */
  db = openDatabase("BackgammonPositionsDB", "2.0", "Backgammon Positions DB", 200000);2.0バージョンは開けずエラーをキャッチするので通常の処理は省略)
} catch(e) {
  if (e.code == DOMException.INVALID_STATE_ERR) { // Version number mismatch.
    var prevdb = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000);
    prevdb.changeVersion("1.0","2.0", 
      function(tx){
        tx.executeSql('ALTER TABLE BGPositions ADD COLUMN crawford INTEGER default 0;VACUUM;');}, 
        function(error){ /* SQLエラー処理 */ }, 
        function(){ /* 成功後初期化処理 */ });
    return;
  }
  alert("Unknown error " + e + ".");
}

またこの検証作業に関して SQLite のバージョンを戻す(1.0 に下げる)必要があり、前述した Apple の文書にもある ~/Library/Safari/Databases/ にあるファイルを削除して Safari を再起動するという若干面倒な手続きを取るしか方法がないので、Rails のような管理手法を Automator や AppleScript で作ることが望ましい気がした。

実際の iPhone 上の UIWevView ではどのような挙動になるのか、悩ましいことになるようであれば追って報告しようと思う。