W3C W3C Member Submission

OpenSocial 2.5.1 Activity Streams and Embedded Experiences APIs

W3C Member Submission 14 March 2014

This version:
http://www.w3.org/submissions/2014/SUBM-osapi-20140314/
Latest version:
http://www.w3.org/submissions/osapi/
Authors:
Matthew Marum (SugarCRM, OpenSocial)
Andy Smith (IBM, OpenSocial)
Ryan Baxter (IBM)
Laurent Walter Goix (Telecom Italia, OpenSocial)
Henry Saputra (Jive)
Mark Weitzel (Jive, OpenSocial)
Eric Woods (IBM)

Abstract

OpenSocial 2.5.1 provides a basis for building portable social applications. The OpenSocial Foundation would like to provide portions of it for consideration in the W3C Social WG. What follows is a revised version of the Activity Streams API and Embedded Experiences portions of the OpenSocial 2.5.1 specification. The revisions have been made to focus on the content we would like to move forward with in the W3C Social Web WG. Where there are concepts that are introduced that are not defined within this document we link to the definition of those terms in the published in other documents such as the OpenSocial 2.5.1 specification.

Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications can be found in the W3C technical reports index at http://www.w3.org/TR/.

By publishing this document, W3C acknowledges that the Submitting Members have made a formal Submission request to W3C for discussion. Publication of this document by W3C indicates no endorsement of its content by W3C, nor that W3C has, is, or will be allocating any resources to the issues addressed by it. This document is not the product of a chartered W3C group, but is published as potential input to the W3C Process. A W3C Team Comment has been published in conjunction with this Member Submission. Publication of acknowledged Member Submissions at the W3C site is one of the benefits of W3C Membership. Please consult the requirements associated with Member Submissions of section 3.3 of the W3C Patent Policy. Please consult the complete list of acknowledged W3C Member Submissions.

Table of Contents


1. Notation and Conventions

Domain name examples use RFC2606 [RFC2606].

1.1 Definition of an "App" in this submission

In the terms of this member submission, we are using the term App as a blanket term for any packaged web application component. This definition is intended to be broad enough to encompass OpenSocial Gadgets, W3C Packaged Web Apps (Widgets), and any future web application component models. Note that the OpenSocial Foundation seeks to pursue an updated OpenSocial Gadget model based on W3C Web Components in the near future.

1.2 Requirements

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119 [RFC2119].

An implementation is not compliant if it fails to satisfy one or more of the MUST or REQUIRED level requirements for the protocols it implements.

1.3 Augmented BNF

The grammatical rules in this document are to be interpreted as described in Augmented Backus-Naur Form [RFC2234]. The following constructs are introduced in this document to augment RFC2234:

{rule1 rule2}

Elements enclosed in braces (squiggly brackets) are treated as a single, UNORDERED element. Its contents may occur in any order. Hence:

{elem foo} bar
would match (elem foo bar) and (foo elem bar).

NOTE: Specifying alternatives is quite different from specifying set grouping. Alternatives indicate the matching of exactly one (sub-)rule out of the total grouping. The set mechanism indicates the matching of a string which contains all of the elements within the group; however the elements may occur in any order.

#rule
A construct "#" is defined, similar to "*", for defining lists of elements. The full form is "<n>#<m>element" indicating at least <n> and at most <m> elements, each separated by one or more commas (",") and OPTIONAL linear white space (LWS). This makes the usual form of lists very easy; a rule such as
( *LWS element *( *LWS "," *LWS element ))
can be shown as
1#element
Wherever this construct is used, null elements are allowed, but do not contribute to the count of elements present. That is, "(element), , (element) " is permitted, but counts as only two elements. Therefore, where at least one element is required, at least one non-null element MUST be present. Default values are 0 and infinity so that "#element" allows any number, including zero; "1#element" requires at least one; and "1#2element" allows one or two.
&rule
A construct "&" is defined, similar to "#", which uses an ampersand (&) instead of commas, and MUST NOT include linear white space between elements.
implied *LWS
The grammar described by this specification is word-based. Except where noted otherwise, linear white space (LWS) can be included between any two adjacent words (token or quoted-string), and between adjacent words and separators, without changing the interpretation of a field. At least one delimiter (LWS and/or separators) MUST exist between any two tokens, since they would otherwise be interpreted as a single token.

1.4 Basic Rules

