2010年6月26日土曜日

[Google Chrome] バカの一つ覚え

[The Chromium Blog] A fresh coat of chrome

Appleが1ボタンマウスに拘りすぎてUXを犠牲にしてしまったという歴史を彼らは知らないようだ。ミニマリスムとは「少なければ少ない程良い」という安易な思想では、断じて、無い。

あいかわらず肝心な事については気付かない間抜けさ加減。速度なんて時間が経ちゃイヤでも上がるものなのにそれをコアコンピタンスにしちまうなんて正気の沙汰じゃねぇ。

2010年6月25日金曜日

[メモ] Amakudari 2.0

[TNW] Facebook Poaches White House Official For Policy Position

あるいは集票システム2.0ってとこか。Googleがそうなんだが、組織運営において政治力が技術力より優先されるようになると、その組織はもう壊死寸前だよ。凍傷における処置と同様、切断しか手は無いわけで、敗血症を防ぐ為にさっさと切り離した方が良いと思うが。

2010年6月23日水曜日

[メモ] 今日は暴言の日

・ボタン付けも出来んヤツがガンプラ作ってんじゃねぇよw
・アドワーズお試しとかうぜぇんだよ、送って来んなボケ。
・おまえ意味と意義をごっちゃにしてねぇか。
・あぁ、それ歴史じゃないから。単なる二次創作だから。
・「他人の無知には寛容であれ、自分の無知には厳しくあれ」ごめんそれムリw
・鬼が恐かったら鬼になるしかない。いじめられたくなかったらいじめるしかない。かくして世界はいつまでたってもこのザマだ。

2010年6月22日火曜日

[メモ] ビットは撒き餌

早速買ったわけですよ『リューシカ・リューシカ(1)』と『男子高校生の日常(2)』

両者ともに素晴らしいという点につきましては、わたくしごときが申し上げるまでもないのでありますが、特にリューシカについては、これはもう万人が読むべき珠玉の一冊だと申し上げてよろしいかと存じます。読む人が何を意識しているかに応じて、ふさわしいシニフィエがページから立ち上がってくるのです。「わからない時はとにかくしゃべれ」という一節から、プログラマーならばコードレビュー、UIデザイナーならばスケッチやモックといった「アウトプット」を通じて新たなインプットを得るというフィードバック的・円環的開発姿勢に思い至ることでしょう。

で、内容についてもさることながら、IT托鉢たるわたくしといたしましては、電子書籍と従来型書籍の幸福な結婚により産まれたこの素晴らしいUXを褒め讃えずにはいられないのであります。ビットメディアで購入モチベーションを高め、紙メディアで通して読んで自らの血肉とするという、ある意味では昔から綿々と続いている黄金のパターンをガンガンONLINEは定着させたんだなという感がわたくしにはございます。ガンガンONLINEに限らず、『千夜千冊』然り『REWORK』然りでありまして、consumerにとってはもちろん、providerにとっても、まさに一粒で二度おいしいウハウハ状態だと申せましょう。

紙メディア全滅とか言ってる間抜けも居るようですが、アーカイビング・推敲・コンテキスト付与・校正といった紙メディアが培って来た編集的土壌は、ビットメディアが持つ低コスト・即時生といった価値とはまた別の価値を持ち、それはビットメディアだけではそう簡単に実現出来ないものであります。よって、紙メディアはビットメディアという良きパートナーを得て飛躍する可能性を掴んだと捉えるのが妥当であります。

逆に、紙メディアのコアコンピタンスである編集的土壌を持たないところはお役御免となるわけで、屍累々阿鼻叫喚はここしばらく続くのでしょう。S学館のアレとか見てるともうね、この内容でどうやって購入モチベーションを高めろと?としか言い様の無い状態ですしね。まぁ、淘汰されるべきはさっさと淘汰されるべしということかと存じます。

2010年6月18日金曜日

[Safari Extension] lookup.safariextz 1.0.12

lookup.safariextz - version 1.0.12

