はじめに
みなさんこんにちは! 今日は、Google Waveのガジェットの作成、途中の落とし穴、およびそれらを開発する便利な方法(ガジェット)について、アクセシブルな方法で話そうとします。 HabréのGoogle Waveブログで、waveのガジェットとロボットの違いはすでに説明されています。 勉強のためにガジェットを選んだ理由は2つあります。
- ロボットを作成するときのように、ウェーブに追加の連絡先を追加する必要はありません
- 最小エントリーしきい値-シンプルなAPIとappspot.comからの独立
そして、「何を書くべきか」という質問は自然に落ちました。 Wave Previewにアクセスし、利用可能な機能を試したとき、オーディオプレーヤーがなかったことに腹を立てました。 なぜ写真を一気に投げ入れて、後で見ることができるが、音楽は見ることができないのですか? 実際、最も可能性が高い理由は、JavaScript自体が音楽の再生方法を認識していないため、インターネットで見つけたすべてのソリューションがフラッシュプレーヤーを使用しているためです。 Wavesはすでにパフォーマンスの問題に直面しており、フラッシュはかなりリソースを消費するアプリケーションです。 さらに、考慮する必要がある使いやすさ-たとえば、1つのメッセージで10人のファイルに10人のプレーヤーを追加するのではなく、10個のファイルのプレイリストを持つ1人のプレーヤーを作成します。
基本を理解する
しかし、きれいな歌詞! ブラウザを備えており、Google Waveガジェットの公式マニュアルを読むために
- より詳細なレベルで状態管理にアクセスする
- 現在の視聴者とWaveの他のすべての参加者を識別する
- Wave再生エンジンを使用する
Google向けのガジェットを作成するのは今回が初めてで、ガジェットの状態を管理する方法に最も興味がありましたか? つまり、上記のリストの最初の機能です。 「ガジェットの状態」という表現のより単純な例えは、「ガジェットの設定」です。 他の2つの機能はすでにより特殊化されており、ガジェットの機能に大きく依存しています。ガジェットの状態(設定)を維持することはほとんどの場合必要です。
また、ガジェットは作成されたまさにそのWaveに属し、すべての設定はWaveに保存され、ガジェットをWaveに追加したユーザーのレベルではありません。 ただし、ガジェットは常にそれを追加したユーザーを「記憶」しています。これは私たちの目的にとって重要です。
ガジェットの構造は非常に単純です:
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
<? xml version ="1.0" encoding ="UTF-8" ? > < Module > < ModulePrefs title ="Hello Wave" > < Require feature ="wave-preview" /> </ ModulePrefs > < Content type ="html" > <! [CDATA[ Hello, Wave! ]] > </ Content > </ Module > * This source code was highlighted with Source Code Highlighter .
構文は非常に簡単です。
<Module> -このガジェットがこのXMLファイルに含まれていることを示します。
<ModulePrefs> -ガジェット、その作成者、スクリーンショットへのリンク、および車とパラメーターの小さなカートに関する情報を含めることができます。 タイトル、身長、author_emailのみを残しました。
ここで良い例を見ることができます。
そして、ここで私は、それさえ知らずに、cな熊手に出くわしました。 このコードは、ロシアの公式Googleマニュアルから取られています。 4行目に注意してください。
<Require feature = "wave-preview" />
このマニュアル全体で、この方法で記述する必要があることはどこにでも記載されています。 行自体は、ガジェットがGoogle Wave APIを必要とすることを意味します。 ただし、このような要件がある場合、ガジェットはFirefoxでのみ機能します(まだOperaに存在している可能性があり、テストされていません)。
マニュアルでどれだけの量のメモを取り、グーグルを苦しめたかはわかりませんが、解決策は1つの例でしか見つかりませんでした。
< Require feature ="wave" />
* This source code was highlighted with Source Code Highlighter .
これは、WebKitブラウザーがwave APIにアクセスできる唯一の方法です。 Firefoxがそれなしでどのように機能したのだろうか。 ちなみに、boxfrommars habrayuzerが示唆しているように 、 すべてがマニュアルの英語版で 正しく書かれているので、今のところはそれに焦点を合わせたほうが良いでしょう。
次に、使用するコンテンツのタイプ(htmlまたはurl)を指定します。 URLは、ガジェットがリモートページをそのフレームに単にロードすることを意味します。 htmlを選択し、xml-keにすべてを記述します。
<![CDATA [...]]> -すべてのHTML、CSS、およびJavaScriptコード(または対応するファイルへのリンク)を含むガジェットのメインコンテンツを含みます。 このセクションのコンテンツは、通常のHTMLページのbodyタグのコンテンツと見なされる必要があります。
ただ? 間違った言葉!
GoogleガジェットAPIを理解する
最後に、プレーヤーガジェットの開発を始めましょう。 私が言ったように、javascriptは音楽自体を再生する方法を知りません、それを助けるためにフラッシュを与えます。 最近、hapodでuppod.ruプロジェクトについて語られました。 登録し、プレーヤーとスタイルを作成し、ダウンロードしました-美! このサイトの良いヘルプは、私にすべての不明瞭な点を明らかにしました。 そして、私にとってまだ非常に興味深いのは、javascriptを介したプレーヤー制御です。 フラッシュドライブをJavaScriptで制御するのは論理的ですか? 論理的です。 私はすぐにコードを投げ、試してみました...
そして、残念ながら、これは機能しません。 なんで? 実際、javascriptは1つのドメインで実行され、別のドメインでフラッシュされます。 セキュリティ設定では、Flash Playerを制御できません。 少なくとも私にはうまくいきませんでした。
次に、最も単純なオプションを使用します。プレーヤーをパーツに組み立て、設定を変更するときに、新しいinnerHTMLを使用してプレーヤーでdivを指定します(リロードします)。 ただし、これは通常、一度だけ実行されます-ガジェットをblipに追加するときに、重要ではないと思います。 GETリクエストを介して、つまりURLで直接すべての設定を渡すこともできます。
ガジェット用のWave APIに必要な機能を検討してください(すべての機能は上記のリンクで説明されています)。
- setStateCallback(コールバック) -ガジェットの状態の変化に応答する関数を定義します。 このメソッドは、ガジェットで1回だけ発生します。
- wave.getState() -キーと値のペアのテーブルであるガジェット状態オブジェクトを返します。
特定のキーを読み取るには、 wave.getState()。Get( 'KeyName')呼び出しを使用します - submitDelta(デルタ) - デルタキーと値のペアのテーブルを追加(または既存のオブジェクトを上書き)することにより、状態オブジェクトを更新します。 例: wave.getState()。SubmitDelta({'count':5})
- wave.getViewer() -ガジェットを表示しているユーザーを識別するオブジェクトを返します
- wave.getHost() -このガジェットを追加したWaveの参加者を識別します
ガジェットを作成するときは、特定のコード構造に従うことをお勧めします-それに従います:
- 起動時に初期化のために呼び出されることが多いinit()関数の状態オブジェクトまたは参加者にアクセスしないでください。 状態および参加者オブジェクトは 、対応するコールバック(setParticipantCallbackおよびsetStateCallback)が完了するまで意味のある値を持ちません 。 Waveの動作を検証し、コールバックを登録するために使用できます。
- ユーザーインターフェイス要素によってイベントが送信されたときに状態オブジェクトを変更します。 たとえば、ボタンをクリックし、submitDeltaのみを呼び出しましたが、この変更が影響することは何も変更しませんでした。
- プログラムロジックをコールバック関数に配置するには、つまり、コードの主要部分をコールバック関数に配置する必要があります。 状態オブジェクト(setStateCallback)または参加者(setParticipantCallback)が変更されると、コールバック関数が呼び出されます。 これらの関数にコードを追加すると、最新の変更を確実に受け取ることができます。
その結果、ガジェットを記述するための次の「スケルトン」を取得します。
*このソースコードは、 ソースコードハイライターで強調表示されました。
- <? xml version = "1.0" encoding = "UTF-8" ? >
- < モジュール >
- < ModulePrefs title = "TitleHere" height = "100" author_email = "mail@mail.com" >
- < 機能が 必要 =「wave」 />
- </ ModulePrefs >
- < コンテンツ タイプ = "html" >
- <! [CDATA [
- < div id = "content_div" style = "height:100px;" > </ div >
- < スクリプト タイプ = "text / javascript" >
- var div = document .getElementById( 'content_div' );
- 関数 stateUpdated(){
- }
- 関数の初期化(){
- if (wave && wave.isInWaveContainer()){
- wave.setStateCallback(stateUpdated);
- }
- }
- gadgets.util.registerOnLoadHandler(init);
- </ スクリプト >
- ]] >
- </ コンテンツ >
- </ モジュール >
プレーヤーの機能
プレーヤーには何が必要ですか? はい、プレイします! 確かに、waveに追加されたファイルから音楽を再生することはできません。ガジェットがblipにアクセスできないか、対応するAPIが見つかりませんでした。 したがって、インターネットの他の部分からの参照により音楽を再生します。 さらに、このガジェットをWaveに追加したユーザーのみに設定の変更を許可し、残りは失うだけです-失うだけです! まあ、ボーナスとして、メロディが好きな人のためにファイルへのリンクを与えるのはいいことです。
そのため、関数のリスト:
- インターネットからのリンクを介して音楽を再生する
- 設定にアクセスすると、ガジェットがWaveに追加されるだけです。 必要に応じて、設定を非表示にする必要があります。
- プレーヤーの下の直接ダウンロードリンク
設定が非表示になるため、もう1つの機能を追加します。ガジェットは高さを最小に調整します。 これを行うには、 <Require feature = "dynamic-height" />をリクエストし、ガジェットの高さが変わる場所でgadgets.window.adjustHeight()メソッドを使用します。
コードを取得する!
任意のエディターを使用して実際のコードを書くことができます。私はポイントではなくNetBeansを使用しました。 しかし、便利なデバッグのために、 Get DropBoxサービスなどに注意する必要があります。 プロジェクトをPublic / WavePlayerフォルダーに配置し、静かにコードを記述するか、既存のコードをデバッグします。 DropBoxは変更されたファイルをサーバーに自動的にアップロードし、waveが更新されると、ガジェットは新しいXML仕様を取得しますが、それらはキャッシュされません。 そこで、プレーヤーファイルとプレーヤーのスタイルシートを配置します。 そこにinstall.xmlをドロップしましょう-新しい拡張インストーラーガジェットへのリンクを提供した仕様(登録中に自動的に追加されるWaveで見つけることができ、便利なガジェットを見つけることができる場所)、ガジェットをパネルに直接インストールできます!
このファイルはどのようなものですか:
< extension name ="Wave mp3" description ="Play mp3 inside a Wave." >
< version > 0.2 </ version >
< author name ="Author" email ="mail@mail.com" />
< menuHook location ="toolbar" text ="Add Wave mp3 Gadget" iconUrl ="" >
< insertGadget url ="http://dl.dropbox.com/u/983333/WavePlayer_v0.2/WavePlayer.xml" />
</ menuHook >
</ extension >
* This source code was highlighted with Source Code Highlighter .
このxmlは、ガジェットへの必要なリンクと、パネル内のガジェットのアイコンを単純に規定しています。
今、コメントされたコードを見てください、そして、私は、すべてが適所に落ちると思う!
<? xml version ="1.0" encoding ="UTF-8" ? >
< Module >
< ModulePrefs title ="WavePlayer" height ="115" author_email ="maksng@gmail.com" >
< Require feature ="wave" />
< Require feature ="dynamic-height" />
</ ModulePrefs >
< Content type ="html" >
<! [CDATA[
< div id ="flash_div" style ="height: 50px;" > Wave player is loading... </ div > <!-- flash -->
< div id ="showlink_div" ></ div > <!-- -->
< div id ="showSettings_div" onClick ="showSettings()" ></ div > <!-- -->
< script type ="text/javascript" >
var flashdiv = document .getElementById( 'flash_div' );
// innerHTML
var player_part_1 = '<object id="waveplayer02" type="application/x-shockwave-flash" data="" width="315" height="50"><param name="allowScriptAccess" value="always" /><param name="wmode" value="transparent" /><param name="movie" value="" /><param name="flashvars" value="comment=Wave Player v0.2&st=http://dl.dropbox.com/u/983333/WavePlayer_v0.2/main.txt&file=' ;
var player_part_2 = '" /></object>' ;
//
var mp3file = 'http://dl.dropbox.com/u/983333/worldapart_.mp3' ;
function buttonChange() { //
if (wave.getViewer() == wave.getHost()) { // , ?
mp3file = document .getElementById( "mp3file" ).value; // input
wave.getState().submitDelta({ 'mp3file' : mp3file}); //
} else { //( )
alert( "Sorry, you are not the owner of this gadget.\n\nOnly the participant who inserted this gadget in the wave (\"the owner\") can change the properties." );
}
}
function buttonHide() { //
wave.getState().submitDelta({ 'hided' : 1}); // ( )
}
function showSettings() { //
wave.getState().submitDelta({ 'hided' : 0}); // ( )
}
function waveStateUpdated() { //callback
if (wave.getState().get( 'mp3file' )) { // mp3file?
mp3file = wave.getState().get( 'mp3file' ); //
}
flashdiv.innerHTML = player_part_1 + mp3file + player_part_2; //
// ,
document .getElementById( "showlink_div" ).innerHTML = "<a href=\"" +mp3file+ "\">Download mp3!</a>" ;
if (wave.getViewer() != wave.getHost()){ // , ?
document .getElementById( "showSettings_div" ).style.display = "none" ; //,
document .getElementById( "settingsDiv" ).style.display = "none" ; //
}
else { //, ,
if (!wave.getState().get( 'hided' )){ // hided()?
document .getElementById( "showSettings_div" ).style.display = "none" ; // -
document .getElementById( "settingsDiv" ).style.display = "" ;
} else { //
var isHided = wave.getState().get( 'hided' ); //
document .getElementById( "showSettings_div" ).style.display = (isHided==1)? "" : "none" ; // -
document .getElementById( "settingsDiv" ).style.display = (isHided==1)? "none" : "" ; // -
}
}
gadgets.window.adjustHeight(); //
}
function init() { //
if (wave && wave.isInWaveContainer()) { //
wave.setStateCallback(waveStateUpdated); // Callback
}
}
gadgets.util.registerOnLoadHandler(init); // init
</ script >
< br >
< div id ="settingsDiv" >
< form name ="mainForm" >
Link to mp3 : < input type ="text" id ="mp3file" value ="" size "40" ></ input >
< input type = button value ="Change mp3!" id ="butChange" onClick ="buttonChange()" >
</ form >< br >
To view it again click on "Show settings!"
< input type = button value ="Hide!" id ="butHide" onClick ="buttonHide()" >
</ div >
]] >
</ Content >
</ Module >
* This source code was highlighted with Source Code Highlighter .
そして、これが私の労働の結果です。
便利なリンク
明らかに、まだ開発することがたくさんありますが、すべてに時間があります!
コメントでは、可能な質問に喜んでお答えします。
ご清聴ありがとうございました! 波を最大限に実行します!