The following rules are used throughout this specification to describe basic parsing constructs. The US-ASCII coded character set is defined by [RFC20]

OCTET          = <any 8-bit sequence of data>
CHAR           = <any US-ASCII character (octets 0 - 127)>
UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
LOALPHA        = <any US-ASCII lowercase letter "a".."z">
ALPHA          = UPALPHA / LOALPHA
DIGIT          = <any US-ASCII digit "0".."9">
CTL            = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>
<">            = <US-ASCII double-quote mark (34)>
CRLF           = CR LF
LWS            = [CRLF] 1*( SP / HT )
TEXT           = <any OCTET except CTLs, but including LWS>
COMMA          = <US-ASCII comma (44)>


2. Services

OpenSocial defines several services for providing access to a container's data. Individual services are required or optional as indicated in the sections that follow.

2.3 Activity Streams

Containers MUST support the Activity Streams Service. Individual operations are required or optional as indicated in the sections that follow. Containers MUST use the following values to define the Activity Streams Service:

XRDS-Type    = "http://ns.opensocial.org/2008/opensocial/activitystreams"

2.3.1 Get Activity Streams

The Get method supports multiple queries, including requests for one or more Activity Stream entries and what fields are available.

Containers MUST support requests to the Activity Stream service. Requests and responses for retrieving Activity Stream entries use the following values:

REST-HTTP-Method       = "GET"
REST-URI-Fragment      = "/activitystreams/" User-Id "/" Group-Id [ "/" App-Id [ "/" (Activity-Id / Array<Activity-Id>) ] ]
REST-Query-Parameters  = ENCODE-REST-PARAMETERS(GetActivityStreams-Request-Parameters)
REST-Request-Payload   = null


Return-Object          = ActivityEntry  / Collection<ActivityEntry>
Activity-Id            = Object-Id

Example GET request:

http://api.example.org/rest/activitystreams/john.doe/@self/@app/object1,object2

2.3.1.1 Get Activity Streams Request Parameters

A request for a Collection of ActivityEntry objects MUST support the Standard-Request-Parameters, the Collection-Request-Parameters, and the following additional parameters:

Name Type Description
userId User-Id or Array<User-Id> User ID(s) of the person whose activities are to be returned. Defaults to "@me", indicating the currently authenticated user. In the REST protocol, userId is specified in the REST-URI-Fragment, rather than in the REST-Query-Parameters.
groupId Group-Id The group Id of the group of users whose ActivityEntries are to be returned. Defaults to "@self", which MUST return only the ActivityEntries specified by the userId parameter. In the REST protocol, the groupId is specified in the REST-URI-Fragment, rather than in the REST-Query-Parameters.
appId App-Id Optional. Specifies that the response should only contain ActivityEntries generated by the given appId. If not included, the container MUST return ActivityEntries created by the currently authenticated application. The "@all" value can be used when the generator of the activity entries of interest is not known or not of interest as filter. In the REST protocol, the appId is specified in the REST-URI-Fragment, rather than in the REST-Query-Parameters.
activityId Array<Object-Id> Optional. Specifies a list of individual ActivityEntries to include in the response. In the REST protocol, the activityIds are specified in the REST-URI-Fragment, rather than in the REST-Query-Parameters.

Example GET request with parameters:

http://api.example.org/rest/activitystreams?userId=john.doe&activityId=object1,object2

2.3.1.2 Retrieve a list of supported Activity Stream fields

Containers MAY support REST requests for supported Activity Stream fields. Requests and responses for retrieving supported Activity Stream fields use the following values:

REST-HTTP-Method       = "GET"
REST-URI-Fragment      = "/activitystreams/@supportedFields"
REST-Query-Parameters  = null
REST-Request-Payload   = null
Return-Object          = Array<String>

2.3.2 Create an ActivityEntry

Containers MUST support creating an ActivityEntry associated with the currently authenticated application. If successful, the container MUST return the ID of the newly-created ActivityEntry. For details on uploading content associated with an ActivityEntry, see the Content Upload section of [Core-API-Server].

Requests and responses to create an ActivityEntry use the following values:

REST-HTTP-Method       = "POST"
REST-URI-Fragment      = "/activitystreams/" User-Id "/@self"
REST-Query-Parameters  = null
REST-Request-Payload   = ActivityEntry


Return-Object          = ActivityEntry

2.3.2.1 Create ActivityEntries Request Parameters