1.0.12 では設定UIでの行単位ドラッグが可能になっています。


各項目の枠線にカーソルを持っていくとカーソルが変わりますので、そのままドラッグして移動して下さい(ドラッグ中は上図の様に、枠線がオレンジ色になります)。

2010年6月17日木曜日

[Safari Extension] lookup.safariextz 1.0.11 を公開しました

lookup.safariextz - version 1.0.11

1.0.11 では、url の記述時にエンコード指定が出来るようになりました。これで goo国語辞書(eucjp)、やAMAZON(shiftjis)も利用可能です。

記述方法は、これまでの {} を拡張して
{utf8}
{shiftjis}
{eucjp}
という形でエンコード指定を行います。従来の {} 、つまり指定内容が空の場合は utf8 としてエンコードされます。

なお、エンコード指定は
  • 大文字は小文字に
  • ハイフンとアンダースコアは無視
してから処理されますので
  • utf-8, UTF-8, Shift_JIS, EUC-JP
といった記述も有効です。

2010年6月16日水曜日

[Safari Extension] ギャラリーへの提出受付が始まったようです

DARING FIREBALL のエントリにその旨記述がありましたので早速行って提出してみました。説明書き等を記入したわけですが「425x275 pxのスクリーンショットをpngで提出せよ」との記述があったのでスクショ撮って指定サイズ通りに切り出して提出したら「275x425じゃボケ」と突き返されました。泣く泣く作り直しましたw

で、めでたく



と相成りましたので、確認の為に Safari Dev Center に行ってみたところ



とのことでした。段取り悪いっすねw、というか私が勇み足だったのでしょうか。

それにしても、いくらまだステータスが experimental だからとはいえ、バイナリとアップデートマニフェストのホスティングは自分でやってね、というのは御無体ですな。やはりこの辺のこなれ具合は Google に一日の長ありといった印象です。


追記: 今行ってみたところ、登録ページSafari Dev Center ともに復帰してますね。よかったよかった。

2010年6月15日火曜日

[Safari Extension] lookup.safariextz 1.0.10 を公開しました

1.0.10 では、GMailページで検索を実行した場合にタブが2つ開いてしまうという不具合が解消されています。既に 1.0.9 にしている方は自動アップデートで 1.0.10 にアップデートされるはずです。それ以前のバージョンの方はこちらからどうぞ → lookup.safariextz

2010年6月14日月曜日

[Safari Extension] 自動アップデートに対応しました

lookup.safariextz --- version 1.0.9

このバージョン以降は自動でアップデートが行われるようになります。自動アップデートに関する記述を追加したのみなので、機能面としては 1.0.3 と変わりません。「アップデートを自動的にインストール」のチェックに関しましてはお好みでどうぞ
ちなみに、これまでは公開用バイナリ等をGitHubのDownloadsに置いていたのですが、どうやら同一ファイル名のまま(つまり同一URL)だとサーバサイドのキャッシュが使われるようで、すぐに更新を反映させる事が出来ませんでした。よって、暫定的にバイナリとアップデートマニフェストだけはDropboxの公開フォルダに置くようにしています。

さて、自動アップデートが出来るようになったからというわけではありませんが、不具合を一つ見つけましたので、1.0.10 で修正する予定です。

[メモ] 終風先生いつもごちそうさまです

[finalventの日記] 読売新聞社説 新常用漢字 日本語を豊かに表現しよう : 社説・コラム : YOMIURI ONLINE(読売新聞)

私の様な根性曲がりにとって、終風先生の「ふにゃふにゃな印象を与えつつも、実は背筋がぴしっとしている」という芸風は憧れなのであります。露伴を思わせるんですな。共通項は「家事が大好き」ですかね。

で、
UTF-8でも出ないか。まあ、そういう問題でもないが。
なんですが、「そういう問題」については「Unicodeに入っていない」ということで問題無いのですが「でもない」については、読み手の問題意識に応じてふにゃふにゃ、というか重層的に解釈する余地が残されています。

