読者です 読者をやめる 読者になる 読者になる

Window Gadgetを制作したときのメモ

Gadget概要

http://twitter.com/shogo4405/の過去ログを任意の数取得してフライアウト(Gadgetの横側に飛び出してくるWindowのこと)に表示するGadgetです。(任意の人のidを入力してその人の過去ログひっぱてくるGadgetのほうがはるかに面白い気が…。)
Gadgetつくっていてテンプレートエンジン欲しかったのでJSmartyをGadget対応にしました。リビジョン番号312から対応しています。

困ったこと

ファイル入力に関してJSmartyのAPIを利用しているので必然的にXMLHttpRequestになるんですが…。相対パス指定だとFileSystemObject含めてそんなファイルないよ!と怒られる始末。そもそも相対パスとカレントがどこになっているのかという話もありますが…。

xhr = new ActiveXObject('Msxml2.XMLHTTP');

// ダメ怒られる。
xhr.open('GET', './hoge.txt', false);
xhr.send('');

// 正常に取得可能
xhr.open('GET', System.Gadget.path + '/hoge.txt', false);
xhr.send('');

Gadgetのインストール先のパス取得するにはSystem.Gadget.pathを利用できるので覚えておくとベター。

制作したファイル

主要なファイルについて解説とソースそのまま貼り付け。

gadget.xml

gadgetの設定ファイル。一番最初のメインのHTMLが何かとか著作権とかバージョン情報を色々と明記する。

<?xml version="1.0" encoding="utf-8" ?>
<gadget>
    <name>TwitterS</name>
    <version>1.0.0.0</version>
    <author name="shogo4405">
        <info url="http://d.hatena.ne.jp/shogo4405/" />
        <logo src="" />
    </author>
    <copyright>-</copyright>
    <description>-</description>
    <icons>
        <icon width="130" height="50" src="" />
    </icons>
    <hosts>
       <host name="sidebar">
           <base type="HTML" apiVersion="1.0.0" src="twitters.html" />
           <permissions>Full</permissions>
           <platform minPlatformVersion="1.0" />
           <defaultImage src="" />
       </host>
    </hosts>
</gadget>
TwitterS.js

こんかいのGadgetでメインとなるjs。コメント付きでそのままソースをコピペ。

// php.http_build_query.jsをグローバルスコープにインポート。
// これ以降、http_build_queryが利用できるなる。
JSmarty.Plugin.importer(
    'php.http_build_query'
);

// ショートカット
function $(id){
    return document.getElementById(id);
};

// 名前空間の作成
TwitterS = {};

// JSmartyのインスタンス作成
TwitterS.Html = new JSmarty();

// DOMによるTwitterAPI動的呼び出し。
// http_build_queryでAPIに渡すコールバック関数や取得数のクエリを作成
// している。
TwitterS.getScript = function(func)
{
    var script  = document.createElement('script');
    var query = http_build_query({callback : func, count : $('idUserId').value || 7 });

    script.type = 'text/javascript';
    script.src  = 'http://twitter.com/statuses/user_timeline/4565321.json?' + query;

    document.getElementsByTagName('head').item(0).appendChild(script);
};

// JSONが呼び出された際のコールバック関数。
// System.Gadget.Flyout.documentで横側に飛びてきた画面(Flyout)
// のDOMが取得できる。JSmarty#fetchを利用しているのはテンプレート処理の
// 結果を文字列として取得したいため。
TwitterS.onLoadScript = function(json)
{
    var Html = TwitterS.Html;
    var document = System.Gadget.Flyout.document;

    Html.assign_by_ref('status', json);
    document.getElementById('result').innerHTML = Html.fetch('timeline.html');
    Html.clear_all_assign();
};

TwitterS.updateFlyout = function(func)
{
    return function(){
        TwitterS.getScript(func);
    };
};

// Twitterでは"."つきのコールバック関数名をサポートしていないので、
// updateにTwitterS.onLoadScriptをマッピングしている。
update = TwitterS.onLoadScript;

window.attachEvent('onload', function()
{
    var idSubmit = $('idSubmit');
    var idUserId = $('idUserId');

    idSubmit.attachEvent('onclick', function()
    {
        var Flyout = System.Gadget.Flyout;

        if(Flyout.show)
        {
            TwitterS.updateFlyout('update')();
            return;
        };

        Flyout.file = "flyout.html";

        // Flyoutを表示/非表示の切替(true=表示/false=非表示)
        Flyout.show = true;

        // Flyoutが表示されたときのイベントリスナの登録。
        Flyout.onShow = TwitterS.updateFlyout('update');
    });
});
timeline.html

JSmartyのテンプレートファイル。flyout.htmlに流し込むために作成。

<ul>
{foreach from=$status item='feed'}
	<li style='background-color:{cycle values="#cccccc,#ffffff"}'>{$feed.text}</li>
{/foreach}
</ul>