A request to create an ActivityEntry MUST support the Standard-Request-Parameters, and the following additional parameters:

Name Type Description
userId User-Id User ID of the person to associate the ActivityEntry with. Defaults to "@me", indicating the currently authenticated user. In the REST protocol, userId is specified in the REST-URI-Fragment, rather than in the REST-Query-Parameters.
activity ActivityEntry The ActivityEntry to associate with the given user.

2.3.3 Update an ActivityEntry

Containers MAY support updating an ActivityEntry associated with the currently authenticated application. For details on uploading content associated with an Activity Stream, see the Content Upload section of [Core-API-Server].

Requests and responses to update an ActivityEntry use the following values:

REST-HTTP-Method       = "PUT"
REST-URI-Fragment      = "/activitystreams/" User-Id "/@self" [ "/" Activity-Id ]
REST-Query-Parameters  = null
REST-Request-Payload   = ActivityEntry


Return-Object          = ActivityEntry
Activity-Id            = Object-Id

2.3.3.1 Update ActivityEntries Request Parameters

A request to update an ActivityEntry MUST support the Standard-Request-Parameters, and the following additional parameters:

Name Type Description
userId User-Id User ID(s) of the person the ActivityEntry is associated with. Defaults to "@me", indicating the currently authenticated user.
activity ActivityEntry The ActivityEntry to update. Only the 'id' field of the ActivityEntry is required.

2.3.4 Delete an ActivityEntry

Containers MAY support deleting an ActivityEntry associated with the currently authenticated application. Requests and responses to update an ActivityEntry use the following values:

REST-HTTP-Method       = "DELETE"
REST-URI-Fragment      = "/activitystreams/" User-Id "/@self/" Activity-Id
REST-Query-Parameters  = null
REST-Request-Payload   = null


Return-Object          = null
Activity-Id            = Object-Id

2.3.4.1 Delete ActivityEntries Request Parameters

A request to delete an ActivityEntry MUST support the Standard-Request-Parameters, and the following additional parameters:

Name Type Description
userId User-Id User ID(s) of the person the ActivityEntry is associated with. Defaults to "@me", indicating the currently authenticated user.
activityId string Identifies the ActivityEntry to delete.

Example DELETE request with parameters:

http://api.example.org/rest/activitystreams?userId=john.doe&activityId=activity123

C.15 Embedded Experiences

Embedded experiences provide a mechanism for embedding Apps and other web-accessible content sources directly into a variety of contexts such as Activity Streams, email messages and Atom feeds. The mechanism works by inserting a small structure of data that includes a reference to the embedded content along with contextual data that a host application (like an OpenSocial Gadget container or a W3C Widget server) would need to render the content appropriately. While some of the concepts and terminology is OpenSocial centric, we do not feel that this approach is necessarily limited in scope to OpenSocial Gadgets as they are defined today.

The Embedded Experience data structure can be serialized as either a JSON object or XML and includes the following properties:

Property Description
context If the Embedded Experience is used to embed an App, the "context" field is used to pass data to the App so that it knows exactly which content to render. For instance, an App that displays a person's profile information will need to know which profile to display; a App that displays an album of recent photos will need to know the identity of the album to display. The content of the "context" field is undefined and specific to each individual app definition with one exception: the special property name "opensocial" is reserved for use by the container implementation. The "context" properties JSON object value or XML element structure MUST NOT contain a property named "opensocial".
gadget A URL to an App definition document that defines the App to be embedded.
preferredExperience An optional collection of properties that describe the preferred way the creator of the embedded experience would like containers to render the content.
previewImage

An optional URI to an image that can be used as a preview for the embedded content. This property accepts URL data scheme [RFC2397] to specify the image as Base64-encoded embedded data.

url A URL to a web page that allows virtually any web-accessible resource to be used as an Embedded Experience.

The "url" and "gadget" properties each reference content that is to be embedded. At least one of these properties MUST be specified. When both properties are used within the Embedded Experience, the decision about which to render is left to the container.

When serialized as JSON, the embedded experience take the form of a single JSON Object with four distinct properties: "context", "gadget", "previewImage" and "url". Additional extension properties MAY be included in the JSON object.

For instance, a simple JSON Embedded Experience that references an App:

  {
    "gadget" : "http://www.example.com/embedded/gadget.xml",
    "context" : {
      "title" : "Hello World",
      "id" : 123
    },
    "previewImage" : "http://www.example.com/embedded/123.png"
  }
    

