HTML を受け取る方法 (HTML)

[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]

HTML コンテンツは、テキスト、画像、その他の情報を含むさまざまなコンテンツで構成できます。ここでは、ユーザーが共有する HTML コンテンツをアプリで受け取る方法について説明します。

この機能をアプリに追加するときは、テキスト形式のコンテンツも受け入れることも考慮します。テキストは HTML に簡単に変換できるので、この形式のサポートを追加すると、ユーザーによるアプリの使用頻度を高めることができます。詳しくは、「テキストを受け取る方法」をご覧ください。

理解しておく必要があること

テクノロジ

必要条件

  • Visual Studio と関連するテンプレートについて理解している必要があります。
  • JavaScript について理解している必要があります。

手順

ステップ 1: 共有コントラクトをサポートする。

アプリで共有コンテンツを受け取るには、事前に共有コントラクトのサポートを宣言する必要があります。このコントラクトを使うと、基本的に、アプリがコンテンツを受け取れることをシステムに通知できます。Microsoft Visual Studio テンプレートを使ってアプリを作る場合は、次の手順に従って共有コントラクトをサポートします。

  1. マニフェスト ファイルを開きます。マニフェスト ファイルは package.appxmanifest のような名前になっています。
  2. [宣言] タブを開きます。
  3. [使用可能な宣言] ボックスの一覧の [共有ターゲット] を選びます。

ステップ 2: アプリが HTML をサポートすることを指定する。

アプリがデータ形式として HTML をサポートすることを次のように指定します。

  1. マニフェスト ファイルを開きます。
  2. [データ形式] セクションで、[新規追加] をクリックします。
  3. 「html」と入力します。

  共有ターゲット コントラクト用にアプリがアクティブ化されている場合は、別のエントリ ポイントを指定できます。そのためには、パッケージ マニフェストの [共有ターゲット] 宣言の [アプリ] 設定セクションで [スタート] ページ エントリを変更します。このページのアクティブ化を処理する別の JavaScript ファイルも使うことを強くお勧めします。例については、コンテンツ共有ターゲット アプリ サンプルをご覧ください。

 

ステップ 3: アプリがどのような状況でアクティブ化されたかを検出するイベント ハンドラーを追加する。

ユーザーがアプリでコンテンツを共有することを選ぶと、システムによってアプリがアクティブ化されます。アクティブ化はさまざまな状況で発生する可能性があるため、アクティブ化が行われた理由を検出するコードを activated イベント ハンドラーに追加する必要があります。これは、kind プロパティの値を調べることで確認できます。

app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        // The application has been launched. Initialize as appropriate.
    } else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
        ...
    }
};

共有ターゲット コントラクト用の専用のスタート ページを使う場合は、kind プロパティのチェックを省略できます。

ステップ 4: ShareOperation オブジェクトを取得する。

ShareOperation オブジェクトには、ユーザーが共有するコンテンツをアプリが取得するために必要なすべてのデータが含まれています。

shareOperation = args.detail.shareOperation;

ステップ 5: activated イベント ハンドラーからすばやく戻る。

activated イベント ハンドラーは、すばやく戻る必要があります。activated イベント ハンドラーからの非同期イベントをキューに入れ、activated イベントから戻った後に共有データの処理が行われるようにします。

WinJS.Application.addEventListener("shareready", shareReady, false);
WinJS.Application.queueEvent({ type: "shareready" });

残りの手順では、shareReady 関数を実装します。

ステップ 6: DataPackageView に HTML が含まれているか確認する。

ShareOperation オブジェクトには DataPackageView オブジェクトが含まれています。このオブジェクトは、基本的に、ソース アプリがデータの作成に使った DataPackage オブジェクトを読み取り専用にしたものです。このオブジェクトを使って共有されたコンテンツが HTML 形式で利用できるか確認します。

if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html)) {
    // Code to get HTML goes here.
}

アプリで 1 つの形式しかサポートしていないとしても、目的のデータ形式が DataPackage に含まれているかどうかをチェックすることをお勧めします。これにより、後で他のデータ形式やファイル形式をサポートするのが簡単になります。

ステップ 7: HTML を処理する。

HTML コンテンツを取り出すために getHtmlFormatAsync を呼び出します。このメソッドは、HTML 形式仕様の HTML コンテンツを返します。HTML 形式から HTML フラグメントを抽出するには、DataTransfer.HtmlFormatHelper.getStaticFragment を使うことができます。結果のセグメントは、スクリプト タグのような動的コンテンツを削除する処理も行われているので、アプリケーションでレンダリングしても安全です。