私は御覧の通りの根性曲がりなので
  1. 漢字制限なんてアホのすること
  2. 漢字はUnicodeで処理出来る、という考え自体が幻想
と解釈しました。

1.についてはもはや言うまでもないでしょう。戦後のどさくさに紛れてねじ込まれた「当用漢字表」「現代かなづかい」なる愚民化政策については、福田恆存『私の國語敎室』をはじめ、多方面でその弊害(この「害」にしても字形的には間違ってる。あやまれ、白川先生にあやまれ。まぁ、終風先生は白川先生を「と」だと言ってはりましたが)が述べられています。アホなデザイナーが作ったアーキテクチャのせいで、コード量がえらく増えてしまいました。文字コードの量も、それを処理するコードの量も。全く、こいつらのせいで、また休日出勤だぜ。

2.については、要は、我々が現在のコンピュータで日本語を使うというのは「トゥール・ダルジャンで、鴨料理をわさび醤油で食する」が如き暴挙なのだということなんですわ。コンピュータというものの背後にある、まさにゴチック建築のように堆く積上げられた「合理主義という名の神」への信仰告白(ちなみにRubyもこれですね)に目を向けようとする日本人は少ないです。その表面に紙を貼付けただけのハリボテを作り上げ、それを「日本のコンピュータ」と称する愚が現状には満ちあふれています。しょうがない、という側面はもちろんあります。現にこうやってUTF-8で書いているわけですし。

でもこれは、日本人(というか漢字を食べて来た民族一同)が、いつか自力で解決しなければならない問題なんですわ。道のりは遠く、玄月先生ですらツールについては全面的に既存のものに頼らざるを得ないという状況ではありますが、それでもなお我々は、コンピュータというもの、チューリングマシンというものを「和」の概念により分解・再構築するという使命を持っています。

なに、じっくりやりゃいいんですよ。我々の祖先は何百年もかけて漢字を食べ、消化し、日本語の血肉として来たじゃないですか。大丈夫です。森有礼とか表音主義者といった、足引っ張るバカは居ましたし、今もこれからも居るでしょうけど、こいつらは放置しときゃ自爆しますから、耳を貸さないようにすればOKです。

2010年6月13日日曜日

[Safari Extension] 設定用 UI を追加しました

version は 1.0.3 となっています。バイナリはこちらです。

  • 記述する内容の詳細は、昨日のエントリを参照して下さい
  • title, url, command のうちのどれか一つでも欠けると、その行はスキップされます
  • apply ボタンを押すと設定が書き込まれ、直ちにコンテキストメニューに反映されます
エディタで書いていた時はJSONのエスケープ文字を気にする必要がありましたが、これからはJSON.stringify()が面倒見てくれますので安心です。調子に乗って、色々と入れて遊んでいます。

2010年6月12日土曜日

[Safari Extension] lookup.safariextzのパターン定義の書き方

lookup.safariextz はバージョン 1.0.2 から、呼び出すサイトをユーザが独自に定義できるようになりました。



パターン定義の部分にJSON形式で記述すれば良いわけですが、これを素でいじるというのはどうみてもしんどいので、それっぽいUIを機能拡張ビルダーで作ろうと思い、昼間っからゴニョゴニョとやっておりました。

で、結論から申しますと「無理です」。この程度のパーツで一体どうしろとw

というわけで、Chrome Extensionでおなじみの、HTMLで設定用UIを書くという方針に変えました。しばらくかかりそうなので、お茶濁しではありますが、エディタでパターンを編集して貼付けるというありがちな方法を書いておきます。