When serialized as XML, it is expressed in the form of a root element <embed> containing four child elements, the order of which is considered insignificant: <context>, <gadget>, <previewImage>, and <url>. Additional extension elements and attributes MAY be included in the XML object.

For example,

  <embed>
    <gadget>http://www.example.com/embedded/gadget.xml</gadget>
    <context>
      <title>Hello World</title>
      <id>123</id>
    </context>
    <previewImage>http://www.example.com/embedded/123.png</previewImage>
  </embed>
    

Note that no XML namespace is currently declared for the XML serialization. This means that special care must be taken when including an XML embedded experience into another type of XML document. For example, the following shows an XML embedded experience within a partial Atom Entry Document. Note the addition of xmlns="" on the embed element in order to "undeclare" the in-scope default XML namespace.

  <entry xmlns="http://www.w3.org/2005/Atom">
    <id>http://example.org/entries/1</id>
    ...
    <embed xmlns="">
      <gadget>http://www.example.com/embedded/gadget.xml</gadget>
      <context>
        <title>Hello World</title>
        <id>123</id>
      </context>
      <previewImage>http://www.example.com/embedded/123.png</previewImage>
    </embed>
  </entry>
    

C.15.1 Additional Examples

A simple URL embedded experience using the JSON serialization:

  {
    "url" : "http://www.example.org/embed/123.html"
  }
      

The same URL embedded experience using the XML serialization:

  <embed>
    <url>http://www.example.org/embed/123.html</url>
  </embed>
      

An embedded experience that specifies both a gadget and URL serialized as JSON:

  {
    "gadget" : "http://www.example.com/embedded/gadget.xml",
    "url" : "http://www.example.org/embed/123.html",
    "context" : {
      "title" : "Hello World",
      "id" : 123
    },
    "previewImage" : "http://www.example.com/embedded/123.png"
  }
      

The same embedded experience serialized as XML:

  <embed>
    <gadget>http://www.example.com/embedded/gadget.xml</gadget>
    <url>http://www.example.org/embed/123.html</url>
    <context>
      <title>Hello World</title>
      <id>123</id>
    </context>
    <previewImage>http://www.example.com/embedded/123.png</previewImage>
  </embed>
    

C.15.2 Considerations for Embedded Experience Apps

C.15.2.1 Views For Embedded Experiences

When rendering an App as an embedded experience, the container will look within the embedded experience data model and see if there is a "preferred experience" (Appendix C.15.3) object containing a "target" property. If the target object (Appendix C.15.3.2) type is equal to "gadget" and there is a view property specified, the container will try and render the value of the "view" property. If there is no "view" property in the target object or there is no target object, or if there is no preferred experience in the data model, the container will render a view called "embedded". If an "embedded" view or the view specified within the target object of the embedded experience data model is not found within the App definition, the container SHOULD render the App's default view.

C.15.2.2 Accessing The Context

An embedded experience App has the option of requiring some contextual information in order to render itself. By abstracting the data from the gadget itself, App developers can develop generalized Apps that can be used for all embedded experiences of a specific type. For example, a gadget developed to display videos can be built so that the id of the video is contained and extracted from the embedded experience's "context" property.

  {
    "gadget" : "http://example.org/embedded/video.xml",
    "context" : {
      "video-id" : "abc123"
    }
  }
        

Apps that are written to support embedded experiences MUST require the "embedded-experiences" feature within their App definition in order to access the context.

For OpenSocial Gadgets, the contextual data is stored within the data context (Section 14.1 of Core Gadget specification) object for the gadget. The key, "org.opensocial.ee.context", is used to access the context. OpenSocial Gadgets can add a listener on the data context object for this key, or it may retrieve the key's value by using the data context APIs.

Example: The OpenSocial Gadget below registers a listener with the data context to retrieve any context data included with the embedded experience:

  <Module>
    <ModulePrefs title="Embedded Experiences Test" description="Tests the embedded experiences APIs.">
      <Require feature="embedded-experiences"></Require>
    </ModulePrefs>
    <Content type="html" view="embedded">
        <![CDATA[
          <script type="text/javascript">
            function myCallback(key) {
              var context = opensocial.data.getDataContext().getDataSet(key);
              document.getElementById('contextData').innerHTML = gadgets.json.stringify(context);
            }
            function initData() {
              opensocial.data.getDataContext().registerListener(
                'org.opensocial.ee.context', myCallback);
            }
            gadgets.util.registerOnLoadHandler(initData);
        </script>
         <div id="contextData"></div>
    ]]>
    </Content>
  </Module>

