再生リストの登録
これまでの内容に加えて、設定ダイアログで再生したい動画のIDを登録して保存できる仕組みを実装すれば、実用的なYouTubeガジェットを実現できそうです。
設定ダイアログを表示するために、ガジェット用のHTMLとは別に、設定用の「settings.html」を作成してSystem.Gadget.settingsUIにパスを設定してください。「settings.html」では、テキスト入力領域を表示してYouTubeのIDを入力することができるようにします。複数のIDを登録する場合は、改行することにしましょう。

ここで入力されたテキストは、[OK]ボタンを押してダイアログが閉じられようとした時にSystem.Gadget.Settings.write()メソッドから設定として保存します。ガジェット側では、入力されたIDのリストをSystem.Gadget.Settings.read()メソッドから取得して表示します。表示されている項目を選択すると、IDに対応した動画が表示されるという仕組みを作れば完成です。

これで、お気に入りの動画を登録してデスクトップ上でいつでも簡単に再生することができるYouTubeガジェットを作ることができます。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp"> <head> <script> System.Gadget.onDock = onDock; System.Gadget.onUndock = onUndock; System.Gadget.settingsUI = "settings.html"; System.Gadget.onSettingsClosed = dialogClosed; //選択項目など、下部のツール領域の高さ var toolHeight = 27; //ドックされている状態のガジェットの幅と高さ var dockedWidth = 125, dockedHeight = 105 + toolHeight; //アンドックされている状態のガジェットの幅と高さ var undockedWidth = 425, undockedHeight = 350 + toolHeight; //設定ダイアログが閉じられた function dialogClosed(event) { if (event.closeAction == event.Action.commit) initMovieSelect(); } /再生リストから動画選択用の select 要素を生成 function initMovieSelect() { var moviesText = System.Gadget.Settings.read("movies"); if (!moviesText) { container.innerHTML = "設定から YouTube の ID を入力してください"; returnl } var select = '<select id="movieSelect" size="1" style="width:100%"onchange="setMovie(movieSelect.value)">'; if (moviesText != null) { var movies = moviesText.split(","); setMovie(movies[0]); for(var i = 0 ; i < movies.length ; i++) { select += '<option value="' + movies[i] + '">' + movies[i] + "</option>"; } } select += '</select>'; tool.innerHTML = select; } //ガジェットが起動したときに呼び出される function init() { if (System.Gadget.docked) onDock(); else onUndock(); initMovieSelect(); } //新しい動画を表示する //movie には新しく表示する動画の ID を指定 function setMovie(movie) { var html = ""; if (System.Gadget.docked) html += '<object id="youtube" style="width:' + dockedWidth +
'px; height:' + (dockedHeight - toolHeight) + 'px;"
codetype="application/x-shockwave-flash">'; else html += '<object id="youtube" style="width:' + undockedWidth
+ 'px; height:' + (undockedHeight - toolHeight) + 'px;"
codetype="application/x-shockwave-flash">'; html += '<param name="movie" value="http://www.youtube.com/v/' +
movie + '" />'; html += '<param name="wmode" value="transparent" />'; html += '</object>'; container.innerHTML = html; } //ドックされたときに呼び出される function onDock() { document.body.style.width = dockedWidth + "px"; document.body.style.height = dockedHeight + "px"; if ("youtube" in window) { youtube.style.width = dockedWidth + "px"; youtube.style.height = (dockedHeight - toolHeight) + "px"; } } //アンドックされたときに呼び出される function onUndock() { document.body.style.width = undockedWidth + "px"; document.body.style.height = undockedHeight + "px"; if ("youtube" in window) { youtube.style.width = undockedWidth + "px"; youtube.style.height = (undockedHeight - toolHeight) + "px"; } } </script> </head> <body onload="init()" style="margin:0px;"> <div id="container"></div> <div id="tool"></div> </body> </html>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp"> <head> <script> System.Gadget.onSettingsClosing = closing; //設定ダイアログが閉じられる時に呼び出される function closing(event) { if (event.closeAction != event.Action.commit) return; //改行を区切り文字として文字列を分割 var movies = vid.value.split("\n"); //カンマで区切られた再生リストの文字列を生成 var moviesText = ""; for(var i = 0 ; i < movies.length - 1 ; i++) { moviesText += movies[i] + ","; } moviesText += movies[movies.length - 1]; //movies という名前で保存 System.Gadget.Settings.write("movies", moviesText); } //設定ダイアログが開かれたときに呼び出される function init() { //再生リストを取得 var moviesText = System.Gadget.Settings.read("movies"); //再生リストを配列に分割 var movies = moviesText.split(","); //ムービーIDをテキストボックスに表示 for(var i = 0 ; i < movies.length - 1 ; i++) { vid.value += movies[i] + "\n"; } vid.value += movies[movies.length - 1]; } </script> </head> <body onload="init()" style="width:400px; height:200px;"> <p> YouTubeのムービーのIDを入力してください。<br/> 改行して複数のIDを登録することができます。 </p> <p><textarea name="txt" cols="30" rows="5" id="vid"></textarea></p> </body> </html>
sample03では少々コードが複雑になってしまいましたが、処理内容はこれまでのものとほとんど変わりません。ガジェットが表示されるときにonloadイベントが発生しinit()関数が実行されます。init()関数はガジェットのサイズを整え、initMovieSelect()を呼び出して登録されているIDのリストを取得し、個別のIDに対応するselect要素に変換します。
生成されたselect要素は、ガジェットの下部に表示されています。リストから特定のIDを選択するとonchangeイベントが発生し、選択された項目のIDでsetMovie()関数が呼び出されるという仕組みになっています。
最後に
本稿では、ガジェット上に表示するHTMLの構造をDOMを用いて動的に変化させる方法を応用して、外部のWebサービスをツール化しました。この方法はYouTube以外にも有効です。例えば、同じような動画共有サービスであるMicrosoftのSoapboxや、Xboxゲーマタグを表示するガジェットも同じような手法で作ることができるでしょう。
他にも、AmazonやGoogleなど、多くの企業がURLからアクセス可能なサービスを公開しています。こうしたサービスが提供しているコンテンツは、ガジェットに埋め込んだり、Ajaxの手法を用いてダウンロードしたり、または内部フレームを使って表示させることができます。ガジェット単体でできることは限られていますが、外部のWebサービスと繋がることで便利なツールに化ける可能性があります。
参考文献
- MSDN Library 『Windows Sidebar』
- Ecma International 『Standard ECMA-262 ECMAScript Language Specification』

onchange=