2009-12-26

Google Wave Gadgets でできることを OpenSocial や Shindig の視点で調べてみました

おはようございます。Nobuhiro Nakajima です。

OpenSocial jQuery は Google Wave Gadgets でも使えるようになりますか... という質問がありました。現状の OpenSocial jQuery のまま gadgets.* API は使えます。また wave.* API はそもそも考慮していません。が答えです。

実例として公開している YouTube ガジェット がありますが、次のとおり Google Wave Gadgets としてそのまま動きます。このように Google Wave で OpenSocial jQuery はすぐに試せます。



Wave Gadgets も iGoogle や Google Friend Connect (GFC) と同じ Apache Shindig 上で構成していると考えられます。ですので、gadgets.* API の振る舞いも同じであり、OpenSocial jQuery がそのまま使えるということになりそうです。

本当にそうなの... という疑問が残るので、Wave Gadgets を Shindig 視点でいろいろ調べてみました。調べたのは Wave Preview です。Sandbox ではありません。

ガジェットのレンダリング

iframe URL を抜粋します。見てのとおり Shindig の Gadgets Rendering Server です。HTTPS (Secure) プロトコルが特徴的です。ホストは googleusercontent.com で iGoogle や GFC の gmodules.com とは異なるので別系統なのでしょう。container パラメータも wave なので、同系統であったとしても、コンテナのプロファイルは別なのでしょう。
https://lq3n3peeciqdlq351d7pd2pqtuvr30al-a-wave-opensocial.googleusercontent.com/gadgets/ifr
?v=b893d00cffa7bf86acedda54be7a116
&container=wave
&view=canvas&
&lang=en&
&url=http://example.com/gadgets.xml
&country=ALL
&libs=core%3Adynamic-height%3Alocked-domain ...
&mid=5
&nocache=1
&parent=https://wave.google.com ...
#rpctoken=...
&st=...
libs パラメータを観察したところ、ガジェットXML の feature を表すようですので、Google Wave 側もガジェット XML の内容を認知しているのでしょう。

view パラメータは、常に canvas のようです。ガジェットXML で profile や home を指定すると、次のエラーとなりますので、canvas ビューのみサポートするのでしょう。既定のビューが canvas ということになるのかな。
Unable to locate an appropriate view in this gadget. Requested: 'canvas' Available: [home]
Unable to locate an appropriate view in this gadget. Requested: 'canvas' Available: [profile]
nocache パラメータは、常に 1 (キャッシュなし) のようです。iframe のソースコードを見ても concat されていませんので、開発中のキャッシュ制御は気にしなくてもよさそうです。

rpctoken パラメータが付与されてますので、クロスホストなデータ通信は gadgets.rpc なのでしょう。iframe のソースコードを見ると gadgets.rpc と gadgets.rpctx が含まれますので、すべてのブラウザで URL flagment (rpc_relay.html) は使われないでしょう。

st パラメータが付与されてますので、Phone home (gadgets.io.makeRequest)の仕組みも同じでしょう。

setprefs feature

Wave Gadgets のドキュメントでサポートすると記載があります。ガジェットXML の UserPref は認知しており、API でも取得できました。ただ API で設定できますが、(確認した限りは)永続化できませんでした。また、UserPref を編集するための UI も提供されていないようです。本当か。

dynamic-height feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に API は存在し、期待どおり動作しました。

settitle feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に API は存在し、呼び出してもエラーにはなりませんが、指定したタイトルがどこで表示されるのか確認できませんでした。

tabs feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に API は存在し、期待どおり動作しました。

minimessage feature

Wave Gagets のドキュメントでサポートすると記載があります。実際に API は存在し、期待どおり動作しました。

locked-domain feature

Wave Gadgets のドキュメントでサポートすると記載があります。実際に locked-domain なしでガジェットを wave に貼り付け、その後 locked-domain ありとして再表示すると、"Invalid domain" というエラーとなるため、機能しているのでしょう。

view feature

Wave Gadgets のドキュメントでサポートすると記載はありません。が、実際に API は存在しました。ただ、サポートするビューは profile と canvas という結果で、前述の結果とズレがあります。また、ビューの移動は API が無反応でした。

opensocial-0.8 feature