まずは上の画面(Safari→環境設定→機能拡張→lookup)のパターン定義の内容をコピーして、エディタに貼付けると、こんな感じです。
[{"command": "googleEJ", "url": "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}", "title": "lookup: Google翻訳(英和)"},   {"command": "alc", "url": "http://eow.alc.co.jp/{}/UTF-8/?ref=sa", "title": "lookup: アルク"}, {"command": "ud", "url": "http://www.urbandictionary.com/define.php?term={}", "title": "lookup: Urban Dictionary"}]
このままだと扱いづらいのですが、そこはJSONですから、好きな書式に書き換えましょう。私はこんな感じにしています。
[
{
"command": "googleEJ",
"url": "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}",
"title": "lookup: Google翻訳(英和)"
},
{
"command": "alc",
"url": "http://eow.alc.co.jp/{}/UTF-8/?ref=sa",
"title": "lookup: アルク"
},
{
"command": "ud",
"url": "http://www.urbandictionary.com/define.php?term={}",
"title": "lookup: Urban Dictionary"
}
]
これでおわかりかと思いますが、基本的な構造は
[{site1},{site2}, ...]
と、個々のサイトの記述が配列に格納された形になっており、サイトの記述は
{"command": ---, "url": ---, "title": ---}
という3つの項目を持っています。

titleにはサイト名を、commandには何らかのユニークな文字列を入れてやります。urlはサイトに応じてパターンを見つける必要があります。たとえばgoo辞書(英和)でtestという単語を引き、URLを見ると
http://dictionary.goo.ne.jp/srch/ej/test/m0u/
となっていますので、testの部分を入れ替えてやれば他の単語も同様に引けるというのがわかります。lookup.safariextzはurl内の{}の部分を、ページ内で選択された単語やフレーズをencodeURIComponent()したもので置き換えるようにしていますので、この場合は
http://dictionary.goo.ne.jp/srch/ej/{}/m0u/
としてやれば良いという事になります。なお、辞書サイトの全てがこのパターンで行けるとは限らないのでご注意ください。POSTメソッドでないと駄目とか、文字コードはShift-jisでないと駄目といったタイプのサイトには、今のところ、lookup.safariextzは対応出来ません。

私はWikipedia(J)とウィクショナリー日本語版の2つを追加して、
[
{
"command": "googleEJ",
"url": "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}",
"title": " Google翻訳(英和)"
},
{
"command": "alc",
"url": "http://eow.alc.co.jp/{}/UTF-8/?ref=sa",
"title": " アルク"
},
{
"command": "ud",
"url": "http://www.urbandictionary.com/define.php?term={}",
"title": " Urban Dictionary"
},
{
"command": "wikipediaJ",
"url": "http://ja.wikipedia.org/wiki/{}",
"title": " Wikipedia(J)"
},
{
"command": "wiktionaryJ",
"url": "http://ja.wiktionary.org/wiki/{}",
"title": " ウィクショナリー日本語版"
}
]
という記述にしました。titleには、他の機能拡張のアイテムと並んでもまぎらわしくないように、頭にスペースを入れてみました。

あとはこれをパターン定義の項目にペーストしてやればOKということになるのですが、その前に、ちゃんとしたJSON形式になっているかどうか確認することをお勧めします。私はJSONLintでチェックしています。チェックしてみてOKだったら、記述をパターン定義の項目にペーストしてやりましょう。

適当なページを右クリックしてコンテキストメニューを表示すると



という具合に、新たな項目2つが追加されているのが確認出来ると思います。

ちなみにtitleは何を書いても構わないので
[
{
"command": "googleEJ",
"url": "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}",
"title": " ____ ∧ ∧"
},
{
"command": "alc",
"url": "http://eow.alc.co.jp/{}/UTF-8/?ref=sa",
"title": "|\ /(´~`)\"
},
{
"command": "ud",
"url": "http://www.urbandictionary.com/define.php?term={}",
"title": "| | ̄ ̄ ̄ ̄ ̄|"
},
{
"command": "wikipediaJ",
"url": "http://ja.wikipedia.org/wiki/{}",
"title": "| |=みかん=|"
},
{
"command": "wiktionaryJ",
"url": "http://ja.wiktionary.org/wiki/{}",
"title": " \|_____|"
}
]
と記述すると



といった感じのコンテキストメニューになります。こう見えても、耳の部分を選べばGoogle翻訳が、みかんの部分を選べばWikipedia日本語版がきちんと呼び出されます。はてしなく使いづらいですがw