shareOperation.data.getHtmlFormatAsync().then(function (htmlFormat) {
    var htmlFragment = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);
    // In this example, we only display the HTML. To do this, you need 
    // a <div> element with an id of "output" in your HTML page.

    // In your app, replace this with whatever is appropriate for your scenario.
    document.getElementById("output").innerHTML = htmlFragment;
});

もちろん取り出した HTML をどのように使うかは、アプリによって異なります。

ステップ 8: HTML のローカルな画像参照を解決する。

共有ソース アプリは、ローカルのストレージ コンテキスト (たとえば、ms-appx、ms-appdata など) にある画像を HTML に含んでいる場合があります。この場合、ソース アプリはリソース マップに適切な参照を設定し、共有ターゲットがこれらのリソースにアクセスできるようにする必要がありました。

ソース アプリのローカルな画像を解決するには、resourceMap プロパティを使って各画像の参照を検索し、対応する RandomAccessStreamReference を取得します。次の例では、オブジェクト Uniform Resource Identifier (URI) を作成して、HTML 内の画像をレンダリングしています。自分のアプリでは、このコードをシナリオに合わせて変更したコードに置き換えてください。

var images = document.getElementById("output").getElementsByTagName("img");
if (images.length > 0) {
    shareOperation.data.getResourceMapAsync().done(function (resourceMap) {
        if (resourceMap.size > 0) {
            for (var i = 0, len = images.length; i < len; i++) {
                var streamReference = resourceMap[images[i].getAttribute("src")];
                if (streamReference) {
                    // Call a helper function to map the image element's src to a 
                    // corresponding blob URL generated from the streamReference.
                    setResourceMapURL(streamReference, images[i]);
                }
            }
        }
    });
}

ステップ 9: reportCompleted を呼び出す。

アプリでコンテンツの共有が完了したら、reportCompleted を呼び出します。このメソッドを呼び出すと、システムによってアプリが閉じられます。

shareOperation.reportCompleted();

注釈

コンテンツ共有ターゲット アプリ サンプルのコード例を調べると、共有の一部として画像を受け取るアプリのエンド ツー エンドのエクスペリエンス全体を把握できます。

完全な例

var shareOperation = null;

function setResourceMapURL(streamReference, imageElement) {
    if (streamReference) {
        streamReference.openReadAsync().done(function (imageStream) {
            if (imageStream) {
                var url = URL.createObjectURL(imageStream, { oneTimeOnly: true });
                imageElement.src = url;
            }
        }, function (e) {
            imageElement.alt = "Failed to load";
        });
    }
}

function shareReady(args) {
    if (shareOperation.data.contains(Windows.ApplicationModel.DataTransfer.StandardDataFormats.html)) {
        shareOperation.data.getHtmlFormatAsync().then(function (htmlFormat) {
            var htmlFragment = Windows.ApplicationModel.DataTransfer.HtmlFormatHelper.getStaticFragment(htmlFormat);
            // In this example, we only display the HTML. To do this, you need 
            // a <div> element with an id of "output" in your HTML page.
            // In your app, replace this with whatever is appropriate for your scenario.
            document.getElementById("output").innerHTML = htmlFragment;

            // Now we loop through any images and use the resourceMap to map each
            // image element's src.
            var images = document.getElementById("output").getElementsByTagName("img");

            if (images.length > 0) {
                shareOperation.data.getResourceMapAsync().done(function (resourceMap) {
                    if (resourceMap.size > 0) {
                        for (var i = 0, len = images.length; i < len; i++) {
                            var streamReference = resourceMap[images[i].getAttribute("src")];
                                if (streamReference) {
                                    // Call a helper function to map the image element's
                                    // src to a corresponding blob URL generated from the
                                    // streamReference.
                                    setResourceMapURL(streamReference, images[i]);
                                }
                        }
                    }
                });
            }
        });
    } 
}

app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        // The application has been launched.
        args.setPromise(WinJS.UI.processAll());
    } else if (args.detail.kind === Windows.ApplicationModel.Activation.ActivationKind.shareTarget) {
        // This application has been activated for the Share contract
        args.setPromise(WinJS.UI.processAll());

        // We receive the ShareOperation object as part of the eventArgs.
        shareOperation = args.detail.shareOperation;

        // We queue an asychronous event so that working with the ShareOperation 
        // object does not block or delay the return of the activation handler.
        WinJS.Application.addEventListener("shareready", shareReady, false);
        WinJS.Application.queueEvent({ type: "shareready" });
    }
};

関連トピック

コンテンツ共有ターゲット アプリ サンプル

データの共有と交換

ファイルを受け取る方法

リンクを受け取る方法

テキストを受け取る方法

クイック スタート: 共有コンテンツの受信

DataPackage

Windows.ApplicationModel.DataTransfer

Windows.ApplicationModel.DataTransfer.Share

ターゲット アプリのデバッグに関するガイドライン