Wave Gadgets のドキュメントで OpenSocial API は未サポートと記載があります。が、実際に API は存在しました。実際に Person の取得を試みたところ、次のエラーとなりました。
Malformed security token ...&c=wavecom.google.gadgets.auth.AuthTokenException: Failure for container wave
Wave は Contact ベースの関係のようですので、OpenSocial に対応するなら iGoogle モデルになるのかなという印象です。もうできてたりして。

といったところを調べてみました。結果、現状の OpenSocial jQuery のまま gadgets.* API なら使えることが把握できました。役に立ちそうであれば使ってみてください。

2009-12-21

メッセージの表示に加え、明示的もしくは自動的にメッセージを閉じる強化をした OpenSocial jQuery Mini Message プラグインを公開しました

おはようございます。Nobuhiro Nakajima です。

OpenSocial jQuery は jQuery.fn.minimessage メソッドで Mini Message を限定的にサポートしてきましたが、このたび OpenSocial jQuery Mini Message としてプラグイン化して、使える機能を強化しました。従来の機能に加えて、明示的もしくは自動的にメッセージを閉じることができるようになりました。

今後、メッセージの表示は OpenSocial jQuery Mini Message プラグインを使ってください。従来の Mini Message は Deprecated 非推奨となり、OpenSocial jQuery 1.3.2.5 以後のバージョンで使えなくなります。

OpenSocial jQuery Mini Message プラグインの使い方は、次のとおりです。質問や要望がありましたら OpenSocial jQuery Discussion までお願いします。

OpenSocial jQuery 本体に続けて、OpenSocial jQuery Mini Message をロードしてください。
<script src="opensocial-jquery.js" type="text/javascript"></script>
<script src="opensocial-jquery.minimessage.js" type="text/javascript"></script>
OpenSocial jQuery Mini Message は minimessage を必要とします。
<Require feature="minimessage" />
閉じるボタン付きのメッセージを表示する

jQuery.fn.minimessage を使って、閉じるボタン付きのメッセージを表示できます。
$('<span/>').text('Say Hello!').minimessage();


また jQuery.fn.minimessage にコールバック関数を指定して、閉じるイベントをハンドリングできます。コールバック関数の戻り値を false とすると、イベントは無効となり、メッセージは閉じません。
$('<span/>').text('Dismissible Message with Callback')
  .minimessage(function() {
    return confirm('Do you close a message?'); // 閉じるかどうか?
  });
メッセージを閉じる

jQuery.fn.remove を使って、メッセージを閉じることができます。
var message = $('<a/>').text('Remove Message')
  .click(function() {
    message.remove(); return false;
  }).minimessage();
});
自動的にメッセージを閉じる

jQuery.fn.minimessage を使って、自動的に閉じるメッセージを表示できます。秒数か fast, normal, slow のいずれかを指定します。

* fast を指定すると、1秒後にメッセージを閉じます。
* normal を指定すると、3秒後にメッセージを閉じます。
* slow を指定すると、5秒後にメッセージを閉じます。
$('<span/>').text('Timer Message')
  .minimessage(3); // 3秒後に閉じる
$('<span/>').text('Timer Message with Predefined Speeds')
  .minimessage('slow');
また jQuery.fn.minimessage にコールバック関数を指定して、閉じるイベントをハンドリングできます。
$('<span/>').text('Timer Message with Callback')
  .minimessage('fast', function() { // 3秒後に閉じる
    alert('The message was closed.');
  });
実例

* OpenSocial jQuery Mini Message Test Suite

2009-12-14

mixi.util.requestExternalNavigateTo を使った外部サイトの誘導を jQuery.fn.live で自動化する方法

こんばんは。しゃっくりが止まらなくなって、丸2日になろうとしてる Nobuhiro Nakajima です。

mixi アプリは jQuery.view (= mixi.util.requestExternalNavigateTo) を使って、ユーザを外部サイトに誘導します。というネタを使って、ちょっとした Tips を紹介します。

