How to receive HTML (HTML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

HTML content can consist of a variety of content, including text, images, and other information. Here's how your app can receive the HTML content a user wants to share.

When adding this functionality to your app, consider also accepting content in a text format as well. Text is easy to convert to HTML, so adding support for this format can help you ensure that your app is available to users more often. To learn more, see How to receive text.

What you need to know

Technologies

Prerequisites

  • You should be familiar with Visual Studio and its associated templates.
  • You should be familiar with JavaScript.

Instructions

Step 1: Support the Share contract.

Before your app can receive shared content, you must declare that it supports the Share contract. This contract essentially lets the system know that your app is available to receive content. If you're using a Microsoft Visual Studio template to create your app, here's how you support the Share contract:

  1. Open the manifest file. It should be called something like package.appxmanifest.
  2. Open the Declarations tab.
  3. Choose Share Target from the Available Declarations list.

Step 2: Specify that your app supports html.

To specify that you support HTML as a data format:

  1. Open the manifest file.
  2. In the Data Formats section, click Add New.
  3. Type html.

Note  You can specify a different entry point when your app is activated for the Share Target contract. To do this, modify the Start page entry in App settings section of the Share Target declaration in the package manifest. We highly recommend that you also use a separate JavaScript file that handles activation for this page. For an example, check out the Sharing content target app sample.

 

Step 3: Add an event handler to detect when your app is activated.

When a user selects your app to share content, the system activates your app. Because there are many ways this can happen, you need to add code to your activated event handler that detects why the activation occurred. You do this by checking the value of the kind property.

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) {
        ...
    }
};

If you use a dedicated start page for the Share Target contract, you can skip checking the kind property

Step 4: Get the ShareOperation object.

The ShareOperation object contains all the data your app needs to get the content that a user wants to share.

shareOperation = args.detail.shareOperation;

Step 5: Return from the activated event handler quickly.

The activated event handler must return quickly. Queue an asynchronous event from activated event handler so that share data processing takes placed after the activated event returns.

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

The remaining steps implement the shareReady function.

Step 6: Check to see if the DataPackageView contains HTML

The ShareOperation object contains a DataPackageView object. This object is essentially a read-only version of the DataPackage object that the source app used to create the data. Use this object to see if the content being shared is available in HTML format.

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

Checking if the DataPackage contains the data format you are interested in is good practice, even if your app supports only one format. This makes it easier to support other data formats types and file formats later.

Step 7: Process the HTML.

To get the HTML content, call the getHtmlFormatAsync method. This method returns HTML content in the HTML Format specification. You can use DataTransfer.HtmlFormatHelper.getStaticFragment to extract the HTML fragment from the HTML Format. The resulting fragment is also sanitized to have any dynamic content such as script tags removed, and is safe to render in your application

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;
});

Of course, what you do with the HTML depends on your app.

Step 8: Resolve any local image references for the HTML.

The sharing source app might include images in the HTML that are located in its local storage context (for example, ms-appx, ms-appdata, and so on). In this case, the source app should have populated the resource map with appropriate references to enable the share target to access these resources.

To resolve local images from the source app, use the resourceMap property to look up each image reference and obtain the corresponding RandomAccessStreamReference. The following example creates the object Uniform Resource Identifier (URI) to render the image(s) in the HTML. In your app, replace this code with any modifications appropriate to your scenario.

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]);
                }
            }
        }
    });
}

Step 9: Call reportCompleted.

After your app finishes sharing the content, call reportCompleted. After you call this method, the system dismisses your app.

shareOperation.reportCompleted();

Remarks

Check out our Sharing content target app sample code sample to see the entire end-to-end experience of an app receiving an image as part of sharing.

Complete example

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" });
    }
};

Sharing content target app sample

Sharing and exchanging data

How to receive files

How to receive a link

How to receive text

Quickstart: Receiving shared content

DataPackage

Windows.ApplicationModel.DataTransfer

Windows.ApplicationModel.DataTransfer.Share

Guidelines for debugging target apps