Instead of using the data context APIs to get the embedded experiences context you may choose to use the gadgets.ee.registerContextListener (Appendix C.15.7.1) API in order to lessen the amount of code you need to write. The above OpenSocial Gadget example can be rewritten to use the registerContextListener API:

  <Module>
    <ModulePrefs title="Embedded Experiences Test" description="Tests the embedded experiences APIs.">
      <Require feature="embedded-experiences"></Require>
    </ModulePrefs>
    <Content type="html" view="embedded">
        <![CDATA[
          <script type="text/javascript">
            gadgets.util.registerOnLoadHandler(function() {
              gadgets.ee.registerContextListener(function(context) {
                document.getElementById('contextData').innerHTML = gadgets.json.stringify(context);
              });
            });
        </script>
         <div id="contextData"></div>
    ]]>
    </Content>
  </Module>
C.15.2.2.1 Additional Container Specific Context

While the contextual data associated with the "org.opensocial.ee.context" key will generally originate from the information provided by the "context" property within the Embedded Experience document, containers are free to insert additional, container specific contexual data into the object. For example, a container might wish to communicate information about the type of parent object within which the Embedded Experience information was received. If the "context" property of the embedded experience document is not an object than containers SHOULD NOT add any additional information to the "context" property.

If such additional information is provided, the object associated with the "org.opensocial.ee.context" key MUST have an additional "openSocial" property.

Containers MAY use the "openSocial" property to communicate additional information about the object containing the embedded experience being rendered. This information should be added to the "associatedContext" property and MUST contain the following properties:

Property Description
id The id of the OpenSocial Data object containing the embedded experience. The type of id will depend on the type of OpenSocial Data object containing the embedded experience.
type The type of OpenSocial Data object containing the embedded experience.

The following is an example of what the embedded experience data model looks like if the container adds the required fields of the "associatedContext" object.

  {
    "gadget" : "http://example.org/AlbumViewer.xml",
    "context" : {
      "albumName": "Germany 2009",
      "photoUrls": [
        "http://examplephotos.com/3495/3925132517_5959dac775_t.jpg",
        "http://examplephotos.com/3629/3394799776_47676abb46_t.jpg",
        "http://examplephotos.com/4009/4413640211_715d924d9b_t.jpg",
        "http://examplephotos.com/2340/3528537244_d2fb037aba_t.jpg",
        "http://examplephotos.com/36/98407782_9c4c5866d1_t.jpg",
        "http://examplephotos.com/48/180544479_bb0d0f6559_t.jpg",
        "http://examplephotos.com/2668/3858018351_1e7b73c0b7_t.jpg"
      ],
      "openSocial" : {
        "associatedContext" : {
          "id" : "container.com:123abc",
          "type" : "opensocial.ActivityEntry"
        }
      }
    }
  }
          

Note: As stated above, everything inside the "openSocial" property of the above example was added by the container.

In addition to the "id" and the "type" properties, containers MAY add an additional property to the associated context called "objectReference". If present, the "objectReference" property will contain the JSON representation of the OpenSocial Data object containing the embedded experience.

Property Description
objectReference The JSON representation of the OpenSocial Data object containing the embedded experience. This OpenSocial Data object MUST contain the complete embedded experience data model.