次のソースコードは、外部サイトのリンクのクリックイベントを捕捉して jQuery.view を使って外部サイトに誘導するものです。(1) はあらかじめ用意した静的なリンク、(2) は RSS フィードを取得して動的生成したリンクで、それぞれ jQuery.view を使って外部サイトに誘導しています。
// (1) 静的リンク
  $('a[target=_blank]').click(function() {
    $.view(this.href); return false;
  });
  // (2) 動的リンク
  $.getFeed('http://rss.rssad.jp/rss/gihyo/feed/atom', function(feed) {
    $.each(feed.Entry, function(i, entry) {
      var a = $('<a target="_blank">')
        .attr('href', entry.Link)
        .text(entry.Title)
        .click(function() {
          $.view(this.href); return false;
        });
      $('<li/>').append(a).appendTo('ul');
    });
  });
<ul></ul>
Powered by <a href="http://code.google.com/p/opensocial-jquery/"
  target="_blank">OpenSocial jQuery</a>
静的リンクにせよ、動的リンクにせよ、外部サイトに誘導するというコードはまったく同じです。また、動的リンクを頻繁に生成するときは、その都度、クリックイベントと jQuery.view のコードを書くことになります。その結果、コードは冗長になりますし、テストケースも増加します。つまり、不健全です。

これ jQuery.fn.live を使うと、次のように自動化できるんです。ここでは target="_blank" のリンクは、外部サイトのリンクと決まりごとにしています。そして jQuery.fn.live を使って、target="_blank" のリンクにクリックイベントを登録し、外部サイトに誘導するようにしています。

たったこれだけで、静的リンクと動的リンクに関わらず、HTML 中に外部サイトのリンクが生成された時点で(あらかじめ存在するのも含む)、自動的にクリックイベントが登録され、外部サイトに誘導するリンクに早変わりします。live というメソッド名からもイメージできるでしょう?
$('a[target=_blank]').live('click', function() {
    $.view(this.href); return false;
  });
  $.getFeed('http://rss.rssad.jp/rss/gihyo/feed/atom', function(feed) {
    $.each(feed.Entry, function(i, entry) {
      var a = $('<a target="_blank">')
        .attr('href', entry.Link)
        .text(entry.Title); // click イベントを登録してない!?
      $('<li/>').append(a).appendTo('ul');
    });
  });
実際に上のソースコードを動かすと分かりますが、RSS フィードのリンクにクリックイベントを登録していないにも関わらず、jQuery.view で外部サイトに誘導されます。RSS フィードを再取得して再表示しても同様です。

jQuery.fn.live は、いろいろ制約があるので、使えるシーンは限られるのですが、頻繁に HTML を動的生成する中で、コールバック関数外の状態に依存しない定型的なイベントブロックを多用するとき、とても役立つと考えます。その1例が、外部サイトの誘導ということです。

2009-12-09

OpenSocial jQuery に mixi Platform 固有の拡張機能を追加する jQuery プラグインを公開しました。

おはようございます。ちょっと体調のすぐれない Nobuhiro Nakajima です。

OpenSocial jQuery mixi Platform 1.0.0 をリリースしました。
http://code.google.com/p/opensocial-jquery/ -- Downlaod
http://code.google.com/p/opensocial-jquery/wiki/PluginMixi -- Document

OpenSocial jQuery mixi Platform は mixi 固有の拡張機能を OpenSocial jQuery に追加するための jQuery プラグインです。OpenSocial jQuery 本体に続けて、OpenSocial jQuery mixi Platform をロードして使ってください。
<script type="text/javascript" src="opensocial-jquery.js"></script>
<script type="text/javascript" src="opensocial-jquery.mixi.js"></script>
外部サイトに誘導する

jQuery.view を使って、外部サイトに誘導できます。このとき、外部サイトの URL を指定します。また、パラメータを指定すると QUERY_STRING に変換して URL に付与します。
// http://www.google.com/
$.view('http://www.google.com/');

// http://www.google.com/search?q=corgi
$.view('http://www.google.com/search', { q: 'corgi' }); 


ただし mixi の URL を指定したときは、外部サイトとみなさず、即ページ遷移します。
// http://mixi.co.jp/
$.view('http://mixi.co.jp/');

// http://mixi.jp/show_profile.pl?id=0123456789
$.view('http://mixi.jp/show_profile.pl', { id: '0123456789' });
また、従来どおり、ビューの切り替えや現在のビュー名の取得もできます。
$.view('profile');
$.view('home');
$.view('canvas', { q: 'corgi' });
console.info($.view()); // profile, home, canvas
参加コミュニティを取得する

