<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 14978 -->
<sect3 id="zend.view.helpers.initial.headscript">
    <title>HeadScript ヘルパー</title>

    <para>
        HTML の <code>&lt;script&gt;</code> 要素を使用して、
        クライアントサイトのスクリプトをインラインで指定したり
        外部のリソースからスクリプトのコードを読み込んだりします。
        <code>HeadScript</code> ヘルパーは、この両方の方式に対応しています。
    </para>

    <para>
        <code>HeadScript</code> ヘルパーは、
        以下のメソッド群によってスクリプトの設定や追加をサポートします。
    </para>

    <itemizedlist>
        <listitem><para><code>appendFile($src, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>offsetSetFile($index, $src, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>prependFile($src, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>setFile($src, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>appendScript($script, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>offsetSetScript($index, $script, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>prependScript($script, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
        <listitem><para><code>setScript($script, $type = 'text/javascript',
                    $attrs = array())</code></para></listitem>
    </itemizedlist>

    <para>
        <code>*File()</code> 系のメソッドでは、<code>$src</code>
        は読み込みたいリモートスクリプトの場所となります。
        通常は、URL あるいはパスの形式となります。<code>*Script()</code>
        系のメソッドでは、<code>$script</code>
        はその要素に使用したいクライアント側のスクリプトとなります。
    </para>

    <note>
        <title>条件コメントの設定</title>

        <para>
            <code>HeadScript</code> では、script タグを条件コメントで囲むことができます。
            そうすれば、特定のブラウザでだけスクリプトを実行しないこともできます。
            これを使用するには conditional タグを設定し、条件をメソッドコール時の
            <code>$attrs</code> パラメータで渡します。
        </para>

        <example id="zend.view.helpers.initial.headscript.conditional">
            <title>Headscript で条件コメントを使う例</title>
            <programlisting role="php"><![CDATA[
// スクリプトを追加します
$this->headScript()->appendFile(
    '/js/prototype.js',
    'text/javascript',
    array('conditional' => 'lt IE 7')
);
]]>
            </programlisting>
        </example>
    </note>

    <para>
        <code>HeadScript</code> はスクリプトのキャプチャも行います。
        これは、クライアント側スクリプトをプログラム上で作成してから
        どこか別の場所で使いたい場合に便利です。
        使用法は、以下の例で示します。
    </para>

    <para>
        <code>headScript()</code> メソッドを使うと、
        スクリプト要素を手っ取り早く追加することができます。
        シグネチャは
        <code>headScript($mode = 'FILE', $spec, $placement = 'APPEND')</code>
        です。<code>$mode</code> は 'FILE' あるいは 'SCRIPT' のいずれかで、
        スクリプトへのリンクを指定するのかスクリプト自体を定義するのかによって切り替えます。
        <code>$spec</code> は、リンクするスクリプトファイルあるいはスクリプトのソースとなります。
        <code>$placement</code> は 'APPEND'、'PREPEND' あるいは 'SET'
        のいずれかでなければなりません。
    </para>

    <para>
        <code>HeadScript</code> は <code>append()</code> や
        <code>offsetSet()</code>、<code>prepend()</code>、そして <code>set()</code>
        をそれぞれオーバーライドして、上にあげた特別なメソッドを使用させるようにします。
        内部的には、各項目を <code>stdClass</code> のトークンとして保管し、
        あとで <code>itemToString()</code> メソッドでシリアライズします。
        これはスタック内の項目についてチェックを行い、
        オプションでそれを修正したものを返します。
    </para>

    <para>
        <code>HeadScript</code> ヘルパーは、
        <link linkend="zend.view.helpers.initial.placeholder">Placeholder
        ヘルパー</link> の具象実装です。
    </para>

    <note>
        <title>HTML Body スクリプトでの InlineScript の使用</title>

        <para>
            HTML の <code>body</code> 部にスクリプトを埋め込みたい場合は、
            <code>HeadScript</code> の姉妹版である <link
                linkend="zend.view.helpers.initial.inlinescript">InlineScript</link>
            を使わなければなりません。
            スクリプトをドキュメントの最後のほうに配置するようにすると、
            ページの表示速度が向上します。特に、
            サードパーティのアクセス解析用スクリプトを使用する場合などにこの効果が顕著にあらわれます。
        </para>
    </note>

    <note>
        <title>すべての属性はデフォルトで無効</title>

        <para>
            デフォルトでは、<code>HeadScript</code> がレンダリングする
            <code>&lt;script&gt;</code> の属性は W3C
            に認められているものだけです。
            'type' や 'charset'、'defer'、'language' そして 'src' が該当します。
            しかし、Javascript のフレームワーク
            (<ulink url="http://www.dojotoolkit.org/">Dojo</ulink> など)
            では独自の属性を用いることでその挙動を変更しています。
            このような属性を許可するには、
            <code>setAllowArbitraryAttributes()</code> メソッドを使用します。
        </para>

        <programlisting role="php"><![CDATA[
$this->headScript()->setAllowArbitraryAttributes(true);
]]>
        </programlisting>
    </note>

    <example id="zend.view.helpers.initial.headscript.basicusage">
        <title>HeadScript ヘルパーの基本的な使用法</title>

        <para>
            上で説明したように、新しい script タグを、好きなときに指定することができます。
            外部のリソースへのリンクも可能ですし、
            スクリプト自体を指定することも可能です。
        </para>

        <programlisting role="php"><![CDATA[
// スクリプトを追加します
$this->headScript()->appendFile('/js/prototype.js')
                   ->appendScript($onloadScript);
]]>
        </programlisting>

        <para>
            クライアント側のスクリプトでは並び順が重要となります。
            指定した並び順で出力させる必要が出てくることでしょう。
            そのために使用するのが、append、prepend そして offsetSet
            といったディレクティブです。
        </para>

        <programlisting role="php"><![CDATA[
// スクリプトの順番を指定します

// 特定の位置を指定し、確実に最後に読み込まれるようにします
$this->headScript()->offsetSetFile(100, '/js/myfuncs.js');

// scriptaculous のエフェクトを使用します (次のインデックスである 101 に追加されます)
$this->headScript()->appendFile('/js/scriptaculous.js');

// でも、もととなる prototype スクリプトは常に最初に読み込まれるようにします
$this->headScript()->prependFile('/js/prototype.js');
]]>
        </programlisting>

        <para>
            すべてのスクリプトを出力する準備が整ったら、
            あとはレイアウトスクリプトでそれを出力するだけです。
        </para>

        <programlisting role="php"><![CDATA[
<?php echo $this->headScript() ?>
]]>
        </programlisting>
    </example>

    <example id="zend.view.helpers.initial.headscript.capture">
        <title>HeadScript ヘルパーによるスクリプトのキャプチャ</title>

        <para>
            時にはクライアント側のスクリプトをプログラムで生成しなければならないこともあるでしょう。
            文字列の連結やヒアドキュメント等を使っても構いませんが、
            ふつうにスクリプトを作成してそれを PHP のタグに埋め込めればより簡単です。
            <code>HeadScript</code> は、スタックにキャプチャすることでこれを実現します。
        </para>

        <programlisting role="php"><![CDATA[
<?php $this->headScript()->captureStart() ?>
var action = '<?php echo $this->baseUrl ?>';
$('foo_form').action = action;
<?php $this->headScript()->captureEnd() ?>
]]>
        </programlisting>

        <para>
            前提条件は次のとおりです。
        </para>

        <itemizedlist>
            <listitem><para>
                    スクリプトは、スタックの末尾に追加されていきます。
                    既存のスタックを上書きしたりスタックの先頭に追加したりしたい場合は、
                    それぞれ 'SET' あるいは 'PREPEND' を
                    <code>captureStart()</code> の最初の引数として渡します。
            </para></listitem>

            <listitem><para>
                    スクリプトの MIME タイプは 'text/javascript' を想定しています。
                    別のものを指定したい場合は、それを
                    <code>captureStart()</code> の 2 番目の引数として渡します。
            </para></listitem>

            <listitem><para>
                    <code>&lt;script&gt;</code> タグに追加の属性を指定したい場合は、
                    <code>captureStart()</code> の 3 番目の引数に配列形式で渡します。
            </para></listitem>
        </itemizedlist>
    </example>
</sect3>
<!--
vim:se ts=4 sw=4 et:
-->