The following is an example of what the embedded experience data model would look like if the container added the required and optional fields of the "associatedContext" object.

  {
    "gadget" : "http://example.org/AlbumViewer.xml",
    "context" : {
      "albumName": "Germany 2009",
      "photoUrls": [
        "http://examplephotos.com/3495/3925132517_5959dac775_t.jpg",
        "http://examplephotos.com/3629/3394799776_47676abb46_t.jpg",
        "http://examplephotos.com/4009/4413640211_715d924d9b_t.jpg",
        "http://examplephotos.com/2340/3528537244_d2fb037aba_t.jpg",
        "http://examplephotos.com/36/98407782_9c4c5866d1_t.jpg",
        "http://examplephotos.com/48/180544479_bb0d0f6559_t.jpg",
        "http://examplephotos.com/2668/3858018351_1e7b73c0b7_t.jpg"
      ],
      "openSocial" : {
        "associatedContext" : {
          "id" : "container.com:123abc",
          "type" : "opensocial.ActivityEntry",
          "objectReference" : {
            "postedTime": "2011-02-10T15:04:55Z",
            "actor": {
              "objectType" : "person",
              "id": "tag:example.org,2011:martin",
              "displayName": "Martin Smith"
            },
            "verb": "post",
            "object" : {
              "objectType":"collection",
              "objectTypes":["image"]
              "id": "http://example.org/albums/germany-2009",
              "url": "http://example.org/albums/germany-2009",
            },
            "openSocial" : {
              "embed" : {
                "gadget" : "http://example.org/AlbumViewer.xml",
                "context" : {
                  "albumName": "Germany 2009",
                  "photoUrls": [
                    "http://examplephotos.com/3495/3925132517_5959dac775_t.jpg",
                    "http://examplephotos.com/3629/3394799776_47676abb46_t.jpg",
                    "http://examplephotos.com/4009/4413640211_715d924d9b_t.jpg",
                    "http://examplephotos.com/2340/3528537244_d2fb037aba_t.jpg",
                    "http://examplephotos.com/36/98407782_9c4c5866d1_t.jpg",
                    "http://examplephotos.com/48/180544479_bb0d0f6559_t.jpg",
                    "http://examplephotos.com/2668/3858018351_1e7b73c0b7_t.jpg"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
          

The following example illustrates how this additional context information is accessed:

  function myCallback(key) {
    var context = opensocial.data.getDataContext().getDataSet(key);
    var video_id = context['albumName'];

    var associatedContext = context.openSocial.associatedContext;
    var ac_id = associatedContext.id;
    var ac_type = associatedContext.type;

    //The container MAY also add an object reference
    var obj_ref = associatedContext.objectReference
    if(typeof obj_ref !== 'undefined') {
      //Do something with the object reference
    }
    // ...
  }
  function initData() {
    opensocial.data.getDataContext().registerListener(
      'org.opensocial.ee.context', myCallback);
  }
  gadgets.util.registerOnLoadHandler(initData);
          

Specific container implementations are free to insert any additional information they wish into the and "openSocial" object values. The interpretation and use of any such information is considered out of the scope of this specification.

C.15.3 Preferred Experiences

While the container retains control over deciding exactly how an embedded experience is processed and rendered, there are situations where the creator of the embedded experience might wish to provide clues to the container as to how it would prefer the content to be displayed. These clues are included within the Embedded Experience using the "preferredExperience" property.

The following illustrates a basic example serialized as JSON:

  {
    "gadget" : "http://www.example.com/embedded/gadget.xml",
    "url" : "http://www.example.com/foo/bar.html",
    "context" : {
      "title" : "Hello World",
      "id" : 123
    },
    "previewImage" : "http://www.example.com/embedded/123.png",
    "preferredExperience" : {
      "target" : {
        "type" : "gadget",
        "view" : "my-ee-view"
      },
      "display" : {
        "type" : "text"
      }
  }
    

And the same example using the alternative XML serialization:

  <embed>
    <gadget>http://www.example.com/embedded/gadget.xml</gadget>
    <url>http://www.example.com/foo/bar.html</url>
    <context>
      <title>Hello World</title>
      <id>123</id>
    </context>
    <previewImage>http://www.example.com/embedded/123.png</previewImage>
    <preferredExperience>
      <target>
        <type>gadget</type>
        <view>my-ee-view</view>
      </target>
      <display>
        <type>text</type>
      </display>
    </preferredExperience>
  </embed>
    

In this example, we have an embedded experience serialized as JSON. The structure defines both a "url" and a "gadget" property, both of which can be used by the container to display embedded content. Typically, the decision of which to display when the embedded experience is rendered is up to the container. The "preferredExperience.target" property allows the creator of the embedded experience to indicate that it would prefer the container to use the "gadget" property for rendering, and specifically that the "my-ee-view" view within that App be used. The "preferredExperience.display" property indicates that rather than simply displaying the App automatically, the embedded experience's creator would rather the container initially display a hyperlink that, when clicked, causes the App to be displayed.

Property Description
display Describes preferences for how the embedded experience should initially be displayed by the container. The "display" property provides the preferred style to container on how it should render the hyperlink to open the embedded experience. The value of the "display" property is an object that contains a required "type" property, the value of which determines what other properties might appear within the object.
target Describes preferences for which type of embedded experience the container should render. For instance, if the embed includes both a "url" and "gadget" property, the "target" is used to specify which is preferred. The value of the "target" property is an object that contains a required "type" property, the value of which determines what other properties might appear within the object.

C.15.3.1 Display Types

This specification currently defines two possible values for the required "type" property on the display object: "text", "image". Each of which are illustrated below.

Display using a hyperlink:

  {
    "gadget" : "...",
    ...,
    "preferredExperience" : {
      "target": {...},
      "display": {
        "type" : "text",
        "label" : "Click on me!",
        "title" : "Click on this link!"
        "icon" : "http://mycontainer.com/app/openissue.jpg"
      }
    }
  }
      

When "type" equals "text", the additional properties on the display object are:

Property Description
label A required String that provides the text to display with the hyperlink.
title Optional text to display as the "popup help" or "tooltip" of the hyperlink.
icon The developer MAY provide a URL to an icon that can be used to decorate the text. For example, an issue management application may provide different icons for open issues than for those that are closed. Because it is expected that embedded experiences flow between containers, the URL MUST be absolute. Developers providing embedded experiences SHOULD ensure that the URL is able to be resolved by any container that will encounter the embedded experience. The container makes no assumptions about the size of the icon and MAY resize it to a size appropriate for the display needs. Use of the icon is optional. Depending on how the text is displayed, the container is not required to display the icon. The container MAY choose to display the icon in a manner appropriate to the current rendering of the object that contains the embedded experience. For example, it would be acceptable for the container to display the link in front of the text, or as a tool tip.

Display using the previewImage:

  {
    "gadget" : "...",
    ...,
    "previewImage" : "http://example.org/preview.png",
    "preferredExperience" : {
      "target": {...},
      "display": {
        "type" : "image",
        "altText" : "The alt text",
        "width" : 100,
        "height" : 100
      }
    }
  }
      

Display using Base64-encoded binary data in the URL data scheme:

  {
    "gadget" : "...",
    ...,
    "previewImage" : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA...",
    "preferredExperience" : {
      "target": {...},
      "display": {
        "type" : "image",
        "altText" : "The alt text",
        "width" : 100,
        "height" : 100
      }
    }
  }
      

When "type" equals "image", the additional properties on the display object are:

Property Description
altText Specifies optional, alternative text to display if the image cannot be displayed. Equivalent to the HTML image tags alt attribute.
height Specifies the preferred display height of the image in pixels.
width Specifies the preferred display width of the image in pixels.

Implementations are free to define additional display types, each with their own properties. If a container encounters an embedded experience that uses an unknown or unsupported display type, the container MUST ignore the display preferences.

C.15.3.2 Target Types

This specification currently defines two possible values for the type property on the target object: "gadget" and "url". Each of which are illustrated below.

Preferring the App target:

  {
    "gadget" : "...",
    "url" : "...",
    ...,
    "preferredExperience" : {
      "target": {
        "type" : "gadget",
        "view" : "my-ee-view"
      },
      "display": {
        ...
      }
    }
  }
      

Note that the preferred experience target's "type" property is only required if the preferred target is not obvious within the embedded experience. For instance, if the embedded experience only defines an IRI value for the "gadget" property, then the preferred target type is "gadget". However, if both the "url" and "gadget" properties are specified, as in the example above, the target type in the preferred experience MUST be specified. Containers MUST ignore the preferred experience if the target type value does not match the options specified within the Embedded Experience (e.g. target type specifies "url" but only a "gadget" IRI is provided, etc).

When "type" equals "gadget", the additional properties on the target object are:

Property Description
view The preferred App view to render. If not specified, the value "embedded" is assumed.
viewTarget Specifies where the container SHOULD render the view. Possible values are "TAB", "DIALOG", "MODALDIALOG", "FLOAT", and "SIDEBAR".

Preferring the url target:

  {
    "gadget" : "...",
    "url" : "...",
    ...,
    "preferredExperience" : {
      "target": {
        "type" : "url",
        "viewTarget" : "_new"
      },
      "display": {
        ...
      }
    }
  }
      

When "type" equals "url", the additional properties on the target object are:

Property Description
viewTarget When specifying a URL, rather than being forced to render in an embedded view, the developer may wish to indicate to the container that the page be opened in a new browser window. In this case, the target properties for a URL match those that are defined by the HTML spec, e.g. "_blank".

Implementations are free to define additional target types, each with their own properties. If a container encounters an embedded experience that uses an unknown or unsupported target type, the container MUST ignore the target preferences.

C.15.4 Security

Embedded experiences allow content to be rendered on the page that user has not necessarily requested, therefore it needs to be secured. The container SHOULD only ever render content that the user has previously approved. This specification does not dictate how secure rendering of embedded experiences is to be performed.

C.15.5 Embedded Experiences within Activity Streams

Embedded experiences can be used within an Activity Streams document in order to provide a more interactive experience. Whereas the core properties of the Activity provide a textual description of the event, an included embedded experience can provide a direct representation of the object involved.

For instance, if a user uploads a collection of photos and creates a new photo album, an embedded experience can be used within the activity to provide a representation of the album itself:

  {
    "postedTime": "2011-02-10T15:04:55Z",
    "actor": {
      "objectType" : "person",
      "id": "tag:example.org,2011:martin",
      "displayName": "Martin Smith"
    },
    "verb": "post",
    "object" : {
      "objectType":"collection",
      "objectTypes":["image"]
      "id": "http://example.org/albums/germany-2009",
      "url": "http://example.org/albums/germany-2009",
    },
    "openSocial" : {
      "embed" : {
        "gadget" : "http://example.org/AlbumViewer.xml",
        "context" : {
          "albumName": "Germany 2009",
          "photoUrls": [
            "http://examplephotos.com/3495/3925132517_5959dac775_t.jpg",
            "http://examplephotos.com/3629/3394799776_47676abb46_t.jpg",
            "http://examplephotos.com/4009/4413640211_715d924d9b_t.jpg",
            "http://examplephotos.com/2340/3528537244_d2fb037aba_t.jpg",
            "http://examplephotos.com/36/98407782_9c4c5866d1_t.jpg",
            "http://examplephotos.com/48/180544479_bb0d0f6559_t.jpg",
            "http://examplephotos.com/2668/3858018351_1e7b73c0b7_t.jpg"
          ]
        }
      }
    }
  }

As illustrated in the example, when included within an activity, the embedded experience MUST appear as the value of the "embed" property as a child of the "openSocial" property.

C.15.6 Embedded Experiences within Email

Numerous services send email notifications to your inbox in order to let you know something took place that you may be interested in. Most of the time however these notifications do not provide much useful information beyond a link back to the service's website. By leveraging embedded experiences, services can send an embedded representation of the object the notification is about, and allow the user to take action on the notification directly from within an embedded experiences enabled email client.

Embedded experiences serialized as either JSON or XML can be embedded Multipart MIME encoded email messages. Such email messages MUST utilize the "multipart/alternative" MIME variant and MUST contain at least two MIME parts -- one containing regular content of the email message encoded as text/html content, and another containing the embedded experience content using either the "application/embed+json" or "application/embed+xml" MIME media type, respectively representing the JSON and XML serializations. Additional MIME parts MAY be included

For instance,

  From: notifications@socialnetwork.com
  To: johndoe@example.com
  Subject: Social Network: Mary Has Commented On Your Status
  MIME-Version: 1.0
  Content-Type: multipart/alternative;
          boundary="XXXXboundary text"

  Mary has commented on your status.

  --XXXXboundary text
  Content-Type: text/plain

  Mary has commented on your status.

  --XXXXboundary text
  Content-Type: text/html

  <html>
  <!-- HTML representation here -->
  </html>

  --XXXXboundary text
  Content-Type: application/embed+json
  {
    "gadget" : "http://www.socialnetwork.com/embedded/commentgadget.xml",
    "context" : 123
  }

C.15.7 Method Details

C.15.7.1 registerContextListener

<static> gadgets.registerContextListener(listener)

Description: Registers a function which will be called when the embedded experience App receives its context.

Parameters:

Name Type Description
listener Function A function that will be called whenever the embedded experience context is set for this App. The function should take one parameter which is a JSON object representing the embedded experience context from the App. See the embedded experiences data model description (Appendix C.15) for more information on the context object.

OpenSocial Gadget Example:

         <script type="text/javascript">
            gadgets.util.registerOnLoadHandler(function() {
              gadgets.ee.registerContextListener(function(context) {
                document.getElementById('contextData').innerHTML = gadgets.json.stringify(context);
              });
            });
         </script>