ちなみにメニューアイテム個数の上限は今のところ10個までとなっています。そのため、12行のクマーAAをtitleに入れてみたところ足が切れてしまいました。ならば、ということで機能拡張ビルダーでメニューアイテムを100個くらいまで増やしたれ、と手を動かしかけましたが、何か間違ってるような気がしましたのでやめましたw

2010年6月11日金曜日

[Safari Extension] change イベントのターゲットは safari.extension.settings

lookup.safariextz のバージョンが 1.0.2 になりました。バイナリはこちらです。変更内容の詳細は、GitHubリポジトリにも記述がありますが「設定変更時に発生する change イベントを拾って、パターン定義の変更が直ちにコンテキストメニューへ反映されるようにした」というものです。

この件に関しましてはちょっと躓きまして、タイトルにもあります通り「change イベントは safari.application ではなく safari.exstension.settings で addEventListener しなきゃ駄目」という事に気付くまでは、イベントが全然入って来ないので頭を抱えておりました。ドキュメント
The target of the event is the settings or secureSettings object.
という一文を見落としていたと言うわけです。ドキュメントはきちんと嫁ということですなw

[Google] せやからゆうたやん

[GigaOM] Poll: Do You Like Google’s New Background Images?
[TNW] No More Pretty Picture Suggestions On Google.com

案の定といったところだが、それにしても最近の Google は戦略面においてこういった脇の甘さが目立つ。企業というものはどうしても、でかくなると、多角化・顧客重視などといった美名のもとでこういった「リソースをドブに捨てる」行為を行ってしまう運命にあるのだろうか。コアコンピタンス分野において最近発表された目立つ成果といえば Caffeine くらいかなという印象なのだが、これにしたって "disruptive" だとはお世辞にも言えない。どうやら順調に Microsoft の轍を踏みつつあるようだ。

[Safari Extension] コンテキストメニューの動的書き換え

レファレンスを見る限りでは、safari.extensionにcontextMenuプロパティがあり、appendContextMenuItemメソッドによりアイテムを追加できそうに見えるのですが、インスペクタで見てもそれらしきプロパティは見当たりません。Global HTML がロードされた時にonloadハンドラ内でコンテキストメニューを構築すれば良いだろう、と考えていたんですがアテが外れました。

頭を抱えていたのですが、イベント受信時にSafariExtensionContextMenuItemがevemt.targetとして渡されるということがわかったので、これのtitle, command, disabledプロパティを設定することでコンテキストメニューを書き換えるという手でやってみましたところ上手くいきました。書き換えるタイミングは、コンテキストメニューが実際に表示される前に発行されるvalidateイベントを受信した段階で、ということになります。

コンテキストメニューに関して制御出来るのはtitleとcommandの書き換えおよびdisabledの設定によりアイテムの表示/非表示を切り替えることだけで、新たにアイテムを追加する事は出来ません。よって、機能拡張ビルダーでダミーのアイテムをあらかじめ10個ほど確保しておきます。こんな感じです。



実際に表示するタイトルとコマンドは設定から読み込みます。patternというキー名で、中味はJSON形式で記述することにしました。



設定はサイト毎に
{"command": "googleEJ", "url": "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}", "title": "lookup: Google翻訳(英和)"}
と記述したものを配列でまとめています。ちなみにurlの{}の部分は、単語やフレーズをencodeURIComponent()したもので置き換えられます。