jQuery.getData を使って、ユーザの参加コミュニティを取得できます。このとき url に /communities からはじまるパスと @viewer, @owner, ユーザID のいずれかを指定します。jQuery.ajax や jQuery.get も同様です。
$.getData('/communities/@viewer/@self').next(function(communities) {
  $.each(communities, function(i, community) {
    console.info(community.id); // コミュニティID
    console.info(community.userId); // ユーザID
    console.info(community.url); // コミュニティURL
    console.info(community.name); // コミュニティ名
    console.info(community.thumbnailUrl); // コミュニティ画像
  });
  console.info(communities.totalResults); // 参加コミュニティ数
}).error(function(e) {
  alert(e+'');
});
学校を選択する

jQuery.getData を使って、VIEWER の母校や在学中の学校を選択できます。このとき url に /schools からはじまるパスと @selected を指定します。jQuery.ajax や jQuery.get も同様です。
$.getData('/schools/@selected').next(function(schools) {
  var school = schools[0];
  console.info(school.token); // 学校トークン
  console.info(school.divisionId); // 学校区分ID
  console.info(school.division); // 学校区分名
});


学校リストを取得する

jQuery.getData を使って、VIEWER の母校や在学中の学校リストを取得できます。このとき url に /schools からはじまるパスと @viewer を指定します。jQuery.ajax や jQuery.get も同様です。
$.getData('/schools/@viewer/@self').next(function(schools) {
  $.each(schools, function(i, school) {
    console.info(school.token); // 学校トークン
    console.info(school.divisionId); // 学校区分ID
    console.info(school.division); // 学校区分名
  }
  console.info(schools.totalResults); // 学校数 = schools.length
}).error(function(e) {
  alert(e+'');
});
マイミクを招待する

jQuery.invite を使って、マイミクを招待できます。このとき @friends を指定します。招待したマイミクのユーザIDリストを取得できます。
$.invite('@friends', function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
});


また @friends を省略しても同じことができます。
$.invite(function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
});
さらに Deferred チェーンを使っても同じことができます。
$.invite('@friends').next(function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
}).error(function(e) {
  alert(e+'');
});
同級生を招待する

jQuery.invite を使って、同級生を招待できます。このとき @classmates を指定します。招待した同級生のユーザIDリストを取得できます。
$.invite('@classmates', function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
});


さらに Deferred チェーンを使っても同じことができます。
$.invite('@classmates').next(function(ids) {
  $.each(ids, function(i, id) { console.log(id) }); // ユーザIDリスト
}).error(function(e) {
  alert(e+'');
});
コンテナを判別する

jQuery.container.mixi を使って、コンテナが mixi Platform かどうか判別できます。
他コンテナも含めて 1つの JS ファイルにまとめるときに役立ちます。
if ($.container.mixi) { ... } // mixi Platform
.mixi クラスを使って、コンテナが mixi Platform かどうか判別できます。
他コンテナも含めて 1つの CSS ファイルにまとめるときに役立ちます。
<style type="text/css">
.mixi p { color: red; } /* mixi Platform */
</style>
OpenSocial jQuery に対する質問や要望は Google Group で受け付けています。開発中の最新情報も入手できます。ぜひご参加ください。

OpenSocial jQuery Discussion
http://groups.google.com/group/opensocial-jquery

-- 2009-12-10 スクリーンキャプチャの追加

2009-12-05

Golazo MA4 - ここで何する? を閉鎖しました。ソースコードは引き続き提供します。

おはようございます。Nobuhiro Nakajima です。

Mashup Awards 5 応募者の参考になればと思い、Mashup Awards 4 受賞作品である Golazo MA4 - ここで何する? を公開し続けてきましたが、

Golazo MA4 - ここで何する?
http://golazo.offtheball.jp/
Golazo MA4 は、ウェブページや入力した文章の内容から位置情報を自動抽出し、その内容と位置情報をメモとして、簡単にクリッピングできるサービスです。

本日(12/5)、Mashup Awards 5 の受付終了と受賞者発表に伴い、サイトを閉鎖しました。アカウントの情報とデータもすべて破棄し、バックアップのデータも破棄しました。

Golazo MA4 のソースコードは、引き続き公開していきますので、ご活用ください。

golazo - Project Hosting on Google Code
http://code.google.com/p/golazo/

ありがとうございました。