実際の書き換え処理はvalidateイベントのリスナーで行います。ビルダーで登録したアイテム数ぶんvalidateイベントが発生しますので、設定の個数ぶんだけtitleとcommandを書き換え、余った分はdisabled=trueとして非表示にしています。以下はGlobal HTMLの一部です。initAll()はonloadハンドラで、設定をvar patternに読み込み、addEventListenerでvalidateイベントを監視しています。
var pattern = undefined;
function initAll() {
pattern = JSON.parse(safari.extension.settings.pattern);
safari.application.addEventListener(
"validate",
function(event) {
if (event.command < pattern.length) {
event.target.command = pattern[event.command].command;
event.target.title = pattern[event.command].title;
event.target.disabled = false;
}
else {
event.target.disabled = true;
}
},
false
);
...
という感じで、とりあえず目的は達成したのですが、このやり方はかなりややこしいですね。邪道ぽいですし。やはりレファレンス通り、appendContextMenuItem等で制御出来るようになるのを待った方が賢明かもしれません。

以上の追加内容はGitHubにバージョン1.0.1として上がっていますので、詳細はそちらを御覧下さい。

2010年6月10日木曜日

[Safari Extension] 辞書サイトを開く機能拡張 (lookup.safariextz) を GitHub にアップしました

一昨日から、ちまちまと Safari Extension をいじっております。公開するならもう少し機能面を充実させてから、などと考えておりましたが、ちょっと壁にぶちあたりましたので、とりあえず現状レベルで公開する事にしました。人柱スキーな方にしかお勧め出来ませんw
現状では呼び出せる辞書サイトが
  • Google翻訳(英→和)
  • アルク
  • Urban Dictionary
だけなので、これはユーザが追加/削除出来るようにしておきたいところですが、これは設定画面を用意するだけでは実現が困難です。というのも、コンテキストメニューにユーザが追加したサイトを動的に追加する必要があるからです。

こちらの資料を見ると、SafariExtensionContextMenu クラスに appendContextMenuItem といったコンテキストメニューを操作するメソッドが用意されているのですが、インスタンス (safari.extension) を見る限りではプロパティが存在しません。Safari Extension まわりはまだまだ開発中という事ですし、このへんに関しましても徐々に実装が進められるということなのでしょう。

2010年6月9日水曜日

[Safari Extension] safariextz の解凍

Safari Extension ファイルには safariextz という拡張子が付いていますが、これは XAR パッケージなので xar コマンドで解凍出来ます。コマンドラインは
$ xar -xf [filename]
でOKです。ちなみに safariextz ファイルが格納されている場所は
~/Library/Safari/Extensions
ですね。

2010年6月8日火曜日

[Safari Extension] injected script が複数個ロードされる場合があるんだが

Webインスペクタを見て気付いたのですが、どうやらページによっては injected script が複数個ロードされることがあるようです。よって、Global HTMLからinjected scriptへのdispatchMessageが複数回行われる事になってしまいます。今回作ったものですとロードされた injected script の数だけタブが開いてしまうので、ページによっては「ブラクラかよw」という状況になっていました(GigaOMなんかがそう)

とりあえずの回避策として、無効な injected script では document.getSelection()が常に undefined を返すので、その場合は Global HTML に対する dispatchMessage を発行しないようにしました。根本的な原因はまだわからないので、勉強かたがたドキュメントを隅々まで読んどかなあきまへんな。

injected.js
safari.self.addEventListener(
"message",
function(msg) {
const pattern = {
google: "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}",
alc: "http://eow.alc.co.jp/{}/UTF-8/?ref=sa",
ud: "http://www.urbandictionary.com/define.php?term={}"
};
var w = document.getSelection().toString();
if (w) {
safari.self.tab.dispatchMessage(pattern[msg.name].replace("{}", encodeURIComponent(w)));
}
},
false
);

[Programming] Safari Extension を作ってみた

Google Chrome に見切りを付けた私といたしましては渡りに舟ということで、早速、手を出してみました。まだ大雑把にしか把握してませんが、流石はWebKitベースという事で、アーキテクチャが Chrome Extension にそっくりです。
  • Global HTML は Chrome で言うところのバックグラウンドページ
  • injected Scripts → content_scripts
  • Extension Bar → ブラウザアクション
  • dispatchMessage → chrome.extension.sendRequest
  • info.plist → manifest.json
といった感じですね。

試しに作ってみたのは、ページ内の単語やフレーズをGoogle翻訳、アルク、Urban Dictionaryといった辞書サイトに渡して新規タブにて表示するというものです。マウスで単語を選択しコンテキストメニューからどの辞書サイトを呼ぶかを選ぶようにしています。


構成は Global HTML と injected script の組み合わせという事になります。以下は現状のソースです。

global.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" charset="utf-8">
function initAll() {
safari.application.addEventListener(
"command",
function(event) {
safari.application.activeBrowserWindow.activeTab.page.dispatchMessage(event.command);
},
false
);
}
</script>
<title>test - Global HTML page</title>
<body onload="initAll();">
</body>
</html>

injected.js
safari.self.addEventListener(
"message",
function(msg) {
var w = document.getSelection().toString();
switch (msg.name) {
case "google":
window.open("http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|" + encodeURIComponent(w), "_blank");
break;
case "alc":
window.open("http://eow.alc.co.jp/" + encodeURIComponent(w) + "/UTF-8/?ref=sa", "_blank");
break;
case "ud":
window.open("http://www.urbandictionary.com/define.php?term=" + encodeURIComponent(w), "_blank");
break;
}
},
false
);

info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>lookup</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.lookup</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>Chrome</key>
<dict>
<key>Context Menu Items</key>
<array>
<dict>
<key>Command</key>
<string>google</string>
<key>Identifier</key>
<string>google</string>
<key>Title</key>
<string>Google翻訳</string>
</dict>
<dict>
<key>Command</key>
<string>alc</string>
<key>Identifier</key>
<string>alc</string>
<key>Title</key>
<string>アルク</string>
</dict>
<dict>
<key>Command</key>
<string>ud</string>
<key>Identifier</key>
<string>ud</string>
<key>Title</key>
<string>Urban Dictionary</string>
</dict>
</array>
<key>Global Page</key>
<string>global.html</string>
</dict>
<key>Content</key>
<dict>
<key>Scripts</key>
<dict>
<key>Start</key>
<array>
<string>injected.js</string>
</array>
</dict>
</dict>
<key>ExtensionInfoDictionaryVersion</key>
<string>1.0</string>
<key>Permissions</key>
<dict>
<key>Website Access</key>
<dict>
<key>Level</key>
<string>All</string>
</dict>
</dict>
</dict>
</plist>

なんといってもコンテキストメニューがさっくり使えるのがうれしいですな。まだ設定画面等については未調査ですが、ざっくりと見た感じでは Chrome Extension よりも使い出がありそうです。機能拡張ビルダーまわりは、まだまだこなれてないようで良く落ちるんですが、まぁこれはそのうち改善されるでしょう。そういえば「拡張機能」じゃなくて「機能拡張」なんすよね。INIT/cdev時代を知るものにとっては、やっぱり「機能拡張」の方がしっくり来るんですわw

処理の流れとしては
  1. コンテキストメニューからどのサイトを開くかを選択するコマンドを発行
  2. Global HTML がコマンドを受信
  3. Global HTML はページ内コンテンツにアクセス出来ない(つまりページ内の単語やフレーズが拾えない)ので injected script に対して dipatchMessage を発行し、その際にパラメータとしてコマンドを引き渡す
  4. injected script は document.getSelection() により、ページ内の単語やフレーズを取得し、コマンドに応じたサイトのURL を生成し、window.open(url, "_blank") により新規タブでページを開く
という感じです。

ちなみに window.open()でタブを開いているので、ポップアップが禁止されていると(「Safari→ポップアップウィンドウを表示しない」にチェックが入ってると)ページが開きません。これは問題ですね。これを回避する為には safari.self.browserWindow.openTab() といった Window/Tab 関連の新規 API を呼ぶしか無いようですが injected scripts からはこれらの API が呼べないようです。ということは、injected scripts から Global HTML に URL を渡す dispatchMessage を発行するってことですか。結構めんどくさいかもw


追記: Global HTML 側で openTab() を呼び出すように変更。それほど面倒じゃないですね。アプリとコンテンツの分離という観点からすれば、これはこれで一貫性があると言えましょう。

global.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" charset="utf-8">
function initAll() {
safari.application.addEventListener(
"command",
function(event) {
safari.application.activeBrowserWindow.activeTab.page.dispatchMessage(event.command);
},
false
);
safari.application.addEventListener(
"message",
function(msg) {
var newTab = safari.application.activeBrowserWindow.activeTab.browserWindow.openTab();
newTab.url = msg.name;
},
false
);
}
</script>
<title>test - Global HTML page</title>
<body onload="initAll();">
</body>
</html>

injected.js
safari.self.addEventListener(
"message",
function(msg) {
const pattern = {
google: "http://translate.google.co.jp/?hl=ja&tab=wT#en|ja|{}",
alc: "http://eow.alc.co.jp/{}/UTF-8/?ref=sa",
ud: "http://www.urbandictionary.com/define.php?term={}"
};
safari.self.tab.dispatchMessage(pattern[msg.name].replace("{}", encodeURIComponent(document.getSelection().toString())));
},
false
);

[Apple] Safari 5 に extension キタキタ

ソフトウェアアップデートに項目がありましたので早速アップデートし、現在、ドキュメントを漁っているところ。

2010年6月2日水曜日

[GigaOM] Google TV は WebTV の二の舞になるのか?

[GigaOM - NewTeeVee] Is Google TV WebTV Part Deux?

こんなエントリを上げたわたくしといたしましてはニヤニヤしながらこの記事を読ませていただいたわけであります。

内容は、Michael Gartenberg が Engadget に寄稿した「やぁ、WebTV パート2さんじゃないですか(笑)という記事に対する批判といったところ。Gartenberg の「ユーザはテレビでブラウジングしようなんて思っちゃいないってのはリサーチで既に何度も確認されてますやん」といった主張を認めつつも「いや、視聴者がWeb上で体験する内容は昔とは全然変わったよ、特にビデオはね」「HuluとかYouTubeなんてテレビにクリソツじゃないっすか」「他社のタブレットPCが総崩れになった後、iPad は実に良いタイミングでリリースされ、ユーザに受け入れられた。Google TVも、今こそ条件が揃ったと言えるんじゃないすかね」と主張している。まぁ、身内思いから出た援護射撃という線も無きにしもあらずなんだが、それにしても歯切れの悪さは否めない。

私から見れば、これってどう見ても分の悪い博打なんだけどね。いまどき「みんなで仲良くコラボしましょう」じゃねぇだろとw。で、これって「こける時も一緒にね♥」ということでもあるんだが、ここでコケたところでGoogle的には屁でもないんだろうけど、気合い入りまくりな某社とかは、うん、どうなんでしょ。いや、なんかね、HTPCとかUMPCとかいったキーワードに踊らされた頃のことを思い出しまして、ちょっと不安になったんですわw

テクノロジー云々ではなく「広告ビジネスの終焉」というコンテキストで捉えれば、結果は自ずと見えてくるはずなんですけどね。ブッフハイトはあくまでも AdSense を「オマケ」として作ったんすよw

[メモ] 「可愛さ=足の多さ」説が否定されましたw

[GRAPH JAM] Cuteness vs. Number of Legs

ということで、河飯家の女性陣にとっては到底受け入れ難い数字が出ております。画一的な審美眼の蔓延についてはわたくしといたしましても深く憂慮するところでありますが、コメント欄には「タランチュラはハムスターやウサギよりも可愛いじゃん」「イカは腕が8本と触手が2本もあって可愛いよ」「それ私が言いたかったのに〜」「腕が6本で足が2組なんじゃね?」「どっちにしても可愛いから問題無し」といった心強い主張が見られ、ほっと胸をなでおろしております。

[メモ] 猫も杓子もソーシャルw

[the Atlantic] Caring for Your Introvert

Jason Kottke が採り上げたこの記事、実に示唆に富んでいる。まぁ、早いハナシが、内向性=ネガティブとしか捉えられないバカや、なうなう言ってるアホはさっさと死んでくれってことですなw